@khorsheed/dsh-local-agent 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 +31 -0
- package/README.en.md +23 -164
- package/README.i18n.yaml +2 -2
- package/README.md +23 -164
- package/lib/client.js +23707 -4768
- package/lib/index.js +827 -62
- package/lib/member-bridge.js +195 -25
- package/lib/tool-factory.js +52 -19
- package/lib/typert.host.js +1440 -353
- package/lib/typert.remote-client.d.ts +43 -3
- package/lib/typert.remote-client.js +973 -335
- package/lib/types/client/FamilyCard.d.ts +37 -0
- package/lib/types/client/FamilyCard.js +55 -0
- package/lib/types/client/HarnessModelPicker.d.ts +21 -1
- package/lib/types/client/HarnessModelPicker.js +31 -3
- package/lib/types/client/MemberLiveNode.js +38 -4
- package/lib/types/client/ModelListSection.d.ts +49 -0
- package/lib/types/client/ModelListSection.js +132 -0
- package/lib/types/client/ProviderAuthBlock.d.ts +10 -2
- package/lib/types/client/ProviderAuthBlock.js +13 -6
- package/lib/types/client/auth-status.d.ts +6 -0
- package/lib/types/client/auth-status.js +8 -0
- package/lib/types/client/harness-cards.d.ts +72 -0
- package/lib/types/client/harness-cards.js +57 -0
- package/lib/types/client/icons.d.ts +2 -1
- package/lib/types/client/icons.js +1 -0
- package/lib/types/client/index.d.ts +32 -7
- package/lib/types/client/index.js +66 -9
- package/lib/types/client/locales.d.ts +25 -1
- package/lib/types/client/locales.js +50 -2
- package/lib/types/client/model-directory-scope.d.ts +14 -0
- package/lib/types/client/model-directory-scope.js +20 -0
- package/lib/types/gateway.d.ts +49 -1
- package/lib/types/gateway.js +89 -0
- package/lib/types/index.d.ts +91 -38
- package/lib/types/index.js +190 -58
- package/lib/types/live-stream.d.ts +11 -0
- package/lib/types/live-stream.js +26 -0
- package/lib/types/member-bridge.d.ts +11 -1
- package/lib/types/member-bridge.js +81 -13
- package/lib/types/member-channel.d.ts +44 -1
- package/lib/types/member-channel.js +65 -2
- package/lib/types/member-controls.d.ts +8 -0
- package/lib/types/member-controls.js +15 -2
- package/lib/types/mode-skills.d.ts +18 -0
- package/lib/types/mode-skills.js +56 -0
- package/lib/types/model-list.d.ts +55 -0
- package/lib/types/model-list.js +101 -0
- package/lib/types/preset-tool-host.d.ts +70 -0
- package/lib/types/preset-tool-host.js +210 -0
- package/lib/types/tool-factory.d.ts +9 -3
- package/lib/types/tool-factory.js +55 -18
- package/lib/types/types.d.ts +62 -5
- package/package.json +27 -23
- package/lib/invariant.js +0 -85
- package/lib/types/invariant.d.ts +0 -16
- package/lib/types/invariant.js +0 -105
package/lib/types/gateway.js
CHANGED
|
@@ -82,6 +82,11 @@ let LocalAgentGateway = (() => {
|
|
|
82
82
|
let _sessions_decorators;
|
|
83
83
|
let _memberOf_decorators;
|
|
84
84
|
let _harnessModel_decorators;
|
|
85
|
+
let _checkEndpoint_decorators;
|
|
86
|
+
let _endpointAuth_decorators;
|
|
87
|
+
let _configureEndpoint_decorators;
|
|
88
|
+
let _modelList_decorators;
|
|
89
|
+
let _configureModelList_decorators;
|
|
85
90
|
let _memberModel_decorators;
|
|
86
91
|
let _setMemberModel_decorators;
|
|
87
92
|
let _memberConfiguration_decorators;
|
|
@@ -108,6 +113,11 @@ let LocalAgentGateway = (() => {
|
|
|
108
113
|
_sessions_decorators = [Remote('sessions')];
|
|
109
114
|
_memberOf_decorators = [Remote('memberOf')];
|
|
110
115
|
_harnessModel_decorators = [Remote('harnessModel')];
|
|
116
|
+
_checkEndpoint_decorators = [Remote('checkEndpoint')];
|
|
117
|
+
_endpointAuth_decorators = [Remote('endpointAuth')];
|
|
118
|
+
_configureEndpoint_decorators = [Remote('configureEndpoint')];
|
|
119
|
+
_modelList_decorators = [Remote('modelList')];
|
|
120
|
+
_configureModelList_decorators = [Remote('configureModelList')];
|
|
111
121
|
_memberModel_decorators = [Remote('memberModel')];
|
|
112
122
|
_setMemberModel_decorators = [Remote('setMemberModel')];
|
|
113
123
|
_memberConfiguration_decorators = [Remote('memberConfiguration')];
|
|
@@ -131,6 +141,11 @@ let LocalAgentGateway = (() => {
|
|
|
131
141
|
__esDecorate(this, null, _sessions_decorators, { kind: "method", name: "sessions", static: false, private: false, access: { has: obj => "sessions" in obj, get: obj => obj.sessions }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
132
142
|
__esDecorate(this, null, _memberOf_decorators, { kind: "method", name: "memberOf", static: false, private: false, access: { has: obj => "memberOf" in obj, get: obj => obj.memberOf }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
133
143
|
__esDecorate(this, null, _harnessModel_decorators, { kind: "method", name: "harnessModel", static: false, private: false, access: { has: obj => "harnessModel" in obj, get: obj => obj.harnessModel }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
144
|
+
__esDecorate(this, null, _checkEndpoint_decorators, { kind: "method", name: "checkEndpoint", static: false, private: false, access: { has: obj => "checkEndpoint" in obj, get: obj => obj.checkEndpoint }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
145
|
+
__esDecorate(this, null, _endpointAuth_decorators, { kind: "method", name: "endpointAuth", static: false, private: false, access: { has: obj => "endpointAuth" in obj, get: obj => obj.endpointAuth }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
146
|
+
__esDecorate(this, null, _configureEndpoint_decorators, { kind: "method", name: "configureEndpoint", static: false, private: false, access: { has: obj => "configureEndpoint" in obj, get: obj => obj.configureEndpoint }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
147
|
+
__esDecorate(this, null, _modelList_decorators, { kind: "method", name: "modelList", static: false, private: false, access: { has: obj => "modelList" in obj, get: obj => obj.modelList }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
148
|
+
__esDecorate(this, null, _configureModelList_decorators, { kind: "method", name: "configureModelList", static: false, private: false, access: { has: obj => "configureModelList" in obj, get: obj => obj.configureModelList }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
134
149
|
__esDecorate(this, null, _memberModel_decorators, { kind: "method", name: "memberModel", static: false, private: false, access: { has: obj => "memberModel" in obj, get: obj => obj.memberModel }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
135
150
|
__esDecorate(this, null, _setMemberModel_decorators, { kind: "method", name: "setMemberModel", static: false, private: false, access: { has: obj => "setMemberModel" in obj, get: obj => obj.setMemberModel }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
136
151
|
__esDecorate(this, null, _memberConfiguration_decorators, { kind: "method", name: "memberConfiguration", static: false, private: false, access: { has: obj => "memberConfiguration" in obj, get: obj => obj.memberConfiguration }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
@@ -330,6 +345,80 @@ let LocalAgentGateway = (() => {
|
|
|
330
345
|
? info
|
|
331
346
|
: { ...info, lastObserved: observed });
|
|
332
347
|
}
|
|
348
|
+
/**
|
|
349
|
+
* Verify one harness's saved endpoint from the host — the settings card's
|
|
350
|
+
* verify button. The answer is the harness's human-readable verdict text.
|
|
351
|
+
* Session-less by design: the commands channel needs a main agent session,
|
|
352
|
+
* which a settings card may not have. Null when the harness is unknown or
|
|
353
|
+
* declares no probe (the card then hides the button — declare-and-degrade).
|
|
354
|
+
* @param name - the harness name.
|
|
355
|
+
* @returns the verdict text, or null.
|
|
356
|
+
*/
|
|
357
|
+
async checkEndpoint(name) {
|
|
358
|
+
const harness = this.ctx.localAgent.get(name);
|
|
359
|
+
if (typeof harness?.checkEndpoint !== 'function')
|
|
360
|
+
return null;
|
|
361
|
+
return harness.checkEndpoint(this.ctx.localAgent.homeDir(name));
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* The settings card's read of one harness's resolved endpoint state —
|
|
365
|
+
* baseUrl verbatim, credentials as presence booleans (secrets never cross).
|
|
366
|
+
* Session-less like the rest of the gateway. Null when the harness is
|
|
367
|
+
* unknown or declares no endpoint face (the card then hides the form).
|
|
368
|
+
* @param name - the harness name.
|
|
369
|
+
* @returns the resolved per-field state, or null.
|
|
370
|
+
*/
|
|
371
|
+
async endpointAuth(name) {
|
|
372
|
+
const harness = this.ctx.localAgent.get(name);
|
|
373
|
+
if (harness?.endpointAuth === undefined)
|
|
374
|
+
return null;
|
|
375
|
+
return harness.endpointAuth.read(this.ctx.localAgent.homeDir(name));
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Apply one endpoint-credential edit into the harness's own credential
|
|
379
|
+
* store (a string sets, null clears, absent leaves), answering the
|
|
380
|
+
* post-write resolved state so the card can flip immediately. The write
|
|
381
|
+
* deliberately bypasses the volatile row-config channel — a credential
|
|
382
|
+
* never lands in the profile patch document. Null when the harness is
|
|
383
|
+
* unknown or declares no endpoint face.
|
|
384
|
+
* @param name - the harness name.
|
|
385
|
+
* @param fields - the field edits.
|
|
386
|
+
* @returns the post-write resolved state, or null.
|
|
387
|
+
*/
|
|
388
|
+
async configureEndpoint(name, fields) {
|
|
389
|
+
const harness = this.ctx.localAgent.get(name);
|
|
390
|
+
if (harness?.endpointAuth === undefined)
|
|
391
|
+
return null;
|
|
392
|
+
await harness.endpointAuth.write(this.ctx.localAgent.homeDir(name), fields);
|
|
393
|
+
return harness.endpointAuth.read(this.ctx.localAgent.homeDir(name));
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* The settings card's read of one harness's curated model list — ordered
|
|
397
|
+
* identifiers, first is the default. Null when the harness is unknown or
|
|
398
|
+
* declares no list face (the card then hides the editor).
|
|
399
|
+
* @param name - the harness name.
|
|
400
|
+
* @returns the ordered list, or null.
|
|
401
|
+
*/
|
|
402
|
+
async modelList(name) {
|
|
403
|
+
const harness = this.ctx.localAgent.get(name);
|
|
404
|
+
if (harness?.modelList === undefined)
|
|
405
|
+
return null;
|
|
406
|
+
return harness.modelList.read(this.ctx.localAgent.homeDir(name));
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Replace one harness's curated model list wholesale (reorders, removals
|
|
410
|
+
* and additions all ride the same write), answering the list as persisted.
|
|
411
|
+
* Null when the harness is unknown or declares no list face.
|
|
412
|
+
* @param name - the harness name.
|
|
413
|
+
* @param models - the new ordered list.
|
|
414
|
+
* @returns the persisted list, or null.
|
|
415
|
+
*/
|
|
416
|
+
async configureModelList(name, models) {
|
|
417
|
+
const harness = this.ctx.localAgent.get(name);
|
|
418
|
+
if (harness?.modelList === undefined)
|
|
419
|
+
return null;
|
|
420
|
+
return harness.modelList.write(this.ctx.localAgent.homeDir(name), models);
|
|
421
|
+
}
|
|
333
422
|
/**
|
|
334
423
|
* The model surface of one member — the composer's picker read. The
|
|
335
424
|
* delegation record's requested model rides in from the core so the broker
|
package/lib/types/index.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ import type { CommandInvocation, CommandResult } from '@deepseek-ai/dsh-commands
|
|
|
22
22
|
import type { ContentBlock, TokenUsage } from '@deepseek-ai/dsh-llm';
|
|
23
23
|
import type { Session, SessionHeader } from '@deepseek-ai/dsh-session';
|
|
24
24
|
import type { SubagentRun } from '@deepseek-ai/dsh-subagent';
|
|
25
|
-
import type { DelegationCallOptions, LocalAgentDelegationInfo, LocalAgentDelegationIntent, LocalAgentDelegationRecord, LocalAgentEffectiveSettings, LocalAgentMemberRun, LocalAgentModelBroker, LocalAgentMemberBinding, LocalAgentMemberControlState, LocalAgentMemberInbox, LocalAgentMemberConfiguration, LocalAgentControlReceipt, LocalAgentAppliedConfiguration, LocalAgentRosterRow, LocalAgentRunProgress, LocalAgentSessionRecord, LocalAgentStatus, LocalAgentToolCalls } from './types.ts';
|
|
25
|
+
import type { DelegationCallOptions, LocalAgentDelegationInfo, LocalAgentDelegationIntent, LocalAgentDelegationRecord, LocalAgentEffectiveSettings, LocalAgentEndpointAuthFields, LocalAgentEndpointAuthState, LocalAgentMemberRun, LocalAgentModelBroker, LocalAgentMemberBinding, LocalAgentMemberControlState, LocalAgentMemberInbox, LocalAgentMemberConfiguration, LocalAgentControlReceipt, LocalAgentAppliedConfiguration, LocalAgentRosterRow, LocalAgentRunProgress, LocalAgentSessionRecord, LocalAgentStatus, LocalAgentToolCalls } from './types.ts';
|
|
26
26
|
import { MemberInbox } from './member-inbox.ts';
|
|
27
27
|
/** Stable Cordis plugin name. */
|
|
28
28
|
export declare const name = "local-agent";
|
|
@@ -33,6 +33,7 @@ export type { DelegationCallOptions, LocalAgentCredentialState, DelegationExecTa
|
|
|
33
33
|
export type { LocalAgentMemberMessage, MemberMessageOutcome, RoomMemberMessageGate, RoomMemberMessageReceipt, } from './types.ts';
|
|
34
34
|
export { delegationEnv } from './env.ts';
|
|
35
35
|
export { ModelDirectoryCache, extendModelDirectory, modelDirectoryContextKey } from './model-directory.ts';
|
|
36
|
+
export { MODEL_LIST_FILE, firstModelOf, normalizeModelList, readModelList, readModelListSync, writeModelList } from './model-list.ts';
|
|
36
37
|
export { MemberConfigurationController } from './member-control.ts';
|
|
37
38
|
export type { MemberConfigurationAdapter, MemberControlStorage, MemberControlRecord } from './member-control.ts';
|
|
38
39
|
export { FileMemberControlStorage } from './member-control-storage.ts';
|
|
@@ -229,9 +230,7 @@ export interface LocalAgentHarness {
|
|
|
229
230
|
homeEnvVar: string;
|
|
230
231
|
/**
|
|
231
232
|
* Subagent provider name this harness delegates through, when it has one.
|
|
232
|
-
* A harness without delegation is record-and-login only.
|
|
233
|
-
* cross-checks this against the mounted subagent providers, so a record
|
|
234
|
-
* that names a provider the composition does not mount fails loud.
|
|
233
|
+
* A harness without delegation is record-and-login only.
|
|
235
234
|
*/
|
|
236
235
|
delegationProvider?: string;
|
|
237
236
|
/**
|
|
@@ -275,6 +274,39 @@ export interface LocalAgentHarness {
|
|
|
275
274
|
*/
|
|
276
275
|
isAuthenticated?: (homeDir: string) => Promise<boolean>;
|
|
277
276
|
/**
|
|
277
|
+
* Optional host-side endpoint verification (the settings card's verify
|
|
278
|
+
* button): a cheap, token-free probe of the SAVED endpoint configuration,
|
|
279
|
+
* answered as human-readable verdict text. It rides the session-less
|
|
280
|
+
* gateway Remote (`checkEndpoint`) because a settings card may have no
|
|
281
|
+
* main agent session to run a slash command through. Absent means the
|
|
282
|
+
* harness has no such probe and the card must not offer the button.
|
|
283
|
+
*/
|
|
284
|
+
checkEndpoint?: (homeDir: string) => Promise<string>;
|
|
285
|
+
/**
|
|
286
|
+
* Optional endpoint-credential face for the settings card: a read of the
|
|
287
|
+
* resolved per-field state (secrets as booleans, never echoed) and a write
|
|
288
|
+
* that applies edits into the harness's OWN credential store. The card
|
|
289
|
+
* talks to it through the session-less gateway Remotes
|
|
290
|
+
* (`endpointAuth`/`configureEndpoint`) instead of the volatile row-config
|
|
291
|
+
* channel — a credential never belongs in the profile patch document, and
|
|
292
|
+
* that channel rejects writes a deployment cannot explain. Absent means
|
|
293
|
+
* the card renders no endpoint form.
|
|
294
|
+
*/
|
|
295
|
+
endpointAuth?: {
|
|
296
|
+
read(homeDir: string): Promise<LocalAgentEndpointAuthState>;
|
|
297
|
+
write(homeDir: string, fields: LocalAgentEndpointAuthFields): Promise<void>;
|
|
298
|
+
};
|
|
299
|
+
/**
|
|
300
|
+
* Optional curated model-list face: an ORDERED list of model identifiers
|
|
301
|
+
* the harness persists in its own store (its first entry is the harness's
|
|
302
|
+
* default model). The settings card edits it through the session-less
|
|
303
|
+
* `modelList`/`configureModelList` gateway Remotes. Absent means the card
|
|
304
|
+
* renders no model-list editor.
|
|
305
|
+
*/
|
|
306
|
+
modelList?: {
|
|
307
|
+
read(homeDir: string): Promise<readonly string[]>;
|
|
308
|
+
write(homeDir: string, models: readonly string[]): Promise<readonly string[]>;
|
|
309
|
+
}; /**
|
|
278
310
|
* The credential marker's modification stamp (epoch ms), undefined when no
|
|
279
311
|
* credential exists. Two consumers: the manual-login watch requires a stamp
|
|
280
312
|
* NEWER than the watch start (a stale marker must not read as a fresh
|
|
@@ -616,9 +648,9 @@ export declare class LocalAgentRegistry {
|
|
|
616
648
|
/**
|
|
617
649
|
* Per-(parent session, provider) FIFO of delegation intents. The family
|
|
618
650
|
* resume tool stages exactly one intent per call before awaiting
|
|
619
|
-
* `ctx.subagents.
|
|
620
|
-
* start, so fresh and resume rounds stay paired even under
|
|
621
|
-
* delegations from one parent.
|
|
651
|
+
* `ctx.subagents.startActivation()`, and the owning provider consumes
|
|
652
|
+
* exactly one per start, so fresh and resume rounds stay paired even under
|
|
653
|
+
* parallel delegations from one parent.
|
|
622
654
|
*/
|
|
623
655
|
private readonly delegationIntents;
|
|
624
656
|
/**
|
|
@@ -671,10 +703,12 @@ export declare class LocalAgentRegistry {
|
|
|
671
703
|
* - **facade-tracked** ({@link trackRun}): runs started through
|
|
672
704
|
* {@link LocalAgentRegistry.start} / {@link LocalAgentRegistry.resume},
|
|
673
705
|
* carrying the fused AbortController whose signal reached
|
|
674
|
-
* `ctx.subagents.
|
|
706
|
+
* `ctx.subagents.startActivation`; cancel aborts the pre-publication
|
|
707
|
+
* signal and disposes the published activation.
|
|
675
708
|
* - **tool-registered** ({@link trackDelegationRun}): runs the family tool
|
|
676
|
-
* starts directly through `ctx.subagents.
|
|
677
|
-
* cancel lever (its fused controller
|
|
709
|
+
* starts directly through `ctx.subagents.startActivation`, carrying an
|
|
710
|
+
* explicit cancel lever (its fused controller plus the activation's
|
|
711
|
+
* dispose); cancel calls it.
|
|
678
712
|
*
|
|
679
713
|
* Every entry clears itself when the run's result settles (any stop
|
|
680
714
|
* reason), and facade entries also stop their heartbeat timer then.
|
|
@@ -917,9 +951,10 @@ export declare class LocalAgentRegistry {
|
|
|
917
951
|
/**
|
|
918
952
|
* Stage one delegation intent for a provider's next `start()`. The family
|
|
919
953
|
* resume tool stages exactly one intent per call before awaiting
|
|
920
|
-
* `ctx.subagents.
|
|
921
|
-
* {@link takeDelegationIntent}, so the per-(parent, provider)
|
|
922
|
-
* fresh and resume rounds even under parallel delegations from
|
|
954
|
+
* `ctx.subagents.startActivation()`; the provider consumes exactly one per
|
|
955
|
+
* start via {@link takeDelegationIntent}, so the per-(parent, provider)
|
|
956
|
+
* FIFO pairs fresh and resume rounds even under parallel delegations from
|
|
957
|
+
* one parent.
|
|
923
958
|
* @param parentSessionId - the delegating parent session id.
|
|
924
959
|
* @param provider - the `ctx.subagents` provider name.
|
|
925
960
|
* @param intent - the fresh or resume intent for the next start.
|
|
@@ -936,7 +971,7 @@ export declare class LocalAgentRegistry {
|
|
|
936
971
|
takeDelegationIntent(parentSessionId: string, provider: string): LocalAgentDelegationIntent | undefined;
|
|
937
972
|
/**
|
|
938
973
|
* Remove one previously staged intent by reference, returning whether it was
|
|
939
|
-
* still queued. The delegation facade calls this when `ctx.subagents.
|
|
974
|
+
* still queued. The delegation facade calls this when `ctx.subagents.startActivation()`
|
|
940
975
|
* throws: an intent the provider never consumed must not linger in the FIFO,
|
|
941
976
|
* where the NEXT same-(parent, provider) start would misconsume it as its own
|
|
942
977
|
* (orphan-intent crosstalk). When the provider already consumed the intent
|
|
@@ -950,9 +985,7 @@ export declare class LocalAgentRegistry {
|
|
|
950
985
|
*/
|
|
951
986
|
unstageDelegationIntent(parentSessionId: string, provider: string, intent: LocalAgentDelegationIntent): boolean;
|
|
952
987
|
/**
|
|
953
|
-
* Every recorded delegation, in recording order.
|
|
954
|
-
* cross-checks each record's provider against the mounted subagent
|
|
955
|
-
* providers so a provider rename cannot leave a stale resume mapping.
|
|
988
|
+
* Every recorded delegation, in recording order.
|
|
956
989
|
* @returns the recorded delegations.
|
|
957
990
|
*/
|
|
958
991
|
listDelegations(): readonly LocalAgentDelegationRecord[];
|
|
@@ -1107,7 +1140,9 @@ export declare class LocalAgentRegistry {
|
|
|
1107
1140
|
* {@link unstageDelegationIntent} (a no-op once the provider consumed it).
|
|
1108
1141
|
*
|
|
1109
1142
|
* The returned run is tracked under its `run.id` (== the new dsh child
|
|
1110
|
-
* session id
|
|
1143
|
+
* session id, minted here and carried to the provider through the staged
|
|
1144
|
+
* intent — host 0.2.1's `startActivation` never surfaces it on the
|
|
1145
|
+
* activation) until `run.result` settles; {@link cancel} aborts it by that
|
|
1111
1146
|
* id. Note on trust: cordis plugins share one process, so the ownership
|
|
1112
1147
|
* checks here and in {@link resume} guard against caller MISTAKES, not
|
|
1113
1148
|
* against a malicious plugin — their real protection target is untrusted
|
|
@@ -1137,12 +1172,12 @@ export declare class LocalAgentRegistry {
|
|
|
1137
1172
|
* without staging; the provider still takes the authoritative lock inside
|
|
1138
1173
|
* its `start()`;
|
|
1139
1174
|
* 4. live parent agent resolution (`ctx.agents.get`) — a harness hard
|
|
1140
|
-
* constraint, since `ctx.subagents.
|
|
1175
|
+
* constraint, since `ctx.subagents.startActivation` requires a live parent;
|
|
1141
1176
|
* 5. child-session REATTACH when `ctx.sessions.get(childSessionId)` is
|
|
1142
1177
|
* undefined (recipe below; `opts.reattach === false` disables this step
|
|
1143
1178
|
* and fails loud on a non-live child instead);
|
|
1144
1179
|
* 6. stage `{ kind: 'resume', childSessionId, cliSessionId }` and, in the
|
|
1145
|
-
* same synchronous flow, `await ctx.subagents.
|
|
1180
|
+
* same synchronous flow, `await ctx.subagents.startActivation({…})`;
|
|
1146
1181
|
* 7. on start failure, roll the intent back via
|
|
1147
1182
|
* {@link unstageDelegationIntent} (no-op once consumed);
|
|
1148
1183
|
* 8. on success, track the run under `childSessionId` for {@link cancel}
|
|
@@ -1155,8 +1190,12 @@ export declare class LocalAgentRegistry {
|
|
|
1155
1190
|
* const handle = await ctx.sessionPersistence.open(SessionId(childSessionId), 'write')
|
|
1156
1191
|
* try {
|
|
1157
1192
|
* const cold = await handle.read(0)
|
|
1193
|
+
* // Close a turn a restart interrupted, or the next round's turn/start
|
|
1194
|
+
* // makes the stored log unreadable.
|
|
1195
|
+
* const closers = interruptedTurnClosers(cold.events)
|
|
1196
|
+
* if (closers.length > 0) await handle.append(closers)
|
|
1158
1197
|
* const session = ctx.sessions.prepare(SessionId(childSessionId), {
|
|
1159
|
-
* seed: [...cold.events],
|
|
1198
|
+
* seed: [...cold.events, ...closers],
|
|
1160
1199
|
* meta: structuredClone(handle.header),
|
|
1161
1200
|
* inheritedEventCount: handle.inheritedEventCount,
|
|
1162
1201
|
* eventState: cold.eventState,
|
|
@@ -1164,7 +1203,7 @@ export declare class LocalAgentRegistry {
|
|
|
1164
1203
|
* // The seeded constructor's session/end-seed marker lands before enter()
|
|
1165
1204
|
* // installs publication hooks — push the unstored suffix through the
|
|
1166
1205
|
* // handle directly, or the writer's contiguous cursor diverges.
|
|
1167
|
-
* const unstored = session.snapshotEvents().slice(cold.events.length)
|
|
1206
|
+
* const unstored = session.snapshotEvents().slice(cold.events.length + closers.length)
|
|
1168
1207
|
* if (unstored.length > 0) await handle.append(unstored)
|
|
1169
1208
|
* const detach = ctx.sessions.enter(session)
|
|
1170
1209
|
* try { ctx.sessions.announce(session) }
|
|
@@ -1196,11 +1235,12 @@ export declare class LocalAgentRegistry {
|
|
|
1196
1235
|
*/
|
|
1197
1236
|
resume(parentSessionId: string, provider: string, childSessionId: string, prompt: ContentBlock[], options?: DelegationCallOptions): Promise<SubagentRun>;
|
|
1198
1237
|
/**
|
|
1199
|
-
* Cancel an in-flight facade-started run by its dsh child session id:
|
|
1200
|
-
* the internal controller
|
|
1201
|
-
*
|
|
1202
|
-
*
|
|
1203
|
-
* reason. A caller holding the `SubagentRun` may also
|
|
1238
|
+
* Cancel an in-flight facade-started run by its dsh child session id:
|
|
1239
|
+
* aborts the internal controller (the pre-publication channel fused into
|
|
1240
|
+
* the activation's start signal) and disposes the activation — host 0.2.1's
|
|
1241
|
+
* canonical POST-publication cancellation, which settles the run with an
|
|
1242
|
+
* `aborted`-class stop reason. A caller holding the `SubagentRun` may also
|
|
1243
|
+
* `run.dispose()`.
|
|
1204
1244
|
* @param childSessionId - the dsh child session id of the run to cancel.
|
|
1205
1245
|
* @returns whether an in-flight run was found and signalled (false on a
|
|
1206
1246
|
* miss — never a silent success, never a throw).
|
|
@@ -1210,16 +1250,17 @@ export declare class LocalAgentRegistry {
|
|
|
1210
1250
|
* Register a NON-facade in-flight delegation run with the active-delegation
|
|
1211
1251
|
* registry, keyed by the dsh child session id, so the `/local-agent stop`
|
|
1212
1252
|
* command and {@link cancel} can reach it. This is the family TOOL's entry
|
|
1213
|
-
* point: the tool starts its runs through `ctx.subagents.
|
|
1214
|
-
* (not the facade), so without this registration its in-flight
|
|
1215
|
-
* be invisible to the stop command. The caller owns the cancel
|
|
1216
|
-
*
|
|
1217
|
-
*
|
|
1218
|
-
* result settles (any stop reason); an
|
|
1219
|
-
* child session wins (it already owns
|
|
1220
|
-
*
|
|
1221
|
-
* @param
|
|
1222
|
-
* @param
|
|
1253
|
+
* point: the tool starts its runs through `ctx.subagents.startActivation`
|
|
1254
|
+
* directly (not the facade), so without this registration its in-flight
|
|
1255
|
+
* runs would be invisible to the stop command. The caller owns the cancel
|
|
1256
|
+
* lever — aborting the fused controller (pre-publication) and disposing the
|
|
1257
|
+
* activation (post-publication), the same channels the facade drives. The
|
|
1258
|
+
* entry clears itself when the run's result settles (any stop reason); an
|
|
1259
|
+
* existing facade entry for the same child session wins (it already owns
|
|
1260
|
+
* cancellation and progress).
|
|
1261
|
+
* @param childSessionId - the dsh child session id.
|
|
1262
|
+
* @param run - the published subagent run (the tool's activation adapter).
|
|
1263
|
+
* @param cancel - the lever that cancels the run.
|
|
1223
1264
|
*/
|
|
1224
1265
|
trackDelegationRun(childSessionId: string, run: SubagentRun, cancel: () => void): void;
|
|
1225
1266
|
/**
|
|
@@ -1267,7 +1308,7 @@ export declare class LocalAgentRegistry {
|
|
|
1267
1308
|
* from persistence when it is not — a host restart evicts every child from
|
|
1268
1309
|
* the live store. This is the public entry of the facade resume's reattach
|
|
1269
1310
|
* recipe for callers that start resume rounds WITHOUT the facade (the
|
|
1270
|
-
* family subagent tool starts runs directly through `ctx.subagents.
|
|
1311
|
+
* family subagent tool starts runs directly through `ctx.subagents.startActivation`;
|
|
1271
1312
|
* without this call the provider refuses the resume as "not live").
|
|
1272
1313
|
* Idempotent; a child that was never persisted fails through the
|
|
1273
1314
|
* persistence layer's own not-found error.
|
|
@@ -1299,6 +1340,18 @@ export declare class LocalAgentRegistry {
|
|
|
1299
1340
|
* @param session - the live child session to sync.
|
|
1300
1341
|
*/
|
|
1301
1342
|
syncChildSession(session: Session, strict?: boolean): Promise<void>;
|
|
1343
|
+
/**
|
|
1344
|
+
* One sync pass. While the write handle is open the host routes every live
|
|
1345
|
+
* append into the writer's buffer, so the routed events are drained first
|
|
1346
|
+
* (`sessions.flush`: drain + flush) and only what is STILL missing — events
|
|
1347
|
+
* from before the handle opened, or a host that routes nothing — goes in
|
|
1348
|
+
* explicitly, bounded to the events that existed before the drain. Appending
|
|
1349
|
+
* routed-but-undrained events explicitly as well would land them twice: the
|
|
1350
|
+
* explicit write wins, the buffered copy then fails contiguity forever, and
|
|
1351
|
+
* every later flush — the host's tool-execution checkpoint included —
|
|
1352
|
+
* throws "append seq mismatch".
|
|
1353
|
+
*/
|
|
1354
|
+
private syncChildSessionOnce;
|
|
1302
1355
|
/**
|
|
1303
1356
|
* Get or open the child session's registry-owned WRITE handle (the
|
|
1304
1357
|
* {@link childWriteHandles} cache). When the caller carries the session
|