@cjhyy/code-shell 0.1.0-alpha.2 → 0.1.5
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/CHANGELOG.md +77 -0
- package/dist/anthropic-IBTI4WL2.cjs +10 -0
- package/dist/anthropic-PRZZKHEZ.js +10 -0
- package/dist/arena/index.cjs +7 -6
- package/dist/arena/index.js +6 -5
- package/dist/arena/model-presets.d.ts +10 -1
- package/dist/{arena-HHDYYVHJ.cjs → arena-KBQOPLFV.cjs} +25 -23
- package/dist/{arena-ENHBHB2W.js → arena-O2L4TN6A.js} +9 -7
- package/dist/{chunk-SW3L7HIM.js → chunk-2EP3CLEN.js} +2 -2
- package/dist/{chunk-EL2RL5DG.cjs → chunk-2YW4FPFG.cjs} +2 -2
- package/dist/chunk-3OA5G4TM.js +47 -0
- package/dist/chunk-52LGZKT3.cjs +47 -0
- package/dist/{chunk-KOGV6PDQ.cjs → chunk-55XGPMAP.cjs} +44 -9
- package/dist/chunk-5ECBT4YA.js +450 -0
- package/dist/{chunk-YD7XTI7T.cjs → chunk-6QVAYW7C.cjs} +116 -28
- package/dist/{chunk-SCDKLTN3.js → chunk-6S4BJ65N.js} +5 -4
- package/dist/{chunk-ZLPJJZUW.js → chunk-76HYEPDM.js} +2 -2
- package/dist/{chunk-FA5KD34T.js → chunk-76W334S4.js} +2 -2
- package/dist/{chunk-GZBD6QRS.cjs → chunk-7EG3V4JY.cjs} +13 -12
- package/dist/{chunk-LMEKCQX4.js → chunk-7JVTYEEC.js} +6 -6
- package/dist/{chunk-ID6EJUHP.js → chunk-7K6SDRRF.js} +1262 -212
- package/dist/{chunk-5C5HIOML.js → chunk-7Y6S3OCX.js} +109 -21
- package/dist/{chunk-G76E5FOB.cjs → chunk-A5LCRPDP.cjs} +4 -4
- package/dist/{chunk-F5BS3GUC.js → chunk-BSW22MPA.js} +39 -4
- package/dist/{chunk-VWFET3MG.cjs → chunk-BUU5PZK2.cjs} +1474 -423
- package/dist/{chunk-HOXQLX5R.cjs → chunk-BWTOS5BH.cjs} +444 -103
- package/dist/{chunk-ZRVPCXI7.js → chunk-BXCY2FSE.js} +2 -1
- package/dist/{chunk-Y7TSCDF6.js → chunk-C5YQBIRK.js} +347 -6
- package/dist/{chunk-C7C7ZZY4.cjs → chunk-HEKQCI7B.cjs} +10 -10
- package/dist/{chunk-JHXNOB5G.cjs → chunk-HS2MFNUC.cjs} +6 -6
- package/dist/{chunk-JHNCK7JP.cjs → chunk-IK4EWJBP.cjs} +4 -3
- package/dist/{chunk-M2QI5X3X.cjs → chunk-JMR33QVF.cjs} +2 -2
- package/dist/{chunk-YAFCN7ZW.cjs → chunk-KOVYSDHZ.cjs} +15 -15
- package/dist/{chunk-IJSHQGMP.cjs → chunk-KS3RYAYL.cjs} +4 -4
- package/dist/{chunk-DI7RDLOS.js → chunk-MD32R22I.js} +7 -4
- package/dist/chunk-MY5XHADU.cjs +216 -0
- package/dist/{chunk-OP57WUWQ.cjs → chunk-NUNC3VFB.cjs} +6 -6
- package/dist/{chunk-TATCTZSB.cjs → chunk-QRM7IF2S.cjs} +133 -175
- package/dist/chunk-R47ROHGL.cjs +298 -0
- package/dist/{chunk-OUC2DFA7.js → chunk-RMYKO74M.js} +3 -3
- package/dist/{chunk-FUOKLKR2.js → chunk-SFXHZSRF.js} +1 -1
- package/dist/{chunk-2EUAE7AY.js → chunk-SIHHIQLO.js} +2 -2
- package/dist/{chunk-3CAZIWUA.cjs → chunk-SNT563K3.cjs} +9 -9
- package/dist/{chunk-SK62UVS6.js → chunk-T6VYG46N.js} +1 -1
- package/dist/{chunk-3QR52LL5.cjs → chunk-TUY2T5KP.cjs} +2 -2
- package/dist/{chunk-I57ZD5IQ.js → chunk-VIAGTYYW.js} +1 -1
- package/dist/{chunk-X2DNIMPC.cjs → chunk-VYL4EFRC.cjs} +32 -32
- package/dist/chunk-W22P377T.js +299 -0
- package/dist/chunk-WASS5YWB.js +215 -0
- package/dist/{chunk-OMRGA6TI.js → chunk-XDIQWQJ4.js} +132 -174
- package/dist/{chunk-BUJ5KYCI.cjs → chunk-YIQBXAYU.cjs} +13 -13
- package/dist/{chunk-REFCCVDM.js → chunk-YJ77GQK5.js} +2 -2
- package/dist/chunk-YUI524OE.cjs +450 -0
- package/dist/{chunk-M2SVOKC6.js → chunk-ZBPSQCPU.js} +6 -6
- package/dist/cli/commands/builtin/export-md.d.ts +19 -0
- package/dist/cli/commands/builtin/init/detect.d.ts +25 -0
- package/dist/cli/commands/builtin/init/index.d.ts +19 -0
- package/dist/cli/main.cjs +2374 -1455
- package/dist/cli/main.js +2505 -1586
- package/dist/cli/migrate-models.d.ts +45 -0
- package/dist/cli/onboarding.d.ts +110 -5
- package/dist/cli/updater.d.ts +51 -4
- package/dist/client-base-HTF236ZD.cjs +9 -0
- package/dist/client-base-QKRKCOWB.js +9 -0
- package/dist/{compaction-YNWCEF7B.js → compaction-6VU2T643.js} +4 -2
- package/dist/compaction-OKUNTCA7.cjs +33 -0
- package/dist/context/compaction.d.ts +35 -3
- package/dist/context/manager.d.ts +40 -3
- package/dist/context/tool-result-storage.d.ts +96 -0
- package/dist/devtools-T2NIZBJK.cjs +6 -0
- package/dist/{devtools-IRQQPIRY.js → devtools-YXWHOVKR.js} +1 -1
- package/dist/engine/engine.d.ts +40 -0
- package/dist/engine/turn-loop.d.ts +6 -0
- package/dist/export-md-RXDW6F5W.cjs +135 -0
- package/dist/export-md-XXKZANW5.js +135 -0
- package/dist/file-history-KYPE3ECT.cjs +7 -0
- package/dist/file-history-LF4F7X26.js +7 -0
- package/dist/index.cjs +42 -22
- package/dist/index.d.ts +5 -2
- package/dist/index.js +40 -20
- package/dist/llm/client-base.d.ts +1 -1
- package/dist/llm/model-cache.d.ts +21 -0
- package/dist/llm/model-fetcher.d.ts +29 -0
- package/dist/llm/model-pool.d.ts +13 -0
- package/dist/llm/provider-catalog.d.ts +30 -0
- package/dist/llm/provider-kinds.d.ts +21 -0
- package/dist/llm/types.d.ts +8 -0
- package/dist/logging/session-recorder.d.ts +77 -0
- package/dist/manager-C2IUXKRC.js +7 -0
- package/dist/manager-YYKWYTRM.cjs +7 -0
- package/dist/mcp-manager-QMKWPBZ4.js +8 -0
- package/dist/mcp-manager-Z3OKI74O.cjs +8 -0
- package/dist/memory-5LWZ6FI2.cjs +9 -0
- package/dist/{memory-EPFDBPII.js → memory-VIJLBAMQ.js} +2 -2
- package/dist/model-cache-5KIYL5SL.js +13 -0
- package/dist/model-cache-OED3IM4R.cjs +13 -0
- package/dist/model-fetcher-HKGICACL.js +8 -0
- package/dist/model-fetcher-UR6WJOQP.cjs +8 -0
- package/dist/openai-JR2WEKOF.js +10 -0
- package/dist/openai-YBTOET4O.cjs +10 -0
- package/dist/openrouter-models-OU4GRZQY.cjs +15 -0
- package/dist/{openrouter-models-OL725CL6.js → openrouter-models-TGKDKY52.js} +2 -2
- package/dist/openrouter-sync-BBHUM3R6.cjs +11 -0
- package/dist/{openrouter-sync-CWD5VNW2.js → openrouter-sync-UXUSJCIR.js} +3 -3
- package/dist/product/index.cjs +17 -15
- package/dist/product/index.js +16 -14
- package/dist/protocol/server.d.ts +3 -1
- package/dist/protocol/types.d.ts +36 -2
- package/dist/run/index.cjs +17 -15
- package/dist/run/index.js +16 -14
- package/dist/services/index.d.ts +0 -1
- package/dist/session-manager-Q22BBMD3.js +8 -0
- package/dist/session-manager-XODQVL3C.cjs +8 -0
- package/dist/settings/schema.d.ts +267 -42
- package/dist/{tool-summary-RYNR4DDB.cjs → tool-summary-63DPIS7G.cjs} +4 -4
- package/dist/{tool-summary-2RUFL5QK.js → tool-summary-NP5CDBKG.js} +2 -2
- package/dist/tool-system/builtin/ask-user.d.ts +9 -1
- package/dist/tool-system/context.d.ts +31 -2
- package/dist/tool-system/executor.d.ts +4 -0
- package/dist/tool-system/investigation-guard.d.ts +37 -0
- package/dist/types.d.ts +13 -2
- package/dist/ui/components/AskUserPrompt.d.ts +8 -1
- package/dist/ui/components/DiffLine.d.ts +33 -0
- package/dist/ui/components/ModelManager.d.ts +34 -1
- package/dist/ui/components/OnboardingPrompt.d.ts +10 -1
- package/dist/ui/components/ProviderModelFlow.d.ts +58 -0
- package/dist/ui/components/UpdateBanner.d.ts +1 -0
- package/dist/updater-QW473OF4.cjs +17 -0
- package/dist/updater-VFUAHCVY.js +17 -0
- package/dist/utils/semver.d.ts +1 -0
- package/dist/utils/task-sanitizer.d.ts +6 -0
- package/package.json +4 -2
- package/scripts/check-node.cjs +21 -0
- package/dist/anthropic-P5VETAFI.cjs +0 -10
- package/dist/anthropic-W2GU3D76.js +0 -10
- package/dist/chunk-75E4BBFC.js +0 -224
- package/dist/chunk-FV2ARONZ.cjs +0 -224
- package/dist/client-base-TOVE25FA.js +0 -9
- package/dist/client-base-VDDIADAC.cjs +0 -9
- package/dist/compaction-D3KV2NWY.cjs +0 -31
- package/dist/devtools-WTC3NFNE.cjs +0 -6
- package/dist/file-history-HZWO2WQ5.js +0 -7
- package/dist/file-history-UQQILIY7.cjs +0 -7
- package/dist/manager-FWLOVEEK.cjs +0 -7
- package/dist/manager-GEXJLOIS.js +0 -7
- package/dist/mcp-manager-37GQLFGX.js +0 -8
- package/dist/mcp-manager-U77NEXBY.cjs +0 -8
- package/dist/memory-ADGOWADP.cjs +0 -9
- package/dist/openai-RXU5URYI.js +0 -10
- package/dist/openai-SQW4H2K4.cjs +0 -10
- package/dist/openrouter-models-UM3AOGZ4.cjs +0 -15
- package/dist/openrouter-sync-HYZZC6RX.cjs +0 -11
- package/dist/services/compact.d.ts +0 -56
- package/dist/session-manager-HRSKENKB.cjs +0 -8
- package/dist/session-manager-NEKFEHF3.js +0 -8
- package/dist/updater-M7L42ASZ.cjs +0 -183
- package/dist/updater-ZRTONIR4.js +0 -183
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One-shot migration of legacy flat models[] into providers[] + models[].
|
|
3
|
+
*
|
|
4
|
+
* Pure function — takes a snapshot, returns the new snapshot plus a flag.
|
|
5
|
+
* The caller (settings load path) is responsible for writing settings.json
|
|
6
|
+
* and the .bak backup.
|
|
7
|
+
*/
|
|
8
|
+
import type { ProviderConfig } from "../llm/provider-catalog.js";
|
|
9
|
+
interface LegacyModel {
|
|
10
|
+
key: string;
|
|
11
|
+
label?: string;
|
|
12
|
+
provider?: string;
|
|
13
|
+
baseUrl?: string;
|
|
14
|
+
apiKey?: string;
|
|
15
|
+
model: string;
|
|
16
|
+
maxOutputTokens?: number;
|
|
17
|
+
maxContextTokens?: number;
|
|
18
|
+
providerKey?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface MigrationInput {
|
|
21
|
+
providers: ProviderConfig[];
|
|
22
|
+
models: LegacyModel[];
|
|
23
|
+
}
|
|
24
|
+
export interface MigrationOutput {
|
|
25
|
+
providers: ProviderConfig[];
|
|
26
|
+
models: Array<{
|
|
27
|
+
key: string;
|
|
28
|
+
label?: string;
|
|
29
|
+
providerKey: string;
|
|
30
|
+
model: string;
|
|
31
|
+
/**
|
|
32
|
+
* Self-describing legacy fields. Kept (rather than stripped) so model
|
|
33
|
+
* entries stay valid standalone — the engine can read credentials
|
|
34
|
+
* straight off the entry without a ProviderCatalog round-trip.
|
|
35
|
+
*/
|
|
36
|
+
provider?: string;
|
|
37
|
+
baseUrl?: string;
|
|
38
|
+
apiKey?: string;
|
|
39
|
+
maxOutputTokens?: number;
|
|
40
|
+
maxContextTokens?: number;
|
|
41
|
+
}>;
|
|
42
|
+
changed: boolean;
|
|
43
|
+
}
|
|
44
|
+
export declare function migrateModels(input: MigrationInput): MigrationOutput;
|
|
45
|
+
export {};
|
package/dist/cli/onboarding.d.ts
CHANGED
|
@@ -5,6 +5,13 @@
|
|
|
5
5
|
* pure(-ish) helpers it consumes, so there's a single input stack.
|
|
6
6
|
*/
|
|
7
7
|
export interface OnboardingResult {
|
|
8
|
+
/**
|
|
9
|
+
* Pool alias key (e.g. "deepseek-v4-pro"). The engine uses this to switch
|
|
10
|
+
* the active model — callers should NOT re-derive an alias from `model`
|
|
11
|
+
* (the old modelKey() helper folded multiple model ids to one key, which
|
|
12
|
+
* silently shadowed entries in the pool).
|
|
13
|
+
*/
|
|
14
|
+
key: string;
|
|
8
15
|
provider: string;
|
|
9
16
|
model: string;
|
|
10
17
|
apiKey: string;
|
|
@@ -42,7 +49,37 @@ export interface DetectedEnvKey {
|
|
|
42
49
|
export declare function detectEnvKeys(): DetectedEnvKey[];
|
|
43
50
|
/** Mask a key for display: "sk-517f...b594" */
|
|
44
51
|
export declare function maskKey(key: string): string;
|
|
52
|
+
/**
|
|
53
|
+
* Find a provider definition that matches a given API key.
|
|
54
|
+
* Checks key prefix first, then env var match, then baseUrl.
|
|
55
|
+
*/
|
|
56
|
+
export declare function detectProviderFromApiKey(apiKey: string, baseUrl?: string): ProviderDef | undefined;
|
|
45
57
|
export declare function validateApiKey(baseUrl: string, apiKey: string): Promise<boolean>;
|
|
58
|
+
/**
|
|
59
|
+
* Resolve an API key from the canonical fallback chain.
|
|
60
|
+
* Priority: 1) command-line option 2) settings.json 3) all provider env vars
|
|
61
|
+
*/
|
|
62
|
+
export declare function resolveApiKey(optionsApiKey?: string, settingsApiKey?: string): string | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* Look up a previously-persisted API key for a given provider in
|
|
65
|
+
* ~/.code-shell/settings.json. Matches by baseUrl (each ProviderDef.baseUrl
|
|
66
|
+
* is unique, while `provider` is a generic kind like "openai" shared across
|
|
67
|
+
* multiple endpoints).
|
|
68
|
+
*
|
|
69
|
+
* Returns the first match found in: settings.models[] (preferred — newer),
|
|
70
|
+
* then settings.model (legacy top-level). undefined when nothing matches.
|
|
71
|
+
*/
|
|
72
|
+
export declare function findSavedKeyForProvider(provider: ProviderDef): {
|
|
73
|
+
apiKey: string;
|
|
74
|
+
baseUrl: string;
|
|
75
|
+
} | undefined;
|
|
76
|
+
/**
|
|
77
|
+
* Return the list of model IDs previously saved under this provider
|
|
78
|
+
* (matched by baseUrl). Used by the onboarding wizard to pre-populate the
|
|
79
|
+
* "model pool" step with the user's prior choices instead of resetting to
|
|
80
|
+
* just provider.defaultModel.
|
|
81
|
+
*/
|
|
82
|
+
export declare function loadSavedModelsForProvider(provider: ProviderDef): string[];
|
|
46
83
|
export declare function hasApiKey(): boolean;
|
|
47
84
|
/**
|
|
48
85
|
* Resolve a model's max-output-token budget. Lookup order:
|
|
@@ -56,12 +93,29 @@ export declare function hasApiKey(): boolean;
|
|
|
56
93
|
*/
|
|
57
94
|
export declare function resolveMaxOutput(model: string): number | undefined;
|
|
58
95
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
96
|
+
* Resolve a model's context window size. Lookup order:
|
|
97
|
+
* 1. KNOWN_CONTEXT_WINDOWS (covers direct providers like DeepSeek)
|
|
98
|
+
* 2. OpenRouter snapshot (covers `vendor/model` style IDs)
|
|
99
|
+
* 3. undefined — unknown
|
|
63
100
|
*/
|
|
64
|
-
export declare function
|
|
101
|
+
export declare function resolveContextWindow(model: string): number | undefined;
|
|
102
|
+
/**
|
|
103
|
+
* Derive a pool key in `provider-model` form. Single source of truth for
|
|
104
|
+
* model alias generation — replaces the old modelKey() function which
|
|
105
|
+
* folded same-family models to one key (e.g. v4-flash and v4-pro both
|
|
106
|
+
* collapsed to "deepseek"), causing the pool to silently shadow entries.
|
|
107
|
+
*
|
|
108
|
+
* ("deepseek", "deepseek-v4-pro") → "deepseek-v4-pro"
|
|
109
|
+
* ("openai", "openai/gpt-5") → "openai-gpt-5"
|
|
110
|
+
* ("anthropic","claude-opus-4-7") → "anthropic-claude-opus-4-7"
|
|
111
|
+
*
|
|
112
|
+
* If the model id already starts with `<provider>-` (e.g. "deepseek-v4-pro"
|
|
113
|
+
* under provider "deepseek"), the prefix isn't duplicated.
|
|
114
|
+
*
|
|
115
|
+
* `used` is a set of already-taken keys; collisions are resolved with a
|
|
116
|
+
* `-2`, `-3`, ... suffix.
|
|
117
|
+
*/
|
|
118
|
+
export declare function deriveModelPoolKey(providerKind: string, modelId: string, used?: string[]): string;
|
|
65
119
|
/**
|
|
66
120
|
* Build model pool entries from a provider's model list.
|
|
67
121
|
*/
|
|
@@ -73,7 +127,58 @@ export declare function buildModelPool(provider: ProviderDef, apiKey: string): A
|
|
|
73
127
|
baseUrl: string;
|
|
74
128
|
apiKey: string;
|
|
75
129
|
maxOutputTokens?: number;
|
|
130
|
+
maxContextTokens?: number;
|
|
76
131
|
}>;
|
|
77
132
|
export declare function modelDisplayName(model: string): string;
|
|
78
133
|
export declare function saveSettings(result: OnboardingResult, providerDef?: ProviderDef, poolModels?: string[]): void;
|
|
134
|
+
/**
|
|
135
|
+
* Append-only persistence for the new ProviderModelFlow-based onboarding.
|
|
136
|
+
*
|
|
137
|
+
* Writes the new shape:
|
|
138
|
+
* - settings.activeKey — primary source of truth for active model
|
|
139
|
+
* - settings.models[] — self-describing entries (key, provider,
|
|
140
|
+
* model, baseUrl, apiKey, maxOutput, maxContext)
|
|
141
|
+
* - settings.providers[] — credential source for the wizard
|
|
142
|
+
* - settings.model.* — legacy mirror of the active entry, kept in
|
|
143
|
+
* sync so legacy boot paths (cli/main.ts,
|
|
144
|
+
* repl.ts, run.ts) keep working without
|
|
145
|
+
* each having to learn about activeKey
|
|
146
|
+
*
|
|
147
|
+
* Append-only: never removes existing entries. To start over use /logout.
|
|
148
|
+
* Writes atomically via tmp+rename.
|
|
149
|
+
*/
|
|
150
|
+
export declare function appendOnboardingResult(opts: {
|
|
151
|
+
/** Alias key the engine should switch to after writing. Matches one of addedModels[].key. */
|
|
152
|
+
activeKey: string;
|
|
153
|
+
/** Active entry's fields, used to mirror into the legacy settings.model.* block. */
|
|
154
|
+
activeMirror: {
|
|
155
|
+
provider: string;
|
|
156
|
+
model: string;
|
|
157
|
+
apiKey: string;
|
|
158
|
+
baseUrl: string;
|
|
159
|
+
};
|
|
160
|
+
addedProvider?: {
|
|
161
|
+
key: string;
|
|
162
|
+
label?: string;
|
|
163
|
+
kind: string;
|
|
164
|
+
baseUrl: string;
|
|
165
|
+
apiKey?: string;
|
|
166
|
+
protocol?: string;
|
|
167
|
+
modelsPath?: string;
|
|
168
|
+
};
|
|
169
|
+
addedModels: Array<{
|
|
170
|
+
key: string;
|
|
171
|
+
label?: string;
|
|
172
|
+
providerKey?: string;
|
|
173
|
+
/** LLM client/protocol ("openai"/"anthropic"). New canonical name. */
|
|
174
|
+
protocol?: string;
|
|
175
|
+
/** Legacy mirror of `protocol`. Both are written so legacy readers keep working. */
|
|
176
|
+
provider?: string;
|
|
177
|
+
model: string;
|
|
178
|
+
baseUrl: string;
|
|
179
|
+
apiKey?: string;
|
|
180
|
+
maxContextTokens?: number;
|
|
181
|
+
maxOutputTokens?: number;
|
|
182
|
+
}>;
|
|
183
|
+
}): void;
|
|
79
184
|
export declare function saveArenaSettingsByKeys(keys: string[]): void;
|
package/dist/cli/updater.d.ts
CHANGED
|
@@ -1,10 +1,57 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Auto-update
|
|
2
|
+
* Auto-update — checks npm registry for newer versions; can optionally install
|
|
3
|
+
* the new version in the background after the current process exits.
|
|
4
|
+
*
|
|
5
|
+
* Flow:
|
|
6
|
+
* 1. `checkForUpdate()` runs at startup (non-blocking). Stores result in
|
|
7
|
+
* module state for the UI to read via `getUpdateAvailable()`.
|
|
8
|
+
* 2. UI re-polls every 30 min via `pollForUpdate()`.
|
|
9
|
+
* 3. If the user has write permission on the npm global prefix, we register
|
|
10
|
+
* `scheduleAutoInstallOnExit()` so that on process exit a detached
|
|
11
|
+
* `npm i -g` spawns and survives the parent. Next startup picks up
|
|
12
|
+
* the new version.
|
|
13
|
+
* 4. If the user has NO permission, UI shows the manual command instead.
|
|
14
|
+
*
|
|
15
|
+
* Concurrency: multiple `code-shell` processes can run at once. A file lock
|
|
16
|
+
* at `~/.code-shell/.update.lock` prevents both from launching `npm i -g`
|
|
17
|
+
* simultaneously (which corrupts the install).
|
|
3
18
|
*/
|
|
19
|
+
export interface UpdateInfo {
|
|
20
|
+
latestVersion: string;
|
|
21
|
+
/** True if `<npm prefix>` is writable by current user — can self-install. */
|
|
22
|
+
canAutoInstall: boolean;
|
|
23
|
+
/** Cached npm global prefix path (for diagnostics / manual command hint). */
|
|
24
|
+
npmPrefix: string | null;
|
|
25
|
+
}
|
|
4
26
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
27
|
+
* Kick off an update check. Non-blocking: returns immediately, fills module
|
|
28
|
+
* state when network/npm respond. Safe to call multiple times (e.g. on a 30min
|
|
29
|
+
* timer).
|
|
7
30
|
*/
|
|
8
31
|
export declare function checkForUpdate(packageName?: string): void;
|
|
9
|
-
|
|
32
|
+
/** Returns update info if a newer version was found, else undefined. */
|
|
33
|
+
export declare function getUpdateAvailable(): UpdateInfo | undefined;
|
|
34
|
+
/** Returns "why is auto-update off" — for /doctor-style diagnostics. */
|
|
35
|
+
export declare function getAutoUpdateDisabledReason(): string | null;
|
|
36
|
+
/**
|
|
37
|
+
* Install the on-exit hook so that the new version is installed AFTER the
|
|
38
|
+
* current process exits (avoids overwriting files the running process still
|
|
39
|
+
* has open). Idempotent — calling twice is a no-op.
|
|
40
|
+
*/
|
|
41
|
+
export declare function scheduleAutoInstallOnExit(): void;
|
|
10
42
|
export declare function getCurrentVersion(): string;
|
|
43
|
+
declare function getLockFilePath(): string;
|
|
44
|
+
/**
|
|
45
|
+
* Try to acquire the update lock. Returns true on success.
|
|
46
|
+
* Uses `O_EXCL` (writeFile flag 'wx') for atomic create. Stale locks (mtime
|
|
47
|
+
* older than LOCK_TIMEOUT_MS) are taken over, re-verifying staleness right
|
|
48
|
+
* before unlink to close the TOCTOU race.
|
|
49
|
+
*/
|
|
50
|
+
declare function acquireLock(): Promise<boolean>;
|
|
51
|
+
declare function releaseLock(): Promise<void>;
|
|
52
|
+
export declare const __internal: {
|
|
53
|
+
acquireLock: typeof acquireLock;
|
|
54
|
+
releaseLock: typeof releaseLock;
|
|
55
|
+
getLockFilePath: typeof getLockFilePath;
|
|
56
|
+
};
|
|
57
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
+
|
|
3
|
+
var _chunk7EG3V4JYcjs = require('./chunk-7EG3V4JY.cjs');
|
|
4
|
+
require('./chunk-2YW4FPFG.cjs');
|
|
5
|
+
require('./chunk-IK4EWJBP.cjs');
|
|
6
|
+
require('./chunk-KS3RYAYL.cjs');
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
exports.LLMClientBase = _chunk7EG3V4JYcjs.LLMClientBase;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
COMPACTABLE_TOOL_NAMES,
|
|
2
3
|
adjustIndexToPreserveAPIInvariants,
|
|
3
4
|
applySummaryCompaction,
|
|
4
5
|
applyToolResultBudget,
|
|
@@ -12,10 +13,11 @@ import {
|
|
|
12
13
|
snipCompact,
|
|
13
14
|
truncateToolResult,
|
|
14
15
|
windowCompact
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
import "./chunk-
|
|
16
|
+
} from "./chunk-7Y6S3OCX.js";
|
|
17
|
+
import "./chunk-MD32R22I.js";
|
|
17
18
|
init_compaction();
|
|
18
19
|
export {
|
|
20
|
+
COMPACTABLE_TOOL_NAMES,
|
|
19
21
|
adjustIndexToPreserveAPIInvariants,
|
|
20
22
|
applySummaryCompaction,
|
|
21
23
|
applyToolResultBudget,
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
var _chunk6QVAYW7Ccjs = require('./chunk-6QVAYW7C.cjs');
|
|
17
|
+
require('./chunk-KS3RYAYL.cjs');
|
|
18
|
+
_chunk6QVAYW7Ccjs.init_compaction.call(void 0, );
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
exports.COMPACTABLE_TOOL_NAMES = _chunk6QVAYW7Ccjs.COMPACTABLE_TOOL_NAMES; exports.adjustIndexToPreserveAPIInvariants = _chunk6QVAYW7Ccjs.adjustIndexToPreserveAPIInvariants; exports.applySummaryCompaction = _chunk6QVAYW7Ccjs.applySummaryCompaction; exports.applyToolResultBudget = _chunk6QVAYW7Ccjs.applyToolResultBudget; exports.buildSummarizationPrompt = _chunk6QVAYW7Ccjs.buildSummarizationPrompt; exports.dropOldestRounds = _chunk6QVAYW7Ccjs.dropOldestRounds; exports.estimateTokens = _chunk6QVAYW7Ccjs.estimateTokens; exports.extractReferencedFilePaths = _chunk6QVAYW7Ccjs.extractReferencedFilePaths; exports.groupMessagesByApiRound = _chunk6QVAYW7Ccjs.groupMessagesByApiRound; exports.microcompact = _chunk6QVAYW7Ccjs.microcompact; exports.snipCompact = _chunk6QVAYW7Ccjs.snipCompact; exports.truncateToolResult = _chunk6QVAYW7Ccjs.truncateToolResult; exports.windowCompact = _chunk6QVAYW7Ccjs.windowCompact;
|
|
@@ -36,12 +36,44 @@ export declare function snipCompact(messages: Message[], keepFirstN?: number, ke
|
|
|
36
36
|
* Uses adjustIndexToPreserveAPIInvariants to avoid splitting tool pairs.
|
|
37
37
|
*/
|
|
38
38
|
export declare function windowCompact(messages: Message[], keepLastN: number): Message[];
|
|
39
|
+
/**
|
|
40
|
+
* Tools whose results are safe to clear during microcompact.
|
|
41
|
+
*
|
|
42
|
+
* Tracks the CC `COMPACTABLE_TOOLS` set: only "data-fetching" tools where the
|
|
43
|
+
* result is reconstructible (re-Read, re-Glob, re-Bash). Orchestration tools
|
|
44
|
+
* (TaskCreate / TaskUpdate / Agent / Skill / etc.) are excluded — their
|
|
45
|
+
* results carry conversation state the model needs to keep referencing.
|
|
46
|
+
*/
|
|
47
|
+
export declare const COMPACTABLE_TOOL_NAMES: ReadonlySet<string>;
|
|
48
|
+
export interface MicrocompactOptions {
|
|
49
|
+
/** Keep this many most-recent compactable tool-result rounds untouched. */
|
|
50
|
+
keepRecentN?: number;
|
|
51
|
+
/** Tool names whose results may be cleared. Defaults to COMPACTABLE_TOOL_NAMES. */
|
|
52
|
+
compactableTools?: ReadonlySet<string>;
|
|
53
|
+
/** Optional callback invoked once when any clearing actually happened. */
|
|
54
|
+
onClear?: (info: {
|
|
55
|
+
clearedRounds: number;
|
|
56
|
+
toolNames: string[];
|
|
57
|
+
}) => void;
|
|
58
|
+
}
|
|
39
59
|
/**
|
|
40
60
|
* Remove old tool_result content (microcompact).
|
|
41
|
-
*
|
|
42
|
-
* older than
|
|
61
|
+
*
|
|
62
|
+
* For each tool_result block older than the most-recent N compactable rounds,
|
|
63
|
+
* replaces its content with a short fingerprint of the originating call
|
|
64
|
+
* (e.g. `[Old tool result cleared — Read file_path=/.../foo.ts]`) so the
|
|
65
|
+
* model can decide whether it's worth re-running the tool instead of
|
|
66
|
+
* guessing what it had seen.
|
|
67
|
+
*
|
|
68
|
+
* Behavior changes vs. earlier versions:
|
|
69
|
+
* - Only clears whitelisted tool names (Read/Glob/Bash/...). Orchestration
|
|
70
|
+
* tool results (TaskCreate/TaskUpdate/Agent/etc.) are left intact.
|
|
71
|
+
* - "Round" count is per *compactable* result, not per message with any
|
|
72
|
+
* tool_result. A round containing only TaskUpdate doesn't count toward N.
|
|
73
|
+
* - Replacement string includes tool name + key args so the model isn't
|
|
74
|
+
* forced into blind re-Reads (which then trip the Investigation guard).
|
|
43
75
|
*/
|
|
44
|
-
export declare function microcompact(messages: Message[],
|
|
76
|
+
export declare function microcompact(messages: Message[], options?: MicrocompactOptions): Message[];
|
|
45
77
|
/**
|
|
46
78
|
* Apply aggregate per-message tool result budget.
|
|
47
79
|
* When total tool_result content in a single message exceeds maxTotalChars,
|
|
@@ -11,13 +11,27 @@ export interface ContextManagerConfig {
|
|
|
11
11
|
compactAtRatio: number;
|
|
12
12
|
summarizeAtRatio: number;
|
|
13
13
|
maxToolResultChars: number;
|
|
14
|
+
/**
|
|
15
|
+
* Lower bound, as a ratio of maxTokens, below which microcompact will not
|
|
16
|
+
* run. CC's external (non-cache-edit) path is "autocompact handles context
|
|
17
|
+
* pressure"; mirror that by leaving early-turn context alone so a model
|
|
18
|
+
* with a 1M window doesn't see its first-3-rounds Read results wiped at
|
|
19
|
+
* 23k tokens. Raising the floor also keeps prompt-cache prefixes warm in
|
|
20
|
+
* short sessions.
|
|
21
|
+
*/
|
|
22
|
+
microcompactFloorRatio: number;
|
|
23
|
+
/**
|
|
24
|
+
* Most-recent compactable rounds microcompact keeps untouched. Auto-derived
|
|
25
|
+
* from maxTokens when not set explicitly: bigger window → keep more.
|
|
26
|
+
*/
|
|
27
|
+
microcompactKeepRecent?: number;
|
|
14
28
|
}
|
|
15
29
|
/**
|
|
16
30
|
* Async function type for LLM summarization calls.
|
|
17
31
|
* Injected by the Engine so the ContextManager doesn't depend on LLM directly.
|
|
18
32
|
*/
|
|
19
33
|
export type SummarizeFn = (prompt: string) => Promise<string>;
|
|
20
|
-
export type CompactStrategy = "summary" | "window" | "snip" | "emergency";
|
|
34
|
+
export type CompactStrategy = "micro" | "summary" | "window" | "snip" | "emergency";
|
|
21
35
|
export type OnCompactFn = (info: {
|
|
22
36
|
strategy: CompactStrategy;
|
|
23
37
|
before: number;
|
|
@@ -35,8 +49,15 @@ export declare class ContextManager {
|
|
|
35
49
|
private lastActualAtMessageCount;
|
|
36
50
|
/** Path to session transcript — passed to summary compaction for on-demand access. */
|
|
37
51
|
private transcriptPath;
|
|
38
|
-
/** Notified whenever
|
|
52
|
+
/** Notified whenever any compaction tier fires, including microcompact. */
|
|
39
53
|
private onCompact;
|
|
54
|
+
/**
|
|
55
|
+
* Tool-result persistence state. Created lazily once we know where to
|
|
56
|
+
* write files (i.e. once setTranscriptPath has been called).
|
|
57
|
+
* `null` = persistence has been explicitly disabled.
|
|
58
|
+
*/
|
|
59
|
+
private replacementState;
|
|
60
|
+
private toolResultsDir;
|
|
40
61
|
constructor(config?: Partial<ContextManagerConfig>);
|
|
41
62
|
setOnCompact(fn: OnCompactFn): void;
|
|
42
63
|
/**
|
|
@@ -54,9 +75,19 @@ export declare class ContextManager {
|
|
|
54
75
|
*/
|
|
55
76
|
setSummarizeFn(fn: SummarizeFn): void;
|
|
56
77
|
/**
|
|
57
|
-
* Set the transcript path so compaction can reference it.
|
|
78
|
+
* Set the transcript path so compaction can reference it. The
|
|
79
|
+
* tool-results directory lives alongside the transcript file:
|
|
80
|
+
* <transcriptDir>/tool-results/<toolUseId>.txt
|
|
58
81
|
*/
|
|
59
82
|
setTranscriptPath(path: string): void;
|
|
83
|
+
/**
|
|
84
|
+
* Initialize tool-result-persistence state from already-loaded messages.
|
|
85
|
+
* Call this once per session, after setTranscriptPath, when resuming so
|
|
86
|
+
* the manager re-enters the same "frozen decision" state it had on the
|
|
87
|
+
* previous run. Without this, a resumed session would re-evaluate
|
|
88
|
+
* every result against the current threshold and might flip choices.
|
|
89
|
+
*/
|
|
90
|
+
initReplacementStateFromMessages(messages: Message[]): void;
|
|
60
91
|
/**
|
|
61
92
|
* Apply progressive context management (sync path).
|
|
62
93
|
* For Tier 2 (LLM summary), call manageAsync instead.
|
|
@@ -67,6 +98,12 @@ export declare class ContextManager {
|
|
|
67
98
|
* Call this when you have access to the LLM (between turns).
|
|
68
99
|
*/
|
|
69
100
|
manageAsync(messages: Message[]): Promise<Message[]>;
|
|
101
|
+
/**
|
|
102
|
+
* Persist large tool_result blocks to disk and replace them with a
|
|
103
|
+
* preview + filepath. No-op when transcript path hasn't been set
|
|
104
|
+
* (e.g. unit tests that exercise compaction directly without a session).
|
|
105
|
+
*/
|
|
106
|
+
private persistLargeToolResults;
|
|
70
107
|
/**
|
|
71
108
|
* Truncate oversized tool results in messages.
|
|
72
109
|
*/
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool-result persistence — write large tool_result content to disk and
|
|
3
|
+
* replace the in-context message with a reference + preview.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors Claude Code's services/compact/microcompact.ts + utils/toolResultStorage.ts
|
|
6
|
+
* approach, simplified for codeshell:
|
|
7
|
+
*
|
|
8
|
+
* • One file per tool_use_id (UUID), so the same id always maps to the
|
|
9
|
+
* same file — guarantees byte-identical preview on every turn.
|
|
10
|
+
* • Decision state (ContentReplacementState) is held by the caller and
|
|
11
|
+
* mutated in place. Once a result is "seen", its fate is frozen for
|
|
12
|
+
* the rest of the session (prevents flapping replacement choices that
|
|
13
|
+
* would constantly invalidate the prompt prefix).
|
|
14
|
+
* • No transcript persistence / no fork-subagent gap-fill. Resume just
|
|
15
|
+
* re-derives the seenIds set from the loaded messages.
|
|
16
|
+
*
|
|
17
|
+
* Strategy:
|
|
18
|
+
* • Per-result cap (DEFAULT_PERSIST_THRESHOLD): when a single tool_result
|
|
19
|
+
* exceeds it, persist + replace.
|
|
20
|
+
* • Per-message aggregate cap (PER_MESSAGE_AGGREGATE_CAP): when a single
|
|
21
|
+
* user message's tool_results together exceed it (e.g. a batch of
|
|
22
|
+
* parallel Read results), persist the largest ones first until under.
|
|
23
|
+
*/
|
|
24
|
+
import type { Message } from "../types.js";
|
|
25
|
+
/** Per-result threshold. Larger than this → persist + replace. */
|
|
26
|
+
export declare const DEFAULT_PERSIST_THRESHOLD = 50000;
|
|
27
|
+
/** Per-message aggregate cap (sum of tool_result content sizes in one user msg). */
|
|
28
|
+
export declare const PER_MESSAGE_AGGREGATE_CAP = 200000;
|
|
29
|
+
/** Preview length included in the replacement string. */
|
|
30
|
+
export declare const PREVIEW_SIZE = 2000;
|
|
31
|
+
/**
|
|
32
|
+
* Per-session decision state for tool-result persistence.
|
|
33
|
+
*
|
|
34
|
+
* seenIds — every tool_use_id we've evaluated; once seen, its fate
|
|
35
|
+
* (persisted or not) is fixed for the rest of the session.
|
|
36
|
+
* replacements — subset of seenIds that were persisted, mapped to the
|
|
37
|
+
* EXACT replacement string sent to the model. Re-applying
|
|
38
|
+
* is a Map lookup, never re-reads the file, guarantees
|
|
39
|
+
* byte-identical output.
|
|
40
|
+
*/
|
|
41
|
+
export interface ContentReplacementState {
|
|
42
|
+
seenIds: Set<string>;
|
|
43
|
+
replacements: Map<string, string>;
|
|
44
|
+
}
|
|
45
|
+
export declare function createContentReplacementState(): ContentReplacementState;
|
|
46
|
+
/**
|
|
47
|
+
* Rebuild a state object by walking the loaded message history.
|
|
48
|
+
* Used on resume so the budget makes the same decisions it made before.
|
|
49
|
+
* Replacements are taken from the messages themselves (we identify them
|
|
50
|
+
* by the PERSISTED_OPEN sentinel), so we don't need a side-channel log.
|
|
51
|
+
*/
|
|
52
|
+
export declare function reconstructContentReplacementState(messages: Message[]): ContentReplacementState;
|
|
53
|
+
/**
|
|
54
|
+
* Resolve the directory tool results are written to, given the engine's
|
|
55
|
+
* transcript path. Layout: <transcriptDir>/tool-results/
|
|
56
|
+
*/
|
|
57
|
+
export declare function resolveToolResultsDir(transcriptPath: string): string;
|
|
58
|
+
interface PersistOptions {
|
|
59
|
+
/** Per-result threshold; default DEFAULT_PERSIST_THRESHOLD. */
|
|
60
|
+
perResultThreshold?: number;
|
|
61
|
+
/** Per-message aggregate cap; default PER_MESSAGE_AGGREGATE_CAP. */
|
|
62
|
+
perMessageCap?: number;
|
|
63
|
+
/** Directory to write tool-result files to. Required. */
|
|
64
|
+
toolResultsDir: string;
|
|
65
|
+
/** Decision state, mutated in place. */
|
|
66
|
+
state: ContentReplacementState;
|
|
67
|
+
/** Optional callback fired when a result is freshly persisted. */
|
|
68
|
+
onPersist?: (info: {
|
|
69
|
+
toolUseId: string;
|
|
70
|
+
filepath: string;
|
|
71
|
+
originalSize: number;
|
|
72
|
+
reason: "per-result-cap" | "per-message-budget";
|
|
73
|
+
}) => void;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Walk each user message, decide which tool_result blocks should be
|
|
77
|
+
* persisted (per-result cap OR per-message aggregate), persist them,
|
|
78
|
+
* and return a new message array with those blocks replaced.
|
|
79
|
+
*
|
|
80
|
+
* Frozen decisions:
|
|
81
|
+
* - If a tool_use_id is already in state.replacements, that exact
|
|
82
|
+
* replacement is re-applied (no I/O).
|
|
83
|
+
* - If it's in state.seenIds but NOT replacements, it was decided
|
|
84
|
+
* "don't persist" on an earlier pass — leave it unreplaced even if
|
|
85
|
+
* it now exceeds the threshold (changing the decision mid-session
|
|
86
|
+
* would invalidate any model state built on the prior content).
|
|
87
|
+
*
|
|
88
|
+
* @returns the new messages array, with replacements applied.
|
|
89
|
+
*/
|
|
90
|
+
export declare function applyToolResultPersistence(messages: Message[], options: PersistOptions): Message[];
|
|
91
|
+
/**
|
|
92
|
+
* Public test helper: check whether content already wears the persisted
|
|
93
|
+
* sentinel. Used by tests to assert idempotency.
|
|
94
|
+
*/
|
|
95
|
+
export declare function isPersistedReplacement(s: string): boolean;
|
|
96
|
+
export {};
|
package/dist/engine/engine.d.ts
CHANGED
|
@@ -64,8 +64,29 @@ export declare class Engine {
|
|
|
64
64
|
private lastSessionId;
|
|
65
65
|
private compactedMessagesBySession;
|
|
66
66
|
private activePermission;
|
|
67
|
+
/** Public accessor so UI/clients can read the resolved per-model window. */
|
|
68
|
+
get maxContextTokens(): number;
|
|
67
69
|
private resolveMaxContextTokens;
|
|
68
70
|
constructor(config: EngineConfig);
|
|
71
|
+
/**
|
|
72
|
+
* Load models[] / providers[] from settings into the active ModelPool and
|
|
73
|
+
* resync this.config.llm with the matching entry. Called from the ctor and
|
|
74
|
+
* from reloadModelPool() (e.g. after onboarding writes new entries to disk).
|
|
75
|
+
*/
|
|
76
|
+
private populateModelPoolFromSettings;
|
|
77
|
+
/**
|
|
78
|
+
* Re-read settings and refresh the model pool. Used after onboarding /login
|
|
79
|
+
* writes new providers[] / models[] to disk so the running engine picks them
|
|
80
|
+
* up without a process restart. Existing pool entries are kept (re-registering
|
|
81
|
+
* the same key overwrites them), so callers don't need to clear first.
|
|
82
|
+
*/
|
|
83
|
+
reloadModelPool(): void;
|
|
84
|
+
/**
|
|
85
|
+
* Auto-populate the model pool when settings.models[] is empty but
|
|
86
|
+
* the user has configured an API key. Detects the provider from the
|
|
87
|
+
* key prefix / baseUrl and registers all its known models.
|
|
88
|
+
*/
|
|
89
|
+
private autoPopulatePool;
|
|
69
90
|
/**
|
|
70
91
|
* Register a custom tool (from product adapter) into the tool registry.
|
|
71
92
|
* Must be called before run().
|
|
@@ -89,8 +110,23 @@ export declare class Engine {
|
|
|
89
110
|
/**
|
|
90
111
|
* Switch the active model by pool key. Takes effect on the next run() call.
|
|
91
112
|
* Returns the new model entry.
|
|
113
|
+
*
|
|
114
|
+
* Persists settings.activeKey (and a legacy settings.model.* mirror) so the
|
|
115
|
+
* next process startup defaults to the same model — without this, switches
|
|
116
|
+
* only live in memory and every restart reverts to the previously persisted
|
|
117
|
+
* activeKey.
|
|
92
118
|
*/
|
|
93
119
|
switchModel(key: string): ModelEntry;
|
|
120
|
+
/**
|
|
121
|
+
* Write the active model selection to ~/.code-shell/settings.json.
|
|
122
|
+
*
|
|
123
|
+
* We mirror into the legacy settings.model.* block (provider/name/apiKey/
|
|
124
|
+
* baseUrl) because boot paths in cli/main.ts, repl.ts, run.ts still read it.
|
|
125
|
+
* The mirror uses resolved llm values (not raw entry.*) so credentials that
|
|
126
|
+
* live on settings.providers[] flow through correctly — entry.apiKey is
|
|
127
|
+
* undefined when the entry resolves via providerCatalog.
|
|
128
|
+
*/
|
|
129
|
+
private persistActiveModel;
|
|
94
130
|
/** Get the model pool. */
|
|
95
131
|
getModelPool(): ModelPool;
|
|
96
132
|
/** Get the current model name (full path). */
|
|
@@ -102,6 +138,10 @@ export declare class Engine {
|
|
|
102
138
|
* Inject context into a session's transcript without triggering a LLM turn.
|
|
103
139
|
* The injected content appears as an assistant message so the LLM can see it
|
|
104
140
|
* in subsequent conversations. The transcript auto-flushes to disk.
|
|
141
|
+
*
|
|
142
|
+
* Also updates the in-memory compacted message cache so the next
|
|
143
|
+
* engine.run() call for this session picks up the injected content
|
|
144
|
+
* instead of a stale snapshot from the previous run.
|
|
105
145
|
*/
|
|
106
146
|
injectContext(sessionId: string, content: string): void;
|
|
107
147
|
/**
|
|
@@ -16,6 +16,12 @@ export interface TurnLoopConfig {
|
|
|
16
16
|
tokenBudget?: number;
|
|
17
17
|
onStream?: StreamCallback;
|
|
18
18
|
signal?: AbortSignal;
|
|
19
|
+
/**
|
|
20
|
+
* Fired after each turn boundary is recorded. Lets the engine flush an
|
|
21
|
+
* up-to-date snapshot to state.json mid-run, so a long run doesn't leave
|
|
22
|
+
* the on-disk turnCount/status frozen at the last completion.
|
|
23
|
+
*/
|
|
24
|
+
onTurnBoundary?: (turnCount: number) => void;
|
|
19
25
|
}
|
|
20
26
|
export interface TurnLoopDeps {
|
|
21
27
|
model: ModelFacade;
|