@huanlin/dsh-plugin-yet-another-subagent 0.1.6 → 0.4.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/README.md +26 -15
- package/lib/client.js +3125 -3099
- package/lib/index.js +5703 -5487
- package/lib/types/client/SettingsPage.d.ts +67 -49
- package/lib/types/client/SubagentCard.d.ts +57 -56
- package/lib/types/client/SubagentTreeView.d.ts +64 -63
- package/lib/types/client/index.d.ts +29 -29
- package/lib/types/client/locales.d.ts +13 -13
- package/lib/types/index.d.ts +42 -42
- package/lib/types/projection.d.ts +200 -103
- package/lib/types/repair.d.ts +66 -49
- package/lib/types/rpc.d.ts +69 -59
- package/package.json +26 -34
- package/lib/invariant.js +0 -21
- package/lib/types/invariant.d.ts +0 -16
|
@@ -1,103 +1,200 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Two session projections (design doc §3.6):
|
|
3
|
-
*
|
|
4
|
-
* - `subagentProfile` (parent session): fold `tool/call` (name `subagent`,
|
|
5
|
-
* profile in `arguments.profile`) + the matching `tool/result.subagentId`,
|
|
6
|
-
* building a `childId → profileId` map. Used as a cross-check / fallback
|
|
7
|
-
* for SubagentCard (which usually reads `profileLabel` straight from the
|
|
8
|
-
* result content).
|
|
9
|
-
*
|
|
10
|
-
* - `yaSubagentProgress` (child session): toolcall count, token usage,
|
|
11
|
-
* and lifecycle state. Pushed over the projection frame so the parent's
|
|
12
|
-
* SubagentCard can subscribe even though client runtime drops non-current
|
|
13
|
-
* `session/event` frames (single-stage model).
|
|
14
|
-
*
|
|
15
|
-
* Both units are pure synchronous folds; the framework drives them and the
|
|
16
|
-
* host wire layer ships the validated views.
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
interface
|
|
31
|
-
/**
|
|
32
|
-
readonly
|
|
33
|
-
/**
|
|
34
|
-
readonly
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
*
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
*/
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
readonly
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Two session projections (design doc §3.6):
|
|
3
|
+
*
|
|
4
|
+
* - `subagentProfile` (parent session): fold `tool/call` (name `subagent`,
|
|
5
|
+
* profile in `arguments.profile`) + the matching `tool/result.subagentId`,
|
|
6
|
+
* building a `childId → profileId` map. Used as a cross-check / fallback
|
|
7
|
+
* for SubagentCard (which usually reads `profileLabel` straight from the
|
|
8
|
+
* result content).
|
|
9
|
+
*
|
|
10
|
+
* - `yaSubagentProgress` (child session): toolcall count, token usage,
|
|
11
|
+
* and lifecycle state. Pushed over the projection frame so the parent's
|
|
12
|
+
* SubagentCard can subscribe even though client runtime drops non-current
|
|
13
|
+
* `session/event` frames (single-stage model).
|
|
14
|
+
*
|
|
15
|
+
* Both units are pure synchronous folds; the framework drives them and the
|
|
16
|
+
* host wire layer ships the validated views.
|
|
17
|
+
*
|
|
18
|
+
* Change-feed contract (`@deepseek-ai/dsh-session-projection`): the drive
|
|
19
|
+
* publishes a client view only when its raw output changes by `Object.is`, so
|
|
20
|
+
* an object-valued view MUST reuse its reference while the wire content is
|
|
21
|
+
* unchanged — a fresh object per call republishes on every internal-only
|
|
22
|
+
* state change. Both `view`s below go through {@link memoizeView} for that
|
|
23
|
+
* reference-stability guarantee.
|
|
24
|
+
*
|
|
25
|
+
* @module @huanlin/dsh-plugin-yet-another-subagent/projection
|
|
26
|
+
*/
|
|
27
|
+
import { z } from 'zod';
|
|
28
|
+
import type { SessionEvent } from '@deepseek-ai/dsh-session';
|
|
29
|
+
/** `subagentProfile` wire shape: childId → profileId, plus callId → childId. */
|
|
30
|
+
export interface SubagentProfileProjection {
|
|
31
|
+
/** childId → profileId (durable). */
|
|
32
|
+
readonly children: Record<string, string>;
|
|
33
|
+
/** callId → childId (for foreground calls where the result text has no embedded id). */
|
|
34
|
+
readonly calls: Record<string, string>;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Internal fold state for `subagentProfile`. Plain JSON only (the persisted
|
|
38
|
+
* projection-cache precondition), so the pending callId map is a Record,
|
|
39
|
+
* not a Map.
|
|
40
|
+
*/
|
|
41
|
+
interface ProfileState {
|
|
42
|
+
/** callId → profileId, awaiting the matching `tool/result`. */
|
|
43
|
+
readonly pending: Record<string, string>;
|
|
44
|
+
/** childId → profileId (the durable mapping). */
|
|
45
|
+
readonly mapping: Record<string, string>;
|
|
46
|
+
/** callId → childId (survives after the pending entry is consumed). */
|
|
47
|
+
readonly callToChild: Record<string, string>;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Fold the parent session's `tool/call` + `tool/result` for tool name
|
|
51
|
+
* `subagent`. The profile id is carried in `tool/call.arguments.profile`
|
|
52
|
+
* (JSON-encoded). The result content embeds `subagentId` (continuable branch)
|
|
53
|
+
* or `runId` (foreground branch); the continuable branch is the durable
|
|
54
|
+
* child identity that survives across activations.
|
|
55
|
+
*/
|
|
56
|
+
export declare const subagentProfileProjection: {
|
|
57
|
+
key: "subagentProfile";
|
|
58
|
+
stateSchema: z.ZodObject<{
|
|
59
|
+
pending: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
60
|
+
mapping: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
61
|
+
callToChild: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
62
|
+
}, z.core.$strict>;
|
|
63
|
+
stateVersion: number;
|
|
64
|
+
init: () => {
|
|
65
|
+
pending: {};
|
|
66
|
+
mapping: {};
|
|
67
|
+
callToChild: {};
|
|
68
|
+
};
|
|
69
|
+
apply: (state: NoInfer<ProfileState>, event: SessionEvent) => ProfileState;
|
|
70
|
+
wire: {
|
|
71
|
+
viewSchema: z.ZodObject<{
|
|
72
|
+
children: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
73
|
+
calls: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
74
|
+
}, z.core.$strict>;
|
|
75
|
+
view: (state: NoInfer<ProfileState>) => {
|
|
76
|
+
children: Record<string, string>;
|
|
77
|
+
calls: Record<string, string>;
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
/** `yaSubagentProgress` wire shape: live child progress for the parent's card. */
|
|
82
|
+
export interface YaSubagentProgressProjection {
|
|
83
|
+
/** Number of `tool/call` events folded so far. */
|
|
84
|
+
readonly toolCallCount: number;
|
|
85
|
+
/** Cumulative token usage folded from `assistant/message.usage`. */
|
|
86
|
+
readonly tokens: {
|
|
87
|
+
readonly input: number;
|
|
88
|
+
readonly output: number;
|
|
89
|
+
readonly cacheRead: number;
|
|
90
|
+
readonly cacheWrite: number;
|
|
91
|
+
readonly reasoning: number;
|
|
92
|
+
};
|
|
93
|
+
/** Lifecycle state derived from turn boundaries. */
|
|
94
|
+
readonly state: 'running' | 'idle' | 'settled';
|
|
95
|
+
/** Latest activity: a tool call or the finalized message text. */
|
|
96
|
+
readonly activity?: Activity;
|
|
97
|
+
}
|
|
98
|
+
/** Discriminated activity union: text or tool call. */
|
|
99
|
+
export type Activity = {
|
|
100
|
+
readonly kind: 'text';
|
|
101
|
+
readonly text: string;
|
|
102
|
+
} | {
|
|
103
|
+
readonly kind: 'tool';
|
|
104
|
+
readonly name: string;
|
|
105
|
+
readonly args?: string;
|
|
106
|
+
};
|
|
107
|
+
interface ProgressState {
|
|
108
|
+
readonly toolCallCount: number;
|
|
109
|
+
readonly tokens: {
|
|
110
|
+
readonly input: number;
|
|
111
|
+
readonly output: number;
|
|
112
|
+
readonly cacheRead: number;
|
|
113
|
+
readonly cacheWrite: number;
|
|
114
|
+
readonly reasoning: number;
|
|
115
|
+
};
|
|
116
|
+
readonly state: 'running' | 'idle' | 'settled';
|
|
117
|
+
readonly activity?: Activity;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Fold the child session's own events into a compact progress view. Token
|
|
121
|
+
* usage accumulates from `assistant/message.usage` (cache fields are
|
|
122
|
+
* optional); tool calls are counted; lifecycle follows turn boundaries.
|
|
123
|
+
* Since dsh 0.1.5 the session log carries no streaming events — activity
|
|
124
|
+
* text updates only when a message finalizes.
|
|
125
|
+
*/
|
|
126
|
+
export declare const yaSubagentProgressProjection: {
|
|
127
|
+
key: "yaSubagentProgress";
|
|
128
|
+
stateSchema: z.ZodObject<{
|
|
129
|
+
toolCallCount: z.ZodNumber;
|
|
130
|
+
tokens: z.ZodObject<{
|
|
131
|
+
input: z.ZodNumber;
|
|
132
|
+
output: z.ZodNumber;
|
|
133
|
+
cacheRead: z.ZodNumber;
|
|
134
|
+
cacheWrite: z.ZodNumber;
|
|
135
|
+
reasoning: z.ZodNumber;
|
|
136
|
+
}, z.core.$strict>;
|
|
137
|
+
state: z.ZodUnion<readonly [z.ZodLiteral<"running">, z.ZodLiteral<"idle">, z.ZodLiteral<"settled">]>;
|
|
138
|
+
activity: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
|
|
139
|
+
kind: z.ZodLiteral<"text">;
|
|
140
|
+
text: z.ZodString;
|
|
141
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
142
|
+
kind: z.ZodLiteral<"tool">;
|
|
143
|
+
name: z.ZodString;
|
|
144
|
+
args: z.ZodOptional<z.ZodString>;
|
|
145
|
+
}, z.core.$strict>]>>;
|
|
146
|
+
}, z.core.$strict>;
|
|
147
|
+
stateVersion: number;
|
|
148
|
+
init: () => {
|
|
149
|
+
toolCallCount: number;
|
|
150
|
+
tokens: {
|
|
151
|
+
input: number;
|
|
152
|
+
output: number;
|
|
153
|
+
cacheRead: number;
|
|
154
|
+
cacheWrite: number;
|
|
155
|
+
reasoning: number;
|
|
156
|
+
};
|
|
157
|
+
state: "idle";
|
|
158
|
+
};
|
|
159
|
+
apply: (state: NoInfer<ProgressState>, event: SessionEvent) => ProgressState;
|
|
160
|
+
wire: {
|
|
161
|
+
viewSchema: z.ZodObject<{
|
|
162
|
+
toolCallCount: z.ZodNumber;
|
|
163
|
+
tokens: z.ZodObject<{
|
|
164
|
+
input: z.ZodNumber;
|
|
165
|
+
output: z.ZodNumber;
|
|
166
|
+
cacheRead: z.ZodNumber;
|
|
167
|
+
cacheWrite: z.ZodNumber;
|
|
168
|
+
reasoning: z.ZodNumber;
|
|
169
|
+
}, z.core.$strict>;
|
|
170
|
+
state: z.ZodUnion<readonly [z.ZodLiteral<"running">, z.ZodLiteral<"idle">, z.ZodLiteral<"settled">]>;
|
|
171
|
+
activity: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
|
|
172
|
+
kind: z.ZodLiteral<"text">;
|
|
173
|
+
text: z.ZodString;
|
|
174
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
175
|
+
kind: z.ZodLiteral<"tool">;
|
|
176
|
+
name: z.ZodString;
|
|
177
|
+
args: z.ZodOptional<z.ZodString>;
|
|
178
|
+
}, z.core.$strict>]>>;
|
|
179
|
+
}, z.core.$strict>;
|
|
180
|
+
view: (state: NoInfer<ProgressState>) => ProgressState;
|
|
181
|
+
};
|
|
182
|
+
};
|
|
183
|
+
/** Convenience: the projection keys registered by this plugin. */
|
|
184
|
+
export declare const PROJECTION_KEYS: readonly ["subagentProfile", "yaSubagentProgress"];
|
|
185
|
+
/** Type-side declaration merges so consumers can read these keys via the projection registry. */
|
|
186
|
+
declare module '@deepseek-ai/dsh-session-projection/types' {
|
|
187
|
+
interface SessionProjectionMap {
|
|
188
|
+
/** Parent-session map of childId → profileId. */
|
|
189
|
+
subagentProfile: SubagentProfileProjection;
|
|
190
|
+
/** Child-session live progress (toolcall count + token usage + state). */
|
|
191
|
+
yaSubagentProgress: YaSubagentProgressProjection;
|
|
192
|
+
}
|
|
193
|
+
interface SessionProjectionStateMap {
|
|
194
|
+
/** Host fold state behind {@link SubagentProfileProjection}. */
|
|
195
|
+
subagentProfile: ProfileState;
|
|
196
|
+
/** Host fold state behind {@link YaSubagentProgressProjection}. */
|
|
197
|
+
yaSubagentProgress: ProgressState;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
export type { SessionEvent };
|
package/lib/types/repair.d.ts
CHANGED
|
@@ -1,49 +1,66 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* One-shot session-log repair:
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* Background:
|
|
7
|
-
* `session.append(...)
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
*
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
*/
|
|
49
|
-
|
|
1
|
+
/**
|
|
2
|
+
* One-shot session-log repair: physically REMOVE legacy `ya-subagent/started`
|
|
3
|
+
* event rows so the harness persistence read path (`assertEventsSupported`)
|
|
4
|
+
* loads the log again.
|
|
5
|
+
*
|
|
6
|
+
* Background: plugin versions ≤0.1.2 appended `ya-subagent/started` via
|
|
7
|
+
* `session.append(...)`. `KNOWN_SESSION_EVENT_TYPES` is code-generated with no
|
|
8
|
+
* plugin registration surface, and v0.1.2-alpha.1 refuses EVERY log row whose
|
|
9
|
+
* type is outside that set — the old `ignorable` envelope flag no longer
|
|
10
|
+
* exists, so stamping it (the ≤0.1.5 repair) cannot help. The only repair is
|
|
11
|
+
* removal.
|
|
12
|
+
*
|
|
13
|
+
* Rows cannot simply be deleted: the read path enforces contiguous `seq`
|
|
14
|
+
* numbers. This module therefore rewrites the log in place (after a `.bak`
|
|
15
|
+
* backup):
|
|
16
|
+
*
|
|
17
|
+
* - drops every `ya-subagent/started` row;
|
|
18
|
+
* - decrements the `seq` of every later ordinary event row (packed
|
|
19
|
+
* `text-chunks` / `reasoning-chunks` / `tool-call-chunks` storage rows
|
|
20
|
+
* shift their `seq0` instead);
|
|
21
|
+
* - shifts every `sourceEventSeqs` citation by the number of dropped rows
|
|
22
|
+
* ahead of it (dropped rows are never cited: only surface events carry
|
|
23
|
+
* provenance and they cite assistant chunks / surface nodes, which a
|
|
24
|
+
* plugin row never is).
|
|
25
|
+
*
|
|
26
|
+
* Two physical encodings (mirrors `session-persistence-jsonl`):
|
|
27
|
+
* - `.jsonl` — plaintext, one JSON record per line.
|
|
28
|
+
* - `.jsonl.zstd` — concatenated independent Zstandard frames: the first
|
|
29
|
+
* frame holds the session header line, subsequent
|
|
30
|
+
* frames each hold one append batch of event lines.
|
|
31
|
+
* Each frame is independently decodable + checksummed.
|
|
32
|
+
* The first frame containing a dropped row and every
|
|
33
|
+
* frame after it are recompressed (their rows renumber);
|
|
34
|
+
* untouched earlier frames are copied verbatim.
|
|
35
|
+
*
|
|
36
|
+
* Modified rows are re-encoded with `JSON.stringify`, which reproduces the
|
|
37
|
+
* write path's canonical single-line form and preserves the parsed key order;
|
|
38
|
+
* untouched lines stay byte-identical.
|
|
39
|
+
*
|
|
40
|
+
* Idempotent: a log with no target rows is left untouched (no backup, no
|
|
41
|
+
* rewrite). A corrupt (unparsable) line is left untouched — that is the
|
|
42
|
+
* harness's refusal job, not ours.
|
|
43
|
+
*
|
|
44
|
+
* @module @huanlin/dsh-plugin-yet-another-subagent/repair
|
|
45
|
+
*/
|
|
46
|
+
/** Aggregate result of one repair run. */
|
|
47
|
+
export interface RepairStats {
|
|
48
|
+
/** Session log files examined (`.jsonl` + `.jsonl.zstd`). */
|
|
49
|
+
readonly scanned: number;
|
|
50
|
+
/** Files rewritten because at least one target row was removed. */
|
|
51
|
+
readonly repaired: number;
|
|
52
|
+
/** Files with no target rows (already clean). */
|
|
53
|
+
readonly skipped: number;
|
|
54
|
+
/** Per-file errors (path + message); empty on a clean run. */
|
|
55
|
+
readonly errors: readonly {
|
|
56
|
+
readonly path: string;
|
|
57
|
+
readonly message: string;
|
|
58
|
+
}[];
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Recursively repair every session log under `sessionsRoot`.
|
|
62
|
+
*
|
|
63
|
+
* @param sessionsRoot - absolute path to `$DSH_HOME/sessions`.
|
|
64
|
+
* @returns aggregate stats. Never throws — per-file failures land in `errors`.
|
|
65
|
+
*/
|
|
66
|
+
export declare function repairSessions(sessionsRoot: string): Promise<RepairStats>;
|
package/lib/types/rpc.d.ts
CHANGED
|
@@ -1,59 +1,69 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* RPC
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* `
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
*/
|
|
59
|
-
export
|
|
1
|
+
/**
|
|
2
|
+
* RPC surface: profile list CRUD + tool list + session repair, exposed as
|
|
3
|
+
* exact Fetch routes on the shared `/api` channel via
|
|
4
|
+
* `ctx.connection.fetch.register(...)`.
|
|
5
|
+
*
|
|
6
|
+
* Why not a dedicated `rpc.handle` channel: the host-side dedicated-channel
|
|
7
|
+
* registry resolves `webServer` through the connection service's origin
|
|
8
|
+
* context chain, and the web profile mounts the webserver as a sibling
|
|
9
|
+
* loader row — never an ancestor of client-connection — so every dedicated
|
|
10
|
+
* channel fails to register with `cannot get property "webServer" without
|
|
11
|
+
* inject`. Exact Fetch routes dispatch inside the already-mounted `/api`
|
|
12
|
+
* carrier instead (the dsh-client-file-upload pattern), inheriting its
|
|
13
|
+
* Host/Origin trust fence and browser authentication for free, and the
|
|
14
|
+
* shared `/api` interceptor slot stays owned by the Typert gateway.
|
|
15
|
+
*
|
|
16
|
+
* Wire endpoints (all POST; URL path `/api/ya-subagent.<endpoint>`, body and
|
|
17
|
+
* response use the Connection client-request / server-response envelopes):
|
|
18
|
+
* - `ya-subagent.profiles.list` payload: {} → { profiles: SubagentProfile[] }
|
|
19
|
+
* - `ya-subagent.profiles.add` payload: { profile: SubagentProfile } → { profiles: ... } | error
|
|
20
|
+
* - `ya-subagent.profiles.update` payload: { profile: SubagentProfile } → { profiles: ... } | error
|
|
21
|
+
* - `ya-subagent.profiles.remove` payload: { id: string } → { profiles: ... } | error
|
|
22
|
+
* - `ya-subagent.tools.list` payload: {} → { tools: { name, description }[] }
|
|
23
|
+
* - `ya-subagent.sessions.repair` payload: {} → RepairStats | error
|
|
24
|
+
*
|
|
25
|
+
* Returns the existing RpcResult shape; business errors use the `internal`
|
|
26
|
+
* code with a descriptive message (the RpcError code union is closed; we do
|
|
27
|
+
* not extend it for plugin-specific failures — see design doc §3.5).
|
|
28
|
+
*
|
|
29
|
+
* @module @huanlin/dsh-plugin-yet-another-subagent/rpc
|
|
30
|
+
*/
|
|
31
|
+
import type { Context } from 'cordis';
|
|
32
|
+
import type { SubagentProfile } from './types.ts';
|
|
33
|
+
import type { ProfileStore } from './profile-store.ts';
|
|
34
|
+
import { type RepairStats } from './repair.ts';
|
|
35
|
+
/** Wire shape for `profiles.list` responses. */
|
|
36
|
+
export interface ProfileListResponse {
|
|
37
|
+
readonly profiles: readonly SubagentProfile[];
|
|
38
|
+
}
|
|
39
|
+
/** Wire shape for `tools.list` responses. */
|
|
40
|
+
export interface ToolListResponse {
|
|
41
|
+
readonly tools: readonly {
|
|
42
|
+
readonly name: string;
|
|
43
|
+
readonly description: string;
|
|
44
|
+
}[];
|
|
45
|
+
}
|
|
46
|
+
/** Wire shape for `profiles.add` request payload. */
|
|
47
|
+
export interface ProfileAddPayload {
|
|
48
|
+
readonly profile: SubagentProfile;
|
|
49
|
+
}
|
|
50
|
+
/** Wire shape for `profiles.update` request payload. */
|
|
51
|
+
export interface ProfileUpdatePayload {
|
|
52
|
+
readonly profile: SubagentProfile;
|
|
53
|
+
}
|
|
54
|
+
/** Wire shape for `profiles.remove` request payload. */
|
|
55
|
+
export interface ProfileRemovePayload {
|
|
56
|
+
readonly id: string;
|
|
57
|
+
}
|
|
58
|
+
/** All ya-subagent RPC endpoint result values. */
|
|
59
|
+
export type YaSubagentValue = ProfileListResponse | ToolListResponse | RepairStats;
|
|
60
|
+
/**
|
|
61
|
+
* Register the ya-subagent RPC routes on the host's connection service.
|
|
62
|
+
* `connection` is provided by the host; the routes roll back with the
|
|
63
|
+
* plugin fiber (each `fetch.register` disposer is collected by an effect).
|
|
64
|
+
* Trust and browser authentication live on the physical `/api` carrier, so
|
|
65
|
+
* the routes carry no authority options of their own.
|
|
66
|
+
* @param ctx - host context.
|
|
67
|
+
* @param store - profile store.
|
|
68
|
+
*/
|
|
69
|
+
export declare function registerRpc(ctx: Context, store: ProfileStore): void;
|