@dotsetlabs/dotclaw 2.1.0 → 2.3.0
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/.env.example +12 -0
- package/README.md +5 -2
- package/config-examples/runtime.json +46 -5
- package/config-examples/tool-budgets.json +1 -1
- package/config-examples/tool-policy.json +1 -1
- package/container/Dockerfile +5 -1
- package/container/agent-runner/package.json +1 -1
- package/container/agent-runner/src/agent-config.ts +67 -17
- package/container/agent-runner/src/container-protocol.ts +6 -0
- package/container/agent-runner/src/daemon.ts +18 -5
- package/container/agent-runner/src/index.ts +442 -243
- package/container/agent-runner/src/ipc.ts +76 -1
- package/container/agent-runner/src/mcp-registry.ts +11 -0
- package/container/agent-runner/src/memory.ts +145 -3
- package/container/agent-runner/src/process-registry.ts +257 -0
- package/container/agent-runner/src/system-prompt.ts +337 -0
- package/container/agent-runner/src/tools.ts +382 -29
- package/container/agent-runner/src/tts.ts +42 -0
- package/dist/agent-context.d.ts +1 -0
- package/dist/agent-context.d.ts.map +1 -1
- package/dist/agent-context.js +6 -3
- package/dist/agent-context.js.map +1 -1
- package/dist/agent-execution.d.ts +1 -0
- package/dist/agent-execution.d.ts.map +1 -1
- package/dist/agent-execution.js +11 -4
- package/dist/agent-execution.js.map +1 -1
- package/dist/container-protocol.d.ts +8 -0
- package/dist/container-protocol.d.ts.map +1 -1
- package/dist/container-runner.d.ts.map +1 -1
- package/dist/container-runner.js +44 -8
- package/dist/container-runner.js.map +1 -1
- package/dist/error-messages.d.ts.map +1 -1
- package/dist/error-messages.js +22 -5
- package/dist/error-messages.js.map +1 -1
- package/dist/index.js +53 -6
- package/dist/index.js.map +1 -1
- package/dist/ipc-dispatcher.d.ts.map +1 -1
- package/dist/ipc-dispatcher.js +336 -6
- package/dist/ipc-dispatcher.js.map +1 -1
- package/dist/memory-recall.d.ts +1 -0
- package/dist/memory-recall.d.ts.map +1 -1
- package/dist/memory-recall.js +3 -0
- package/dist/memory-recall.js.map +1 -1
- package/dist/memory-store.d.ts.map +1 -1
- package/dist/memory-store.js +5 -3
- package/dist/memory-store.js.map +1 -1
- package/dist/message-pipeline.d.ts.map +1 -1
- package/dist/message-pipeline.js +53 -12
- package/dist/message-pipeline.js.map +1 -1
- package/dist/model-registry.d.ts +15 -0
- package/dist/model-registry.d.ts.map +1 -1
- package/dist/model-registry.js +56 -12
- package/dist/model-registry.js.map +1 -1
- package/dist/providers/telegram/telegram-provider.d.ts +1 -0
- package/dist/providers/telegram/telegram-provider.d.ts.map +1 -1
- package/dist/providers/telegram/telegram-provider.js +14 -0
- package/dist/providers/telegram/telegram-provider.js.map +1 -1
- package/dist/request-router.d.ts +0 -1
- package/dist/request-router.d.ts.map +1 -1
- package/dist/request-router.js +18 -6
- package/dist/request-router.js.map +1 -1
- package/dist/runtime-config.d.ts +14 -0
- package/dist/runtime-config.d.ts.map +1 -1
- package/dist/runtime-config.js +64 -16
- package/dist/runtime-config.js.map +1 -1
- package/dist/task-scheduler.d.ts.map +1 -1
- package/dist/task-scheduler.js +3 -5
- package/dist/task-scheduler.js.map +1 -1
- package/dist/tool-budgets.js +1 -1
- package/dist/tool-budgets.js.map +1 -1
- package/dist/tool-policy.d.ts.map +1 -1
- package/dist/tool-policy.js +13 -3
- package/dist/tool-policy.js.map +1 -1
- package/dist/webhook.d.ts +14 -0
- package/dist/webhook.d.ts.map +1 -0
- package/dist/webhook.js +169 -0
- package/dist/webhook.js.map +1 -0
- package/package.json +3 -2
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured system prompt builder for DotClaw agent.
|
|
3
|
+
*
|
|
4
|
+
* Organizes the system prompt into clear sections with a consistent
|
|
5
|
+
* format. Supports "full" mode for user-facing calls and "minimal"
|
|
6
|
+
* mode for background tasks (summaries, memory extraction).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { SkillCatalog } from './skill-loader.js';
|
|
10
|
+
import type { PromptPack } from './prompt-packs.js';
|
|
11
|
+
import { formatSkillCatalog } from './skill-loader.js';
|
|
12
|
+
import { formatPromptPack } from './prompt-packs.js';
|
|
13
|
+
|
|
14
|
+
export type PromptMode = 'full' | 'minimal';
|
|
15
|
+
|
|
16
|
+
export interface SystemPromptParams {
|
|
17
|
+
mode: PromptMode;
|
|
18
|
+
assistantName: string;
|
|
19
|
+
|
|
20
|
+
// Identity & context
|
|
21
|
+
messagingPlatform?: string;
|
|
22
|
+
hostPlatform?: string;
|
|
23
|
+
timezone?: string;
|
|
24
|
+
|
|
25
|
+
// Scheduled task context
|
|
26
|
+
isScheduledTask: boolean;
|
|
27
|
+
taskId?: string;
|
|
28
|
+
|
|
29
|
+
// Notes & skills
|
|
30
|
+
groupNotes?: string | null;
|
|
31
|
+
globalNotes?: string | null;
|
|
32
|
+
skillCatalog?: SkillCatalog | null;
|
|
33
|
+
|
|
34
|
+
// Memory
|
|
35
|
+
memorySummary: string;
|
|
36
|
+
memoryFacts: string[];
|
|
37
|
+
sessionRecall: string[];
|
|
38
|
+
longTermRecall: string[];
|
|
39
|
+
userProfile?: string | null;
|
|
40
|
+
memoryStats?: { total: number; user: number; group: number; global: number };
|
|
41
|
+
|
|
42
|
+
// Groups
|
|
43
|
+
availableGroups?: Array<{ jid: string; name: string; lastActivity: string; isRegistered: boolean }>;
|
|
44
|
+
|
|
45
|
+
// Tool reliability
|
|
46
|
+
toolReliability?: Array<{ name: string; success_rate: number; count: number; avg_duration_ms: number | null }>;
|
|
47
|
+
|
|
48
|
+
// Behavior
|
|
49
|
+
behaviorConfig?: Record<string, unknown>;
|
|
50
|
+
|
|
51
|
+
// Prompt packs
|
|
52
|
+
taskExtractionPack?: PromptPack | null;
|
|
53
|
+
responseQualityPack?: PromptPack | null;
|
|
54
|
+
toolCallingPack?: PromptPack | null;
|
|
55
|
+
toolOutcomePack?: PromptPack | null;
|
|
56
|
+
memoryPolicyPack?: PromptPack | null;
|
|
57
|
+
memoryRecallPack?: PromptPack | null;
|
|
58
|
+
|
|
59
|
+
// Budget
|
|
60
|
+
maxToolSteps?: number;
|
|
61
|
+
|
|
62
|
+
// Tool config
|
|
63
|
+
browserEnabled: boolean;
|
|
64
|
+
|
|
65
|
+
// Pack limits
|
|
66
|
+
promptPacksMaxChars: number;
|
|
67
|
+
promptPacksMaxDemos: number;
|
|
68
|
+
|
|
69
|
+
// System prompt trim level (0 = full, higher = more aggressive trimming)
|
|
70
|
+
trimLevel?: number;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const MEMORY_SUMMARY_MAX_CHARS = 2000;
|
|
74
|
+
const PROMPT_PACKS_TOTAL_BUDGET_FACTOR = 3;
|
|
75
|
+
|
|
76
|
+
/** Build a section with a heading, only if content is present */
|
|
77
|
+
function section(heading: string, content: string): string {
|
|
78
|
+
if (!content.trim()) return '';
|
|
79
|
+
return `## ${heading}\n${content}`;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function buildIdentitySection(params: SystemPromptParams): string {
|
|
83
|
+
const parts = [
|
|
84
|
+
`You are ${params.assistantName}, a personal assistant running inside DotClaw.`
|
|
85
|
+
];
|
|
86
|
+
if (params.messagingPlatform) {
|
|
87
|
+
parts[0] += ` You are currently connected via ${params.messagingPlatform}.`;
|
|
88
|
+
}
|
|
89
|
+
return parts.join('\n');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function buildPlatformSection(params: SystemPromptParams): string {
|
|
93
|
+
if (!params.hostPlatform) return '';
|
|
94
|
+
if (params.hostPlatform.startsWith('linux')) {
|
|
95
|
+
return `Host platform: ${params.hostPlatform} (matches container).`;
|
|
96
|
+
}
|
|
97
|
+
return [
|
|
98
|
+
`You are running inside a Linux container, but the user's host machine is ${params.hostPlatform}.`,
|
|
99
|
+
'Prefer pnpm over npm for installing packages — it generates cross-platform lockfiles.',
|
|
100
|
+
'node_modules and package-lock.json are automatically cleaned up after your run finishes (pnpm-lock.yaml is preserved).',
|
|
101
|
+
'You do NOT need to delete them yourself. The user will need to run `pnpm install` (or `npx pnpm install`) on their machine before building.',
|
|
102
|
+
'Use node_modules freely during your run for builds and tests.'
|
|
103
|
+
].join(' ');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function buildScheduledSection(params: SystemPromptParams): string {
|
|
107
|
+
if (!params.isScheduledTask) return '';
|
|
108
|
+
return `You are running as a scheduled task${params.taskId ? ` (task id: ${params.taskId})` : ''}. If you need to communicate, use \`mcp__dotclaw__send_message\`.`;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function buildResponseGuidanceSection(): string {
|
|
112
|
+
return [
|
|
113
|
+
'- Always answer the user\'s question directly before reaching for tools.',
|
|
114
|
+
'- If the user asks about your previous actions (e.g., "did you use X tool?"), reflect on the conversation history — do not re-execute the task.',
|
|
115
|
+
'- If the user asks a simple factual question, answer from your knowledge — do not call tools unless you need to verify or act.',
|
|
116
|
+
'- When you have genuinely nothing to say, respond with ONLY: NO_REPLY (your entire message must be just this token, nothing else).'
|
|
117
|
+
].join('\n');
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function buildToolCallStyleSection(): string {
|
|
121
|
+
return [
|
|
122
|
+
'Default: do not narrate routine, low-risk tool calls — just call the tool.',
|
|
123
|
+
'Narrate only when it helps: multi-step work, complex/challenging problems, sensitive actions, or when the user explicitly asks.',
|
|
124
|
+
'Keep narration brief and value-dense; avoid repeating obvious steps.'
|
|
125
|
+
].join('\n');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function buildToolGuidanceSection(params: SystemPromptParams): string {
|
|
129
|
+
const lines = [
|
|
130
|
+
'Key tool rules:',
|
|
131
|
+
'- User attachments arrive in /workspace/group/inbox/ (see <attachment> tags). Process with Read/Bash/Python.',
|
|
132
|
+
'- To send media from the web: download_url → send_photo/send_file/send_audio.',
|
|
133
|
+
'- Charts/plots: matplotlib → savefig → send_photo. Graphviz → dot -Tpng → send_photo.',
|
|
134
|
+
'- Voice messages are auto-transcribed (<transcript> in <attachment>). Reply with normal text — the host auto-converts to voice.',
|
|
135
|
+
'- GitHub CLI (`gh`) is available if GH_TOKEN is set.',
|
|
136
|
+
'- plugin__* and mcp_ext__* tools may be available if configured.',
|
|
137
|
+
'- Use [[reply_to_current]] to reply to the message that triggered this run, or [[reply_to:<id>]] to reply to a specific message ID.'
|
|
138
|
+
];
|
|
139
|
+
|
|
140
|
+
if (params.browserEnabled) {
|
|
141
|
+
lines.push(
|
|
142
|
+
'Browser Tool: actions: navigate, snapshot, click, fill, screenshot, extract, evaluate, close.',
|
|
143
|
+
'Use snapshot with interactive=true for clickable refs (@e1, @e2). Screenshots → /workspace/group/screenshots/.'
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
lines.push(
|
|
148
|
+
'Process Tool: for commands that run longer than ~2 minutes (builds, servers, data pipelines, web scrapers).',
|
|
149
|
+
'Use Process start to launch, poll to check output, write for stdin, kill to stop, remove to clean up.',
|
|
150
|
+
'AnalyzeImage Tool: analyze image files in the workspace using a vision model.',
|
|
151
|
+
'Use `pdftotext file.pdf -` via Bash to extract text from PDFs. poppler-utils is installed.',
|
|
152
|
+
'Skill authoring: create skills by writing .md files to /workspace/group/skills/ with YAML frontmatter (name, description). Skills are auto-discovered on next run.',
|
|
153
|
+
'Plugin authoring: create plugins by writing JSON files to /workspace/group/plugins/ following the plugin schema (name, description, type: http|bash, url|command, input, required).',
|
|
154
|
+
'Config tools: use mcp__dotclaw__get_config to inspect current configuration and mcp__dotclaw__set_tool_policy / set_behavior / set_mcp_config to self-configure.',
|
|
155
|
+
'Sub-agents: use mcp__dotclaw__subagent to spawn parallel tasks with different models. Spawn for parallel research, long computations, or tasks requiring a different model.'
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
return lines.join('\n');
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function buildMemorySection(params: SystemPromptParams): string {
|
|
162
|
+
const parts: string[] = [];
|
|
163
|
+
const hasAny = params.memorySummary || params.memoryFacts.length > 0 ||
|
|
164
|
+
params.longTermRecall.length > 0 || params.userProfile;
|
|
165
|
+
|
|
166
|
+
if (hasAny) {
|
|
167
|
+
parts.push('The following memories may or may not be relevant to the current conversation. Use them only if they directly answer the user\'s question.');
|
|
168
|
+
if (params.memorySummary) {
|
|
169
|
+
parts.push('Long-term memory summary:');
|
|
170
|
+
parts.push(params.memorySummary.slice(0, MEMORY_SUMMARY_MAX_CHARS));
|
|
171
|
+
}
|
|
172
|
+
if (params.memoryFacts.length > 0) {
|
|
173
|
+
parts.push('Long-term facts:');
|
|
174
|
+
parts.push(params.memoryFacts.map(f => `- ${f}`).join('\n'));
|
|
175
|
+
}
|
|
176
|
+
if (params.userProfile) {
|
|
177
|
+
parts.push('User profile:');
|
|
178
|
+
parts.push(params.userProfile);
|
|
179
|
+
}
|
|
180
|
+
if (params.longTermRecall.length > 0) {
|
|
181
|
+
parts.push('What you remember about the user (long-term):');
|
|
182
|
+
parts.push(params.longTermRecall.map(item => `- ${item}`).join('\n'));
|
|
183
|
+
}
|
|
184
|
+
if (params.memoryStats) {
|
|
185
|
+
parts.push(`Memory stats: Total: ${params.memoryStats.total}, User: ${params.memoryStats.user}, Group: ${params.memoryStats.group}, Global: ${params.memoryStats.global}`);
|
|
186
|
+
}
|
|
187
|
+
} else {
|
|
188
|
+
parts.push('No long-term memory available yet.');
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (params.sessionRecall.length > 0) {
|
|
192
|
+
parts.push('Recent conversation context:');
|
|
193
|
+
parts.push(params.sessionRecall.map(item => `- ${item}`).join('\n'));
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return parts.join('\n');
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function buildBehaviorSection(params: SystemPromptParams): string {
|
|
200
|
+
const notes: string[] = [];
|
|
201
|
+
const responseStyle = typeof params.behaviorConfig?.response_style === 'string'
|
|
202
|
+
? String(params.behaviorConfig.response_style) : '';
|
|
203
|
+
if (responseStyle === 'concise') {
|
|
204
|
+
notes.push('Keep responses short and to the point.');
|
|
205
|
+
} else if (responseStyle === 'detailed') {
|
|
206
|
+
notes.push('Give detailed, step-by-step responses when helpful.');
|
|
207
|
+
}
|
|
208
|
+
const toolBias = typeof params.behaviorConfig?.tool_calling_bias === 'number'
|
|
209
|
+
? Number(params.behaviorConfig.tool_calling_bias) : null;
|
|
210
|
+
if (toolBias !== null && toolBias < 0.4) {
|
|
211
|
+
notes.push('Ask before using tools unless the intent is obvious.');
|
|
212
|
+
} else if (toolBias !== null && toolBias > 0.6) {
|
|
213
|
+
notes.push('Use tools proactively when they add accuracy or save time.');
|
|
214
|
+
}
|
|
215
|
+
const cautionBias = typeof params.behaviorConfig?.caution_bias === 'number'
|
|
216
|
+
? Number(params.behaviorConfig.caution_bias) : null;
|
|
217
|
+
if (cautionBias !== null && cautionBias > 0.6) {
|
|
218
|
+
notes.push('Double-check uncertain facts and flag limitations.');
|
|
219
|
+
}
|
|
220
|
+
return notes.join('\n');
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function buildPromptPackSections(params: SystemPromptParams): string[] {
|
|
224
|
+
const totalBudget = params.promptPacksMaxChars * PROMPT_PACKS_TOTAL_BUDGET_FACTOR;
|
|
225
|
+
const fmtPack = (label: string, pack: PromptPack | null | undefined) =>
|
|
226
|
+
pack ? formatPromptPack({ label, pack, maxDemos: params.promptPacksMaxDemos, maxChars: params.promptPacksMaxChars }) : '';
|
|
227
|
+
|
|
228
|
+
const packEntries: Array<[string, PromptPack | null | undefined]> = [
|
|
229
|
+
['Tool Calling Guidelines', params.toolCallingPack],
|
|
230
|
+
['Tool Outcome Guidelines', params.toolOutcomePack],
|
|
231
|
+
['Task Extraction Guidelines', params.taskExtractionPack],
|
|
232
|
+
['Response Quality Guidelines', params.responseQualityPack],
|
|
233
|
+
['Memory Policy Guidelines', params.memoryPolicyPack],
|
|
234
|
+
['Memory Recall Guidelines', params.memoryRecallPack],
|
|
235
|
+
];
|
|
236
|
+
const blocks: string[] = [];
|
|
237
|
+
let totalChars = 0;
|
|
238
|
+
for (const [label, pack] of packEntries) {
|
|
239
|
+
const block = fmtPack(label, pack);
|
|
240
|
+
if (!block) continue;
|
|
241
|
+
if (totalChars + block.length > totalBudget) break;
|
|
242
|
+
blocks.push(block);
|
|
243
|
+
totalChars += block.length;
|
|
244
|
+
}
|
|
245
|
+
return blocks;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Build a complete system prompt from structured parameters.
|
|
250
|
+
*
|
|
251
|
+
* "full" mode includes all sections for user-facing agent calls.
|
|
252
|
+
* "minimal" mode includes only identity + essential context for background tasks.
|
|
253
|
+
*/
|
|
254
|
+
/**
|
|
255
|
+
* Trim levels for progressive system prompt budgeting:
|
|
256
|
+
* 0 = full (no trimming)
|
|
257
|
+
* 1 = drop prompt packs
|
|
258
|
+
* 2 = drop tool reliability stats
|
|
259
|
+
* 3 = truncate memory section (drop session recall, reduce long-term recall)
|
|
260
|
+
* 4 = truncate group/global notes
|
|
261
|
+
*/
|
|
262
|
+
export function buildSystemPrompt(params: SystemPromptParams): string {
|
|
263
|
+
if (params.mode === 'minimal') {
|
|
264
|
+
return [
|
|
265
|
+
buildIdentitySection(params),
|
|
266
|
+
buildScheduledSection(params),
|
|
267
|
+
'Be concise and helpful.'
|
|
268
|
+
].filter(Boolean).join('\n\n');
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const trimLevel = params.trimLevel ?? 0;
|
|
272
|
+
|
|
273
|
+
const timezoneNote = params.timezone
|
|
274
|
+
? `Timezone: ${params.timezone}. Use this timezone when interpreting or presenting timestamps unless the user specifies another.`
|
|
275
|
+
: '';
|
|
276
|
+
|
|
277
|
+
const groupNotes = params.groupNotes
|
|
278
|
+
? `Group notes:\n${trimLevel >= 4 ? params.groupNotes.slice(0, 1000) : params.groupNotes}`
|
|
279
|
+
: '';
|
|
280
|
+
const globalNotes = params.globalNotes
|
|
281
|
+
? `Global notes:\n${trimLevel >= 4 ? params.globalNotes.slice(0, 1000) : params.globalNotes}`
|
|
282
|
+
: '';
|
|
283
|
+
const skillNotes = params.skillCatalog ? formatSkillCatalog(params.skillCatalog) : '';
|
|
284
|
+
|
|
285
|
+
const availableGroups = params.availableGroups && params.availableGroups.length > 0
|
|
286
|
+
? params.availableGroups
|
|
287
|
+
.map(g => `- ${g.name} (chat ${g.jid}, last: ${g.lastActivity})`)
|
|
288
|
+
.join('\n')
|
|
289
|
+
: '';
|
|
290
|
+
|
|
291
|
+
// Trim level 2+: drop tool reliability stats
|
|
292
|
+
const toolReliability = trimLevel >= 2 ? '' : (
|
|
293
|
+
params.toolReliability && params.toolReliability.length > 0
|
|
294
|
+
? params.toolReliability
|
|
295
|
+
.sort((a, b) => a.success_rate - b.success_rate)
|
|
296
|
+
.slice(0, 20)
|
|
297
|
+
.map(t => {
|
|
298
|
+
const pct = `${Math.round(t.success_rate * 100)}%`;
|
|
299
|
+
const avg = Number.isFinite(t.avg_duration_ms) ? `${Math.round(t.avg_duration_ms!)}ms` : 'n/a';
|
|
300
|
+
return `- ${t.name}: success ${pct} over ${t.count} calls (avg ${avg})`;
|
|
301
|
+
})
|
|
302
|
+
.join('\n')
|
|
303
|
+
: ''
|
|
304
|
+
);
|
|
305
|
+
|
|
306
|
+
// Trim level 1+: drop prompt packs
|
|
307
|
+
const packBlocks = trimLevel >= 1 ? [] : buildPromptPackSections(params);
|
|
308
|
+
|
|
309
|
+
// Trim level 3+: reduce memory section (drop session recall, limit long-term recall)
|
|
310
|
+
const memoryParams = trimLevel >= 3
|
|
311
|
+
? { ...params, sessionRecall: [], longTermRecall: params.longTermRecall.slice(0, 2) }
|
|
312
|
+
: params;
|
|
313
|
+
|
|
314
|
+
const sections = [
|
|
315
|
+
buildIdentitySection(params),
|
|
316
|
+
buildPlatformSection(params),
|
|
317
|
+
buildScheduledSection(params),
|
|
318
|
+
section('Response Guidelines', buildResponseGuidanceSection()),
|
|
319
|
+
section('Tools', buildToolGuidanceSection(params)),
|
|
320
|
+
section('Tool Call Style', buildToolCallStyleSection()),
|
|
321
|
+
groupNotes,
|
|
322
|
+
globalNotes,
|
|
323
|
+
skillNotes,
|
|
324
|
+
timezoneNote,
|
|
325
|
+
...packBlocks,
|
|
326
|
+
availableGroups ? section('Available Groups', availableGroups) : '',
|
|
327
|
+
toolReliability ? section('Tool Reliability', toolReliability) : '',
|
|
328
|
+
buildBehaviorSection(params) ? section('Behavior', buildBehaviorSection(params)) : '',
|
|
329
|
+
section('Memory', buildMemorySection(memoryParams)),
|
|
330
|
+
params.maxToolSteps
|
|
331
|
+
? `You have a budget of ${params.maxToolSteps} tool steps per request. If a task is large, break your work into phases and always finish with a text summary of what you accomplished — never end on a tool call without a response.`
|
|
332
|
+
: '',
|
|
333
|
+
'Be concise and helpful. When you use tools, summarize what happened rather than dumping raw output.'
|
|
334
|
+
];
|
|
335
|
+
|
|
336
|
+
return sections.filter(Boolean).join('\n\n');
|
|
337
|
+
}
|