dsh-pause-session 0.2.0 → 0.2.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/CHANGELOG.md +32 -39
- package/lib/client.js +95 -70
- package/lib/client.js.map +1 -1
- package/lib/index.js +187 -182
- package/lib/index.js.map +1 -1
- package/lib/types/client/locales.d.ts +1 -0
- package/lib/types/client/remote.d.ts +6 -0
- package/lib/types/composition.d.ts +35 -61
- package/lib/types/index.d.ts +1 -1
- package/lib/types/release-order.d.ts +8 -4
- package/lib/types/resume-activation.d.ts +14 -5
- package/lib/types/resume.d.ts +2 -4
- package/package.json +2 -2
|
@@ -47,6 +47,12 @@ export interface RemoteStatusSource {
|
|
|
47
47
|
}
|
|
48
48
|
/**
|
|
49
49
|
* Open the native status stream and expose its latest snapshot to both controls.
|
|
50
|
+
*
|
|
51
|
+
* The stream owns no retry of its own: a carrier can drop it on a mux reconnect,
|
|
52
|
+
* a host reload, or a network blip, and the controls must not stay unavailable
|
|
53
|
+
* until the page is refreshed. This source reconnects with a bounded backoff and
|
|
54
|
+
* republishes the new snapshot; while it is disconnected the last value is
|
|
55
|
+
* discarded, so readers see "unavailable" rather than a stale claim.
|
|
50
56
|
* @param remote - the generated Remote namespace.
|
|
51
57
|
* @param lifetime - client lifetime; aborting it releases the stream.
|
|
52
58
|
* @returns the cached source and its change subscription.
|
|
@@ -1,58 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* What a parked Session needs to come back as itself.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* scoped tools, prompt sections, skills,
|
|
6
|
-
*
|
|
7
|
-
* the
|
|
8
|
-
*
|
|
4
|
+
* A root Session is loaded directly: the Agent preset it ran supplies the
|
|
5
|
+
* scoped tools, prompt sections, and skills, so the resume mounts that preset
|
|
6
|
+
* before the Agent is published. A subagent child is not loaded here at all —
|
|
7
|
+
* the subagent runtime owns its activation, composition, and tree membership,
|
|
8
|
+
* and cold-resumes it when this plugin delivers the wake through
|
|
9
|
+
* `ctx.subagents.prompt`.
|
|
9
10
|
*
|
|
10
|
-
* The
|
|
11
|
-
*
|
|
12
|
-
* its first turn, and the projection records the selection that actually ran.
|
|
13
|
-
* A child with no independent selection joins its live parent's preset
|
|
14
|
-
* generation; one that selected independently mounts the projected preset.
|
|
15
|
-
* The durable child descriptor supplies the persona, tool filter, and route
|
|
16
|
-
* that are reapplied only on cold resume.
|
|
17
|
-
*
|
|
18
|
-
* Both services are optional. A profile without `agentPresets` has no scoped
|
|
19
|
-
* preset composition to restore, and this module leaves the resume unchanged.
|
|
20
|
-
* A profile that mounts one but cannot read the Session projection cannot
|
|
21
|
-
* prove what composition the Session ran, so it fails the resume instead of
|
|
22
|
-
* silently starting a different Agent.
|
|
11
|
+
* The two cases are told apart by one read of the Session's own log, which is
|
|
12
|
+
* the same read the press-time resumability check already pays for.
|
|
23
13
|
* @module dsh-pause-session/composition
|
|
24
14
|
*/
|
|
25
15
|
import type { Context } from '@deepseek-ai/cordis';
|
|
26
|
-
import type {
|
|
27
|
-
import type {
|
|
28
|
-
/**
|
|
29
|
-
export
|
|
30
|
-
/**
|
|
31
|
-
readonly
|
|
16
|
+
import type { AgentSetup } from '@deepseek-ai/dsh-agent';
|
|
17
|
+
import type { SessionId } from '@deepseek-ai/dsh-session';
|
|
18
|
+
/** How one parked Session comes back. */
|
|
19
|
+
export type ParkedComposition = {
|
|
20
|
+
/** An ordinary Session the plugin loads itself. */
|
|
21
|
+
readonly kind: 'root';
|
|
32
22
|
/** The scoped Agent world to mount before the Agent is published. */
|
|
33
23
|
readonly setup?: AgentSetup;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
export declare class UnresumableSessionError extends Error {
|
|
43
|
-
constructor(sessionId: SessionId);
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Whether the child's own log selected a preset before its descriptor.
|
|
47
|
-
*
|
|
48
|
-
* The creation-time selection precedes the first `subagent/descriptor`; a
|
|
49
|
-
* selection after the descriptor belongs to the child's own later history and
|
|
50
|
-
* does not decide which composition cold resume joins. This mirrors the
|
|
51
|
-
* subagent runtime's own cold-resume rule.
|
|
52
|
-
* @param events - the child's own log suffix, without the fork-inherited prefix.
|
|
53
|
-
* @returns whether the child carries an independent preset selection.
|
|
54
|
-
*/
|
|
55
|
-
export declare function hasIndependentPresetSelection(events: readonly SessionEvent[]): boolean;
|
|
24
|
+
} | {
|
|
25
|
+
/**
|
|
26
|
+
* A subagent child. The subagent runtime restores its composition from the
|
|
27
|
+
* persisted descriptor and preset projection, so the plugin only delivers
|
|
28
|
+
* the wake.
|
|
29
|
+
*/
|
|
30
|
+
readonly kind: 'child';
|
|
31
|
+
};
|
|
56
32
|
/**
|
|
57
33
|
* Whether a local Session may be parked under a promise of a later resume.
|
|
58
34
|
*
|
|
@@ -73,22 +49,20 @@ export declare function hasIndependentPresetSelection(events: readonly SessionEv
|
|
|
73
49
|
*/
|
|
74
50
|
export declare function isResumableSession(ctx: Context, sessionId: SessionId, signal?: AbortSignal): Promise<boolean>;
|
|
75
51
|
/**
|
|
76
|
-
* Read one parked Session's
|
|
52
|
+
* Read one parked Session's own log and decide how it comes back.
|
|
53
|
+
*
|
|
54
|
+
* A child returns as `child` with no setup: the subagent runtime restores the
|
|
55
|
+
* composition from the descriptor and the preset projection, and mounting a
|
|
56
|
+
* second one here would start a different Agent on the same history.
|
|
77
57
|
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
* child composition: an independent preset mounts separately, while an
|
|
83
|
-
* inherited composition joins the parent's current generation; the historical
|
|
84
|
-
* descriptor's persona and tool filter are reapplied in both cases.
|
|
58
|
+
* A root resolves the preset it ran — the projection, never the creation-time
|
|
59
|
+
* header alone, because a blank Session may select another preset before its
|
|
60
|
+
* first turn — and hands back the setup that mounts it. A profile with no
|
|
61
|
+
* preset roster has no scoped composition to restore and resumes unchanged.
|
|
85
62
|
* @param ctx - host context carrying the optional preset and Session-query services.
|
|
86
63
|
* @param sessionId - the parked Session being resumed.
|
|
87
|
-
* @param parent - the live direct parent, when a child is resumed under it.
|
|
88
64
|
* @param signal - cancellation for the observation read.
|
|
89
|
-
* @returns
|
|
90
|
-
* @throws
|
|
91
|
-
* @throws when a mounted preset roster cannot read the Session projection, or
|
|
92
|
-
* a recorded preset cannot be restored.
|
|
65
|
+
* @returns how this Session comes back.
|
|
66
|
+
* @throws when a mounted preset roster cannot read the Session projection.
|
|
93
67
|
*/
|
|
94
|
-
export declare function
|
|
68
|
+
export declare function readParkedComposition(ctx: Context, sessionId: SessionId, signal?: AbortSignal): Promise<ParkedComposition>;
|
package/lib/types/index.d.ts
CHANGED
|
@@ -51,7 +51,7 @@ export type Config = z.infer<typeof ConfigShape>;
|
|
|
51
51
|
export declare const Config: z.ZodPreprocess<z.ZodObject<{
|
|
52
52
|
silentWakeRoutes: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
53
53
|
maxListedLogEvents: z.ZodDefault<z.ZodNumber>;
|
|
54
|
-
}, z.core.$strip
|
|
54
|
+
}, z.core.$strip>, unknown>;
|
|
55
55
|
/**
|
|
56
56
|
* Mount the durable pause registry, the pause gate, the activity fold, their
|
|
57
57
|
* session control, and the clean resume path.
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The order a
|
|
2
|
+
* The order a batch release walks: parent before child, shallowest first.
|
|
3
|
+
*
|
|
4
|
+
* A single tree release already has the pre-order from its own walk, so this
|
|
5
|
+
* module serves the batch path, where the recorded sessions may span several
|
|
6
|
+
* trees. `listDescendants` stamps each row with its distance from the listing
|
|
7
|
+
* root, so one catalog read per recorded root places every member. A session
|
|
8
|
+
* the walk never reached is its own root and releases with the first level.
|
|
3
9
|
* @module dsh-pause-session/release-order
|
|
4
10
|
*/
|
|
5
11
|
import type { Context } from '@deepseek-ai/cordis';
|
|
6
12
|
import type { SessionId } from '@deepseek-ai/dsh-session';
|
|
7
13
|
/** How a batch release is sequenced. */
|
|
8
14
|
export interface ReleaseOrder {
|
|
9
|
-
/** The tree edge each child was found under. */
|
|
10
|
-
readonly parents: ReadonlyMap<SessionId, SessionId>;
|
|
11
15
|
/** One list per depth, shallowest first. */
|
|
12
16
|
readonly levels: readonly (readonly SessionId[])[];
|
|
13
17
|
}
|
|
@@ -16,6 +20,6 @@ export interface ReleaseOrder {
|
|
|
16
20
|
* @param ctx - host context carrying the optional subagent catalog.
|
|
17
21
|
* @param sessionIds - every recorded session, in registry order.
|
|
18
22
|
* @param signal - cancellation for each catalog read.
|
|
19
|
-
* @returns
|
|
23
|
+
* @returns one list per depth level, shallowest first.
|
|
20
24
|
*/
|
|
21
25
|
export declare function releaseOrder(ctx: Context, sessionIds: readonly SessionId[], signal?: AbortSignal): Promise<ReleaseOrder>;
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Reactivate one parked
|
|
3
|
-
*
|
|
2
|
+
* Reactivate one parked Session and deliver the wake it owes.
|
|
3
|
+
*
|
|
4
|
+
* The two Session kinds come back through different owners. An ordinary
|
|
5
|
+
* Session is loaded by this plugin and given the route its own log recorded.
|
|
6
|
+
* A subagent child belongs to the subagent runtime: delivering the wake through
|
|
7
|
+
* `ctx.subagents.prompt` is what cold-resumes it as a managed activation, under
|
|
8
|
+
* its live tree root, with its persisted composition and tree membership
|
|
9
|
+
* restored by the runtime itself.
|
|
10
|
+
*
|
|
11
|
+
* Both paths keep the same release order: the durable record goes first, then
|
|
12
|
+
* the gate, so a record that cannot be dropped leaves the Session parked.
|
|
4
13
|
* @module dsh-pause-session/resume-activation
|
|
5
14
|
*/
|
|
6
15
|
import type { Context } from '@deepseek-ai/cordis';
|
|
@@ -11,17 +20,17 @@ import type { ParkRegistry } from './registry.js';
|
|
|
11
20
|
import type { ResumeAttempt, ResumeOptions, WakeRequest } from './resume-text.js';
|
|
12
21
|
/** The activation entry points the resume path composes. */
|
|
13
22
|
export interface Activator {
|
|
14
|
-
activate(sessionId: SessionId, request: WakeRequest, rearm: boolean,
|
|
23
|
+
activate(sessionId: SessionId, request: WakeRequest, rearm: boolean, signal?: AbortSignal): Promise<ResumeAttempt>;
|
|
15
24
|
ensureRoute(agent: Agent): void;
|
|
16
25
|
wake(agent: Agent, request: WakeRequest): void;
|
|
17
26
|
rearmGoal(agent: Agent): void;
|
|
18
27
|
}
|
|
19
28
|
/**
|
|
20
29
|
* Build the activation closure.
|
|
21
|
-
* @param ctx - host context carrying the agent store and goal service.
|
|
30
|
+
* @param ctx - host context carrying the agent store, subagent runtime, and goal service.
|
|
22
31
|
* @param gate - the pause gate released after activation.
|
|
23
32
|
* @param registry - the durable list the release forgets from.
|
|
24
|
-
* @param options - the route knowledge the wake content depends on.
|
|
33
|
+
* @param options - the route knowledge the root wake content depends on.
|
|
25
34
|
* @returns the activation methods the resume path uses.
|
|
26
35
|
*/
|
|
27
36
|
export declare function createActivator(ctx: Context, gate: PauseGate, registry: ParkRegistry, options: ResumeOptions): Activator;
|
package/lib/types/resume.d.ts
CHANGED
|
@@ -71,11 +71,10 @@ export interface ResumePath {
|
|
|
71
71
|
* Resume one session the registry remembers.
|
|
72
72
|
* @param sessionId - the session to resume.
|
|
73
73
|
* @param request - which wake this resume delivers; see {@link WakeRequest}.
|
|
74
|
-
* @param parentId - the direct parent a batch release already brought back, when there is one.
|
|
75
74
|
* @param signal - cancellation for the cold load and setup.
|
|
76
75
|
* @returns what happened, and the copy for whoever asked.
|
|
77
76
|
*/
|
|
78
|
-
resumeSession(sessionId: SessionId, request: WakeRequest,
|
|
77
|
+
resumeSession(sessionId: SessionId, request: WakeRequest, signal?: AbortSignal): Promise<ResumeAttempt>;
|
|
79
78
|
/**
|
|
80
79
|
* Resume one session the decision list officially owns — a record that is
|
|
81
80
|
* known NOT to be clean, which the clean path above must refuse and this entry
|
|
@@ -86,11 +85,10 @@ export interface ResumePath {
|
|
|
86
85
|
* or only answers it (`'review'`). A review activates nothing and writes
|
|
87
86
|
* nothing: opening a session to read it is the user's own action, not this
|
|
88
87
|
* plugin's.
|
|
89
|
-
* @param parentId - the direct parent a batch release already brought back, when there is one.
|
|
90
88
|
* @param signal - cancellation for the cold load and setup.
|
|
91
89
|
* @returns what happened, and the copy for whoever asked.
|
|
92
90
|
*/
|
|
93
|
-
decideUnclean(sessionId: SessionId, request: WakeRequest, finalize: 'release' | 'review',
|
|
91
|
+
decideUnclean(sessionId: SessionId, request: WakeRequest, finalize: 'release' | 'review', signal?: AbortSignal): Promise<ResumeAttempt>;
|
|
94
92
|
/**
|
|
95
93
|
* Resume every session the registry remembers, clean ones only. One session's
|
|
96
94
|
* failure never stops the others.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-pause-session",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "DSH plugin: pause every running session (and its subagents) at a safe point before you leave, then resume them the next morning as if nothing was interrupted.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"@deepseek-ai/dsh-typert-protocol": "*"
|
|
87
87
|
},
|
|
88
88
|
"dependencies": {
|
|
89
|
-
"zod": "4.
|
|
89
|
+
"zod": "4.6.6"
|
|
90
90
|
},
|
|
91
91
|
"devDependencies": {
|
|
92
92
|
"@deepseek-ai/cordis": "link:../../deepseek-harness/vendor/cordis",
|