@wrongstack/core 0.302.2 → 0.305.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/README.md +1 -1
- package/dist/chronicle/index.js +117 -30
- package/dist/chronicle/project-server.js +12 -5
- package/dist/coordination/agents/index.js +4645 -3448
- package/dist/coordination/agents/project-agent-auto-optimize.d.ts +116 -0
- package/dist/coordination/agents/project-agent-capture-window.d.ts +29 -0
- package/dist/coordination/agents/project-agent-config-io.d.ts +11 -0
- package/dist/coordination/agents/project-agent-consolidation.d.ts +34 -2
- package/dist/coordination/agents/project-agent-directive-outcome.d.ts +57 -0
- package/dist/coordination/agents/project-agent-files.d.ts +12 -3
- package/dist/coordination/agents/project-agent-identity-types.d.ts +4 -0
- package/dist/coordination/agents/project-agent-identity.d.ts +38 -11
- package/dist/coordination/agents/project-agent-learning-entries.d.ts +8 -2
- package/dist/coordination/agents/project-agent-learning-policy.d.ts +22 -1
- package/dist/coordination/agents/project-agent-learning-structured.d.ts +72 -1
- package/dist/coordination/agents/project-agent-optimizer.d.ts +49 -0
- package/dist/coordination/agents/project-agent-quarantine.d.ts +63 -0
- package/dist/coordination/agents/project-agent-skill-layer.d.ts +146 -0
- package/dist/coordination/agents/role-skills.d.ts +11 -1
- package/dist/coordination/agents/types.d.ts +10 -2
- package/dist/coordination/director-prompts.d.ts +19 -6
- package/dist/coordination/director-tools.d.ts +2 -2
- package/dist/coordination/fleet.d.ts +0 -6
- package/dist/coordination/index.d.ts +1 -1
- package/dist/coordination/index.js +5746 -4326
- package/dist/coordination/mail-tools.d.ts +1 -1
- package/dist/core/agent-types.d.ts +4 -2
- package/dist/core/agent.d.ts +1 -0
- package/dist/core/context.d.ts +19 -0
- package/dist/core/conversation-state.d.ts +14 -0
- package/dist/core/fallback-profile-manager.d.ts +70 -2
- package/dist/core/index.js +317 -108
- package/dist/core/system-prompt-blocks.d.ts +1 -1
- package/dist/core/system-prompt-builder.d.ts +13 -1
- package/dist/core/system-prompt-glossary.d.ts +73 -0
- package/dist/core/system-prompt-memory-skills.d.ts +2 -2
- package/dist/defaults/index.js +1635 -1120
- package/dist/execution/council-orchestrator.d.ts +3 -13
- package/dist/execution/index.js +3136 -2706
- package/dist/execution/one-shot-llm.d.ts +5 -0
- package/dist/goal/index.js +7 -0
- package/dist/hq/index.js +17 -7
- package/dist/hq/protocol/kanban.d.ts +21 -0
- package/dist/hq/protocol.js +5 -1
- package/dist/hq/redaction.d.ts +14 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +5502 -3483
- package/dist/infrastructure/index.js +247 -122
- package/dist/kernel/events/agent-events.d.ts +28 -0
- package/dist/plugin/index.js +111 -7
- package/dist/registry/index.js +11 -0
- package/dist/registry/tool-registry.d.ts +8 -0
- package/dist/replay/hash.d.ts +9 -0
- package/dist/replay/index.js +14 -4
- package/dist/replay/replay-provider-runner.d.ts +31 -1
- package/dist/security/index.js +92 -21
- package/dist/security/kanban-boundary.d.ts +5 -1
- package/dist/security/secret-vault.d.ts +2 -0
- package/dist/session-catalog/index.js +86 -10
- package/dist/session-catalog/project-server.js +100 -17
- package/dist/session-catalog/protocol.d.ts +20 -4
- package/dist/session-catalog/store.d.ts +19 -3
- package/dist/storage/index.js +305 -69
- package/dist/storage/memory-consolidator.d.ts +4 -2
- package/dist/storage/plan-store.d.ts +1 -1
- package/dist/storage/session-resume-validation.d.ts +24 -0
- package/dist/storage/session-store/directory-scan.d.ts +5 -1
- package/dist/storage/session-store/fork-session.d.ts +13 -1
- package/dist/storage/session-store/load-cache.d.ts +11 -0
- package/dist/storage/session-store/prune-helpers.d.ts +5 -0
- package/dist/storage/session-store.d.ts +18 -0
- package/dist/tasking/index.js +5 -0
- package/dist/tools/index.js +1151 -831
- package/dist/types/config/mcp-features.d.ts +31 -1
- package/dist/types/config/root.d.ts +23 -1
- package/dist/types/config/skills-fleet-brain.d.ts +34 -0
- package/dist/types/config/tools.d.ts +22 -0
- package/dist/types/config/ui.d.ts +14 -0
- package/dist/types/config.d.ts +1 -0
- package/dist/types/default-config.d.ts +1 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.js +23 -0
- package/dist/types/multi-agent.d.ts +7 -0
- package/dist/types/session.d.ts +9 -1
- package/dist/types/task-graph.d.ts +2 -0
- package/dist/types/tool-executor.d.ts +2 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +217 -76
- package/dist/utils/project-state-guard.d.ts +21 -0
- package/dist/utils/session-scoped-path.d.ts +17 -0
- package/dist/utils/todos-format.d.ts +20 -0
- package/instructions/leader-after-task.md +3 -4
- package/instructions/system-lite.md +17 -14
- package/instructions/system-pro.md +29 -30
- package/instructions/system.md +29 -28
- package/package.json +3 -3
- package/skills/wrongstack-kanban/SKILL.md +95 -93
package/dist/core/index.js
CHANGED
|
@@ -2177,12 +2177,11 @@ function redactHqValueInternal(value, options, preserveRawContentKeys) {
|
|
|
2177
2177
|
});
|
|
2178
2178
|
return { value: result.value, redacted: result.redacted };
|
|
2179
2179
|
}
|
|
2180
|
+
function redactHqEventPayload(type, payload, options = {}) {
|
|
2181
|
+
return redactHqValueInternal(payload, options, HQ_PROJECT_STATE_EVENT_TYPES.has(type));
|
|
2182
|
+
}
|
|
2180
2183
|
function redactHqEvent(event, options = {}) {
|
|
2181
|
-
const payload =
|
|
2182
|
-
event.payload,
|
|
2183
|
-
options,
|
|
2184
|
-
HQ_PROJECT_STATE_EVENT_TYPES.has(event.type)
|
|
2185
|
-
);
|
|
2184
|
+
const payload = redactHqEventPayload(event.type, event.payload, options);
|
|
2186
2185
|
const nextEvent = {
|
|
2187
2186
|
...event,
|
|
2188
2187
|
payload: payload.value
|
|
@@ -2334,7 +2333,9 @@ function queuedFrameCoalesceKey(frame) {
|
|
|
2334
2333
|
if (frame.type !== "client.event" || !frame.event.type.endsWith(".snapshot")) {
|
|
2335
2334
|
return void 0;
|
|
2336
2335
|
}
|
|
2337
|
-
|
|
2336
|
+
const payload = frame.event.payload;
|
|
2337
|
+
const chunk = typeof payload?.chunkIndex === "number" && Number.isFinite(payload.chunkIndex) ? String(payload.chunkIndex) : "";
|
|
2338
|
+
return [frame.event.type, frame.event.sessionId ?? "", frame.event.runId ?? "", chunk].join("|");
|
|
2338
2339
|
}
|
|
2339
2340
|
function defaultSocketFactory(url) {
|
|
2340
2341
|
const WebSocketCtor = globalThis.WebSocket;
|
|
@@ -2667,6 +2668,10 @@ var HqPublisher = class {
|
|
|
2667
2668
|
if (bytes > this.maxQueuedBytes) {
|
|
2668
2669
|
this.droppedFrames += 1;
|
|
2669
2670
|
this.droppedBytes += bytes;
|
|
2671
|
+
process.emitWarning(
|
|
2672
|
+
`HQ telemetry frame of ${bytes} bytes exceeds the ${this.maxQueuedBytes}-byte offline queue cap and was dropped.`,
|
|
2673
|
+
{ code: "WRONGSTACK_HQ_FRAME_TOO_LARGE" }
|
|
2674
|
+
);
|
|
2670
2675
|
return;
|
|
2671
2676
|
}
|
|
2672
2677
|
if (coalesceKey !== void 0) {
|
|
@@ -4338,6 +4343,18 @@ function metadataReferencedByText(metadata, haystack) {
|
|
|
4338
4343
|
}
|
|
4339
4344
|
|
|
4340
4345
|
// src/utils/todos-format.ts
|
|
4346
|
+
function formatTodoForModel(todo) {
|
|
4347
|
+
const binding = todo.kanbanBoardId && todo.kanbanTaskId ? ` <kanban ${todo.kanbanBoardId}/${todo.kanbanTaskId}>` : "";
|
|
4348
|
+
const blocked = todo.blockedBy?.length ? ` [blocked by: ${todo.blockedBy.join("; ")}]` : "";
|
|
4349
|
+
return `- [${todo.status}]${blocked} ${todo.content} (${todo.id})${binding}`;
|
|
4350
|
+
}
|
|
4351
|
+
function formatTodosForModel(todos, emptyLine = "- No active todos remain.") {
|
|
4352
|
+
return todos.length ? todos.map(formatTodoForModel).join("\n") : emptyLine;
|
|
4353
|
+
}
|
|
4354
|
+
function hasKanbanBoundTodos(todos) {
|
|
4355
|
+
if (!Array.isArray(todos)) return false;
|
|
4356
|
+
return todos.some((todo) => Boolean(todo.kanbanBoardId && todo.kanbanTaskId));
|
|
4357
|
+
}
|
|
4341
4358
|
function hasOpenTodos(todos) {
|
|
4342
4359
|
if (!Array.isArray(todos) || todos.length === 0) return false;
|
|
4343
4360
|
return todos.some((t2) => t2.status === "pending" || t2.status === "in_progress");
|
|
@@ -4620,6 +4637,12 @@ function getCalibrationState(calibrationKey = CALIBRATION_GLOBAL_KEY) {
|
|
|
4620
4637
|
import * as path10 from "node:path";
|
|
4621
4638
|
|
|
4622
4639
|
// src/core/conversation-state.ts
|
|
4640
|
+
function hasToolResultBlock(message) {
|
|
4641
|
+
return message !== void 0 && Array.isArray(message.content) && message.content.some((block) => block.type === "tool_result");
|
|
4642
|
+
}
|
|
4643
|
+
function hasToolUseBlock(message) {
|
|
4644
|
+
return message?.role === "assistant" && Array.isArray(message.content) && message.content.some((block) => block.type === "tool_use");
|
|
4645
|
+
}
|
|
4623
4646
|
var ConversationState = class {
|
|
4624
4647
|
ctx;
|
|
4625
4648
|
listeners = /* @__PURE__ */ new Set();
|
|
@@ -4687,15 +4710,32 @@ var ConversationState = class {
|
|
|
4687
4710
|
*/
|
|
4688
4711
|
overflowCount(arr) {
|
|
4689
4712
|
let drop = Context.MAX_MESSAGES > 0 ? Math.max(0, arr.length - Context.MAX_MESSAGES) : 0;
|
|
4690
|
-
if (Context.MAX_MESSAGE_TOKENS <= 0) return drop;
|
|
4713
|
+
if (Context.MAX_MESSAGE_TOKENS <= 0) return this.protocolSafeDropCount(arr, drop);
|
|
4691
4714
|
let total = 0;
|
|
4692
4715
|
for (let i = drop; i < arr.length; i++) total += arr[i]?._estTokens ?? 0;
|
|
4693
|
-
if (total <= Context.MAX_MESSAGE_TOKENS) return drop;
|
|
4716
|
+
if (total <= Context.MAX_MESSAGE_TOKENS) return this.protocolSafeDropCount(arr, drop);
|
|
4694
4717
|
while (drop < arr.length - 1 && total > Context.MAX_MESSAGE_TOKENS) {
|
|
4695
4718
|
total -= arr[drop]?._estTokens ?? 0;
|
|
4696
4719
|
drop++;
|
|
4697
4720
|
}
|
|
4698
|
-
return drop;
|
|
4721
|
+
return this.protocolSafeDropCount(arr, drop);
|
|
4722
|
+
}
|
|
4723
|
+
/**
|
|
4724
|
+
* Front eviction must not retain a `tool_result` after evicting the
|
|
4725
|
+
* immediately preceding assistant `tool_use`. Long tool-heavy sessions sit
|
|
4726
|
+
* at the retention cap, so an unsafe boundary would create a fresh orphan on
|
|
4727
|
+
* nearly every append and make the request-time repair discard protocol
|
|
4728
|
+
* history continuously.
|
|
4729
|
+
*
|
|
4730
|
+
* Move the boundary backward to retain the complete exchange for one more
|
|
4731
|
+
* eviction cycle. Moving it forward would also drop non-protocol text/images
|
|
4732
|
+
* that may share either message. The temporary one-message cap overshoot is
|
|
4733
|
+
* the minimum lossless representation; once enough newer messages exist, the
|
|
4734
|
+
* next eviction boundary naturally moves past both halves together.
|
|
4735
|
+
*/
|
|
4736
|
+
protocolSafeDropCount(arr, drop) {
|
|
4737
|
+
if (drop <= 0 || drop >= arr.length) return drop;
|
|
4738
|
+
return hasToolResultBlock(arr[drop]) && hasToolUseBlock(arr[drop - 1]) ? drop - 1 : drop;
|
|
4699
4739
|
}
|
|
4700
4740
|
/**
|
|
4701
4741
|
* Append a content block to the trailing user message's content array.
|
|
@@ -5103,6 +5143,28 @@ var Context = class _Context {
|
|
|
5103
5143
|
return _Context.CONVERSATION_JOURNAL_MAX_BYTES + 1;
|
|
5104
5144
|
}
|
|
5105
5145
|
}
|
|
5146
|
+
_journalDropCount = 0;
|
|
5147
|
+
_journalDropWarnAt = 0;
|
|
5148
|
+
/** Throttled notice that a conversation event never reached the journal. */
|
|
5149
|
+
warnConversationJournalDrop(eventType) {
|
|
5150
|
+
this._journalDropCount++;
|
|
5151
|
+
const now = Date.now();
|
|
5152
|
+
if (now - this._journalDropWarnAt < 5e3) return;
|
|
5153
|
+
this._journalDropWarnAt = now;
|
|
5154
|
+
const dropped = this._journalDropCount;
|
|
5155
|
+
this._journalDropCount = 0;
|
|
5156
|
+
console.warn(
|
|
5157
|
+
JSON.stringify({
|
|
5158
|
+
level: "error",
|
|
5159
|
+
event: "session.conversation_journal_drop",
|
|
5160
|
+
sessionId: this.session?.id,
|
|
5161
|
+
eventType,
|
|
5162
|
+
droppedEvents: dropped,
|
|
5163
|
+
message: "Session writer is not draining; replay of this session will be incomplete.",
|
|
5164
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
5165
|
+
})
|
|
5166
|
+
);
|
|
5167
|
+
}
|
|
5106
5168
|
enqueueConversationJournal(event, writer) {
|
|
5107
5169
|
const bytes = this.conversationJournalBytes(event);
|
|
5108
5170
|
const shouldSnapshot = event.type === "messages_replaced" || this._conversationJournalQueue.length >= _Context.CONVERSATION_JOURNAL_MAX_EVENTS || this._conversationJournalBytes + bytes > _Context.CONVERSATION_JOURNAL_MAX_BYTES;
|
|
@@ -5120,18 +5182,21 @@ var Context = class _Context {
|
|
|
5120
5182
|
this._conversationJournalBytes = Math.max(0, this._conversationJournalBytes - queued.bytes);
|
|
5121
5183
|
this._conversationJournalQueue.splice(index, 1);
|
|
5122
5184
|
}
|
|
5123
|
-
|
|
5124
|
-
|
|
5125
|
-
this._conversationJournalBytes += snapshotBytes;
|
|
5126
|
-
}
|
|
5185
|
+
this._conversationJournalQueue.push({ event: snapshot, bytes: snapshotBytes, writer });
|
|
5186
|
+
this._conversationJournalBytes += snapshotBytes;
|
|
5127
5187
|
} else {
|
|
5128
5188
|
this._conversationJournalQueue.push({ event, bytes, writer });
|
|
5129
5189
|
this._conversationJournalBytes += bytes;
|
|
5130
5190
|
}
|
|
5131
5191
|
while (this._conversationJournalQueue.length > _Context.CONVERSATION_JOURNAL_MAX_EVENTS || this._conversationJournalBytes > _Context.CONVERSATION_JOURNAL_MAX_BYTES) {
|
|
5132
|
-
const
|
|
5192
|
+
const index = this._conversationJournalQueue.findIndex(
|
|
5193
|
+
(queued) => queued.event.type !== "messages_replaced"
|
|
5194
|
+
);
|
|
5195
|
+
if (index === -1) break;
|
|
5196
|
+
const [dropped] = this._conversationJournalQueue.splice(index, 1);
|
|
5133
5197
|
if (!dropped) break;
|
|
5134
5198
|
this._conversationJournalBytes = Math.max(0, this._conversationJournalBytes - dropped.bytes);
|
|
5199
|
+
this.warnConversationJournalDrop(dropped.event.type);
|
|
5135
5200
|
}
|
|
5136
5201
|
this.startConversationJournalDrain();
|
|
5137
5202
|
}
|
|
@@ -5369,6 +5434,12 @@ var Context = class _Context {
|
|
|
5369
5434
|
setCurrentKanbanTask(taskId, boardId) {
|
|
5370
5435
|
this.currentKanbanTaskId = taskId;
|
|
5371
5436
|
this.currentKanbanBoardId = boardId;
|
|
5437
|
+
const existing = this.meta["kanban"] && typeof this.meta["kanban"] === "object" ? this.meta["kanban"] : {};
|
|
5438
|
+
this.state.setMeta("kanban", {
|
|
5439
|
+
...existing,
|
|
5440
|
+
...taskId ? { taskId } : { taskId: void 0 },
|
|
5441
|
+
...boardId ? { boardId } : { boardId: void 0 }
|
|
5442
|
+
});
|
|
5372
5443
|
}
|
|
5373
5444
|
/**
|
|
5374
5445
|
* Record a comprehensive file event for the audit trail.
|
|
@@ -7087,6 +7158,9 @@ ${text}` : text;
|
|
|
7087
7158
|
const responseProvider = providerBoundToRequest(req) ?? requestProvider;
|
|
7088
7159
|
const responseResult = await handlers.response.processResponse(res, req, responseProvider);
|
|
7089
7160
|
await refreshProviderContextLimit(responseProvider, req.model, { probe: false });
|
|
7161
|
+
if (responseResult.finalText) {
|
|
7162
|
+
a.ctx.meta["lastAgentOutput"] = responseResult.finalText;
|
|
7163
|
+
}
|
|
7090
7164
|
if (responseResult.aborted) {
|
|
7091
7165
|
return {
|
|
7092
7166
|
status: "aborted",
|
|
@@ -7211,7 +7285,7 @@ ${text}` : text;
|
|
|
7211
7285
|
if (a.ctx.agentId === "leader" && a.tools.get("todo") !== void 0 && hasOpenTodos(a.ctx.todos) && todoReconcileSteers < 2) {
|
|
7212
7286
|
todoReconcileSteers++;
|
|
7213
7287
|
queueLoopSteer(
|
|
7214
|
-
"[todo-reconciliation] The live todo/Kanban list still has open work, but you tried to end the turn without reconciling it. Call the `todo` tool now with the complete current list. Mark work you actually finished as completed, put the one item you are actively working on in_progress, and leave the rest pending. If the current item is genuinely unfinished, continue doing the work before answering; do not merely repeat the previous final response or emit <nextsteps
|
|
7288
|
+
"[todo-reconciliation] The live todo/Kanban list still has open work, but you tried to end the turn without reconciling it. Call the `todo` tool now with the complete current list. Mark work you actually finished as completed, put the one item you are actively working on in_progress, and leave the rest pending. If the current item is genuinely unfinished, continue doing the work before answering; do not merely repeat the previous final response or emit <nextsteps>.\nCanonical live list:\n" + formatTodosForModel(a.ctx.todos) + (hasKanbanBoundTodos(a.ctx.todos) ? "\nEach <kanban board/task> binding must be resent verbatim as `kanbanBoardId`/`kanbanTaskId`; a row without it is not applied to its card." : "")
|
|
7215
7289
|
);
|
|
7216
7290
|
await a.extensions.runAfterIteration(a.ctx, i);
|
|
7217
7291
|
continue;
|
|
@@ -7432,12 +7506,15 @@ function buildLiveNextStepsGateBlock(ctx) {
|
|
|
7432
7506
|
const todoSnapshot = openTodos.slice(0, MAX_TODO_SNAPSHOT_ITEMS).map((todo) => {
|
|
7433
7507
|
const normalized = todo.content.replace(/\s+/g, " ").trim();
|
|
7434
7508
|
const content = normalized.length > MAX_TODO_SNAPSHOT_CONTENT ? `${normalized.slice(0, MAX_TODO_SNAPSHOT_CONTENT - 1)}\u2026` : normalized;
|
|
7435
|
-
return
|
|
7509
|
+
return formatTodoForModel({ ...todo, content });
|
|
7436
7510
|
});
|
|
7437
7511
|
const omitted = openTodos.length - todoSnapshot.length;
|
|
7438
7512
|
if (omitted > 0) todoSnapshot.push(`- \u2026and ${omitted} more open todo(s)`);
|
|
7439
7513
|
const todoReconciliation = ctx.tools?.some((tool) => tool.name === "todo") ? [
|
|
7440
|
-
"Before ending the turn, you MUST call the `todo` tool with the complete current list to reconcile actual progress: finished items completed, exactly one actively worked item in_progress, and untouched items pending. A prose claim that work is done does not update the Todo/Kanban state."
|
|
7514
|
+
"Before ending the turn, you MUST call the `todo` tool with the complete current list to reconcile actual progress: finished items completed, exactly one actively worked item in_progress, and untouched items pending. A prose claim that work is done does not update the Todo/Kanban state.",
|
|
7515
|
+
...hasKanbanBoundTodos(openTodos) ? [
|
|
7516
|
+
"Rows below carry a <kanban board/task> binding. Pass those exact ids back as `kanbanBoardId`/`kanbanTaskId` on every row you resend; a row that arrives without its binding is not applied to its card."
|
|
7517
|
+
] : []
|
|
7441
7518
|
] : [];
|
|
7442
7519
|
return {
|
|
7443
7520
|
type: "text",
|
|
@@ -8153,6 +8230,7 @@ var Agent = class {
|
|
|
8153
8230
|
/** Resolved loop-detector settings (see `tools.loopDetection`). */
|
|
8154
8231
|
loopDetection;
|
|
8155
8232
|
autonomousContinue;
|
|
8233
|
+
refreshSystemPrompt;
|
|
8156
8234
|
tracer;
|
|
8157
8235
|
extensions;
|
|
8158
8236
|
_toolHandler;
|
|
@@ -8182,6 +8260,7 @@ var Agent = class {
|
|
|
8182
8260
|
this.autoExtendLimit = init.autoExtendLimit ?? true;
|
|
8183
8261
|
this.loopDetection = resolveLoopDetection(init.loopDetection);
|
|
8184
8262
|
this.autonomousContinue = init.autonomousContinue ?? false;
|
|
8263
|
+
this.refreshSystemPrompt = init.refreshSystemPrompt ?? false;
|
|
8185
8264
|
this.tracer = init.tracer;
|
|
8186
8265
|
this.extensions = init.extensions ?? new ExtensionRegistry();
|
|
8187
8266
|
this._logger = this.container.resolve(TOKENS.Logger).child({ sessionId: this.ctx.session.id });
|
|
@@ -8259,6 +8338,7 @@ var Agent = class {
|
|
|
8259
8338
|
context: { phase: "concurrency-guard" }
|
|
8260
8339
|
});
|
|
8261
8340
|
}
|
|
8341
|
+
let newInputHash;
|
|
8262
8342
|
const inputText = typeof userInput === "string" ? userInput : userInput?.prompt ?? "";
|
|
8263
8343
|
if (inputText.length > 0) {
|
|
8264
8344
|
const hash2 = createHash7("sha256").update(inputText).digest("hex");
|
|
@@ -8268,7 +8348,7 @@ var Agent = class {
|
|
|
8268
8348
|
iterations: 0
|
|
8269
8349
|
};
|
|
8270
8350
|
}
|
|
8271
|
-
|
|
8351
|
+
newInputHash = hash2;
|
|
8272
8352
|
}
|
|
8273
8353
|
this._runInProgress = true;
|
|
8274
8354
|
const controller = new RunController({ parentSignal: opts.signal });
|
|
@@ -8285,16 +8365,33 @@ var Agent = class {
|
|
|
8285
8365
|
});
|
|
8286
8366
|
this.ctx.tools = this.tools.listForProvider();
|
|
8287
8367
|
this.ctx.catalogTools = this.tools.list();
|
|
8288
|
-
const span = this.tracer?.startSpan("agent.run", {
|
|
8289
|
-
"agent.model": opts.model ?? this.ctx.model,
|
|
8290
|
-
"agent.executionStrategy": opts.executionStrategy ?? this.executionStrategy
|
|
8291
|
-
});
|
|
8292
|
-
const { blocks, text } = normalizeInput(userInput);
|
|
8293
|
-
const inputPayload = { content: blocks, text, ctx: this.ctx };
|
|
8294
|
-
await this.extensions.runBeforeRun(this.ctx, inputPayload);
|
|
8295
8368
|
const runStartedAt = Date.now();
|
|
8296
8369
|
const runStartedIso = new Date(runStartedAt).toISOString();
|
|
8370
|
+
let span;
|
|
8297
8371
|
try {
|
|
8372
|
+
if (this.refreshSystemPrompt) {
|
|
8373
|
+
const builder = this.container.safeResolve(TOKENS.SystemPromptBuilder);
|
|
8374
|
+
if (builder) {
|
|
8375
|
+
const onlineAgents = Array.isArray(this.ctx.meta["promptOnlineAgents"]) ? this.ctx.meta["promptOnlineAgents"] : void 0;
|
|
8376
|
+
this.ctx.systemPrompt = await builder.build({
|
|
8377
|
+
cwd: this.ctx.cwd,
|
|
8378
|
+
projectRoot: this.ctx.projectRoot,
|
|
8379
|
+
tools: this.ctx.tools,
|
|
8380
|
+
catalogTools: this.ctx.catalogTools,
|
|
8381
|
+
provider: this.ctx.provider.id,
|
|
8382
|
+
model: opts.model ?? this.ctx.model,
|
|
8383
|
+
onlineAgents
|
|
8384
|
+
});
|
|
8385
|
+
}
|
|
8386
|
+
}
|
|
8387
|
+
span = this.tracer?.startSpan("agent.run", {
|
|
8388
|
+
"agent.model": opts.model ?? this.ctx.model,
|
|
8389
|
+
"agent.executionStrategy": opts.executionStrategy ?? this.executionStrategy
|
|
8390
|
+
});
|
|
8391
|
+
const { blocks, text } = normalizeInput(userInput);
|
|
8392
|
+
const inputPayload = { content: blocks, text, ctx: this.ctx };
|
|
8393
|
+
await this.extensions.runBeforeRun(this.ctx, inputPayload);
|
|
8394
|
+
this._lastInputHash = newInputHash;
|
|
8298
8395
|
this.events.emit("agent.run.started", {
|
|
8299
8396
|
sessionId,
|
|
8300
8397
|
ctx: this.ctx,
|
|
@@ -8762,12 +8859,97 @@ var FallbackProfileManager = class {
|
|
|
8762
8859
|
return this.resolveRefs([ref], exclude);
|
|
8763
8860
|
}
|
|
8764
8861
|
/**
|
|
8765
|
-
* Resolve every usable configured target as
|
|
8862
|
+
* Resolve every usable configured target as a bounded last-resort chain.
|
|
8766
8863
|
* Normal smart defaults stay bounded; callers append this only after the
|
|
8767
|
-
* preferred chain and only when automatic fallback is enabled.
|
|
8864
|
+
* preferred chain and only when automatic fallback is enabled. The cap
|
|
8865
|
+
* ({@link MAX_LAST_RESORT_CANDIDATES}) prevents a config with many providers
|
|
8866
|
+
* from producing a degenerate chain of doomed requests during a systemic
|
|
8867
|
+
* outage — by this point the smart default, bridge, and default profile
|
|
8868
|
+
* have already failed.
|
|
8768
8869
|
*/
|
|
8769
8870
|
resolveAllConfigured(exclude) {
|
|
8770
|
-
return this.smartDefault(exclude,
|
|
8871
|
+
return this.smartDefault(exclude, this.lastResortCap());
|
|
8872
|
+
}
|
|
8873
|
+
/**
|
|
8874
|
+
* Effective cap for the last-resort append. Reads the user-configurable
|
|
8875
|
+
* {@link Config.fallbackMaxLastResortCandidates} when set and valid;
|
|
8876
|
+
* otherwise falls back to the compiled-in default
|
|
8877
|
+
* {@link MAX_LAST_RESORT_CANDIDATES}.
|
|
8878
|
+
*/
|
|
8879
|
+
lastResortCap() {
|
|
8880
|
+
const configured = this.config.fallbackMaxLastResortCandidates;
|
|
8881
|
+
if (typeof configured === "number" && Number.isFinite(configured) && configured >= 0) {
|
|
8882
|
+
return Math.floor(configured);
|
|
8883
|
+
}
|
|
8884
|
+
return MAX_LAST_RESORT_CANDIDATES;
|
|
8885
|
+
}
|
|
8886
|
+
/**
|
|
8887
|
+
* Build the complete fallback candidate chain shared by the agent-loop
|
|
8888
|
+
* extension and the one-shot orchestrator. Centralizes the bridge → primary →
|
|
8889
|
+
* selected → default-profile → all-configured ladder and the fromExplicitSource
|
|
8890
|
+
* gate so both consumers produce identical ordering and depth semantics.
|
|
8891
|
+
*
|
|
8892
|
+
* Layering (each step deduped against all prior):
|
|
8893
|
+
* 1. Bridge (emergency continuity route).
|
|
8894
|
+
* 2. Configured primary, when the live context drifted from it.
|
|
8895
|
+
* 3. The selected chain (explicit refs → named profile → smart default),
|
|
8896
|
+
* via {@link resolveEffective}.
|
|
8897
|
+
* 4. The "default" profile — extra depth, ONLY when the chain was auto-derived.
|
|
8898
|
+
* 5. Every other configured provider — last resort, ONLY when the chain was
|
|
8899
|
+
* auto-derived AND `effectiveFallbackAuto` is true.
|
|
8900
|
+
*
|
|
8901
|
+
* Returns the empty chain when `closedWorld` is true and no explicit
|
|
8902
|
+
* refs/profile resolved — a model allowlist never leaks to unlisted models.
|
|
8903
|
+
*
|
|
8904
|
+
* @internal caller-aware options (primary, closedWorld) are accepted because
|
|
8905
|
+
* the agent loop has context the manager does not own; the resolution
|
|
8906
|
+
* pipeline itself is identical for both callers.
|
|
8907
|
+
*/
|
|
8908
|
+
resolveCandidates(current, opts = {}) {
|
|
8909
|
+
const configuredPrimary = opts.primary ?? {
|
|
8910
|
+
providerId: this.config.provider,
|
|
8911
|
+
model: this.config.model
|
|
8912
|
+
};
|
|
8913
|
+
const configFallbackAuto = this.config.fallbackAuto;
|
|
8914
|
+
const effectiveFallbackAuto = configFallbackAuto !== void 0 && configFallbackAuto !== null ? configFallbackAuto : !opts.closedWorld;
|
|
8915
|
+
const explicitRefs = opts.fallbackModels ?? this.config.fallbackModels;
|
|
8916
|
+
const explicitUsable = explicitRefs !== void 0 && explicitRefs.length > 0 && this.resolveRefs(explicitRefs, current).length > 0;
|
|
8917
|
+
const profileUsable = opts.fallbackProfile !== void 0 && this.hasProfile(opts.fallbackProfile) && this.resolve(opts.fallbackProfile, { exclude: current }).length > 0;
|
|
8918
|
+
const fromExplicitSource = explicitUsable || profileUsable;
|
|
8919
|
+
const selectedChain = opts.closedWorld ? explicitRefs && explicitRefs.length > 0 ? this.resolveRefs(explicitRefs, current) : opts.fallbackProfile ? this.resolve(opts.fallbackProfile, { exclude: current }) : FREEZER_EMPTY : this.resolveEffective({
|
|
8920
|
+
fallbackModels: explicitRefs,
|
|
8921
|
+
fallbackProfile: opts.fallbackProfile,
|
|
8922
|
+
fallbackAuto: effectiveFallbackAuto,
|
|
8923
|
+
exclude: current
|
|
8924
|
+
});
|
|
8925
|
+
const candidates = [];
|
|
8926
|
+
if (opts.closedWorld) {
|
|
8927
|
+
candidates.push(...selectedChain);
|
|
8928
|
+
} else {
|
|
8929
|
+
candidates.push(...this.resolveBridge(current));
|
|
8930
|
+
if (!(configuredPrimary.providerId === current.providerId && configuredPrimary.model === current.model)) {
|
|
8931
|
+
candidates.push({
|
|
8932
|
+
providerId: configuredPrimary.providerId,
|
|
8933
|
+
model: configuredPrimary.model,
|
|
8934
|
+
providerSwitched: configuredPrimary.providerId !== current.providerId
|
|
8935
|
+
});
|
|
8936
|
+
}
|
|
8937
|
+
candidates.push(...selectedChain);
|
|
8938
|
+
if (!fromExplicitSource && effectiveFallbackAuto && opts.fallbackProfile !== "default") {
|
|
8939
|
+
candidates.push(...this.resolve("default", { exclude: current }));
|
|
8940
|
+
}
|
|
8941
|
+
if (!fromExplicitSource && effectiveFallbackAuto) {
|
|
8942
|
+
const cap = this.lastResortCap();
|
|
8943
|
+
if (cap > 0) {
|
|
8944
|
+
const usedKeys = new Set(
|
|
8945
|
+
candidates.map((c) => `${c.providerId}/${c.model}`)
|
|
8946
|
+
);
|
|
8947
|
+
const lastResort = this.smartDefault(current, Number.POSITIVE_INFINITY).filter((c) => !usedKeys.has(`${c.providerId}/${c.model}`)).slice(0, cap);
|
|
8948
|
+
candidates.push(...lastResort);
|
|
8949
|
+
}
|
|
8950
|
+
}
|
|
8951
|
+
}
|
|
8952
|
+
return dedupeChain(candidates, current);
|
|
8771
8953
|
}
|
|
8772
8954
|
// ── Provider availability (read-only) ──────────────────────────────────
|
|
8773
8955
|
checkProvider(providerId) {
|
|
@@ -8891,7 +9073,20 @@ var FallbackProfileManager = class {
|
|
|
8891
9073
|
);
|
|
8892
9074
|
}
|
|
8893
9075
|
};
|
|
9076
|
+
var MAX_LAST_RESORT_CANDIDATES = 12;
|
|
8894
9077
|
var FREEZER_EMPTY = Object.freeze([]);
|
|
9078
|
+
function dedupeChain(entries, current) {
|
|
9079
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9080
|
+
const currentKey = `${current.providerId}/${current.model}`;
|
|
9081
|
+
return Object.freeze(
|
|
9082
|
+
entries.filter((entry) => {
|
|
9083
|
+
const key = `${entry.providerId}/${entry.model}`;
|
|
9084
|
+
if (key === currentKey || seen.has(key)) return false;
|
|
9085
|
+
seen.add(key);
|
|
9086
|
+
return true;
|
|
9087
|
+
})
|
|
9088
|
+
);
|
|
9089
|
+
}
|
|
8895
9090
|
|
|
8896
9091
|
// src/core/fallback-model.ts
|
|
8897
9092
|
function fallbackProfileChain(config, profileName) {
|
|
@@ -8940,56 +9135,12 @@ function sameTarget(a, b) {
|
|
|
8940
9135
|
}
|
|
8941
9136
|
function fallbackCandidates(config, current, opts = {}) {
|
|
8942
9137
|
const mgr = opts.sharedManager ?? new FallbackProfileManager(config);
|
|
8943
|
-
|
|
8944
|
-
|
|
8945
|
-
const effectiveFallbackAuto = configFallbackAuto !== void 0 && configFallbackAuto !== null ? configFallbackAuto : !opts.closedWorld;
|
|
8946
|
-
const explicitRefs = opts.fallbackModels ?? config.fallbackModels;
|
|
8947
|
-
const explicitUsable = explicitRefs !== void 0 && explicitRefs.length > 0 && mgr.resolveRefs(explicitRefs, current).length > 0;
|
|
8948
|
-
const profileUsable = opts.fallbackProfile !== void 0 && mgr.hasProfile(opts.fallbackProfile) && mgr.resolve(opts.fallbackProfile, { exclude: current }).length > 0;
|
|
8949
|
-
const fromExplicitSource = explicitUsable || profileUsable;
|
|
8950
|
-
const selectedChain = opts.closedWorld ? explicitRefs && explicitRefs.length > 0 ? mgr.resolveRefs(explicitRefs, current) : opts.fallbackProfile ? mgr.resolve(opts.fallbackProfile, { exclude: current }) : Object.freeze([]) : mgr.resolveEffective({
|
|
8951
|
-
fallbackModels: explicitRefs,
|
|
9138
|
+
return mgr.resolveCandidates(current, {
|
|
9139
|
+
fallbackModels: opts.fallbackModels,
|
|
8952
9140
|
fallbackProfile: opts.fallbackProfile,
|
|
8953
|
-
|
|
8954
|
-
|
|
9141
|
+
primary: opts.primary ?? primaryTarget(config),
|
|
9142
|
+
closedWorld: opts.closedWorld
|
|
8955
9143
|
});
|
|
8956
|
-
const candidates = [];
|
|
8957
|
-
if (opts.closedWorld) {
|
|
8958
|
-
candidates.push(...selectedChain);
|
|
8959
|
-
const seen2 = /* @__PURE__ */ new Set();
|
|
8960
|
-
return Object.freeze(
|
|
8961
|
-
candidates.filter((entry) => {
|
|
8962
|
-
const key = `${entry.providerId}/${entry.model}`;
|
|
8963
|
-
if (key === `${current.providerId}/${current.model}` || seen2.has(key)) return false;
|
|
8964
|
-
seen2.add(key);
|
|
8965
|
-
return true;
|
|
8966
|
-
})
|
|
8967
|
-
);
|
|
8968
|
-
}
|
|
8969
|
-
candidates.push(...mgr.resolveBridge(current));
|
|
8970
|
-
if (!sameTarget(configuredPrimary, current)) {
|
|
8971
|
-
candidates.push({
|
|
8972
|
-
providerId: configuredPrimary.providerId,
|
|
8973
|
-
model: configuredPrimary.model,
|
|
8974
|
-
providerSwitched: configuredPrimary.providerId !== current.providerId
|
|
8975
|
-
});
|
|
8976
|
-
}
|
|
8977
|
-
candidates.push(...selectedChain);
|
|
8978
|
-
if (!fromExplicitSource && opts.fallbackProfile !== "default") {
|
|
8979
|
-
candidates.push(...mgr.resolve("default", { exclude: current }));
|
|
8980
|
-
}
|
|
8981
|
-
if (!fromExplicitSource && effectiveFallbackAuto) {
|
|
8982
|
-
candidates.push(...mgr.resolveAllConfigured(current));
|
|
8983
|
-
}
|
|
8984
|
-
const seen = /* @__PURE__ */ new Set();
|
|
8985
|
-
return Object.freeze(
|
|
8986
|
-
candidates.filter((entry) => {
|
|
8987
|
-
const key = `${entry.providerId}/${entry.model}`;
|
|
8988
|
-
if (key === `${current.providerId}/${current.model}` || seen.has(key)) return false;
|
|
8989
|
-
seen.add(key);
|
|
8990
|
-
return true;
|
|
8991
|
-
})
|
|
8992
|
-
);
|
|
8993
9144
|
}
|
|
8994
9145
|
var primaryTarget = (cfg) => ({ providerId: cfg.provider, model: cfg.model });
|
|
8995
9146
|
function maxContextOf(provider) {
|
|
@@ -10491,7 +10642,7 @@ async function buildEnvironment(ctx, env) {
|
|
|
10491
10642
|
]);
|
|
10492
10643
|
const tier = env.tier;
|
|
10493
10644
|
const lines = ["## Environment"];
|
|
10494
|
-
if (tier === "minimal") {
|
|
10645
|
+
if (tier === "minimal" || tier === "aggressive") {
|
|
10495
10646
|
lines.push(`- Git: ${git} | Date: ${today}`);
|
|
10496
10647
|
} else {
|
|
10497
10648
|
lines.push(`- Operating system: ${platform2}`);
|
|
@@ -10499,38 +10650,26 @@ async function buildEnvironment(ctx, env) {
|
|
|
10499
10650
|
lines.push(`- Shell: ${shell}`);
|
|
10500
10651
|
lines.push(`- Node.js: ${node}`);
|
|
10501
10652
|
}
|
|
10502
|
-
if (tier === "off" || tier === "medium"
|
|
10653
|
+
if (tier === "off" || tier === "medium") {
|
|
10503
10654
|
lines.push(`- Detected languages: ${langs}`);
|
|
10504
10655
|
}
|
|
10505
10656
|
lines.push(`- Git status: ${git}`);
|
|
10506
10657
|
lines.push(`- Today's date: ${today}`);
|
|
10507
|
-
if (
|
|
10508
|
-
if (ctx.provider || ctx.model) {
|
|
10509
|
-
lines.push(
|
|
10510
|
-
`- Running on: ${ctx.provider ?? "<unknown provider>"}/${ctx.model ?? "<unknown model>"}`
|
|
10511
|
-
);
|
|
10512
|
-
}
|
|
10513
|
-
if (modelCapabilities) {
|
|
10514
|
-
lines.push(
|
|
10515
|
-
`- Context window: ${modelCapabilities.maxContextTokens.toLocaleString()} tokens max`
|
|
10516
|
-
);
|
|
10517
|
-
}
|
|
10518
|
-
}
|
|
10519
|
-
if (tier !== "aggressive" && modelCapabilities) {
|
|
10658
|
+
if (modelCapabilities) {
|
|
10520
10659
|
lines.push(
|
|
10521
10660
|
`- Context window: ${modelCapabilities.maxContextTokens.toLocaleString()} tokens max`
|
|
10522
10661
|
);
|
|
10523
10662
|
}
|
|
10524
|
-
if (
|
|
10663
|
+
if (ctx.provider || ctx.model) {
|
|
10525
10664
|
lines.push(
|
|
10526
10665
|
`- Running on: ${ctx.provider ?? "<unknown provider>"}/${ctx.model ?? "<unknown model>"}`
|
|
10527
10666
|
);
|
|
10528
10667
|
}
|
|
10529
|
-
if (
|
|
10668
|
+
if (env.modeId && env.modeId !== "default") {
|
|
10530
10669
|
lines.push(`- Mode: ${env.modeId}`);
|
|
10531
10670
|
}
|
|
10532
10671
|
}
|
|
10533
|
-
if (ctx.tools.some((tool) => tool.name === "bash") && effShell !== "posix" && tier !== "minimal") {
|
|
10672
|
+
if (ctx.tools.some((tool) => tool.name === "bash") && effShell !== "posix" && tier !== "minimal" && tier !== "aggressive") {
|
|
10534
10673
|
const guide = shellGuidanceBlock(effShell, tier === "light" ? "short" : "full");
|
|
10535
10674
|
if (guide) lines.push("", guide);
|
|
10536
10675
|
}
|
|
@@ -10553,6 +10692,70 @@ async function buildEnvironment(ctx, env) {
|
|
|
10553
10692
|
return text;
|
|
10554
10693
|
}
|
|
10555
10694
|
|
|
10695
|
+
// src/core/system-prompt-glossary.ts
|
|
10696
|
+
function findDomainGlossaryEntries(memory) {
|
|
10697
|
+
return safeList(memory, { limit: 200 }).then((rows) => rows ?? []).then(
|
|
10698
|
+
(rows) => rows.filter(
|
|
10699
|
+
(r) => Array.isArray(r?.tags) && r.tags.includes("domain-term")
|
|
10700
|
+
)
|
|
10701
|
+
);
|
|
10702
|
+
}
|
|
10703
|
+
async function safeList(memory, opts) {
|
|
10704
|
+
try {
|
|
10705
|
+
const rows = await memory.list("project-memory", opts.limit);
|
|
10706
|
+
if (!Array.isArray(rows) || rows.length === 0) return null;
|
|
10707
|
+
return rows;
|
|
10708
|
+
} catch {
|
|
10709
|
+
return null;
|
|
10710
|
+
}
|
|
10711
|
+
}
|
|
10712
|
+
var GLOSSARY_HEADING = "# Project Jargon Dictionary (auto-mined from SAGE; update via SageDomainTermExtractor)";
|
|
10713
|
+
async function renderDomainGlossary(ctx, memory, options = {}) {
|
|
10714
|
+
if (!memory) return null;
|
|
10715
|
+
const maxEntries = options.maxEntries ?? 12;
|
|
10716
|
+
const maxEntryChars = options.maxEntryChars ?? 80;
|
|
10717
|
+
const entries = await findDomainGlossaryEntries(memory);
|
|
10718
|
+
if (entries.length === 0) return "";
|
|
10719
|
+
const sorted = [...entries].sort((a, b) => {
|
|
10720
|
+
const dc = (b.confidence ?? 0) - (a.confidence ?? 0);
|
|
10721
|
+
if (dc !== 0) return dc;
|
|
10722
|
+
return b.ts.localeCompare(a.ts);
|
|
10723
|
+
});
|
|
10724
|
+
const lines = [GLOSSARY_HEADING, ""];
|
|
10725
|
+
let emitted = 0;
|
|
10726
|
+
for (const entry of sorted) {
|
|
10727
|
+
if (emitted >= maxEntries) break;
|
|
10728
|
+
const { term, definition } = parseTermEntry(entry.text);
|
|
10729
|
+
if (!term) continue;
|
|
10730
|
+
const def = (definition || "").slice(0, maxEntryChars).trim();
|
|
10731
|
+
lines.push(def ? `- **${term}** \u2014 ${def}` : `- **${term}**`);
|
|
10732
|
+
emitted += 1;
|
|
10733
|
+
}
|
|
10734
|
+
if (emitted === 0) return "";
|
|
10735
|
+
lines.push("");
|
|
10736
|
+
lines.push(
|
|
10737
|
+
`_Source: <${ctx.projectRoot}>/.wrongstack/domain-terms.md (auto-generated; do not edit by hand)._`
|
|
10738
|
+
);
|
|
10739
|
+
lines.push(
|
|
10740
|
+
'_Lookup tag: `domain-term` (search: `memory_search({ query: "domain-term", scope: "project-memory" })`)._'
|
|
10741
|
+
);
|
|
10742
|
+
return lines.join("\n");
|
|
10743
|
+
}
|
|
10744
|
+
function parseTermEntry(text) {
|
|
10745
|
+
const trimmed = text.trim();
|
|
10746
|
+
const separators = [" \u2014 ", " \u2013 ", " - ", " -- "];
|
|
10747
|
+
for (const sep of separators) {
|
|
10748
|
+
const idx = trimmed.indexOf(sep);
|
|
10749
|
+
if (idx > 0) {
|
|
10750
|
+
return {
|
|
10751
|
+
term: trimmed.slice(0, idx).trim(),
|
|
10752
|
+
definition: trimmed.slice(idx + sep.length).trim()
|
|
10753
|
+
};
|
|
10754
|
+
}
|
|
10755
|
+
}
|
|
10756
|
+
return { term: trimmed, definition: "" };
|
|
10757
|
+
}
|
|
10758
|
+
|
|
10556
10759
|
// src/skills/limits.ts
|
|
10557
10760
|
var SKILL_LIMITS = {
|
|
10558
10761
|
/**
|
|
@@ -10819,7 +11022,7 @@ function renderOnlineAgents(agents, tier, cache) {
|
|
|
10819
11022
|
return { text: cache.text, cache };
|
|
10820
11023
|
}
|
|
10821
11024
|
const totalCount = agents.length;
|
|
10822
|
-
if (tier === "minimal" || tier === "light") {
|
|
11025
|
+
if (tier === "minimal" || tier === "light" || tier === "aggressive") {
|
|
10823
11026
|
const text2 = ` (${totalCount} agent${totalCount !== 1 ? "s" : ""} online)`;
|
|
10824
11027
|
return { text: text2, cache: { hash: hash2, text: text2 } };
|
|
10825
11028
|
}
|
|
@@ -10844,8 +11047,8 @@ ${agentList}`;
|
|
|
10844
11047
|
async function buildMemoryAndSkills(mem) {
|
|
10845
11048
|
const parts = [];
|
|
10846
11049
|
let skillBodyCache = mem.skillBodyCache;
|
|
10847
|
-
const memoryCount = mem.tier === "minimal" || mem.tier === "light" ? 3 : 5;
|
|
10848
|
-
const compactMemory = mem.tier === "minimal";
|
|
11050
|
+
const memoryCount = mem.tier === "minimal" || mem.tier === "light" || mem.tier === "aggressive" ? 3 : 5;
|
|
11051
|
+
const compactMemory = mem.tier === "minimal" || mem.tier === "aggressive";
|
|
10849
11052
|
if (mem.memoryStore && mem.injectMemory !== false) {
|
|
10850
11053
|
try {
|
|
10851
11054
|
if (mem.memoryStore.scoreRelevant) {
|
|
@@ -11026,7 +11229,7 @@ var DefaultSystemPromptBuilder = class {
|
|
|
11026
11229
|
}
|
|
11027
11230
|
/**
|
|
11028
11231
|
* Returns the max tool description length for the current tier.
|
|
11029
|
-
*
|
|
11232
|
+
* The aggressive tier has the shortest descriptions; off keeps the most detail.
|
|
11030
11233
|
*/
|
|
11031
11234
|
toolDescLimit() {
|
|
11032
11235
|
switch (this.tier) {
|
|
@@ -11037,7 +11240,7 @@ var DefaultSystemPromptBuilder = class {
|
|
|
11037
11240
|
case "medium":
|
|
11038
11241
|
return 50;
|
|
11039
11242
|
case "aggressive":
|
|
11040
|
-
return
|
|
11243
|
+
return 20;
|
|
11041
11244
|
default:
|
|
11042
11245
|
return 70;
|
|
11043
11246
|
}
|
|
@@ -11149,6 +11352,12 @@ var DefaultSystemPromptBuilder = class {
|
|
|
11149
11352
|
}
|
|
11150
11353
|
}
|
|
11151
11354
|
}
|
|
11355
|
+
if (this.opts.domainGlossary) {
|
|
11356
|
+
const glossary = await renderDomainGlossary(ctx, this.opts.domainGlossary);
|
|
11357
|
+
if (glossary) {
|
|
11358
|
+
volatile.push(tagBlock({ type: "text", text: glossary }, "glossary"));
|
|
11359
|
+
}
|
|
11360
|
+
}
|
|
11152
11361
|
if (!ctx.subagent) {
|
|
11153
11362
|
session.push(
|
|
11154
11363
|
tagBlock(
|
|
@@ -11306,8 +11515,8 @@ ${hint.trim()}`);
|
|
|
11306
11515
|
return Array.isArray(role) ? role.filter((r) => typeof r === "string") : [];
|
|
11307
11516
|
})();
|
|
11308
11517
|
const roleList = enumValues.length > 0 ? enumValues.join(", ") : "(no roster configured)";
|
|
11309
|
-
if (this.tier === "minimal") {
|
|
11310
|
-
} else if (this.tier === "light" || this.tier === "medium"
|
|
11518
|
+
if (this.tier === "minimal" || this.tier === "aggressive") {
|
|
11519
|
+
} else if (this.tier === "light" || this.tier === "medium") {
|
|
11311
11520
|
const delegation = section("tool.delegation.compact", {
|
|
11312
11521
|
roleList
|
|
11313
11522
|
});
|
|
@@ -11343,7 +11552,7 @@ ${hint.trim()}`);
|
|
|
11343
11552
|
}
|
|
11344
11553
|
}
|
|
11345
11554
|
const hasGitTool = tools.some((t2) => t2.name === "git");
|
|
11346
|
-
if (hasGitTool && this.tier !== "minimal" && this.tier !== "light") {
|
|
11555
|
+
if (hasGitTool && this.tier !== "minimal" && this.tier !== "light" && this.tier !== "aggressive") {
|
|
11347
11556
|
const commitHygiene = section("tool.commit.hygiene");
|
|
11348
11557
|
if (commitHygiene) lines.push(commitHygiene);
|
|
11349
11558
|
}
|
|
@@ -11360,7 +11569,7 @@ ${hint.trim()}`);
|
|
|
11360
11569
|
}
|
|
11361
11570
|
const hasContextManager = tools.some((t2) => t2.name === "context_manager");
|
|
11362
11571
|
if (hasContextManager) {
|
|
11363
|
-
if (this.tier === "minimal" || this.tier === "light") {
|
|
11572
|
+
if (this.tier === "minimal" || this.tier === "light" || this.tier === "aggressive") {
|
|
11364
11573
|
} else if (this.tier === "medium") {
|
|
11365
11574
|
const contextManagement = section("tool.context.management.compact");
|
|
11366
11575
|
if (contextManagement) lines.push(contextManagement);
|
|
@@ -11413,11 +11622,11 @@ ${hint.trim()}`);
|
|
|
11413
11622
|
return result.text;
|
|
11414
11623
|
}
|
|
11415
11624
|
async buildMode() {
|
|
11416
|
-
if (this.opts.
|
|
11417
|
-
|
|
11418
|
-
|
|
11419
|
-
|
|
11420
|
-
return
|
|
11625
|
+
if (this.opts.modeStore) {
|
|
11626
|
+
const mode = await this.opts.modeStore.getActiveMode();
|
|
11627
|
+
if (mode?.prompt) return mode.prompt;
|
|
11628
|
+
}
|
|
11629
|
+
return this.opts.modePrompt ?? "";
|
|
11421
11630
|
}
|
|
11422
11631
|
};
|
|
11423
11632
|
export {
|