Tell a local model what it is, and number children once
Two things the read-tool transcript exposed.
A local session sent no system prompt. The thread lane sends the server an
objective at thread creation; the local lane sent a bare user message and the
tool schemas. Asked what tools it had, the model answered with what a coding
agent usually has -- read/write, search, bash, web fetch -- none of which this
session declares. That answer then sat in the transcript, and the next turn read
it back as instruction: its own reasoning says the tools are "not in the function
list" and then defers to "the instructions state that Read/Write etc. exist".
There were no such instructions. The model file carries no system directive and
its template is `{{ .Prompt }}`, so the vacuum was ours to fill.
So the source now opens with one. It is derived from the tools actually declared
rather than written out, which is the point: it cannot name a tool the session
does not pass, cannot miss one it does, and needs no edit when the tool list
changes. It says the list is complete, that the session has no file, shell,
search, or web tools of its own, and that a capability named in a tool's
description belongs to the child that tool starts, not to the model reading it.
Three runs that had been inventing tools now answer with `delegate` alone and
say what they cannot do.
The delegate description invited the second bug. It said each child is told its
number "so a prompt may say work on your own numbered file", and the model wrote
`You are child #1 of 3` into the prompt every child receives. The harness
already numbers each child, so children two and three were told they were both
themselves and child one, and did identical work: three agents, one file, one
result, reported as "same result -- a good sign". It was the opposite. The
description now says every child runs the same prompt and is told its own number
separately, and to write for whichever child reads it rather than naming one.
The same fan-out now reads three different files and reports three line counts,
all three correct.
280 tests pass, including four on the system prompt: that it names the declared
tools, that it says there are none when there are none, that it is derived
rather than fixed, and that it is sent once rather than per turn.
Tell a local model what it is, and number children once
Deploy story
What this commit did to the running system — joined from the forge receipt chain, the part a commit page elsewhere cannot show.
Not deployed through the forge lane
No push, promotion, build, or deploy receipt references this commit (receipts are scanned over a bounded recent window). Changes shipped by full node replacement carry their proof in the release gate receipt instead.
Changed files
-
modified
packages/openagents-cli/src/coder-ollama.ts -
modified
packages/openagents-cli/src/coder-tools.ts -
modified
packages/openagents-cli/test/coder-ollama.test.ts
Diff
3 files changed, +126 -4
packages/openagents-cli/src/coder-ollama.ts modified +47
@@ -53,6 +53,47 @@ export const parseOllamaModelFlag = (value: string): string | undefined => {
| 53 | 53 |
|
| 54 | 54 |
|
| 55 | 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 |
|
|
| 56 | 97 |
|
| 57 | 98 |
|
| 58 | 99 |
|
@@ -81,6 +122,12 @@ export class OllamaReplySource implements ReplySource {
| 81 | 122 |
|
| 82 | 123 |
|
| 83 | 124 |
|
| 125 |
|
|
| 126 |
|
|
| 127 |
|
|
| 128 |
|
|
| 129 |
|
|
| 130 |
|
|
| 84 | 131 |
|
| 85 | 132 |
|
| 86 | 133 |
|
packages/openagents-cli/src/coder-tools.ts modified +5 -3
@@ -56,9 +56,11 @@ export function delegateTool(delegation: CoderDelegation): CoderTool {
| 56 | 56 |
|
| 57 | 57 |
|
| 58 | 58 |
|
| 59 |
|
|
| 60 |
|
|
| 61 |
|
|
| 59 |
|
|
| 60 |
|
|
| 61 |
|
|
| 62 |
|
|
| 63 |
|
|
| 62 | 64 |
|
| 63 | 65 |
|
| 64 | 66 |
|
packages/openagents-cli/test/coder-ollama.test.ts modified +74 -1
@@ -119,7 +119,12 @@ describe("an ollama turn that calls a tool", () => {
| 119 | 119 |
|
| 120 | 120 |
|
| 121 | 121 |
|
| 122 |
|
|
| 122 |
|
|
| 123 |
|
|
| 124 |
|
|
| 125 |
|
|
| 126 |
|
|
| 127 |
|
|
| 123 | 128 |
|
| 124 | 129 |
|
| 125 | 130 |
|
@@ -173,3 +178,71 @@ describe("an ollama turn that calls a tool", () => {
| 173 | 178 |
|
| 174 | 179 |
|
| 175 | 180 |
|
| 181 |
|
|
| 182 |
|
|
| 183 |
|
|
| 184 |
|
|
| 185 |
|
|
| 186 |
|
|
| 187 |
|
|
| 188 |
|
|
| 189 |
|
|
| 190 |
|
|
| 191 |
|
|
| 192 |
|
|
| 193 |
|
|
| 194 |
|
|
| 195 |
|
|
| 196 |
|
|
| 197 |
|
|
| 198 |
|
|
| 199 |
|
|
| 200 |
|
|
| 201 |
|
|
| 202 |
|
|
| 203 |
|
|
| 204 |
|
|
| 205 |
|
|
| 206 |
|
|
| 207 |
|
|
| 208 |
|
|
| 209 |
|
|
| 210 |
|
|
| 211 |
|
|
| 212 |
|
|
| 213 |
|
|
| 214 |
|
|
| 215 |
|
|
| 216 |
|
|
| 217 |
|
|
| 218 |
|
|
| 219 |
|
|
| 220 |
|
|
| 221 |
|
|
| 222 |
|
|
| 223 |
|
|
| 224 |
|
|
| 225 |
|
|
| 226 |
|
|
| 227 |
|
|
| 228 |
|
|
| 229 |
|
|
| 230 |
|
|
| 231 |
|
|
| 232 |
|
|
| 233 |
|
|
| 234 |
|
|
| 235 |
|
|
| 236 |
|
|
| 237 |
|
|
| 238 |
|
|
| 239 |
|
|
| 240 |
|
|
| 241 |
|
|
| 242 |
|
|
| 243 |
|
|
| 244 |
|
|
| 245 |
|
|
| 246 |
|
|
| 247 |
|
|
| 248 |
|