@khorsheed/dsh-local-agent-kimi 0.2.0-rc.1 → 0.2.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/CHANGELOG.md +26 -0
- package/README.en.md +24 -112
- package/README.i18n.yaml +2 -2
- package/README.md +24 -112
- package/lib/client.js +816 -324
- package/lib/index.js +2121 -1311
- package/lib/types/client/SettingsCard.d.ts +75 -24
- package/lib/types/client/SettingsCard.js +110 -137
- package/lib/types/client/icons.d.ts +1 -1
- package/lib/types/client/index.d.ts +6 -25
- package/lib/types/client/index.js +134 -51
- package/lib/types/client/locales.d.ts +34 -24
- package/lib/types/client/locales.js +38 -28
- package/lib/types/endpoint-auth.d.ts +202 -0
- package/lib/types/endpoint-auth.js +287 -0
- package/lib/types/index.d.ts +19 -2
- package/lib/types/index.js +146 -19
- package/lib/types/kimi-cli-provider.d.ts +31 -4
- package/lib/types/kimi-cli-provider.js +110 -60
- package/lib/types/live-driver.d.ts +17 -5
- package/lib/types/live-driver.js +345 -129
- package/lib/types/live-switch.d.ts +16 -1
- package/lib/types/live-switch.js +11 -1
- package/lib/types/model-broker.d.ts +12 -2
- package/lib/types/model-broker.js +51 -6
- package/lib/types/model-catalog.d.ts +44 -1
- package/lib/types/model-catalog.js +110 -17
- package/lib/types/model-configuration.d.ts +26 -0
- package/lib/types/model-configuration.js +43 -0
- package/lib/types/provision.d.ts +102 -31
- package/lib/types/provision.js +257 -45
- package/lib/types/records.d.ts +0 -20
- package/lib/types/records.js +1 -40
- package/lib/types/session-mirror.d.ts +115 -52
- package/lib/types/session-mirror.js +286 -210
- package/lib/types/session-view.d.ts +23 -2
- package/lib/types/session-view.js +37 -7
- package/locale/en.json +2 -2
- package/locale/zh.json +2 -2
- package/package.json +21 -22
- package/lib/invariant.js +0 -31
- package/lib/types/credential-guard.d.ts +0 -29
- package/lib/types/credential-guard.js +0 -107
- package/lib/types/invariant.d.ts +0 -16
- package/lib/types/invariant.js +0 -33
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { randomUUID } from 'node:crypto';
|
|
12
12
|
import { SessionId } from '@deepseek-ai/dsh-session';
|
|
13
|
-
import { NO_START_CAPABILITIES, settleRunResult, subprocessRunHandle, } from '@deepseek-ai/dsh-subagent';
|
|
14
|
-
import { assertResumeCwdUnchanged, assertResumeScopeUnchanged, resolveRoundModel, containerExecSpawn, containerScopedHome, delegationEnv, establishSubagentCatalogChild, probeCliVersion, resolveChildCwd, subagentDelegationLabel, } from '@khorsheed/dsh-local-agent';
|
|
13
|
+
import { NO_START_CAPABILITIES, SUBAGENT_DESCRIPTOR_VERSION, settleRunResult, subprocessRunHandle, } from '@deepseek-ai/dsh-subagent';
|
|
14
|
+
import { assertResumeCwdUnchanged, assertResumeScopeUnchanged, resolveRoundModel, containerExecSpawn, containerScopedHome, delegationEnv, establishSubagentCatalogChild, persistChildSession, probeCliVersion, resolveChildCwd, subagentDelegationLabel, } from '@khorsheed/dsh-local-agent';
|
|
15
15
|
import { MEMBER_BRIDGE_SOCKET_ENV, MEMBER_BRIDGE_TOKEN_ENV } from '@khorsheed/dsh-local-agent/types';
|
|
16
16
|
import { LiveChannelUnavailableError } from './live-driver.js';
|
|
17
|
-
import { guardKimiCredential } from './credential-guard.js';
|
|
18
17
|
import { injectMemberBridge, memberBridgeServerKey, removeMemberBridge } from './member-bridge-config.js';
|
|
19
|
-
import { readKimiBaseUrl } from './provision.js';
|
|
18
|
+
import { ensureKimiEndpointProvider, KIMI_MANAGED_BASE_URL, readKimiBaseUrl } from './provision.js';
|
|
19
|
+
import { endpointAuthEnv, hasEndpointCredential } from './endpoint-auth.js';
|
|
20
20
|
import { kimiExecConfiguration } from './model-configuration.js';
|
|
21
21
|
import { addTokenUsage } from './session-view.js';
|
|
22
22
|
import { mirrorKimiSessionDelta } from './session-mirror.js';
|
|
@@ -81,6 +81,7 @@ export class KimiCliProvider {
|
|
|
81
81
|
live;
|
|
82
82
|
model;
|
|
83
83
|
memberModels;
|
|
84
|
+
endpoint;
|
|
84
85
|
name = 'kimi-cli';
|
|
85
86
|
capabilities = NO_START_CAPABILITIES;
|
|
86
87
|
inheritsParentContext = false;
|
|
@@ -91,19 +92,43 @@ export class KimiCliProvider {
|
|
|
91
92
|
* while a retiring generation still hosts it).
|
|
92
93
|
* @param model - resolver for the configured model, read PER ROUND so a
|
|
93
94
|
* settings-card write takes effect on the next delegation without a
|
|
94
|
-
* reload
|
|
95
|
-
*
|
|
96
|
-
*
|
|
95
|
+
* reload; it receives the round's scope (a named scope's curated list
|
|
96
|
+
* answers first). Undefined (the resolver absent, or returning
|
|
97
|
+
* undefined) leaves the argv exactly as it was before the key rode every
|
|
98
|
+
* round — the scoped config.toml's `default_model` then decides, as it
|
|
99
|
+
* always did.
|
|
97
100
|
* @param memberModels - the broker's member-model ledger: the provider
|
|
98
101
|
* records each delegation's start model here (the live driver's spawn
|
|
99
102
|
* resolver binds it) and reads the session-level override as the exec
|
|
100
103
|
* path's top layer. Absent (older wiring), both drop out.
|
|
101
104
|
*/
|
|
102
|
-
constructor(ctx, live, model, memberModels
|
|
105
|
+
constructor(ctx, live, model, memberModels,
|
|
106
|
+
/**
|
|
107
|
+
* Resolver for the scope's endpoint credential, read PER ROUND so a
|
|
108
|
+
* settings-card write takes effect on the next delegation without a
|
|
109
|
+
* reload. A resolution carrying a key authenticates the round through the
|
|
110
|
+
* managed provider's `api_key_env` indirection (the key rides the child
|
|
111
|
+
* process's environment); the same resolution's baseUrl is pinned onto
|
|
112
|
+
* the managed provider by the pre-spawn config surgery.
|
|
113
|
+
*/
|
|
114
|
+
endpoint) {
|
|
103
115
|
this.ctx = ctx;
|
|
104
116
|
this.live = live;
|
|
105
117
|
this.model = model;
|
|
106
118
|
this.memberModels = memberModels;
|
|
119
|
+
this.endpoint = endpoint;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Resolve the scope's endpoint for this round and land its baseUrl on the
|
|
123
|
+
* managed provider (the surgery writes only on drift), so a hand-edited
|
|
124
|
+
* endpoint-auth.json applies without a restart.
|
|
125
|
+
*/
|
|
126
|
+
async prepareEndpoint(homeDir) {
|
|
127
|
+
if (this.endpoint === undefined)
|
|
128
|
+
return undefined;
|
|
129
|
+
const endpoint = await this.endpoint(homeDir).catch(() => undefined);
|
|
130
|
+
await ensureKimiEndpointProvider(homeDir, hasEndpointCredential(endpoint) ? endpoint.baseUrl ?? KIMI_MANAGED_BASE_URL : undefined).catch(() => false);
|
|
131
|
+
return endpoint;
|
|
107
132
|
}
|
|
108
133
|
/** Resolve the live driver for one round's member, if live is on for it. */
|
|
109
134
|
liveDriver(childSessionId) {
|
|
@@ -200,7 +225,7 @@ export class KimiCliProvider {
|
|
|
200
225
|
...record?.configurationLock === undefined ? {} : { configurationLock: record.configurationLock },
|
|
201
226
|
}, configuration => this.startKimiResume(request, intent, cwd, homeDir, exec, scope, record?.model, configuration), request.signal, intent?.onAdmitted);
|
|
202
227
|
}
|
|
203
|
-
const childSessionId = SessionId(intent?.preparedMemberId ?? randomUUID());
|
|
228
|
+
const childSessionId = SessionId(intent?.preparedMemberId ?? intent?.childSessionId ?? randomUUID());
|
|
204
229
|
if (typeof this.ctx.localAgent.withMemberConfigurationRound !== 'function') {
|
|
205
230
|
if (intent?.effort !== undefined)
|
|
206
231
|
throw new Error('Kimi effort requires the configuration admission core');
|
|
@@ -234,20 +259,25 @@ export class KimiCliProvider {
|
|
|
234
259
|
delegationDepth: (request.parent.session.header.delegationDepth ?? 0) + 1,
|
|
235
260
|
},
|
|
236
261
|
});
|
|
237
|
-
// The durable one-shot descriptor
|
|
238
|
-
//
|
|
239
|
-
//
|
|
240
|
-
//
|
|
241
|
-
//
|
|
262
|
+
// The durable one-shot descriptor marks this child as session-backed;
|
|
263
|
+
// without it the 子代理 projection cannot classify the session and the
|
|
264
|
+
// delegation stays invisible. Host 0.2.1 no longer resolves a descriptor
|
|
265
|
+
// onto the request (the runtime's one-shot snapshot is gone), so the
|
|
266
|
+
// provider stamps the same payload itself. The label carries the harness
|
|
267
|
+
// display name as the source marker so the dropdown shows which local
|
|
268
|
+
// agent produced the conversation; the activation spec's required label
|
|
269
|
+
// arrives as the empty string when the caller named none.
|
|
242
270
|
const harness = this.ctx.localAgent.get('kimi');
|
|
243
|
-
const label = subagentDelegationLabel(harness?.displayName ?? 'kimi', request.
|
|
271
|
+
const label = subagentDelegationLabel(harness?.displayName ?? 'kimi', request.label || undefined);
|
|
244
272
|
childSession.append('subagent/descriptor', {
|
|
245
|
-
|
|
273
|
+
version: SUBAGENT_DESCRIPTOR_VERSION,
|
|
274
|
+
mode: 'one-shot',
|
|
275
|
+
provider: this.name,
|
|
246
276
|
label,
|
|
247
277
|
});
|
|
248
|
-
// The
|
|
249
|
-
//
|
|
250
|
-
//
|
|
278
|
+
// The 0.2.1 manager appends the parent-side subagent/catalog discovery
|
|
279
|
+
// row only for parent-delivered children; the family runs caller
|
|
280
|
+
// delivery, so the provider appends it here — once per child, where
|
|
251
281
|
// the descriptor lands. A failure degrades to the warn below; a missing
|
|
252
282
|
// row never blocks the delegation.
|
|
253
283
|
establishSubagentCatalogChild(request.parent.session, childSession.header, label);
|
|
@@ -264,7 +294,13 @@ export class KimiCliProvider {
|
|
|
264
294
|
// diagnostics: the CLI reads it directly, and a user-edited value is
|
|
265
295
|
// authoritative. Log it so a failing delegation reports which endpoint
|
|
266
296
|
// it actually used.
|
|
267
|
-
|
|
297
|
+
// The round's endpoint credential: resolved per round (a card write
|
|
298
|
+
// applies to the next delegation) and pinned onto the managed provider
|
|
299
|
+
// by the surgery above; the key rides the spawn env under api_key_env.
|
|
300
|
+
const endpoint = await this.prepareEndpoint(homeDir);
|
|
301
|
+
const baseUrl = hasEndpointCredential(endpoint)
|
|
302
|
+
? endpoint.baseUrl
|
|
303
|
+
: await readKimiBaseUrl(homeDir).catch(() => undefined);
|
|
268
304
|
this.ctx.logger.info(`subagent-kimi: delegating via ${baseUrl ?? 'kimi default endpoint'}`);
|
|
269
305
|
// Live driver: the round goes to the member's resident `kimi acp` process.
|
|
270
306
|
// A channel that fails at spawn/handshake falls through to the exec
|
|
@@ -330,12 +366,12 @@ export class KimiCliProvider {
|
|
|
330
366
|
try {
|
|
331
367
|
const run = await startKimiCliRun(request, {
|
|
332
368
|
cwd,
|
|
333
|
-
env: delegationEnv({ KIMI_CODE_HOME: homeDir }),
|
|
369
|
+
env: delegationEnv({ KIMI_CODE_HOME: homeDir, ...endpointAuthEnv(endpoint) }),
|
|
334
370
|
...exec === undefined ? {} : { exec },
|
|
335
371
|
endpointLabel: baseUrl,
|
|
336
372
|
// The session-level override (the composer picker) outranks even the
|
|
337
373
|
// delegation's own model — the family order puts it first.
|
|
338
|
-
...(configuration?.resolved ?? resolveRoundModel(this.memberModels?.overrideFor(runId) ?? requestedModel, this.model)),
|
|
374
|
+
...(configuration?.resolved ?? resolveRoundModel(this.memberModels?.overrideFor(runId) ?? requestedModel, () => this.model?.(scope))),
|
|
339
375
|
...configuration === undefined ? {} : { controlled: true },
|
|
340
376
|
disposeGraceMs: DEFAULT_DISPOSE_GRACE_MS,
|
|
341
377
|
spawn: spec => this.ctx.subprocess.spawn(spec),
|
|
@@ -343,9 +379,6 @@ export class KimiCliProvider {
|
|
|
343
379
|
this.ctx.logger.warn(`subagent-kimi: child run failed (${stopReason}) via ${baseUrl ?? 'kimi default endpoint'}: ${error instanceof Error ? error.message : String(error)}`);
|
|
344
380
|
},
|
|
345
381
|
onAuthFailure: (detail) => {
|
|
346
|
-
// The sentinel: an empty-shell wipe restored here makes the
|
|
347
|
-
// caller's retry (or the next round) succeed.
|
|
348
|
-
void guardKimiCredential(homeDir, message => { this.ctx.logger.warn(message); });
|
|
349
382
|
this.ctx.localAgent.reportAuthFailure('kimi', detail, scope);
|
|
350
383
|
},
|
|
351
384
|
onAuthSuccess: () => { markCredentialVerified(this.ctx, scope); },
|
|
@@ -442,18 +475,23 @@ export class KimiCliProvider {
|
|
|
442
475
|
const member = exec === undefined && scope === undefined
|
|
443
476
|
? this.memberRun(intent.childSessionId, request.parent.session.id, homeDir)
|
|
444
477
|
: undefined;
|
|
445
|
-
|
|
478
|
+
// Same endpoint handling as the fresh path: resolve per round, pin
|
|
479
|
+
// the managed provider, inject the key under api_key_env.
|
|
480
|
+
const endpoint = await this.prepareEndpoint(homeDir);
|
|
481
|
+
const baseUrl = hasEndpointCredential(endpoint)
|
|
482
|
+
? endpoint.baseUrl
|
|
483
|
+
: await readKimiBaseUrl(homeDir).catch(() => undefined);
|
|
446
484
|
this.ctx.logger.info(`subagent-kimi: resuming via ${baseUrl ?? 'kimi default endpoint'}`);
|
|
447
485
|
let run;
|
|
448
486
|
try {
|
|
449
487
|
run = await startKimiCliRun(request, {
|
|
450
488
|
cwd,
|
|
451
|
-
env: delegationEnv({ KIMI_CODE_HOME: homeDir }),
|
|
489
|
+
env: delegationEnv({ KIMI_CODE_HOME: homeDir, ...endpointAuthEnv(endpoint) }),
|
|
452
490
|
...exec === undefined ? {} : { exec },
|
|
453
491
|
endpointLabel: baseUrl,
|
|
454
492
|
// See the fresh path: the session-level override outranks the
|
|
455
493
|
// delegation's recorded model on the exec path too.
|
|
456
|
-
...(configuration?.resolved ?? resolveRoundModel(this.memberModels?.overrideFor(intent.childSessionId) ?? requestedModel, this.model)),
|
|
494
|
+
...(configuration?.resolved ?? resolveRoundModel(this.memberModels?.overrideFor(intent.childSessionId) ?? requestedModel, () => this.model?.(scope))),
|
|
457
495
|
...configuration === undefined ? {} : { controlled: true },
|
|
458
496
|
disposeGraceMs: DEFAULT_DISPOSE_GRACE_MS,
|
|
459
497
|
spawn: spec => this.ctx.subprocess.spawn(spec),
|
|
@@ -461,9 +499,6 @@ export class KimiCliProvider {
|
|
|
461
499
|
this.ctx.logger.warn(`subagent-kimi: child run failed (${stopReason}) via ${baseUrl ?? 'kimi default endpoint'}: ${error instanceof Error ? error.message : String(error)}`);
|
|
462
500
|
},
|
|
463
501
|
onAuthFailure: (detail) => {
|
|
464
|
-
// The sentinel: an empty-shell wipe restored here makes the
|
|
465
|
-
// caller's retry (or the next round) succeed.
|
|
466
|
-
void guardKimiCredential(homeDir, message => { this.ctx.logger.warn(message); });
|
|
467
502
|
this.ctx.localAgent.reportAuthFailure('kimi', detail, scope);
|
|
468
503
|
},
|
|
469
504
|
onAuthSuccess: () => { markCredentialVerified(this.ctx, scope); },
|
|
@@ -588,8 +623,11 @@ async function mirrorKimiAfterExit(spec, stderr) {
|
|
|
588
623
|
// The round's turn selects which transcript lines the tool-call accounting
|
|
589
624
|
// belongs to — the mirror window would under-count a settle pass a live
|
|
590
625
|
// poll already drained, and over-count a resume round's earlier turns.
|
|
626
|
+
// Settle mode: calls whose result never reached the wire fold with a
|
|
627
|
+
// synthesized interrupted result instead of holding the offset forever.
|
|
591
628
|
const delta = await mirrorKimiDelta(spec.ctx, spec.childSession, spec.homeDir, kimiSessionId, {
|
|
592
629
|
turn: spec.resume?.turn ?? 1,
|
|
630
|
+
settle: true,
|
|
593
631
|
});
|
|
594
632
|
// Report the final mirrored-line count even when the live mirror already
|
|
595
633
|
// advanced the offset (empty delta): the settle report is authoritative.
|
|
@@ -783,24 +821,6 @@ export async function startKimiCliRun(request, spec) {
|
|
|
783
821
|
// or not the round is session-backed.
|
|
784
822
|
if (settled.stopReason === 'completed')
|
|
785
823
|
spec.onAuthSuccess?.();
|
|
786
|
-
// The turn closes at the real settle moment, so the timing projection's
|
|
787
|
-
// duration equals the actual CLI runtime. Every terminal path closes the
|
|
788
|
-
// window — a failed or cancelled run settles 'error'/'aborted' instead of
|
|
789
|
-
// leaving the turn open with a distorted tiny duration.
|
|
790
|
-
if (spec.childSession !== undefined) {
|
|
791
|
-
if (settled.stopReason === 'completed') {
|
|
792
|
-
spec.childSession.append('turn/end', { turn, reason: { kind: 'completed' } });
|
|
793
|
-
}
|
|
794
|
-
else if (settled.stopReason === 'aborted') {
|
|
795
|
-
spec.childSession.append('turn/end', { turn, reason: { kind: 'aborted', reason: { kind: 'parent' } } });
|
|
796
|
-
}
|
|
797
|
-
else {
|
|
798
|
-
spec.childSession.append('turn/end', {
|
|
799
|
-
turn,
|
|
800
|
-
reason: { kind: 'error', error: { message: 'kimi -p exited before the run completed', code: 'UNKNOWN' } },
|
|
801
|
-
});
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
824
|
return settled;
|
|
805
825
|
});
|
|
806
826
|
// After the child EXITS — however it ended (completed, killed by dispose, or
|
|
@@ -808,9 +828,12 @@ export async function startKimiCliRun(request, spec) {
|
|
|
808
828
|
// subagent session, so a cancelled round still preserves its partial work
|
|
809
829
|
// and real token usage instead of leaving the child blank. The mirror reads
|
|
810
830
|
// the wire file, so it only reflects what kimi flushed before the kill.
|
|
811
|
-
// Waits for the settle chain first
|
|
812
|
-
// the
|
|
813
|
-
//
|
|
831
|
+
// Waits for the settle chain first AND for the process to actually exit (so
|
|
832
|
+
// the wire file is complete) before reading it. Enqueued behind any
|
|
833
|
+
// in-flight live poll on the mirror queue. The turn closes AFTER the settle
|
|
834
|
+
// mirror, still inside the mirror queue: every mirrored step must land
|
|
835
|
+
// before turn/end — the released-log reader rejects a step outside an open
|
|
836
|
+
// turn on every cold read.
|
|
814
837
|
void result.then(() => child.done).then(() => {
|
|
815
838
|
// Auth detection runs post-exit: streams are drained by then, so a fast
|
|
816
839
|
// failure's stderr is complete (a settle-time read could race the flush).
|
|
@@ -828,24 +851,51 @@ export async function startKimiCliRun(request, spec) {
|
|
|
828
851
|
// usage into the round total, then reports the round's settled
|
|
829
852
|
// observation — the wire's model plus the round's accumulated usage.
|
|
830
853
|
enqueueMirror(async () => {
|
|
831
|
-
const settled = await
|
|
832
|
-
|
|
854
|
+
const settled = await result;
|
|
855
|
+
const mirrored = await mirrorKimiAfterExit(spec, stderr);
|
|
856
|
+
addRoundUsage(mirrored?.usage);
|
|
857
|
+
// The turn closes at the real settle moment, so the timing
|
|
858
|
+
// projection's duration equals the actual CLI runtime (plus the
|
|
859
|
+
// settle-mirror quiescence). Every terminal path closes the window —
|
|
860
|
+
// a failed or cancelled run settles 'error'/'aborted' instead of
|
|
861
|
+
// leaving the turn open with a distorted tiny duration.
|
|
862
|
+
if (spec.childSession !== undefined) {
|
|
863
|
+
if (settled.stopReason === 'completed') {
|
|
864
|
+
spec.childSession.append('turn/end', { turn, reason: { kind: 'completed' } });
|
|
865
|
+
}
|
|
866
|
+
else if (settled.stopReason === 'aborted') {
|
|
867
|
+
spec.childSession.append('turn/end', { turn, reason: { kind: 'aborted', reason: { kind: 'parent' } } });
|
|
868
|
+
}
|
|
869
|
+
else {
|
|
870
|
+
spec.childSession.append('turn/end', {
|
|
871
|
+
turn,
|
|
872
|
+
reason: { kind: 'error', error: { message: 'kimi -p exited before the run completed', code: 'UNKNOWN' } },
|
|
873
|
+
});
|
|
874
|
+
}
|
|
875
|
+
if (spec.ctx !== undefined) {
|
|
876
|
+
await persistChildSession(spec.ctx, spec.childSession).catch((error) => {
|
|
877
|
+
spec.ctx?.logger.warn(`subagent-kimi: turn/end persistence failed: ${thrown(error).message}`);
|
|
878
|
+
});
|
|
879
|
+
}
|
|
880
|
+
}
|
|
833
881
|
// The wire log names the model but never the CLI build, so the version
|
|
834
882
|
// is the executable's own answer, probed once per binary.
|
|
835
883
|
const cliVersion = await spec.cliVersion?.();
|
|
836
884
|
spec.onRoundSettled?.({
|
|
837
|
-
...
|
|
885
|
+
...mirrored?.model === undefined ? {} : { observedModel: mirrored.model },
|
|
838
886
|
...cliVersion === undefined ? {} : { cliVersion },
|
|
839
887
|
...roundUsage === undefined ? {} : { usage: roundUsage },
|
|
840
|
-
...
|
|
888
|
+
...mirrored?.toolCalls === undefined ? {} : { toolCalls: mirrored.toolCalls },
|
|
841
889
|
});
|
|
842
890
|
});
|
|
843
891
|
}, () => { });
|
|
844
892
|
return Promise.resolve(subprocessRunHandle({
|
|
845
|
-
//
|
|
846
|
-
//
|
|
847
|
-
//
|
|
848
|
-
id
|
|
893
|
+
// Host 0.2.1: the published run id is a fresh PER-EXECUTION identity —
|
|
894
|
+
// the activation manager rejects a run id naming a live Session (the
|
|
895
|
+
// mirrored child session is exactly that), and resume rounds reuse the
|
|
896
|
+
// child session id. The durable child identity the family tracks rides
|
|
897
|
+
// the staged intent instead (spec.childSession.id == its childSessionId).
|
|
898
|
+
id: SessionId(randomUUID()),
|
|
849
899
|
result,
|
|
850
900
|
signal: request.signal,
|
|
851
901
|
onAbort,
|
|
@@ -16,11 +16,14 @@
|
|
|
16
16
|
* throttled `mirrorKimiDelta` passes and the settle pass stays authoritative
|
|
17
17
|
* (one fold, one offset, zero divergence between the two drivers). Every
|
|
18
18
|
* transcript item folds 1:1 into the child session log.
|
|
19
|
-
* Live output
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
19
|
+
* Live output rides the `local-agent/stream` channel: chunk deltas
|
|
20
|
+
* accumulate per streaming item and publish throttled updates at the item's
|
|
21
|
+
* reserved (turn, step) — the member live node renders them as-is — while
|
|
22
|
+
* the item's durable content lands as ONE atomic step/start→…→step/end
|
|
23
|
+
* triple at that step, written by the completing wire line's fold or at
|
|
24
|
+
* settle. Durable steps stay dense and strictly sequential (the released-log
|
|
25
|
+
* reader validates exactly that on every cold open); snapshots never hold a
|
|
26
|
+
* step open across appends.
|
|
24
27
|
*
|
|
25
28
|
* Lifecycle mirrors the dsh/codex live drivers' discipline: lazy spawn with an
|
|
26
29
|
* initialize handshake (loadSession capability required — crash recovery is
|
|
@@ -38,6 +41,7 @@ import { type KimiNativeConfiguration } from './model-catalog.ts';
|
|
|
38
41
|
import type { Context } from '@deepseek-ai/cordis';
|
|
39
42
|
import type { Session } from '@deepseek-ai/dsh-session';
|
|
40
43
|
import { type SubagentRun, type SubagentStartRequest, type SubagentStopReason } from '@deepseek-ai/dsh-subagent';
|
|
44
|
+
import { type KimiEndpointAuth } from './endpoint-auth.ts';
|
|
41
45
|
/** Default idle lifetime of an unused resident runtime before reclaim. */
|
|
42
46
|
export declare const DEFAULT_LIVE_IDLE_MS: number;
|
|
43
47
|
/** Default timeout for a wire request acknowledgement (never for session/prompt). */
|
|
@@ -159,6 +163,14 @@ export declare class KimiAcpLiveDriver {
|
|
|
159
163
|
* retired and respawned onto the new one.
|
|
160
164
|
*/
|
|
161
165
|
model?: (childSessionId: string) => string | undefined;
|
|
166
|
+
/**
|
|
167
|
+
* Resolver for the scope's endpoint credential, read at each RUNTIME
|
|
168
|
+
* SPAWN so a settings-card write reaches the next respawn without a
|
|
169
|
+
* reload. A resolution carrying a key authenticates the runtime through
|
|
170
|
+
* the managed provider's `api_key_env` indirection (the key rides the
|
|
171
|
+
* process env; the baseUrl is pinned by the pre-spawn surgery).
|
|
172
|
+
*/
|
|
173
|
+
endpoint?: (scopeHome: string) => Promise<KimiEndpointAuth>;
|
|
162
174
|
}, timeouts?: KimiLiveDriverTimeouts);
|
|
163
175
|
/** Whether the channel is in its post-failure cooldown (rounds fall back to exec). */
|
|
164
176
|
get disabled(): boolean;
|