@deepseek-ai/dsh-api-session-controller 0.1.6-alpha.2 → 0.1.7-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.i18n.yaml +2 -2
- package/README.md +31 -8
- package/README.zh.md +31 -8
- package/lib/client.js +603 -515
- package/lib/index.js +299 -137
- package/lib/typert.host.js +373 -183
- package/lib/typert.remote-client.d.ts +10 -5
- package/lib/typert.remote-client.js +216 -124
- package/lib/types/archived-session-gate.d.ts +30 -0
- package/lib/types/archived-session-gate.js +52 -0
- package/lib/types/client/contract/session.d.ts +2 -0
- package/lib/types/client/contract/sessions.d.ts +11 -16
- package/lib/types/client/index.d.ts +1 -1
- package/lib/types/client/sessions/lineage.d.ts +4 -1
- package/lib/types/client/sessions/lineage.js +2 -1
- package/lib/types/client/sessions/manager.d.ts +66 -59
- package/lib/types/client/sessions/manager.js +249 -277
- package/lib/types/client/sessions/projection-store.d.ts +32 -13
- package/lib/types/client/sessions/projection-store.js +45 -13
- package/lib/types/client/sessions/remotes.d.ts +1 -2
- package/lib/types/client/sessions/service.d.ts +23 -35
- package/lib/types/client/sessions/service.js +35 -47
- package/lib/types/client/sessions/session.d.ts +18 -16
- package/lib/types/client/sessions/session.js +112 -50
- package/lib/types/commands.d.ts +4 -2
- package/lib/types/commands.js +72 -36
- package/lib/types/control.d.ts +2 -4
- package/lib/types/control.js +2 -44
- package/lib/types/history.js +1 -1
- package/lib/types/index.d.ts +32 -5
- package/lib/types/index.js +117 -13
- package/lib/types/list.js +24 -15
- package/lib/types/skill-catalog.js +60 -50
- package/lib/types/types.d.ts +37 -23
- package/lib/types/types.js +0 -1
- package/package.json +71 -76
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The controller's admission gate for archived Sessions: an archived
|
|
3
|
+
* Session, or a subagent descendant of one, must not run a model step until
|
|
4
|
+
* it is restored. The work a Session still runs is reported and stopped by
|
|
5
|
+
* its owners — the Agent registry (`turn`), the job registry seam (`job`),
|
|
6
|
+
* the Subagent runtime (`subagent`), and the Schedule plugin (`schedule`) —
|
|
7
|
+
* through the Workspace registry's archive-admission events.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* The gate as a plugin for `ctx.plugin(...)`: it loads once the Agent
|
|
11
|
+
* registry, Session store, and Workspace registry are available and unwinds
|
|
12
|
+
* with the plugin's fiber. A late waking delivery to an archived Session — a
|
|
13
|
+
* subagent settlement, a queued follow-up — proposes a step the gate rejects,
|
|
14
|
+
* which the loop ends as `blocked` without a request; unarchiving lifts the
|
|
15
|
+
* gate for the whole lineage.
|
|
16
|
+
*/
|
|
17
|
+
export const ArchivedSessionGate = {
|
|
18
|
+
name: 'archived-session-gate',
|
|
19
|
+
inject: ['agents', 'sessions', 'workspaceRegistry'],
|
|
20
|
+
apply(ctx) {
|
|
21
|
+
ctx.on('agent/pre-step', (payload, next) => underArchivedSession(ctx, payload.agent)
|
|
22
|
+
? Promise.resolve({ kind: 'reject' })
|
|
23
|
+
: next());
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Whether the Agent's Session, or a Session above it in its subagent lineage,
|
|
28
|
+
* is archived. Lineage follows the durable header fields through
|
|
29
|
+
* subagent-origin Sessions only: a fork of an archived Session is an
|
|
30
|
+
* independent conversation.
|
|
31
|
+
* @param ctx - Host context.
|
|
32
|
+
* @param agent - the Agent proposing a step.
|
|
33
|
+
* @returns whether an archived Session owns the step.
|
|
34
|
+
*/
|
|
35
|
+
export function underArchivedSession(ctx, agent) {
|
|
36
|
+
const archived = ctx.workspaceRegistry.archivedSessionIds;
|
|
37
|
+
let header = agent.session.header;
|
|
38
|
+
const visited = new Set();
|
|
39
|
+
while (!visited.has(header.id)) {
|
|
40
|
+
if (archived.includes(header.id))
|
|
41
|
+
return true;
|
|
42
|
+
visited.add(header.id);
|
|
43
|
+
if (header.origin !== 'subagent' || header.parentSession === undefined)
|
|
44
|
+
return false;
|
|
45
|
+
const parent = ctx.sessions.get(header.parentSession);
|
|
46
|
+
if (parent === undefined)
|
|
47
|
+
return archived.includes(header.parentSession);
|
|
48
|
+
header = parent.header;
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=archived-session-gate.js.map
|
|
@@ -127,6 +127,8 @@ export interface ISession {
|
|
|
127
127
|
* turn-jump loader. Repeated calls while a jump is paging lower its shared
|
|
128
128
|
* target and return the in-flight completion; `snapshot.loadingOlder` is
|
|
129
129
|
* the busy signal for the whole jump.
|
|
130
|
+
* Older pages publish together at completion, including successful pages
|
|
131
|
+
* before a later failure; live events remain independently visible.
|
|
130
132
|
* @param seq - durable event seq the window must reach (a turn's `turn/start` seq).
|
|
131
133
|
* @returns completion once covered, exhausted, superseded, or failed soft.
|
|
132
134
|
*/
|
|
@@ -85,21 +85,15 @@ export interface ISessions {
|
|
|
85
85
|
/**
|
|
86
86
|
* Resolve an already discovered direct-parent address without opening it.
|
|
87
87
|
* @param id - possible addressed child id.
|
|
88
|
-
* @returns
|
|
88
|
+
* @returns a retained or loaded-catalog address, without retaining a new selection or scope.
|
|
89
89
|
*/
|
|
90
90
|
subagentAddress(id: SessionId): SubagentAddress | undefined;
|
|
91
91
|
/**
|
|
92
|
-
*
|
|
93
|
-
* @param
|
|
94
|
-
* @param open - current menu state.
|
|
95
|
-
*/
|
|
96
|
-
setSubagentCatalogOpen(parentSessionId: SessionId, open: boolean): void;
|
|
97
|
-
/**
|
|
98
|
-
* Refresh one direct-child catalog.
|
|
99
|
-
* @param parentSessionId - catalog owner.
|
|
92
|
+
* Load all Session projections once per connection; retry an unsuccessful initial read.
|
|
93
|
+
* @param sessionId - Session to inspect without opening its conversation.
|
|
100
94
|
* @returns completion of the current or newly started refresh.
|
|
101
95
|
*/
|
|
102
|
-
|
|
96
|
+
refreshProjections(sessionId: SessionId): Promise<void>;
|
|
103
97
|
/**
|
|
104
98
|
* Refresh the Host-authoritative Session list.
|
|
105
99
|
* @returns completion of the current or newly started Session-list refresh.
|
|
@@ -117,12 +111,13 @@ export interface ISessions {
|
|
|
117
111
|
hasMore: boolean;
|
|
118
112
|
}>>;
|
|
119
113
|
/**
|
|
120
|
-
* Fork a session from
|
|
121
|
-
* the child is
|
|
122
|
-
* @param opts - source session id, the optional
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
* and whether to increment an
|
|
114
|
+
* Fork a session from an exact inclusive prefix of the source; on
|
|
115
|
+
* resolution the child is catalogued and can be explicitly retained.
|
|
116
|
+
* @param opts - source session id, the optional exact inclusive boundary
|
|
117
|
+
* seq (a real event seq the caller already knows; a cut inside an open
|
|
118
|
+
* turn is balanced Host-side with synthetic closers, and omission selects
|
|
119
|
+
* the latest completed-turn prefix), and whether to increment an
|
|
120
|
+
* inherited durable title before resolving.
|
|
126
121
|
* @returns the child session id.
|
|
127
122
|
* @throws when the fork fails, or when a requested child-title rename fails after creation.
|
|
128
123
|
*/
|
|
@@ -6,7 +6,7 @@ export { createScope, scopeOf } from './scope.ts';
|
|
|
6
6
|
export type { AgentContext, AgentScopeHandle } from './scope.ts';
|
|
7
7
|
export { SessionCreateError, SessionForkError } from './sessions/service.ts';
|
|
8
8
|
export type { SessionBinding, SessionListState, SessionSummary } from './sessions/service.ts';
|
|
9
|
-
export type { SessionListPhase, SessionListSnapshot, SessionSearchResultItem,
|
|
9
|
+
export type { SessionListPhase, SessionListSnapshot, SessionSearchResultItem, SessionProjectionSnapshot, } from './sessions/manager.ts';
|
|
10
10
|
export type { Session } from './sessions/session.ts';
|
|
11
11
|
export type { ProjectionsBaseline, ProjectionValueStore, SessionProjectionMap, UseProjection, } from './sessions/projection-store.ts';
|
|
12
12
|
export type { BeginSubmissionInput, ISession, PendingSubmissionRetirement, ProjectionsFace, SessionFace, SubmissionHandle, } from './contract/session.ts';
|
|
@@ -13,7 +13,10 @@ export interface SessionListEntry {
|
|
|
13
13
|
title?: string;
|
|
14
14
|
updatedAt: number;
|
|
15
15
|
running: boolean;
|
|
16
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* New Session presentation and reuse eligibility, reconciled with
|
|
18
|
+
* `sessionListMetadata`; lists hide blank sessions (filtering stays with the consumer).
|
|
19
|
+
*/
|
|
17
20
|
blank: boolean;
|
|
18
21
|
parentSessionId?: SessionId;
|
|
19
22
|
/** Coarse durable origin for navigation filtering; not a continuation capability. */
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/** Host catalog, durable projection caches, and explicitly retained Client instances. */
|
|
2
|
-
import type { SubagentAddress
|
|
2
|
+
import type { SubagentAddress } from '@deepseek-ai/dsh-subagent/client';
|
|
3
3
|
import { SessionSeq, type SessionId } from '@deepseek-ai/dsh-session/types';
|
|
4
4
|
import type { SessionProjectionMap } from '@deepseek-ai/dsh-session-projection/types';
|
|
5
5
|
import type { WorkspaceId } from '@deepseek-ai/dsh-workspace/types';
|
|
6
|
-
import type { SessionControlFrame,
|
|
6
|
+
import type { SessionControlFrame, SessionRenameValue, SessionSummary } from '../../types.ts';
|
|
7
7
|
import type { RemoteFailure, RemoteResult } from '@deepseek-ai/dsh-typert-protocol';
|
|
8
8
|
import type { SessionListEntry } from './lineage.ts';
|
|
9
9
|
import { Session } from './session.ts';
|
|
@@ -30,23 +30,29 @@ export interface SessionListSnapshot {
|
|
|
30
30
|
/** Arrival lifecycle (see {@link SessionListPhase}); `state` stays the pull-activity axis. */
|
|
31
31
|
phase: SessionListPhase;
|
|
32
32
|
error: RemoteFailure | null;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
projectionsBySession: Readonly<Record<SessionId, SessionProjectionSnapshot>>;
|
|
34
|
+
}
|
|
35
|
+
/** Shared projection values and the lifecycle of their explicit baseline read. */
|
|
36
|
+
export interface SessionProjectionSnapshot {
|
|
37
|
+
readonly values: Readonly<Partial<SessionProjectionMap>>;
|
|
38
|
+
readonly state: 'idle' | 'loading' | 'ready' | 'error';
|
|
39
|
+
readonly error: RemoteFailure | null;
|
|
36
40
|
}
|
|
37
|
-
/** One parent-addressed durable catalog projected through the sessions snapshot. */
|
|
38
|
-
export type SubagentCatalogSnapshot = Omit<SubagentCatalog, 'parentAvailable'> & {
|
|
39
|
-
/** Absent until the first successful catalog read. */
|
|
40
|
-
readonly parentAvailable?: boolean;
|
|
41
|
-
state: 'loading' | 'ready' | 'error';
|
|
42
|
-
error: RemoteFailure | null;
|
|
43
|
-
};
|
|
44
41
|
/** Instance cluster + frame entry + the session list. */
|
|
45
42
|
export declare class SessionManager {
|
|
46
43
|
private readonly remote;
|
|
47
44
|
private readonly sessions;
|
|
48
45
|
/** In-flight Session disposals remain here after instances leave `sessions`, so manager disposal can await quiescence. */
|
|
49
46
|
private readonly sessionDisposals;
|
|
47
|
+
/**
|
|
48
|
+
* Accepted/running presentation must survive a later empty-history list
|
|
49
|
+
* response. Host-asserted running is recorded even before a row, instance, or
|
|
50
|
+
* address holds the identity — the listing that would hold it may not have
|
|
51
|
+
* landed yet — while the client-local acceptance callback requires a current
|
|
52
|
+
* holder, because it can arrive from a replaced or already-dropped Session.
|
|
53
|
+
*/
|
|
54
|
+
private readonly engagedSessions;
|
|
55
|
+
private disposed;
|
|
50
56
|
/** Per-session projection value stores, retained independently of instance arrival (the
|
|
51
57
|
* title-snapshot precedent, generalized): push frames land here whether or not the Session
|
|
52
58
|
* is instantiated (list rows read the 'title' key), and an instantiated Session adopts the
|
|
@@ -61,18 +67,8 @@ export declare class SessionManager {
|
|
|
61
67
|
/** Active list request's mutation log; its identity also fences completion after reconnect. */
|
|
62
68
|
private listMutations;
|
|
63
69
|
private readonly addresses;
|
|
64
|
-
private readonly
|
|
65
|
-
private readonly
|
|
66
|
-
/** Catalog owners whose membership changed while a pull was in flight: one trailing refresh after it settles. */
|
|
67
|
-
private readonly catalogStale;
|
|
68
|
-
private readonly openCatalogs;
|
|
69
|
-
private readonly catalogDebounce;
|
|
70
|
-
/**
|
|
71
|
-
* Background jobs per session, last-wins from Session Controller's control
|
|
72
|
-
* stream. An empty set is stored as an absent key, so absence and `[]` are
|
|
73
|
-
* one representation.
|
|
74
|
-
*/
|
|
75
|
-
private readonly jobsBySession;
|
|
70
|
+
private readonly projectionLoads;
|
|
71
|
+
private readonly projectionInflight;
|
|
76
72
|
private listSnapshotCache;
|
|
77
73
|
/** Entry-identity cache (reference stability): list rebuilds reuse the previous entry
|
|
78
74
|
* object when every field matches — wire refreshes mint all-new summary objects, so identity
|
|
@@ -88,18 +84,12 @@ export declare class SessionManager {
|
|
|
88
84
|
* @returns the resolved identity with its explicit or catalog-derived history route installed.
|
|
89
85
|
*/
|
|
90
86
|
resolveTarget(target: SessionTarget): SessionId;
|
|
91
|
-
/**
|
|
92
|
-
* Return the durable catalog address retained for one child.
|
|
93
|
-
* @param sessionId - possible addressed child id.
|
|
94
|
-
* @returns The direct-parent address, when navigation discovered one.
|
|
95
|
-
*/
|
|
96
|
-
subagentAddress(sessionId: SessionId): SubagentAddress | undefined;
|
|
97
87
|
/**
|
|
98
88
|
* Resolve an address for breadcrumb navigation without retaining transport authority.
|
|
99
89
|
* @param sessionId - possible child id in an already-loaded catalog.
|
|
100
90
|
* @returns A retained or catalog-derived direct-parent address.
|
|
101
91
|
*/
|
|
102
|
-
|
|
92
|
+
subagentAddress(sessionId: SessionId): SubagentAddress | undefined;
|
|
103
93
|
/**
|
|
104
94
|
* Withdraw an exact Client instance before running its teardown callbacks.
|
|
105
95
|
* @param sessionId - identity to withdraw.
|
|
@@ -117,24 +107,36 @@ export declare class SessionManager {
|
|
|
117
107
|
/**
|
|
118
108
|
* Lazy build: return the existing instance or construct one (no auto-open —
|
|
119
109
|
* the reference allocator opens history after binding the scope).
|
|
110
|
+
* New instances reconcile retained metadata before returning.
|
|
120
111
|
* @param sessionId - the session to get.
|
|
121
112
|
* @returns the resident instance.
|
|
122
113
|
*/
|
|
123
114
|
get(sessionId: SessionId): Session;
|
|
124
115
|
private createSession;
|
|
125
|
-
|
|
126
|
-
private projectionStore;
|
|
116
|
+
private effectiveBlank;
|
|
127
117
|
/**
|
|
128
|
-
*
|
|
129
|
-
*
|
|
118
|
+
* Identities an engagement may still belong to: the given list rows, resident
|
|
119
|
+
* Session instances, and retained child addresses.
|
|
120
|
+
* @param summaries - list rows of the caller's snapshot.
|
|
121
|
+
* @returns the retained identity set.
|
|
130
122
|
*/
|
|
131
|
-
|
|
123
|
+
private retainedIds;
|
|
124
|
+
/**
|
|
125
|
+
* Forget one engagement that no retained identity holds.
|
|
126
|
+
* @param sessionId - identity whose engagement may be dropped.
|
|
127
|
+
* @param retained - identities from {@link retainedIds} for the caller's snapshot.
|
|
128
|
+
*/
|
|
129
|
+
private pruneEngagement;
|
|
130
|
+
/** Resident per-session projection store (create-on-demand; outlives instantiation). */
|
|
131
|
+
private projectionStore;
|
|
132
132
|
/**
|
|
133
|
-
*
|
|
134
|
-
* @param
|
|
135
|
-
* @
|
|
133
|
+
* Load a complete projection baseline once per connection; retry unsuccessful reads.
|
|
134
|
+
* @param sessionId - Session to inspect without opening its conversation.
|
|
135
|
+
* @returns completion of the current or newly started read.
|
|
136
136
|
*/
|
|
137
|
-
|
|
137
|
+
refreshProjections(sessionId: SessionId): Promise<void>;
|
|
138
|
+
private agentAvailable;
|
|
139
|
+
private updateParentAvailability;
|
|
138
140
|
/** Full refresh via session.list (single-flight within one Host generation). */
|
|
139
141
|
refreshList(): Promise<void>;
|
|
140
142
|
/**
|
|
@@ -164,11 +166,12 @@ export declare class SessionManager {
|
|
|
164
166
|
}>>;
|
|
165
167
|
/**
|
|
166
168
|
* Contract session.fork; on success merge the child into summaries
|
|
167
|
-
* immediately (same synchronous-addressability guarantee as create).
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
169
|
+
* immediately (same synchronous-addressability guarantee as create).
|
|
170
|
+
* Blankness starts provisionally true so the authoritative Host summary can
|
|
171
|
+
* preserve it or lower it after an exact cut before the first `turn/start`;
|
|
172
|
+
* lineage rides parentSessionId. A child published before Workspace
|
|
173
|
+
* attachment fails is also reconciled into the list.
|
|
174
|
+
* @param opts - source session and the optional exact inclusive boundary seq.
|
|
172
175
|
* @returns the fork result (the child session id).
|
|
173
176
|
*/
|
|
174
177
|
fork(opts: {
|
|
@@ -178,10 +181,15 @@ export declare class SessionManager {
|
|
|
178
181
|
sessionId: SessionId;
|
|
179
182
|
}>>;
|
|
180
183
|
/**
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
184
|
+
* Rename a Session and update its title projection without opening its history.
|
|
185
|
+
* @param sessionId - Session to rename.
|
|
186
|
+
* @param title - raw title text for Host normalization.
|
|
187
|
+
* @returns the accepted title and event position, or the Remote failure.
|
|
188
|
+
*/
|
|
189
|
+
rename(sessionId: SessionId, title: string): Promise<RemoteResult<SessionRenameValue>>;
|
|
190
|
+
/**
|
|
191
|
+
* Merge a Host summary, replacing live state and filling missing metadata.
|
|
192
|
+
* Local create/fork placeholders only fill metadata on an existing row.
|
|
185
193
|
*/
|
|
186
194
|
private mergeSummary;
|
|
187
195
|
/** Apply immediately and retain for replay when a list response is in flight. */
|
|
@@ -214,6 +222,15 @@ export declare class SessionManager {
|
|
|
214
222
|
* @param summary - current Host summary for the added Session.
|
|
215
223
|
*/
|
|
216
224
|
handleSessionAdded(summary: SessionSummary): void;
|
|
225
|
+
/**
|
|
226
|
+
* Merge one list-surface projection block by the sequence space it declares.
|
|
227
|
+
* A `sequenced` block came from the Host's live registry for an attached
|
|
228
|
+
* Session, so each key lands under higher-seq-wins against that Session's
|
|
229
|
+
* baselines and frames. A `cached` block was viewed from the persisted
|
|
230
|
+
* checkpoint by a header-only listing: its watermark is not comparable with
|
|
231
|
+
* this connection's seqs, so it only fills keys no sequenced row holds.
|
|
232
|
+
*/
|
|
233
|
+
private applyListBlock;
|
|
217
234
|
/**
|
|
218
235
|
* Apply one Session removal forwarded through `ctx.remote.$on`.
|
|
219
236
|
* @param sessionId - removed Session identity.
|
|
@@ -244,16 +261,6 @@ export declare class SessionManager {
|
|
|
244
261
|
* Opened Session follow streams resume independently through API Gateway.
|
|
245
262
|
*/
|
|
246
263
|
handleConnected(): void;
|
|
247
|
-
/** Debounce membership refetches for an explicitly consumed catalog. */
|
|
248
|
-
private scheduleCatalogRefresh;
|
|
249
|
-
/** Apply one Agent-driver transition to loaded and in-flight catalogs. */
|
|
250
|
-
private updateCatalogActivity;
|
|
251
|
-
/** Preserve and project a positive expandability hint after one direct subagent publishes. */
|
|
252
|
-
private markCatalogParentExpandable;
|
|
253
|
-
/** Apply one positive expandability hint to every loaded catalog containing that unique row id. */
|
|
254
|
-
private applyCatalogParentExpandable;
|
|
255
|
-
/** Fold request-local row mutations into one catalog result before publication. */
|
|
256
|
-
private withCatalogMutations;
|
|
257
264
|
private buildListSnapshot;
|
|
258
265
|
}
|
|
259
266
|
//# sourceMappingURL=manager.d.ts.map
|