@wrongstack/core 0.286.0 → 0.287.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/boot.d.ts.map +1 -1
- package/dist/coordination/brain-monitor.d.ts +15 -0
- package/dist/coordination/brain-monitor.d.ts.map +1 -1
- package/dist/coordination/delegate-tool.d.ts +8 -14
- package/dist/coordination/delegate-tool.d.ts.map +1 -1
- package/dist/coordination/director/director-btw-notes.d.ts +20 -0
- package/dist/coordination/director/director-btw-notes.d.ts.map +1 -0
- package/dist/coordination/director/director-collab.d.ts +40 -0
- package/dist/coordination/director/director-collab.d.ts.map +1 -0
- package/dist/coordination/director.d.ts +27 -8
- package/dist/coordination/director.d.ts.map +1 -1
- package/dist/coordination/fleet-manager.d.ts +21 -0
- package/dist/coordination/fleet-manager.d.ts.map +1 -1
- package/dist/coordination/fleet.d.ts +2 -3
- package/dist/coordination/fleet.d.ts.map +1 -1
- package/dist/coordination/global-mailbox.d.ts +36 -22
- package/dist/coordination/global-mailbox.d.ts.map +1 -1
- package/dist/coordination/icoordinator.d.ts +1 -3
- package/dist/coordination/icoordinator.d.ts.map +1 -1
- package/dist/coordination/index.js +708 -442
- package/dist/coordination/index.js.map +4 -4
- package/dist/coordination/mail-tools.d.ts.map +1 -1
- package/dist/coordination/mailbox-message-codec.d.ts +21 -1
- package/dist/coordination/mailbox-message-codec.d.ts.map +1 -1
- package/dist/coordination/mailbox-types.d.ts +42 -1
- package/dist/coordination/mailbox-types.d.ts.map +1 -1
- package/dist/core/agent-loop.d.ts.map +1 -1
- package/dist/core/agent-response.d.ts +10 -1
- package/dist/core/agent-response.d.ts.map +1 -1
- package/dist/core/agent-tools.d.ts.map +1 -1
- package/dist/core/agent.d.ts +8 -0
- package/dist/core/agent.d.ts.map +1 -1
- package/dist/core/context.d.ts +25 -0
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/conversation-state.d.ts +6 -0
- package/dist/core/conversation-state.d.ts.map +1 -1
- package/dist/core/fallback-model.d.ts.map +1 -1
- package/dist/core/mailbox-loop.d.ts +12 -5
- package/dist/core/mailbox-loop.d.ts.map +1 -1
- package/dist/core/system-prompt-builder.d.ts +14 -6
- package/dist/core/system-prompt-builder.d.ts.map +1 -1
- package/dist/defaults/index.d.ts +0 -1
- package/dist/defaults/index.d.ts.map +1 -1
- package/dist/defaults/index.js +834 -1465
- package/dist/defaults/index.js.map +4 -4
- package/dist/execution/auto-compaction-middleware.d.ts +8 -1
- package/dist/execution/auto-compaction-middleware.d.ts.map +1 -1
- package/dist/execution/compaction-core.d.ts.map +1 -1
- package/dist/execution/council-brain.d.ts.map +1 -1
- package/dist/execution/council-orchestrator.d.ts +32 -0
- package/dist/execution/council-orchestrator.d.ts.map +1 -0
- package/dist/execution/council-personas.d.ts +19 -0
- package/dist/execution/council-personas.d.ts.map +1 -0
- package/dist/execution/council-profiles.d.ts +34 -0
- package/dist/execution/council-profiles.d.ts.map +1 -0
- package/dist/execution/council-prompts.d.ts +21 -0
- package/dist/execution/council-prompts.d.ts.map +1 -0
- package/dist/execution/council-resolution.d.ts +57 -0
- package/dist/execution/council-resolution.d.ts.map +1 -0
- package/dist/execution/design-kit-loader.d.ts.map +1 -1
- package/dist/execution/enhance-recovery.d.ts +35 -0
- package/dist/execution/enhance-recovery.d.ts.map +1 -0
- package/dist/execution/error-handler.d.ts.map +1 -1
- package/dist/execution/index.d.ts +6 -0
- package/dist/execution/index.d.ts.map +1 -1
- package/dist/execution/index.js +1738 -161
- package/dist/execution/index.js.map +4 -4
- package/dist/execution/intelligent-compactor.d.ts +18 -7
- package/dist/execution/intelligent-compactor.d.ts.map +1 -1
- package/dist/execution/one-shot-llm.d.ts +52 -0
- package/dist/execution/one-shot-llm.d.ts.map +1 -0
- package/dist/execution/prompt-enhancer.d.ts +23 -4
- package/dist/execution/prompt-enhancer.d.ts.map +1 -1
- package/dist/execution/prompt-enhancer.js +24 -6
- package/dist/execution/prompt-enhancer.js.map +2 -2
- package/dist/execution/selective-compactor.d.ts +4 -4
- package/dist/execution/strategy-compactor.d.ts +7 -0
- package/dist/execution/strategy-compactor.d.ts.map +1 -1
- package/dist/execution/tool-executor.d.ts +19 -5
- package/dist/execution/tool-executor.d.ts.map +1 -1
- package/dist/hooks/registry.d.ts.map +1 -1
- package/dist/hooks/runner.d.ts.map +1 -1
- package/dist/hooks/shell-executor.d.ts.map +1 -1
- package/dist/hq/alerts.d.ts +5 -0
- package/dist/hq/alerts.d.ts.map +1 -1
- package/dist/hq/auth-store.d.ts +17 -7
- package/dist/hq/auth-store.d.ts.map +1 -1
- package/dist/hq/commands.d.ts +8 -4
- package/dist/hq/commands.d.ts.map +1 -1
- package/dist/hq/cost-bridge.d.ts +5 -3
- package/dist/hq/cost-bridge.d.ts.map +1 -1
- package/dist/hq/fleet-bridge.d.ts.map +1 -1
- package/dist/hq/index.d.ts +0 -1
- package/dist/hq/index.d.ts.map +1 -1
- package/dist/hq/index.js +471 -294
- package/dist/hq/index.js.map +4 -4
- package/dist/hq/persistence.d.ts +42 -0
- package/dist/hq/persistence.d.ts.map +1 -1
- package/dist/hq/protocol/brain.d.ts +24 -0
- package/dist/hq/protocol/brain.d.ts.map +1 -0
- package/dist/hq/protocol/browser.d.ts +12 -0
- package/dist/hq/protocol/browser.d.ts.map +1 -0
- package/dist/hq/protocol/client.d.ts +69 -0
- package/dist/hq/protocol/client.d.ts.map +1 -0
- package/dist/hq/protocol/core.d.ts +130 -0
- package/dist/hq/protocol/core.d.ts.map +1 -0
- package/dist/hq/protocol/fleet.d.ts +73 -0
- package/dist/hq/protocol/fleet.d.ts.map +1 -0
- package/dist/hq/protocol/mailbox.d.ts +76 -0
- package/dist/hq/protocol/mailbox.d.ts.map +1 -0
- package/dist/hq/protocol/mcp.d.ts +51 -0
- package/dist/hq/protocol/mcp.d.ts.map +1 -0
- package/dist/hq/protocol/project.d.ts +26 -0
- package/dist/hq/protocol/project.d.ts.map +1 -0
- package/dist/hq/protocol/session.d.ts +153 -0
- package/dist/hq/protocol/session.d.ts.map +1 -0
- package/dist/hq/protocol/tool.d.ts +31 -0
- package/dist/hq/protocol/tool.d.ts.map +1 -0
- package/dist/hq/protocol.d.ts +10 -611
- package/dist/hq/protocol.d.ts.map +1 -1
- package/dist/index.d.ts +12 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4540 -2283
- package/dist/index.js.map +4 -4
- package/dist/infrastructure/index.js +13 -11
- package/dist/infrastructure/index.js.map +2 -2
- package/dist/infrastructure/token-counter.d.ts.map +1 -1
- package/dist/kernel/events/agent-events.d.ts +283 -0
- package/dist/kernel/events/agent-events.d.ts.map +1 -0
- package/dist/kernel/events/brain-events.d.ts +176 -0
- package/dist/kernel/events/brain-events.d.ts.map +1 -0
- package/dist/kernel/events/fleet-events.d.ts +39 -0
- package/dist/kernel/events/fleet-events.d.ts.map +1 -0
- package/dist/kernel/events/memory-events.d.ts +165 -0
- package/dist/kernel/events/memory-events.d.ts.map +1 -0
- package/dist/kernel/events/provider-events.d.ts +98 -0
- package/dist/kernel/events/provider-events.d.ts.map +1 -0
- package/dist/kernel/events/sdd-events.d.ts +118 -0
- package/dist/kernel/events/sdd-events.d.ts.map +1 -0
- package/dist/kernel/events/session-events.d.ts +227 -0
- package/dist/kernel/events/session-events.d.ts.map +1 -0
- package/dist/kernel/events/tool-events.d.ts +185 -0
- package/dist/kernel/events/tool-events.d.ts.map +1 -0
- package/dist/kernel/events/worktree-events.d.ts +58 -0
- package/dist/kernel/events/worktree-events.d.ts.map +1 -0
- package/dist/kernel/events.d.ts +10 -1298
- package/dist/kernel/events.d.ts.map +1 -1
- package/dist/kernel/index.js +22 -2
- package/dist/kernel/index.js.map +2 -2
- package/dist/kernel/run-controller.d.ts +15 -0
- package/dist/kernel/run-controller.d.ts.map +1 -1
- package/dist/mailbox-attach.d.ts.map +1 -1
- package/dist/models/index.js +19 -6
- package/dist/models/index.js.map +2 -2
- package/dist/models/llm-selector.d.ts +7 -0
- package/dist/models/llm-selector.d.ts.map +1 -1
- package/dist/plugins/auto-review-plugin.d.ts +36 -0
- package/dist/plugins/auto-review-plugin.d.ts.map +1 -0
- package/dist/plugins/chimera-plugin.d.ts +8 -0
- package/dist/plugins/chimera-plugin.d.ts.map +1 -1
- package/dist/security/index.js +7 -2
- package/dist/security/index.js.map +2 -2
- package/dist/security/secret-scrubber.d.ts.map +1 -1
- package/dist/skills/index.js.map +2 -2
- package/dist/storage/config-loader.d.ts.map +1 -1
- package/dist/storage/goal-kanban.d.ts +69 -0
- package/dist/storage/goal-kanban.d.ts.map +1 -0
- package/dist/storage/index.d.ts +1 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +425 -717
- package/dist/storage/index.js.map +4 -4
- package/dist/storage/memory-consolidator.d.ts +9 -1
- package/dist/storage/memory-consolidator.d.ts.map +1 -1
- package/dist/tools/council-tool.d.ts +25 -0
- package/dist/tools/council-tool.d.ts.map +1 -0
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +1884 -12
- package/dist/tools/index.js.map +4 -4
- package/dist/tools/one-shot-llm-tool.d.ts +51 -0
- package/dist/tools/one-shot-llm-tool.d.ts.map +1 -0
- package/dist/types/config.d.ts +27 -3
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/context-window.d.ts.map +1 -1
- package/dist/types/council.d.ts +134 -0
- package/dist/types/council.d.ts.map +1 -0
- package/dist/types/default-config.d.ts +3 -3
- package/dist/types/hooks.d.ts +14 -0
- package/dist/types/hooks.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +29 -8
- package/dist/types/index.js.map +3 -3
- package/dist/types/one-shot-llm.d.ts +128 -0
- package/dist/types/one-shot-llm.d.ts.map +1 -0
- package/dist/types/plugin.d.ts +6 -0
- package/dist/types/plugin.d.ts.map +1 -1
- package/dist/types/provider.d.ts +17 -0
- package/dist/types/provider.d.ts.map +1 -1
- package/dist/types/system-prompt.d.ts +2 -1
- package/dist/types/system-prompt.d.ts.map +1 -1
- package/dist/types/tool-executor.d.ts +10 -0
- package/dist/types/tool-executor.d.ts.map +1 -1
- package/dist/utils/atomic-write.d.ts.map +1 -1
- package/dist/utils/index.js +75 -8
- package/dist/utils/index.js.map +3 -3
- package/dist/utils/tool-wire-compact.d.ts +1 -0
- package/dist/utils/tool-wire-compact.d.ts.map +1 -1
- package/dist/utils/wstack-paths.d.ts +20 -4
- package/dist/utils/wstack-paths.d.ts.map +1 -1
- package/instructions/cli/next-task-predictor.md +5 -3
- package/instructions/coordination/subagent-baseline.md +8 -7
- package/instructions/leader-after-task.md +18 -9
- package/instructions/llm/council-judge.md +19 -0
- package/instructions/llm/council-voter.md +22 -0
- package/instructions/modes/architect.md +14 -9
- package/instructions/modes/audit-lite.md +9 -7
- package/instructions/modes/brief-system.md +12 -12
- package/instructions/modes/brief.md +7 -5
- package/instructions/modes/code-auditor.md +13 -8
- package/instructions/modes/code-reviewer.md +13 -8
- package/instructions/modes/debug-lite.md +7 -6
- package/instructions/modes/debugger.md +13 -9
- package/instructions/modes/devops.md +13 -9
- package/instructions/modes/plan-lite.md +7 -6
- package/instructions/modes/refactor-lite.md +7 -6
- package/instructions/modes/refactorer.md +14 -9
- package/instructions/modes/research-lite.md +8 -6
- package/instructions/modes/research-web.md +18 -55
- package/instructions/modes/review-lite.md +7 -6
- package/instructions/modes/teach-system.md +15 -15
- package/instructions/modes/teach.md +13 -12
- package/instructions/modes/test-lite.md +6 -5
- package/instructions/modes/tester.md +13 -9
- package/instructions/modes/ui-design.md +14 -8
- package/instructions/sections/tool/commit-hygiene.md +1 -7
- package/instructions/sections/tool/common-patterns.md +5 -5
- package/instructions/sections/tool/delegation-full.md +3 -31
- package/instructions/sections/tool/mailbox-compact.md +1 -1
- package/instructions/sections/tool/mailbox-full.md +6 -22
- package/instructions/system.md +278 -39
- package/package.json +2 -2
- package/skills/mailbox-bridge/SKILL.md +16 -7
- package/skills/output-standards/SKILL.md +16 -16
- package/skills/wrongstack-mailbox/SKILL.md +6 -0
- package/dist/coordination/director-construction.d.ts +0 -90
- package/dist/coordination/director-construction.d.ts.map +0 -1
- package/dist/hq/agent-bridge.d.ts +0 -27
- package/dist/hq/agent-bridge.d.ts.map +0 -1
- package/dist/storage/memory-store.d.ts +0 -119
- package/dist/storage/memory-store.d.ts.map +0 -1
|
@@ -1,32 +1,40 @@
|
|
|
1
1
|
import type { Context } from '../core/context.js';
|
|
2
2
|
import type { CompactReport, Compactor } from '../types/compactor.js';
|
|
3
3
|
import type { Provider } from '../types/provider.js';
|
|
4
|
+
import type { OneShotOrchestrator } from './one-shot-llm.js';
|
|
4
5
|
/**
|
|
5
6
|
* Options for IntelligentCompactor.
|
|
6
7
|
*/
|
|
7
8
|
export interface IntelligentCompactorOptions {
|
|
8
9
|
/** Provider to use for LLM-assisted summarization. Required. */
|
|
9
10
|
provider: Provider;
|
|
10
|
-
/** Fraction of maxContext that triggers a warning (default 0.
|
|
11
|
+
/** Fraction of maxContext that triggers a warning (default 0.5). */
|
|
11
12
|
warnThreshold?: number | undefined;
|
|
12
|
-
/** Fraction of maxContext that triggers soft compaction (default 0.
|
|
13
|
+
/** Fraction of maxContext that triggers soft compaction (default 0.65). */
|
|
13
14
|
softThreshold?: number | undefined;
|
|
14
|
-
/** Fraction of maxContext that triggers hard compaction (default 0.
|
|
15
|
+
/** Fraction of maxContext that triggers hard compaction (default 0.8). */
|
|
15
16
|
hardThreshold?: number | undefined;
|
|
16
17
|
/** Max context window in tokens (used only for threshold fraction math). */
|
|
17
18
|
maxContext?: number | undefined;
|
|
18
19
|
/** How many recent (user+assistant) pairs to always preserve (default 4). */
|
|
19
20
|
preserveK?: number | undefined;
|
|
20
|
-
/** Token threshold below which tool results are not elided (default
|
|
21
|
+
/** Token threshold below which tool results are not elided (default 300). */
|
|
21
22
|
eliseThreshold?: number | undefined;
|
|
22
23
|
/** System prompt for the summarizer sub-LLM. */
|
|
23
24
|
summarizerPrompt?: string | undefined;
|
|
24
25
|
/**
|
|
25
|
-
* Model ID to use for summarization. When not set,
|
|
26
|
-
*
|
|
27
|
-
* a fast/cheap configured model for
|
|
26
|
+
* Model ID to use for summarization. When not set, falls back to
|
|
27
|
+
* "deepseek-chat" when a OneShotOrchestrator is wired, or the agent's
|
|
28
|
+
* own model otherwise. Set to a fast/cheap configured model for
|
|
29
|
+
* resilience and cost efficiency.
|
|
28
30
|
*/
|
|
29
31
|
summarizerModel?: string | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* OneShotOrchestrator for LLM-assisted summarization. When set,
|
|
34
|
+
* `callSummarizer` uses it instead of the direct provider.complete()
|
|
35
|
+
* path, gaining fallback chain support and cheap-model defaulting.
|
|
36
|
+
*/
|
|
37
|
+
oneShotOrchestrator?: OneShotOrchestrator | undefined;
|
|
30
38
|
}
|
|
31
39
|
/**
|
|
32
40
|
* An importance label for a message or message range.
|
|
@@ -67,6 +75,7 @@ export declare class IntelligentCompactor implements Compactor {
|
|
|
67
75
|
private readonly eliseThreshold;
|
|
68
76
|
private readonly summarizerPrompt;
|
|
69
77
|
private readonly summarizerModel?;
|
|
78
|
+
private readonly oneShotOrchestrator?;
|
|
70
79
|
constructor(opts: IntelligentCompactorOptions);
|
|
71
80
|
compact(ctx: Context, opts?: {
|
|
72
81
|
aggressive?: boolean | undefined;
|
|
@@ -81,5 +90,7 @@ export declare class IntelligentCompactor implements Compactor {
|
|
|
81
90
|
private summarizeAncientTurns;
|
|
82
91
|
private callSummarizer;
|
|
83
92
|
private messagesToText;
|
|
93
|
+
/** Compact string summary of messages (no TextBlock wrapper). */
|
|
94
|
+
private messagesToSummary;
|
|
84
95
|
}
|
|
85
96
|
//# sourceMappingURL=intelligent-compactor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intelligent-compactor.d.ts","sourceRoot":"","sources":["../../src/execution/intelligent-compactor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAGlD,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEtE,OAAO,KAAK,EAAE,QAAQ,EAAW,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"intelligent-compactor.d.ts","sourceRoot":"","sources":["../../src/execution/intelligent-compactor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAGlD,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEtE,OAAO,KAAK,EAAE,QAAQ,EAAW,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAY7D;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,gEAAgE;IAChE,QAAQ,EAAE,QAAQ,CAAC;IACnB,oEAAoE;IACpE,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,2EAA2E;IAC3E,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,0EAA0E;IAC1E,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,6EAA6E;IAC7E,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,gDAAgD;IAChD,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC;CACvD;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,UAAU,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3E,cAAc,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACtE;AAED;;;;;;;;;GASG;AACH,qBAAa,oBAAqB,YAAW,SAAS;IACpD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAqB;IACtD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAkC;IAEvE,YAAY,IAAI,EAAE,2BAA2B,EAa5C;IAEK,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,GAAE;QAAE,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;KAAO,GAAG,OAAO,CAAC,aAAa,CAAC,CAmDnG;IAED;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAI3B,2EAA2E;IAC3E,OAAO,CAAC,KAAK;YASC,qBAAqB;YA6CrB,cAAc;IAmD5B,OAAO,CAAC,cAAc;IAgBtB,iEAAiE;IACjE,OAAO,CAAC,iBAAiB;CAe1B"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { OneShotLLMInput, OneShotLLMResult, OneShotOrchestratorOptions } from '../types/one-shot-llm.js';
|
|
2
|
+
/**
|
|
3
|
+
* OneShotOrchestrator — a stateless, reusable utility for making single
|
|
4
|
+
* LLM calls with provider resolution, fallback chains, and structured results.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* ```ts
|
|
8
|
+
* const oneShot = new OneShotOrchestrator({ buildProvider, getConfig });
|
|
9
|
+
* const result = await oneShot.call({
|
|
10
|
+
* system: 'You are a helpful assistant.',
|
|
11
|
+
* userPrompt: 'Summarize this conversation.',
|
|
12
|
+
* model: 'deepseek-chat',
|
|
13
|
+
* fallbackProfile: 'summary',
|
|
14
|
+
* });
|
|
15
|
+
* console.log(result.text);
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* Every method is stateless — a single instance can be shared across
|
|
19
|
+
* the entire process lifetime.
|
|
20
|
+
*/
|
|
21
|
+
export declare class OneShotOrchestrator {
|
|
22
|
+
private readonly opts;
|
|
23
|
+
constructor(opts: OneShotOrchestratorOptions);
|
|
24
|
+
/**
|
|
25
|
+
* Make a one-shot LLM call. Resolves provider+model, applies fallback
|
|
26
|
+
* chain on transient errors, and returns a structured result.
|
|
27
|
+
*
|
|
28
|
+
* Never throws — all errors are captured in `OneShotLLMResult.error`.
|
|
29
|
+
*/
|
|
30
|
+
call(input: OneShotLLMInput): Promise<OneShotLLMResult>;
|
|
31
|
+
/**
|
|
32
|
+
* Resolve the target provider + model from input + config.
|
|
33
|
+
* Priority: role-based routing > explicit providerId+model > defaults.
|
|
34
|
+
*/
|
|
35
|
+
private resolveTarget;
|
|
36
|
+
/**
|
|
37
|
+
* Build a Provider Request from the input.
|
|
38
|
+
*/
|
|
39
|
+
private buildRequest;
|
|
40
|
+
/**
|
|
41
|
+
* Resolve the abort signal. Provider calls always receive the per-call
|
|
42
|
+
* timeout, composed with external cancellation when the caller supplies it.
|
|
43
|
+
*/
|
|
44
|
+
private resolveSignal;
|
|
45
|
+
/**
|
|
46
|
+
* Build the fallback model chain from input + config + current target.
|
|
47
|
+
*/
|
|
48
|
+
private resolveFallbackChain;
|
|
49
|
+
/** Attempt a provider call while preserving the actual failure for callers. */
|
|
50
|
+
private tryCall;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=one-shot-llm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"one-shot-llm.d.ts","sourceRoot":"","sources":["../../src/execution/one-shot-llm.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AAwB9G;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA6B;IAElD,YAAY,IAAI,EAAE,0BAA0B,EAE3C;IAED;;;;;OAKG;IACG,IAAI,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAsH5D;IAID;;;OAGG;IACH,OAAO,CAAC,aAAa;IAmCrB;;OAEG;IACH,OAAO,CAAC,YAAY;IAkBpB;;;OAGG;IACH,OAAO,CAAC,aAAa;IAKrB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IA4B5B,+EAA+E;YACjE,OAAO;CAmBtB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Message } from '../types/messages.js';
|
|
2
2
|
import type { Provider, ReasoningConfig, ReasoningRequest } from '../types/provider.js';
|
|
3
|
+
import type { OneShotOrchestrator } from './one-shot-llm.js';
|
|
3
4
|
/**
|
|
4
5
|
* Prompt refinement ("did you mean this?").
|
|
5
6
|
*
|
|
@@ -62,6 +63,16 @@ export interface EnhanceResult {
|
|
|
62
63
|
/** Refined in English. Equals `refined` when the input was already English. */
|
|
63
64
|
english: string;
|
|
64
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Why a refine attempt fell through. Callers use this to decide the recovery
|
|
68
|
+
* path: `timeout` is a transient capacity/latency failure worth an automatic
|
|
69
|
+
* retry with a longer window (the model was reachable, just slow); `empty` and
|
|
70
|
+
* `provider_error` mean the attempt produced nothing useful, so the caller
|
|
71
|
+
* should surface the recovery options (retry, switch model, send as-is) rather
|
|
72
|
+
* than silently retry. User-initiated cancellation is NOT reported here (it
|
|
73
|
+
* returns `null` with no `onError` call).
|
|
74
|
+
*/
|
|
75
|
+
export type EnhanceFailureKind = 'timeout' | 'empty' | 'provider_error';
|
|
65
76
|
export interface EnhanceUserPromptOptions {
|
|
66
77
|
provider: Provider;
|
|
67
78
|
model: string;
|
|
@@ -91,11 +102,19 @@ export interface EnhanceUserPromptOptions {
|
|
|
91
102
|
*/
|
|
92
103
|
reasoning?: ReasoningRequest | undefined;
|
|
93
104
|
/**
|
|
94
|
-
* Called with a short reason
|
|
95
|
-
* empty response). NOT called when the caller
|
|
96
|
-
*
|
|
105
|
+
* Called with a short reason and a machine-readable `kind` when refinement
|
|
106
|
+
* fails (provider error, timeout, empty response). NOT called when the caller
|
|
107
|
+
* cancels via `signal`. The `kind` lets the UI drive recovery: `timeout` is
|
|
108
|
+
* eligible for an automatic longer-window retry; `empty` / `provider_error`
|
|
109
|
+
* surface the recovery options instead. The second argument is optional so
|
|
110
|
+
* existing callers that only read the reason keep compiling.
|
|
111
|
+
*/
|
|
112
|
+
onError?: ((reason: string, kind?: EnhanceFailureKind) => void) | undefined;
|
|
113
|
+
/**
|
|
114
|
+
* OneShotOrchestrator for the refiner LLM call. When set, uses it instead
|
|
115
|
+
* of direct provider.complete(), gaining fallback chain support.
|
|
97
116
|
*/
|
|
98
|
-
|
|
117
|
+
oneShotOrchestrator?: OneShotOrchestrator | undefined;
|
|
99
118
|
}
|
|
100
119
|
/**
|
|
101
120
|
* Refine a raw user prompt. Returns the refined text, or `null` when the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt-enhancer.d.ts","sourceRoot":"","sources":["../../src/execution/prompt-enhancer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,KAAK,EACV,QAAQ,EACR,eAAe,EAEf,gBAAgB,EAEjB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"prompt-enhancer.d.ts","sourceRoot":"","sources":["../../src/execution/prompt-enhancer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,KAAK,EACV,QAAQ,EACR,eAAe,EAEf,gBAAgB,EAEjB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAG7D;;;;;;;;;;;;GAYG;AAEH,eAAO,MAAM,sBAAsB,QAAuD,CAAC;AAM3F;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAUnD;AAoBD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CACpC,EAAE,EAAE,eAAe,GAAG,SAAS,GAC9B,gBAAgB,GAAG,SAAS,CAU9B;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAG7D;AAED,oEAAoE;AACpE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,+EAA+E;IAC/E,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,OAAO,GAAG,gBAAgB,CAAC;AAExE,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,gBAAgB,EAAE,GAAG,SAAS,CAAC;IACzC,2DAA2D;IAC3D,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IACjC,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACzC;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,kBAAkB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC5E;;;OAGG;IACH,mBAAmB,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC;CACvD;AAmBD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAgG/B;AAYD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,OAAO,EAAE,EACnB,QAAQ,SAAI,EACZ,QAAQ,SAAO,GACd,gBAAgB,EAAE,CAapB"}
|
|
@@ -118,10 +118,28 @@ async function enhanceUserPrompt(opts) {
|
|
|
118
118
|
const to = setTimeout(() => timer.abort(new Error("enhancer timeout")), timeoutMs);
|
|
119
119
|
const signal = opts.signal ? AbortSignal.any([opts.signal, timer.signal]) : timer.signal;
|
|
120
120
|
try {
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
let raw;
|
|
122
|
+
if (opts.oneShotOrchestrator) {
|
|
123
|
+
const result = await opts.oneShotOrchestrator.call({
|
|
124
|
+
system: ENHANCER_SYSTEM_PROMPT,
|
|
125
|
+
messages: [
|
|
126
|
+
{ role: "user", content: buildRefinerInput(text, opts.history) }
|
|
127
|
+
],
|
|
128
|
+
maxTokens,
|
|
129
|
+
timeoutMs,
|
|
130
|
+
signal: opts.signal
|
|
131
|
+
});
|
|
132
|
+
if (result.error) {
|
|
133
|
+
opts.onError?.(result.error, "provider_error");
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
raw = result.text;
|
|
137
|
+
} else {
|
|
138
|
+
const res = await provider.complete(req, { signal });
|
|
139
|
+
raw = res.content.filter(isTextBlock).map((b) => b.text).join("\n").trim();
|
|
140
|
+
}
|
|
123
141
|
if (!raw) {
|
|
124
|
-
opts.onError?.("model returned no text");
|
|
142
|
+
opts.onError?.("model returned no text", "empty");
|
|
125
143
|
return null;
|
|
126
144
|
}
|
|
127
145
|
const sepIdx = raw.indexOf("\n---\n");
|
|
@@ -131,17 +149,17 @@ async function enhanceUserPrompt(opts) {
|
|
|
131
149
|
const refined = raw.slice(0, sepIdx).trim();
|
|
132
150
|
const english = raw.slice(sepIdx + 5).trim();
|
|
133
151
|
if (!refined || !english) {
|
|
134
|
-
opts.onError?.("one or both versions empty");
|
|
152
|
+
opts.onError?.("one or both versions empty", "empty");
|
|
135
153
|
return null;
|
|
136
154
|
}
|
|
137
155
|
return { refined, english };
|
|
138
156
|
} catch (err) {
|
|
139
157
|
if (opts.signal?.aborted) return null;
|
|
140
158
|
if (timer.signal.aborted) {
|
|
141
|
-
opts.onError?.(`timed out after ${Math.round(timeoutMs / 1e3)}s
|
|
159
|
+
opts.onError?.(`timed out after ${Math.round(timeoutMs / 1e3)}s`, "timeout");
|
|
142
160
|
return null;
|
|
143
161
|
}
|
|
144
|
-
opts.onError?.(toErrorMessage(err));
|
|
162
|
+
opts.onError?.(toErrorMessage(err), "provider_error");
|
|
145
163
|
return null;
|
|
146
164
|
} finally {
|
|
147
165
|
timer.abort();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/types/blocks.ts", "../../src/utils/error.ts", "../../src/utils/instruction-file.ts", "../../src/execution/prompt-enhancer.ts"],
|
|
4
|
-
"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` \u2014 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` \u2014 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` \u2014 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 \u2014 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}\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 { readFileSync, statSync } from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Cache of resolved instruction text, keyed by the relative path. Bundled\n * instruction files are immutable for the process lifetime, so re-reading them\n * on every call (some callers do so per LLM request) is wasted disk I/O.\n */\nconst textCache = new Map<string, string>();\n\n/** Resolved once \u2014 the candidate roots only depend on this module's location. */\nlet rootCandidates: string[] | undefined;\n\nexport function readBundledInstructionText(relativePath: string): string {\n const cached = textCache.get(relativePath);\n if (cached !== undefined) return cached;\n\n let resolved = '';\n for (const root of instructionRootCandidates()) {\n try {\n resolved = readFileSync(path.join(root, relativePath), 'utf8').trimEnd();\n break;\n } catch {\n // try next candidate\n }\n }\n textCache.set(relativePath, resolved);\n return resolved;\n}\n\nexport function renderInstructionTemplate(\n template: string,\n values: Record<string, string>,\n): string {\n return template.replace(/\\{\\{\\s*([a-zA-Z0-9_.-]+)\\s*\\}\\}/g, (match, key: string) =>\n Object.hasOwn(values, key) ? (values[key] ?? '') : match,\n );\n}\n\nfunction instructionRootCandidates(): string[] {\n if (rootCandidates !== undefined) return rootCandidates;\n const here = path.dirname(fileURLToPath(import.meta.url));\n const candidates = [\n path.resolve(here, '../../instructions'),\n path.resolve(here, '../instructions'),\n path.resolve(here, 'instructions'),\n ];\n rootCandidates = candidates.sort((a, b) => Number(!isDirectory(a)) - Number(!isDirectory(b)));\n return rootCandidates;\n}\n\nfunction isDirectory(candidate: string): boolean {\n try {\n return statSync(candidate).isDirectory();\n } catch {\n return false;\n }\n}\n", "import type { ContentBlock } from '../types/blocks.js';\nimport { isTextBlock } from '../types/blocks.js';\nimport type { Message } from '../types/messages.js';\nimport type {\n Provider,\n ReasoningConfig,\n ReasoningEffort,\n ReasoningRequest,\n Request,\n} from '../types/provider.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport { readBundledInstructionText } from '../utils/instruction-file.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` \u2014 a plain\n * `provider.complete()` with a dedicated system prompt \u2014 and is deliberately\n * free of React / TUI dependencies so it can be unit-tested in isolation.\n */\n\nexport const ENHANCER_SYSTEM_PROMPT = readBundledInstructionText('llm/prompt-enhancer.md');\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\u20132 words rarely benefit\n return true;\n}\n\n/**\n * Preference order when picking an effort level: the cheapest level that still\n * does SOME reasoning first ('low', then 'minimal'), then up the ladder, with\n * fully-off ('none') last so it's only chosen when it's the sole advertised\n * option. This keeps the refiner cheap without dropping reasoning entirely when\n * a little still helps. 'low' leads because it's the most widely accepted low\n * level across adapters (e.g. OpenAI's reasoning_effort set).\n */\nconst EFFORT_PREFERENCE: ReasoningEffort[] = [\n 'low',\n 'minimal',\n 'medium',\n 'high',\n 'xhigh',\n 'max',\n 'none',\n];\n\n/**\n * Build a reasoning directive for the refiner that minimizes wasted thinking,\n * gated to what the model actually accepts. Refinement is a shallow rewrite\n * task \u2014 extended thinking adds latency and (hidden) token cost for little\n * gain \u2014 so we ask the model to spend as little reasoning as it safely can.\n *\n * The gating mirrors `resolveReasoningForRequest` so we never send a field the\n * model would reject:\n * - effort-capable model \u2192 its lowest advertised effort level;\n * - else disable-capable model \u2192 disable thinking (`enabled: false`);\n * - else (always-on / unknown) \u2192 `undefined` (leave the provider default).\n *\n * Returns `undefined` whenever nothing can be safely reduced. Callers forward\n * that verbatim to `enhanceUserPrompt`, which then sends no reasoning field \u2014\n * identical to the behavior before this hint existed. Pure + exported for unit\n * testing.\n */\nexport function gatedEnhancerReasoning(\n rc: ReasoningConfig | undefined,\n): ReasoningRequest | undefined {\n // Capabilities unknown \u2192 don't risk an unsupported field (matches the\n // conservative \"capabilities unknown\" branch in resolveReasoningForRequest).\n if (!rc) return undefined;\n if (rc.effortSupported && rc.effortLevels.length > 0) {\n const lowest = EFFORT_PREFERENCE.find((e) => rc.effortLevels.includes(e)) ?? rc.effortLevels[0];\n if (lowest) return { effort: lowest };\n }\n if (rc.disableSupported) return { enabled: false };\n return undefined;\n}\n\n/**\n * Normalize for \"did the refiner actually change anything?\" comparison \u2014\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. Carries the original-language and\n * English versions so the UI can offer both. When the input was already in\n * English the refiner emits a single version and both fields hold the same\n * text (the UI then offers two identical choices, which is correct).\n */\nexport interface EnhanceResult {\n /** Refined in the user's original language. */\n refined: string;\n /** Refined in English. Equals `refined` when the input was already English. */\n english: string;\n}\n\nexport interface EnhanceUserPromptOptions {\n provider: Provider;\n model: string;\n text: string;\n /**\n * Recent conversation turns (oldest\u2192newest), 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 * Reasoning directive for the refiner call. Refinement is a shallow\n * restate-this-more-clearly task that does not benefit from extended\n * thinking, so callers pass a low-effort / thinking-disabled hint here to\n * cut latency and (hidden) reasoning-token cost \u2014 most impactful on slow\n * reasoning models. Build it with `gatedEnhancerReasoning(rc)` so the field\n * is gated to what the model accepts. Omit (undefined) to send no reasoning\n * directive at all (the provider's own default applies).\n */\n reasoning?: ReasoningRequest | 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 \u2014 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 \u2014 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 (\u2192 empty completion \u2192 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, \u2026) return HTTP 400 when\n // `temperature` is present \u2014 which would make every refine call fail and\n // silently fall back to the original (no panel shown).\n //\n // A reasoning hint is forwarded ONLY when the caller supplies one (it must\n // already be gated to the model's advertised support \u2014 see\n // `gatedEnhancerReasoning`). Absent it, no reasoning field is sent, which\n // is identical to the original behavior.\n ...(opts.reasoning ? { reasoning: opts.reasoning } : {}),\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 ? AbortSignal.any([opts.signal, timer.signal]) : 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 // English input \u2192 ONE version (no \"---\"); other languages \u2192 two versions\n // separated by a line with only \"---\". Split on the first occurrence so the\n // delimiter can still appear inside the second version's text.\n const sepIdx = raw.indexOf('\\n---\\n');\n if (sepIdx === -1) {\n // Single version: the input was already English (or the model chose not\n // to translate). Use it for both fields \u2014 the UI offers identical\n // \"refined\" / \"english\" options, which is correct and saves the model\n // from generating a redundant second copy. NOT an error.\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 \u2192 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 \u2014 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)}\u2026` : text,\n });\n }\n return turns;\n}\n"],
|
|
5
|
-
"mappings": ";AA2EO,SAAS,YAAY,GAAiC;AAC3D,SAAO,EAAE,SAAS;AACpB;;;ACzEO,SAAS,eAAe,KAAsB;AACnD,SAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AACxD;;;ACNA,SAAS,cAAc,gBAAgB;AACvC,YAAY,UAAU;AACtB,SAAS,qBAAqB;AAO9B,IAAM,YAAY,oBAAI,IAAoB;AAG1C,IAAI;AAEG,SAAS,2BAA2B,cAA8B;AACvE,QAAM,SAAS,UAAU,IAAI,YAAY;AACzC,MAAI,WAAW,OAAW,QAAO;AAEjC,MAAI,WAAW;AACf,aAAW,QAAQ,0BAA0B,GAAG;AAC9C,QAAI;AACF,iBAAW,aAAkB,UAAK,MAAM,YAAY,GAAG,MAAM,EAAE,QAAQ;AACvE;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AACA,YAAU,IAAI,cAAc,QAAQ;AACpC,SAAO;AACT;AAWA,SAAS,4BAAsC;AAC7C,MAAI,mBAAmB,OAAW,QAAO;AACzC,QAAM,OAAY,aAAQ,cAAc,YAAY,GAAG,CAAC;AACxD,QAAM,aAAa;AAAA,IACZ,aAAQ,MAAM,oBAAoB;AAAA,IAClC,aAAQ,MAAM,iBAAiB;AAAA,IAC/B,aAAQ,MAAM,cAAc;AAAA,EACnC;AACA,mBAAiB,WAAW,KAAK,CAAC,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC,IAAI,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;AAC5F,SAAO;AACT;AAEA,SAAS,YAAY,WAA4B;AAC/C,MAAI;AACF,WAAO,SAAS,SAAS,EAAE,YAAY;AAAA,EACzC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;
|
|
4
|
+
"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` \u2014 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` \u2014 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` \u2014 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 \u2014 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}\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 { readFileSync, statSync } from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Cache of resolved instruction text, keyed by the relative path. Bundled\n * instruction files are immutable for the process lifetime, so re-reading them\n * on every call (some callers do so per LLM request) is wasted disk I/O.\n */\nconst textCache = new Map<string, string>();\n\n/** Resolved once \u2014 the candidate roots only depend on this module's location. */\nlet rootCandidates: string[] | undefined;\n\nexport function readBundledInstructionText(relativePath: string): string {\n const cached = textCache.get(relativePath);\n if (cached !== undefined) return cached;\n\n let resolved = '';\n for (const root of instructionRootCandidates()) {\n try {\n resolved = readFileSync(path.join(root, relativePath), 'utf8').trimEnd();\n break;\n } catch {\n // try next candidate\n }\n }\n textCache.set(relativePath, resolved);\n return resolved;\n}\n\nexport function renderInstructionTemplate(\n template: string,\n values: Record<string, string>,\n): string {\n return template.replace(/\\{\\{\\s*([a-zA-Z0-9_.-]+)\\s*\\}\\}/g, (match, key: string) =>\n Object.hasOwn(values, key) ? (values[key] ?? '') : match,\n );\n}\n\nfunction instructionRootCandidates(): string[] {\n if (rootCandidates !== undefined) return rootCandidates;\n const here = path.dirname(fileURLToPath(import.meta.url));\n const candidates = [\n path.resolve(here, '../../instructions'),\n path.resolve(here, '../instructions'),\n path.resolve(here, 'instructions'),\n ];\n rootCandidates = candidates.sort((a, b) => Number(!isDirectory(a)) - Number(!isDirectory(b)));\n return rootCandidates;\n}\n\nfunction isDirectory(candidate: string): boolean {\n try {\n return statSync(candidate).isDirectory();\n } catch {\n return false;\n }\n}\n", "import type { ContentBlock } from '../types/blocks.js';\nimport { isTextBlock } from '../types/blocks.js';\nimport type { Message } from '../types/messages.js';\nimport type {\n Provider,\n ReasoningConfig,\n ReasoningEffort,\n ReasoningRequest,\n Request,\n} from '../types/provider.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport type { OneShotOrchestrator } from './one-shot-llm.js';\nimport { readBundledInstructionText } from '../utils/instruction-file.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` \u2014 a plain\n * `provider.complete()` with a dedicated system prompt \u2014 and is deliberately\n * free of React / TUI dependencies so it can be unit-tested in isolation.\n */\n\nexport const ENHANCER_SYSTEM_PROMPT = readBundledInstructionText('llm/prompt-enhancer.md');\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\u20132 words rarely benefit\n return true;\n}\n\n/**\n * Preference order when picking an effort level: the cheapest level that still\n * does SOME reasoning first ('low', then 'minimal'), then up the ladder, with\n * fully-off ('none') last so it's only chosen when it's the sole advertised\n * option. This keeps the refiner cheap without dropping reasoning entirely when\n * a little still helps. 'low' leads because it's the most widely accepted low\n * level across adapters (e.g. OpenAI's reasoning_effort set).\n */\nconst EFFORT_PREFERENCE: ReasoningEffort[] = [\n 'low',\n 'minimal',\n 'medium',\n 'high',\n 'xhigh',\n 'max',\n 'none',\n];\n\n/**\n * Build a reasoning directive for the refiner that minimizes wasted thinking,\n * gated to what the model actually accepts. Refinement is a shallow rewrite\n * task \u2014 extended thinking adds latency and (hidden) token cost for little\n * gain \u2014 so we ask the model to spend as little reasoning as it safely can.\n *\n * The gating mirrors `resolveReasoningForRequest` so we never send a field the\n * model would reject:\n * - effort-capable model \u2192 its lowest advertised effort level;\n * - else disable-capable model \u2192 disable thinking (`enabled: false`);\n * - else (always-on / unknown) \u2192 `undefined` (leave the provider default).\n *\n * Returns `undefined` whenever nothing can be safely reduced. Callers forward\n * that verbatim to `enhanceUserPrompt`, which then sends no reasoning field \u2014\n * identical to the behavior before this hint existed. Pure + exported for unit\n * testing.\n */\nexport function gatedEnhancerReasoning(\n rc: ReasoningConfig | undefined,\n): ReasoningRequest | undefined {\n // Capabilities unknown \u2192 don't risk an unsupported field (matches the\n // conservative \"capabilities unknown\" branch in resolveReasoningForRequest).\n if (!rc) return undefined;\n if (rc.effortSupported && rc.effortLevels.length > 0) {\n const lowest = EFFORT_PREFERENCE.find((e) => rc.effortLevels.includes(e)) ?? rc.effortLevels[0];\n if (lowest) return { effort: lowest };\n }\n if (rc.disableSupported) return { enabled: false };\n return undefined;\n}\n\n/**\n * Normalize for \"did the refiner actually change anything?\" comparison \u2014\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. Carries the original-language and\n * English versions so the UI can offer both. When the input was already in\n * English the refiner emits a single version and both fields hold the same\n * text (the UI then offers two identical choices, which is correct).\n */\nexport interface EnhanceResult {\n /** Refined in the user's original language. */\n refined: string;\n /** Refined in English. Equals `refined` when the input was already English. */\n english: string;\n}\n\n/**\n * Why a refine attempt fell through. Callers use this to decide the recovery\n * path: `timeout` is a transient capacity/latency failure worth an automatic\n * retry with a longer window (the model was reachable, just slow); `empty` and\n * `provider_error` mean the attempt produced nothing useful, so the caller\n * should surface the recovery options (retry, switch model, send as-is) rather\n * than silently retry. User-initiated cancellation is NOT reported here (it\n * returns `null` with no `onError` call).\n */\nexport type EnhanceFailureKind = 'timeout' | 'empty' | 'provider_error';\n\nexport interface EnhanceUserPromptOptions {\n provider: Provider;\n model: string;\n text: string;\n /**\n * Recent conversation turns (oldest\u2192newest), 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 * Reasoning directive for the refiner call. Refinement is a shallow\n * restate-this-more-clearly task that does not benefit from extended\n * thinking, so callers pass a low-effort / thinking-disabled hint here to\n * cut latency and (hidden) reasoning-token cost \u2014 most impactful on slow\n * reasoning models. Build it with `gatedEnhancerReasoning(rc)` so the field\n * is gated to what the model accepts. Omit (undefined) to send no reasoning\n * directive at all (the provider's own default applies).\n */\n reasoning?: ReasoningRequest | undefined;\n /**\n * Called with a short reason and a machine-readable `kind` when refinement\n * fails (provider error, timeout, empty response). NOT called when the caller\n * cancels via `signal`. The `kind` lets the UI drive recovery: `timeout` is\n * eligible for an automatic longer-window retry; `empty` / `provider_error`\n * surface the recovery options instead. The second argument is optional so\n * existing callers that only read the reason keep compiling.\n */\n onError?: ((reason: string, kind?: EnhanceFailureKind) => void) | undefined;\n /**\n * OneShotOrchestrator for the refiner LLM call. When set, uses it instead\n * of direct provider.complete(), gaining fallback chain support.\n */\n oneShotOrchestrator?: OneShotOrchestrator | 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 \u2014 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 \u2014 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 (\u2192 empty completion \u2192 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, \u2026) return HTTP 400 when\n // `temperature` is present \u2014 which would make every refine call fail and\n // silently fall back to the original (no panel shown).\n //\n // A reasoning hint is forwarded ONLY when the caller supplies one (it must\n // already be gated to the model's advertised support \u2014 see\n // `gatedEnhancerReasoning`). Absent it, no reasoning field is sent, which\n // is identical to the original behavior.\n ...(opts.reasoning ? { reasoning: opts.reasoning } : {}),\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 ? AbortSignal.any([opts.signal, timer.signal]) : timer.signal;\n\n try {\n let raw: string;\n if (opts.oneShotOrchestrator) {\n const result = await opts.oneShotOrchestrator.call({\n system: ENHANCER_SYSTEM_PROMPT,\n messages: [\n { role: 'user', content: buildRefinerInput(text, opts.history) },\n ],\n maxTokens,\n timeoutMs,\n signal: opts.signal,\n });\n if (result.error) {\n opts.onError?.(result.error, 'provider_error');\n return null;\n }\n raw = result.text;\n } else {\n const res = await provider.complete(req, { signal });\n raw = res.content\n .filter(isTextBlock)\n .map((b) => b.text)\n .join('\\n')\n .trim();\n }\n if (!raw) {\n opts.onError?.('model returned no text', 'empty');\n return null;\n }\n\n // English input \u2192 ONE version (no \"---\"); other languages \u2192 two versions\n // separated by a line with only \"---\". Split on the first occurrence so the\n // delimiter can still appear inside the second version's text.\n const sepIdx = raw.indexOf('\\n---\\n');\n if (sepIdx === -1) {\n // Single version: the input was already English (or the model chose not\n // to translate). Use it for both fields \u2014 the UI offers identical\n // \"refined\" / \"english\" options, which is correct and saves the model\n // from generating a redundant second copy. NOT an error.\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', 'empty');\n return null;\n }\n return { refined, english };\n } catch (err) {\n // User-initiated cancel \u2192 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`, 'timeout');\n return null;\n }\n opts.onError?.(toErrorMessage(err), 'provider_error');\n return null;\n } finally {\n // Idempotent \u2014 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)}\u2026` : text,\n });\n }\n return turns;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -10,17 +10,17 @@ export interface SelectiveCompactorOptions {
|
|
|
10
10
|
provider: Provider;
|
|
11
11
|
/** Selector for LLM-driven importance analysis. */
|
|
12
12
|
selector?: MessageSelector | undefined;
|
|
13
|
-
/** Fraction of maxContext that triggers a warning (default 0.
|
|
13
|
+
/** Fraction of maxContext that triggers a warning (default 0.5). */
|
|
14
14
|
warnThreshold?: number | undefined;
|
|
15
|
-
/** Fraction of maxContext that triggers soft compaction (default 0.
|
|
15
|
+
/** Fraction of maxContext that triggers soft compaction (default 0.65). */
|
|
16
16
|
softThreshold?: number | undefined;
|
|
17
|
-
/** Fraction of maxContext that triggers hard compaction (default 0.
|
|
17
|
+
/** Fraction of maxContext that triggers hard compaction (default 0.8). */
|
|
18
18
|
hardThreshold?: number | undefined;
|
|
19
19
|
/** Max context window in tokens (used for threshold fraction math). */
|
|
20
20
|
maxContext?: number | undefined;
|
|
21
21
|
/** How many recent (user+assistant) pairs to always preserve (default 4). */
|
|
22
22
|
preserveK?: number | undefined;
|
|
23
|
-
/** Token threshold below which tool results are not elided (default
|
|
23
|
+
/** Token threshold below which tool results are not elided (default 300). */
|
|
24
24
|
eliseThreshold?: number | undefined;
|
|
25
25
|
/** Model for selector LLM calls (default: same as provider default). */
|
|
26
26
|
selectorModel?: string | undefined;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Compactor } from '../types/compactor.js';
|
|
2
|
+
import type { OneShotOrchestrator } from './one-shot-llm.js';
|
|
2
3
|
export type CompactorStrategy = 'hybrid' | 'intelligent' | 'selective';
|
|
3
4
|
export interface StrategyCompactorOptions {
|
|
4
5
|
/** Which compactor to use. Defaults to 'hybrid' (lossless, no LLM). */
|
|
@@ -25,6 +26,12 @@ export interface StrategyCompactorOptions {
|
|
|
25
26
|
* An explicit `strategy` always wins.
|
|
26
27
|
*/
|
|
27
28
|
llmSelector?: boolean | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* OneShotOrchestrator for LLM-backed compaction summarization. When set,
|
|
31
|
+
* the intelligent/selective compactor uses it instead of direct provider
|
|
32
|
+
* calls, gaining fallback chain support and a cheap default model.
|
|
33
|
+
*/
|
|
34
|
+
oneShotOrchestrator?: OneShotOrchestrator | undefined;
|
|
28
35
|
}
|
|
29
36
|
/**
|
|
30
37
|
* Build the compactor named by `config.context.strategy`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strategy-compactor.d.ts","sourceRoot":"","sources":["../../src/execution/strategy-compactor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"strategy-compactor.d.ts","sourceRoot":"","sources":["../../src/execution/strategy-compactor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAMtE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAG7D,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,aAAa,GAAG,WAAW,CAAC;AAEvE,MAAM,WAAW,wBAAwB;IACvC,uEAAuE;IACvE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,MAAM,GAAG,SAAS,CAAC;IAClD,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,+DAA+D;IAC/D,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,2EAA2E;IAC3E,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,2FAA2F;IAC3F,uBAAuB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAClC;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC;CACvD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,GAAE,wBAA6B,GAAG,SAAS,CActF"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Context } from '../core/context.js';
|
|
2
2
|
import type { ToolResultBlock, ToolUseBlock } from '../types/blocks.js';
|
|
3
3
|
import type { Tool, ToolErrorCategory } from '../types/tool.js';
|
|
4
|
-
import type
|
|
4
|
+
import { type ToolBatchResult, type ToolExecutorOptions, type ToolExecutorStrategy } from '../types/tool-executor.js';
|
|
5
5
|
export declare class ToolExecutor {
|
|
6
6
|
private readonly registry;
|
|
7
7
|
private opts;
|
|
@@ -47,10 +47,24 @@ export declare class ToolExecutor {
|
|
|
47
47
|
*/
|
|
48
48
|
executeBatch(toolUses: ToolUseBlock[], ctx: Context, strategy: ToolExecutorStrategy): Promise<ToolBatchResult>;
|
|
49
49
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
50
|
+
* Internal batch implementation. Nested meta-tool calls enter here through
|
|
51
|
+
* the governed bridge so they traverse the same validation, hooks,
|
|
52
|
+
* permission/capability, timeout, scrubbing, and audit path without
|
|
53
|
+
* replacing the bridge that is already active for the outer call.
|
|
54
|
+
*/
|
|
55
|
+
private executeBatchInternal;
|
|
56
|
+
/**
|
|
57
|
+
* Install the executor-owned bridge used by meta-tools for nested calls.
|
|
58
|
+
* The bridge deliberately returns the governed, scrubbed ToolResultBlock
|
|
59
|
+
* content rather than the raw tool value. This prevents a meta-tool from
|
|
60
|
+
* bypassing output controls while preserving structured success/failure.
|
|
61
|
+
*/
|
|
62
|
+
private withGovernedExecutionBridge;
|
|
63
|
+
/**
|
|
64
|
+
* Execute a single tool with timeout and output capping after its permission
|
|
65
|
+
* decision has already been resolved by executeBatch/the confirmation flow.
|
|
66
|
+
* Also installs the governed bridge because confirmed tools are re-run
|
|
67
|
+
* through this method after a pending confirmation.
|
|
54
68
|
*/
|
|
55
69
|
executeTool(tool: Tool, use: ToolUseBlock, ctx: Context, budget: number): Promise<{
|
|
56
70
|
block: ToolResultBlock;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-executor.d.ts","sourceRoot":"","sources":["../../src/execution/tool-executor.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAKlD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"tool-executor.d.ts","sourceRoot":"","sources":["../../src/execution/tool-executor.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAKlD,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,KAAK,EAAE,IAAI,EAAqB,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEnF,OAAO,EAGL,KAAK,eAAe,EAGpB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EAC1B,MAAM,2BAA2B,CAAC;AAYnC,qBAAa,YAAY;IAarB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,IAAI;IAbd,0EAA0E;IAC1E,MAAM,CAAC,QAAQ,CAAC,yBAAyB,OAAO;IAChD,8EAA8E;IAC9E,MAAM,CAAC,QAAQ,CAAC,mBAAmB,SAAU;IAC7C,2EAA2E;IAC3E,MAAM,CAAC,QAAQ,CAAC,mBAAmB,SAAU;IAE7C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;IAC5B,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAE1C,YACmB,QAAQ,EAAE;QAAE,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;QAAC,IAAI,IAAI,IAAI,EAAE,CAAA;KAAE,EAC1E,IAAI,EAAE,mBAAmB,EAOlC;IAED;;;;;OAKG;IACH,mBAAmB,IAAI,IAAI,CAE1B;IAED;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,WAAW;IAiBnB,OAAO,CAAC,cAAc;IAwBtB,OAAO,CAAC,cAAc;IAuCtB;;;OAGG;IACG,YAAY,CAChB,QAAQ,EAAE,YAAY,EAAE,EACxB,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,oBAAoB,GAC7B,OAAO,CAAC,eAAe,CAAC,CAK1B;IAED;;;;;OAKG;YACW,oBAAoB;IA8alC;;;;;OAKG;YACW,2BAA2B;IAqCzC;;;;;OAKG;IACG,WAAW,CACf,IAAI,EAAE,IAAI,EACV,GAAG,EAAE,YAAY,EACjB,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;QAAE,KAAK,EAAE,eAAe,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAKpD;IAED;;;;;;;;;;OAUG;YACW,iBAAiB;IAmB/B;;;;;;;;;OASG;IACH,OAAO,CAAC,gBAAgB;YA4BV,cAAc;IAsF5B,sEAAsE;YACxD,cAAc;YASd,eAAe;IA0H7B,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,oBAAoB;IA2B5B,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,mBAAmB;IAS3B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,eAAe;CAIxB;AAiED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG;IAAE,QAAQ,EAAE,iBAAiB,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAqFpH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/hooks/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EACT,SAAS,EACT,WAAW,EACX,uBAAuB,EACvB,QAAQ,EACR,aAAa,EACb,SAAS,EACV,MAAM,mBAAmB,CAAC;AAE3B,UAAU,0BAA0B;IAClC,qEAAqE;IACrE,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAClC;
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/hooks/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EACT,SAAS,EACT,WAAW,EACX,uBAAuB,EACvB,QAAQ,EACR,aAAa,EACb,SAAS,EACV,MAAM,mBAAmB,CAAC;AAE3B,UAAU,0BAA0B;IAClC,qEAAqE;IACrE,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAClC;AAqBD;;;;;GAKG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAE3C,oEAAoE;IACpE,iBAAiB,CACf,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,WAAW,GAAG,SAAS,EAChC,IAAI,EAAE,aAAa,EACnB,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,GAAE,uBAA4B,GACpC,MAAM,IAAI,CAgBZ;IAED;;;OAGG;IACH,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,IAAI,CAU3D;IAED,mCAAmC;IACnC,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,IAAI,CAWzD;IAED,8DAA8D;IAC9D,cAAc,CACZ,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,cAAc,EAAE,CAAC,CAAC,GAAG,SAAS,EAC/D,OAAO,GAAE,0BAA+B,GACvC,IAAI,CAeN;IAED;;;;;;;;;;;;OAYG;IACH,iBAAiB,CACf,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,cAAc,EAAE,CAAC,CAAC,GAAG,SAAS,EAC/D,OAAO,GAAE,0BAA+B,GACvC,IAAI,CAcN;IAED,kEAAkE;IAClE,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,SAAS,EAAE,CAE3C;IAED,uDAAuD;IACvD,GAAG,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAE7B;IAED,4DAA4D;IAC5D,GAAG,IAAI,SAAS,SAAS,EAAE,CAE1B;IAED;;;;;;;;;;;OAWG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUlC;IAED,iEAAiE;IACjE,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMlC;IAED,6DAA6D;IAC7D,KAAK,IAAI,IAAI,CAEZ;IAED,OAAO,CAAC,MAAM;CAIf;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAS9F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/hooks/runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,SAAS,EAGV,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAGjD,OAAO,EAAE,KAAK,YAAY,EAAsB,MAAM,eAAe,CAAC;AAUtE,+EAA+E;AAC/E,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,YAAY,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,wEAAwE;IACxE,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,kEAAkE;IAClE,SAAS,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,SAAS,CAAC;CACxC;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAsCD,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACxC;AAED;;;;;GAKG;AACH,qBAAa,UAAU;IAGT,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IAExC,YAA6B,IAAI,EAAE,iBAAiB,EAEnD;IAED,8EAA8E;IAC9E,GAAG,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAE7B;IAEK,UAAU,CACd,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,gBAAgB,CAAC,CAmD3B;IAEK,WAAW,CACf,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,OAAO,EAClB,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,EAC7C,GAAG,EAAE,UAAU,GACd,OAAO,CAAC;QAAE,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,SAAS,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAA;KAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/hooks/runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,SAAS,EAGV,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAGjD,OAAO,EAAE,KAAK,YAAY,EAAsB,MAAM,eAAe,CAAC;AAUtE,+EAA+E;AAC/E,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,YAAY,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,wEAAwE;IACxE,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,kEAAkE;IAClE,SAAS,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,SAAS,CAAC;CACxC;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAsCD,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACxC;AAED;;;;;GAKG;AACH,qBAAa,UAAU;IAGT,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IAExC,YAA6B,IAAI,EAAE,iBAAiB,EAEnD;IAED,8EAA8E;IAC9E,GAAG,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAE7B;IAEK,UAAU,CACd,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,gBAAgB,CAAC,CAmD3B;IAEK,WAAW,CACf,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,OAAO,EAClB,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,EAC7C,GAAG,EAAE,UAAU,GACd,OAAO,CAAC;QAAE,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,SAAS,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAA;KAAE,CAAC,CAyCxF;IAEK,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAgB7E;IAEK,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC;QAAE,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC,CAKvF;IAEK,IAAI,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAGzC;IAID,OAAO,CAAC,IAAI;IAKZ,OAAO,CAAC,QAAQ;YAIF,MAAM;YA4CN,eAAe;IAyD7B,OAAO,CAAC,cAAc;YAcR,cAAc;CAqB7B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell-executor.d.ts","sourceRoot":"","sources":["../../src/hooks/shell-executor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"shell-executor.d.ts","sourceRoot":"","sources":["../../src/hooks/shell-executor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AA+GjD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED,MAAM,MAAM,wBAAwB,GAChC,SAAS,GACT,OAAO,GACP,MAAM,GACN,gBAAgB,GAChB,UAAU,GACV,SAAS,CAAC;AAEd,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,wBAAwB,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IAC/B,OAAO,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;CAC5C;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CAClC;AAiCD;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,aAAa,EACnB,KAAK,EAAE,SAAS,EAChB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,GAC1B,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAY7B;AAED,6EAA6E;AAC7E,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,aAAa,EACnB,KAAK,EAAE,SAAS,EAChB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,mBAAmB,CAAC,CA2H9B;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAmDtE"}
|
package/dist/hq/alerts.d.ts
CHANGED
|
@@ -42,9 +42,12 @@ export declare class HqAlertEngine {
|
|
|
42
42
|
private readonly maxHistory;
|
|
43
43
|
private timer;
|
|
44
44
|
private readonly onAlert;
|
|
45
|
+
private readonly onPersist?;
|
|
45
46
|
constructor(opts: {
|
|
46
47
|
onAlert: (alert: HqAlert) => void;
|
|
47
48
|
maxHistory?: number;
|
|
49
|
+
/** Optional durable sink — fires when an alert transitions to firing. */
|
|
50
|
+
onPersist?: ((alert: HqAlert) => void) | undefined;
|
|
48
51
|
});
|
|
49
52
|
/**
|
|
50
53
|
* Evaluate all rules against the snapshot. Emits (via the `onAlert`
|
|
@@ -56,6 +59,8 @@ export declare class HqAlertEngine {
|
|
|
56
59
|
activeAlerts(): HqAlert[];
|
|
57
60
|
/** Historical alerts (newest-last), capped at maxHistory. */
|
|
58
61
|
recentAlerts(limit?: number): HqAlert[];
|
|
62
|
+
/** Seed the history from a durable store on boot (no alert callbacks fired). */
|
|
63
|
+
seed(alerts: readonly HqAlert[]): void;
|
|
59
64
|
/**
|
|
60
65
|
* Start periodic evaluation against a snapshot getter. The timer is
|
|
61
66
|
* unref'd so it never keeps the process alive. Returns a disposer.
|
package/dist/hq/alerts.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alerts.d.ts","sourceRoot":"","sources":["../../src/hq/alerts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhE,oEAAoE;AACpE,MAAM,MAAM,eAAe,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;AAEzD,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,eAAe,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,YAAY,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oFAAoF;IACpF,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,6FAA6F;IAC7F,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA8ED;;;;GAIG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA8B;IACrD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;
|
|
1
|
+
{"version":3,"file":"alerts.d.ts","sourceRoot":"","sources":["../../src/hq/alerts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhE,oEAAoE;AACpE,MAAM,MAAM,eAAe,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;AAEzD,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,eAAe,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,YAAY,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oFAAoF;IACpF,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,6FAA6F;IAC7F,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA8ED;;;;GAIG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA8B;IACrD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IACnD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAyC;IAEpE,YAAY,IAAI,EAAE;QAChB,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;QAClC,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,yEAAyE;QACzE,SAAS,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;KACpD,EAIA;IAED;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,UAAU,GAAG,IAAI,EAAE,MAAM,CAAC,EAAE,iBAAiB,EAAE,GAAG,GAAE,MAAmB,GAAG,OAAO,EAAE,CAyCrG;IAED,wCAAwC;IACxC,YAAY,IAAI,OAAO,EAAE,CAExB;IAED,6DAA6D;IAC7D,YAAY,CAAC,KAAK,SAAM,GAAG,OAAO,EAAE,CAEnC;IAED,gFAAgF;IAChF,IAAI,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,GAAG,IAAI,CAOrC;IAED;;;OAGG;IACH,aAAa,CACX,WAAW,EAAE,MAAM,UAAU,GAAG,IAAI,EACpC,MAAM,CAAC,EAAE,iBAAiB,GAAG,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAC,EAClE,UAAU,SAAS,GAClB,MAAM,IAAI,CAkBZ;CACF;AAED,0EAA0E;AAC1E,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAO7D"}
|
package/dist/hq/auth-store.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { HqAlertRuleConfig } from './alerts.js';
|
|
1
2
|
import type { HqRedactionPolicy } from './protocol.js';
|
|
2
3
|
/** Current auth-file schema version. Bump on breaking shape changes. */
|
|
3
4
|
export declare const HQ_AUTH_FILE_VERSION: 1;
|
|
@@ -76,6 +77,12 @@ export interface HqAuthFile {
|
|
|
76
77
|
passwordHash?: string;
|
|
77
78
|
/** Secret used to sign browser session cookies. */
|
|
78
79
|
cookieSecret?: string;
|
|
80
|
+
/**
|
|
81
|
+
* Operator-configured alert-rule thresholds. When present, these override
|
|
82
|
+
* the built-in defaults for the alert engine (cost ceiling, stale-machine
|
|
83
|
+
* window, concurrency limit). Live-reloaded with the rest of the file.
|
|
84
|
+
*/
|
|
85
|
+
alertRules?: HqAlertRuleConfig;
|
|
79
86
|
}
|
|
80
87
|
/** An empty auth file — what a brand-new HQ install starts with. */
|
|
81
88
|
export declare function emptyHqAuthFile(): HqAuthFile;
|
|
@@ -86,15 +93,18 @@ export declare function hqRuntimeFilePath(dataDir: string): string;
|
|
|
86
93
|
export declare function writeHqRuntimeFile(dataDir: string, file: Omit<HqRuntimeFile, 'updatedAt'>): Promise<void>;
|
|
87
94
|
export declare function readHqRuntimeFileSync(dataDir: string): HqRuntimeFile | undefined;
|
|
88
95
|
/**
|
|
89
|
-
* Read `auth.json` from disk. Returns `emptyHqAuthFile()` when
|
|
90
|
-
*
|
|
91
|
-
*
|
|
96
|
+
* Read `auth.json` from disk. Returns `emptyHqAuthFile()` when the file does
|
|
97
|
+
* NOT exist (ENOENT) — the only case treated as intentional open mode.
|
|
98
|
+
*
|
|
99
|
+
* Throws for all other read failures (EACCES, EIO, etc.), malformed JSON,
|
|
100
|
+
* and unsupported schema versions. A corrupt or unreadable auth file must
|
|
101
|
+
* never silently open the server.
|
|
92
102
|
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
103
|
+
* Callers that want to handle errors gracefully (e.g. the live-reload
|
|
104
|
+
* watcher which should preserve the last-known-good state) should catch
|
|
105
|
+
* the thrown error.
|
|
96
106
|
*/
|
|
97
|
-
export declare function readHqAuthFile(dataDir: string,
|
|
107
|
+
export declare function readHqAuthFile(dataDir: string, _opts?: {
|
|
98
108
|
warn?: (msg: string) => void;
|
|
99
109
|
}): Promise<HqAuthFile>;
|
|
100
110
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-store.d.ts","sourceRoot":"","sources":["../../src/hq/auth-store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth-store.d.ts","sourceRoot":"","sources":["../../src/hq/auth-store.ts"],"names":[],"mappings":"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"}
|