@cuongtran001/kanna 1.3.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/assets/{arc-CAysfmX5.js → arc-DXtN3EWJ.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-BKqRYsm4.js → architectureDiagram-3BPJPVTR-CIGqW1z-.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-Ce7Eorec.js → blockDiagram-GPEHLZMM-BafNS_H6.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-CJ77zauH.js → c4Diagram-AAUBKEIU-YdAgRSis.js} +1 -1
- package/dist/client/assets/channel-BEYTrUAm.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-Rk_3zLxJ.js → chunk-2J33WTMH-eiP5y5G-.js} +1 -1
- package/dist/client/assets/{chunk-4BX2VUAB-DPIz6Nvf.js → chunk-4BX2VUAB-CvLGzPMF.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-D-TkbGh2.js → chunk-55IACEB6-Y-S9Fb8A.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-B4NOSIZV.js → chunk-727SXJPM-6sJH1RI9.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-Cm_TGLYm.js → chunk-AQP2D5EJ-hV1r_IXO.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-Bu45BUVh.js → chunk-FMBD7UC4-CC3L28S5.js} +1 -1
- package/dist/client/assets/{chunk-ND2GUHAM-C1Bw8_gg.js → chunk-ND2GUHAM-BZ3czhdH.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-DueG15o0.js → chunk-QZHKN3VN-Bjyd6Yr-.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-CvnF5Ud6.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-CvnF5Ud6.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-YgpMurXf.js → cose-bilkent-S5V4N54A-CfxdDghE.js} +1 -1
- package/dist/client/assets/{dagre-BM42HDAG-Dop7Oq67.js → dagre-BM42HDAG-B8CddsbB.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-unMfBEJH.js → diagram-2AECGRRQ-F0yS0fVB.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-D9EJ9qMI.js → diagram-5GNKFQAL-cW0i0qlh.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-C5IykOIR.js → diagram-KO2AKTUF-BzAKMeJT.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-DJAuPngz.js → diagram-LMA3HP47-qdC4XqIl.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-B3wHFtS-.js → diagram-OG6HWLK6-CGcpi6Dh.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-Dm7kt9o5.js → erDiagram-TEJ5UH35-CxNTDicM.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-s9Lds3ny.js → flowDiagram-I6XJVG4X-qkGa5TqY.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-CRQNYdAf.js → ganttDiagram-6RSMTGT7-D9mVPoQi.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-DhYjK4Jb.js → gitGraphDiagram-PVQCEYII-DA0grAXe.js} +1 -1
- package/dist/client/assets/{index-CbSY9HfS.js → index-BqUY1Bm4.js} +1 -1
- package/dist/client/assets/{index-C0U2kwuB.js → index-TU1k6ov6.js} +5 -5
- package/dist/client/assets/{infoDiagram-5YYISTIA-CRKJ0PSH.js → infoDiagram-5YYISTIA-CGljtLs3.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-CEAkB0IY.js → ishikawaDiagram-YF4QCWOH-CtC0xrmG.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-CyOK5_DG.js → journeyDiagram-JHISSGLW-URLnVZeN.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-BfKjiJSo.js → kanban-definition-UN3LZRKU-C2Q6aqQh.js} +1 -1
- package/dist/client/assets/{linear-DLR6miy3.js → linear-ByKHtsIx.js} +1 -1
- package/dist/client/assets/{mermaid.core-D7AdC_lE.js → mermaid.core-Dl_f2KLc.js} +4 -4
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-zYyJtDSa.js → mindmap-definition-RKZ34NQL-CaJ9IDLI.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-BgP8PFlo.js → pieDiagram-4H26LBE5-mmYaf2Oa.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-Di8h7J96.js → quadrantDiagram-W4KKPZXB-B_PO6OCC.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-DuTzFl3R.js → requirementDiagram-4Y6WPE33-M4huwJt1.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-DBRoMm_T.js → sankeyDiagram-5OEKKPKP-B0hb1sWh.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-Bmb-1HUN.js → sequenceDiagram-3UESZ5HK-BAqSptnA.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-fnv5ayn-.js → stateDiagram-AJRCARHV-DTNkvPi5.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-CVN3oGTF.js +1 -0
- package/dist/client/assets/{timeline-definition-PNZ67QCA-ByWRdpQX.js → timeline-definition-PNZ67QCA-MgAjHz8Q.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN--2WGpVXW.js → vennDiagram-CIIHVFJN-DmKoO51W.js} +1 -1
- package/dist/client/assets/{wardley-L42UT6IY-24zlnzxK.js → wardley-L42UT6IY-CWcyHnYs.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-Cllvqb3K.js → wardleyDiagram-YWT4CUSO-BGIGmFP9.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-ZcdC6nPE.js → xychartDiagram-2RQKCTM6-D20YIvEl.js} +1 -1
- package/dist/client/index.html +1 -1
- package/package.json +1 -1
- package/src/server/agent-coordinator-types.ts +158 -0
- package/src/server/agent-coordinator.ts +919 -0
- package/src/server/agent-deps-builders.ts +425 -0
- package/src/server/agent.test.ts +22 -6
- package/src/server/agent.ts +35 -4987
- package/src/server/claude-autocontinue-commands.test.ts +494 -0
- package/src/server/claude-autocontinue-commands.ts +256 -0
- package/src/server/claude-cancel-handler.test.ts +472 -0
- package/src/server/claude-cancel-handler.ts +241 -0
- package/src/server/claude-chat-management.test.ts +395 -0
- package/src/server/claude-chat-management.ts +251 -0
- package/src/server/claude-harness-stream.test.ts +273 -0
- package/src/server/claude-harness-stream.ts +158 -0
- package/src/server/claude-loop-orch-commands.test.ts +579 -0
- package/src/server/claude-loop-orch-commands.ts +466 -0
- package/src/server/claude-message-normalizer.test.ts +213 -0
- package/src/server/claude-message-normalizer.ts +436 -0
- package/src/server/claude-prompt-helpers.test.ts +248 -0
- package/src/server/claude-prompt-helpers.ts +139 -0
- package/src/server/claude-sdk-queue.test.ts +169 -0
- package/src/server/claude-sdk-queue.ts +82 -0
- package/src/server/claude-send-command.test.ts +414 -0
- package/src/server/claude-send-command.ts +420 -0
- package/src/server/claude-session-config-helpers.test.ts +279 -0
- package/src/server/claude-session-config-helpers.ts +151 -0
- package/src/server/claude-session-config.test.ts +250 -0
- package/src/server/claude-session-config.ts +159 -0
- package/src/server/claude-session-error-handler.test.ts +498 -0
- package/src/server/claude-session-error-handler.ts +361 -0
- package/src/server/claude-session-lifecycle.test.ts +669 -0
- package/src/server/claude-session-lifecycle.ts +283 -0
- package/src/server/claude-session-rebuild.test.ts +224 -0
- package/src/server/claude-session-rebuild.ts +101 -0
- package/src/server/claude-session-runner.test.ts +523 -0
- package/src/server/claude-session-runner.ts +521 -0
- package/src/server/claude-session-spawner.test.ts +401 -0
- package/src/server/claude-session-spawner.ts +401 -0
- package/src/server/claude-session-start.test.ts +205 -0
- package/src/server/claude-session-start.ts +277 -0
- package/src/server/claude-session-state-queries.test.ts +344 -0
- package/src/server/claude-session-state-queries.ts +160 -0
- package/src/server/claude-session-state.ts +104 -0
- package/src/server/claude-slash-commands.test.ts +277 -0
- package/src/server/claude-slash-commands.ts +234 -0
- package/src/server/claude-spawn-helpers.test.ts +221 -0
- package/src/server/claude-spawn-helpers.ts +179 -0
- package/src/server/claude-steer-log.test.ts +243 -0
- package/src/server/claude-steer-log.ts +58 -0
- package/src/server/claude-subagent-tool-response.test.ts +213 -0
- package/src/server/claude-subagent-tool-response.ts +165 -0
- package/src/server/claude-subagent-wiring.test.ts +263 -0
- package/src/server/claude-subagent-wiring.ts +324 -0
- package/src/server/claude-tool-respond.test.ts +321 -0
- package/src/server/claude-tool-respond.ts +142 -0
- package/src/server/claude-turn-runner.test.ts +310 -0
- package/src/server/claude-turn-runner.ts +228 -0
- package/src/server/claude-turn-starter.test.ts +266 -0
- package/src/server/claude-turn-starter.ts +566 -0
- package/src/server/claude-usage-math.test.ts +169 -0
- package/src/server/claude-usage-math.ts +132 -0
- package/src/server/diff-store-branch-ops.adapter.test.ts +332 -0
- package/src/server/diff-store-branch-ops.adapter.ts +602 -0
- package/src/server/diff-store-commit-ops.adapter.test.ts +358 -0
- package/src/server/diff-store-commit-ops.adapter.ts +258 -0
- package/src/server/diff-store-errors.ts +85 -0
- package/src/server/diff-store-file-ops.adapter.ts +212 -0
- package/src/server/diff-store-git-branch.adapter.ts +686 -0
- package/src/server/diff-store-io.adapter.ts +27 -0
- package/src/server/diff-store-parse.test.ts +212 -0
- package/src/server/diff-store-parse.ts +122 -0
- package/src/server/diff-store-state.ts +82 -0
- package/src/server/diff-store.ts +76 -1854
- package/src/server/event-store-apply.test.ts +280 -0
- package/src/server/event-store-apply.ts +132 -0
- package/src/server/event-store-chat-lifecycle.test.ts +408 -0
- package/src/server/event-store-chat-lifecycle.ts +441 -0
- package/src/server/event-store-entity-write.ts +356 -0
- package/src/server/event-store-helpers.test.ts +230 -0
- package/src/server/event-store-helpers.ts +235 -0
- package/src/server/event-store-init.ts +276 -0
- package/src/server/event-store-messages.adapter.test.ts +365 -0
- package/src/server/event-store-messages.adapter.ts +213 -0
- package/src/server/event-store-orch-subscription.ts +124 -0
- package/src/server/event-store-orch.test.ts +462 -0
- package/src/server/event-store-orch.ts +312 -0
- package/src/server/event-store-peripheral-events.adapter.test.ts +254 -0
- package/src/server/event-store-peripheral-events.adapter.ts +105 -0
- package/src/server/event-store-snapshot.test.ts +597 -0
- package/src/server/event-store-snapshot.ts +658 -0
- package/src/server/event-store-subagent.test.ts +408 -0
- package/src/server/event-store-subagent.ts +198 -0
- package/src/server/event-store-tool-requests.test.ts +210 -0
- package/src/server/event-store-tool-requests.ts +131 -0
- package/src/server/event-store-transcript-write.adapter.ts +285 -0
- package/src/server/event-store-write-ops.test.ts +554 -0
- package/src/server/event-store-write-ops.ts +529 -0
- package/src/server/event-store.test.ts +35 -0
- package/src/server/event-store.ts +251 -2285
- package/src/server/harness-types.ts +15 -1
- package/src/server/oauth-errors.ts +19 -0
- package/src/server/ws-router-agent-ctrl.test.ts +187 -0
- package/src/server/ws-router-agent-ctrl.ts +137 -0
- package/src/server/ws-router-broadcast.ts +488 -0
- package/src/server/ws-router-chat.test.ts +461 -0
- package/src/server/ws-router-chat.ts +279 -0
- package/src/server/ws-router-defaults.test.ts +283 -0
- package/src/server/ws-router-defaults.ts +434 -0
- package/src/server/ws-router-diff.test.ts +167 -0
- package/src/server/ws-router-diff.ts +250 -0
- package/src/server/ws-router-envelope.ts +329 -0
- package/src/server/ws-router-misc.test.ts +422 -0
- package/src/server/ws-router-misc.ts +265 -0
- package/src/server/ws-router-orch.test.ts +190 -0
- package/src/server/ws-router-orch.ts +93 -0
- package/src/server/ws-router-project.test.ts +403 -0
- package/src/server/ws-router-project.ts +256 -0
- package/src/server/ws-router-push.test.ts +193 -0
- package/src/server/ws-router-push.ts +120 -0
- package/src/server/ws-router-settings.test.ts +173 -0
- package/src/server/ws-router-settings.ts +416 -0
- package/src/server/ws-router-skills.test.ts +194 -0
- package/src/server/ws-router-skills.ts +204 -0
- package/src/server/ws-router-utils.ts +224 -0
- package/src/server/ws-router.ts +339 -2254
- package/src/shared/app-settings-types.ts +365 -0
- package/src/shared/core-types.ts +27 -0
- package/src/shared/git-diff-types.ts +165 -0
- package/src/shared/mcp-types.ts +105 -0
- package/src/shared/provider-model-types.ts +437 -0
- package/src/shared/subagent-types.ts +198 -0
- package/src/shared/tool-call-types.ts +314 -0
- package/src/shared/transcript-types.ts +270 -0
- package/src/shared/types.ts +25 -1711
- package/dist/client/assets/channel-KQhRwDzJ.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-ChxT1GNq.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-ChxT1GNq.js +0 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-D4X-ZnLV.js +0 -1
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider and model catalog types — extracted from shared/types.ts.
|
|
3
|
+
* Imported via the re-export barrel in types.ts; all external consumers
|
|
4
|
+
* continue to import from "../shared/types" unchanged.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// AgentProvider lives in types.ts and is only needed as a type here.
|
|
8
|
+
// import type = erased at compile time → no circular runtime dependency.
|
|
9
|
+
import type { AgentProvider } from "./types"
|
|
10
|
+
|
|
11
|
+
export const DEFAULT_OPENROUTER_SDK_MODEL = "moonshotai/kimi-k2.5:nitro"
|
|
12
|
+
|
|
13
|
+
export const OPENROUTER_BASE_URL = "https://openrouter.ai/api"
|
|
14
|
+
export const OPENROUTER_MODELS_URL = "https://openrouter.ai/api/v1/models"
|
|
15
|
+
|
|
16
|
+
export interface OpenRouterModel {
|
|
17
|
+
id: string
|
|
18
|
+
label: string
|
|
19
|
+
contextLength: number
|
|
20
|
+
pricing?: { promptPerTok: number; completionPerTok: number }
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Provider model option primitives
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
|
|
27
|
+
export interface ProviderModelOption {
|
|
28
|
+
id: string
|
|
29
|
+
label: string
|
|
30
|
+
supportsEffort: boolean
|
|
31
|
+
aliases?: readonly string[]
|
|
32
|
+
contextWindowOptions?: readonly ProviderContextWindowOption[]
|
|
33
|
+
supportsMaxReasoningEffort?: boolean
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface ProviderEffortOption {
|
|
37
|
+
id: string
|
|
38
|
+
label: string
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface ProviderContextWindowOption {
|
|
42
|
+
id: ClaudeContextWindow
|
|
43
|
+
label: string
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const CLAUDE_REASONING_OPTIONS = [
|
|
47
|
+
{ id: "low", label: "Low" },
|
|
48
|
+
{ id: "medium", label: "Medium" },
|
|
49
|
+
{ id: "high", label: "High" },
|
|
50
|
+
{ id: "max", label: "Max" },
|
|
51
|
+
] as const satisfies readonly ProviderEffortOption[]
|
|
52
|
+
|
|
53
|
+
export const CODEX_REASONING_OPTIONS = [
|
|
54
|
+
{ id: "minimal", label: "Minimal" },
|
|
55
|
+
{ id: "low", label: "Low" },
|
|
56
|
+
{ id: "medium", label: "Medium" },
|
|
57
|
+
{ id: "high", label: "High" },
|
|
58
|
+
{ id: "xhigh", label: "XHigh" },
|
|
59
|
+
] as const satisfies readonly ProviderEffortOption[]
|
|
60
|
+
|
|
61
|
+
export type ClaudeReasoningEffort = (typeof CLAUDE_REASONING_OPTIONS)[number]["id"]
|
|
62
|
+
export type CodexReasoningEffort = (typeof CODEX_REASONING_OPTIONS)[number]["id"]
|
|
63
|
+
export type ClaudeContextWindow = "200k" | "1m"
|
|
64
|
+
export type ServiceTier = "fast"
|
|
65
|
+
|
|
66
|
+
export interface ClaudeModelOptions {
|
|
67
|
+
reasoningEffort: ClaudeReasoningEffort
|
|
68
|
+
contextWindow: ClaudeContextWindow
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface CodexModelOptions {
|
|
72
|
+
reasoningEffort: CodexReasoningEffort
|
|
73
|
+
fastMode: boolean
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export type OpenRouterModelOptions = Record<string, never>
|
|
77
|
+
|
|
78
|
+
export interface ProviderModelOptionsByProvider {
|
|
79
|
+
claude: ClaudeModelOptions
|
|
80
|
+
codex: CodexModelOptions
|
|
81
|
+
openrouter: OpenRouterModelOptions
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface ProviderPreference<TModelOptions> {
|
|
85
|
+
model: string
|
|
86
|
+
modelOptions: TModelOptions
|
|
87
|
+
planMode: boolean
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export type ChatProviderPreferences = {
|
|
91
|
+
claude: ProviderPreference<ClaudeModelOptions>
|
|
92
|
+
codex: ProviderPreference<CodexModelOptions>
|
|
93
|
+
openrouter: ProviderPreference<OpenRouterModelOptions>
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
// Model option defaults and type-guards
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
|
|
100
|
+
export type ModelOptions = Partial<{
|
|
101
|
+
[K in AgentProvider]: Partial<ProviderModelOptionsByProvider[K]>
|
|
102
|
+
}>
|
|
103
|
+
|
|
104
|
+
export const DEFAULT_CLAUDE_MODEL_OPTIONS = {
|
|
105
|
+
reasoningEffort: "high",
|
|
106
|
+
contextWindow: "200k",
|
|
107
|
+
} as const satisfies ClaudeModelOptions
|
|
108
|
+
|
|
109
|
+
export const DEFAULT_CODEX_MODEL_OPTIONS = {
|
|
110
|
+
reasoningEffort: "high",
|
|
111
|
+
fastMode: false,
|
|
112
|
+
} as const satisfies CodexModelOptions
|
|
113
|
+
|
|
114
|
+
export function isClaudeReasoningEffort(value: string | null | undefined): value is ClaudeReasoningEffort {
|
|
115
|
+
return CLAUDE_REASONING_OPTIONS.some((option) => option.id === value)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function isCodexReasoningEffort(value: string | null | undefined): value is CodexReasoningEffort {
|
|
119
|
+
return CODEX_REASONING_OPTIONS.some((option) => option.id === value)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export const CLAUDE_CONTEXT_WINDOW_OPTIONS = [
|
|
123
|
+
{ id: "200k", label: "200k" },
|
|
124
|
+
{ id: "1m", label: "1M" },
|
|
125
|
+
] as const satisfies readonly ProviderContextWindowOption[]
|
|
126
|
+
|
|
127
|
+
export function isClaudeContextWindow(value: string | null | undefined): value is ClaudeContextWindow {
|
|
128
|
+
return CLAUDE_CONTEXT_WINDOW_OPTIONS.some((option) => option.id === value)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
// Provider catalog
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
|
|
135
|
+
export interface ProviderCatalogEntry {
|
|
136
|
+
id: AgentProvider
|
|
137
|
+
label: string
|
|
138
|
+
defaultModel: string
|
|
139
|
+
defaultEffort?: string
|
|
140
|
+
supportsPlanMode: boolean
|
|
141
|
+
models: ProviderModelOption[]
|
|
142
|
+
efforts: ProviderEffortOption[]
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export const PROVIDERS: ProviderCatalogEntry[] = [
|
|
146
|
+
{
|
|
147
|
+
id: "claude",
|
|
148
|
+
label: "Claude",
|
|
149
|
+
defaultModel: "claude-sonnet-4-6",
|
|
150
|
+
defaultEffort: "high",
|
|
151
|
+
supportsPlanMode: true,
|
|
152
|
+
models: [
|
|
153
|
+
{
|
|
154
|
+
id: "claude-fable-5",
|
|
155
|
+
label: "Fable 5",
|
|
156
|
+
supportsEffort: true,
|
|
157
|
+
aliases: ["fable"],
|
|
158
|
+
contextWindowOptions: [...CLAUDE_CONTEXT_WINDOW_OPTIONS],
|
|
159
|
+
supportsMaxReasoningEffort: true,
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
id: "claude-opus-4-7",
|
|
163
|
+
label: "Opus 4.7",
|
|
164
|
+
supportsEffort: true,
|
|
165
|
+
aliases: ["opus"],
|
|
166
|
+
contextWindowOptions: [...CLAUDE_CONTEXT_WINDOW_OPTIONS],
|
|
167
|
+
supportsMaxReasoningEffort: true,
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
id: "claude-sonnet-4-6",
|
|
171
|
+
label: "Sonnet 4.6",
|
|
172
|
+
supportsEffort: true,
|
|
173
|
+
aliases: ["sonnet"],
|
|
174
|
+
contextWindowOptions: [...CLAUDE_CONTEXT_WINDOW_OPTIONS],
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
id: "claude-haiku-4-5-20251001",
|
|
178
|
+
label: "Haiku 4.5",
|
|
179
|
+
supportsEffort: true,
|
|
180
|
+
aliases: ["haiku"],
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
id: "claude-opus-4-8",
|
|
184
|
+
label: "Opus 4.8",
|
|
185
|
+
supportsEffort: true,
|
|
186
|
+
aliases: ["opus-4-8"],
|
|
187
|
+
contextWindowOptions: [...CLAUDE_CONTEXT_WINDOW_OPTIONS],
|
|
188
|
+
supportsMaxReasoningEffort: true,
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
efforts: [...CLAUDE_REASONING_OPTIONS],
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
id: "codex",
|
|
195
|
+
label: "Codex",
|
|
196
|
+
defaultModel: "gpt-5.5",
|
|
197
|
+
supportsPlanMode: true,
|
|
198
|
+
models: [
|
|
199
|
+
{ id: "gpt-5.5", label: "GPT-5.5", supportsEffort: false },
|
|
200
|
+
{ id: "gpt-5.4", label: "GPT-5.4", supportsEffort: false },
|
|
201
|
+
{ id: "gpt-5.3-codex", label: "GPT-5.3 Codex", supportsEffort: false, aliases: ["gpt-5-codex"] },
|
|
202
|
+
{ id: "gpt-5.3-codex-spark", label: "GPT-5.3 Codex Spark", supportsEffort: false },
|
|
203
|
+
],
|
|
204
|
+
efforts: [],
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
id: "openrouter",
|
|
208
|
+
label: "OpenRouter",
|
|
209
|
+
defaultModel: DEFAULT_OPENROUTER_SDK_MODEL,
|
|
210
|
+
supportsPlanMode: true,
|
|
211
|
+
models: [],
|
|
212
|
+
efforts: [],
|
|
213
|
+
},
|
|
214
|
+
]
|
|
215
|
+
|
|
216
|
+
export function getProviderCatalog(provider: AgentProvider): ProviderCatalogEntry {
|
|
217
|
+
const entry = PROVIDERS.find((candidate) => candidate.id === provider)
|
|
218
|
+
if (!entry) {
|
|
219
|
+
throw new Error(`Unknown provider: ${provider}`)
|
|
220
|
+
}
|
|
221
|
+
return entry
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// ---------------------------------------------------------------------------
|
|
225
|
+
// Custom model entries (user-configurable overrides over the catalog)
|
|
226
|
+
// ---------------------------------------------------------------------------
|
|
227
|
+
|
|
228
|
+
export interface CustomModelEntry {
|
|
229
|
+
id: string
|
|
230
|
+
label: string
|
|
231
|
+
provider: "claude" | "codex"
|
|
232
|
+
supportsEffort: boolean
|
|
233
|
+
aliases?: readonly string[]
|
|
234
|
+
contextWindowOptions?: readonly ProviderContextWindowOption[]
|
|
235
|
+
supportsMaxReasoningEffort?: boolean
|
|
236
|
+
createdAt: number
|
|
237
|
+
updatedAt: number
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export interface CustomModelInput {
|
|
241
|
+
id: string
|
|
242
|
+
label: string
|
|
243
|
+
provider: "claude" | "codex"
|
|
244
|
+
supportsEffort: boolean
|
|
245
|
+
aliases?: readonly string[]
|
|
246
|
+
contextWindowOptions?: readonly ProviderContextWindowOption[]
|
|
247
|
+
supportsMaxReasoningEffort?: boolean
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export interface CustomModelPatch {
|
|
251
|
+
label?: string
|
|
252
|
+
supportsEffort?: boolean
|
|
253
|
+
aliases?: readonly string[] | null
|
|
254
|
+
contextWindowOptions?: readonly ProviderContextWindowOption[] | null
|
|
255
|
+
supportsMaxReasoningEffort?: boolean
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// ---------------------------------------------------------------------------
|
|
259
|
+
// Text snippets (keyboard-shortcut text expansions)
|
|
260
|
+
// ---------------------------------------------------------------------------
|
|
261
|
+
|
|
262
|
+
export interface TextSnippet {
|
|
263
|
+
id: string
|
|
264
|
+
shortcut: string
|
|
265
|
+
expansion: string
|
|
266
|
+
createdAt: number
|
|
267
|
+
updatedAt: number
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export interface TextSnippetInput {
|
|
271
|
+
shortcut: string
|
|
272
|
+
expansion: string
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export interface TextSnippetPatch {
|
|
276
|
+
shortcut?: string
|
|
277
|
+
expansion?: string
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// ---------------------------------------------------------------------------
|
|
281
|
+
// mergeCustomModels — folds user overrides into the provider catalog
|
|
282
|
+
// ---------------------------------------------------------------------------
|
|
283
|
+
|
|
284
|
+
function customEntryToModelOption(entry: CustomModelEntry): ProviderModelOption {
|
|
285
|
+
return {
|
|
286
|
+
id: entry.id,
|
|
287
|
+
label: entry.label,
|
|
288
|
+
supportsEffort: entry.supportsEffort,
|
|
289
|
+
...(entry.aliases ? { aliases: entry.aliases } : {}),
|
|
290
|
+
...(entry.contextWindowOptions ? { contextWindowOptions: entry.contextWindowOptions } : {}),
|
|
291
|
+
...(entry.supportsMaxReasoningEffort !== undefined ? { supportsMaxReasoningEffort: entry.supportsMaxReasoningEffort } : {}),
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
export function mergeCustomModels(
|
|
296
|
+
base: ProviderCatalogEntry[],
|
|
297
|
+
customModels: readonly CustomModelEntry[],
|
|
298
|
+
): ProviderCatalogEntry[] {
|
|
299
|
+
return base.map((entry) => {
|
|
300
|
+
if (entry.id !== "claude" && entry.id !== "codex") return { ...entry, models: [...entry.models] }
|
|
301
|
+
const forProvider = customModels.filter((m) => m.provider === entry.id)
|
|
302
|
+
if (forProvider.length === 0) return { ...entry, models: [...entry.models] }
|
|
303
|
+
const models = [...entry.models]
|
|
304
|
+
for (const custom of forProvider) {
|
|
305
|
+
const option = customEntryToModelOption(custom)
|
|
306
|
+
const idx = models.findIndex((m) => m.id === option.id)
|
|
307
|
+
if (idx >= 0) models[idx] = option
|
|
308
|
+
else models.push(option)
|
|
309
|
+
}
|
|
310
|
+
return { ...entry, models }
|
|
311
|
+
})
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// ---------------------------------------------------------------------------
|
|
315
|
+
// Provider session helpers and model-id normalization
|
|
316
|
+
// ---------------------------------------------------------------------------
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* True when the provider's turns run through the Claude SDK session transport
|
|
320
|
+
* (a live `claudeSessions` entry consumed by `runClaudeSession`, prompts
|
|
321
|
+
* delivered via `session.sendPrompt`) rather than the generic harness-turn
|
|
322
|
+
* transport (`runTurn` over `active.turn.stream`).
|
|
323
|
+
*
|
|
324
|
+
* `claude` and `openrouter` both ride the SDK session — openrouter just points
|
|
325
|
+
* the SDK at OpenRouter's Anthropic-compatible endpoint. Branching on
|
|
326
|
+
* `provider === "claude"` where the real intent is "uses the SDK session" is
|
|
327
|
+
* what silently dropped openrouter's prompt delivery; use this predicate so a
|
|
328
|
+
* new SDK-backed provider can never be forgotten by an `if`-chain again.
|
|
329
|
+
*/
|
|
330
|
+
export function providerUsesSdkSession(provider: AgentProvider): boolean {
|
|
331
|
+
return provider === "claude" || provider === "openrouter"
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function catalogModelsFor(
|
|
335
|
+
provider: AgentProvider,
|
|
336
|
+
customModels?: readonly CustomModelEntry[],
|
|
337
|
+
): readonly ProviderModelOption[] {
|
|
338
|
+
const catalog = getProviderCatalog(provider)
|
|
339
|
+
if (!customModels || customModels.length === 0) return catalog.models
|
|
340
|
+
const [merged] = mergeCustomModels([{ ...catalog, models: [...catalog.models] }], customModels)
|
|
341
|
+
return merged.models
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function getProviderModelMatch(
|
|
345
|
+
provider: AgentProvider,
|
|
346
|
+
modelId?: string,
|
|
347
|
+
customModels?: readonly CustomModelEntry[],
|
|
348
|
+
): ProviderModelOption | undefined {
|
|
349
|
+
if (!modelId) return undefined
|
|
350
|
+
|
|
351
|
+
return catalogModelsFor(provider, customModels).find((candidate) =>
|
|
352
|
+
candidate.id === modelId || candidate.aliases?.includes(modelId)
|
|
353
|
+
)
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
export function normalizeProviderModelId(
|
|
357
|
+
provider: AgentProvider,
|
|
358
|
+
modelId?: string,
|
|
359
|
+
fallbackModelId?: string,
|
|
360
|
+
customModels?: readonly CustomModelEntry[],
|
|
361
|
+
): string {
|
|
362
|
+
return getProviderModelMatch(provider, modelId, customModels)?.id
|
|
363
|
+
?? fallbackModelId
|
|
364
|
+
?? getProviderCatalog(provider).defaultModel
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
export function normalizeClaudeModelId(
|
|
368
|
+
modelId?: string,
|
|
369
|
+
fallbackModelId = "claude-opus-4-7",
|
|
370
|
+
customModels?: readonly CustomModelEntry[],
|
|
371
|
+
): string {
|
|
372
|
+
return normalizeProviderModelId("claude", modelId, fallbackModelId, customModels)
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
export function normalizeCodexModelId(
|
|
376
|
+
modelId?: string,
|
|
377
|
+
fallbackModelId = "gpt-5.5",
|
|
378
|
+
customModels?: readonly CustomModelEntry[],
|
|
379
|
+
): string {
|
|
380
|
+
return normalizeProviderModelId("codex", modelId, fallbackModelId, customModels)
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
export function getProviderModelOption(
|
|
384
|
+
provider: AgentProvider,
|
|
385
|
+
modelId: string,
|
|
386
|
+
customModels?: readonly CustomModelEntry[],
|
|
387
|
+
): ProviderModelOption | undefined {
|
|
388
|
+
const normalizedModelId = normalizeProviderModelId(provider, modelId, undefined, customModels)
|
|
389
|
+
return catalogModelsFor(provider, customModels).find((candidate) => candidate.id === normalizedModelId)
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
export function getClaudeModelOption(
|
|
393
|
+
modelId: string,
|
|
394
|
+
customModels?: readonly CustomModelEntry[],
|
|
395
|
+
): ProviderModelOption | undefined {
|
|
396
|
+
return getProviderModelOption("claude", modelId, customModels)
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
export function supportsClaudeMaxReasoningEffort(
|
|
400
|
+
modelId: string,
|
|
401
|
+
customModels?: readonly CustomModelEntry[],
|
|
402
|
+
): boolean {
|
|
403
|
+
return Boolean(getClaudeModelOption(modelId, customModels)?.supportsMaxReasoningEffort)
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
export function getClaudeContextWindowOptions(
|
|
407
|
+
modelId: string,
|
|
408
|
+
customModels?: readonly CustomModelEntry[],
|
|
409
|
+
): readonly ProviderContextWindowOption[] {
|
|
410
|
+
return getClaudeModelOption(modelId, customModels)?.contextWindowOptions ?? []
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
export function normalizeClaudeContextWindow(
|
|
414
|
+
modelId: string,
|
|
415
|
+
contextWindow?: string,
|
|
416
|
+
customModels?: readonly CustomModelEntry[],
|
|
417
|
+
): ClaudeContextWindow {
|
|
418
|
+
const options = getClaudeContextWindowOptions(modelId, customModels)
|
|
419
|
+
if (options.length === 0) return DEFAULT_CLAUDE_MODEL_OPTIONS.contextWindow
|
|
420
|
+
return isClaudeContextWindow(contextWindow) && options.some((option) => option.id === contextWindow)
|
|
421
|
+
? contextWindow
|
|
422
|
+
: DEFAULT_CLAUDE_MODEL_OPTIONS.contextWindow
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
export function resolveClaudeApiModelId(modelId: string, contextWindow?: ClaudeContextWindow): string {
|
|
426
|
+
return contextWindow === "1m" ? `${modelId}[1m]` : modelId
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
export function resolveClaudeContextWindowTokens(contextWindow: ClaudeContextWindow): number {
|
|
430
|
+
switch (contextWindow) {
|
|
431
|
+
case "1m":
|
|
432
|
+
return 1_000_000
|
|
433
|
+
case "200k":
|
|
434
|
+
default:
|
|
435
|
+
return 200_000
|
|
436
|
+
}
|
|
437
|
+
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
// Subagent domain types: definitions, runtime snapshots, loop progress.
|
|
2
|
+
// Extracted from types.ts to keep the barrel lean.
|
|
3
|
+
// All external consumers importing from "../shared/types" continue to work unchanged.
|
|
4
|
+
|
|
5
|
+
import type { AgentProvider } from "./core-types"
|
|
6
|
+
import type { ClaudeModelOptions, CodexModelOptions } from "./provider-model-types"
|
|
7
|
+
import type { TranscriptEntry } from "./transcript-types"
|
|
8
|
+
|
|
9
|
+
export type SubagentContextScope = "previous-assistant-reply" | "full-transcript"
|
|
10
|
+
|
|
11
|
+
export type SubagentTriggerMode = "auto" | "manual"
|
|
12
|
+
|
|
13
|
+
export interface SubagentRestriction {
|
|
14
|
+
workingDir?: string
|
|
15
|
+
allowedPaths?: string[]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface Subagent {
|
|
19
|
+
id: string
|
|
20
|
+
name: string
|
|
21
|
+
description?: string
|
|
22
|
+
provider: AgentProvider
|
|
23
|
+
model: string
|
|
24
|
+
modelOptions: ClaudeModelOptions | CodexModelOptions
|
|
25
|
+
systemPrompt: string
|
|
26
|
+
contextScope: SubagentContextScope
|
|
27
|
+
triggerMode: SubagentTriggerMode
|
|
28
|
+
workingDir?: string
|
|
29
|
+
allowedPaths?: string[]
|
|
30
|
+
// Per-subagent agentic-turn bound — the analog of Claude Code's agent
|
|
31
|
+
// frontmatter `maxTurns`. Unset = unbounded (Claude Code's default).
|
|
32
|
+
// Claude-SDK runs pass it natively to query() (graceful stop, output kept);
|
|
33
|
+
// PTY/Codex runs get a host-side tool-call-count backstop (hard abort).
|
|
34
|
+
maxTurns?: number
|
|
35
|
+
createdAt: number
|
|
36
|
+
updatedAt: number
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface SubagentInput {
|
|
40
|
+
name: string
|
|
41
|
+
description?: string
|
|
42
|
+
provider: AgentProvider
|
|
43
|
+
model: string
|
|
44
|
+
modelOptions: ClaudeModelOptions | CodexModelOptions
|
|
45
|
+
systemPrompt: string
|
|
46
|
+
contextScope: SubagentContextScope
|
|
47
|
+
triggerMode?: SubagentTriggerMode
|
|
48
|
+
workingDir?: string
|
|
49
|
+
allowedPaths?: string[]
|
|
50
|
+
maxTurns?: number
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface SubagentPatch {
|
|
54
|
+
name?: string
|
|
55
|
+
description?: string | null
|
|
56
|
+
provider?: AgentProvider
|
|
57
|
+
model?: string
|
|
58
|
+
modelOptions?: Partial<ClaudeModelOptions> | Partial<CodexModelOptions>
|
|
59
|
+
systemPrompt?: string
|
|
60
|
+
contextScope?: SubagentContextScope
|
|
61
|
+
triggerMode?: SubagentTriggerMode
|
|
62
|
+
workingDir?: string | null
|
|
63
|
+
allowedPaths?: string[] | null
|
|
64
|
+
maxTurns?: number | null
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export type SubagentValidationErrorCode =
|
|
68
|
+
| "EMPTY_NAME"
|
|
69
|
+
| "INVALID_CHAR"
|
|
70
|
+
| "RESERVED_NAME"
|
|
71
|
+
| "DUPLICATE_NAME"
|
|
72
|
+
| "TOO_LONG"
|
|
73
|
+
| "NOT_FOUND"
|
|
74
|
+
| "RESTRICTION_NOT_SUPPORTED"
|
|
75
|
+
| "INVALID_PATH"
|
|
76
|
+
| "PATH_ESCAPE"
|
|
77
|
+
| "EMPTY_ALLOWED_PATHS"
|
|
78
|
+
|
|
79
|
+
export interface SubagentValidationError {
|
|
80
|
+
code: SubagentValidationErrorCode
|
|
81
|
+
message: string
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export type SubagentErrorCode =
|
|
85
|
+
| "AUTH_REQUIRED"
|
|
86
|
+
| "UNKNOWN_SUBAGENT"
|
|
87
|
+
| "MANUAL_ONLY"
|
|
88
|
+
| "LOOP_DETECTED"
|
|
89
|
+
| "DEPTH_EXCEEDED"
|
|
90
|
+
| "TIMEOUT"
|
|
91
|
+
| "MAX_TURNS"
|
|
92
|
+
| "PROVIDER_ERROR"
|
|
93
|
+
| "INTERRUPTED"
|
|
94
|
+
| "USER_CANCELLED"
|
|
95
|
+
| "CAP_EXCEEDED"
|
|
96
|
+
| "NO_LIVE_SESSION"
|
|
97
|
+
|
|
98
|
+
export type SubagentRunStatus = "running" | "completed" | "failed" | "cancelled"
|
|
99
|
+
|
|
100
|
+
export interface ProviderUsage {
|
|
101
|
+
inputTokens?: number
|
|
102
|
+
outputTokens?: number
|
|
103
|
+
cachedInputTokens?: number
|
|
104
|
+
costUsd?: number
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface SubagentPendingTool {
|
|
108
|
+
toolUseId: string
|
|
109
|
+
toolKind: "ask_user_question" | "exit_plan_mode"
|
|
110
|
+
input: Record<string, unknown>
|
|
111
|
+
requestedAt: number
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export interface SubagentRunSnapshot {
|
|
115
|
+
runId: string
|
|
116
|
+
chatId: string
|
|
117
|
+
subagentId: string | null
|
|
118
|
+
subagentName: string
|
|
119
|
+
/**
|
|
120
|
+
* Short human label for this run, derived from the first line of the spawn
|
|
121
|
+
* prompt (e.g. "Migrate useKannaState.ts"). Null for runs started before this
|
|
122
|
+
* field existed or by error paths that never carried a prompt. Drives the
|
|
123
|
+
* Loop Progress panel rows so each round reads as the chunk it worked on
|
|
124
|
+
* rather than an opaque run id.
|
|
125
|
+
*/
|
|
126
|
+
label: string | null
|
|
127
|
+
provider: AgentProvider
|
|
128
|
+
model: string
|
|
129
|
+
status: SubagentRunStatus
|
|
130
|
+
parentUserMessageId: string
|
|
131
|
+
parentRunId: string | null
|
|
132
|
+
depth: number
|
|
133
|
+
startedAt: number
|
|
134
|
+
finishedAt: number | null
|
|
135
|
+
finalText: string | null
|
|
136
|
+
error: { code: SubagentErrorCode; message: string } | null
|
|
137
|
+
usage: ProviderUsage | null
|
|
138
|
+
/**
|
|
139
|
+
* Every TranscriptEntry the subagent produced, in arrival order. Includes
|
|
140
|
+
* tool_call, tool_result, system_init, account_info, result. assistant_text
|
|
141
|
+
* entries also live here in addition to being concatenated into finalText
|
|
142
|
+
* via subagent_message_delta — clients should prefer entries[] for rich
|
|
143
|
+
* rendering, finalText only as a quick text-only summary.
|
|
144
|
+
*/
|
|
145
|
+
entries: TranscriptEntry[]
|
|
146
|
+
/**
|
|
147
|
+
* Set while the subagent is awaiting a user response to an
|
|
148
|
+
* interactive tool call (AskUserQuestion / ExitPlanMode). Null
|
|
149
|
+
* otherwise. The orchestrator's wall-clock timeout is paused while
|
|
150
|
+
* this is non-null.
|
|
151
|
+
*/
|
|
152
|
+
pendingTool: SubagentPendingTool | null
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export type LoopRowStatus = "pending" | "running" | "done" | "failed"
|
|
156
|
+
|
|
157
|
+
export interface LoopRow {
|
|
158
|
+
runId: string
|
|
159
|
+
label: string
|
|
160
|
+
status: LoopRowStatus
|
|
161
|
+
startedAt: number
|
|
162
|
+
finishedAt: number | null
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export interface LoopRateLimitInfo {
|
|
166
|
+
/** The live auto-continue schedule id, so the panel's Resume action can accept it. */
|
|
167
|
+
scheduleId: string
|
|
168
|
+
/** epoch ms the usage limit resets (and the resume is/would be scheduled for) */
|
|
169
|
+
resetAt: number
|
|
170
|
+
tz: string
|
|
171
|
+
/**
|
|
172
|
+
* true → an auto-continue is already scheduled to fire at `resetAt`
|
|
173
|
+
* (the loop resumes on its own).
|
|
174
|
+
* false → the resume is only proposed and waits on the user
|
|
175
|
+
* (auto-resume setting off) — render a "Resume" action.
|
|
176
|
+
*/
|
|
177
|
+
scheduled: boolean
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export interface LoopProgressSnapshot {
|
|
181
|
+
chatId: string
|
|
182
|
+
/** Whether a loop is currently armed for this chat. */
|
|
183
|
+
armed: boolean
|
|
184
|
+
/** Latest first — most recent delegation at the top, mirroring PROGRESS.md. */
|
|
185
|
+
rows: LoopRow[]
|
|
186
|
+
/** Non-null while the loop is paused on a Claude usage limit. */
|
|
187
|
+
rateLimit: LoopRateLimitInfo | null
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Type guards
|
|
191
|
+
|
|
192
|
+
export function isSubagentContextScope(value: string): value is SubagentContextScope {
|
|
193
|
+
return value === "previous-assistant-reply" || value === "full-transcript"
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export function isSubagentTriggerMode(value: string): value is SubagentTriggerMode {
|
|
197
|
+
return value === "auto" || value === "manual"
|
|
198
|
+
}
|