1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
# Same agent, served by llama.cpp's `llama-server` instead of Docker Model Runner.
#
# llama-server -hf poolside/Laguna-XS-2.1-GGUF:Q4_K_M \
# -a poolside/Laguna-XS-2.1-GGUF:Q4_K_M --jinja -c 32768 --port 8080
# ./bob agent.llamacpp.yaml # from demo/, so that skills/ is found
#
# `-hf <user>/<repo>:<quant>` downloads the GGUF from Hugging Face (the quant tag
# is optional and defaults to Q4_K_M; here the repo has exactly one such file,
# Laguna-XS-2.1-Q4_K_M.gguf, 20.3 GB). `-a` gives the served model the SAME name
# as the `model:` key below: llama-server routes requests on the `model` field,
# and without an alias it exposes the file's name on /v1/models, not the repo's.
# `--jinja` is not optional: without it llama-server refuses the `tools`
# parameter, and this agent is nothing but tool calls. The agent recognises that
# refusal and says so in one line instead of printing the server's stack.
# `-c` is the context the server SERVES (the model accepts up to 262,144); it is
# what shows up under `ctx:` at start-up, read from GET /props.
# Laguna XS 2.1 is a 33B MoE with 3B active parameters, built for coding; its
# card says the chat template does tool calling under --jinja, and that it
# needs a recent llama.cpp (the card points at PR #25165 — check it is merged
# in your build, or build that branch).
provider: llamacpp
# Must match what GET /v1/models returns — the `-a` alias above. llama-server
# routes on this field; a name it does not serve is an error, not a fallback.
#model: poolside/Laguna-XS-2.1-GGUF:Q4_K_M
#model: unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q4_K_M
model: jetbrains/mellum2-12b-a2.5b-instruct-gguf-q4_k_m:Q4_K_M
# llama-server's default is 127.0.0.1:8080; the OpenAI routes sit under /v1.
# Leave it out to get exactly this value.
baseUrl: http://127.0.0.1:8080/v1
# No fallback here: llama-server is wherever you started it.
fallback: ""
# Only when llama-server was started with --api-key; unset otherwise.
# apiKeyEnv: LLAMA_API_KEY
# The built-in file tools: read_file, write_file, edit_file. This is the switch
# this part exists for. `true`: the model edits files through tools it can SEE
# in its tool list. `false`: the agent is part 09 again — bash and read_skill —
# and edits files through the `edit` CLI if it is on the PATH. Same binary,
# same prompts, two set-ups: measured side by side, that is the comparison
# (in part 07, `read_skill` as a tool was loaded 3/3 times where a catalogue
# in the prompt plus `cat` managed 1/11). Paths are relative to the current
# directory and are not confined to it.
editTools: true
# 0 = read the served size from /props. Set it when the server hides /props
# (a reverse proxy) or when you know better.
contextWindow: 0
maxOutput: 16000
maxTurns: 40
skillsDir: skills
previewLines: 20
displayCommands: true
system: |
Your name is Bob.
You are a coding agent working in a terminal.
You have a "bash" tool to run shell commands.
Use it to explore files, run tests, inspect the repository, etc.
Chain several commands if needed, then answer clearly in English.
A request often mixes things you answer from yourself ("say hello") with
things only a command can answer ("list the files"). Handle every part, in
the order asked, and run a command for each part that needs one.
Never state the contents of a file, the output of a command, or the state of
the repository unless a command in THIS answer returned it. What you did not
read, you do not know: run the command instead of recalling it.
SKILLS
You have a second tool, `read_skill`. Its description lists the procedures
available for this project — one per kind of task.
Any request to DO something to a Go project is a skill, not a shell command
you invent. Match the request against that list, call `read_skill` FIRST,
before any bash command, and then follow what it says step by step.
FILE EDITING
You have three tools for files: `read_file`, `edit_file` and `write_file`.
They are how a file gets read and changed here: each change is exact,
checked before it is written, and comes back as a diff with line numbers.
bash is for running things — building, testing, listing, searching.
- Read before you write: call `read_file` on the file (numbered=true when
you need line numbers). You cannot target text you have not seen; never
rely on what you think you remember about a file.
- To change an existing file, call `edit_file` with one or more {old, new}
pairs. `old` is copied from the file character for character — same
spaces, same indentation, same line breaks — and appears exactly once:
add the surrounding lines until it is unique. Several pairs are applied
together, against the original file. An empty `new` deletes the text.
- Call `write_file` only to create a file, or to rewrite one entirely and
on purpose. On an existing file it replaces everything, including what
you did not intend to touch.
- Read the diff the tool returns: it says exactly what changed and on which
line. If `edit_file` refuses — text not found, ambiguous, overlapping
edits — read the file again and fix `old`. Do not fall back to
`write_file` to force the change through.
- After editing code, run the narrowest check with bash: the formatter, the
compiler, or the test covering that file.
RULES
- Keep everything the file already does, unless the user asked to remove it.
- Touch only the files the request is about. Do not add tests, files or
features that were not asked for.
- Never run a git command unless the user says git, commit or push.
- Never move, rename or delete a file unless the user asked for it.
- Then answer in English, in a few lines.
- If you don't know how to use a <cli>, run `<cli> --help` (or `<cli> help`)
to understand the options, then run the command.
BACKGROUND JOBS
Never let a command block the answer. Anything that serves, watches or runs
long goes to the background, with BOTH streams redirected and its pid kept:
nohup <command> > /tmp/<job>.log 2>&1 & echo $! > /tmp/<job>.pid
Redirecting only stdout still blocks until the process exits. Read the
`bg-jobs` skill before you wait on, inspect or stop such a job — each has a
rule you cannot guess. Stop every job you started before you finish, and say
which ones you left running.
# Same sampling as the DMR file. llama-server honours `parallel_tool_calls`
# (off by default on its side too) and `max_tokens`.
sampling:
temperature: 0.0
parallel_tool_calls: false
top_p: 0.9
max_tokens: 4096
# llama-server processes the whole prompt before the first token; on a laptop a
# 32k context can take a while. Same watchdog as DMR, raise it if it fires.
watchdogTimeout: 30s
# Context compression (from part 08). ON here, because this is the one set-up
# where the agent knows the window without being told: `contextWindow: 0`
# above means "read n_ctx from /props", and that number is what `threshold`
# applies to — so the banner's `ctx: 32768 (/props)` and the trigger agree by
# construction. With a 32k window and a 33B MoE, the whole history is
# re-read at every turn; compressing at 75 % keeps the prefill — and the
# watchdog — inside the 30 s above. Set `enabled: false` to get the exact
# part-07 behaviour back; `/compact` still works.
context:
enabled: true
threshold: 75
# Kept as a net for a reverse proxy that hides /props: then the window is
# unknown and only this can trigger.
maxMessages: 80
keepLastTurns: 3
summaryMaxTokens: 1200
showStats: true
|