@covibes/zeroshot 5.3.0 → 5.4.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/LICENSE +1 -1
- package/README.md +8 -385
- package/cli/index.js +108 -4615
- package/package.json +16 -125
- package/CHANGELOG.md +0 -537
- package/cli/commands/providers.js +0 -150
- package/cli/lib/first-run.js +0 -211
- package/cli/lib/update-checker.js +0 -281
- package/cli/message-formatter-utils.js +0 -75
- package/cli/message-formatters-normal.js +0 -253
- package/cli/message-formatters-watch.js +0 -181
- package/cluster-templates/base-templates/debug-workflow.json +0 -375
- package/cluster-templates/base-templates/full-workflow.json +0 -697
- package/cluster-templates/base-templates/single-worker.json +0 -63
- package/cluster-templates/base-templates/worker-validator.json +0 -152
- package/cluster-templates/conductor-bootstrap.json +0 -124
- package/docker/zeroshot-cluster/Dockerfile +0 -152
- package/docker/zeroshot-cluster/pre-baked-deps.json +0 -28
- package/lib/completion.js +0 -174
- package/lib/docker-config.js +0 -212
- package/lib/id-detector.js +0 -53
- package/lib/provider-detection.js +0 -59
- package/lib/provider-names.js +0 -56
- package/lib/settings.js +0 -405
- package/lib/stream-json-parser.js +0 -10
- package/scripts/fix-node-pty-permissions.js +0 -75
- package/scripts/record-demo.sh +0 -279
- package/scripts/test-install.sh +0 -40
- package/scripts/validate-templates.js +0 -100
- package/src/agent/agent-config.js +0 -193
- package/src/agent/agent-context-builder.js +0 -335
- package/src/agent/agent-hook-executor.js +0 -402
- package/src/agent/agent-lifecycle.js +0 -683
- package/src/agent/agent-stuck-detector.js +0 -256
- package/src/agent/agent-task-executor.js +0 -1431
- package/src/agent/agent-trigger-evaluator.js +0 -67
- package/src/agent/output-extraction.js +0 -200
- package/src/agent/output-reformatter.js +0 -175
- package/src/agent/schema-utils.js +0 -111
- package/src/agent-wrapper.js +0 -570
- package/src/agents/git-pusher-agent.json +0 -20
- package/src/attach/attach-client.js +0 -438
- package/src/attach/attach-server.js +0 -543
- package/src/attach/index.js +0 -35
- package/src/attach/protocol.js +0 -220
- package/src/attach/ring-buffer.js +0 -121
- package/src/attach/socket-discovery.js +0 -267
- package/src/claude-task-runner.js +0 -523
- package/src/config-router.js +0 -80
- package/src/config-validator.js +0 -1660
- package/src/copy-worker.js +0 -43
- package/src/github.js +0 -139
- package/src/isolation-manager.js +0 -1381
- package/src/ledger.js +0 -614
- package/src/logic-engine.js +0 -223
- package/src/message-bus-bridge.js +0 -139
- package/src/message-bus.js +0 -249
- package/src/name-generator.js +0 -232
- package/src/orchestrator.js +0 -2519
- package/src/preflight.js +0 -485
- package/src/process-metrics.js +0 -566
- package/src/providers/anthropic/cli-builder.js +0 -45
- package/src/providers/anthropic/index.js +0 -134
- package/src/providers/anthropic/models.js +0 -23
- package/src/providers/anthropic/output-parser.js +0 -159
- package/src/providers/base-provider.js +0 -181
- package/src/providers/capabilities.js +0 -51
- package/src/providers/google/cli-builder.js +0 -55
- package/src/providers/google/index.js +0 -116
- package/src/providers/google/models.js +0 -24
- package/src/providers/google/output-parser.js +0 -92
- package/src/providers/index.js +0 -75
- package/src/providers/openai/cli-builder.js +0 -122
- package/src/providers/openai/index.js +0 -135
- package/src/providers/openai/models.js +0 -21
- package/src/providers/openai/output-parser.js +0 -129
- package/src/schemas/sub-cluster.js +0 -156
- package/src/status-footer.js +0 -980
- package/src/sub-cluster-wrapper.js +0 -560
- package/src/task-runner.js +0 -30
- package/src/template-resolver.js +0 -369
- package/src/tui/CHANGES.txt +0 -133
- package/src/tui/LAYOUT.md +0 -261
- package/src/tui/README.txt +0 -192
- package/src/tui/TWO-LEVEL-NAVIGATION.md +0 -186
- package/src/tui/data-poller.js +0 -325
- package/src/tui/demo.js +0 -208
- package/src/tui/formatters.js +0 -128
- package/src/tui/index.js +0 -193
- package/src/tui/keybindings.js +0 -383
- package/src/tui/layout.js +0 -334
- package/src/tui/renderer.js +0 -194
- package/task-lib/attachable-watcher.js +0 -272
- package/task-lib/claude-recovery.js +0 -119
- package/task-lib/commands/clean.js +0 -50
- package/task-lib/commands/get-log-path.js +0 -23
- package/task-lib/commands/kill.js +0 -32
- package/task-lib/commands/list.js +0 -105
- package/task-lib/commands/logs.js +0 -411
- package/task-lib/commands/resume.js +0 -42
- package/task-lib/commands/run.js +0 -57
- package/task-lib/commands/schedule.js +0 -105
- package/task-lib/commands/scheduler-cmd.js +0 -96
- package/task-lib/commands/schedules.js +0 -98
- package/task-lib/commands/status.js +0 -44
- package/task-lib/commands/unschedule.js +0 -16
- package/task-lib/completion.js +0 -9
- package/task-lib/config.js +0 -10
- package/task-lib/name-generator.js +0 -230
- package/task-lib/package.json +0 -3
- package/task-lib/runner.js +0 -144
- package/task-lib/scheduler.js +0 -252
- package/task-lib/store.js +0 -230
- package/task-lib/tui/formatters.js +0 -166
- package/task-lib/tui/index.js +0 -197
- package/task-lib/tui/layout.js +0 -111
- package/task-lib/tui/renderer.js +0 -119
- package/task-lib/tui.js +0 -384
- package/task-lib/watcher.js +0 -188
|
@@ -1,335 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AgentContextBuilder - Build agent execution context from ledger
|
|
3
|
-
*
|
|
4
|
-
* Provides:
|
|
5
|
-
* - Context assembly from multiple message sources
|
|
6
|
-
* - Context strategy evaluation (topics, limits, since timestamps)
|
|
7
|
-
* - Prompt injection and formatting
|
|
8
|
-
* - Token-based truncation
|
|
9
|
-
* - Defensive context overflow prevention
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
// Defensive limit: 500,000 chars ≈ 125k tokens (safe buffer below 200k limit)
|
|
13
|
-
// Prevents "Prompt is too long" errors that kill tasks
|
|
14
|
-
const MAX_CONTEXT_CHARS = 500000;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Generate an example object from a JSON schema
|
|
18
|
-
* Used to show models a concrete example of expected output
|
|
19
|
-
*
|
|
20
|
-
* @param {object} schema - JSON schema
|
|
21
|
-
* @returns {object|null} Example object or null if generation fails
|
|
22
|
-
*/
|
|
23
|
-
function generateExampleFromSchema(schema) {
|
|
24
|
-
if (!schema || schema.type !== 'object' || !schema.properties) {
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const example = {};
|
|
29
|
-
|
|
30
|
-
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
31
|
-
if (propSchema.enum && propSchema.enum.length > 0) {
|
|
32
|
-
// Use first enum value as example
|
|
33
|
-
example[key] = propSchema.enum[0];
|
|
34
|
-
} else if (propSchema.type === 'string') {
|
|
35
|
-
example[key] = propSchema.description || `${key} value`;
|
|
36
|
-
} else if (propSchema.type === 'boolean') {
|
|
37
|
-
example[key] = true;
|
|
38
|
-
} else if (propSchema.type === 'number' || propSchema.type === 'integer') {
|
|
39
|
-
example[key] = 0;
|
|
40
|
-
} else if (propSchema.type === 'array') {
|
|
41
|
-
if (propSchema.items?.type === 'string') {
|
|
42
|
-
example[key] = [];
|
|
43
|
-
} else {
|
|
44
|
-
example[key] = [];
|
|
45
|
-
}
|
|
46
|
-
} else if (propSchema.type === 'object') {
|
|
47
|
-
example[key] = generateExampleFromSchema(propSchema) || {};
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return example;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Build execution context for an agent
|
|
56
|
-
* @param {object} params - Context building parameters
|
|
57
|
-
* @param {string} params.id - Agent ID
|
|
58
|
-
* @param {string} params.role - Agent role
|
|
59
|
-
* @param {number} params.iteration - Current iteration number
|
|
60
|
-
* @param {any} params.config - Agent configuration
|
|
61
|
-
* @param {any} params.messageBus - Message bus for querying ledger
|
|
62
|
-
* @param {any} params.cluster - Cluster object
|
|
63
|
-
* @param {number} [params.lastTaskEndTime] - Timestamp of last task completion
|
|
64
|
-
* @param {any} params.triggeringMessage - Message that triggered this execution
|
|
65
|
-
* @param {string} [params.selectedPrompt] - Pre-selected prompt from _selectPrompt() (iteration-based)
|
|
66
|
-
* @param {object} [params.worktree] - Worktree isolation state (if running in worktree mode)
|
|
67
|
-
* @param {object} [params.isolation] - Docker isolation state (if running in Docker mode)
|
|
68
|
-
* @returns {string} Assembled context string
|
|
69
|
-
*/
|
|
70
|
-
function buildContext({
|
|
71
|
-
id,
|
|
72
|
-
role,
|
|
73
|
-
iteration,
|
|
74
|
-
config,
|
|
75
|
-
messageBus,
|
|
76
|
-
cluster,
|
|
77
|
-
lastTaskEndTime,
|
|
78
|
-
triggeringMessage,
|
|
79
|
-
selectedPrompt,
|
|
80
|
-
worktree,
|
|
81
|
-
isolation,
|
|
82
|
-
}) {
|
|
83
|
-
const strategy = config.contextStrategy || { sources: [] };
|
|
84
|
-
|
|
85
|
-
let context = `You are agent "${id}" with role "${role}".\n\n`;
|
|
86
|
-
context += `Iteration: ${iteration}\n\n`;
|
|
87
|
-
|
|
88
|
-
// GLOBAL RULE: NEVER ASK QUESTIONS - Vibe agents run non-interactively
|
|
89
|
-
context += `## 🔴 CRITICAL: AUTONOMOUS EXECUTION REQUIRED\n\n`;
|
|
90
|
-
context += `You are running in a NON-INTERACTIVE cluster environment.\n\n`;
|
|
91
|
-
context += `**NEVER** use AskUserQuestion or ask for user input - there is NO user to respond.\n`;
|
|
92
|
-
context += `**NEVER** ask "Would you like me to..." or "Should I..." - JUST DO IT.\n`;
|
|
93
|
-
context += `**NEVER** wait for approval or confirmation - MAKE DECISIONS AUTONOMOUSLY.\n\n`;
|
|
94
|
-
context += `When facing choices:\n`;
|
|
95
|
-
context += `- Choose the option that maintains code quality and correctness\n`;
|
|
96
|
-
context += `- If unsure between "fix the code" vs "relax the rules" → ALWAYS fix the code\n`;
|
|
97
|
-
context += `- If unsure between "do more" vs "do less" → ALWAYS do what's required, nothing more\n\n`;
|
|
98
|
-
|
|
99
|
-
// OUTPUT STYLE - NON-NEGOTIABLE
|
|
100
|
-
context += `## 🔴 OUTPUT STYLE - NON-NEGOTIABLE\n\n`;
|
|
101
|
-
context += `**ALL OUTPUT: Maximum informativeness, minimum verbosity. NO EXCEPTIONS.**\n\n`;
|
|
102
|
-
context += `This applies to EVERYTHING you output:\n`;
|
|
103
|
-
context += `- Text responses\n`;
|
|
104
|
-
context += `- JSON schema values\n`;
|
|
105
|
-
context += `- Reasoning fields\n`;
|
|
106
|
-
context += `- Summary fields\n`;
|
|
107
|
-
context += `- ALL string values in structured output\n\n`;
|
|
108
|
-
context += `Rules:\n`;
|
|
109
|
-
context += `- Progress: "Reading auth.ts" NOT "I will now read the auth.ts file..."\n`;
|
|
110
|
-
context += `- Tool calls: NO preamble. Call immediately.\n`;
|
|
111
|
-
context += `- Schema strings: Dense facts. No filler. No fluff.\n`;
|
|
112
|
-
context += `- Errors: DETAILED (stack traces, repro). NEVER compress errors.\n`;
|
|
113
|
-
context += `- FORBIDDEN: "I'll help...", "Let me...", "I'm going to...", "Sure!", "Great!", "Certainly!"\n\n`;
|
|
114
|
-
context += `Every token costs money. Waste nothing.\n\n`;
|
|
115
|
-
|
|
116
|
-
// GIT OPERATIONS RESTRICTION - Only when NOT running in isolation mode
|
|
117
|
-
// When isolated (worktree or Docker), agents CAN commit/push safely
|
|
118
|
-
// When NOT isolated, agents are on main branch - git operations are dangerous
|
|
119
|
-
const isIsolated = !!(worktree?.enabled || isolation?.enabled);
|
|
120
|
-
if (!isIsolated) {
|
|
121
|
-
context += `## 🚫 GIT OPERATIONS - FORBIDDEN\n\n`;
|
|
122
|
-
context += `NEVER commit, push, or create PRs. You only modify files.\n`;
|
|
123
|
-
context += `The git-pusher agent handles ALL git operations AFTER validators approve.\n\n`;
|
|
124
|
-
context += `- ❌ NEVER run: git add, git commit, git push, gh pr create\n`;
|
|
125
|
-
context += `- ❌ NEVER suggest committing changes\n`;
|
|
126
|
-
context += `- ✅ Only modify files and publish your completion message when done\n\n`;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Add prompt from config (system prompt, instructions, output format)
|
|
130
|
-
// If selectedPrompt is provided (iteration-based), use it directly
|
|
131
|
-
// Otherwise fall back to legacy config.prompt handling
|
|
132
|
-
const promptText =
|
|
133
|
-
selectedPrompt || (typeof config.prompt === 'string' ? config.prompt : config.prompt?.system);
|
|
134
|
-
|
|
135
|
-
if (promptText) {
|
|
136
|
-
context += `## Instructions\n\n${promptText}\n\n`;
|
|
137
|
-
} else if (config.prompt && typeof config.prompt !== 'string' && !config.prompt?.system) {
|
|
138
|
-
// FAIL HARD: prompt exists but format is unrecognized (and no selectedPrompt provided)
|
|
139
|
-
throw new Error(
|
|
140
|
-
`Agent "${id}" has invalid prompt format. ` +
|
|
141
|
-
`Expected string or object with .system property, got: ${JSON.stringify(config.prompt).slice(0, 100)}...`
|
|
142
|
-
);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// Output format schema (if configured via legacy format)
|
|
146
|
-
if (config.prompt?.outputFormat) {
|
|
147
|
-
context += `## Output Schema (REQUIRED)\n\n`;
|
|
148
|
-
context += `\`\`\`json\n${JSON.stringify(config.prompt.outputFormat.example, null, 2)}\n\`\`\`\n\n`;
|
|
149
|
-
context += `STRING VALUES IN THIS SCHEMA: Dense. Factual. No filler words. No pleasantries.\n`;
|
|
150
|
-
if (config.prompt.outputFormat.rules) {
|
|
151
|
-
for (const rule of config.prompt.outputFormat.rules) {
|
|
152
|
-
context += `- ${rule}\n`;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
context += '\n';
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// AUTO-INJECT JSON OUTPUT INSTRUCTIONS when jsonSchema is defined
|
|
159
|
-
// This ensures ALL agents with structured output schemas get explicit "output ONLY JSON" instructions
|
|
160
|
-
// Critical for less capable models (Codex, Gemini) that output prose without explicit instructions
|
|
161
|
-
if (config.jsonSchema && config.outputFormat === 'json') {
|
|
162
|
-
context += `## 🔴 OUTPUT FORMAT - JSON ONLY\n\n`;
|
|
163
|
-
context += `Your response must be ONLY valid JSON. No other text before or after.\n`;
|
|
164
|
-
context += `Start with { and end with }. Nothing else.\n\n`;
|
|
165
|
-
context += `Required schema:\n`;
|
|
166
|
-
context += `\`\`\`json\n${JSON.stringify(config.jsonSchema, null, 2)}\n\`\`\`\n\n`;
|
|
167
|
-
|
|
168
|
-
// Generate example from schema
|
|
169
|
-
const example = generateExampleFromSchema(config.jsonSchema);
|
|
170
|
-
if (example) {
|
|
171
|
-
context += `Example output:\n`;
|
|
172
|
-
context += `\`\`\`json\n${JSON.stringify(example, null, 2)}\n\`\`\`\n\n`;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
context += `CRITICAL RULES:\n`;
|
|
176
|
-
context += `- Output ONLY the JSON object - no explanation, no thinking, no preamble\n`;
|
|
177
|
-
context += `- Use EXACTLY the enum values specified (case-sensitive)\n`;
|
|
178
|
-
context += `- Include ALL required fields\n\n`;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// Add sources
|
|
182
|
-
for (const source of strategy.sources) {
|
|
183
|
-
// Resolve special 'since' values
|
|
184
|
-
let sinceTimestamp = source.since;
|
|
185
|
-
if (source.since === 'cluster_start') {
|
|
186
|
-
sinceTimestamp = cluster.createdAt;
|
|
187
|
-
} else if (source.since === 'last_task_end') {
|
|
188
|
-
// Use timestamp of last task completion, or cluster start if no tasks completed yet
|
|
189
|
-
sinceTimestamp = lastTaskEndTime || cluster.createdAt;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
const messages = messageBus.query({
|
|
193
|
-
cluster_id: cluster.id,
|
|
194
|
-
topic: source.topic,
|
|
195
|
-
sender: source.sender,
|
|
196
|
-
since: sinceTimestamp,
|
|
197
|
-
limit: source.limit,
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
if (messages.length > 0) {
|
|
201
|
-
context += `\n## Messages from topic: ${source.topic}\n\n`;
|
|
202
|
-
for (const msg of messages) {
|
|
203
|
-
context += `[${new Date(msg.timestamp).toISOString()}] ${msg.sender}:\n`;
|
|
204
|
-
if (msg.content?.text) {
|
|
205
|
-
context += `${msg.content.text}\n`;
|
|
206
|
-
}
|
|
207
|
-
if (msg.content?.data) {
|
|
208
|
-
context += `Data: ${JSON.stringify(msg.content.data, null, 2)}\n`;
|
|
209
|
-
}
|
|
210
|
-
context += '\n';
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// Add triggering message
|
|
216
|
-
context += `\n## Triggering Message\n\n`;
|
|
217
|
-
context += `Topic: ${triggeringMessage.topic}\n`;
|
|
218
|
-
context += `Sender: ${triggeringMessage.sender}\n`;
|
|
219
|
-
if (triggeringMessage.content?.text) {
|
|
220
|
-
context += `\n${triggeringMessage.content.text}\n`;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// DEFENSIVE TRUNCATION - Prevent context overflow errors
|
|
224
|
-
// Strategy: Keep ISSUE_OPENED (original task) + most recent messages
|
|
225
|
-
// Truncate from MIDDLE (oldest context messages) if too long
|
|
226
|
-
const originalLength = context.length;
|
|
227
|
-
|
|
228
|
-
if (originalLength > MAX_CONTEXT_CHARS) {
|
|
229
|
-
console.log(
|
|
230
|
-
`[Context] Context too large (${originalLength} chars), truncating to prevent overflow...`
|
|
231
|
-
);
|
|
232
|
-
|
|
233
|
-
// Split context into sections
|
|
234
|
-
const lines = context.split('\n');
|
|
235
|
-
|
|
236
|
-
// Find critical sections that must be preserved
|
|
237
|
-
let issueOpenedStart = -1;
|
|
238
|
-
let issueOpenedEnd = -1;
|
|
239
|
-
let triggeringStart = -1;
|
|
240
|
-
|
|
241
|
-
for (let i = 0; i < lines.length; i++) {
|
|
242
|
-
if (lines[i].includes('## Messages from topic: ISSUE_OPENED')) {
|
|
243
|
-
issueOpenedStart = i;
|
|
244
|
-
}
|
|
245
|
-
if (issueOpenedStart !== -1 && issueOpenedEnd === -1 && lines[i].startsWith('## ')) {
|
|
246
|
-
issueOpenedEnd = i;
|
|
247
|
-
}
|
|
248
|
-
if (lines[i].includes('## Triggering Message')) {
|
|
249
|
-
triggeringStart = i;
|
|
250
|
-
break;
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
// Build truncated context:
|
|
255
|
-
// 1. Header (agent info, instructions, output format)
|
|
256
|
-
// 2. ISSUE_OPENED message (original task - NEVER truncate)
|
|
257
|
-
// 3. Most recent N messages (whatever fits in budget)
|
|
258
|
-
// 4. Triggering message (current event)
|
|
259
|
-
|
|
260
|
-
const headerEnd = issueOpenedStart !== -1 ? issueOpenedStart : triggeringStart;
|
|
261
|
-
const header = lines.slice(0, headerEnd).join('\n');
|
|
262
|
-
|
|
263
|
-
const issueOpened =
|
|
264
|
-
issueOpenedStart !== -1 && issueOpenedEnd !== -1
|
|
265
|
-
? lines.slice(issueOpenedStart, issueOpenedEnd).join('\n')
|
|
266
|
-
: '';
|
|
267
|
-
|
|
268
|
-
const triggeringMsg = lines.slice(triggeringStart).join('\n');
|
|
269
|
-
|
|
270
|
-
// Calculate remaining budget for recent messages
|
|
271
|
-
const fixedSize = header.length + issueOpened.length + triggeringMsg.length;
|
|
272
|
-
const budgetForRecent = MAX_CONTEXT_CHARS - fixedSize - 200; // 200 char buffer for markers
|
|
273
|
-
|
|
274
|
-
// Collect recent messages (from end backwards until budget exhausted)
|
|
275
|
-
const recentLines = [];
|
|
276
|
-
let recentSize = 0;
|
|
277
|
-
|
|
278
|
-
const middleStart = issueOpenedEnd !== -1 ? issueOpenedEnd : headerEnd;
|
|
279
|
-
const middleEnd = triggeringStart;
|
|
280
|
-
const middleLines = lines.slice(middleStart, middleEnd);
|
|
281
|
-
|
|
282
|
-
for (let i = middleLines.length - 1; i >= 0; i--) {
|
|
283
|
-
const line = middleLines[i];
|
|
284
|
-
const lineSize = line.length + 1; // +1 for newline
|
|
285
|
-
|
|
286
|
-
if (recentSize + lineSize > budgetForRecent) {
|
|
287
|
-
break; // Budget exhausted
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
recentLines.unshift(line);
|
|
291
|
-
recentSize += lineSize;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
// Assemble truncated context
|
|
295
|
-
const parts = [header];
|
|
296
|
-
|
|
297
|
-
if (issueOpened) {
|
|
298
|
-
parts.push(issueOpened);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
if (recentLines.length < middleLines.length) {
|
|
302
|
-
// Some messages were truncated
|
|
303
|
-
const truncatedCount = middleLines.length - recentLines.length;
|
|
304
|
-
parts.push(
|
|
305
|
-
`\n[...${truncatedCount} earlier context messages truncated to prevent overflow...]\n`
|
|
306
|
-
);
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
if (recentLines.length > 0) {
|
|
310
|
-
parts.push(recentLines.join('\n'));
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
parts.push(triggeringMsg);
|
|
314
|
-
|
|
315
|
-
context = parts.join('\n');
|
|
316
|
-
|
|
317
|
-
const truncatedLength = context.length;
|
|
318
|
-
console.log(
|
|
319
|
-
`[Context] Truncated from ${originalLength} to ${truncatedLength} chars (${Math.round((truncatedLength / originalLength) * 100)}% retained)`
|
|
320
|
-
);
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
// Legacy maxTokens check (for backward compatibility with agent configs)
|
|
324
|
-
const maxTokens = strategy.maxTokens || 100000;
|
|
325
|
-
const maxChars = maxTokens * 4;
|
|
326
|
-
if (context.length > maxChars) {
|
|
327
|
-
context = context.slice(0, maxChars) + '\n\n[Context truncated...]';
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
return context;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
module.exports = {
|
|
334
|
-
buildContext,
|
|
335
|
-
};
|