@wrongstack/core 0.264.0 → 0.267.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/dist/{agent-bridge-D8sa1vtv.d.ts → agent-bridge-STJ3JwwK.d.ts} +1 -1
- package/dist/{agent-subagent-runner-c9DLkaas.d.ts → agent-subagent-runner-CzPGP3jA.d.ts} +131 -11
- package/dist/{brain-O1IdKPaK.d.ts → brain-Cdg77tVN.d.ts} +103 -2
- package/dist/{compactor-BBy0rCtB.d.ts → compactor-iMZ84CXq.d.ts} +19 -1
- package/dist/{config-Dz2F3H2K.d.ts → config-Du3pYYln.d.ts} +132 -13
- package/dist/{context-BGSpZNSE.d.ts → context-dT5Ueund.d.ts} +90 -12
- package/dist/coordination/index.d.ts +78 -22
- package/dist/coordination/index.js +695 -273
- package/dist/coordination/index.js.map +1 -1
- package/dist/{default-config-CXsDvOmP.d.ts → default-config-B0cj-Hry.d.ts} +11 -1
- package/dist/defaults/index.d.ts +28 -28
- package/dist/defaults/index.js +2327 -965
- package/dist/defaults/index.js.map +1 -1
- package/dist/execution/index.d.ts +16 -16
- package/dist/execution/index.js +1500 -371
- package/dist/execution/index.js.map +1 -1
- package/dist/execution/prompt-enhancer.d.ts +2 -2
- package/dist/execution/prompt-enhancer.js +1 -1
- package/dist/execution/prompt-enhancer.js.map +1 -1
- package/dist/extension/index.d.ts +6 -6
- package/dist/{goal-preamble-DzjFuN3p.d.ts → goal-preamble-SulMTowG.d.ts} +33 -12
- package/dist/{goal-store-CxWmCGbH.d.ts → goal-store-CABDwdFE.d.ts} +1 -1
- package/dist/{index-CbLSI66_.d.ts → index-Bms0m4oy.d.ts} +5 -5
- package/dist/{index-CYIQrXVF.d.ts → index-DtCVWel4.d.ts} +8 -8
- package/dist/index-IEuxQd-E.d.ts +82 -0
- package/dist/index.d.ts +261 -57
- package/dist/index.js +4799 -2212
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +6 -6
- package/dist/infrastructure/index.js +84 -9
- package/dist/infrastructure/index.js.map +1 -1
- package/dist/kernel/index.d.ts +9 -9
- package/dist/kernel/index.js +1 -1
- package/dist/kernel/index.js.map +1 -1
- package/dist/{mcp-servers-DC4QRPUI.d.ts → mcp-servers-C2cBTxUR.d.ts} +3 -3
- package/dist/models/index.d.ts +5 -5
- package/dist/models/index.js +104 -31
- package/dist/models/index.js.map +1 -1
- package/dist/{models-registry-B_siPxqN.d.ts → models-registry-BqGZNJQ-.d.ts} +1 -1
- package/dist/{multi-agent-coordinator-CK5Jdj9K.d.ts → multi-agent-coordinator-B8R43uPz.d.ts} +1 -1
- package/dist/{null-fleet-bus-DgvD4SCO.d.ts → null-fleet-bus-CnXa5oTH.d.ts} +14 -9
- package/dist/observability/index.d.ts +2 -2
- package/dist/{parallel-eternal-engine-bK0JQBR_.d.ts → parallel-eternal-engine-DdNnw9BQ.d.ts} +11 -9
- package/dist/{path-resolver-BPEDlN38.d.ts → path-resolver-COIMLCQL.d.ts} +3 -3
- package/dist/{permission-4yvGmMRB.d.ts → permission-B75JAi3-.d.ts} +1 -1
- package/dist/{permission-policy-C6XpsBOy.d.ts → permission-policy-DlR9eJAM.d.ts} +2 -2
- package/dist/{pipeline-CXCeMz8J.d.ts → pipeline-BfD2k1rT.d.ts} +3 -3
- package/dist/{plan-templates-BvzRBkJc.d.ts → plan-templates-DSIKCXZN.d.ts} +32 -8
- package/dist/provider-model-resolve-BNRsNuJx.d.ts +107 -0
- package/dist/{provider-runner-C5aQpDWE.d.ts → provider-runner-CX7iIvox.d.ts} +3 -3
- package/dist/{retry-policy-CFhdtRzz.d.ts → retry-policy-BilV1ujH.d.ts} +1 -1
- package/dist/sdd/index.d.ts +8 -8
- package/dist/sdd/index.js +286 -105
- package/dist/sdd/index.js.map +1 -1
- package/dist/secret-vault-BAKpgFw_.d.ts +57 -0
- package/dist/{secret-vault-CxiVLbt1.d.ts → secret-vault-gkvEZZfE.d.ts} +43 -4
- package/dist/security/index.d.ts +6 -68
- package/dist/security/index.js +296 -95
- package/dist/security/index.js.map +1 -1
- package/dist/{selector-gIuhRTkN.d.ts → selector-Bc7eWtT3.d.ts} +1 -1
- package/dist/{session-event-bridge-DkvvrpDt.d.ts → session-event-bridge-D-araDEz.d.ts} +1 -1
- package/dist/{session-reader-KdfVwkKP.d.ts → session-reader-D7Dapswh.d.ts} +1 -1
- package/dist/storage/index.d.ts +112 -15
- package/dist/storage/index.js +491 -156
- package/dist/storage/index.js.map +1 -1
- package/dist/tools/index.d.ts +4 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/types/index.d.ts +21 -21
- package/dist/types/index.js +1523 -450
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +455 -407
- package/dist/utils/index.js +2191 -1203
- package/dist/utils/index.js.map +1 -1
- package/dist/{wstack-paths-CJjEwPXn.d.ts → wstack-paths-hOpNLmvf.d.ts} +2 -0
- package/package.json +1 -1
- package/skills/api-design/SKILL.md +1 -1
- package/skills/audit-log/SKILL.md +6 -6
- package/skills/bug-hunter/SKILL.md +5 -5
- package/skills/chimera/SKILL.md +4 -4
- package/skills/docker-deploy/SKILL.md +1 -1
- package/skills/git-flow/SKILL.md +3 -3
- package/skills/multi-agent/SKILL.md +3 -3
- package/skills/node-modern/SKILL.md +1 -0
- package/skills/observability/SKILL.md +2 -2
- package/skills/output-standards/SKILL.md +51 -28
- package/skills/refactor-planner/SKILL.md +3 -3
- package/skills/security-scanner/SKILL.md +4 -3
- package/skills/tech-stack/SKILL.md +1 -2
- package/dist/llm-selector-DzxuZnNz.d.ts +0 -58
- package/dist/secret-vault-BJDY28ev.d.ts +0 -25
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { P as Provider, M as Message } from '../context-
|
|
1
|
+
import { P as Provider, M as Message } from '../context-dT5Ueund.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Prompt refinement ("did you mean this?").
|
|
@@ -13,7 +13,7 @@ import { P as Provider, M as Message } from '../context-BGSpZNSE.js';
|
|
|
13
13
|
* `provider.complete()` with a dedicated system prompt — and is deliberately
|
|
14
14
|
* free of React / TUI dependencies so it can be unit-tested in isolation.
|
|
15
15
|
*/
|
|
16
|
-
declare const ENHANCER_SYSTEM_PROMPT = "You are a request refiner embedded in a coding agent. Your ONLY job is to rewrite the user's message into clearer, unambiguous instructions that the coding agent can act on confidently.\
|
|
16
|
+
declare const ENHANCER_SYSTEM_PROMPT = "You are a request refiner embedded in a coding agent. Your ONLY job is to rewrite the user's message into clearer, unambiguous instructions that the coding agent can act on confidently.\n\nRules:\n- Preserve the user's intent and scope EXACTLY. Do not add new requirements, features, constraints, or steps the user did not ask for. Do not remove anything they did ask for.\n- Do NOT answer, solve, or perform the request. Only restate it more clearly.\n- Keep all concrete details verbatim: file paths, identifiers, code, error text, numbers, names, URLs.\n- Resolve obvious ambiguity by making the implied subject explicit, not by inventing specifics. If something is genuinely unspecified, leave it general rather than guessing.\n- Be concise: one tight instruction per version (a few sentences at most). No preamble, no explanation, no quotes, no markdown headers.\n- If the message is already clear and complete, return it essentially unchanged.\n\nYou MUST output TWO versions of the refined request, separated by a line containing only \"---\".\n- First version: refined in the SAME LANGUAGE the user wrote in (if Turkish \u2192 Turkish, if Spanish \u2192 Spanish, etc.).\n- Second version: refined in ENGLISH (translate the intent into clear English while preserving all concrete details).\n\nOutput format:\n<refined in user's language>\n---\n<refined in English>\n\nWhen earlier conversation turns are provided, they are CONTEXT ONLY. Use them to resolve references in the user's latest message \u2014 \"it\", \"that\", \"the same\", \"the other one\", \"this file\", \"again\" \u2014 so the refined instruction is self-contained. Refine ONLY the user's latest message; do not answer it, do not act on or restate earlier turns, and do not summarize the conversation.\n\nOutput ONLY the two versions separated by \"---\" \u2014 nothing else.";
|
|
17
17
|
/**
|
|
18
18
|
* Heuristic gate: should this raw input be sent through the refiner at all?
|
|
19
19
|
* Pure + exported for unit testing. Returns false for inputs where refinement
|
|
@@ -10,7 +10,6 @@ function toErrorMessage(err) {
|
|
|
10
10
|
|
|
11
11
|
// src/execution/prompt-enhancer.ts
|
|
12
12
|
var ENHANCER_SYSTEM_PROMPT = `You are a request refiner embedded in a coding agent. Your ONLY job is to rewrite the user's message into clearer, unambiguous instructions that the coding agent can act on confidently.
|
|
13
|
-
import { toErrorMessage } from '../utils/error.js';
|
|
14
13
|
|
|
15
14
|
Rules:
|
|
16
15
|
- Preserve the user's intent and scope EXACTLY. Do not add new requirements, features, constraints, or steps the user did not ask for. Do not remove anything they did ask for.
|
|
@@ -104,6 +103,7 @@ async function enhanceUserPrompt(opts) {
|
|
|
104
103
|
opts.onError?.(toErrorMessage(err));
|
|
105
104
|
return null;
|
|
106
105
|
} finally {
|
|
106
|
+
timer.abort();
|
|
107
107
|
clearTimeout(to);
|
|
108
108
|
}
|
|
109
109
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/types/blocks.ts","../../src/utils/error.ts","../../src/execution/prompt-enhancer.ts"],"names":[],"mappings":"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","file":"prompt-enhancer.js","sourcesContent":["export interface TextBlock {\n type: 'text';\n text: string;\n cache_control?: { type: 'ephemeral' | undefined };\n}\n\nexport interface ToolUseBlock {\n type: 'tool_use';\n id: string;\n name: string;\n input: Record<string, unknown>;\n /**\n * Provider-specific opaque metadata captured from the wire response.\n * Echoed back verbatim in the next request so providers that bind\n * extra state to function calls keep working. Example: Gemini's\n * `thoughtSignature` — required for tool-use turns with thinking\n * models, otherwise the next request fails with 400 \"Function call\n * is missing a thought_signature in functionCall parts\".\n *\n * Keys are namespaced by intent so multiple wires can coexist:\n * - `google.thoughtSignature` — Gemini signed-thought blob\n * Other providers can add their own keys without colliding.\n */\n providerMeta?: Record<string, unknown>;\n}\n\nexport interface ToolResultBlock {\n type: 'tool_result';\n tool_use_id: string;\n /**\n * The original tool name. Useful for providers like Google Gemini that\n * need the tool name in `functionResponse.name` — the tool_use_id is\n * only a session-local identifier and is not stable across replays.\n * Always set by ToolExecutor; may be absent on manually-constructed blocks.\n */\n name?: string | undefined;\n content: string;\n is_error?: boolean | undefined;\n}\n\nexport interface ImageBlock {\n type: 'image';\n source: {\n type: 'base64' | 'url';\n media_type?: string | undefined;\n data?: string | undefined;\n url?: string | undefined;\n };\n}\n\n/**\n * Chain-of-thought / extended-thinking content emitted by the model.\n *\n * Both Anthropic extended thinking (`{type:'thinking', thinking, signature}`)\n * and DeepSeek reasoning mode (top-level `reasoning_content` on the assistant\n * message) require this content to be echoed back verbatim on the next\n * request, otherwise the provider returns 400:\n * - Anthropic: \"The `content[].thinking` in the thinking mode must be passed back\"\n * - DeepSeek: \"The `reasoning_content` in the thinking mode must be passed back\"\n *\n * `signature` is Anthropic-specific (an opaque integrity blob). DeepSeek\n * doesn't issue a signature — the field is absent for that provider.\n *\n * Per Anthropic, thinking blocks MUST appear before any text/tool_use blocks\n * in an assistant message. Stream builders preserve that order.\n */\nexport interface ThinkingBlock {\n type: 'thinking';\n thinking: string;\n signature?: string | undefined;\n providerMeta?: Record<string, unknown>;\n}\n\nexport type ContentBlock = TextBlock | ToolUseBlock | ToolResultBlock | ImageBlock | ThinkingBlock;\n\nexport function isTextBlock(b: ContentBlock): b is TextBlock {\n return b.type === 'text';\n}\nexport function isToolUseBlock(b: ContentBlock): b is ToolUseBlock {\n return b.type === 'tool_use';\n}\nexport function isToolResultBlock(b: ContentBlock): b is ToolResultBlock {\n return b.type === 'tool_result';\n}\nexport function isImageBlock(b: ContentBlock): b is ImageBlock {\n return b.type === 'image';\n}\nexport function isThinkingBlock(b: ContentBlock): b is ThinkingBlock {\n return b.type === 'thinking';\n}\n","/**\n * Converts an unknown error value to a human-readable string.\n * Used in 40+ files across the codebase to normalize error messaging.\n */\nexport function toErrorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","import { isTextBlock } from '../types/blocks.js';\nimport type { ContentBlock } from '../types/blocks.js';\nimport type { Message } from '../types/messages.js';\nimport type { Provider, Request } from '../types/provider.js';\nimport { toErrorMessage } from '../utils/error.js';\n\n/**\n * Prompt refinement (\"did you mean this?\").\n *\n * Runs a one-shot LLM call in a SEPARATE context (its own system prompt, no\n * conversation history, no tools) that rewrites a raw user message into a\n * clearer, more complete instruction BEFORE the main agent sees it. The goal\n * is to make the main context start from a well-understood request rather than\n * guessing intent from terse input like \"fix the bug\".\n *\n * This mirrors `IntelligentCompactor.callSummarizer` — a plain\n * `provider.complete()` with a dedicated system prompt — and is deliberately\n * free of React / TUI dependencies so it can be unit-tested in isolation.\n */\n\nexport const ENHANCER_SYSTEM_PROMPT = `You are a request refiner embedded in a coding agent. Your ONLY job is to rewrite the user's message into clearer, unambiguous instructions that the coding agent can act on confidently.\nimport { toErrorMessage } from '../utils/error.js';\n\nRules:\n- Preserve the user's intent and scope EXACTLY. Do not add new requirements, features, constraints, or steps the user did not ask for. Do not remove anything they did ask for.\n- Do NOT answer, solve, or perform the request. Only restate it more clearly.\n- Keep all concrete details verbatim: file paths, identifiers, code, error text, numbers, names, URLs.\n- Resolve obvious ambiguity by making the implied subject explicit, not by inventing specifics. If something is genuinely unspecified, leave it general rather than guessing.\n- Be concise: one tight instruction per version (a few sentences at most). No preamble, no explanation, no quotes, no markdown headers.\n- If the message is already clear and complete, return it essentially unchanged.\n\nYou MUST output TWO versions of the refined request, separated by a line containing only \"---\".\n- First version: refined in the SAME LANGUAGE the user wrote in (if Turkish → Turkish, if Spanish → Spanish, etc.).\n- Second version: refined in ENGLISH (translate the intent into clear English while preserving all concrete details).\n\nOutput format:\n<refined in user's language>\n---\n<refined in English>\n\nWhen earlier conversation turns are provided, they are CONTEXT ONLY. Use them to resolve references in the user's latest message — \"it\", \"that\", \"the same\", \"the other one\", \"this file\", \"again\" — so the refined instruction is self-contained. Refine ONLY the user's latest message; do not answer it, do not act on or restate earlier turns, and do not summarize the conversation.\n\nOutput ONLY the two versions separated by \"---\" — nothing else.`;\n\n/** Words/phrases that are control answers, not refinable requests. */\nconst AFFIRMATION_RE =\n /^(y|n|yes|no|yep|nope|ok|okay|sure|go|go ahead|continue|proceed|stop|cancel|done|next|skip|retry|again|please do|do it)\\b[.! ]*$/i;\n\n/**\n * Heuristic gate: should this raw input be sent through the refiner at all?\n * Pure + exported for unit testing. Returns false for inputs where refinement\n * is pointless or unwanted (slash commands, one-word affirmations, trivially\n * short text, bare numbers).\n */\nexport function shouldEnhance(text: string): boolean {\n const t = text.trim();\n if (!t) return false;\n if (t.startsWith('/')) return false; // slash command\n if (t.length < 12) return false; // too short to be worth refining\n if (AFFIRMATION_RE.test(t)) return false; // \"yes\" / \"continue\" / ...\n if (/^[\\d\\s.,]+$/.test(t)) return false; // bare numbers (menu picks, etc.)\n const words = t.split(/\\s+/).filter(Boolean);\n if (words.length < 3) return false; // 1–2 words rarely benefit\n return true;\n}\n\n/**\n * Normalize for \"did the refiner actually change anything?\" comparison —\n * collapse whitespace and lowercase so trivial reformatting doesn't trigger\n * the confirmation panel.\n */\nexport function normalizedEqual(a: string, b: string): boolean {\n const norm = (s: string) => s.trim().replace(/\\s+/g, ' ').toLowerCase();\n return norm(a) === norm(b);\n}\n\n/** A single text-only conversation turn used as refiner context. */\nexport interface ConversationTurn {\n role: 'user' | 'assistant';\n text: string;\n}\n\n/**\n * Result of a successful prompt refinement. Contains both the\n * original-language and English versions so the UI can offer both.\n */\nexport interface EnhanceResult {\n /** Refined in the user's original language. */\n refined: string;\n /** Refined in English. */\n english: string;\n}\n\nexport interface EnhanceUserPromptOptions {\n provider: Provider;\n model: string;\n text: string;\n /**\n * Recent conversation turns (oldest→newest), text only, used purely as\n * CONTEXT so the refiner can resolve references in a follow-up message\n * (\"it\", \"the same\", \"that file\"). Without this, the refiner is blind to\n * the conversation and can only refine self-contained prompts. Build with\n * `recentTextTurns(ctx.messages)`.\n */\n history?: ConversationTurn[] | undefined;\n /** Parent abort signal (e.g. the run controller / Esc). */\n signal?: AbortSignal | undefined;\n /** Hard cap on how long to wait for the refiner before giving up. Default 90s. */\n timeoutMs?: number | undefined;\n /** Max tokens for the refined output. Default 2048. */\n maxTokens?: number | undefined;\n /**\n * Called with a short reason when refinement fails (provider error, timeout,\n * empty response). NOT called when the caller cancels via `signal`. Lets the\n * UI surface *why* a refine fell through instead of a generic message.\n */\n onError?: ((reason: string) => void) | undefined;\n}\n\n/**\n * Compose the single user message sent to the refiner: the recent\n * conversation embedded as plain text (so we never trip provider\n * role-alternation rules) followed by the latest message to refine.\n */\nfunction buildRefinerInput(text: string, history?: ConversationTurn[]): string {\n if (!history || history.length === 0) return text;\n const lines = history.map((t) => `${t.role === 'user' ? 'User' : 'Assistant'}: ${t.text}`);\n return [\n 'Recent conversation (context only — do not act on it):',\n ...lines,\n '',\n 'Latest message to refine:',\n text,\n ].join('\\n');\n}\n\n/**\n * Refine a raw user prompt. Returns the refined text, or `null` when the\n * caller should fall back to the original (refiner errored, timed out, was\n * aborted, or returned nothing useful). NEVER throws — refinement is a\n * best-effort convenience and must never block the user from sending.\n */\nexport async function enhanceUserPrompt(\n opts: EnhanceUserPromptOptions,\n): Promise<EnhanceResult | null> {\n const { provider, model, text } = opts;\n // Reasoning models (\"thinking\" models like DeepSeek reasoner / o1) take\n // longer to first token, so give a generous default window.\n const timeoutMs = opts.timeoutMs ?? 90000;\n // Generous default: on some endpoints the model's hidden \"thinking\" tokens\n // count against this budget, so a small cap can leave NO room for the actual\n // refined text (→ empty completion → null). 2048 keeps the output room ample.\n const maxTokens = opts.maxTokens ?? 2048;\n\n const req: Request = {\n model,\n system: [{ type: 'text', text: ENHANCER_SYSTEM_PROMPT }],\n messages: [{ role: 'user', content: buildRefinerInput(text, opts.history) }],\n maxTokens,\n // NOTE: deliberately NO `temperature`. The main agent loop never sets it,\n // and reasoning models (DeepSeek reasoner, o1/o3, …) return HTTP 400 when\n // `temperature` is present — which would make every refine call fail and\n // silently fall back to the original (no panel shown).\n };\n\n // Link a local timeout to the parent signal so a stuck provider call can't\n // hang the submit path. AbortSignal.any keeps both cancellation sources.\n const timer = new AbortController();\n const to = setTimeout(() => timer.abort(new Error('enhancer timeout')), timeoutMs);\n const signal = opts.signal\n ? AbortSignal.any([opts.signal, timer.signal])\n : timer.signal;\n\n try {\n const res = await provider.complete(req, { signal });\n const raw = res.content\n .filter(isTextBlock)\n .map((b) => b.text)\n .join('\\n')\n .trim();\n if (!raw) {\n opts.onError?.('model returned no text');\n return null;\n }\n\n // The model outputs two versions separated by a line with only \"---\".\n // Split on the first occurrence so the delimiter can appear in the text.\n const sepIdx = raw.indexOf('\\n---\\n');\n if (sepIdx === -1) {\n // Model didn't follow the format — treat the whole response as a\n // single refined version (best-effort fallback).\n opts.onError?.('model did not produce two versions');\n return { refined: raw, english: raw };\n }\n const refined = raw.slice(0, sepIdx).trim();\n const english = raw.slice(sepIdx + 5).trim(); // skip \"\\n---\\n\"\n if (!refined || !english) {\n opts.onError?.('one or both versions empty');\n return null;\n }\n return { refined, english };\n } catch (err) {\n // User-initiated cancel → stay silent (they chose to send the original).\n if (opts.signal?.aborted) return null;\n if (timer.signal.aborted) {\n opts.onError?.(`timed out after ${Math.round(timeoutMs / 1000)}s`);\n return null;\n }\n opts.onError?.(toErrorMessage(err));\n return null;\n } finally {\n clearTimeout(to);\n }\n}\n\n/** Pull the visible text out of a message's content (ignores tool blocks). */\nfunction messageText(content: string | ContentBlock[]): string {\n if (typeof content === 'string') return content;\n return content\n .filter(isTextBlock)\n .map((b) => b.text)\n .join('\\n')\n .trim();\n}\n\n/**\n * Extract the last few user/assistant TEXT turns from a conversation, newest\n * last, for use as refiner context. Skips system messages and tool-only turns\n * (tool_use / tool_result carry no useful natural-language context and bloat\n * the call). Each turn is truncated to `maxChars`; at most `maxTurns` are\n * returned. Pure + exported for unit testing.\n */\nexport function recentTextTurns(\n messages: Message[],\n maxTurns = 6,\n maxChars = 1500,\n): ConversationTurn[] {\n const turns: ConversationTurn[] = [];\n for (let i = messages.length - 1; i >= 0 && turns.length < maxTurns; i--) {\n const m = messages[i];\n if (!m || (m.role !== 'user' && m.role !== 'assistant')) continue;\n const text = messageText(m.content);\n if (!text) continue;\n turns.unshift({\n role: m.role,\n text: text.length > maxChars ? `${text.slice(0, maxChars - 1)}…` : text,\n });\n }\n return turns;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/types/blocks.ts","../../src/utils/error.ts","../../src/execution/prompt-enhancer.ts"],"names":[],"mappings":"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","file":"prompt-enhancer.js","sourcesContent":["export interface TextBlock {\n type: 'text';\n text: string;\n cache_control?: { type: 'ephemeral' | undefined };\n}\n\nexport interface ToolUseBlock {\n type: 'tool_use';\n id: string;\n name: string;\n input: Record<string, unknown>;\n /**\n * Provider-specific opaque metadata captured from the wire response.\n * Echoed back verbatim in the next request so providers that bind\n * extra state to function calls keep working. Example: Gemini's\n * `thoughtSignature` — required for tool-use turns with thinking\n * models, otherwise the next request fails with 400 \"Function call\n * is missing a thought_signature in functionCall parts\".\n *\n * Keys are namespaced by intent so multiple wires can coexist:\n * - `google.thoughtSignature` — Gemini signed-thought blob\n * Other providers can add their own keys without colliding.\n */\n providerMeta?: Record<string, unknown>;\n}\n\nexport interface ToolResultBlock {\n type: 'tool_result';\n tool_use_id: string;\n /**\n * The original tool name. Useful for providers like Google Gemini that\n * need the tool name in `functionResponse.name` — the tool_use_id is\n * only a session-local identifier and is not stable across replays.\n * Always set by ToolExecutor; may be absent on manually-constructed blocks.\n */\n name?: string | undefined;\n content: string;\n is_error?: boolean | undefined;\n}\n\nexport interface ImageBlock {\n type: 'image';\n source: {\n type: 'base64' | 'url';\n media_type?: string | undefined;\n data?: string | undefined;\n url?: string | undefined;\n };\n}\n\n/**\n * Chain-of-thought / extended-thinking content emitted by the model.\n *\n * Both Anthropic extended thinking (`{type:'thinking', thinking, signature}`)\n * and DeepSeek reasoning mode (top-level `reasoning_content` on the assistant\n * message) require this content to be echoed back verbatim on the next\n * request, otherwise the provider returns 400:\n * - Anthropic: \"The `content[].thinking` in the thinking mode must be passed back\"\n * - DeepSeek: \"The `reasoning_content` in the thinking mode must be passed back\"\n *\n * `signature` is Anthropic-specific (an opaque integrity blob). DeepSeek\n * doesn't issue a signature — the field is absent for that provider.\n *\n * Per Anthropic, thinking blocks MUST appear before any text/tool_use blocks\n * in an assistant message. Stream builders preserve that order.\n */\nexport interface ThinkingBlock {\n type: 'thinking';\n thinking: string;\n signature?: string | undefined;\n providerMeta?: Record<string, unknown>;\n}\n\nexport type ContentBlock = TextBlock | ToolUseBlock | ToolResultBlock | ImageBlock | ThinkingBlock;\n\nexport function isTextBlock(b: ContentBlock): b is TextBlock {\n return b.type === 'text';\n}\nexport function isToolUseBlock(b: ContentBlock): b is ToolUseBlock {\n return b.type === 'tool_use';\n}\nexport function isToolResultBlock(b: ContentBlock): b is ToolResultBlock {\n return b.type === 'tool_result';\n}\nexport function isImageBlock(b: ContentBlock): b is ImageBlock {\n return b.type === 'image';\n}\nexport function isThinkingBlock(b: ContentBlock): b is ThinkingBlock {\n return b.type === 'thinking';\n}\n","/**\n * Converts an unknown error value to a human-readable string.\n * Used in 40+ files across the codebase to normalize error messaging.\n */\nexport function toErrorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","import { isTextBlock } from '../types/blocks.js';\nimport type { ContentBlock } from '../types/blocks.js';\nimport type { Message } from '../types/messages.js';\nimport type { Provider, Request } from '../types/provider.js';\nimport { toErrorMessage } from '../utils/error.js';\n\n/**\n * Prompt refinement (\"did you mean this?\").\n *\n * Runs a one-shot LLM call in a SEPARATE context (its own system prompt, no\n * conversation history, no tools) that rewrites a raw user message into a\n * clearer, more complete instruction BEFORE the main agent sees it. The goal\n * is to make the main context start from a well-understood request rather than\n * guessing intent from terse input like \"fix the bug\".\n *\n * This mirrors `IntelligentCompactor.callSummarizer` — a plain\n * `provider.complete()` with a dedicated system prompt — and is deliberately\n * free of React / TUI dependencies so it can be unit-tested in isolation.\n */\n\nexport const ENHANCER_SYSTEM_PROMPT = `You are a request refiner embedded in a coding agent. Your ONLY job is to rewrite the user's message into clearer, unambiguous instructions that the coding agent can act on confidently.\n\nRules:\n- Preserve the user's intent and scope EXACTLY. Do not add new requirements, features, constraints, or steps the user did not ask for. Do not remove anything they did ask for.\n- Do NOT answer, solve, or perform the request. Only restate it more clearly.\n- Keep all concrete details verbatim: file paths, identifiers, code, error text, numbers, names, URLs.\n- Resolve obvious ambiguity by making the implied subject explicit, not by inventing specifics. If something is genuinely unspecified, leave it general rather than guessing.\n- Be concise: one tight instruction per version (a few sentences at most). No preamble, no explanation, no quotes, no markdown headers.\n- If the message is already clear and complete, return it essentially unchanged.\n\nYou MUST output TWO versions of the refined request, separated by a line containing only \"---\".\n- First version: refined in the SAME LANGUAGE the user wrote in (if Turkish → Turkish, if Spanish → Spanish, etc.).\n- Second version: refined in ENGLISH (translate the intent into clear English while preserving all concrete details).\n\nOutput format:\n<refined in user's language>\n---\n<refined in English>\n\nWhen earlier conversation turns are provided, they are CONTEXT ONLY. Use them to resolve references in the user's latest message — \"it\", \"that\", \"the same\", \"the other one\", \"this file\", \"again\" — so the refined instruction is self-contained. Refine ONLY the user's latest message; do not answer it, do not act on or restate earlier turns, and do not summarize the conversation.\n\nOutput ONLY the two versions separated by \"---\" — nothing else.`;\n\n/** Words/phrases that are control answers, not refinable requests. */\nconst AFFIRMATION_RE =\n /^(y|n|yes|no|yep|nope|ok|okay|sure|go|go ahead|continue|proceed|stop|cancel|done|next|skip|retry|again|please do|do it)\\b[.! ]*$/i;\n\n/**\n * Heuristic gate: should this raw input be sent through the refiner at all?\n * Pure + exported for unit testing. Returns false for inputs where refinement\n * is pointless or unwanted (slash commands, one-word affirmations, trivially\n * short text, bare numbers).\n */\nexport function shouldEnhance(text: string): boolean {\n const t = text.trim();\n if (!t) return false;\n if (t.startsWith('/')) return false; // slash command\n if (t.length < 12) return false; // too short to be worth refining\n if (AFFIRMATION_RE.test(t)) return false; // \"yes\" / \"continue\" / ...\n if (/^[\\d\\s.,]+$/.test(t)) return false; // bare numbers (menu picks, etc.)\n const words = t.split(/\\s+/).filter(Boolean);\n if (words.length < 3) return false; // 1–2 words rarely benefit\n return true;\n}\n\n/**\n * Normalize for \"did the refiner actually change anything?\" comparison —\n * collapse whitespace and lowercase so trivial reformatting doesn't trigger\n * the confirmation panel.\n */\nexport function normalizedEqual(a: string, b: string): boolean {\n const norm = (s: string) => s.trim().replace(/\\s+/g, ' ').toLowerCase();\n return norm(a) === norm(b);\n}\n\n/** A single text-only conversation turn used as refiner context. */\nexport interface ConversationTurn {\n role: 'user' | 'assistant';\n text: string;\n}\n\n/**\n * Result of a successful prompt refinement. Contains both the\n * original-language and English versions so the UI can offer both.\n */\nexport interface EnhanceResult {\n /** Refined in the user's original language. */\n refined: string;\n /** Refined in English. */\n english: string;\n}\n\nexport interface EnhanceUserPromptOptions {\n provider: Provider;\n model: string;\n text: string;\n /**\n * Recent conversation turns (oldest→newest), text only, used purely as\n * CONTEXT so the refiner can resolve references in a follow-up message\n * (\"it\", \"the same\", \"that file\"). Without this, the refiner is blind to\n * the conversation and can only refine self-contained prompts. Build with\n * `recentTextTurns(ctx.messages)`.\n */\n history?: ConversationTurn[] | undefined;\n /** Parent abort signal (e.g. the run controller / Esc). */\n signal?: AbortSignal | undefined;\n /** Hard cap on how long to wait for the refiner before giving up. Default 90s. */\n timeoutMs?: number | undefined;\n /** Max tokens for the refined output. Default 2048. */\n maxTokens?: number | undefined;\n /**\n * Called with a short reason when refinement fails (provider error, timeout,\n * empty response). NOT called when the caller cancels via `signal`. Lets the\n * UI surface *why* a refine fell through instead of a generic message.\n */\n onError?: ((reason: string) => void) | undefined;\n}\n\n/**\n * Compose the single user message sent to the refiner: the recent\n * conversation embedded as plain text (so we never trip provider\n * role-alternation rules) followed by the latest message to refine.\n */\nfunction buildRefinerInput(text: string, history?: ConversationTurn[]): string {\n if (!history || history.length === 0) return text;\n const lines = history.map((t) => `${t.role === 'user' ? 'User' : 'Assistant'}: ${t.text}`);\n return [\n 'Recent conversation (context only — do not act on it):',\n ...lines,\n '',\n 'Latest message to refine:',\n text,\n ].join('\\n');\n}\n\n/**\n * Refine a raw user prompt. Returns the refined text, or `null` when the\n * caller should fall back to the original (refiner errored, timed out, was\n * aborted, or returned nothing useful). NEVER throws — refinement is a\n * best-effort convenience and must never block the user from sending.\n */\nexport async function enhanceUserPrompt(\n opts: EnhanceUserPromptOptions,\n): Promise<EnhanceResult | null> {\n const { provider, model, text } = opts;\n // Reasoning models (\"thinking\" models like DeepSeek reasoner / o1) take\n // longer to first token, so give a generous default window.\n const timeoutMs = opts.timeoutMs ?? 90000;\n // Generous default: on some endpoints the model's hidden \"thinking\" tokens\n // count against this budget, so a small cap can leave NO room for the actual\n // refined text (→ empty completion → null). 2048 keeps the output room ample.\n const maxTokens = opts.maxTokens ?? 2048;\n\n const req: Request = {\n model,\n system: [{ type: 'text', text: ENHANCER_SYSTEM_PROMPT }],\n messages: [{ role: 'user', content: buildRefinerInput(text, opts.history) }],\n maxTokens,\n // NOTE: deliberately NO `temperature`. The main agent loop never sets it,\n // and reasoning models (DeepSeek reasoner, o1/o3, …) return HTTP 400 when\n // `temperature` is present — which would make every refine call fail and\n // silently fall back to the original (no panel shown).\n };\n\n // Link a local timeout to the parent signal so a stuck provider call can't\n // hang the submit path. AbortSignal.any keeps both cancellation sources.\n const timer = new AbortController();\n const to = setTimeout(() => timer.abort(new Error('enhancer timeout')), timeoutMs);\n const signal = opts.signal\n ? AbortSignal.any([opts.signal, timer.signal])\n : timer.signal;\n\n try {\n const res = await provider.complete(req, { signal });\n const raw = res.content\n .filter(isTextBlock)\n .map((b) => b.text)\n .join('\\n')\n .trim();\n if (!raw) {\n opts.onError?.('model returned no text');\n return null;\n }\n\n // The model outputs two versions separated by a line with only \"---\".\n // Split on the first occurrence so the delimiter can appear in the text.\n const sepIdx = raw.indexOf('\\n---\\n');\n if (sepIdx === -1) {\n // Model didn't follow the format — treat the whole response as a\n // single refined version (best-effort fallback).\n opts.onError?.('model did not produce two versions');\n return { refined: raw, english: raw };\n }\n const refined = raw.slice(0, sepIdx).trim();\n const english = raw.slice(sepIdx + 5).trim(); // skip \"\\n---\\n\"\n if (!refined || !english) {\n opts.onError?.('one or both versions empty');\n return null;\n }\n return { refined, english };\n } catch (err) {\n // User-initiated cancel → stay silent (they chose to send the original).\n if (opts.signal?.aborted) return null;\n if (timer.signal.aborted) {\n opts.onError?.(`timed out after ${Math.round(timeoutMs / 1000)}s`);\n return null;\n }\n opts.onError?.(toErrorMessage(err));\n return null;\n } finally {\n // Idempotent — abort() after signal already fired is a no-op, so this is\n // always safe regardless of whether the timeout fired first.\n timer.abort();\n clearTimeout(to);\n }\n}\n\n/** Pull the visible text out of a message's content (ignores tool blocks). */\nfunction messageText(content: string | ContentBlock[]): string {\n if (typeof content === 'string') return content;\n return content\n .filter(isTextBlock)\n .map((b) => b.text)\n .join('\\n')\n .trim();\n}\n\n/**\n * Extract the last few user/assistant TEXT turns from a conversation, newest\n * last, for use as refiner context. Skips system messages and tool-only turns\n * (tool_use / tool_result carry no useful natural-language context and bloat\n * the call). Each turn is truncated to `maxChars`; at most `maxTurns` are\n * returned. Pure + exported for unit testing.\n */\nexport function recentTextTurns(\n messages: Message[],\n maxTurns = 6,\n maxChars = 1500,\n): ConversationTurn[] {\n const turns: ConversationTurn[] = [];\n for (let i = messages.length - 1; i >= 0 && turns.length < maxTurns; i--) {\n const m = messages[i];\n if (!m || (m.role !== 'user' && m.role !== 'assistant')) continue;\n const text = messageText(m.content);\n if (!text) continue;\n turns.unshift({\n role: m.role,\n text: text.length > maxChars ? `${text.slice(0, maxChars - 1)}…` : text,\n });\n }\n return turns;\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { i as AfterIterationHook, j as AfterRunHook, k as AfterToolExecutionHook, l as AgentExtension, B as BeforeIterationHook, m as BeforeRunHook, n as BeforeToolExecutionHook, E as ExtensionRegistry, O as OnErrorHook, v as ProviderRunnerFn, t as ProviderRunnerWrapper } from '../index-
|
|
2
|
-
import '../context-
|
|
1
|
+
export { i as AfterIterationHook, j as AfterRunHook, k as AfterToolExecutionHook, l as AgentExtension, B as BeforeIterationHook, m as BeforeRunHook, n as BeforeToolExecutionHook, E as ExtensionRegistry, O as OnErrorHook, v as ProviderRunnerFn, t as ProviderRunnerWrapper } from '../index-Bms0m4oy.js';
|
|
2
|
+
import '../context-dT5Ueund.js';
|
|
3
3
|
import '../logger-B63L5bTg.js';
|
|
4
|
-
import '../pipeline-
|
|
5
|
-
import '../config-
|
|
4
|
+
import '../pipeline-BfD2k1rT.js';
|
|
5
|
+
import '../config-Du3pYYln.js';
|
|
6
6
|
import '../observability-D-HZN_mF.js';
|
|
7
|
-
import '../brain-
|
|
8
|
-
import '../permission-
|
|
7
|
+
import '../brain-Cdg77tVN.js';
|
|
8
|
+
import '../permission-B75JAi3-.js';
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { S as SkillLoader, a as SkillManifest, b as SkillEntry } from './skill-DGIXCtdv.js';
|
|
2
|
-
import { W as WstackPaths } from './wstack-paths-
|
|
3
|
-
import { P as Provider, C as Context } from './context-
|
|
4
|
-
import { C as Compactor, a as CompactReport } from './compactor-
|
|
5
|
-
import { M as MessageSelector } from './selector-
|
|
6
|
-
import { E as EventBus } from './brain-
|
|
7
|
-
import { M as MiddlewareHandler } from './pipeline-
|
|
8
|
-
import { S as SessionEventBridge } from './session-event-bridge-
|
|
9
|
-
import { C as ContextWindowAggressiveOn,
|
|
10
|
-
import { g as Agent, D as DoneCondition } from './agent-subagent-runner-
|
|
11
|
-
import { R as RunResult, S as SystemPromptContributor } from './index-
|
|
2
|
+
import { W as WstackPaths } from './wstack-paths-hOpNLmvf.js';
|
|
3
|
+
import { P as Provider, C as Context } from './context-dT5Ueund.js';
|
|
4
|
+
import { C as Compactor, a as CompactReport } from './compactor-iMZ84CXq.js';
|
|
5
|
+
import { M as MessageSelector } from './selector-Bc7eWtT3.js';
|
|
6
|
+
import { E as EventBus } from './brain-Cdg77tVN.js';
|
|
7
|
+
import { M as MiddlewareHandler } from './pipeline-BfD2k1rT.js';
|
|
8
|
+
import { S as SessionEventBridge } from './session-event-bridge-D-araDEz.js';
|
|
9
|
+
import { C as ContextWindowAggressiveOn, h as ContextWindowPolicy } from './config-Du3pYYln.js';
|
|
10
|
+
import { g as Agent, D as DoneCondition } from './agent-subagent-runner-CzPGP3jA.js';
|
|
11
|
+
import { R as RunResult, S as SystemPromptContributor } from './index-Bms0m4oy.js';
|
|
12
12
|
|
|
13
13
|
interface SkillLoaderOptions {
|
|
14
14
|
paths: WstackPaths;
|
|
@@ -121,6 +121,8 @@ interface SelectiveCompactorOptions {
|
|
|
121
121
|
eliseThreshold?: number | undefined;
|
|
122
122
|
/** Model for selector LLM calls (default: same as provider default). */
|
|
123
123
|
selectorModel?: string | undefined;
|
|
124
|
+
/** Max output tokens for the selector LLM call (default: 1024). */
|
|
125
|
+
selectorMaxOutputTokens?: number | undefined;
|
|
124
126
|
/** Summarizer model for collapsed ranges (default: same as selectorModel). */
|
|
125
127
|
summarizerModel?: string | undefined;
|
|
126
128
|
/** Prompt for the summarizer sub-LLM. */
|
|
@@ -176,8 +178,15 @@ declare class SelectiveCompactor implements Compactor {
|
|
|
176
178
|
private computeTargetBudget;
|
|
177
179
|
private eliseOldToolResults;
|
|
178
180
|
private hasTextContent;
|
|
181
|
+
/**
|
|
182
|
+
* Estimate message-array tokens via the shared `estimateMessages` primitive
|
|
183
|
+
* so SelectiveCompactor's before/after/load figures agree with the
|
|
184
|
+
* middleware threshold math and the other compactors. Previously this used a
|
|
185
|
+
* private `ceil(len/3.5)` walk that diverged from the calibrated shared
|
|
186
|
+
* estimator, causing the selective `load`/`targetBudget` comparison to mix
|
|
187
|
+
* two incompatible token scales.
|
|
188
|
+
*/
|
|
179
189
|
private estimateTokens;
|
|
180
|
-
private roughTokenEstimate;
|
|
181
190
|
}
|
|
182
191
|
|
|
183
192
|
type CompactorStrategy = 'hybrid' | 'intelligent' | 'selective';
|
|
@@ -198,6 +207,8 @@ interface StrategyCompactorOptions {
|
|
|
198
207
|
smart?: boolean | undefined;
|
|
199
208
|
/** Model used by the LLM-backed strategies for summarization/selection. */
|
|
200
209
|
summarizerModel?: string | undefined;
|
|
210
|
+
/** Max output tokens for the selector LLM call in 'selective' strategy (default: 1024). */
|
|
211
|
+
selectorMaxOutputTokens?: number | undefined;
|
|
201
212
|
/**
|
|
202
213
|
* Legacy shortcut for `strategy: 'selective'`. When `strategy` is unset (or
|
|
203
214
|
* 'hybrid') and this is true, the selective (LLM-driven) compactor is used.
|
|
@@ -220,6 +231,16 @@ interface StrategyCompactorOptions {
|
|
|
220
231
|
*/
|
|
221
232
|
declare function createStrategyCompactor(opts?: StrategyCompactorOptions): Compactor;
|
|
222
233
|
|
|
234
|
+
interface ContextWindowBudgetSnapshot {
|
|
235
|
+
maxContext: number;
|
|
236
|
+
inputTokens: number;
|
|
237
|
+
availableInputTokens: number;
|
|
238
|
+
remainingInputTokens: number;
|
|
239
|
+
reservedOutputTokens: number;
|
|
240
|
+
reservedSafetyTokens: number;
|
|
241
|
+
load: number;
|
|
242
|
+
overflowTokens: number;
|
|
243
|
+
}
|
|
223
244
|
type CompactionFailureMode = 'throw' | 'throw_on_hard' | 'continue';
|
|
224
245
|
interface AutoCompactionOptions {
|
|
225
246
|
aggressiveOn?: ContextWindowAggressiveOn | undefined;
|
|
@@ -447,4 +468,4 @@ declare function makeAutonomyPromptContributor(opts: AutonomyPromptContributorOp
|
|
|
447
468
|
*/
|
|
448
469
|
declare function buildGoalPreamble(goal: string, deliverables?: string[]): string;
|
|
449
470
|
|
|
450
|
-
export { AutoCompactionMiddleware as A, type CompactorStrategy as C, DefaultSkillLoader as D, IntelligentCompactor as I, SelectiveCompactor as S, AutonomousRunner as a, type AutonomousRunnerOptions as b, type AutonomyPromptContributorOptions as c, type DoneCheckResult as d, DoneConditionChecker as e, type IntelligentCompactorOptions as f, type SelectiveCompactorOptions as g, type SkillLoaderOptions as h, type StrategyCompactorOptions as i, buildGoalPreamble as j, createStrategyCompactor as k, makeAutonomyPromptContributor as m };
|
|
471
|
+
export { AutoCompactionMiddleware as A, type CompactorStrategy as C, DefaultSkillLoader as D, IntelligentCompactor as I, SelectiveCompactor as S, AutonomousRunner as a, type AutonomousRunnerOptions as b, type AutonomyPromptContributorOptions as c, type DoneCheckResult as d, DoneConditionChecker as e, type IntelligentCompactorOptions as f, type SelectiveCompactorOptions as g, type SkillLoaderOptions as h, type StrategyCompactorOptions as i, buildGoalPreamble as j, createStrategyCompactor as k, type ContextWindowBudgetSnapshot as l, makeAutonomyPromptContributor as m };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { o as TextBlock, T as Tool, m as ToolUseBlock, C as Context, n as ToolResultBlock, R as Request, b as Response, P as Provider, g as ContentBlock, a9 as WrongStackError } from './context-dT5Ueund.js';
|
|
2
2
|
import { L as Logger } from './logger-B63L5bTg.js';
|
|
3
|
-
import { B as BuildContext, H as HookRegistry, a as Renderer, P as Pipeline, C as Container } from './pipeline-
|
|
4
|
-
import { H as HookEvent, W as WireFamily, P as ProviderConfig } from './config-
|
|
3
|
+
import { B as BuildContext, H as HookRegistry, a as Renderer, P as Pipeline, C as Container } from './pipeline-BfD2k1rT.js';
|
|
4
|
+
import { H as HookEvent, W as WireFamily, P as ProviderConfig } from './config-Du3pYYln.js';
|
|
5
5
|
import { T as Tracer } from './observability-D-HZN_mF.js';
|
|
6
|
-
import { E as EventBus } from './brain-
|
|
7
|
-
import { P as PermissionPolicy, S as SecretScrubber } from './permission-
|
|
6
|
+
import { E as EventBus } from './brain-Cdg77tVN.js';
|
|
7
|
+
import { P as PermissionPolicy, S as SecretScrubber } from './permission-B75JAi3-.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* A contributor that injects additional TextBlocks into the system prompt.
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { T as Token, a as Renderer, S as SystemPromptBuilder, H as HookRegistry } from './pipeline-
|
|
2
|
-
import { E as EventBus, c as MemoryStore, B as BrainArbiter } from './brain-
|
|
3
|
-
import { C as Compactor } from './compactor-
|
|
4
|
-
import {
|
|
5
|
-
import { E as ErrorHandler, R as RetryPolicy } from './retry-policy-
|
|
1
|
+
import { T as Token, a as Renderer, S as SystemPromptBuilder, H as HookRegistry } from './pipeline-BfD2k1rT.js';
|
|
2
|
+
import { E as EventBus, c as MemoryStore, B as BrainArbiter } from './brain-Cdg77tVN.js';
|
|
3
|
+
import { C as Compactor } from './compactor-iMZ84CXq.js';
|
|
4
|
+
import { k as ConfigLoader, j as ConfigStore, M as ModelsRegistry } from './config-Du3pYYln.js';
|
|
5
|
+
import { E as ErrorHandler, R as RetryPolicy } from './retry-policy-BilV1ujH.js';
|
|
6
6
|
import { I as InputReader } from './input-reader-E-ffP2ee.js';
|
|
7
7
|
import { L as Logger } from './logger-B63L5bTg.js';
|
|
8
8
|
import { M as ModeStore } from './mode-CZlO9iU1.js';
|
|
9
9
|
import { P as PathResolver } from './path-resolver-CPRj4bFY.js';
|
|
10
|
-
import { P as PermissionPolicy, S as SecretScrubber } from './permission-
|
|
11
|
-
import { P as ProviderRunner } from './provider-runner-
|
|
12
|
-
import { c as TokenCounter, i as SessionStore } from './context-
|
|
10
|
+
import { P as PermissionPolicy, S as SecretScrubber } from './permission-B75JAi3-.js';
|
|
11
|
+
import { P as ProviderRunner } from './provider-runner-CX7iIvox.js';
|
|
12
|
+
import { c as TokenCounter, i as SessionStore } from './context-dT5Ueund.js';
|
|
13
13
|
import { S as SkillLoader } from './skill-DGIXCtdv.js';
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import './secret-vault-gkvEZZfE.js';
|
|
2
|
+
import './permission-policy-DlR9eJAM.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Well-known tool capabilities used for authorization decisions.
|
|
6
|
+
*
|
|
7
|
+
* These are the preferred values for `Tool.capabilities`.
|
|
8
|
+
* New capabilities should be added here with clear documentation.
|
|
9
|
+
*
|
|
10
|
+
* Philosophy (2026-06+):
|
|
11
|
+
* - Prefer capabilities over exact tool name matching.
|
|
12
|
+
* - Subagent guards and future policies should primarily key off capabilities.
|
|
13
|
+
* - Name-based denylists are legacy and will be phased down.
|
|
14
|
+
*/
|
|
15
|
+
declare const ToolCapabilities: {
|
|
16
|
+
/** Can execute arbitrary commands in the user's shell (the `bash` tool). */
|
|
17
|
+
readonly SHELL_ARBITRARY: "shell.arbitrary";
|
|
18
|
+
/** Can execute a restricted set of commands (the `exec` tool). */
|
|
19
|
+
readonly SHELL_RESTRICTED: "shell.restricted";
|
|
20
|
+
/** Can read files inside the project (and possibly outside via symlinks if not guarded). */
|
|
21
|
+
readonly FS_READ: "fs.read";
|
|
22
|
+
/** Can write / modify / delete files inside the project. */
|
|
23
|
+
readonly FS_WRITE: "fs.write";
|
|
24
|
+
/** Can write files outside the current project root (very high risk). */
|
|
25
|
+
readonly FS_WRITE_OUTSIDE_PROJECT: "fs.write.outside-project";
|
|
26
|
+
/** Can perform outbound network requests. */
|
|
27
|
+
readonly NET_OUTBOUND: "net.outbound";
|
|
28
|
+
/** Proxies tools from external MCP servers (unknown capability). */
|
|
29
|
+
readonly MCP_PROXY: "mcp.proxy";
|
|
30
|
+
/** Can spawn or manage subagents / multi-agent tasks. */
|
|
31
|
+
readonly SUBAGENT_SPAWN: "subagent.spawn";
|
|
32
|
+
/** Can mutate global or session configuration / trust state. */
|
|
33
|
+
readonly CONFIG_MUTATE: "config.mutate";
|
|
34
|
+
/** Can install packages or run package managers with side effects. */
|
|
35
|
+
readonly PACKAGE_INSTALL: "package.install";
|
|
36
|
+
};
|
|
37
|
+
type ToolCapability = (typeof ToolCapabilities)[keyof typeof ToolCapabilities];
|
|
38
|
+
/**
|
|
39
|
+
* Set of capabilities that are considered dangerous for subagents by default.
|
|
40
|
+
* Subagents should not receive these capabilities unless the leader explicitly
|
|
41
|
+
* allows the specific tool at spawn time.
|
|
42
|
+
*/
|
|
43
|
+
declare const DANGEROUS_FOR_SUBAGENTS: readonly ToolCapability[];
|
|
44
|
+
/**
|
|
45
|
+
* Wide capability allowlist for subagents that the user has authorized to act
|
|
46
|
+
* with full developer power (the CLI fleet host applies this to any subagent
|
|
47
|
+
* that isn't given an explicit, narrower grant). It covers everything needed to
|
|
48
|
+
* do real work end-to-end — read, write/edit inside the project, outbound
|
|
49
|
+
* network, and shell/build/install — so a delegated coding or build agent runs
|
|
50
|
+
* the same toolchain the leader would, without per-tool confirmation it cannot
|
|
51
|
+
* answer.
|
|
52
|
+
*
|
|
53
|
+
* Deliberately EXCLUDED (require an explicit per-spawn `allowedCapabilities`
|
|
54
|
+
* grant, because they escape the task's blast radius rather than perform it):
|
|
55
|
+
* - `fs.write.outside-project` — writing outside the repo (e.g. ~/.ssh).
|
|
56
|
+
* - `mcp.proxy` — third-party MCP tools (also hard-blocked by name).
|
|
57
|
+
* - `subagent.spawn` — recursive delegation (the baseline prompt forbids it).
|
|
58
|
+
* - `config.mutate` — rewriting trust/config is privilege escalation, not work.
|
|
59
|
+
*/
|
|
60
|
+
declare const WIDE_SUBAGENT_CAPABILITIES: readonly ToolCapability[];
|
|
61
|
+
/**
|
|
62
|
+
* Check if a tool (or its capabilities array) includes any dangerous capability
|
|
63
|
+
* for subagent execution.
|
|
64
|
+
*/
|
|
65
|
+
declare function hasDangerousCapabilityForSubagents(toolOrCaps: {
|
|
66
|
+
capabilities?: readonly string[] | undefined;
|
|
67
|
+
} | readonly string[] | undefined): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Check if a tool declares a specific capability (or any of the provided ones).
|
|
70
|
+
*/
|
|
71
|
+
declare function hasCapability(toolOrCaps: {
|
|
72
|
+
capabilities?: readonly string[] | undefined;
|
|
73
|
+
} | readonly string[] | undefined, capability: ToolCapability | ToolCapability[]): boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Returns the intersection of a tool's capabilities with the dangerous set.
|
|
76
|
+
* Useful for logging and audit trails.
|
|
77
|
+
*/
|
|
78
|
+
declare function getDangerousCapabilities(toolOrCaps: {
|
|
79
|
+
capabilities?: readonly string[] | undefined;
|
|
80
|
+
} | readonly string[] | undefined): ToolCapability[];
|
|
81
|
+
|
|
82
|
+
export { DANGEROUS_FOR_SUBAGENTS as D, ToolCapabilities as T, WIDE_SUBAGENT_CAPABILITIES as W, type ToolCapability as a, hasDangerousCapabilityForSubagents as b, getDangerousCapabilities as g, hasCapability as h };
|