@stigmer/runner 3.11.1-dev.20260812192248 → 3.12.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/dist/.build-fingerprint +1 -1
- package/dist/activities/execute-cursor/attachment-resolver.d.ts +11 -0
- package/dist/activities/execute-cursor/attachment-resolver.js +8 -0
- package/dist/activities/execute-cursor/attachment-resolver.js.map +1 -1
- package/dist/activities/execute-cursor/blueprint-resolver.d.ts +1 -9
- package/dist/activities/execute-cursor/blueprint-resolver.js +0 -1
- package/dist/activities/execute-cursor/blueprint-resolver.js.map +1 -1
- package/dist/activities/execute-cursor/index.d.ts +6 -2
- package/dist/activities/execute-cursor/index.js +16 -32
- package/dist/activities/execute-cursor/index.js.map +1 -1
- package/dist/activities/execute-cursor/prompt-builder.d.ts +15 -11
- package/dist/activities/execute-cursor/prompt-builder.js +20 -10
- package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
- package/dist/activities/execute-deep-agent/attachment-injector.d.ts +34 -8
- package/dist/activities/execute-deep-agent/attachment-injector.js +111 -106
- package/dist/activities/execute-deep-agent/attachment-injector.js.map +1 -1
- package/dist/activities/execute-deep-agent/index.js +0 -15
- package/dist/activities/execute-deep-agent/index.js.map +1 -1
- package/dist/activities/execute-deep-agent/mcp-gate.d.ts +0 -2
- package/dist/activities/execute-deep-agent/mcp-gate.js +0 -1
- package/dist/activities/execute-deep-agent/mcp-gate.js.map +1 -1
- package/dist/activities/execute-deep-agent/prompt-builder.d.ts +7 -8
- package/dist/activities/execute-deep-agent/prompt-builder.js +25 -8
- package/dist/activities/execute-deep-agent/prompt-builder.js.map +1 -1
- package/dist/activities/execute-deep-agent/setup.d.ts +0 -10
- package/dist/activities/execute-deep-agent/setup.js +13 -45
- package/dist/activities/execute-deep-agent/setup.js.map +1 -1
- package/dist/config.d.ts +6 -5
- package/dist/config.js.map +1 -1
- package/dist/middleware/path-normalization.d.ts +15 -2
- package/dist/middleware/path-normalization.js +39 -5
- package/dist/middleware/path-normalization.js.map +1 -1
- package/dist/shared/artifact-storage.d.ts +11 -0
- package/dist/shared/artifact-storage.js +2 -0
- package/dist/shared/artifact-storage.js.map +1 -1
- package/dist/shared/attachment-download-urls.d.ts +62 -0
- package/dist/shared/attachment-download-urls.js +79 -0
- package/dist/shared/attachment-download-urls.js.map +1 -0
- package/dist/shared/channel-attachment.d.ts +1 -1
- package/dist/shared/channel-attachment.js +1 -1
- package/dist/shared/conversation-attachment.d.ts +2 -3
- package/dist/shared/conversation-attachment.js +2 -3
- package/dist/shared/conversation-attachment.js.map +1 -1
- package/dist/shared/mcp-enabled-tools.d.ts +6 -2
- package/dist/shared/mcp-enabled-tools.js +6 -2
- package/dist/shared/mcp-enabled-tools.js.map +1 -1
- package/dist/shared/mcp-transport-guard.d.ts +2 -2
- package/dist/shared/mcp-transport-guard.js +2 -2
- package/dist/shared/plan-mode-permissions.d.ts +46 -10
- package/dist/shared/plan-mode-permissions.js +56 -12
- package/dist/shared/plan-mode-permissions.js.map +1 -1
- package/dist/shared/synthesized-attachment.d.ts +4 -4
- package/dist/shared/synthesized-attachment.js +4 -4
- package/dist/shared/zip-extract.d.ts +24 -6
- package/dist/shared/zip-extract.js +31 -90
- package/dist/shared/zip-extract.js.map +1 -1
- package/dist/shared/zip-structure.d.ts +61 -0
- package/dist/shared/zip-structure.js +128 -0
- package/dist/shared/zip-structure.js.map +1 -0
- package/package.json +2 -2
- package/src/__test-utils__/fake-artifact-storage.ts +10 -1
- package/src/__test-utils__/zip-fixtures.ts +206 -0
- package/src/activities/execute-cursor/__tests__/attachment-resolver.test.ts +63 -3
- package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +62 -29
- package/src/activities/execute-cursor/__tests__/skill-resolver.test.ts +3 -42
- package/src/activities/execute-cursor/attachment-resolver.ts +24 -0
- package/src/activities/execute-cursor/blueprint-resolver.ts +1 -10
- package/src/activities/execute-cursor/index.ts +22 -37
- package/src/activities/execute-cursor/prompt-builder.ts +38 -22
- package/src/activities/execute-deep-agent/__tests__/attachment-injector.test.ts +270 -126
- package/src/activities/execute-deep-agent/__tests__/hitl-reject.test.ts +0 -2
- package/src/activities/execute-deep-agent/__tests__/hitl-resume-approve-all.test.ts +0 -1
- package/src/activities/execute-deep-agent/__tests__/hitl-resume-history.test.ts +0 -1
- package/src/activities/execute-deep-agent/__tests__/mcp-gate.test.ts +2 -7
- package/src/activities/execute-deep-agent/__tests__/plan-mode-path-normalization.test.ts +246 -37
- package/src/activities/execute-deep-agent/__tests__/prompt-builder.test.ts +78 -2
- package/src/activities/execute-deep-agent/__tests__/sequential-gate-resume.test.ts +0 -1
- package/src/activities/execute-deep-agent/__tests__/subagent-plan-mode-permissions.test.ts +35 -4
- package/src/activities/execute-deep-agent/attachment-injector.ts +166 -143
- package/src/activities/execute-deep-agent/index.ts +0 -19
- package/src/activities/execute-deep-agent/mcp-gate.ts +0 -3
- package/src/activities/execute-deep-agent/prompt-builder.ts +38 -16
- package/src/activities/execute-deep-agent/setup.ts +13 -68
- package/src/config.ts +6 -5
- package/src/middleware/__tests__/path-normalization.test.ts +29 -3
- package/src/middleware/path-normalization.ts +42 -5
- package/src/shared/__tests__/artifact-storage.test.ts +9 -0
- package/src/shared/__tests__/attachment-download-urls.test.ts +70 -0
- package/src/shared/__tests__/channel-attachment.test.ts +2 -2
- package/src/shared/__tests__/plan-mode-permissions.test.ts +58 -0
- package/src/shared/__tests__/synthesized-attachment.test.ts +19 -41
- package/src/shared/__tests__/zip-extract.test.ts +106 -89
- package/src/shared/artifact-storage.ts +11 -0
- package/src/shared/attachment-download-urls.ts +98 -0
- package/src/shared/channel-attachment.ts +1 -1
- package/src/shared/conversation-attachment.ts +2 -3
- package/src/shared/mcp-enabled-tools.ts +6 -2
- package/src/shared/mcp-transport-guard.ts +2 -2
- package/src/shared/plan-mode-permissions.ts +59 -12
- package/src/shared/synthesized-attachment.ts +4 -4
- package/src/shared/zip-extract.ts +35 -117
- package/src/shared/zip-structure.ts +181 -0
- package/dist/shared/datastore-attachment.d.ts +0 -99
- package/dist/shared/datastore-attachment.js +0 -184
- package/dist/shared/datastore-attachment.js.map +0 -1
- package/src/activities/execute-deep-agent/__tests__/datastore-degradation.test.ts +0 -104
- package/src/shared/__tests__/datastore-attachment.test.ts +0 -293
- package/src/shared/datastore-attachment.ts +0 -209
|
@@ -72,7 +72,6 @@ import { StreamingUpdateScheduler, loadStreamingConfig } from "../../shared/stre
|
|
|
72
72
|
import { createCursorEventRecorder } from "./cursor-event-recorder.js";
|
|
73
73
|
import { resolveMcpServers, toCursorMcpConfig, validateMcpServerEnv } from "./mcp-resolver.js";
|
|
74
74
|
import { resolveMcpTransportPosture } from "../../shared/mcp-transport-guard.js";
|
|
75
|
-
import { synthesizeDatastoreAttachment } from "../../shared/datastore-attachment.js";
|
|
76
75
|
import {
|
|
77
76
|
discoverChannelMessaging,
|
|
78
77
|
synthesizeChannelAttachment,
|
|
@@ -665,35 +664,16 @@ async function executeCursorInner(
|
|
|
665
664
|
?? config.stigmerTokenRef?.current
|
|
666
665
|
?? config.stigmerToken;
|
|
667
666
|
|
|
668
|
-
// Phase 4a2: Synthesize the
|
|
669
|
-
// Deliberately AFTER resolve + backfill: the attachment has
|
|
670
|
-
// McpServerUsage and reports discovered capabilities, so the
|
|
671
|
-
// backfill's destructiveHint tightener can never force-gate
|
|
672
|
-
//
|
|
673
|
-
//
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
backendEndpoint: config.stigmerBackendEndpoint,
|
|
679
|
-
});
|
|
680
|
-
if (attachment) {
|
|
681
|
-
const resolvedServers = injectSynthesizedAttachment(
|
|
682
|
-
mcpResolution.resolvedServers, attachment, "datastore records",
|
|
683
|
-
);
|
|
684
|
-
mcpResolution = {
|
|
685
|
-
resolvedServers,
|
|
686
|
-
cursorConfig: toCursorMcpConfig(resolvedServers),
|
|
687
|
-
};
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
// Phase 4a3: Synthesize the channel messaging attachment (DD-006
|
|
692
|
-
// D7/D8), the records attachment's twin. The discovery read is the
|
|
693
|
-
// attachment decision — the control plane runs the SAME candidate
|
|
694
|
-
// computation the send authorization uses — and every failure mode
|
|
695
|
-
// (no channel, OSS, registry down, pre-3a control plane) degrades
|
|
696
|
-
// to honest absence: no tool, no section, execution unharmed.
|
|
667
|
+
// Phase 4a2: Synthesize the channel messaging attachment (DD-006
|
|
668
|
+
// D7/D8). Deliberately AFTER resolve + backfill: the attachment has
|
|
669
|
+
// no McpServerUsage and reports discovered capabilities, so the
|
|
670
|
+
// backfill's destructiveHint tightener can never force-gate its
|
|
671
|
+
// tools; empty approval maps keep it approval-free by construction.
|
|
672
|
+
// The discovery read is the attachment decision — the control plane
|
|
673
|
+
// runs the SAME candidate computation the send authorization uses —
|
|
674
|
+
// and every failure mode (no channel, OSS, registry down, pre-3a
|
|
675
|
+
// control plane) degrades to honest absence: no tool, no section,
|
|
676
|
+
// execution unharmed.
|
|
697
677
|
const channelMessaging = await discoverChannelMessaging(client, exchangedRunnerToken);
|
|
698
678
|
if (channelMessaging.length > 0) {
|
|
699
679
|
const attachment = synthesizeChannelAttachment(channelMessaging, {
|
|
@@ -802,6 +782,7 @@ async function executeCursorInner(
|
|
|
802
782
|
const attachmentEntries = attachmentResults.map((a) => ({
|
|
803
783
|
path: a.relativePath,
|
|
804
784
|
...(a.renamedFrom !== undefined ? { renamedFrom: a.renamedFrom } : {}),
|
|
785
|
+
...(a.downloadUrl !== undefined ? { downloadUrl: a.downloadUrl } : {}),
|
|
805
786
|
}));
|
|
806
787
|
// Vision facts, derived once from the single resolution result: the
|
|
807
788
|
// images the model will see inline (in attachment order) and the ones
|
|
@@ -1147,13 +1128,13 @@ async function executeCursorInner(
|
|
|
1147
1128
|
instructions: blueprint.instructions,
|
|
1148
1129
|
userMessage: spec.message,
|
|
1149
1130
|
skills: skillMetadata,
|
|
1150
|
-
datastoreUsages: blueprint.datastoreUsages,
|
|
1151
1131
|
channelMessaging,
|
|
1152
1132
|
subAgents: blueprint.subAgents,
|
|
1153
1133
|
workspaceDirs: blueprint.workspaceDirs,
|
|
1154
1134
|
workspaceFileRefs: spec.workspaceFileRefs ?? [],
|
|
1155
1135
|
attachments: attachmentEntries,
|
|
1156
1136
|
vision: visionPromptInfo,
|
|
1137
|
+
downloadUrlKind: artifactStorage?.downloadUrlKind,
|
|
1157
1138
|
pendingApprovals: adjudicatedApprovals,
|
|
1158
1139
|
appliedToolCallIds,
|
|
1159
1140
|
interactionMode,
|
|
@@ -1821,13 +1802,13 @@ async function executeCursorInner(
|
|
|
1821
1802
|
instructions: blueprint.instructions,
|
|
1822
1803
|
userMessage: spec.message,
|
|
1823
1804
|
skills: skillMetadata,
|
|
1824
|
-
datastoreUsages: blueprint.datastoreUsages,
|
|
1825
1805
|
channelMessaging,
|
|
1826
1806
|
subAgents: blueprint.subAgents,
|
|
1827
1807
|
workspaceDirs: blueprint.workspaceDirs,
|
|
1828
1808
|
workspaceFileRefs: spec.workspaceFileRefs ?? [],
|
|
1829
1809
|
attachments: attachmentEntries,
|
|
1830
1810
|
vision: visionPromptInfo,
|
|
1811
|
+
downloadUrlKind: artifactStorage?.downloadUrlKind,
|
|
1831
1812
|
pendingApprovals: adjudicatedApprovals,
|
|
1832
1813
|
// Without the applied set, the HITL-recovery prompt would tell
|
|
1833
1814
|
// the fresh agent to carry out writes the runner already
|
|
@@ -2367,8 +2348,6 @@ export interface BuildPromptInput {
|
|
|
2367
2348
|
instructions: string;
|
|
2368
2349
|
userMessage: string;
|
|
2369
2350
|
skills: import("./prompt-builder.js").SkillMetadata[];
|
|
2370
|
-
/** Datastores attached via `datastore_usages` — the `<available_datastores>` section. */
|
|
2371
|
-
datastoreUsages?: import("@stigmer/protos/ai/stigmer/agentic/agent/v1/spec_pb").DatastoreUsage[];
|
|
2372
2351
|
/**
|
|
2373
2352
|
* Serving proactive channels + their templates (the DD-006 D2
|
|
2374
2353
|
* discovery read) — the `<available_channel_templates>` section.
|
|
@@ -2388,6 +2367,12 @@ export interface BuildPromptInput {
|
|
|
2388
2367
|
* catchup — it rides both the enhanced prompt and a resumed turn's prefix.
|
|
2389
2368
|
*/
|
|
2390
2369
|
vision?: import("./prompt-builder.js").VisionPromptInfo;
|
|
2370
|
+
/**
|
|
2371
|
+
* What kind of URL the turn's storage backend mints (issue #532) — keys
|
|
2372
|
+
* the input-files hand-off wording. Sourced from the resolved
|
|
2373
|
+
* artifactStorage's self-description; absent when no storage resolved.
|
|
2374
|
+
*/
|
|
2375
|
+
downloadUrlKind?: import("../../shared/attachment-download-urls.js").DownloadUrlKind;
|
|
2391
2376
|
pendingApprovals: import("@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/approval_pb").PendingApproval[];
|
|
2392
2377
|
/**
|
|
2393
2378
|
* Approved whole-file writes the runner already applied itself (exact-apply).
|
|
@@ -2546,13 +2531,13 @@ export function buildPrompt(input: BuildPromptInput): string {
|
|
|
2546
2531
|
instructions,
|
|
2547
2532
|
userMessage,
|
|
2548
2533
|
skills,
|
|
2549
|
-
datastoreUsages: input.datastoreUsages ?? [],
|
|
2550
2534
|
channelMessaging: input.channelMessaging ?? [],
|
|
2551
2535
|
subAgents,
|
|
2552
2536
|
workspaceDirs,
|
|
2553
2537
|
workspaceFileRefs,
|
|
2554
2538
|
attachments,
|
|
2555
2539
|
vision: input.vision,
|
|
2540
|
+
downloadUrlKind: input.downloadUrlKind,
|
|
2556
2541
|
interactionMode,
|
|
2557
2542
|
buildFromPlan,
|
|
2558
2543
|
contextBridge: input.contextBridge,
|
|
@@ -2594,7 +2579,7 @@ export function buildPrompt(input: BuildPromptInput): string {
|
|
|
2594
2579
|
formatInteractionModePrefix(interactionMode),
|
|
2595
2580
|
formatImplementPlanSection(buildFromPlan, attachments),
|
|
2596
2581
|
attachments.length > 0
|
|
2597
|
-
? formatInputFiles(attachments, input.vision)
|
|
2582
|
+
? formatInputFiles(attachments, input.vision, input.downloadUrlKind)
|
|
2598
2583
|
: undefined,
|
|
2599
2584
|
conversationCatchup !== undefined
|
|
2600
2585
|
? formatConversationCatchupSection(conversationCatchup)
|
|
@@ -2612,13 +2597,13 @@ export function buildPrompt(input: BuildPromptInput): string {
|
|
|
2612
2597
|
instructions,
|
|
2613
2598
|
userMessage,
|
|
2614
2599
|
skills,
|
|
2615
|
-
datastoreUsages: input.datastoreUsages ?? [],
|
|
2616
2600
|
channelMessaging: input.channelMessaging ?? [],
|
|
2617
2601
|
subAgents,
|
|
2618
2602
|
workspaceDirs,
|
|
2619
2603
|
workspaceFileRefs,
|
|
2620
2604
|
attachments,
|
|
2621
2605
|
vision: input.vision,
|
|
2606
|
+
downloadUrlKind: input.downloadUrlKind,
|
|
2622
2607
|
interactionMode,
|
|
2623
2608
|
buildFromPlan,
|
|
2624
2609
|
contextBridge: input.contextBridge,
|
|
@@ -17,12 +17,11 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import { resolve } from "node:path";
|
|
20
|
-
import type {
|
|
20
|
+
import type { SubAgent } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/spec_pb";
|
|
21
21
|
import type { PendingApproval } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/approval_pb";
|
|
22
22
|
import { ApprovalAction, InteractionMode } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
23
23
|
import { formatContextBridgeText } from "../../shared/context-bridge.js";
|
|
24
24
|
import { formatConversationCatchupText } from "../../shared/conversation-catchup.js";
|
|
25
|
-
import { formatDatastoresSection } from "../../shared/datastore-attachment.js";
|
|
26
25
|
import {
|
|
27
26
|
formatChannelTemplatesSection,
|
|
28
27
|
type ChannelMessagingInfo,
|
|
@@ -36,6 +35,10 @@ import {
|
|
|
36
35
|
visionDisclosureLines,
|
|
37
36
|
type NotViewableEntry,
|
|
38
37
|
} from "../../shared/attachment-vision.js";
|
|
38
|
+
import {
|
|
39
|
+
downloadUrlDisclosureLine,
|
|
40
|
+
type DownloadUrlKind,
|
|
41
|
+
} from "../../shared/attachment-download-urls.js";
|
|
39
42
|
import { formatTurnRecoveryText } from "./turn-recovery.js";
|
|
40
43
|
import { PLAN_MODE_DIRECTIVE } from "../../shared/plan-mode-prompt.js";
|
|
41
44
|
import {
|
|
@@ -82,21 +85,18 @@ export interface AttachmentPromptEntry {
|
|
|
82
85
|
path: string;
|
|
83
86
|
/** Original filename, present only when a duplicate name was renamed. */
|
|
84
87
|
renamedFrom?: string;
|
|
88
|
+
/**
|
|
89
|
+
* Download URL for the attachment's stored object, when one was minted
|
|
90
|
+
* (shared/attachment-download-urls.ts) — rendered beside the path so the
|
|
91
|
+
* agent can hand the file to tools that cannot read this filesystem.
|
|
92
|
+
*/
|
|
93
|
+
downloadUrl?: string;
|
|
85
94
|
}
|
|
86
95
|
|
|
87
96
|
export interface EnhancedPromptOptions {
|
|
88
97
|
instructions: string;
|
|
89
98
|
userMessage: string;
|
|
90
99
|
skills: SkillMetadata[];
|
|
91
|
-
/**
|
|
92
|
-
* Datastores attached via `datastore_usages` — rendered as the
|
|
93
|
-
* `<available_datastores>` section (DD-005 SD-5, skills precedent)
|
|
94
|
-
* pointing the model at the synthesized record tools. Always the healthy
|
|
95
|
-
* rendering here: the Cursor SDK connects MCP itself, so this harness can
|
|
96
|
-
* never observe the live roster — the section's standing
|
|
97
|
-
* failure-disclosure instruction is its whole coverage (issue #325).
|
|
98
|
-
*/
|
|
99
|
-
datastoreUsages?: DatastoreUsage[];
|
|
100
100
|
/**
|
|
101
101
|
* Serving proactive channels + their approved templates — rendered as
|
|
102
102
|
* the `<available_channel_templates>` section (proactive-messaging
|
|
@@ -109,6 +109,12 @@ export interface EnhancedPromptOptions {
|
|
|
109
109
|
attachments: AttachmentPromptEntry[];
|
|
110
110
|
/** Inline/degraded image facts for the input-files section (T04 vision). */
|
|
111
111
|
vision?: VisionPromptInfo;
|
|
112
|
+
/**
|
|
113
|
+
* What kind of URL the turn's storage backend mints — keys the input-files
|
|
114
|
+
* section's hand-off wording (attachment-download-urls.ts). One turn-level
|
|
115
|
+
* fact: all attachments ride the one configured storage.
|
|
116
|
+
*/
|
|
117
|
+
downloadUrlKind?: DownloadUrlKind;
|
|
112
118
|
interactionMode?: InteractionMode;
|
|
113
119
|
/**
|
|
114
120
|
* The execution is a Build-from-plan turn (spec.execution_config
|
|
@@ -183,10 +189,6 @@ export function buildEnhancedPrompt(options: EnhancedPromptOptions): string {
|
|
|
183
189
|
sections.push(formatSkillsSection(options.skills));
|
|
184
190
|
}
|
|
185
191
|
|
|
186
|
-
if (options.datastoreUsages !== undefined && options.datastoreUsages.length > 0) {
|
|
187
|
-
sections.push(formatDatastoresSection(options.datastoreUsages));
|
|
188
|
-
}
|
|
189
|
-
|
|
190
192
|
if (options.channelMessaging !== undefined && options.channelMessaging.length > 0) {
|
|
191
193
|
// "" when nothing is sendable — the tool alone still serves text
|
|
192
194
|
// sends inside a 24-hour window (DD-006 D6).
|
|
@@ -212,7 +214,7 @@ export function buildEnhancedPrompt(options: EnhancedPromptOptions): string {
|
|
|
212
214
|
}
|
|
213
215
|
|
|
214
216
|
if (options.attachments.length > 0) {
|
|
215
|
-
sections.push(formatInputFiles(options.attachments, options.vision));
|
|
217
|
+
sections.push(formatInputFiles(options.attachments, options.vision, options.downloadUrlKind));
|
|
216
218
|
}
|
|
217
219
|
|
|
218
220
|
if (options.workspaceFileRefs.length > 0) {
|
|
@@ -548,15 +550,28 @@ export function formatWorkspaceContext(dirs: string[]): string {
|
|
|
548
550
|
export function formatInputFiles(
|
|
549
551
|
attachments: readonly AttachmentPromptEntry[],
|
|
550
552
|
vision?: VisionPromptInfo,
|
|
553
|
+
downloadUrlKind?: DownloadUrlKind,
|
|
551
554
|
): string {
|
|
552
555
|
// A duplicate-renamed file (attachment-naming.ts) discloses its original
|
|
553
556
|
// name so the agent can connect "the two report.pdfs" in the user's
|
|
554
|
-
// message to distinct files on disk.
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
557
|
+
// message to distinct files on disk. A file with a minted download URL
|
|
558
|
+
// (attachment-download-urls.ts) lists it beside the path for the remote
|
|
559
|
+
// hand-off story.
|
|
560
|
+
const entries = attachments.map((a) => {
|
|
561
|
+
const rename =
|
|
562
|
+
a.renamedFrom !== undefined
|
|
563
|
+
? ` (renamed from duplicate '${a.renamedFrom}')`
|
|
564
|
+
: "";
|
|
565
|
+
const url = a.downloadUrl !== undefined ? ` — download URL: ${a.downloadUrl}` : "";
|
|
566
|
+
return `- \`${a.path}\`${rename}${url}`;
|
|
567
|
+
});
|
|
568
|
+
// The URL hand-off line (shared wording, attachment-download-urls.ts)
|
|
569
|
+
// renders only when some listed file actually carries a URL — its wording
|
|
570
|
+
// keys on what kind of URL the storage backend mints.
|
|
571
|
+
const urlDisclosure =
|
|
572
|
+
downloadUrlKind !== undefined && attachments.some((a) => a.downloadUrl !== undefined)
|
|
573
|
+
? [downloadUrlDisclosureLine(downloadUrlKind)]
|
|
574
|
+
: [];
|
|
560
575
|
// The vision lines (shared wording, attachment-vision.ts) tell the model
|
|
561
576
|
// which of these files it can already SEE inline versus which degraded to
|
|
562
577
|
// path-only — without them an agent silently ignores a photo the user
|
|
@@ -568,6 +583,7 @@ export function formatInputFiles(
|
|
|
568
583
|
"<input_files>",
|
|
569
584
|
"The following files have been provided as inputs. Read them when relevant to the task:",
|
|
570
585
|
...entries,
|
|
586
|
+
...urlDisclosure,
|
|
571
587
|
...disclosure,
|
|
572
588
|
"</input_files>",
|
|
573
589
|
].join("\n");
|