dsh-side-chat-plus 0.3.2 → 0.3.3
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 +326 -326
- package/README.zh.md +268 -268
- package/dsh.plugin.json +1 -1
- package/lib/client-registry.js +125 -125
- package/lib/client-registry.js.map +1 -1
- package/lib/client.js +125 -125
- package/lib/client.js.map +1 -1
- package/lib/index.js +7 -2
- package/package.json +1 -1
- package/src/client/attachments/AttachmentRail.module.css +89 -89
- package/src/client/attachments/AttachmentRail.tsx +173 -173
- package/src/client/attachments/DropOverlay.module.css +38 -38
- package/src/client/attachments/DropOverlay.tsx +62 -62
- package/src/client/attachments/ImageLightbox.module.css +44 -44
- package/src/client/attachments/ImageLightbox.tsx +58 -58
- package/src/client/attachments/MessageImage.module.css +61 -61
- package/src/client/attachments/MessageImage.tsx +120 -120
- package/src/client/attachments/index.ts +19 -19
- package/src/client/client.module.css +1032 -1032
- package/src/client/index.tsx +1966 -1966
- package/src/client/locales.ts +173 -173
- package/src/context-types.ts +384 -384
- package/src/index.ts +14 -6
package/src/context-types.ts
CHANGED
|
@@ -1,384 +1,384 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Structural types for the cordis services this plugin consumes, plus the
|
|
3
|
-
* Context augmentation both halves share. A third-party plugin resolves
|
|
4
|
-
* outside the DSH monorepo's single cordis instance, so the upstream
|
|
5
|
-
* `declare module 'cordis'` augmentations do not reach this Context; the
|
|
6
|
-
* members below mirror the actual runtime shapes this plugin touches.
|
|
7
|
-
*
|
|
8
|
-
* The `sessions` field is a union of the HOST store face (get/list) and the
|
|
9
|
-
* CLIENT list feed (list.getSnapshot/subscribe): each half only touches its
|
|
10
|
-
* own side, and the shared declaration keeps the two cordis instance layers
|
|
11
|
-
* from colliding under one tsconfig.
|
|
12
|
-
*/
|
|
13
|
-
import type { IncomingMessage, ServerResponse } from 'node:http'
|
|
14
|
-
import type { Context } from 'cordis'
|
|
15
|
-
|
|
16
|
-
/** One named webserver route. */
|
|
17
|
-
export interface SideWebRoute {
|
|
18
|
-
kind: 'exact' | 'prefix'
|
|
19
|
-
path: string
|
|
20
|
-
handler: (req: IncomingMessage, res: ServerResponse) => void | Promise<void>
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/** The webServer service face this plugin uses. */
|
|
24
|
-
export interface SideWebServer {
|
|
25
|
-
register(route: SideWebRoute): () => void
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/** A published session's header slice (authoritative cwd, lineage, origin). */
|
|
29
|
-
export interface SideSessionHeader {
|
|
30
|
-
cwd?: string
|
|
31
|
-
parentSession?: string
|
|
32
|
-
origin?: 'subagent'
|
|
33
|
-
delegationDepth?: number
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/** One session event (fold source for history and permission current). */
|
|
37
|
-
export interface SideSessionEvent {
|
|
38
|
-
type: string
|
|
39
|
-
seq: number
|
|
40
|
-
time: number
|
|
41
|
-
data: Record<string, unknown>
|
|
42
|
-
surfaceOp?: 'append' | 'replace' | 'remove'
|
|
43
|
-
sourceEventSeqs?: number[]
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/** The live session face the host reads (header + append-only event log). */
|
|
47
|
-
export interface SideSession {
|
|
48
|
-
id: string
|
|
49
|
-
header: SideSessionHeader
|
|
50
|
-
events?: readonly SideSessionEvent[]
|
|
51
|
-
requestHeader?: () => { config?: { provider?: string; model?: string; reasoningEffort?: string; maxTokens?: number } } | undefined
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/** The host session store face (`ctx.sessions` host side). */
|
|
55
|
-
export interface SideSessionStore {
|
|
56
|
-
get(id: string): SideSession | undefined
|
|
57
|
-
list(): SideSession[]
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/** One session list row (client list feed). */
|
|
61
|
-
export interface SideSessionSummary {
|
|
62
|
-
id: string
|
|
63
|
-
displayTitle: string
|
|
64
|
-
cwd?: string
|
|
65
|
-
origin?: 'subagent'
|
|
66
|
-
parentId?: string
|
|
67
|
-
running: boolean
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/** The session list snapshot the browser half subscribes to. */
|
|
71
|
-
export interface SideSessionList {
|
|
72
|
-
current: string | undefined
|
|
73
|
-
byId: Record<string, SideSessionSummary>
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/** One selectable answer in a user-question dialog. */
|
|
77
|
-
export interface SideQuestionOption {
|
|
78
|
-
label: string
|
|
79
|
-
description?: string
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/** One question in a pending user-question dialog. */
|
|
83
|
-
export interface SideQuestionItem {
|
|
84
|
-
id: string
|
|
85
|
-
question: string
|
|
86
|
-
detail?: string
|
|
87
|
-
header?: string
|
|
88
|
-
options?: SideQuestionOption[]
|
|
89
|
-
multiSelect?: boolean
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/** A pending main-conversation interaction (question / plan-review / approval dialog). */
|
|
93
|
-
export interface SidePendingInteraction {
|
|
94
|
-
/** Presentation discriminator: the question family, or an approval. */
|
|
95
|
-
kind: 'question' | 'plan-review' | 'approval'
|
|
96
|
-
/** Opaque render identity and request key (e.g. `question:1`). */
|
|
97
|
-
key: string
|
|
98
|
-
sessionId: string
|
|
99
|
-
/** The request's question list (present for the question family). */
|
|
100
|
-
questions?: SideQuestionItem[]
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/** The per-session pending-interaction source exposed by the `uiSession` service. */
|
|
104
|
-
export interface SidePendingInteractionStore {
|
|
105
|
-
getSnapshot(): ReadonlyMap<string, SidePendingInteraction>
|
|
106
|
-
subscribe(fn: () => void): () => void
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/** The client sessions service face (list feed + scope resolution). */
|
|
110
|
-
export interface SideSessionsService {
|
|
111
|
-
list: {
|
|
112
|
-
getSnapshot(): SideSessionList
|
|
113
|
-
subscribe(fn: () => void): () => void
|
|
114
|
-
}
|
|
115
|
-
/** Resolve an Agent-scoped context view for a listed session id (use-and-discard). */
|
|
116
|
-
scope(id: string): Context | undefined
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/** The client UI-session service face (per-session pending interactions). */
|
|
120
|
-
export interface SideUiSessionService {
|
|
121
|
-
/** Per-session pending UI interaction (question / plan-review / approval). */
|
|
122
|
-
pendingInteractions: SidePendingInteractionStore
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/** Agent options (provider/model/maxTokens). */
|
|
126
|
-
export interface SideAgentOptions {
|
|
127
|
-
provider?: string
|
|
128
|
-
model?: string
|
|
129
|
-
maxTokens?: number
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/** The live agent face (`ctx.agents.get(id)` / `AgentHandle.agent`). */
|
|
133
|
-
export interface SideAgent {
|
|
134
|
-
readonly id: string
|
|
135
|
-
readonly options: SideAgentOptions
|
|
136
|
-
readonly session: SideSession
|
|
137
|
-
readonly status: string
|
|
138
|
-
readonly ctx: Context
|
|
139
|
-
followup(message: unknown): void
|
|
140
|
-
inject(message: unknown): void
|
|
141
|
-
cancel(cause: { kind: 'user' | 'parent' | 'disposed' } | { kind: 'hook'; reason: string }): void
|
|
142
|
-
whenIdle(): Promise<void>
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/** The agent handle `ctx.agents.create` resolves (owner tears the agent down). */
|
|
146
|
-
export interface SideAgentHandle {
|
|
147
|
-
agent: SideAgent
|
|
148
|
-
dispose(): Promise<void>
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/** `ctx.agents.create` options (mirror of CreateAgentOptions). */
|
|
152
|
-
export interface SideCreateAgentOptions {
|
|
153
|
-
sessionId: string
|
|
154
|
-
meta?: {
|
|
155
|
-
cwd?: string
|
|
156
|
-
parentSession?: string
|
|
157
|
-
agentPreset?: string
|
|
158
|
-
}
|
|
159
|
-
agentOptions?: SideAgentOptions
|
|
160
|
-
setup?: (agentCtx: Context) => void | Promise<void>
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/** The host agent registry face. */
|
|
164
|
-
export interface SideAgentsService {
|
|
165
|
-
get(id: string): SideAgent | undefined
|
|
166
|
-
create(options: SideCreateAgentOptions): Promise<SideAgentHandle>
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/** Live provider / model / reasoning-effort selection for one agent. */
|
|
170
|
-
export interface SideModelSelection {
|
|
171
|
-
provider: string
|
|
172
|
-
model: string
|
|
173
|
-
reasoningEffort?: string
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Mutable selection plus the value captured when the current step entered
|
|
178
|
-
* prompt assembly (`current` / `assembled`).
|
|
179
|
-
*/
|
|
180
|
-
export interface SideModelSelectionRef {
|
|
181
|
-
current: SideModelSelection | undefined
|
|
182
|
-
assembled: SideModelSelection | undefined
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* Couple a mutable selection to an agent's prompt assembly and request routing
|
|
187
|
-
* (`installModelSelection` on the agent package). Typed structurally rather
|
|
188
|
-
* than imported: this plugin resolves outside the DSH monorepo's single cordis
|
|
189
|
-
* instance, so the upstream export is reached through a loose signature.
|
|
190
|
-
*/
|
|
191
|
-
export type SideInstallModelSelection = (agentCtx: Context, selection: SideModelSelectionRef) => () => void
|
|
192
|
-
|
|
193
|
-
/** The workspace registry face (archive a session durably). */
|
|
194
|
-
export interface SideWorkspaceRegistry {
|
|
195
|
-
archiveSession(sessionId: string): Promise<void>
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/** `sessionQuery.readSession` snapshot. */
|
|
199
|
-
export interface SideSessionLogSnapshot {
|
|
200
|
-
session: SideSessionHeader
|
|
201
|
-
events: SideSessionEvent[]
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/** The session query face. */
|
|
205
|
-
export interface SideSessionQuery {
|
|
206
|
-
readSession(sessionId: string): Promise<SideSessionLogSnapshot>
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/** Sandbox mode vocabulary (read from the session override). */
|
|
210
|
-
export type SideSandboxMode = 'read-only' | 'workspace-write' | 'danger-full-access'
|
|
211
|
-
|
|
212
|
-
/** The sandbox policy face. */
|
|
213
|
-
export interface SideSandboxPolicy {
|
|
214
|
-
overrideOf(session: SideSession): SideSandboxMode | undefined
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/** One permission preset option. */
|
|
218
|
-
export interface SidePresetOption {
|
|
219
|
-
value: string
|
|
220
|
-
name: string
|
|
221
|
-
description?: string
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/** The permission presets face. */
|
|
225
|
-
export interface SidePermissionPresets {
|
|
226
|
-
current(events: readonly SideSessionEvent[]): string
|
|
227
|
-
set(session: SideSession, name: string): void
|
|
228
|
-
selectFor(state: unknown): { options: SidePresetOption[]; currentValue: string }
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/** The agent presets face (composeFrom joins a child to the parent's composition). */
|
|
232
|
-
export interface SideAgentPresets {
|
|
233
|
-
composeFrom(agentCtx: Context, parentCtx: Context): string | undefined
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/** One provider route. */
|
|
237
|
-
export interface SideLlmProvider {
|
|
238
|
-
id: string
|
|
239
|
-
name: string
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/** One model entry. */
|
|
243
|
-
export interface SideLlmModel {
|
|
244
|
-
provider: string
|
|
245
|
-
id: string
|
|
246
|
-
name: string
|
|
247
|
-
description?: string
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/** One reasoning-effort entry. */
|
|
251
|
-
export interface SideLlmEffort {
|
|
252
|
-
id: string
|
|
253
|
-
name: string
|
|
254
|
-
description?: string
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
/** One model-request stream chunk (minimal structural view for text collection). */
|
|
258
|
-
export interface SideLlmStreamChunk {
|
|
259
|
-
type: string
|
|
260
|
-
text?: string
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/** Minimal generate options the summarize route builds (a hand-built user prompt). */
|
|
264
|
-
export interface SideLlmGenerateOptions {
|
|
265
|
-
provider: string
|
|
266
|
-
model: string
|
|
267
|
-
reasoningEffort?: string
|
|
268
|
-
maxTokens?: number
|
|
269
|
-
signal?: AbortSignal
|
|
270
|
-
messages: Array<{
|
|
271
|
-
id?: string
|
|
272
|
-
role: 'user' | 'assistant' | 'system'
|
|
273
|
-
content: Array<{ type: 'text'; text: string }>
|
|
274
|
-
source?: { kind: string }
|
|
275
|
-
}>
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
/** The llm face (model/effort catalog + one-shot streaming calls). */
|
|
279
|
-
export interface SideLlm {
|
|
280
|
-
listProviders(): SideLlmProvider[]
|
|
281
|
-
listModels(provider: string): Promise<SideLlmModel[]>
|
|
282
|
-
resolveModelInfo(provider: string, model: string): Promise<{
|
|
283
|
-
provider: string
|
|
284
|
-
id: string
|
|
285
|
-
name: string
|
|
286
|
-
reasoning?: { efforts: readonly SideLlmEffort[]; defaultEffort?: string }
|
|
287
|
-
}>
|
|
288
|
-
stream(options: SideLlmGenerateOptions): AsyncIterable<SideLlmStreamChunk>
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
/** The client locale service face. */
|
|
292
|
-
export interface SideLocaleService {
|
|
293
|
-
getSnapshot(): { active: string }
|
|
294
|
-
subscribe(fn: () => void): () => void
|
|
295
|
-
register(ns: string, locale: string, dict: Record<string, string>): () => void
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
/** The host settings service face (namespace registration + read/write). */
|
|
299
|
-
export interface SideSettingsService {
|
|
300
|
-
register(ns: unknown, schema: unknown): { get(): unknown; watch(cb: (next: unknown, prev: unknown) => void): () => void }
|
|
301
|
-
describe(opts: { redactSecrets?: boolean }): Array<{ ns: unknown; value?: unknown; revision?: number }>
|
|
302
|
-
update(ns: unknown, patch: Record<string, unknown>, expectedRevision?: number): Promise<void>
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
/** The client slots service face (settings.section registration). */
|
|
306
|
-
export interface SideSlotsService {
|
|
307
|
-
inject(name: string, factory: () => () => void): void
|
|
308
|
-
register(options: Record<string, unknown>, component: unknown): () => void
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
/** One durable image reference (mirror of ImageAttachmentRef). */
|
|
312
|
-
export interface SideImageAttachmentRef {
|
|
313
|
-
attachmentId: string
|
|
314
|
-
mediaType: 'image/png' | 'image/jpeg' | 'image/webp' | 'image/gif'
|
|
315
|
-
bytes: number
|
|
316
|
-
width: number
|
|
317
|
-
height: number
|
|
318
|
-
name?: string
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
/** The host attachment store face (`ctx.attachments`). */
|
|
322
|
-
export interface SideAttachmentStore {
|
|
323
|
-
readonly imageLimits: {
|
|
324
|
-
maxImageBytes: number
|
|
325
|
-
maxImagesPerMessage: number
|
|
326
|
-
maxMessageImageBytes: number
|
|
327
|
-
maxImagePixels: number
|
|
328
|
-
mediaTypes: readonly string[]
|
|
329
|
-
}
|
|
330
|
-
validateImage(input: { data: Uint8Array; mediaType: string; name?: string }): Promise<void>
|
|
331
|
-
saveImage(input: { data: Uint8Array; mediaType: string; name?: string }): Promise<SideImageAttachmentRef>
|
|
332
|
-
readImage(ref: SideImageAttachmentRef): Promise<{ ref: SideImageAttachmentRef; data: Uint8Array }>
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
/** The host command registry face (`ctx.commands`). */
|
|
336
|
-
export interface SideCommandsService {
|
|
337
|
-
list(agent: SideAgent): Array<{ name: string; description: string }>
|
|
338
|
-
execute(agent: SideAgent, line: string, signal: AbortSignal): Promise<unknown>
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
/** The per-session composer input face this plugin writes to (draft-only). */
|
|
342
|
-
export interface SideSessionInput {
|
|
343
|
-
/** Replace the session composer draft (never submits). */
|
|
344
|
-
setDraft(text: string): void
|
|
345
|
-
/** Live input state store (draft read). */
|
|
346
|
-
state: { getSnapshot(): { draft: string } }
|
|
347
|
-
/** Surface a notice on the session composer. */
|
|
348
|
-
notify(level: 'info' | 'error', text: string): void
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
/** The conversation service face (`ctx.conversation`) — input registry only. */
|
|
352
|
-
export interface SideConversationService {
|
|
353
|
-
input: {
|
|
354
|
-
/** Resolve the input facade for one session-scope context. */
|
|
355
|
-
for(actx: Context): SideSessionInput
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
declare module 'cordis' {
|
|
360
|
-
interface Context {
|
|
361
|
-
webServer: SideWebServer
|
|
362
|
-
sessions: SideSessionStore & SideSessionsService
|
|
363
|
-
agents: SideAgentsService
|
|
364
|
-
workspaceRegistry: SideWorkspaceRegistry
|
|
365
|
-
sessionQuery: SideSessionQuery
|
|
366
|
-
sandboxPolicy: SideSandboxPolicy
|
|
367
|
-
permissionPresets: SidePermissionPresets
|
|
368
|
-
agentPresets: SideAgentPresets
|
|
369
|
-
llm: SideLlm
|
|
370
|
-
locale: SideLocaleService
|
|
371
|
-
settings: SideSettingsService
|
|
372
|
-
slots: SideSlotsService
|
|
373
|
-
attachments: SideAttachmentStore
|
|
374
|
-
commands: SideCommandsService
|
|
375
|
-
conversation: SideConversationService
|
|
376
|
-
uiSession: SideUiSessionService
|
|
377
|
-
inject(deps: string[], callback: (ctx: Context) => void): void
|
|
378
|
-
get(name: string): unknown | undefined
|
|
379
|
-
on(name: string, listener: (...args: any[]) => any): () => void
|
|
380
|
-
effect(fn: () => void | (() => void), label?: string): void
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
export type { Context }
|
|
1
|
+
/**
|
|
2
|
+
* Structural types for the cordis services this plugin consumes, plus the
|
|
3
|
+
* Context augmentation both halves share. A third-party plugin resolves
|
|
4
|
+
* outside the DSH monorepo's single cordis instance, so the upstream
|
|
5
|
+
* `declare module 'cordis'` augmentations do not reach this Context; the
|
|
6
|
+
* members below mirror the actual runtime shapes this plugin touches.
|
|
7
|
+
*
|
|
8
|
+
* The `sessions` field is a union of the HOST store face (get/list) and the
|
|
9
|
+
* CLIENT list feed (list.getSnapshot/subscribe): each half only touches its
|
|
10
|
+
* own side, and the shared declaration keeps the two cordis instance layers
|
|
11
|
+
* from colliding under one tsconfig.
|
|
12
|
+
*/
|
|
13
|
+
import type { IncomingMessage, ServerResponse } from 'node:http'
|
|
14
|
+
import type { Context } from 'cordis'
|
|
15
|
+
|
|
16
|
+
/** One named webserver route. */
|
|
17
|
+
export interface SideWebRoute {
|
|
18
|
+
kind: 'exact' | 'prefix'
|
|
19
|
+
path: string
|
|
20
|
+
handler: (req: IncomingMessage, res: ServerResponse) => void | Promise<void>
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** The webServer service face this plugin uses. */
|
|
24
|
+
export interface SideWebServer {
|
|
25
|
+
register(route: SideWebRoute): () => void
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** A published session's header slice (authoritative cwd, lineage, origin). */
|
|
29
|
+
export interface SideSessionHeader {
|
|
30
|
+
cwd?: string
|
|
31
|
+
parentSession?: string
|
|
32
|
+
origin?: 'subagent'
|
|
33
|
+
delegationDepth?: number
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** One session event (fold source for history and permission current). */
|
|
37
|
+
export interface SideSessionEvent {
|
|
38
|
+
type: string
|
|
39
|
+
seq: number
|
|
40
|
+
time: number
|
|
41
|
+
data: Record<string, unknown>
|
|
42
|
+
surfaceOp?: 'append' | 'replace' | 'remove'
|
|
43
|
+
sourceEventSeqs?: number[]
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** The live session face the host reads (header + append-only event log). */
|
|
47
|
+
export interface SideSession {
|
|
48
|
+
id: string
|
|
49
|
+
header: SideSessionHeader
|
|
50
|
+
events?: readonly SideSessionEvent[]
|
|
51
|
+
requestHeader?: () => { config?: { provider?: string; model?: string; reasoningEffort?: string; maxTokens?: number } } | undefined
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** The host session store face (`ctx.sessions` host side). */
|
|
55
|
+
export interface SideSessionStore {
|
|
56
|
+
get(id: string): SideSession | undefined
|
|
57
|
+
list(): SideSession[]
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** One session list row (client list feed). */
|
|
61
|
+
export interface SideSessionSummary {
|
|
62
|
+
id: string
|
|
63
|
+
displayTitle: string
|
|
64
|
+
cwd?: string
|
|
65
|
+
origin?: 'subagent'
|
|
66
|
+
parentId?: string
|
|
67
|
+
running: boolean
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** The session list snapshot the browser half subscribes to. */
|
|
71
|
+
export interface SideSessionList {
|
|
72
|
+
current: string | undefined
|
|
73
|
+
byId: Record<string, SideSessionSummary>
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** One selectable answer in a user-question dialog. */
|
|
77
|
+
export interface SideQuestionOption {
|
|
78
|
+
label: string
|
|
79
|
+
description?: string
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** One question in a pending user-question dialog. */
|
|
83
|
+
export interface SideQuestionItem {
|
|
84
|
+
id: string
|
|
85
|
+
question: string
|
|
86
|
+
detail?: string
|
|
87
|
+
header?: string
|
|
88
|
+
options?: SideQuestionOption[]
|
|
89
|
+
multiSelect?: boolean
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** A pending main-conversation interaction (question / plan-review / approval dialog). */
|
|
93
|
+
export interface SidePendingInteraction {
|
|
94
|
+
/** Presentation discriminator: the question family, or an approval. */
|
|
95
|
+
kind: 'question' | 'plan-review' | 'approval'
|
|
96
|
+
/** Opaque render identity and request key (e.g. `question:1`). */
|
|
97
|
+
key: string
|
|
98
|
+
sessionId: string
|
|
99
|
+
/** The request's question list (present for the question family). */
|
|
100
|
+
questions?: SideQuestionItem[]
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** The per-session pending-interaction source exposed by the `uiSession` service. */
|
|
104
|
+
export interface SidePendingInteractionStore {
|
|
105
|
+
getSnapshot(): ReadonlyMap<string, SidePendingInteraction>
|
|
106
|
+
subscribe(fn: () => void): () => void
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** The client sessions service face (list feed + scope resolution). */
|
|
110
|
+
export interface SideSessionsService {
|
|
111
|
+
list: {
|
|
112
|
+
getSnapshot(): SideSessionList
|
|
113
|
+
subscribe(fn: () => void): () => void
|
|
114
|
+
}
|
|
115
|
+
/** Resolve an Agent-scoped context view for a listed session id (use-and-discard). */
|
|
116
|
+
scope(id: string): Context | undefined
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** The client UI-session service face (per-session pending interactions). */
|
|
120
|
+
export interface SideUiSessionService {
|
|
121
|
+
/** Per-session pending UI interaction (question / plan-review / approval). */
|
|
122
|
+
pendingInteractions: SidePendingInteractionStore
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** Agent options (provider/model/maxTokens). */
|
|
126
|
+
export interface SideAgentOptions {
|
|
127
|
+
provider?: string
|
|
128
|
+
model?: string
|
|
129
|
+
maxTokens?: number
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** The live agent face (`ctx.agents.get(id)` / `AgentHandle.agent`). */
|
|
133
|
+
export interface SideAgent {
|
|
134
|
+
readonly id: string
|
|
135
|
+
readonly options: SideAgentOptions
|
|
136
|
+
readonly session: SideSession
|
|
137
|
+
readonly status: string
|
|
138
|
+
readonly ctx: Context
|
|
139
|
+
followup(message: unknown): void
|
|
140
|
+
inject(message: unknown): void
|
|
141
|
+
cancel(cause: { kind: 'user' | 'parent' | 'disposed' } | { kind: 'hook'; reason: string }): void
|
|
142
|
+
whenIdle(): Promise<void>
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** The agent handle `ctx.agents.create` resolves (owner tears the agent down). */
|
|
146
|
+
export interface SideAgentHandle {
|
|
147
|
+
agent: SideAgent
|
|
148
|
+
dispose(): Promise<void>
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** `ctx.agents.create` options (mirror of CreateAgentOptions). */
|
|
152
|
+
export interface SideCreateAgentOptions {
|
|
153
|
+
sessionId: string
|
|
154
|
+
meta?: {
|
|
155
|
+
cwd?: string
|
|
156
|
+
parentSession?: string
|
|
157
|
+
agentPreset?: string
|
|
158
|
+
}
|
|
159
|
+
agentOptions?: SideAgentOptions
|
|
160
|
+
setup?: (agentCtx: Context) => void | Promise<void>
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** The host agent registry face. */
|
|
164
|
+
export interface SideAgentsService {
|
|
165
|
+
get(id: string): SideAgent | undefined
|
|
166
|
+
create(options: SideCreateAgentOptions): Promise<SideAgentHandle>
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** Live provider / model / reasoning-effort selection for one agent. */
|
|
170
|
+
export interface SideModelSelection {
|
|
171
|
+
provider: string
|
|
172
|
+
model: string
|
|
173
|
+
reasoningEffort?: string
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Mutable selection plus the value captured when the current step entered
|
|
178
|
+
* prompt assembly (`current` / `assembled`).
|
|
179
|
+
*/
|
|
180
|
+
export interface SideModelSelectionRef {
|
|
181
|
+
current: SideModelSelection | undefined
|
|
182
|
+
assembled: SideModelSelection | undefined
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Couple a mutable selection to an agent's prompt assembly and request routing
|
|
187
|
+
* (`installModelSelection` on the agent package). Typed structurally rather
|
|
188
|
+
* than imported: this plugin resolves outside the DSH monorepo's single cordis
|
|
189
|
+
* instance, so the upstream export is reached through a loose signature.
|
|
190
|
+
*/
|
|
191
|
+
export type SideInstallModelSelection = (agentCtx: Context, selection: SideModelSelectionRef) => () => void
|
|
192
|
+
|
|
193
|
+
/** The workspace registry face (archive a session durably). */
|
|
194
|
+
export interface SideWorkspaceRegistry {
|
|
195
|
+
archiveSession(sessionId: string): Promise<void>
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/** `sessionQuery.readSession` snapshot. */
|
|
199
|
+
export interface SideSessionLogSnapshot {
|
|
200
|
+
session: SideSessionHeader
|
|
201
|
+
events: SideSessionEvent[]
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/** The session query face. */
|
|
205
|
+
export interface SideSessionQuery {
|
|
206
|
+
readSession(sessionId: string): Promise<SideSessionLogSnapshot>
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/** Sandbox mode vocabulary (read from the session override). */
|
|
210
|
+
export type SideSandboxMode = 'read-only' | 'workspace-write' | 'danger-full-access'
|
|
211
|
+
|
|
212
|
+
/** The sandbox policy face. */
|
|
213
|
+
export interface SideSandboxPolicy {
|
|
214
|
+
overrideOf(session: SideSession): SideSandboxMode | undefined
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** One permission preset option. */
|
|
218
|
+
export interface SidePresetOption {
|
|
219
|
+
value: string
|
|
220
|
+
name: string
|
|
221
|
+
description?: string
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/** The permission presets face. */
|
|
225
|
+
export interface SidePermissionPresets {
|
|
226
|
+
current(events: readonly SideSessionEvent[]): string
|
|
227
|
+
set(session: SideSession, name: string): void
|
|
228
|
+
selectFor(state: unknown): { options: SidePresetOption[]; currentValue: string }
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/** The agent presets face (composeFrom joins a child to the parent's composition). */
|
|
232
|
+
export interface SideAgentPresets {
|
|
233
|
+
composeFrom(agentCtx: Context, parentCtx: Context): string | undefined
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/** One provider route. */
|
|
237
|
+
export interface SideLlmProvider {
|
|
238
|
+
id: string
|
|
239
|
+
name: string
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/** One model entry. */
|
|
243
|
+
export interface SideLlmModel {
|
|
244
|
+
provider: string
|
|
245
|
+
id: string
|
|
246
|
+
name: string
|
|
247
|
+
description?: string
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/** One reasoning-effort entry. */
|
|
251
|
+
export interface SideLlmEffort {
|
|
252
|
+
id: string
|
|
253
|
+
name: string
|
|
254
|
+
description?: string
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/** One model-request stream chunk (minimal structural view for text collection). */
|
|
258
|
+
export interface SideLlmStreamChunk {
|
|
259
|
+
type: string
|
|
260
|
+
text?: string
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/** Minimal generate options the summarize route builds (a hand-built user prompt). */
|
|
264
|
+
export interface SideLlmGenerateOptions {
|
|
265
|
+
provider: string
|
|
266
|
+
model: string
|
|
267
|
+
reasoningEffort?: string
|
|
268
|
+
maxTokens?: number
|
|
269
|
+
signal?: AbortSignal
|
|
270
|
+
messages: Array<{
|
|
271
|
+
id?: string
|
|
272
|
+
role: 'user' | 'assistant' | 'system'
|
|
273
|
+
content: Array<{ type: 'text'; text: string }>
|
|
274
|
+
source?: { kind: string }
|
|
275
|
+
}>
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/** The llm face (model/effort catalog + one-shot streaming calls). */
|
|
279
|
+
export interface SideLlm {
|
|
280
|
+
listProviders(): SideLlmProvider[]
|
|
281
|
+
listModels(provider: string): Promise<SideLlmModel[]>
|
|
282
|
+
resolveModelInfo(provider: string, model: string): Promise<{
|
|
283
|
+
provider: string
|
|
284
|
+
id: string
|
|
285
|
+
name: string
|
|
286
|
+
reasoning?: { efforts: readonly SideLlmEffort[]; defaultEffort?: string }
|
|
287
|
+
}>
|
|
288
|
+
stream(options: SideLlmGenerateOptions): AsyncIterable<SideLlmStreamChunk>
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/** The client locale service face. */
|
|
292
|
+
export interface SideLocaleService {
|
|
293
|
+
getSnapshot(): { active: string }
|
|
294
|
+
subscribe(fn: () => void): () => void
|
|
295
|
+
register(ns: string, locale: string, dict: Record<string, string>): () => void
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/** The host settings service face (namespace registration + read/write). */
|
|
299
|
+
export interface SideSettingsService {
|
|
300
|
+
register(ns: unknown, schema: unknown): { get(): unknown; watch(cb: (next: unknown, prev: unknown) => void): () => void }
|
|
301
|
+
describe(opts: { redactSecrets?: boolean }): Array<{ ns: unknown; value?: unknown; revision?: number }>
|
|
302
|
+
update(ns: unknown, patch: Record<string, unknown>, expectedRevision?: number): Promise<void>
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/** The client slots service face (settings.section registration). */
|
|
306
|
+
export interface SideSlotsService {
|
|
307
|
+
inject(name: string, factory: () => () => void): void
|
|
308
|
+
register(options: Record<string, unknown>, component: unknown): () => void
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/** One durable image reference (mirror of ImageAttachmentRef). */
|
|
312
|
+
export interface SideImageAttachmentRef {
|
|
313
|
+
attachmentId: string
|
|
314
|
+
mediaType: 'image/png' | 'image/jpeg' | 'image/webp' | 'image/gif'
|
|
315
|
+
bytes: number
|
|
316
|
+
width: number
|
|
317
|
+
height: number
|
|
318
|
+
name?: string
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/** The host attachment store face (`ctx.attachments`). */
|
|
322
|
+
export interface SideAttachmentStore {
|
|
323
|
+
readonly imageLimits: {
|
|
324
|
+
maxImageBytes: number
|
|
325
|
+
maxImagesPerMessage: number
|
|
326
|
+
maxMessageImageBytes: number
|
|
327
|
+
maxImagePixels: number
|
|
328
|
+
mediaTypes: readonly string[]
|
|
329
|
+
}
|
|
330
|
+
validateImage(input: { data: Uint8Array; mediaType: string; name?: string }): Promise<void>
|
|
331
|
+
saveImage(input: { data: Uint8Array; mediaType: string; name?: string }): Promise<SideImageAttachmentRef>
|
|
332
|
+
readImage(ref: SideImageAttachmentRef): Promise<{ ref: SideImageAttachmentRef; data: Uint8Array }>
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/** The host command registry face (`ctx.commands`). */
|
|
336
|
+
export interface SideCommandsService {
|
|
337
|
+
list(agent: SideAgent): Array<{ name: string; description: string }>
|
|
338
|
+
execute(agent: SideAgent, line: string, signal: AbortSignal): Promise<unknown>
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/** The per-session composer input face this plugin writes to (draft-only). */
|
|
342
|
+
export interface SideSessionInput {
|
|
343
|
+
/** Replace the session composer draft (never submits). */
|
|
344
|
+
setDraft(text: string): void
|
|
345
|
+
/** Live input state store (draft read). */
|
|
346
|
+
state: { getSnapshot(): { draft: string } }
|
|
347
|
+
/** Surface a notice on the session composer. */
|
|
348
|
+
notify(level: 'info' | 'error', text: string): void
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/** The conversation service face (`ctx.conversation`) — input registry only. */
|
|
352
|
+
export interface SideConversationService {
|
|
353
|
+
input: {
|
|
354
|
+
/** Resolve the input facade for one session-scope context. */
|
|
355
|
+
for(actx: Context): SideSessionInput
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
declare module 'cordis' {
|
|
360
|
+
interface Context {
|
|
361
|
+
webServer: SideWebServer
|
|
362
|
+
sessions: SideSessionStore & SideSessionsService
|
|
363
|
+
agents: SideAgentsService
|
|
364
|
+
workspaceRegistry: SideWorkspaceRegistry
|
|
365
|
+
sessionQuery: SideSessionQuery
|
|
366
|
+
sandboxPolicy: SideSandboxPolicy
|
|
367
|
+
permissionPresets: SidePermissionPresets
|
|
368
|
+
agentPresets: SideAgentPresets
|
|
369
|
+
llm: SideLlm
|
|
370
|
+
locale: SideLocaleService
|
|
371
|
+
settings: SideSettingsService
|
|
372
|
+
slots: SideSlotsService
|
|
373
|
+
attachments: SideAttachmentStore
|
|
374
|
+
commands: SideCommandsService
|
|
375
|
+
conversation: SideConversationService
|
|
376
|
+
uiSession: SideUiSessionService
|
|
377
|
+
inject(deps: string[], callback: (ctx: Context) => void): void
|
|
378
|
+
get(name: string): unknown | undefined
|
|
379
|
+
on(name: string, listener: (...args: any[]) => any): () => void
|
|
380
|
+
effect(fn: () => void | (() => void), label?: string): void
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
export type { Context }
|