@stigmer/runner 3.39.1-dev.20260928194002 → 3.40.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/.build-fingerprint +1 -1
- package/dist/activities/execute-deep-agent/prompt-builder.d.ts +70 -35
- package/dist/activities/execute-deep-agent/prompt-builder.js +70 -55
- package/dist/activities/execute-deep-agent/prompt-builder.js.map +1 -1
- package/dist/activities/execute-deep-agent/turn-setup.d.ts +18 -13
- package/dist/activities/execute-deep-agent/turn-setup.js +35 -29
- package/dist/activities/execute-deep-agent/turn-setup.js.map +1 -1
- package/dist/shared/prompt-sections.d.ts +6 -28
- package/dist/shared/prompt-sections.js +6 -35
- package/dist/shared/prompt-sections.js.map +1 -1
- package/dist/shared/skill-resolver.d.ts +2 -3
- package/dist/shared/skill-resolver.js +2 -3
- package/dist/shared/skill-resolver.js.map +1 -1
- package/dist/shared/workspace/sources/git.js +13 -6
- package/dist/shared/workspace/sources/git.js.map +1 -1
- package/package.json +5 -5
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.build-from-plan.prompt.md +1 -27
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.everything.prompt.md +26 -30
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.plan-mode.prompt.md +1 -26
- package/src/activities/execute-deep-agent/__tests__/goldens/user-message.everything.md +36 -0
- package/src/activities/execute-deep-agent/__tests__/prompt-builder.test.ts +127 -199
- package/src/activities/execute-deep-agent/__tests__/prompt-goldens.test.ts +31 -26
- package/src/activities/execute-deep-agent/prompt-builder.ts +104 -92
- package/src/activities/execute-deep-agent/turn-setup.ts +36 -31
- package/src/shared/__tests__/prompt-sections.test.ts +2 -54
- package/src/shared/prompt-sections.ts +6 -55
- package/src/shared/skill-resolver.ts +2 -3
- package/src/shared/workspace/__tests__/git-source.test.ts +11 -5
- package/src/shared/workspace/sources/git.ts +14 -8
- package/dist/shared/skill-relevance.d.ts +0 -65
- package/dist/shared/skill-relevance.js +0 -175
- package/dist/shared/skill-relevance.js.map +0 -1
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.skills-below-threshold.prompt.md +0 -146
- package/src/shared/__tests__/skill-relevance.test.ts +0 -292
- package/src/shared/skill-relevance.ts +0 -222
package/README.md
CHANGED
|
@@ -176,7 +176,7 @@ All configuration is environment-driven. Names and defaults below are verified a
|
|
|
176
176
|
|----------|-----------|----------|---------|---------|
|
|
177
177
|
| `ARTIFACT_STORAGE_TYPE` | All | No | `proxy` if `STIGMER_PROXY_ENDPOINT` is set, else `local` | Selects the artifact backend: `local` (filesystem, served by the Stigmer backend) or `proxy` (presigned URLs via the proxy). An explicit value always wins. Storage follows transport, not execution location. |
|
|
178
178
|
| `LOCAL_ARTIFACT_PATH` | Local storage | No | `~/.stigmer/data/artifacts` | Filesystem root of the local artifact store. **Must equal the stigmer-server's `ARTIFACT_LOCAL_BASE_PATH`** — in local mode the server writes an artifact to `<ARTIFACT_LOCAL_BASE_PATH>/<key>` and the runner reads it from `<LOCAL_ARTIFACT_PATH>/<key>`, so a mismatch makes every storage-key attachment and offload fail to resolve. The defaults align out of the box; the CLI local daemon sets both explicitly. |
|
|
179
|
-
| `LOCAL_ARTIFACT_SERVE_URL` | Local storage | No | `http://localhost:7235` | Base URL of the server's artifact HTTP file server (its `ARTIFACT_HTTP_PORT`, default `GRPC_PORT + 1`). Used for blob downloads; the runner's own read-back goes straight to disk. |
|
|
179
|
+
| `LOCAL_ARTIFACT_SERVE_URL` | Local storage | No | `http://localhost:7235` | Base URL of the server's artifact HTTP file server (its `ARTIFACT_HTTP_PORT`, default `GRPC_PORT + 1`, or an ephemeral port the server's boot log names when `GRPC_PORT` is 0). Used for blob downloads; the runner's own read-back goes straight to disk. |
|
|
180
180
|
|
|
181
181
|
### Payload encryption (Temporal history at rest)
|
|
182
182
|
|
package/dist/.build-fingerprint
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"hash":"
|
|
1
|
+
{"hash":"45461275395af5f1","builtAt":"2026-09-29T00:28:45.200Z","fileCount":335}
|
|
@@ -1,19 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The native harness's system prompt
|
|
3
|
-
* `systemPrompt`,
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* The native harness's prompt: the system prompt `createDeepAgent` receives
|
|
3
|
+
* as `systemPrompt`, and the turn's user message.
|
|
4
|
+
*
|
|
5
|
+
* The system prompt is rebuilt on EVERY invocation (never checkpointed with
|
|
6
|
+
* the message history), so every standing fact is injected on every turn by
|
|
7
|
+
* design — a first-turn-only injection would vanish from turn 2 onward. It is
|
|
8
|
+
* a function of the session and of the execution's settings (its mode), never
|
|
9
|
+
* of the turn. The provider caches tools, system and messages as one prefix,
|
|
10
|
+
* so a system byte that follows the message re-writes the cached prompt and
|
|
11
|
+
* the whole conversation after it, on every turn, at the cache-write price.
|
|
12
|
+
* What belongs to one turn — its input files, the workspace paths it
|
|
13
|
+
* references, the conversation catchup — rides that turn's user message
|
|
14
|
+
* (`composeUserMessage`), which enters the checkpointer with the turn and
|
|
15
|
+
* stays in history. That is the Cursor harness's resumed-turn placement
|
|
16
|
+
* (`execute-cursor/prompt-builder.ts` `buildPrompt`) and the runner's rule
|
|
17
|
+
* that user content goes in user messages, never the system prompt.
|
|
6
18
|
*
|
|
7
19
|
* Pure functions: no side effects, no I/O. `turn-setup.ts` gathers the
|
|
8
20
|
* inputs from the runtime's resolved record and this module renders them.
|
|
9
21
|
*
|
|
10
22
|
* What is this harness's and what is shared (since #1096):
|
|
11
23
|
* - Shared through `shared/prompt-sections.ts`: WHICH standing sections
|
|
12
|
-
* render and in WHAT order (`standingContextSections`)
|
|
13
|
-
* bullet and disclosure lines (`inputFileLines`)
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
24
|
+
* render and in WHAT order (`standingContextSections`) and the
|
|
25
|
+
* input-files bullet and disclosure lines (`inputFileLines`). Their WORDS
|
|
26
|
+
* come from each fact's own module; this builder only frames them. Every
|
|
27
|
+
* mounted skill is described on every turn, as the Cursor harness does:
|
|
28
|
+
* choosing skills by the message made the system prompt follow the
|
|
29
|
+
* message.
|
|
17
30
|
* - This harness's: the framing — `## Heading` markdown sections, the house
|
|
18
31
|
* style for a system prompt — and every text that quotes this engine's
|
|
19
32
|
* tools: the `## Skills` activation protocol, the response rules, the
|
|
@@ -24,7 +37,8 @@
|
|
|
24
37
|
*
|
|
25
38
|
* The rendered bytes are load-bearing for the hermetic tests: `ScriptedModel`
|
|
26
39
|
* tells its scripted roles apart by the system prompt's text, so this
|
|
27
|
-
* module's whole output
|
|
40
|
+
* module's whole output — the system prompt and the turn's message — is
|
|
41
|
+
* pinned by `__tests__/prompt-goldens.test.ts`.
|
|
28
42
|
*/
|
|
29
43
|
import { InteractionMode } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
30
44
|
import type { ProvisionResult } from "../../shared/workspace/types.js";
|
|
@@ -47,22 +61,6 @@ export interface PromptBuilderInput {
|
|
|
47
61
|
* when the agent serves no proactive channel or nothing is sendable.
|
|
48
62
|
*/
|
|
49
63
|
channelTemplatesPromptSection?: string;
|
|
50
|
-
workspaceFileRefs: string[];
|
|
51
|
-
workspaceRoot: string;
|
|
52
|
-
/** The turn's resolved input files, as the runtime's attachment phase returns them. */
|
|
53
|
-
inputFiles: readonly ResolvedAttachment[];
|
|
54
|
-
/**
|
|
55
|
-
* Vision facts about this turn's attachments (T04): which images the model
|
|
56
|
-
* sees inline in the user message and which degraded to path-only.
|
|
57
|
-
* Rendered inside the Input Files section.
|
|
58
|
-
*/
|
|
59
|
-
vision?: VisionPromptInfo;
|
|
60
|
-
/**
|
|
61
|
-
* What kind of URL the turn's storage backend mints (issue #532) — keys
|
|
62
|
-
* the Input Files section's hand-off wording (attachment-download-urls.ts).
|
|
63
|
-
* One turn-level fact: all attachments ride the one configured storage.
|
|
64
|
-
*/
|
|
65
|
-
downloadUrlKind?: DownloadUrlKind;
|
|
66
64
|
/**
|
|
67
65
|
* The execution's interaction mode. PLAN appends the shared plan-mode
|
|
68
66
|
* directive so the model knows the turn's deliverable is a plan document.
|
|
@@ -79,6 +77,14 @@ export interface PromptBuilderInput {
|
|
|
79
77
|
* message itself is just a short label ("Build from plan").
|
|
80
78
|
*/
|
|
81
79
|
buildFromPlan?: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* The approved plan's path among the turn's input files
|
|
82
|
+
* (`implement-plan-prompt.ts` `findApprovedPlanPath`), read only under
|
|
83
|
+
* `buildFromPlan`. Absent when the plan did not materialize, which selects
|
|
84
|
+
* the directive's conversation-plan variant. The Input Files section
|
|
85
|
+
* itself rides the turn's message (`composeUserMessage`).
|
|
86
|
+
*/
|
|
87
|
+
approvedPlanPath?: string;
|
|
82
88
|
/**
|
|
83
89
|
* Rollover context bridge (cloud DD-013): a digest of the previous
|
|
84
90
|
* session's conversation, read from `SessionSpec.metadata`. Injected on
|
|
@@ -128,17 +134,46 @@ export type { VisionPromptInfo };
|
|
|
128
134
|
* sections. Pure function with no I/O.
|
|
129
135
|
*/
|
|
130
136
|
export declare function buildEnhancedSystemPrompt(input: PromptBuilderInput): string;
|
|
137
|
+
/** The turn's own content, composed around what the user typed. */
|
|
138
|
+
export interface TurnMessageInput {
|
|
139
|
+
/** What the user typed (`spec.message`); never mutated. */
|
|
140
|
+
readonly message: string;
|
|
141
|
+
/** The conversation catchup digest (cloud DD-006), when the turn carries one. */
|
|
142
|
+
readonly conversationCatchup?: string;
|
|
143
|
+
/** This turn's resolved input files, as the runtime's attachment phase returns them. */
|
|
144
|
+
readonly inputFiles: readonly ResolvedAttachment[];
|
|
145
|
+
/**
|
|
146
|
+
* Vision facts about this turn's attachments (T04): which images the model
|
|
147
|
+
* sees inline in this same message and which degraded to path-only.
|
|
148
|
+
* Rendered inside the Input Files section.
|
|
149
|
+
*/
|
|
150
|
+
readonly vision?: VisionPromptInfo;
|
|
151
|
+
/**
|
|
152
|
+
* What kind of URL the turn's storage backend mints (issue #532) — keys
|
|
153
|
+
* the Input Files section's hand-off wording (attachment-download-urls.ts).
|
|
154
|
+
* One turn-level fact: all attachments ride the one configured storage.
|
|
155
|
+
*/
|
|
156
|
+
readonly downloadUrlKind?: DownloadUrlKind;
|
|
157
|
+
/** The workspace paths the user highlighted for this message (`spec.workspace_file_refs`). */
|
|
158
|
+
readonly workspaceFileRefs: readonly string[];
|
|
159
|
+
}
|
|
131
160
|
/**
|
|
132
|
-
* Compose the turn's USER MESSAGE for the graph invocation:
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
161
|
+
* Compose the turn's USER MESSAGE for the graph invocation: this turn's
|
|
162
|
+
* payload (its input files, then the workspace paths it references), then the
|
|
163
|
+
* framed conversation catchup (cloud DD-006), then what the user typed, each
|
|
164
|
+
* set off by a horizontal rule. Payload first and context closest to the task
|
|
165
|
+
* is the Cursor harness's resumed-turn order.
|
|
166
|
+
*
|
|
167
|
+
* In the user message and never the system prompt (A27, and the module
|
|
168
|
+
* header): the system prompt is rebuilt per invocation, so a turn's content
|
|
169
|
+
* there would vanish one turn later and, while it lasted, change the cached
|
|
170
|
+
* prefix; a message enters the checkpointer with the turn and persists in
|
|
171
|
+
* history, so a later turn still knows which files an earlier one carried.
|
|
172
|
+
* An approval resume sends no new message and needs none: the payload is
|
|
173
|
+
* already in the checkpointed one. The caller's `spec.message` is never
|
|
174
|
+
* mutated; the composition exists only in the graph input.
|
|
140
175
|
*/
|
|
141
|
-
export declare function composeUserMessage(
|
|
176
|
+
export declare function composeUserMessage(input: TurnMessageInput): string;
|
|
142
177
|
/**
|
|
143
178
|
* The `## Skills` section of this harness's system prompt, rendered from the
|
|
144
179
|
* runtime's mounted-skill metadata (`shared/skill-resolver.ts`
|
|
@@ -1,19 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The native harness's system prompt
|
|
3
|
-
* `systemPrompt`,
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* The native harness's prompt: the system prompt `createDeepAgent` receives
|
|
3
|
+
* as `systemPrompt`, and the turn's user message.
|
|
4
|
+
*
|
|
5
|
+
* The system prompt is rebuilt on EVERY invocation (never checkpointed with
|
|
6
|
+
* the message history), so every standing fact is injected on every turn by
|
|
7
|
+
* design — a first-turn-only injection would vanish from turn 2 onward. It is
|
|
8
|
+
* a function of the session and of the execution's settings (its mode), never
|
|
9
|
+
* of the turn. The provider caches tools, system and messages as one prefix,
|
|
10
|
+
* so a system byte that follows the message re-writes the cached prompt and
|
|
11
|
+
* the whole conversation after it, on every turn, at the cache-write price.
|
|
12
|
+
* What belongs to one turn — its input files, the workspace paths it
|
|
13
|
+
* references, the conversation catchup — rides that turn's user message
|
|
14
|
+
* (`composeUserMessage`), which enters the checkpointer with the turn and
|
|
15
|
+
* stays in history. That is the Cursor harness's resumed-turn placement
|
|
16
|
+
* (`execute-cursor/prompt-builder.ts` `buildPrompt`) and the runner's rule
|
|
17
|
+
* that user content goes in user messages, never the system prompt.
|
|
6
18
|
*
|
|
7
19
|
* Pure functions: no side effects, no I/O. `turn-setup.ts` gathers the
|
|
8
20
|
* inputs from the runtime's resolved record and this module renders them.
|
|
9
21
|
*
|
|
10
22
|
* What is this harness's and what is shared (since #1096):
|
|
11
23
|
* - Shared through `shared/prompt-sections.ts`: WHICH standing sections
|
|
12
|
-
* render and in WHAT order (`standingContextSections`)
|
|
13
|
-
* bullet and disclosure lines (`inputFileLines`)
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
24
|
+
* render and in WHAT order (`standingContextSections`) and the
|
|
25
|
+
* input-files bullet and disclosure lines (`inputFileLines`). Their WORDS
|
|
26
|
+
* come from each fact's own module; this builder only frames them. Every
|
|
27
|
+
* mounted skill is described on every turn, as the Cursor harness does:
|
|
28
|
+
* choosing skills by the message made the system prompt follow the
|
|
29
|
+
* message.
|
|
17
30
|
* - This harness's: the framing — `## Heading` markdown sections, the house
|
|
18
31
|
* style for a system prompt — and every text that quotes this engine's
|
|
19
32
|
* tools: the `## Skills` activation protocol, the response rules, the
|
|
@@ -24,7 +37,8 @@
|
|
|
24
37
|
*
|
|
25
38
|
* The rendered bytes are load-bearing for the hermetic tests: `ScriptedModel`
|
|
26
39
|
* tells its scripted roles apart by the system prompt's text, so this
|
|
27
|
-
* module's whole output
|
|
40
|
+
* module's whole output — the system prompt and the turn's message — is
|
|
41
|
+
* pinned by `__tests__/prompt-goldens.test.ts`.
|
|
28
42
|
*/
|
|
29
43
|
import { relative } from "node:path";
|
|
30
44
|
import { InteractionMode } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
@@ -32,7 +46,7 @@ import { formatConversationCatchupText } from "../../shared/conversation-catchup
|
|
|
32
46
|
import { inputFileLines, standingContextSections, } from "../../shared/prompt-sections.js";
|
|
33
47
|
import { effectiveInstructions } from "../../shared/builtin-assistant-prompt.js";
|
|
34
48
|
import { PLAN_MODE_DIRECTIVE } from "../../shared/plan-mode-prompt.js";
|
|
35
|
-
import { buildImplementPlanDirective
|
|
49
|
+
import { buildImplementPlanDirective } from "../../shared/implement-plan-prompt.js";
|
|
36
50
|
import { STIGMER_LOCAL_STATE_DIR } from "../../shared/workspace/stigmer-link.js";
|
|
37
51
|
import { DEFAULT_MAX_CONCURRENT } from "../../shared/subagent-gate.js";
|
|
38
52
|
import { ENGINE_TOOL } from "./engine-tools.js";
|
|
@@ -127,15 +141,6 @@ export function buildEnhancedSystemPrompt(input) {
|
|
|
127
141
|
if (input.channelTemplatesPromptSection) {
|
|
128
142
|
prompt += "\n\n" + input.channelTemplatesPromptSection;
|
|
129
143
|
}
|
|
130
|
-
if (input.workspaceFileRefs.length > 0) {
|
|
131
|
-
const refSection = buildReferencedFilesSection(input.workspaceFileRefs, input.workspaceRoot);
|
|
132
|
-
if (refSection) {
|
|
133
|
-
prompt += refSection;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
if (input.inputFiles.length > 0) {
|
|
137
|
-
prompt += buildInputFilesSection(input.inputFiles, input.vision, input.downloadUrlKind);
|
|
138
|
-
}
|
|
139
144
|
// The standing context, in the shared order (the doctrine is stated once,
|
|
140
145
|
// on `standingContextSections`); this harness only frames each section.
|
|
141
146
|
for (const section of standingContextSections(input)) {
|
|
@@ -161,27 +166,41 @@ export function buildEnhancedSystemPrompt(input) {
|
|
|
161
166
|
"`.stigmer/` directory); paths outside it are refused.";
|
|
162
167
|
}
|
|
163
168
|
if (input.buildFromPlan) {
|
|
164
|
-
const planPath = findApprovedPlanPath(input.inputFiles.map((f) => f.relativePath));
|
|
165
169
|
prompt +=
|
|
166
170
|
"\n\n## Implement the approved plan\n\n" +
|
|
167
|
-
buildImplementPlanDirective(
|
|
171
|
+
buildImplementPlanDirective(input.approvedPlanPath);
|
|
168
172
|
}
|
|
169
173
|
return prompt;
|
|
170
174
|
}
|
|
171
175
|
/**
|
|
172
|
-
* Compose the turn's USER MESSAGE for the graph invocation:
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
176
|
+
* Compose the turn's USER MESSAGE for the graph invocation: this turn's
|
|
177
|
+
* payload (its input files, then the workspace paths it references), then the
|
|
178
|
+
* framed conversation catchup (cloud DD-006), then what the user typed, each
|
|
179
|
+
* set off by a horizontal rule. Payload first and context closest to the task
|
|
180
|
+
* is the Cursor harness's resumed-turn order.
|
|
181
|
+
*
|
|
182
|
+
* In the user message and never the system prompt (A27, and the module
|
|
183
|
+
* header): the system prompt is rebuilt per invocation, so a turn's content
|
|
184
|
+
* there would vanish one turn later and, while it lasted, change the cached
|
|
185
|
+
* prefix; a message enters the checkpointer with the turn and persists in
|
|
186
|
+
* history, so a later turn still knows which files an earlier one carried.
|
|
187
|
+
* An approval resume sends no new message and needs none: the payload is
|
|
188
|
+
* already in the checkpointed one. The caller's `spec.message` is never
|
|
189
|
+
* mutated; the composition exists only in the graph input.
|
|
180
190
|
*/
|
|
181
|
-
export function composeUserMessage(
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
191
|
+
export function composeUserMessage(input) {
|
|
192
|
+
const parts = [];
|
|
193
|
+
if (input.inputFiles.length > 0) {
|
|
194
|
+
parts.push(buildInputFilesSection(input.inputFiles, input.vision, input.downloadUrlKind));
|
|
195
|
+
}
|
|
196
|
+
if (input.workspaceFileRefs.length > 0) {
|
|
197
|
+
parts.push(buildReferencedFilesSection(input.workspaceFileRefs));
|
|
198
|
+
}
|
|
199
|
+
if (input.conversationCatchup) {
|
|
200
|
+
parts.push(formatConversationCatchupText(input.conversationCatchup));
|
|
201
|
+
}
|
|
202
|
+
parts.push(input.message);
|
|
203
|
+
return parts.join("\n\n---\n\n");
|
|
185
204
|
}
|
|
186
205
|
/**
|
|
187
206
|
* The `## Skills` section of this harness's system prompt, rendered from the
|
|
@@ -292,13 +311,13 @@ function formatEntryDescription(result) {
|
|
|
292
311
|
"You are operating directly on the user's files — changes are " +
|
|
293
312
|
"immediate and persistent. Use git to track and verify your changes.");
|
|
294
313
|
}
|
|
314
|
+
// No commit: the clone's HEAD moves with every write-back commit, and a
|
|
315
|
+
// system prompt that names it would change on every such turn
|
|
316
|
+
// (`shared/workspace/sources/git.ts` says the same for one entry).
|
|
295
317
|
if (result.sourceType === "git_repo" && result.gitMetadata) {
|
|
296
318
|
const meta = result.gitMetadata;
|
|
297
|
-
const
|
|
298
|
-
|
|
299
|
-
: meta.baseCommit;
|
|
300
|
-
return (`Workspace entry **${name}** was initialized from ` +
|
|
301
|
-
`${meta.repoUrl} (branch: ${meta.branch}, commit: ${shortSha}).\n` +
|
|
319
|
+
const branch = meta.branch ? ` (branch: ${meta.branch})` : "";
|
|
320
|
+
return (`Workspace entry **${name}** was initialized from ${meta.repoUrl}${branch}.\n` +
|
|
302
321
|
"Changes you make will be captured as artifacts when execution completes.");
|
|
303
322
|
}
|
|
304
323
|
if (result.sourceType === "empty") {
|
|
@@ -307,25 +326,22 @@ function formatEntryDescription(result) {
|
|
|
307
326
|
}
|
|
308
327
|
return result.workspaceDescription;
|
|
309
328
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
let section = "\n\n## Referenced Files\n\n" +
|
|
329
|
+
/** The `## Referenced Files` part of the turn's message: the paths the user highlighted, one bullet each. */
|
|
330
|
+
function buildReferencedFilesSection(workspaceFileRefs) {
|
|
331
|
+
return ("## Referenced Files\n\n" +
|
|
314
332
|
"The user has highlighted the following workspace paths for your " +
|
|
315
|
-
`attention. Use \`${ENGINE_TOOL.readFile}\` to access file contents.\n\n
|
|
316
|
-
|
|
317
|
-
section += `- \`${refPath}\`\n`;
|
|
318
|
-
}
|
|
319
|
-
return section;
|
|
333
|
+
`attention. Use \`${ENGINE_TOOL.readFile}\` to access file contents.\n\n` +
|
|
334
|
+
workspaceFileRefs.map((refPath) => `- \`${refPath}\``).join("\n"));
|
|
320
335
|
}
|
|
321
336
|
/**
|
|
322
|
-
* The `## Input Files`
|
|
323
|
-
* file-reading tool) around the shared lines
|
|
324
|
-
* says what each bullet and disclosure
|
|
325
|
-
* group is set off by a blank line, the
|
|
337
|
+
* The `## Input Files` part of the turn's message: this harness's intro (it
|
|
338
|
+
* names this engine's file-reading tool) around the shared lines
|
|
339
|
+
* (`prompt-sections.ts` `inputFileLines` says what each bullet and disclosure
|
|
340
|
+
* carries and why). Each disclosure group is set off by a blank line, the
|
|
341
|
+
* markdown idiom.
|
|
326
342
|
*/
|
|
327
343
|
function buildInputFilesSection(files, vision, downloadUrlKind) {
|
|
328
|
-
let section = "
|
|
344
|
+
let section = "## Input Files\n\n";
|
|
329
345
|
section +=
|
|
330
346
|
"The following files have been provided as read-only reference " +
|
|
331
347
|
"material for your task. They live under `.stigmer/inputs/` and " +
|
|
@@ -344,8 +360,7 @@ function buildInputFilesSection(files, vision, downloadUrlKind) {
|
|
|
344
360
|
if (lines.vision.length > 0) {
|
|
345
361
|
section += "\n" + lines.vision.join("\n") + "\n";
|
|
346
362
|
}
|
|
347
|
-
//
|
|
348
|
-
// ends on its last line rather than adding a second blank (#1127).
|
|
363
|
+
// The part ends on its last line; the message's rule sets it off (#1127).
|
|
349
364
|
return section.replace(/\n+$/, "");
|
|
350
365
|
}
|
|
351
366
|
//# sourceMappingURL=prompt-builder.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt-builder.js","sourceRoot":"","sources":["../../../src/activities/execute-deep-agent/prompt-builder.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"prompt-builder.js","sourceRoot":"","sources":["../../../src/activities/execute-deep-agent/prompt-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,8DAA8D,CAAC;AAE/F,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AAKrF,OAAO,EACL,cAAc,EACd,uBAAuB,GAGxB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EAAE,2BAA2B,EAAE,MAAM,uCAAuC,CAAC;AAGpF,OAAO,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AACjF,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,cAAc,GAAG;;;;gCAIS,WAAW,CAAC,QAAQ;;;;;;;;;;;;;;yDAcK,CAAC;AAE1D,4EAA4E;AAC5E,2EAA2E;AAE3E;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,SAAS,YAAY,CAAC,eAA4C;IAChE,MAAM,QAAQ,GACZ,eAAe,KAAK,eAAe,CAAC,IAAI;QACtC,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,wCAAwC,WAAW,CAAC,OAAO,qBAAqB,CAAC;IACvF,OAAO;;;;0FAIiF,QAAQ;;4EAEtB,WAAW,CAAC,QAAQ;;;;;;;YAOpF,sBAAsB;oEACkC,CAAC;AACrE,CAAC;AA0FD;;;;;GAKG;AACH,MAAM,yBAAyB,GAAwC;IACrE,qBAAqB,EAAE,qBAAqB;IAC5C,sBAAsB,EAAE,sBAAsB;IAC9C,mBAAmB,EAAE,kBAAkB;IACvC,iBAAiB,EAAE,iBAAiB;IACpC,uBAAuB,EAAE,+BAA+B;CACzD,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,KAAyB;IACjE,IAAI,MAAM,GAAG,qBAAqB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IAEvD,MAAM,gBAAgB,GAAG,2BAA2B,CAClD,KAAK,CAAC,gBAAgB,EACtB,KAAK,CAAC,aAAa,CACpB,CAAC;IACF,IAAI,gBAAgB,EAAE,CAAC;QACrB,MAAM,IAAI,gBAAgB,CAAC;IAC7B,CAAC;IAED,IAAI,KAAK,CAAC,mBAAmB,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC;IACtC,CAAC;IAED,IAAI,KAAK,CAAC,6BAA6B,EAAE,CAAC;QACxC,MAAM,IAAI,MAAM,GAAG,KAAK,CAAC,6BAA6B,CAAC;IACzD,CAAC;IAED,0EAA0E;IAC1E,wEAAwE;IACxE,KAAK,MAAM,OAAO,IAAI,uBAAuB,CAAC,KAAK,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,UAAU,yBAAyB,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC;IACnF,CAAC;IAED,MAAM,IAAI,cAAc,CAAC;IACzB,MAAM,IAAI,YAAY,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IAE9C,wEAAwE;IACxE,yEAAyE;IACzE,wEAAwE;IACxE,qDAAqD;IACrD,IAAI,KAAK,CAAC,eAAe,KAAK,eAAe,CAAC,IAAI,EAAE,CAAC;QACnD,0EAA0E;QAC1E,wEAAwE;QACxE,sEAAsE;QACtE,oEAAoE;QACpE,yEAAyE;QACzE,qBAAqB;QACrB,MAAM;YACJ,sBAAsB;gBACtB,mBAAmB;gBACnB,8DAA8D;gBAC9D,uDAAuD,CAAC;IAC5D,CAAC;IAED,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;QACxB,MAAM;YACJ,wCAAwC;gBACxC,2BAA2B,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACxD,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AA0BD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAuB;IACxD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;IAC5F,CAAC;IACD,IAAI,KAAK,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvC,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;IACnE,CAAC;IACD,IAAI,KAAK,CAAC,mBAAmB,EAAE,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;IACvE,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC1B,OAAO,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AACnC,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAgC;IAClE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEnC,MAAM,KAAK,GAAa;QACtB,EAAE;QACF,EAAE;QACF,WAAW;QACX,EAAE;QACF,2EAA2E;YAC3E,4BAA4B;QAC5B,EAAE;QACF,kEAAkE;YAClE,UAAU,WAAW,CAAC,QAAQ,mDAAmD;YACjF,sCAAsC;QACtC,EAAE;QACF,oBAAoB;QACpB,EAAE;QACF,8DAA8D;QAC9D,qDAAqD;QACrD,8CAA8C;QAC9C,EAAE;QACF,KAAK,WAAW,CAAC,QAAQ,2CAA2C;QACpE,KAAK,WAAW,CAAC,OAAO,+CAA+C;QACvE,EAAE;KACH,CAAC;IAEF,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAChC,KAAK,CAAC,IAAI,CAAC,oBAAoB,KAAK,CAAC,WAAW,IAAI,kBAAkB,EAAE,CAAC,CAAC;QAC1E,KAAK,CAAC,IAAI,CAAC,mBAAmB,QAAQ,KAAK,CAAC,CAAC;QAC7C,KAAK,CAAC,IAAI,CAAC,mBAAmB,WAAW,CAAC,QAAQ,WAAW,QAAQ,aAAa,CAAC,CAAC;QACpF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,sFAAsF;AACtF,SAAS,UAAU,CAAC,KAAoB;IACtC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC1C,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,uBAAuB,WAAW,KAAK,CAAC,IAAI,EAAE,CAAC;AACpG,CAAC;AAED,SAAS,2BAA2B,CAChC,gBAAmC,EACnC,aAAqB;IAEvB,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAE7C,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,2BAA2B,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,0BAA0B,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC;AACrE,CAAC;AAED,SAAS,2BAA2B,CAAC,MAAuB;IAC1D,IAAI,CAAC,MAAM,CAAC,oBAAoB;QAAE,OAAO,EAAE,CAAC;IAE5C,IAAI,OAAO,GAAG,sBAAsB,GAAG,MAAM,CAAC,oBAAoB,CAAC;IACnE,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,OAAO,IAAI,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC;IACtC,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,0BAA0B,CACjC,OAA0B,EAC1B,aAAqB;IAErB,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,SAAS,CAAC;IAErD,IAAI,OAAO,GACT,sBAAsB;QACtB,oBAAoB,OAAO,CAAC,MAAM,yBAAyB;QAC3D,kEAAkE;QAClE,4CAA4C,UAAU,kBAAkB,CAAC;IAE3E,yEAAyE;IACzE,yCAAyC;IACzC,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC;QAC9C,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,IAAI,SAAS,GAAG,GAAG,CAAC,EAAE,CAAC;QACrD,MAAM,OAAO,GAAG,qBAAqB,CAAC,MAAM,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;QACrE,OAAO,IAAI,WAAW,KAAK,OAAO,OAAO,SAAS,CAAC;QACnD,OAAO,IAAI,sBAAsB,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACpB,OAAO,IAAI,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC;QACtC,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,qBAAqB,CAAC,OAAe,EAAE,aAAqB;IACnE,IAAI,CAAC,aAAa;QAAE,OAAO,OAAO,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QAC7C,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,OAAO,CAAC;QACzC,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED,SAAS,sBAAsB,CAAC,MAAuB;IACrD,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,IAAI,YAAY,CAAC;IAE9C,IAAI,MAAM,CAAC,UAAU,KAAK,YAAY,EAAE,CAAC;QACvC,OAAO,CACL,qBAAqB,IAAI,uCAAuC;YAChE,+DAA+D;YAC/D,qEAAqE,CACtE,CAAC;IACJ,CAAC;IAED,wEAAwE;IACxE,8DAA8D;IAC9D,mEAAmE;IACnE,IAAI,MAAM,CAAC,UAAU,KAAK,UAAU,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QAC3D,MAAM,IAAI,GAAgB,MAAM,CAAC,WAAW,CAAC;QAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,OAAO,CACL,qBAAqB,IAAI,2BAA2B,IAAI,CAAC,OAAO,GAAG,MAAM,KAAK;YAC9E,0EAA0E,CAC3E,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,CAAC,UAAU,KAAK,OAAO,EAAE,CAAC;QAClC,OAAO,CACL,qBAAqB,IAAI,6BAA6B;YACtD,uDAAuD,CACxD,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC,oBAAoB,CAAC;AACrC,CAAC;AAED,6GAA6G;AAC7G,SAAS,2BAA2B,CAAC,iBAAoC;IACvE,OAAO,CACL,yBAAyB;QACzB,kEAAkE;QAClE,oBAAoB,WAAW,CAAC,QAAQ,iCAAiC;QACzE,iBAAiB,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAClE,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,sBAAsB,CAC7B,KAAoC,EACpC,MAAyB,EACzB,eAAiC;IAEjC,IAAI,OAAO,GAAG,oBAAoB,CAAC;IACnC,OAAO;QACL,gEAAgE;YAChE,iEAAiE;YACjE,8CAA8C;YAC9C,oBAAoB,WAAW,CAAC,QAAQ,mCAAmC;YAC3E,oEAAoE;YACpE,8CAA8C;YAC9C,0CAA0C,CAAC;IAE7C,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;IAC7D,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAClC,OAAO,IAAI,GAAG,KAAK,IAAI,CAAC;IAC1B,CAAC;IACD,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACnC,OAAO,IAAI,IAAI,GAAG,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC;IAC5C,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,IAAI,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACnD,CAAC;IAED,0EAA0E;IAC1E,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACrC,CAAC"}
|
|
@@ -155,16 +155,6 @@ export declare function connectTools(input: TurnInput, sink: TurnSink): Promise<
|
|
|
155
155
|
* the gate. Both flow into sub-agents via the shared gate config.
|
|
156
156
|
*/
|
|
157
157
|
export declare function readGateState(input: TurnInput, tools: DeepAgentTools): DeepAgentGateState;
|
|
158
|
-
/**
|
|
159
|
-
* The `## Skills` section of the root prompt: the skills the shared selection
|
|
160
|
-
* highlights for this turn's message (`shared/prompt-sections.ts`
|
|
161
|
-
* `selectSkillsForPrompt`: every skill below the threshold, the relevant ones
|
|
162
|
-
* at and above it), rendered with this engine's activation protocol, plus —
|
|
163
|
-
* when the selection left any out — an `### Also Available` note naming them
|
|
164
|
-
* (the sentence is the shared, tool-neutral one; the heading is this
|
|
165
|
-
* harness's markdown framing).
|
|
166
|
-
*/
|
|
167
|
-
export declare function renderRootSkillsSection(input: TurnInput): string;
|
|
168
158
|
/**
|
|
169
159
|
* The system prompt over the runtime's resolved record: every input the
|
|
170
160
|
* builder renders is read from `TurnInput` here, in one place, so the mapping
|
|
@@ -173,8 +163,22 @@ export declare function renderRootSkillsSection(input: TurnInput): string;
|
|
|
173
163
|
* that is not on the record is the memoized memory selection, which the
|
|
174
164
|
* caller awaits (the runtime stamps the report on the status the first time
|
|
175
165
|
* it is pulled, before this turn's first persist).
|
|
166
|
+
*
|
|
167
|
+
* Nothing here reads the turn's message or payload: the system prompt is the
|
|
168
|
+
* session's (`prompt-builder.ts` says why), so every mounted skill is
|
|
169
|
+
* described and the turn's files ride its message (`composeTurnMessage`).
|
|
170
|
+
* The approved plan's path is the one fact taken from the attachments, and
|
|
171
|
+
* only on a build-from-plan turn, where the mode already changes the prompt.
|
|
176
172
|
*/
|
|
177
173
|
export declare function composeSystemPrompt(input: TurnInput, recalledMemories: RecalledMemoriesContent | undefined): string;
|
|
174
|
+
/**
|
|
175
|
+
* The turn's user message over the runtime's resolved record: what the user
|
|
176
|
+
* typed, with this turn's payload (its input files and referenced paths) and
|
|
177
|
+
* the conversation catchup composed around it (`prompt-builder.ts`
|
|
178
|
+
* `composeUserMessage`). The twin of `composeSystemPrompt` for the turn's
|
|
179
|
+
* half, so the goldens pin this mapping and not a copy of it.
|
|
180
|
+
*/
|
|
181
|
+
export declare function composeTurnMessage(input: TurnInput): string;
|
|
178
182
|
/**
|
|
179
183
|
* Build the engine: the model, the middleware stack with the gate, the
|
|
180
184
|
* tools, the compiled sub-agents, the system prompt and `createDeepAgent`.
|
|
@@ -204,9 +208,10 @@ export declare function buildEngine(input: TurnInput, sink: TurnSink, config: De
|
|
|
204
208
|
* What the graph is invoked with. The checkpoint is read once (on the
|
|
205
209
|
* durable http saver an extra `getState` is a network round-trip): pending
|
|
206
210
|
* interrupts that the runtime's decisions answer make a `Command(resume)`;
|
|
207
|
-
* anything else is the turn's user message —
|
|
208
|
-
* framed before it (
|
|
209
|
-
* checkpointer with the turn
|
|
211
|
+
* anything else is the turn's user message — this turn's payload and the
|
|
212
|
+
* conversation catchup framed before it (`composeTurnMessage`; in the USER
|
|
213
|
+
* MESSAGE so it enters the checkpointer with the turn and the system prompt
|
|
214
|
+
* stays the session's), the structured-output contract appended, and
|
|
210
215
|
* the inline images FIRST as content blocks when the turn carries any (per
|
|
211
216
|
* Anthropic's images-before-text guidance; a plain string otherwise).
|
|
212
217
|
*/
|
|
@@ -57,7 +57,8 @@ import { getDefaultModel, getNativeRequestProfile } from "../../shared/model-reg
|
|
|
57
57
|
import { buildChatModel } from "../../shared/model-client.js";
|
|
58
58
|
import { graphThinks, toAnthropicThinking } from "../../shared/thinking-mode.js";
|
|
59
59
|
import { isUnattendedApprovalMode } from "../../shared/approval-policy.js";
|
|
60
|
-
import {
|
|
60
|
+
import { visionPromptInfoOf } from "../../shared/prompt-sections.js";
|
|
61
|
+
import { findApprovedPlanPath } from "../../shared/implement-plan-prompt.js";
|
|
61
62
|
import { toLangChainImageBlocks } from "../../shared/attachment-vision.js";
|
|
62
63
|
import { resolveRecursionLimit, UNBOUNDED_ADVISORY_RECURSION_LIMIT } from "../../shared/tool-rounds.js";
|
|
63
64
|
import { jsonSchemaToZod } from "../../shared/json-schema-to-zod.js";
|
|
@@ -171,23 +172,6 @@ export function readGateState(input, tools) {
|
|
|
171
172
|
unattendedSkips: new Set(),
|
|
172
173
|
};
|
|
173
174
|
}
|
|
174
|
-
/**
|
|
175
|
-
* The `## Skills` section of the root prompt: the skills the shared selection
|
|
176
|
-
* highlights for this turn's message (`shared/prompt-sections.ts`
|
|
177
|
-
* `selectSkillsForPrompt`: every skill below the threshold, the relevant ones
|
|
178
|
-
* at and above it), rendered with this engine's activation protocol, plus —
|
|
179
|
-
* when the selection left any out — an `### Also Available` note naming them
|
|
180
|
-
* (the sentence is the shared, tool-neutral one; the heading is this
|
|
181
|
-
* harness's markdown framing).
|
|
182
|
-
*/
|
|
183
|
-
export function renderRootSkillsSection(input) {
|
|
184
|
-
const { highlighted, alsoAvailable } = selectSkillsForPrompt(input.execution.spec?.message ?? "", input.skills.root);
|
|
185
|
-
if (alsoAvailable.length === 0)
|
|
186
|
-
return renderSkillsSection(highlighted);
|
|
187
|
-
console.log(`[turn-setup] Skill relevance filter: ${highlighted.length} included, ` +
|
|
188
|
-
`${alsoAvailable.length} excluded: ${alsoAvailable.join(", ")}`);
|
|
189
|
-
return renderSkillsSection(highlighted) + "\n### Also Available\n\n" + alsoAvailableSkillsNote(alsoAvailable) + "\n";
|
|
190
|
-
}
|
|
191
175
|
/**
|
|
192
176
|
* The system prompt over the runtime's resolved record: every input the
|
|
193
177
|
* builder renders is read from `TurnInput` here, in one place, so the mapping
|
|
@@ -196,6 +180,12 @@ export function renderRootSkillsSection(input) {
|
|
|
196
180
|
* that is not on the record is the memoized memory selection, which the
|
|
197
181
|
* caller awaits (the runtime stamps the report on the status the first time
|
|
198
182
|
* it is pulled, before this turn's first persist).
|
|
183
|
+
*
|
|
184
|
+
* Nothing here reads the turn's message or payload: the system prompt is the
|
|
185
|
+
* session's (`prompt-builder.ts` says why), so every mounted skill is
|
|
186
|
+
* described and the turn's files ride its message (`composeTurnMessage`).
|
|
187
|
+
* The approved plan's path is the one fact taken from the attachments, and
|
|
188
|
+
* only on a build-from-plan turn, where the mode already changes the prompt.
|
|
199
189
|
*/
|
|
200
190
|
export function composeSystemPrompt(input, recalledMemories) {
|
|
201
191
|
const spec = input.execution.spec;
|
|
@@ -205,19 +195,17 @@ export function composeSystemPrompt(input, recalledMemories) {
|
|
|
205
195
|
instructions: input.blueprint.instructions,
|
|
206
196
|
provisionResults: input.workspace.provision.provisionResults,
|
|
207
197
|
containerRoot: primaryDir,
|
|
208
|
-
skillsPromptSection:
|
|
198
|
+
skillsPromptSection: renderSkillsSection(input.skills.root),
|
|
209
199
|
// "" (nothing sendable) threads as undefined: the tool alone still serves
|
|
210
200
|
// text sends inside a 24-hour window (DD-006 D6).
|
|
211
201
|
channelTemplatesPromptSection: input.mcp.channelMessaging.length > 0
|
|
212
202
|
? formatChannelTemplatesSection(input.mcp.channelMessaging) || undefined
|
|
213
203
|
: undefined,
|
|
214
|
-
workspaceFileRefs: spec.workspaceFileRefs ?? [],
|
|
215
|
-
workspaceRoot: primaryDir,
|
|
216
|
-
inputFiles: input.attachments.results,
|
|
217
|
-
vision: visionPromptInfoOf(input.attachments),
|
|
218
|
-
downloadUrlKind: input.artifactStorage?.downloadUrlKind,
|
|
219
204
|
interactionMode: execConfig?.interactionMode,
|
|
220
205
|
buildFromPlan: execConfig?.buildFromPlan,
|
|
206
|
+
...(execConfig?.buildFromPlan
|
|
207
|
+
? { approvedPlanPath: findApprovedPlanPath(input.attachments.results.map((f) => f.relativePath)) }
|
|
208
|
+
: {}),
|
|
221
209
|
contextBridge: input.standing.contextBridge,
|
|
222
210
|
senderIdentity: input.standing.senderIdentity,
|
|
223
211
|
sessionContext: input.standing.sessionContext,
|
|
@@ -225,6 +213,24 @@ export function composeSystemPrompt(input, recalledMemories) {
|
|
|
225
213
|
recalledMemories,
|
|
226
214
|
});
|
|
227
215
|
}
|
|
216
|
+
/**
|
|
217
|
+
* The turn's user message over the runtime's resolved record: what the user
|
|
218
|
+
* typed, with this turn's payload (its input files and referenced paths) and
|
|
219
|
+
* the conversation catchup composed around it (`prompt-builder.ts`
|
|
220
|
+
* `composeUserMessage`). The twin of `composeSystemPrompt` for the turn's
|
|
221
|
+
* half, so the goldens pin this mapping and not a copy of it.
|
|
222
|
+
*/
|
|
223
|
+
export function composeTurnMessage(input) {
|
|
224
|
+
const spec = input.execution.spec;
|
|
225
|
+
return composeUserMessage({
|
|
226
|
+
message: spec.message,
|
|
227
|
+
conversationCatchup: input.standing.conversationCatchup,
|
|
228
|
+
inputFiles: input.attachments.results,
|
|
229
|
+
vision: visionPromptInfoOf(input.attachments),
|
|
230
|
+
downloadUrlKind: input.artifactStorage?.downloadUrlKind,
|
|
231
|
+
workspaceFileRefs: spec.workspaceFileRefs ?? [],
|
|
232
|
+
});
|
|
233
|
+
}
|
|
228
234
|
/**
|
|
229
235
|
* Build the engine: the model, the middleware stack with the gate, the
|
|
230
236
|
* tools, the compiled sub-agents, the system prompt and `createDeepAgent`.
|
|
@@ -456,9 +462,10 @@ export async function buildEngine(input, sink, config, args) {
|
|
|
456
462
|
* What the graph is invoked with. The checkpoint is read once (on the
|
|
457
463
|
* durable http saver an extra `getState` is a network round-trip): pending
|
|
458
464
|
* interrupts that the runtime's decisions answer make a `Command(resume)`;
|
|
459
|
-
* anything else is the turn's user message —
|
|
460
|
-
* framed before it (
|
|
461
|
-
* checkpointer with the turn
|
|
465
|
+
* anything else is the turn's user message — this turn's payload and the
|
|
466
|
+
* conversation catchup framed before it (`composeTurnMessage`; in the USER
|
|
467
|
+
* MESSAGE so it enters the checkpointer with the turn and the system prompt
|
|
468
|
+
* stays the session's), the structured-output contract appended, and
|
|
462
469
|
* the inline images FIRST as content blocks when the turn carries any (per
|
|
463
470
|
* Anthropic's images-before-text guidance; a plain string otherwise).
|
|
464
471
|
*/
|
|
@@ -468,8 +475,7 @@ export async function composeGraphInput(input, engine) {
|
|
|
468
475
|
if (resume.isResumeFromApproval) {
|
|
469
476
|
return { kind: "resume", command: resume.graphInput };
|
|
470
477
|
}
|
|
471
|
-
|
|
472
|
-
let userMessage = composeUserMessage(spec.message, input.standing.conversationCatchup);
|
|
478
|
+
let userMessage = composeTurnMessage(input);
|
|
473
479
|
if (engine.hasStructuredOutput) {
|
|
474
480
|
userMessage += `\n\n---\nIMPORTANT: When your analysis is complete, provide your findings as structured output matching the required schema. The system will capture your structured response automatically.`;
|
|
475
481
|
}
|