@borgee/agents-host 0.2.35 → 0.2.56
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 +23 -27
- package/dist/agents-host.d.ts +28 -5
- package/dist/agents-host.js +274 -236
- package/dist/chat/chat-control-plane.d.ts +3 -0
- package/dist/chat/sdk-chat-control-plane.d.ts +4 -3
- package/dist/chat/sdk-chat-control-plane.js +6 -0
- package/dist/cli.js +1 -5
- package/dist/compatibility-gates.d.ts +4 -0
- package/dist/compatibility-gates.js +18 -1
- package/dist/context/claude-file-brief.d.ts +2 -0
- package/dist/context/claude-file-brief.js +83 -0
- package/dist/context/compaction.d.ts +20 -0
- package/dist/context/compaction.js +59 -0
- package/dist/context/injection.d.ts +44 -9
- package/dist/context/injection.js +360 -53
- package/dist/context/main-session-delegation.d.ts +1 -1
- package/dist/context/projection-strategy.d.ts +24 -0
- package/dist/context/projection-strategy.js +90 -0
- package/dist/context/prompt.d.ts +16 -1
- package/dist/context/prompt.js +475 -53
- package/dist/context/resolved-workspace.d.ts +2 -0
- package/dist/context/resolved-workspace.js +64 -0
- package/dist/context/skill-manual.d.ts +14 -0
- package/dist/context/skill-manual.js +21 -0
- package/dist/context/turn-preparation.d.ts +8 -2
- package/dist/context/turn-preparation.js +68 -17
- package/dist/gateway/localhost-gateway.js +18 -8
- package/dist/hosted-turn-content.d.ts +15 -0
- package/dist/hosted-turn-content.js +50 -0
- package/dist/managed-daemon.d.ts +3 -2
- package/dist/managed-daemon.js +198 -37
- package/dist/plugin-sdk.js +276 -359
- package/dist/plugin-sdk.js.map +4 -4
- package/dist/progress-to-activity.d.ts +16 -0
- package/dist/progress-to-activity.js +24 -0
- package/dist/projection-strategy-values.d.ts +4 -0
- package/dist/projection-strategy-values.js +28 -0
- package/dist/providers/acp-progress-collector.d.ts +44 -0
- package/dist/providers/acp-progress-collector.js +130 -0
- package/dist/providers/awaiting-user.d.ts +2 -3
- package/dist/providers/awaiting-user.js +5 -7
- package/dist/providers/claude/activity-metadata.d.ts +14 -0
- package/dist/providers/claude/activity-metadata.js +81 -0
- package/dist/providers/claude/adapter.d.ts +3 -1
- package/dist/providers/claude/adapter.js +10 -0
- package/dist/providers/claude/cli-client.d.ts +9 -1
- package/dist/providers/claude/cli-client.js +270 -126
- package/dist/providers/codex/adapter.d.ts +3 -1
- package/dist/providers/codex/adapter.js +10 -0
- package/dist/providers/codex/cli-client.d.ts +10 -2
- package/dist/providers/codex/cli-client.js +88 -104
- package/dist/providers/codex/project-doc.js +22 -37
- package/dist/providers/copilot/adapter.d.ts +3 -1
- package/dist/providers/copilot/adapter.js +10 -0
- package/dist/providers/copilot/cli-client.d.ts +9 -1
- package/dist/providers/copilot/cli-client.js +68 -85
- package/dist/providers/create-provider.d.ts +3 -1
- package/dist/providers/create-provider.js +36 -9
- package/dist/providers/provider-adapter.d.ts +35 -0
- package/dist/providers/provider-adapter.js +44 -1
- package/dist/state-paths.d.ts +10 -2
- package/dist/state-paths.js +25 -6
- package/dist/task-thread-resolution.d.ts +3 -2
- package/dist/types.d.ts +163 -8
- package/package.json +2 -2
- package/skills/borgee-agent/SKILL.md +127 -38
- package/skills/borgee-agent/references/errors.md +38 -0
- package/skills/borgee-agent/references/task-properties.md +33 -0
- package/skills/borgee-agent/scripts/borgee-agent.mjs +553 -0
- package/skills/borgee-agent/scripts/borgee-agent.py +547 -0
- package/dist/durable-cursor-store.d.ts +0 -5
- package/dist/durable-cursor-store.js +0 -7
- package/skills/borgee-agent/borgee-agent.mjs +0 -562
- package/skills/borgee-agent/borgee-agent.py +0 -469
package/dist/context/prompt.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import { DEFAULT_PROJECTION_STRATEGY, normalizeProjectionStrategy, } from '../projection-strategy-values.js';
|
|
1
2
|
import { AWAITING_USER_CONTROL_PREFIX } from '../providers/awaiting-user.js';
|
|
2
3
|
import { buildAttentionSummaryLines } from './attention.js';
|
|
3
4
|
import { buildCollaborationCapabilityDeclarationSummaryLines, buildMissedCollaborationDiagnosticSummaryLines, } from './collaboration-capabilities-diagnostics.js';
|
|
4
5
|
import { buildCollaborationOutcomeSummaryLines } from './collaboration-outcome.js';
|
|
5
6
|
import { MAIN_SESSION_DELEGATION_LINES } from './main-session-delegation.js';
|
|
7
|
+
import { buildResolvedWorkspaceGuidanceLines } from './resolved-workspace.js';
|
|
8
|
+
import { buildSkillManualLines, buildSkillManualReadLine } from './skill-manual.js';
|
|
6
9
|
import { buildTaskThreadCollaborationSummaryLines } from './task-thread-collaboration.js';
|
|
7
10
|
function providerLabel(provider) {
|
|
8
11
|
if (provider === 'copilot') {
|
|
@@ -13,50 +16,61 @@ function providerLabel(provider) {
|
|
|
13
16
|
}
|
|
14
17
|
return 'Claude';
|
|
15
18
|
}
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
// Claude and Codex name the manual once on their session-scoped surfaces. Copilot has no
|
|
20
|
+
// session-scoped surface — this prompt is its only model-facing text — so for Copilot alone the
|
|
21
|
+
// pointer rides every turn.
|
|
22
|
+
function buildSkillManualPromptLines(provider, context) {
|
|
23
|
+
if (provider !== 'copilot' || !context?.skillRuntime || !context.gatewayCredentialPath) {
|
|
18
24
|
return [];
|
|
19
25
|
}
|
|
20
|
-
return [
|
|
21
|
-
'',
|
|
22
|
-
'Read-only local skill runtime bootstrap is available for this turn.',
|
|
23
|
-
`Channel context payload: ${context.channelContextPayloadPath}`,
|
|
24
|
-
`Skill guide: ${context.skillRuntime.skillMarkdownPath}`,
|
|
25
|
-
`Node CLI: node ${context.skillRuntime.nodeCliPath} --context ${context.channelContextPayloadPath} --print-bootstrap`,
|
|
26
|
-
`Python CLI: python3 ${context.skillRuntime.pythonCliPath} --context ${context.channelContextPayloadPath} --print-bootstrap`,
|
|
27
|
-
'These CLIs are local-only, may only access the loopback gateway described below, must not mutate files or the local environment, and may only send auxiliary collaboration messages when that gateway surface is explicitly advertised below.',
|
|
28
|
-
];
|
|
26
|
+
return ['', ...buildSkillManualLines(context.skillRuntime)];
|
|
29
27
|
}
|
|
28
|
+
// Only the facts that change from turn to turn: which credential file authorizes this turn, which
|
|
29
|
+
// task grammar the thread shape licenses, and whether the collaboration commands can be reached at
|
|
30
|
+
// all. Everything else a model needs to invoke the CLI is in the manual, which does not change.
|
|
30
31
|
function buildLocalhostGatewayPromptLines(context) {
|
|
31
32
|
if (!context?.localhostGateway) {
|
|
32
33
|
return [];
|
|
33
34
|
}
|
|
34
|
-
if (!context.
|
|
35
|
+
if (!context.gatewayCredentialPath) {
|
|
35
36
|
return [];
|
|
36
37
|
}
|
|
37
|
-
const lines = [
|
|
38
|
-
'',
|
|
39
|
-
'A loopback-only localhost gateway is available for this turn.',
|
|
40
|
-
'Use the packaged local CLI with the existing --context payload to access the documented gateway surface.',
|
|
41
|
-
`Gateway auth sidecar for this turn: ${context.gatewayAuthPath}`,
|
|
42
|
-
];
|
|
43
|
-
const isTaskAssignmentThread = context.taskAssignmentContext?.active === true;
|
|
38
|
+
const lines = ['', `Gateway credential file for this turn: ${context.gatewayCredentialPath}`];
|
|
44
39
|
if (!context.skillRuntime) {
|
|
45
40
|
return lines;
|
|
46
41
|
}
|
|
47
|
-
lines.push(
|
|
48
|
-
|
|
49
|
-
|
|
42
|
+
lines.push(context.taskAssignmentContext?.active === true
|
|
43
|
+
? 'This turn runs inside a task assignment thread.'
|
|
44
|
+
: 'This turn runs in a parent channel, not a task thread.');
|
|
45
|
+
if (context.runtimeSurface?.task.currentThread === 'parent-channel'
|
|
46
|
+
&& (context.collaborationTurnMode ?? 'ordinary') === 'ordinary') {
|
|
47
|
+
if (context.runtimeSurface.task.parentChannelTaskCollection === 'available') {
|
|
48
|
+
lines.push('Task list and task create are available in this parent channel.');
|
|
49
|
+
lines.push(`For parent-channel task operations on this turn, read the packaged borgee-agent manual at ${context.skillRuntime.skillMarkdownPath} and follow that command grammar exactly.`);
|
|
50
|
+
lines.push('For task creation and task updates in this parent channel, use the packaged borgee-agent task rail through this gateway credential file.');
|
|
51
|
+
lines.push('Do not invent a bare task or bare borgee command.');
|
|
52
|
+
}
|
|
53
|
+
if (context.runtimeSurface.task.currentTaskShorthand === 'requires-task-id') {
|
|
54
|
+
lines.push('In this parent channel, task get, task update, task history, and task property commands require an explicit task id.');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else if (context.runtimeSurface?.task.currentThread === 'task-assignment-thread'
|
|
58
|
+
&& (context.collaborationTurnMode ?? 'ordinary') === 'ordinary') {
|
|
59
|
+
lines.push('In this task thread, task list and task create stay on the parent channel.');
|
|
50
60
|
}
|
|
51
|
-
|
|
52
|
-
|
|
61
|
+
const collaborationLive = context.localhostGateway.collaboration?.enabled === true
|
|
62
|
+
&& (context.collaborationTurnMode ?? 'ordinary') === 'ordinary';
|
|
63
|
+
if (!collaborationLive) {
|
|
64
|
+
lines.push('Auxiliary collaboration commands (users, draft, send, mention) are not available this turn.');
|
|
65
|
+
}
|
|
66
|
+
else if (context.collaborationTurnExecutionId) {
|
|
67
|
+
lines.push(`Pass --turn-execution-id ${context.collaborationTurnExecutionId} on send, mention and draft.`);
|
|
68
|
+
}
|
|
69
|
+
if (context.runtimeSurface?.response.mainVisibleReply === 'model-visible-reply') {
|
|
70
|
+
lines.push('Keep the main visible completion in this thread.');
|
|
53
71
|
}
|
|
54
|
-
if (context.
|
|
55
|
-
(
|
|
56
|
-
const turnExecutionArgument = context.collaborationTurnExecutionId
|
|
57
|
-
? ` --turn-execution-id ${context.collaborationTurnExecutionId}`
|
|
58
|
-
: '';
|
|
59
|
-
lines.push('Auxiliary collaboration commands are available for this turn. Use them only for short targeted escalation, mention, or reply notices, never for the main final answer body.', 'When you need the host-private in-flight draft for this live collaboration turn, use the dedicated read-draft command rather than inspecting public channel messages.', 'When --list-users is listed below, it is a read-only command for this turn and may be executed directly without asking for permission.', 'When the user explicitly asks you to mention, ping, notify, or send a short note to another visible participant, use the dedicated send-mention command directly and include a visible <@targetId> token in the body.', 'If the user asks you to @ another agent now, send the short auxiliary mention first, then confirm what you sent.', 'If the user says "the other agent" and only one other visible agent is present, resolve that target from --list-users and then use --send-mention with that participant id.', 'If collaboration with another visible agent would help, use these auxiliary commands to send a short targeted mention or reply-thread note yourself rather than asking AgentsHost to orchestrate a special protocol.', `Node private draft snapshot: node ${context.skillRuntime.nodeCliPath} --context ${context.channelContextPayloadPath} --auth-path ${context.gatewayAuthPath}${turnExecutionArgument} --read-draft`, `Node user directory: node ${context.skillRuntime.nodeCliPath} --context ${context.channelContextPayloadPath} --auth-path ${context.gatewayAuthPath} --list-users`, `Node auxiliary mention: node ${context.skillRuntime.nodeCliPath} --context ${context.channelContextPayloadPath} --auth-path ${context.gatewayAuthPath}${turnExecutionArgument} --send-mention user-id --body "Need review from <@user-id>"`, `Node reply thread notice: node ${context.skillRuntime.nodeCliPath} --context ${context.channelContextPayloadPath} --auth-path ${context.gatewayAuthPath}${turnExecutionArgument} --send-message --body "Following up here" --reply-to message-id`, `Python private draft snapshot: python3 ${context.skillRuntime.pythonCliPath} --context ${context.channelContextPayloadPath} --auth-path ${context.gatewayAuthPath}${turnExecutionArgument} --read-draft`, `Python user directory: python3 ${context.skillRuntime.pythonCliPath} --context ${context.channelContextPayloadPath} --auth-path ${context.gatewayAuthPath} --list-users`, `Python auxiliary mention: python3 ${context.skillRuntime.pythonCliPath} --context ${context.channelContextPayloadPath} --auth-path ${context.gatewayAuthPath}${turnExecutionArgument} --send-mention user-id --body "Need review from <@user-id>"`, `Python reply thread notice: python3 ${context.skillRuntime.pythonCliPath} --context ${context.channelContextPayloadPath} --auth-path ${context.gatewayAuthPath}${turnExecutionArgument} --send-message --body "Following up here" --reply-to message-id`);
|
|
72
|
+
if (context.runtimeSurface?.response.auxiliaryMessageUsage === 'targeted-escalation-only') {
|
|
73
|
+
lines.push('Use auxiliary sends only for intentional targeted escalation, mention, or reply notices when the injected runtimeSurface allows them.');
|
|
60
74
|
}
|
|
61
75
|
return lines;
|
|
62
76
|
}
|
|
@@ -66,6 +80,12 @@ function buildTaskAssignmentPromptLines(params) {
|
|
|
66
80
|
if (!isTaskAssignmentTurn && taskAssignmentContext?.active !== true) {
|
|
67
81
|
return [];
|
|
68
82
|
}
|
|
83
|
+
if (params.provider === 'claude'
|
|
84
|
+
&& params.forceInlineForClaude !== true
|
|
85
|
+
&& !isTaskAssignmentTurn
|
|
86
|
+
&& taskAssignmentContext?.active === true) {
|
|
87
|
+
return [];
|
|
88
|
+
}
|
|
69
89
|
const lines = isTaskAssignmentTurn
|
|
70
90
|
? [
|
|
71
91
|
'This message is a task assignment.',
|
|
@@ -75,21 +95,167 @@ function buildTaskAssignmentPromptLines(params) {
|
|
|
75
95
|
'This thread is continuing an existing task assignment.',
|
|
76
96
|
'Keep the main work in this thread.',
|
|
77
97
|
];
|
|
78
|
-
if (
|
|
98
|
+
if ((params.provider !== 'claude' || params.forceInlineForClaude === true) && params.promptContext?.resolvedWorkspace) {
|
|
99
|
+
lines.push(...buildResolvedWorkspacePromptLines(params.provider, params.promptContext));
|
|
100
|
+
}
|
|
101
|
+
if ((params.provider !== 'claude' || params.forceInlineForClaude === true) && taskAssignmentContext?.currentTaskId) {
|
|
79
102
|
lines.push(`Current assigned task id: ${taskAssignmentContext.currentTaskId}.`);
|
|
80
|
-
lines.push('Inside this task thread, the packaged Node and Python CLIs may omit --task-id for --get-task and --update-task because the current task id is already persisted in the injected thread context.');
|
|
81
|
-
if (params.promptContext?.taskWorkspace) {
|
|
82
|
-
lines.push(`Task-scoped writable workspace root: ${params.promptContext.taskWorkspace.rootPath}.`);
|
|
83
|
-
lines.push('This writable workspace is local to agents-host for the current task thread. It does not imply that the target repository has already been checked out there.');
|
|
84
|
-
}
|
|
85
103
|
}
|
|
86
|
-
else if (taskAssignmentContext?.active === true) {
|
|
104
|
+
else if ((params.provider !== 'claude' || params.forceInlineForClaude === true) && taskAssignmentContext?.active === true) {
|
|
87
105
|
lines.push('No current task id is persisted in the injected thread context for this task thread.');
|
|
88
|
-
lines.push('Inside this task thread, shorthand --get-task/--update-task calls without --task-id use an agents-host local fallback that scans visible parent-channel tasks for this thread; pass --task-id explicitly if that fallback cannot resolve a unique task.');
|
|
89
106
|
}
|
|
90
|
-
|
|
107
|
+
if (params.provider !== 'claude' || params.forceInlineForClaude === true) {
|
|
108
|
+
lines.push('Return your normal final response in this thread, and do not move the main work back to the parent channel.');
|
|
109
|
+
}
|
|
110
|
+
return lines;
|
|
111
|
+
}
|
|
112
|
+
function buildResolvedWorkspacePromptLines(provider, context) {
|
|
113
|
+
return buildResolvedWorkspaceGuidanceLines(context, provider);
|
|
114
|
+
}
|
|
115
|
+
function buildClaudeOrdinaryGatewayTaskLines(context) {
|
|
116
|
+
if (!context?.skillRuntime || !context.localhostGateway || !context.gatewayCredentialPath) {
|
|
117
|
+
return [];
|
|
118
|
+
}
|
|
119
|
+
if ((context.collaborationTurnMode ?? 'ordinary') !== 'ordinary') {
|
|
120
|
+
return [];
|
|
121
|
+
}
|
|
122
|
+
if (context.runtimeSurface?.task.currentThread !== 'parent-channel') {
|
|
123
|
+
return [];
|
|
124
|
+
}
|
|
125
|
+
if (context.runtimeSurface.task.parentChannelTaskCollection !== 'available') {
|
|
126
|
+
return [];
|
|
127
|
+
}
|
|
128
|
+
const lines = [
|
|
129
|
+
`Gateway credential file for this turn: ${context.gatewayCredentialPath}`,
|
|
130
|
+
'This turn runs in a parent channel, not a task thread.',
|
|
131
|
+
'Task list and task create are available in this parent channel.',
|
|
132
|
+
`For parent-channel task operations on this turn, read the packaged borgee-agent manual at ${context.skillRuntime.skillMarkdownPath} and follow that command grammar exactly.`,
|
|
133
|
+
'For task creation and task updates in this parent channel, use the packaged borgee-agent task rail through this gateway credential file.',
|
|
134
|
+
'Do not invent a bare task or bare borgee command.',
|
|
135
|
+
];
|
|
136
|
+
if (context.runtimeSurface.task.currentTaskShorthand === 'requires-task-id') {
|
|
137
|
+
lines.push('In this parent channel, task get, task update, task history, and task property commands require an explicit task id.');
|
|
138
|
+
}
|
|
91
139
|
return lines;
|
|
92
140
|
}
|
|
141
|
+
function buildClaudeProjectedBriefSessionLines(context) {
|
|
142
|
+
if (!context?.claudeProjectedBriefPath) {
|
|
143
|
+
return [];
|
|
144
|
+
}
|
|
145
|
+
const lines = [
|
|
146
|
+
`Read the stable Borgee runtime brief for this session at ${context.claudeProjectedBriefPath} before you act on this channel; it is authoritative for the stable platform rules on this channel.`,
|
|
147
|
+
];
|
|
148
|
+
if (context.skillRuntime) {
|
|
149
|
+
lines.push(`For command grammar and CLI inventory, read the packaged borgee-agent manual at ${context.skillRuntime.skillMarkdownPath}.`);
|
|
150
|
+
}
|
|
151
|
+
lines.push(...buildClaudeOrdinarySessionControlLines());
|
|
152
|
+
return lines;
|
|
153
|
+
}
|
|
154
|
+
function buildClaudeProjectedBriefTurnDeltaLines(context) {
|
|
155
|
+
if (!context?.localhostGateway || !context.gatewayCredentialPath) {
|
|
156
|
+
return [];
|
|
157
|
+
}
|
|
158
|
+
const lines = [];
|
|
159
|
+
if ((context.collaborationTurnMode ?? 'ordinary') !== 'ordinary') {
|
|
160
|
+
return [`Gateway credential file for this turn: ${context.gatewayCredentialPath}`];
|
|
161
|
+
}
|
|
162
|
+
if (context.runtimeSurface?.task.currentThread === 'parent-channel') {
|
|
163
|
+
const taskLines = buildClaudeOrdinaryGatewayTaskLines(context);
|
|
164
|
+
if (taskLines.length > 0) {
|
|
165
|
+
lines.push(...taskLines);
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
lines.push(`Gateway credential file for this turn: ${context.gatewayCredentialPath}`, 'This turn runs in a parent channel, not a task thread.');
|
|
169
|
+
if (context.runtimeSurface.task.parentChannelTaskCollection === 'available') {
|
|
170
|
+
lines.push('Task list and task create are available in this parent channel.');
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
else if (context.runtimeSurface?.task.currentThread === 'task-assignment-thread') {
|
|
175
|
+
lines.push(`Gateway credential file for this turn: ${context.gatewayCredentialPath}`, 'This turn runs inside a task assignment thread.', 'In this task thread, task list and task create stay on the parent channel.');
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
lines.push(`Gateway credential file for this turn: ${context.gatewayCredentialPath}`);
|
|
179
|
+
}
|
|
180
|
+
const collaborationLive = context.localhostGateway.collaboration?.enabled === true
|
|
181
|
+
&& (context.collaborationTurnMode ?? 'ordinary') === 'ordinary';
|
|
182
|
+
if (!collaborationLive) {
|
|
183
|
+
lines.push('Auxiliary collaboration commands (users, draft, send, mention) are not available this turn.');
|
|
184
|
+
}
|
|
185
|
+
else if (context.collaborationTurnExecutionId) {
|
|
186
|
+
lines.push(`Pass --turn-execution-id ${context.collaborationTurnExecutionId} on send, mention and draft.`);
|
|
187
|
+
}
|
|
188
|
+
if (context.runtimeSurface?.response.mainVisibleReply === 'model-visible-reply') {
|
|
189
|
+
lines.push('Keep the main visible completion in this thread.');
|
|
190
|
+
}
|
|
191
|
+
if (context.runtimeSurface?.response.auxiliaryMessageUsage === 'targeted-escalation-only') {
|
|
192
|
+
lines.push('Use auxiliary sends only for intentional targeted escalation, mention, or reply notices when the injected runtimeSurface allows them.');
|
|
193
|
+
}
|
|
194
|
+
return lines;
|
|
195
|
+
}
|
|
196
|
+
function buildClaudeProjectedBriefTurnPrompt(params) {
|
|
197
|
+
if (isClaudeZeroTurnFallbackRequired(params)) {
|
|
198
|
+
return buildClaudeZeroTurnPrompt(params);
|
|
199
|
+
}
|
|
200
|
+
if (!params.promptContext?.claudeProjectedBriefPath) {
|
|
201
|
+
return [
|
|
202
|
+
...buildClaudeTurnControlPromptLines(params.promptContext),
|
|
203
|
+
...buildPromptBodyLines({
|
|
204
|
+
provider: 'claude',
|
|
205
|
+
channelId: params.channelId,
|
|
206
|
+
incomingAuthorId: params.incomingAuthorId,
|
|
207
|
+
incomingContent: params.incomingContent,
|
|
208
|
+
incomingEventKind: params.incomingEventKind,
|
|
209
|
+
incomingMessageType: params.incomingMessageType,
|
|
210
|
+
promptContext: params.promptContext,
|
|
211
|
+
}),
|
|
212
|
+
].join('\n');
|
|
213
|
+
}
|
|
214
|
+
const deltaLines = buildClaudeProjectedBriefTurnDeltaLines(params.promptContext);
|
|
215
|
+
return [
|
|
216
|
+
...buildClaudeTurnControlPromptLines(params.promptContext),
|
|
217
|
+
`Channel: ${params.channelId}`,
|
|
218
|
+
...buildInboundMetadataLines({
|
|
219
|
+
provider: 'claude',
|
|
220
|
+
incomingEventKind: params.incomingEventKind,
|
|
221
|
+
incomingMessageType: params.incomingMessageType,
|
|
222
|
+
promptContext: params.promptContext,
|
|
223
|
+
}),
|
|
224
|
+
...(() => {
|
|
225
|
+
const lines = buildCollaborationOutcomeSummaryLines(params.promptContext?.collaborationOutcome);
|
|
226
|
+
return lines.length > 0 ? ['', ...lines] : [];
|
|
227
|
+
})(),
|
|
228
|
+
...(() => {
|
|
229
|
+
const lines = buildAttentionSummaryLines(params.promptContext?.attentionSnapshot);
|
|
230
|
+
return lines.length > 0 ? ['', ...lines] : [];
|
|
231
|
+
})(),
|
|
232
|
+
...(() => {
|
|
233
|
+
const lines = buildCollaborationCapabilityDeclarationSummaryLines(params.promptContext?.collaborationCapabilities);
|
|
234
|
+
return lines.length > 0 ? ['', ...lines] : [];
|
|
235
|
+
})(),
|
|
236
|
+
...(() => {
|
|
237
|
+
const lines = buildMissedCollaborationDiagnosticSummaryLines(params.promptContext?.missedCollaborationDiagnostic);
|
|
238
|
+
return lines.length > 0 ? ['', ...lines] : [];
|
|
239
|
+
})(),
|
|
240
|
+
...(deltaLines.length > 0 ? ['', ...deltaLines] : []),
|
|
241
|
+
'',
|
|
242
|
+
`New message from ${params.incomingAuthorId}:`,
|
|
243
|
+
params.incomingContent,
|
|
244
|
+
].join('\n');
|
|
245
|
+
}
|
|
246
|
+
function buildOrdinaryCopilotWorkspacePromptLines(params) {
|
|
247
|
+
if (params.provider !== 'copilot') {
|
|
248
|
+
return [];
|
|
249
|
+
}
|
|
250
|
+
if (!params.promptContext?.resolvedWorkspace) {
|
|
251
|
+
return [];
|
|
252
|
+
}
|
|
253
|
+
if (params.incomingMessageType?.trim() === 'task_assignment'
|
|
254
|
+
|| params.promptContext.taskAssignmentContext?.active === true) {
|
|
255
|
+
return [];
|
|
256
|
+
}
|
|
257
|
+
return buildResolvedWorkspacePromptLines(params.provider, params.promptContext);
|
|
258
|
+
}
|
|
93
259
|
function buildInboundMetadataLines(params) {
|
|
94
260
|
return [
|
|
95
261
|
`Incoming transport event kind: ${params.incomingEventKind?.trim() || 'message'}`,
|
|
@@ -98,7 +264,16 @@ function buildInboundMetadataLines(params) {
|
|
|
98
264
|
const lines = buildTaskThreadCollaborationSummaryLines(params.promptContext?.taskThreadCollaborationContract);
|
|
99
265
|
return lines.length > 0 ? ['', ...lines] : [];
|
|
100
266
|
})(),
|
|
101
|
-
...
|
|
267
|
+
...(() => {
|
|
268
|
+
const lines = buildOrdinaryCopilotWorkspacePromptLines(params);
|
|
269
|
+
return lines.length > 0 ? ['', ...lines] : [];
|
|
270
|
+
})(),
|
|
271
|
+
...buildTaskAssignmentPromptLines({
|
|
272
|
+
provider: params.provider,
|
|
273
|
+
incomingMessageType: params.incomingMessageType,
|
|
274
|
+
promptContext: params.promptContext,
|
|
275
|
+
forceInlineForClaude: params.forceClaudeTaskAssignmentInline,
|
|
276
|
+
}),
|
|
102
277
|
];
|
|
103
278
|
}
|
|
104
279
|
function describeIdentity(identity) {
|
|
@@ -109,7 +284,7 @@ function describeIdentity(identity) {
|
|
|
109
284
|
const label = name && name.length > 0 ? `${name} (${identity.id})` : identity.id;
|
|
110
285
|
return `${label}, kind=${identity.kind}`;
|
|
111
286
|
}
|
|
112
|
-
function
|
|
287
|
+
function buildTurnControlAttentionLines(context) {
|
|
113
288
|
const taskThreadAttentionAvailable = context?.taskAssignmentContext?.active === true
|
|
114
289
|
&& typeof context.taskAssignmentContext.currentTaskId === 'string'
|
|
115
290
|
&& context.taskAssignmentContext.currentTaskId.trim().length > 0;
|
|
@@ -135,6 +310,10 @@ function buildTurnControlPromptLines(context) {
|
|
|
135
310
|
`For an attention-only reply, keep a non-empty visible body and append: ${AWAITING_USER_CONTROL_PREFIX}{"kind":"attention-only","attentionUpdate":"follow-channel"}`,
|
|
136
311
|
]
|
|
137
312
|
: [];
|
|
313
|
+
return { attentionLines, attentionOnlyLine };
|
|
314
|
+
}
|
|
315
|
+
function buildTurnControlPromptLines(context) {
|
|
316
|
+
const { attentionLines, attentionOnlyLine } = buildTurnControlAttentionLines(context);
|
|
138
317
|
if (!context) {
|
|
139
318
|
return [
|
|
140
319
|
`Only when you need host-local turn control, append exactly one final non-empty line starting with ${AWAITING_USER_CONTROL_PREFIX}.`,
|
|
@@ -207,14 +386,69 @@ function buildTurnControlPromptLines(context) {
|
|
|
207
386
|
'Do not emit multiple control lines, and do not use a control footer for ordinary answers.',
|
|
208
387
|
];
|
|
209
388
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
389
|
+
function buildClaudeTurnControlPromptLines(context) {
|
|
390
|
+
const { attentionLines, attentionOnlyLine } = buildTurnControlAttentionLines(context);
|
|
391
|
+
if (context?.collaborationTurnMode === 'protocol-managed' && context.protocol) {
|
|
392
|
+
const selfIdentity = describeIdentity(context.grounding?.self);
|
|
393
|
+
const incomingIdentity = describeIdentity(context.grounding?.incomingAuthor);
|
|
394
|
+
const peerIdentity = describeIdentity(context.grounding?.peer);
|
|
395
|
+
return [
|
|
396
|
+
`Protocol-managed collaboration is already active for this turn. Your host-managed role is ${context.protocol.role}, and your target peer is ${context.protocol.targetPeerId}.`,
|
|
397
|
+
...(selfIdentity ? [`Your self identity for this turn: ${selfIdentity}.`] : []),
|
|
398
|
+
...(peerIdentity ? [`Your peer for this turn: ${peerIdentity}.`] : []),
|
|
399
|
+
...(incomingIdentity ? [`The incoming author for this turn is ${incomingIdentity}.`] : []),
|
|
400
|
+
'The host will deliver the visible protocol reply body for you; you only decide the body plus exactly one control footer.',
|
|
401
|
+
'Do not use auxiliary collaboration send commands during this turn, even if other turns can use them.',
|
|
402
|
+
'Do not attempt a localhost gateway message post during this turn.',
|
|
403
|
+
`When handing off to the named peer, use: ${AWAITING_USER_CONTROL_PREFIX}{"kind":"continue-to-peer"}`,
|
|
404
|
+
`When finishing locally, use: ${AWAITING_USER_CONTROL_PREFIX}{"kind":"conclude-locally"}`,
|
|
405
|
+
`If you are blocked on the human instead, use: ${AWAITING_USER_CONTROL_PREFIX}{"kind":"awaiting-user","question":"<short question>","reason":"<short reason>"}`,
|
|
406
|
+
...(context.attentionSnapshot
|
|
407
|
+
? ['You may add one attentionUpdate field to continue-to-peer, conclude-locally, or awaiting-user when you also need an attention change for this channel.']
|
|
408
|
+
: []),
|
|
409
|
+
...attentionLines,
|
|
410
|
+
'Do not use start-protocol while host-managed collaboration is already active.',
|
|
411
|
+
];
|
|
412
|
+
}
|
|
413
|
+
if (context?.collaborationTurnMode === 'silent-kickoff' && context.kickoff) {
|
|
414
|
+
const kickoff = context.kickoff;
|
|
415
|
+
const otherParticipantId = kickoff.participantIds.find((participantId) => participantId !== kickoff.issuerId);
|
|
416
|
+
const selfIdentity = describeIdentity(context.grounding?.self);
|
|
417
|
+
const incomingIdentity = describeIdentity(context.grounding?.incomingAuthor);
|
|
418
|
+
const peerIdentity = describeIdentity(context.grounding?.peer);
|
|
419
|
+
const participantSummary = context.grounding?.participants
|
|
420
|
+
?.map((participant) => describeIdentity(participant))
|
|
421
|
+
.filter((participant) => participant != null)
|
|
422
|
+
.join('; ');
|
|
423
|
+
return [
|
|
424
|
+
`Silent protocol kickoff evaluation is active for anchor ${kickoff.anchorMessageId}. The issuer is ${kickoff.issuerId}${otherParticipantId ? ` and the other participant is ${otherParticipantId}` : ''}.`,
|
|
425
|
+
...(context.grounding?.hostRecognizedKickoffCandidate
|
|
426
|
+
? [
|
|
427
|
+
'The host has already recognized this message as a structurally valid kickoff candidate and is asking you to decide whether host-managed collaboration should start.',
|
|
428
|
+
]
|
|
429
|
+
: []),
|
|
430
|
+
...(selfIdentity ? [`Your self identity for this decision: ${selfIdentity}.`] : []),
|
|
431
|
+
...(peerIdentity ? [`Your peer candidate for this decision: ${peerIdentity}.`] : []),
|
|
432
|
+
...(incomingIdentity
|
|
433
|
+
? [`The incoming author for this decision is ${incomingIdentity}.`]
|
|
434
|
+
: []),
|
|
435
|
+
...(participantSummary ? [`Visible kickoff participants: ${participantSummary}.`] : []),
|
|
436
|
+
'This evaluation is read-only and silent: do not use auxiliary collaboration send commands, and do not draft a user-visible reply body for this turn.',
|
|
437
|
+
`If the anchor message is genuinely requesting host-managed collaboration between the named agents, use: ${AWAITING_USER_CONTROL_PREFIX}{"kind":"start-protocol","rounds":<positive integer>}`,
|
|
438
|
+
'Do not combine start-protocol with any attentionUpdate field.',
|
|
439
|
+
'If collaboration should not start, omit the control footer entirely.',
|
|
440
|
+
];
|
|
441
|
+
}
|
|
442
|
+
return [
|
|
443
|
+
'Do not claim to have performed actions you did not actually perform.',
|
|
444
|
+
...(context?.attentionSnapshot
|
|
445
|
+
? ['You may add one attentionUpdate field to awaiting-user when you also need an attention change for this channel.']
|
|
446
|
+
: []),
|
|
447
|
+
...attentionLines,
|
|
448
|
+
...attentionOnlyLine,
|
|
449
|
+
];
|
|
450
|
+
}
|
|
451
|
+
function buildPromptHeaderLines(params) {
|
|
218
452
|
return [
|
|
219
453
|
`You are ${params.agentName}, a helpful AI teammate inside Borgee.`,
|
|
220
454
|
`Your current backend provider is ${providerLabel(params.provider)} (${params.provider}).`,
|
|
@@ -222,14 +456,34 @@ export function buildPrompt(params) {
|
|
|
222
456
|
'Be concise, helpful, and honest about uncertainty.',
|
|
223
457
|
'Do not claim to have performed actions you did not actually perform.',
|
|
224
458
|
'Keep the visible reply text concise.',
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
459
|
+
];
|
|
460
|
+
}
|
|
461
|
+
function buildProviderIdentityReminderLine(provider) {
|
|
462
|
+
return `If the user asks who you are, what powers you, or which backend/provider you use, mention that you are currently running on ${providerLabel(provider)}.`;
|
|
463
|
+
}
|
|
464
|
+
function buildSessionDelegationPromptLines(provider, context) {
|
|
465
|
+
if (provider === 'copilot') {
|
|
466
|
+
return MAIN_SESSION_DELEGATION_LINES;
|
|
467
|
+
}
|
|
468
|
+
return context?.skillRuntime ? [] : MAIN_SESSION_DELEGATION_LINES;
|
|
469
|
+
}
|
|
470
|
+
function buildClaudeOrdinarySessionControlLines() {
|
|
471
|
+
return [
|
|
472
|
+
`Only when you need host-local turn control, append exactly one final non-empty line starting with ${AWAITING_USER_CONTROL_PREFIX}.`,
|
|
473
|
+
`For ordinary blocked-on-human turns, use: ${AWAITING_USER_CONTROL_PREFIX}{"kind":"awaiting-user","question":"<short question>","reason":"<short reason>"}`,
|
|
474
|
+
'Do not emit multiple control lines.',
|
|
475
|
+
'Do not use a control footer for ordinary answers.',
|
|
476
|
+
];
|
|
477
|
+
}
|
|
478
|
+
function buildPromptBodyLines(params) {
|
|
479
|
+
return [
|
|
228
480
|
`Channel: ${params.channelId}`,
|
|
229
481
|
...buildInboundMetadataLines({
|
|
482
|
+
provider: params.provider,
|
|
230
483
|
incomingEventKind: params.incomingEventKind,
|
|
231
484
|
incomingMessageType: params.incomingMessageType,
|
|
232
485
|
promptContext: params.promptContext,
|
|
486
|
+
forceClaudeTaskAssignmentInline: params.forceClaudeTaskAssignmentInline,
|
|
233
487
|
}),
|
|
234
488
|
...(() => {
|
|
235
489
|
const lines = buildCollaborationOutcomeSummaryLines(params.promptContext?.collaborationOutcome);
|
|
@@ -247,10 +501,178 @@ export function buildPrompt(params) {
|
|
|
247
501
|
const lines = buildMissedCollaborationDiagnosticSummaryLines(params.promptContext?.missedCollaborationDiagnostic);
|
|
248
502
|
return lines.length > 0 ? ['', ...lines] : [];
|
|
249
503
|
})(),
|
|
250
|
-
...
|
|
504
|
+
...buildSkillManualPromptLines(params.provider, params.promptContext),
|
|
251
505
|
...buildLocalhostGatewayPromptLines(params.promptContext),
|
|
252
506
|
'',
|
|
253
507
|
`New message from ${params.incomingAuthorId}:`,
|
|
254
508
|
params.incomingContent,
|
|
509
|
+
];
|
|
510
|
+
}
|
|
511
|
+
function resolveProjectionStrategy(strategy) {
|
|
512
|
+
return normalizeProjectionStrategy(strategy) ?? DEFAULT_PROJECTION_STRATEGY;
|
|
513
|
+
}
|
|
514
|
+
function isClaudeZeroTurnFallbackRequired(params) {
|
|
515
|
+
return (params.incomingMessageType?.trim() === 'task_assignment'
|
|
516
|
+
|| params.promptContext?.collaborationTurnMode === 'protocol-managed'
|
|
517
|
+
|| params.promptContext?.collaborationTurnMode === 'silent-kickoff');
|
|
518
|
+
}
|
|
519
|
+
function buildClaudeLegacyTurnPrompt(params) {
|
|
520
|
+
const controlLines = params.promptContext?.collaborationTurnMode
|
|
521
|
+
&& params.promptContext.collaborationTurnMode !== 'ordinary'
|
|
522
|
+
? buildClaudeTurnControlPromptLines(params.promptContext)
|
|
523
|
+
: buildTurnControlPromptLines(params.promptContext);
|
|
524
|
+
const environmentLines = buildClaudeSessionEnvironmentLines(params.promptContext);
|
|
525
|
+
const sessionDelegationLines = params.promptContext?.skillRuntime ? [] : MAIN_SESSION_DELEGATION_LINES;
|
|
526
|
+
return [
|
|
527
|
+
...buildPromptHeaderLines({
|
|
528
|
+
agentName: params.agentName ?? 'Borgee agent',
|
|
529
|
+
provider: 'claude',
|
|
530
|
+
}),
|
|
531
|
+
...sessionDelegationLines,
|
|
532
|
+
...(environmentLines.length > 0 ? ['', ...environmentLines] : []),
|
|
533
|
+
...controlLines,
|
|
534
|
+
buildProviderIdentityReminderLine('claude'),
|
|
535
|
+
...buildPromptBodyLines({
|
|
536
|
+
provider: 'claude',
|
|
537
|
+
channelId: params.channelId,
|
|
538
|
+
incomingAuthorId: params.incomingAuthorId,
|
|
539
|
+
incomingContent: params.incomingContent,
|
|
540
|
+
incomingEventKind: params.incomingEventKind,
|
|
541
|
+
incomingMessageType: params.incomingMessageType,
|
|
542
|
+
promptContext: params.promptContext,
|
|
543
|
+
forceClaudeTaskAssignmentInline: true,
|
|
544
|
+
}),
|
|
545
|
+
].join('\n');
|
|
546
|
+
}
|
|
547
|
+
function buildClaudeZeroTurnPrompt(params) {
|
|
548
|
+
if (isClaudeZeroTurnFallbackRequired(params)) {
|
|
549
|
+
return [
|
|
550
|
+
...buildClaudeTurnControlPromptLines(params.promptContext),
|
|
551
|
+
...buildPromptBodyLines({
|
|
552
|
+
provider: 'claude',
|
|
553
|
+
channelId: params.channelId,
|
|
554
|
+
incomingAuthorId: params.incomingAuthorId,
|
|
555
|
+
incomingContent: params.incomingContent,
|
|
556
|
+
incomingEventKind: params.incomingEventKind,
|
|
557
|
+
incomingMessageType: params.incomingMessageType,
|
|
558
|
+
promptContext: params.promptContext,
|
|
559
|
+
}),
|
|
560
|
+
].join('\n');
|
|
561
|
+
}
|
|
562
|
+
const gatewayTaskLines = buildClaudeOrdinaryGatewayTaskLines(params.promptContext);
|
|
563
|
+
return [
|
|
564
|
+
'Do not claim to have performed actions you did not actually perform.',
|
|
565
|
+
...(gatewayTaskLines.length > 0 ? [...gatewayTaskLines, ''] : []),
|
|
566
|
+
`New message from ${params.incomingAuthorId}:`,
|
|
567
|
+
params.incomingContent,
|
|
568
|
+
].join('\n');
|
|
569
|
+
}
|
|
570
|
+
function buildClaudeMinimalTurnPrompt(params) {
|
|
571
|
+
if (isClaudeZeroTurnFallbackRequired(params)) {
|
|
572
|
+
return buildClaudeZeroTurnPrompt(params);
|
|
573
|
+
}
|
|
574
|
+
const gatewayTaskLines = buildClaudeOrdinaryGatewayTaskLines(params.promptContext);
|
|
575
|
+
return [
|
|
576
|
+
`You are ${params.agentName ?? 'Borgee agent'}, a helpful AI teammate inside Borgee.`,
|
|
577
|
+
'You are replying inside a shared collaboration channel.',
|
|
578
|
+
'Do not claim to have performed actions you did not actually perform.',
|
|
579
|
+
'Keep the visible reply text concise.',
|
|
580
|
+
...(gatewayTaskLines.length > 0 ? ['', ...gatewayTaskLines] : []),
|
|
581
|
+
'',
|
|
582
|
+
`New message from ${params.incomingAuthorId}:`,
|
|
583
|
+
params.incomingContent,
|
|
584
|
+
].join('\n');
|
|
585
|
+
}
|
|
586
|
+
function buildClaudeSessionEnvironmentLines(context) {
|
|
587
|
+
if (!context) {
|
|
588
|
+
return [];
|
|
589
|
+
}
|
|
590
|
+
const lines = [];
|
|
591
|
+
if (context.skillRuntime) {
|
|
592
|
+
lines.push(...(context.gatewayCredentialPath
|
|
593
|
+
? buildSkillManualLines(context.skillRuntime)
|
|
594
|
+
: [buildSkillManualReadLine(context.skillRuntime)]));
|
|
595
|
+
}
|
|
596
|
+
if (context.localhostGateway && context.gatewayCredentialPath) {
|
|
597
|
+
lines.push(`Gateway credential file for this session: ${context.gatewayCredentialPath}`);
|
|
598
|
+
}
|
|
599
|
+
lines.push(...buildResolvedWorkspaceGuidanceLines(context));
|
|
600
|
+
if (context.taskAssignmentContext?.currentTaskId) {
|
|
601
|
+
lines.push(`Current assigned task id: ${context.taskAssignmentContext.currentTaskId}.`);
|
|
602
|
+
}
|
|
603
|
+
else if (context.taskAssignmentContext?.active === true) {
|
|
604
|
+
lines.push('No current task id is persisted in the injected thread context for this task thread.');
|
|
605
|
+
}
|
|
606
|
+
if (context.taskAssignmentContext?.active === true) {
|
|
607
|
+
lines.push('This session is an active task assignment thread. Keep the main work in this thread.', 'Return your normal final response in this thread, and do not move the main work back to the parent channel.');
|
|
608
|
+
}
|
|
609
|
+
return lines;
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Builds the per-turn prompt. Conversation memory is intentionally NOT
|
|
613
|
+
* assembled here: each provider's CLI client resumes a native per-channel
|
|
614
|
+
* session (Claude `--resume`, Copilot `--session-id`), so the CLI itself
|
|
615
|
+
* already has the prior turns. This only needs to carry the agent's
|
|
616
|
+
* identity/instructions plus the new incoming message.
|
|
617
|
+
*/
|
|
618
|
+
export function buildPrompt(params) {
|
|
619
|
+
return [
|
|
620
|
+
...buildPromptHeaderLines(params),
|
|
621
|
+
...buildSessionDelegationPromptLines(params.provider, params.promptContext),
|
|
622
|
+
...buildTurnControlPromptLines(params.promptContext),
|
|
623
|
+
buildProviderIdentityReminderLine(params.provider),
|
|
624
|
+
...buildPromptBodyLines(params),
|
|
625
|
+
].join('\n');
|
|
626
|
+
}
|
|
627
|
+
export function buildClaudeSessionPromptAppend(params) {
|
|
628
|
+
const promptStrategy = resolveProjectionStrategy(params.promptStrategy);
|
|
629
|
+
if (promptStrategy === 'turn-full') {
|
|
630
|
+
return undefined;
|
|
631
|
+
}
|
|
632
|
+
if (promptStrategy === 'file-brief' && params.promptContext?.claudeProjectedBriefPath) {
|
|
633
|
+
const bootstrapLines = buildClaudeProjectedBriefSessionLines(params.promptContext);
|
|
634
|
+
return [
|
|
635
|
+
...buildPromptHeaderLines({ agentName: params.agentName, provider: 'claude' }),
|
|
636
|
+
...(bootstrapLines.length > 0 ? ['', ...bootstrapLines] : []),
|
|
637
|
+
'',
|
|
638
|
+
buildProviderIdentityReminderLine('claude'),
|
|
639
|
+
].join('\n');
|
|
640
|
+
}
|
|
641
|
+
const environmentLines = buildClaudeSessionEnvironmentLines(params.promptContext);
|
|
642
|
+
const sessionDelegationLines = params.promptContext?.skillRuntime ? [] : MAIN_SESSION_DELEGATION_LINES;
|
|
643
|
+
return [
|
|
644
|
+
...buildPromptHeaderLines({ agentName: params.agentName, provider: 'claude' }),
|
|
645
|
+
...sessionDelegationLines,
|
|
646
|
+
...(environmentLines.length > 0 ? ['', ...environmentLines] : []),
|
|
647
|
+
'',
|
|
648
|
+
...buildClaudeOrdinarySessionControlLines(),
|
|
649
|
+
buildProviderIdentityReminderLine('claude'),
|
|
650
|
+
].join('\n');
|
|
651
|
+
}
|
|
652
|
+
export function buildClaudeTurnPrompt(params) {
|
|
653
|
+
const promptStrategy = resolveProjectionStrategy(params.promptStrategy);
|
|
654
|
+
if (promptStrategy === 'turn-full') {
|
|
655
|
+
return buildClaudeLegacyTurnPrompt(params);
|
|
656
|
+
}
|
|
657
|
+
if (promptStrategy === 'message-only') {
|
|
658
|
+
return buildClaudeZeroTurnPrompt(params);
|
|
659
|
+
}
|
|
660
|
+
if (promptStrategy === 'turn-thin') {
|
|
661
|
+
return buildClaudeMinimalTurnPrompt(params);
|
|
662
|
+
}
|
|
663
|
+
if (promptStrategy === 'file-brief') {
|
|
664
|
+
return buildClaudeProjectedBriefTurnPrompt(params);
|
|
665
|
+
}
|
|
666
|
+
return [
|
|
667
|
+
...buildClaudeTurnControlPromptLines(params.promptContext),
|
|
668
|
+
...buildPromptBodyLines({
|
|
669
|
+
provider: 'claude',
|
|
670
|
+
channelId: params.channelId,
|
|
671
|
+
incomingAuthorId: params.incomingAuthorId,
|
|
672
|
+
incomingContent: params.incomingContent,
|
|
673
|
+
incomingEventKind: params.incomingEventKind,
|
|
674
|
+
incomingMessageType: params.incomingMessageType,
|
|
675
|
+
promptContext: params.promptContext,
|
|
676
|
+
}),
|
|
255
677
|
].join('\n');
|
|
256
678
|
}
|