@deepseek-ai/dsh-api-session-controller 0.2.1-alpha.1 → 0.2.1-alpha.2
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 +3 -1
- package/README.zh.md +3 -1
- package/lib/client.js +44 -20
- package/lib/index.js +43 -13
- package/lib/typert.host.js +227 -41
- package/lib/typert.remote-client.js +199 -21
- package/lib/types/client/contract/sessions.d.ts +4 -2
- package/lib/types/client/sessions/lineage.d.ts +2 -0
- package/lib/types/client/sessions/manager.d.ts +7 -5
- package/lib/types/client/sessions/manager.js +36 -11
- package/lib/types/client/sessions/projection-store.d.ts +3 -3
- package/lib/types/client/sessions/projection-store.js +1 -1
- package/lib/types/client/sessions/service.d.ts +8 -4
- package/lib/types/client/sessions/service.js +7 -3
- package/lib/types/index.d.ts +5 -4
- package/lib/types/index.js +40 -10
- package/lib/types/list.js +6 -4
- package/lib/types/skill-catalog.js +7 -6
- package/lib/types/types.d.ts +14 -2
- package/package.json +78 -75
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* (`{ value, seq }`) comes from the connected Host — a follow opening
|
|
7
7
|
* baseline, a Session Controller `projection` frame, a list block the Host
|
|
8
8
|
* computed for an attached Session — and merges under **higher seq wins**
|
|
9
|
-
* against other sequenced rows. A `cached` row (`{ value }`) comes from
|
|
10
|
-
*
|
|
9
|
+
* against other sequenced rows. A `cached` row (`{ value }`) comes from
|
|
10
|
+
* a Host view of the persisted checkpoint, carries no comparable
|
|
11
11
|
* seq, and yields to every sequenced write. No client-side domain folding
|
|
12
12
|
* exists: a domain ships projection support with zero client code. Per-key
|
|
13
13
|
* bare observable faces feed `useProjection` (ui-renderer binds them).
|
|
@@ -101,7 +101,7 @@ export declare class ProjectionValueStore {
|
|
|
101
101
|
*/
|
|
102
102
|
apply(key: string, value: unknown, seq: SessionSeqCursor): void;
|
|
103
103
|
/**
|
|
104
|
-
* Fill keys from a
|
|
104
|
+
* Fill keys from a Host block labeled `cached`: a zero-I/O
|
|
105
105
|
* view of the persisted checkpoint. A cached value lands only where no
|
|
106
106
|
* sequenced row exists: a connected Session has already answered for such
|
|
107
107
|
* a key, and the list's view of the persisted checkpoint cannot be newer
|
|
@@ -82,7 +82,7 @@ export class ProjectionValueStore {
|
|
|
82
82
|
this.changed(key);
|
|
83
83
|
}
|
|
84
84
|
/**
|
|
85
|
-
* Fill keys from a
|
|
85
|
+
* Fill keys from a Host block labeled `cached`: a zero-I/O
|
|
86
86
|
* view of the persisted checkpoint. A cached value lands only where no
|
|
87
87
|
* sequenced row exists: a connected Session has already answered for such
|
|
88
88
|
* a key, and the list's view of the persisted checkpoint cannot be newer
|
|
@@ -12,6 +12,7 @@ import type { AgentContext, ISessions, SessionReference, SessionRetainInfo, Sess
|
|
|
12
12
|
import { SessionManager } from './manager.ts';
|
|
13
13
|
import type { SessionRemotes } from './remotes.ts';
|
|
14
14
|
import type { SessionListPhase, SessionSearchResultItem, SessionProjectionSnapshot } from './manager.ts';
|
|
15
|
+
import type { SessionListEntry } from './lineage.ts';
|
|
15
16
|
/** Session list row projected from the host list RPC plus live stream increments. */
|
|
16
17
|
export interface SessionSummary {
|
|
17
18
|
id: SessionId;
|
|
@@ -23,6 +24,8 @@ export interface SessionSummary {
|
|
|
23
24
|
parentId?: SessionId;
|
|
24
25
|
/** Coarse durable origin for navigation filtering; not a continuation capability. */
|
|
25
26
|
origin?: 'subagent';
|
|
27
|
+
/** Format classification supplied by the Host list, when available. */
|
|
28
|
+
formatStatus?: SessionListEntry['formatStatus'];
|
|
26
29
|
/** Host running state for `ids` members; a display fallback for other rows. */
|
|
27
30
|
running: boolean;
|
|
28
31
|
/** Local ownership counts; Host metadata refreshes cannot overwrite them. */
|
|
@@ -30,7 +33,7 @@ export interface SessionSummary {
|
|
|
30
33
|
/**
|
|
31
34
|
* New Session presentation and reuse eligibility, derived from the Host
|
|
32
35
|
* summary, `sessionListMetadata`, and client acceptance/running observations.
|
|
33
|
-
*
|
|
36
|
+
* Workspace reconnection may reuse a blank in the same workspace. Filtering
|
|
34
37
|
* stays with the consumer: the store carries every row, while the Workspace
|
|
35
38
|
* browser shows only the selected blank entry.
|
|
36
39
|
*/
|
|
@@ -113,11 +116,11 @@ export declare class ClientSessions implements ISessions {
|
|
|
113
116
|
* Resolve an already discovered direct-parent address without opening it.
|
|
114
117
|
* Feature plugins use this to avoid Agent-bound RPCs in persisted child views.
|
|
115
118
|
* @param id - possible addressed child id.
|
|
116
|
-
* @returns A retained or
|
|
119
|
+
* @returns A retained, catalog-derived, or unknown-mode listed address, without retaining a new selection or scope.
|
|
117
120
|
*/
|
|
118
121
|
subagentAddress(id: SessionId): SubagentAddress | undefined;
|
|
119
122
|
/**
|
|
120
|
-
*
|
|
123
|
+
* Read projections without starting migration; retry failed or migration-deferred reads.
|
|
121
124
|
* @param sessionId - Session to inspect without opening its conversation.
|
|
122
125
|
*/
|
|
123
126
|
refreshProjections(sessionId: SessionId): Promise<void>;
|
|
@@ -189,7 +192,7 @@ export declare class ClientSessions implements ISessions {
|
|
|
189
192
|
* seq (a real event seq the caller already knows; a cut inside an open
|
|
190
193
|
* turn is balanced Host-side with synthetic closers, and omission selects
|
|
191
194
|
* the latest completed-turn prefix), and whether to increment an
|
|
192
|
-
* inherited durable title before resolving.
|
|
195
|
+
* inherited durable title before resolving, plus permission to start source migration.
|
|
193
196
|
* @returns the child session id.
|
|
194
197
|
* @throws {SessionForkError} with the source id.
|
|
195
198
|
* @throws {Error} when a requested child-title rename fails after creation.
|
|
@@ -199,6 +202,7 @@ export declare class ClientSessions implements ISessions {
|
|
|
199
202
|
atSeq?: number;
|
|
200
203
|
increaseTitle?: boolean;
|
|
201
204
|
onCreated?: (childId: SessionId) => void;
|
|
205
|
+
allowMigration?: boolean;
|
|
202
206
|
}): Promise<SessionId>;
|
|
203
207
|
/**
|
|
204
208
|
* Borrow an already-retained Agent-scoped Context.
|
|
@@ -234,13 +234,13 @@ export class ClientSessions {
|
|
|
234
234
|
* Resolve an already discovered direct-parent address without opening it.
|
|
235
235
|
* Feature plugins use this to avoid Agent-bound RPCs in persisted child views.
|
|
236
236
|
* @param id - possible addressed child id.
|
|
237
|
-
* @returns A retained or
|
|
237
|
+
* @returns A retained, catalog-derived, or unknown-mode listed address, without retaining a new selection or scope.
|
|
238
238
|
*/
|
|
239
239
|
subagentAddress(id) {
|
|
240
240
|
return this.manager.subagentAddress(id);
|
|
241
241
|
}
|
|
242
242
|
/**
|
|
243
|
-
*
|
|
243
|
+
* Read projections without starting migration; retry failed or migration-deferred reads.
|
|
244
244
|
* @param sessionId - Session to inspect without opening its conversation.
|
|
245
245
|
*/
|
|
246
246
|
refreshProjections(sessionId) {
|
|
@@ -331,7 +331,7 @@ export class ClientSessions {
|
|
|
331
331
|
* seq (a real event seq the caller already knows; a cut inside an open
|
|
332
332
|
* turn is balanced Host-side with synthetic closers, and omission selects
|
|
333
333
|
* the latest completed-turn prefix), and whether to increment an
|
|
334
|
-
* inherited durable title before resolving.
|
|
334
|
+
* inherited durable title before resolving, plus permission to start source migration.
|
|
335
335
|
* @returns the child session id.
|
|
336
336
|
* @throws {SessionForkError} with the source id.
|
|
337
337
|
* @throws {Error} when a requested child-title rename fails after creation.
|
|
@@ -343,6 +343,7 @@ export class ClientSessions {
|
|
|
343
343
|
const result = await this.manager.fork({
|
|
344
344
|
sessionId: opts.sessionId,
|
|
345
345
|
...(opts.atSeq === undefined ? {} : { atSeq: SessionSeq(opts.atSeq) }),
|
|
346
|
+
...(opts.allowMigration === undefined ? {} : { allowMigration: opts.allowMigration }),
|
|
346
347
|
});
|
|
347
348
|
if (!result.ok)
|
|
348
349
|
throw new SessionForkError(result.error, opts.sessionId);
|
|
@@ -502,6 +503,7 @@ export class ClientSessions {
|
|
|
502
503
|
retainedBy: this.retentionSnapshot(entry.sessionId).retainedBy,
|
|
503
504
|
blank: entry.blank,
|
|
504
505
|
updatedAt: entry.updatedAt,
|
|
506
|
+
formatStatus: entry.formatStatus,
|
|
505
507
|
...(entry.projectionValues === undefined
|
|
506
508
|
? {}
|
|
507
509
|
: { projectionValues: entry.projectionValues }),
|
|
@@ -513,6 +515,8 @@ export class ClientSessions {
|
|
|
513
515
|
}
|
|
514
516
|
for (const [parentId, projection] of Object.entries(projectionsBySession)) {
|
|
515
517
|
for (const child of projection.values.subagentCatalog ?? []) {
|
|
518
|
+
if (child.mode === 'external')
|
|
519
|
+
continue;
|
|
516
520
|
const childId = child.id;
|
|
517
521
|
const summary = byId[childId];
|
|
518
522
|
const projectionValues = summary?.projectionValues ?? this.manager.projectionValues(childId);
|
package/lib/types/index.d.ts
CHANGED
|
@@ -156,7 +156,7 @@ export declare class SessionController extends TypertRemoteService {
|
|
|
156
156
|
* Fork one cold-readable exact event prefix into a new Session. An omitted
|
|
157
157
|
* boundary selects the latest completed-turn prefix; an open cut receives
|
|
158
158
|
* synthetic fork closers.
|
|
159
|
-
* @param request - source Session
|
|
159
|
+
* @param request - source Session, optional exact inclusive event boundary, and migration preflight choice.
|
|
160
160
|
* @returns the new Session identity.
|
|
161
161
|
*/
|
|
162
162
|
fork(request: SessionForkRequest): Promise<SessionForkValue>;
|
|
@@ -201,12 +201,13 @@ export declare class SessionController extends TypertRemoteService {
|
|
|
201
201
|
*/
|
|
202
202
|
follow(request: SessionFollowRequest, signal: AbortSignal): AsyncIterable<SessionFollowFrame>;
|
|
203
203
|
/**
|
|
204
|
-
* Read
|
|
204
|
+
* Read exact projections, returning cached hints only when migration is required.
|
|
205
205
|
* @param request - Session whose current values are required.
|
|
206
|
-
* @param signal - cancellation for the Session
|
|
207
|
-
* @returns
|
|
206
|
+
* @param signal - cancellation for the Session read.
|
|
207
|
+
* @returns a sequenced baseline, cached hints when migration is deferred, or null when absent.
|
|
208
208
|
*/
|
|
209
209
|
projections(request: SessionProjectionsRequest, signal: AbortSignal): Promise<SessionProjectionsValue>;
|
|
210
|
+
private liveProjections;
|
|
210
211
|
/**
|
|
211
212
|
* Stream a complete live-control baseline followed by replacement frames.
|
|
212
213
|
* @param signal - cancellation owned by the Remote stream carrier.
|
package/lib/types/index.js
CHANGED
|
@@ -463,10 +463,18 @@ let SessionController = (() => {
|
|
|
463
463
|
* Fork one cold-readable exact event prefix into a new Session. An omitted
|
|
464
464
|
* boundary selects the latest completed-turn prefix; an open cut receives
|
|
465
465
|
* synthetic fork closers.
|
|
466
|
-
* @param request - source Session
|
|
466
|
+
* @param request - source Session, optional exact inclusive event boundary, and migration preflight choice.
|
|
467
467
|
* @returns the new Session identity.
|
|
468
468
|
*/
|
|
469
|
-
fork(request) {
|
|
469
|
+
async fork(request) {
|
|
470
|
+
if (request.allowMigration === false && this.ctx.sessions.get(request.sessionId) === undefined) {
|
|
471
|
+
const stored = await this.ctx.get('sessionPersistence')?.stat(request.sessionId);
|
|
472
|
+
if (stored?.formatStatus === 'migration-required' && this.ctx.sessions.get(request.sessionId) === undefined) {
|
|
473
|
+
throw new RemoteError('session/migration-required', 'Open the source Session to complete migration before forking', {
|
|
474
|
+
sessionId: request.sessionId,
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
}
|
|
470
478
|
return this.commands.fork(request);
|
|
471
479
|
}
|
|
472
480
|
/**
|
|
@@ -523,10 +531,10 @@ let SessionController = (() => {
|
|
|
523
531
|
return this.history.follow(request, signal);
|
|
524
532
|
}
|
|
525
533
|
/**
|
|
526
|
-
* Read
|
|
534
|
+
* Read exact projections, returning cached hints only when migration is required.
|
|
527
535
|
* @param request - Session whose current values are required.
|
|
528
|
-
* @param signal - cancellation for the Session
|
|
529
|
-
* @returns
|
|
536
|
+
* @param signal - cancellation for the Session read.
|
|
537
|
+
* @returns a sequenced baseline, cached hints when migration is deferred, or null when absent.
|
|
530
538
|
*/
|
|
531
539
|
async projections(request, signal) {
|
|
532
540
|
const { sessionId } = request;
|
|
@@ -536,12 +544,27 @@ let SessionController = (() => {
|
|
|
536
544
|
try {
|
|
537
545
|
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
538
546
|
try {
|
|
547
|
+
signal.throwIfAborted();
|
|
548
|
+
const live = this.liveProjections(sessionId);
|
|
549
|
+
if (live !== undefined)
|
|
550
|
+
return live;
|
|
551
|
+
const stored = await this.ctx.get('sessionPersistence')?.stat(sessionId, { signal });
|
|
552
|
+
signal.throwIfAborted();
|
|
553
|
+
const attached = this.liveProjections(sessionId);
|
|
554
|
+
if (attached !== undefined)
|
|
555
|
+
return attached;
|
|
556
|
+
if (stored === undefined)
|
|
557
|
+
return null;
|
|
558
|
+
if (stored.formatStatus === 'migration-required') {
|
|
559
|
+
const cached = this.ctx.get('sessionProjectionCache')?.cachedSnapshot(stored.header);
|
|
560
|
+
return { kind: 'migration-required', values: { ...cached?.values } };
|
|
561
|
+
}
|
|
539
562
|
const observation = __addDisposableResource(env_2, await this.ctx.sessionQuery.observeSession(sessionId, { signal }), false);
|
|
540
563
|
const projections = observation.projections;
|
|
541
564
|
if (projections === undefined) {
|
|
542
565
|
throw new RemoteError('session/projections-unavailable', 'Session projections are unavailable', {});
|
|
543
566
|
}
|
|
544
|
-
return { asOfSeq: projections.asOfSeq, values: projections.values };
|
|
567
|
+
return { kind: 'sequenced', asOfSeq: projections.asOfSeq, values: projections.values };
|
|
545
568
|
}
|
|
546
569
|
catch (e_2) {
|
|
547
570
|
env_2.error = e_2;
|
|
@@ -552,10 +575,10 @@ let SessionController = (() => {
|
|
|
552
575
|
}
|
|
553
576
|
}
|
|
554
577
|
catch (error) {
|
|
555
|
-
if (error instanceof SessionQueryError && error.code === 'SESSION_QUERY_SESSION_NOT_FOUND')
|
|
556
|
-
return null;
|
|
557
|
-
|
|
558
|
-
|
|
578
|
+
if (error instanceof SessionQueryError && error.code === 'SESSION_QUERY_SESSION_NOT_FOUND') {
|
|
579
|
+
return this.liveProjections(sessionId) ?? null;
|
|
580
|
+
}
|
|
581
|
+
if (signal.aborted || (error instanceof SessionQueryError && error.code === 'SESSION_QUERY_ABORTED')) {
|
|
559
582
|
throw new RemoteError('gateway/cancelled', 'Session projection read was cancelled', {}, { cause: error });
|
|
560
583
|
}
|
|
561
584
|
if (error instanceof RemoteError)
|
|
@@ -563,6 +586,13 @@ let SessionController = (() => {
|
|
|
563
586
|
throw new RemoteError('gateway/internal', 'Session projection read failed', {}, { cause: error });
|
|
564
587
|
}
|
|
565
588
|
}
|
|
589
|
+
liveProjections(sessionId) {
|
|
590
|
+
const session = this.ctx.sessions.get(sessionId);
|
|
591
|
+
if (session === undefined)
|
|
592
|
+
return undefined;
|
|
593
|
+
const snapshot = this.ctx.sessionProjections.snapshot(session);
|
|
594
|
+
return { kind: 'sequenced', asOfSeq: snapshot.asOfSeq, values: snapshot.values };
|
|
595
|
+
}
|
|
566
596
|
/**
|
|
567
597
|
* Stream a complete live-control baseline followed by replacement frames.
|
|
568
598
|
* @param signal - cancellation owned by the Remote stream carrier.
|
package/lib/types/list.js
CHANGED
|
@@ -97,6 +97,7 @@ export class ApiSessionList {
|
|
|
97
97
|
sessionId: session.id,
|
|
98
98
|
updatedAt: updatedAt(session.header, metadata),
|
|
99
99
|
agentAvailable: this.ctx.agents.get(session.id)?.session === session,
|
|
100
|
+
formatStatus: 'current',
|
|
100
101
|
running: this.ctx.agents.get(session.id)?.status === 'running',
|
|
101
102
|
blank: metadata?.blank ?? session.seq === 0,
|
|
102
103
|
...listFields(session.header),
|
|
@@ -122,7 +123,7 @@ export class ApiSessionList {
|
|
|
122
123
|
items.push(this.summaryFor(live));
|
|
123
124
|
}
|
|
124
125
|
else if (record.header.cwd !== undefined) {
|
|
125
|
-
cold.push(record
|
|
126
|
+
cold.push(record);
|
|
126
127
|
}
|
|
127
128
|
if (performance.now() >= yieldDeadline) {
|
|
128
129
|
await scheduler.yield();
|
|
@@ -130,9 +131,9 @@ export class ApiSessionList {
|
|
|
130
131
|
yieldDeadline = performance.now() + this.workSliceMs;
|
|
131
132
|
}
|
|
132
133
|
}
|
|
133
|
-
for (const
|
|
134
|
+
for (const record of cold) {
|
|
134
135
|
signal?.throwIfAborted();
|
|
135
|
-
items.push(this.summarizeCold(
|
|
136
|
+
items.push(this.summarizeCold(record));
|
|
136
137
|
if (performance.now() >= yieldDeadline) {
|
|
137
138
|
await scheduler.yield();
|
|
138
139
|
signal?.throwIfAborted();
|
|
@@ -143,13 +144,14 @@ export class ApiSessionList {
|
|
|
143
144
|
items.sort((left, right) => right.updatedAt - left.updatedAt);
|
|
144
145
|
return items;
|
|
145
146
|
}
|
|
146
|
-
summarizeCold(header) {
|
|
147
|
+
summarizeCold({ header, formatStatus }) {
|
|
147
148
|
const projections = this.projectionsFor(header, undefined);
|
|
148
149
|
const metadata = projections?.values.sessionListMetadata;
|
|
149
150
|
return {
|
|
150
151
|
sessionId: header.id,
|
|
151
152
|
updatedAt: updatedAt(header, metadata),
|
|
152
153
|
agentAvailable: false,
|
|
154
|
+
...(formatStatus === undefined ? {} : { formatStatus }),
|
|
153
155
|
running: false,
|
|
154
156
|
// A large, metadata-less, or inaccessible cache miss remains unknown and visible.
|
|
155
157
|
blank: metadata?.blank ?? false,
|
|
@@ -100,7 +100,7 @@ let SessionSkillCatalog = (() => {
|
|
|
100
100
|
__esDecorate(this, null, _list_decorators, { kind: "method", name: "list", static: false, private: false, access: { has: obj => "list" in obj, get: obj => obj.list }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
101
101
|
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
102
102
|
}
|
|
103
|
-
static inject = ['agents', 'sessionQuery', 'typert'];
|
|
103
|
+
static inject = ['agents', 'sessionQuery', 'typert', 'workingDirectory'];
|
|
104
104
|
/** @param ctx - Host context carrying Session reads and optional skill/preset services. */
|
|
105
105
|
constructor(ctx) {
|
|
106
106
|
super(ctx, 'sessionSkillCatalog', { namespace: 'skills' });
|
|
@@ -116,7 +116,6 @@ let SessionSkillCatalog = (() => {
|
|
|
116
116
|
async list(request, signal) {
|
|
117
117
|
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
118
118
|
try {
|
|
119
|
-
void signal;
|
|
120
119
|
const { sessionId } = request;
|
|
121
120
|
let cwd;
|
|
122
121
|
let agentPreset;
|
|
@@ -127,8 +126,13 @@ let SessionSkillCatalog = (() => {
|
|
|
127
126
|
if (observation.projections === undefined) {
|
|
128
127
|
throw new Error('skill catalog requires a projected Session observation');
|
|
129
128
|
}
|
|
130
|
-
cwd = observation.
|
|
129
|
+
cwd = observation.projections.values.workingDirectory
|
|
130
|
+
?? observation.header.cwd
|
|
131
|
+
?? this.ctx.workingDirectory.defaultDirectory;
|
|
131
132
|
agentPreset = observation.projections.values.agentPreset ?? undefined;
|
|
133
|
+
const live = this.ctx.agents.get(sessionId);
|
|
134
|
+
if (live !== undefined)
|
|
135
|
+
cwd = await this.ctx.workingDirectory.ensure(live, signal);
|
|
132
136
|
}
|
|
133
137
|
catch (e_1) {
|
|
134
138
|
env_2.error = e_1;
|
|
@@ -145,9 +149,6 @@ let SessionSkillCatalog = (() => {
|
|
|
145
149
|
}
|
|
146
150
|
throw new RemoteError('gateway/internal', `session "${sessionId}" could not be inspected: ${String(error)}`, {});
|
|
147
151
|
}
|
|
148
|
-
if (cwd === undefined) {
|
|
149
|
-
throw new RemoteError('gateway/internal', `session "${sessionId}" has no project cwd`, {});
|
|
150
|
-
}
|
|
151
152
|
const live = this.ctx.agents.get(sessionId);
|
|
152
153
|
const presets = this.ctx.get('agentPresets');
|
|
153
154
|
const scoped = live === undefined ? undefined : presets?.serviceFor(live, 'skills');
|
package/lib/types/types.d.ts
CHANGED
|
@@ -159,6 +159,8 @@ export type QueueAction = {
|
|
|
159
159
|
export interface SessionSummary {
|
|
160
160
|
/** Whether this Session currently owns a live Agent. */
|
|
161
161
|
readonly agentAvailable: boolean;
|
|
162
|
+
/** Current for attached Sessions; otherwise the persistence format status when reported. */
|
|
163
|
+
readonly formatStatus?: 'current' | 'migration-required';
|
|
162
164
|
readonly sessionId: SessionId;
|
|
163
165
|
readonly updatedAt: number;
|
|
164
166
|
readonly running: boolean;
|
|
@@ -226,6 +228,9 @@ declare module '@deepseek-ai/dsh-typert-protocol' {
|
|
|
226
228
|
'session/fork-unavailable': {
|
|
227
229
|
readonly sessionId: SessionId;
|
|
228
230
|
};
|
|
231
|
+
'session/migration-required': {
|
|
232
|
+
readonly sessionId: SessionId;
|
|
233
|
+
};
|
|
229
234
|
'subagent/not-found': {
|
|
230
235
|
readonly parentSessionId: SessionId;
|
|
231
236
|
readonly childSessionId: SessionId;
|
|
@@ -310,6 +315,8 @@ export interface SessionForkRequest {
|
|
|
310
315
|
readonly sessionId: SessionId;
|
|
311
316
|
/** Exact inclusive source event seq; omission selects the latest completed-turn prefix. */
|
|
312
317
|
readonly atSeq?: number;
|
|
318
|
+
/** False asks the Host to check for required migration before forking. Defaults to true. */
|
|
319
|
+
readonly allowMigration?: boolean;
|
|
313
320
|
}
|
|
314
321
|
/** Identity of a newly forked Session. */
|
|
315
322
|
export interface SessionForkValue {
|
|
@@ -396,8 +403,13 @@ export type SessionAddress = {
|
|
|
396
403
|
export interface SessionProjectionsRequest {
|
|
397
404
|
readonly sessionId: SessionId;
|
|
398
405
|
}
|
|
399
|
-
/**
|
|
400
|
-
export type SessionProjectionsValue = SessionProjectionBaseline
|
|
406
|
+
/** Exact projections carry their event cut; required migration returns sequence-free cache hints. Null means absent. */
|
|
407
|
+
export type SessionProjectionsValue = (SessionProjectionBaseline & {
|
|
408
|
+
readonly kind: 'sequenced';
|
|
409
|
+
}) | {
|
|
410
|
+
readonly kind: 'migration-required';
|
|
411
|
+
readonly values: SessionProjectionValues;
|
|
412
|
+
} | null;
|
|
401
413
|
/** One raw Session event in the Remote journal. */
|
|
402
414
|
export interface SessionEventEntry {
|
|
403
415
|
readonly type: 'event';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-api-session-controller",
|
|
3
3
|
"description": "Session Remote commands, cold reads, and live control transport",
|
|
4
|
-
"version": "0.2.1-alpha.
|
|
4
|
+
"version": "0.2.1-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -65,43 +65,44 @@
|
|
|
65
65
|
],
|
|
66
66
|
"license": "MIT",
|
|
67
67
|
"dependencies": {
|
|
68
|
+
"@deepseek-ai/dsh-brand": "0.2.1-alpha.2",
|
|
69
|
+
"@deepseek-ai/dsh-deque": "0.2.1-alpha.2",
|
|
70
|
+
"@deepseek-ai/schemastery": "~3.18.5-alpha.1",
|
|
68
71
|
"mime-types": "^3.0.2",
|
|
69
|
-
"zod": "^4.4.3"
|
|
70
|
-
"@deepseek-ai/dsh-deque": "0.2.1-alpha.1",
|
|
71
|
-
"@deepseek-ai/dsh-brand": "0.2.1-alpha.1",
|
|
72
|
-
"@deepseek-ai/schemastery": "~3.18.5-alpha.1"
|
|
72
|
+
"zod": "^4.4.3"
|
|
73
73
|
},
|
|
74
74
|
"peerDependencies": {
|
|
75
75
|
"@deepseek-ai/cordis": "~4.0.5-alpha.1",
|
|
76
|
-
"@deepseek-ai/dsh-agent": "0.2.1-alpha.
|
|
77
|
-
"@deepseek-ai/dsh-agent-default-model": "0.2.1-alpha.
|
|
78
|
-
"@deepseek-ai/dsh-agent-preset-registry": "0.2.1-alpha.
|
|
79
|
-
"@deepseek-ai/dsh-api-gateway": "0.2.1-alpha.
|
|
80
|
-
"@deepseek-ai/dsh-attachment": "0.2.1-alpha.
|
|
81
|
-
"@deepseek-ai/dsh-client-connection": "0.2.1-alpha.
|
|
82
|
-
"@deepseek-ai/dsh-client-file-upload": "0.2.1-alpha.
|
|
83
|
-
"@deepseek-ai/dsh-commands": "0.2.1-alpha.
|
|
84
|
-
"@deepseek-ai/dsh-
|
|
85
|
-
"@deepseek-ai/dsh-
|
|
86
|
-
"@deepseek-ai/dsh-
|
|
87
|
-
"@deepseek-ai/dsh-
|
|
88
|
-
"@deepseek-ai/dsh-
|
|
89
|
-
"@deepseek-ai/dsh-
|
|
90
|
-
"@deepseek-ai/dsh-session
|
|
91
|
-
"@deepseek-ai/dsh-session": "0.2.1-alpha.
|
|
92
|
-
"@deepseek-ai/dsh-
|
|
93
|
-
"@deepseek-ai/dsh-session-
|
|
94
|
-
"@deepseek-ai/dsh-
|
|
95
|
-
"@deepseek-ai/dsh-session-title": "0.2.1-alpha.
|
|
96
|
-
"@deepseek-ai/dsh-settings": "0.2.1-alpha.
|
|
97
|
-
"@deepseek-ai/dsh-skill": "0.2.1-alpha.
|
|
98
|
-
"@deepseek-ai/dsh-subagent": "0.2.1-alpha.
|
|
99
|
-
"@deepseek-ai/dsh-
|
|
100
|
-
"@deepseek-ai/dsh-
|
|
101
|
-
"@deepseek-ai/dsh-
|
|
102
|
-
"@deepseek-ai/dsh-util-
|
|
103
|
-
"@deepseek-ai/dsh-
|
|
104
|
-
"@deepseek-ai/dsh-workspace": "0.2.1-alpha.
|
|
76
|
+
"@deepseek-ai/dsh-agent": "0.2.1-alpha.2",
|
|
77
|
+
"@deepseek-ai/dsh-agent-default-model": "0.2.1-alpha.2",
|
|
78
|
+
"@deepseek-ai/dsh-agent-preset-registry": "0.2.1-alpha.2",
|
|
79
|
+
"@deepseek-ai/dsh-api-gateway": "0.2.1-alpha.2",
|
|
80
|
+
"@deepseek-ai/dsh-attachment": "0.2.1-alpha.2",
|
|
81
|
+
"@deepseek-ai/dsh-client-connection": "0.2.1-alpha.2",
|
|
82
|
+
"@deepseek-ai/dsh-client-file-upload": "0.2.1-alpha.2",
|
|
83
|
+
"@deepseek-ai/dsh-commands": "0.2.1-alpha.2",
|
|
84
|
+
"@deepseek-ai/dsh-credentials": "0.2.1-alpha.2",
|
|
85
|
+
"@deepseek-ai/dsh-file-reference": "0.2.1-alpha.2",
|
|
86
|
+
"@deepseek-ai/dsh-fs": "0.2.1-alpha.2",
|
|
87
|
+
"@deepseek-ai/dsh-llm": "0.2.1-alpha.2",
|
|
88
|
+
"@deepseek-ai/dsh-native-command": "0.2.1-alpha.2",
|
|
89
|
+
"@deepseek-ai/dsh-scope": "0.2.1-alpha.2",
|
|
90
|
+
"@deepseek-ai/dsh-session": "0.2.1-alpha.2",
|
|
91
|
+
"@deepseek-ai/dsh-session-persistence": "0.2.1-alpha.2",
|
|
92
|
+
"@deepseek-ai/dsh-session-projection": "0.2.1-alpha.2",
|
|
93
|
+
"@deepseek-ai/dsh-session-projection-cache": "0.2.1-alpha.2",
|
|
94
|
+
"@deepseek-ai/dsh-session-query": "0.2.1-alpha.2",
|
|
95
|
+
"@deepseek-ai/dsh-session-title": "0.2.1-alpha.2",
|
|
96
|
+
"@deepseek-ai/dsh-settings": "0.2.1-alpha.2",
|
|
97
|
+
"@deepseek-ai/dsh-skill": "0.2.1-alpha.2",
|
|
98
|
+
"@deepseek-ai/dsh-subagent": "0.2.1-alpha.2",
|
|
99
|
+
"@deepseek-ai/dsh-typert-protocol": "0.2.1-alpha.2",
|
|
100
|
+
"@deepseek-ai/dsh-typert-registry": "0.2.1-alpha.2",
|
|
101
|
+
"@deepseek-ai/dsh-util-time": "0.2.1-alpha.2",
|
|
102
|
+
"@deepseek-ai/dsh-util-values": "0.2.1-alpha.2",
|
|
103
|
+
"@deepseek-ai/dsh-util-workspace-path": "0.2.1-alpha.2",
|
|
104
|
+
"@deepseek-ai/dsh-workspace": "0.2.1-alpha.2",
|
|
105
|
+
"@deepseek-ai/dsh-working-directory": "0.2.1-alpha.2"
|
|
105
106
|
},
|
|
106
107
|
"peerDependenciesMeta": {
|
|
107
108
|
"@deepseek-ai/dsh-session-persistence": {
|
|
@@ -115,48 +116,50 @@
|
|
|
115
116
|
}
|
|
116
117
|
},
|
|
117
118
|
"devDependencies": {
|
|
118
|
-
"@types/mime-types": "^3.0.1",
|
|
119
|
-
"@deepseek-ai/dsh-agent": "0.2.1-alpha.1",
|
|
120
|
-
"@deepseek-ai/dsh-agent-default-model": "0.2.1-alpha.1",
|
|
121
119
|
"@deepseek-ai/cordis": "~4.0.5-alpha.1",
|
|
122
|
-
"@deepseek-ai/dsh-agent
|
|
123
|
-
"@deepseek-ai/dsh-agent-
|
|
124
|
-
"@deepseek-ai/dsh-agent-
|
|
125
|
-
"@deepseek-ai/dsh-
|
|
126
|
-
"@deepseek-ai/dsh-
|
|
127
|
-
"@deepseek-ai/dsh-
|
|
128
|
-
"@deepseek-ai/dsh-
|
|
129
|
-
"@deepseek-ai/dsh-client-
|
|
130
|
-
"@deepseek-ai/dsh-
|
|
131
|
-
"@deepseek-ai/dsh-
|
|
132
|
-
"@deepseek-ai/dsh-
|
|
133
|
-
"@deepseek-ai/dsh-
|
|
134
|
-
"@deepseek-ai/dsh-
|
|
135
|
-
"@deepseek-ai/dsh-
|
|
136
|
-
"@deepseek-ai/dsh-
|
|
137
|
-
"@deepseek-ai/dsh-
|
|
138
|
-
"@deepseek-ai/dsh-
|
|
139
|
-
"@deepseek-ai/dsh-
|
|
140
|
-
"@deepseek-ai/dsh-
|
|
141
|
-
"@deepseek-ai/dsh-
|
|
142
|
-
"@deepseek-ai/dsh-
|
|
143
|
-
"@deepseek-ai/dsh-session
|
|
144
|
-
"@deepseek-ai/dsh-session-
|
|
145
|
-
"@deepseek-ai/dsh-session-
|
|
146
|
-
"@deepseek-ai/dsh-session-
|
|
147
|
-
"@deepseek-ai/dsh-
|
|
148
|
-
"@deepseek-ai/dsh-
|
|
149
|
-
"@deepseek-ai/dsh-
|
|
150
|
-
"@deepseek-ai/dsh-
|
|
151
|
-
"@deepseek-ai/dsh-
|
|
152
|
-
"@deepseek-ai/dsh-
|
|
153
|
-
"@deepseek-ai/dsh-
|
|
154
|
-
"@deepseek-ai/dsh-
|
|
155
|
-
"@deepseek-ai/dsh-
|
|
156
|
-
"@deepseek-ai/dsh-
|
|
157
|
-
"@deepseek-ai/dsh-
|
|
158
|
-
"@deepseek-ai/dsh-
|
|
159
|
-
"@deepseek-ai/dsh-
|
|
120
|
+
"@deepseek-ai/dsh-agent": "0.2.1-alpha.2",
|
|
121
|
+
"@deepseek-ai/dsh-agent-default-model": "0.2.1-alpha.2",
|
|
122
|
+
"@deepseek-ai/dsh-agent-loop": "0.2.1-alpha.2",
|
|
123
|
+
"@deepseek-ai/dsh-agent-loop-testkit": "0.2.1-alpha.2",
|
|
124
|
+
"@deepseek-ai/dsh-agent-preset-registry": "0.2.1-alpha.2",
|
|
125
|
+
"@deepseek-ai/dsh-api-gateway": "0.2.1-alpha.2",
|
|
126
|
+
"@deepseek-ai/dsh-attachment": "0.2.1-alpha.2",
|
|
127
|
+
"@deepseek-ai/dsh-client-connection": "0.2.1-alpha.2",
|
|
128
|
+
"@deepseek-ai/dsh-client-file-upload": "0.2.1-alpha.2",
|
|
129
|
+
"@deepseek-ai/dsh-client-store": "0.2.1-alpha.2",
|
|
130
|
+
"@deepseek-ai/dsh-client-test-runtime": "0.2.1-alpha.2",
|
|
131
|
+
"@deepseek-ai/dsh-commands": "0.2.1-alpha.2",
|
|
132
|
+
"@deepseek-ai/dsh-credentials": "0.2.1-alpha.2",
|
|
133
|
+
"@deepseek-ai/dsh-file-reference": "0.2.1-alpha.2",
|
|
134
|
+
"@deepseek-ai/dsh-fs": "0.2.1-alpha.2",
|
|
135
|
+
"@deepseek-ai/dsh-fs-local": "0.2.1-alpha.2",
|
|
136
|
+
"@deepseek-ai/dsh-llm": "0.2.1-alpha.2",
|
|
137
|
+
"@deepseek-ai/dsh-native-command": "0.2.1-alpha.2",
|
|
138
|
+
"@deepseek-ai/dsh-permission-presets": "0.2.1-alpha.2",
|
|
139
|
+
"@deepseek-ai/dsh-remote-mock": "0.2.1-alpha.2",
|
|
140
|
+
"@deepseek-ai/dsh-scope": "0.2.1-alpha.2",
|
|
141
|
+
"@deepseek-ai/dsh-session": "0.2.1-alpha.2",
|
|
142
|
+
"@deepseek-ai/dsh-session-persistence": "0.2.1-alpha.2",
|
|
143
|
+
"@deepseek-ai/dsh-session-persistence-jsonl": "0.2.1-alpha.2",
|
|
144
|
+
"@deepseek-ai/dsh-session-projection": "0.2.1-alpha.2",
|
|
145
|
+
"@deepseek-ai/dsh-session-projection-cache": "0.2.1-alpha.2",
|
|
146
|
+
"@deepseek-ai/dsh-session-query": "0.2.1-alpha.2",
|
|
147
|
+
"@deepseek-ai/dsh-session-title": "0.2.1-alpha.2",
|
|
148
|
+
"@deepseek-ai/dsh-settings": "0.2.1-alpha.2",
|
|
149
|
+
"@deepseek-ai/dsh-skill": "0.2.1-alpha.2",
|
|
150
|
+
"@deepseek-ai/dsh-storage": "0.2.1-alpha.2",
|
|
151
|
+
"@deepseek-ai/dsh-storage-domain": "0.2.1-alpha.2",
|
|
152
|
+
"@deepseek-ai/dsh-storage-json": "0.2.1-alpha.2",
|
|
153
|
+
"@deepseek-ai/dsh-subagent": "0.2.1-alpha.2",
|
|
154
|
+
"@deepseek-ai/dsh-typert-protocol": "0.2.1-alpha.2",
|
|
155
|
+
"@deepseek-ai/dsh-typert-registry": "0.2.1-alpha.2",
|
|
156
|
+
"@deepseek-ai/dsh-util-crypto": "0.2.1-alpha.2",
|
|
157
|
+
"@deepseek-ai/dsh-util-time": "0.2.1-alpha.2",
|
|
158
|
+
"@deepseek-ai/dsh-util-values": "0.2.1-alpha.2",
|
|
159
|
+
"@deepseek-ai/dsh-util-workspace-path": "0.2.1-alpha.2",
|
|
160
|
+
"@deepseek-ai/dsh-workspace": "0.2.1-alpha.2",
|
|
161
|
+
"@types/mime-types": "^3.0.1",
|
|
162
|
+
"@deepseek-ai/dsh-working-directory": "0.2.1-alpha.2"
|
|
160
163
|
},
|
|
161
164
|
"scripts": {
|
|
162
165
|
"bundle": "tsdown",
|