@steerable/agent-runtime 0.0.0-stage → 0.9.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/LICENSE +201 -0
- package/README.md +140 -2
- package/dist/index.d.ts +12 -0
- package/dist/index.js +12 -0
- package/dist/jsonrpc.d.ts +88 -0
- package/dist/jsonrpc.js +167 -0
- package/dist/methods.d.ts +16 -0
- package/dist/methods.js +58 -0
- package/dist/platform-runtime.d.ts +87 -0
- package/dist/platform-runtime.js +211 -0
- package/dist/runtime.d.ts +460 -0
- package/dist/runtime.js +446 -0
- package/dist/sidecar.d.ts +122 -0
- package/dist/sidecar.js +306 -0
- package/dist/transports.d.ts +68 -0
- package/dist/transports.js +57 -0
- package/package.json +57 -3
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `AgentRuntime` — the CoreLoop-level API of the framework for TypeScript
|
|
3
|
+
* products. Every method maps 1:1 onto the sidecar JSON-RPC surface
|
|
4
|
+
* (`docs/spec/sidecar.md`); the runtime drives the same Rust CoreLoop the
|
|
5
|
+
* server uses (via the Python sidecar facade), so there is no second
|
|
6
|
+
* implementation to drift.
|
|
7
|
+
*
|
|
8
|
+
* Streaming is exposed as an async-iterable of `SSEEvent`-shaped frames so
|
|
9
|
+
* callers can `for await` a turn, and as a `done` promise carrying the
|
|
10
|
+
* terminal status. `cancel` / `steer` target the in-flight stream by id.
|
|
11
|
+
*/
|
|
12
|
+
import type { AgentSession, HarnessTrace, SidecarHealth, SSEEvent, ToolCall, ToolResult, TraceEvent, TraceSpan } from '@steerable/agent-protocol';
|
|
13
|
+
import { SidecarProcess, type SidecarProcessOptions } from './sidecar.js';
|
|
14
|
+
export interface BranchPoint {
|
|
15
|
+
recordId: string;
|
|
16
|
+
lineage: string;
|
|
17
|
+
seq: number;
|
|
18
|
+
label?: string | null;
|
|
19
|
+
}
|
|
20
|
+
export interface BranchFamily {
|
|
21
|
+
lineage: string;
|
|
22
|
+
children: unknown[];
|
|
23
|
+
}
|
|
24
|
+
export interface SessionMessages {
|
|
25
|
+
recordId: string;
|
|
26
|
+
messages: {
|
|
27
|
+
seq: number;
|
|
28
|
+
role: string;
|
|
29
|
+
content: string;
|
|
30
|
+
}[];
|
|
31
|
+
}
|
|
32
|
+
export interface ToolDescriptor {
|
|
33
|
+
name: string;
|
|
34
|
+
description?: string;
|
|
35
|
+
parameters?: Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
export interface SkillInfo {
|
|
38
|
+
name: string;
|
|
39
|
+
path: string;
|
|
40
|
+
description?: string;
|
|
41
|
+
[key: string]: unknown;
|
|
42
|
+
}
|
|
43
|
+
export interface ApplyEditsResult {
|
|
44
|
+
content: string;
|
|
45
|
+
diff: string;
|
|
46
|
+
applied: number;
|
|
47
|
+
matches: unknown[];
|
|
48
|
+
}
|
|
49
|
+
export interface TraceFetchResult {
|
|
50
|
+
trace: HarnessTrace;
|
|
51
|
+
spans: TraceSpan[];
|
|
52
|
+
events: TraceEvent[];
|
|
53
|
+
}
|
|
54
|
+
export interface TraceExportResult {
|
|
55
|
+
status: string;
|
|
56
|
+
traceId: string;
|
|
57
|
+
privacyMode: string;
|
|
58
|
+
}
|
|
59
|
+
/** One finished turn, as `metrics.export` accepts it. Counts and labels only. */
|
|
60
|
+
export interface MetricsExportSample {
|
|
61
|
+
outcome: 'completed' | 'failed' | 'cancelled';
|
|
62
|
+
failureKind?: string | null;
|
|
63
|
+
attempts?: number | null;
|
|
64
|
+
retried?: boolean;
|
|
65
|
+
usedDirect?: boolean;
|
|
66
|
+
}
|
|
67
|
+
export interface MetricsExportResult {
|
|
68
|
+
status: string;
|
|
69
|
+
metrics: number;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Wire-level descriptor of one OpenAI-compat flag, as served by
|
|
73
|
+
* `compat.describe`. `kind` is `"bool"`, `"string-list"`, or
|
|
74
|
+
* `"enum:<opt1>,<opt2>"`-style; `default` mirrors the framework's
|
|
75
|
+
* `OpenAICompatFlags` defaults.
|
|
76
|
+
*/
|
|
77
|
+
export interface CompatFlagDescriptor {
|
|
78
|
+
key: string;
|
|
79
|
+
field: string;
|
|
80
|
+
kind: string;
|
|
81
|
+
default: unknown;
|
|
82
|
+
description: string;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* One harness implementation choice as served by `harness.describe`
|
|
86
|
+
* (W1.2.2): the impl name plus its assumption contract.
|
|
87
|
+
*/
|
|
88
|
+
export interface HarnessImplDescriptor {
|
|
89
|
+
impl: string;
|
|
90
|
+
assumes: string;
|
|
91
|
+
params?: Record<string, unknown>;
|
|
92
|
+
}
|
|
93
|
+
/** The `harness.describe` payload: the registry vocabulary plus the
|
|
94
|
+
* active default selection, keyed by dimension. */
|
|
95
|
+
export interface HarnessDescription {
|
|
96
|
+
available: Record<string, HarnessImplDescriptor[]>;
|
|
97
|
+
default: Record<string, HarnessImplDescriptor[] | HarnessImplDescriptor>;
|
|
98
|
+
}
|
|
99
|
+
/** One model id the configured gateway accepts (`models.list`), joined
|
|
100
|
+
* with the bundled models.dev capability catalog by the same resolution
|
|
101
|
+
* the request path's reasoning-effort clamp uses. `joinedFrom` keeps the
|
|
102
|
+
* leaf-join provenance; `capabilities: 'unknown'` means no catalog tier
|
|
103
|
+
* matched, so reasoning levels are unavailable rather than empty. */
|
|
104
|
+
export interface GatewayModelEntry {
|
|
105
|
+
id: string;
|
|
106
|
+
name: string | null;
|
|
107
|
+
window: number | null;
|
|
108
|
+
modalities: string[];
|
|
109
|
+
reasoningLevels: string[];
|
|
110
|
+
pricing: {
|
|
111
|
+
promptPerMtok: number | null;
|
|
112
|
+
completionPerMtok: number | null;
|
|
113
|
+
} | null;
|
|
114
|
+
joinedFrom: string | null;
|
|
115
|
+
capabilities: 'known' | 'unknown';
|
|
116
|
+
}
|
|
117
|
+
/** The `models.list` payload. `catalogStatus` is `live` when the listing
|
|
118
|
+
* was just fetched from the gateway, `stale` when served from cache after
|
|
119
|
+
* a refresh failure, and `offline` when the gateway is unreachable with no
|
|
120
|
+
* cache (then `models` is empty and `error` carries the cause). Discovery
|
|
121
|
+
* only — the catalog is not a routing whitelist. */
|
|
122
|
+
export interface GatewayModelCatalog {
|
|
123
|
+
models: GatewayModelEntry[];
|
|
124
|
+
catalogStatus: 'live' | 'stale' | 'offline';
|
|
125
|
+
error?: string;
|
|
126
|
+
fetchedAt?: number;
|
|
127
|
+
/** Absent on the offline path (no gateway/env context to report). */
|
|
128
|
+
current?: {
|
|
129
|
+
model: string | null;
|
|
130
|
+
reasoningEffort: string | null;
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* One built-in provider preset as served by `presets.describe`: the match
|
|
135
|
+
* rule (`host` + `modelPrefix`) plus the parameter patch it applies. Host
|
|
136
|
+
* settings UIs render their preset picker from this list.
|
|
137
|
+
*/
|
|
138
|
+
export interface ProviderPresetDescriptor {
|
|
139
|
+
host: string;
|
|
140
|
+
modelPrefix: string;
|
|
141
|
+
temperature: number | null;
|
|
142
|
+
topP: number | null;
|
|
143
|
+
maxTokens: number | null;
|
|
144
|
+
reasoningEffort: string | null;
|
|
145
|
+
extraBody: Record<string, unknown> | null;
|
|
146
|
+
}
|
|
147
|
+
/** The resolved parameter patch from `presets.resolve` (`None` fields omitted). */
|
|
148
|
+
export interface ProviderPreset {
|
|
149
|
+
temperature?: number;
|
|
150
|
+
topP?: number;
|
|
151
|
+
maxTokens?: number;
|
|
152
|
+
reasoningEffort?: string;
|
|
153
|
+
extraBody?: Record<string, unknown>;
|
|
154
|
+
}
|
|
155
|
+
/** One plugin record as served by the `plugin.*` lifecycle RPCs. */
|
|
156
|
+
export interface PluginRecord {
|
|
157
|
+
name: string;
|
|
158
|
+
origin: string;
|
|
159
|
+
tools: string[];
|
|
160
|
+
enabled: boolean;
|
|
161
|
+
reloadable: boolean;
|
|
162
|
+
}
|
|
163
|
+
/** One enabled plugin's tool as served by `plugin.tools.describe`. */
|
|
164
|
+
export interface PluginToolDescriptor {
|
|
165
|
+
name: string;
|
|
166
|
+
description: string;
|
|
167
|
+
schema: Record<string, unknown>;
|
|
168
|
+
mode: string;
|
|
169
|
+
exposure: 'direct' | 'deferred' | 'hidden';
|
|
170
|
+
requireConsent: boolean;
|
|
171
|
+
concurrencySafe: boolean;
|
|
172
|
+
plugin: string | null;
|
|
173
|
+
}
|
|
174
|
+
/** Recursive node of the `agent.session.tree` branch-family view. */
|
|
175
|
+
export interface SessionTreeNode {
|
|
176
|
+
recordId: string;
|
|
177
|
+
sourceRecordId: string | null;
|
|
178
|
+
sourceUntilSeq: number | null;
|
|
179
|
+
label: string | null;
|
|
180
|
+
depth: number;
|
|
181
|
+
children: SessionTreeNode[];
|
|
182
|
+
}
|
|
183
|
+
/** The `agent.session.tree` payload; `truncated` marks a family cut by the
|
|
184
|
+
* depth/node bounds documented on the Python handler. */
|
|
185
|
+
export interface SessionTreeResult {
|
|
186
|
+
recordId: string;
|
|
187
|
+
tree: SessionTreeNode;
|
|
188
|
+
nodeCount: number;
|
|
189
|
+
truncated: boolean;
|
|
190
|
+
}
|
|
191
|
+
export type ChatStreamStatus = 'completed' | 'cancelled' | 'budget_exhausted' | 'error';
|
|
192
|
+
export interface ChatStreamHandle {
|
|
193
|
+
/** Server-assigned stream id (also the cancel/steer target). */
|
|
194
|
+
readonly streamId: string;
|
|
195
|
+
/** Turn events: content deltas, tool calls/results, child lifecycle. */
|
|
196
|
+
readonly events: AsyncIterable<SSEEvent>;
|
|
197
|
+
/**
|
|
198
|
+
* Resolves with the terminal status once `stream.done`/`stream.error`
|
|
199
|
+
* arrives. Never rejects for a *completed* turn; rejects only when the
|
|
200
|
+
* transport dies mid-turn.
|
|
201
|
+
*/
|
|
202
|
+
readonly done: Promise<{
|
|
203
|
+
status: ChatStreamStatus;
|
|
204
|
+
cancelled: boolean;
|
|
205
|
+
}>;
|
|
206
|
+
}
|
|
207
|
+
export interface ChatStreamParams {
|
|
208
|
+
/** LLM provider kind: "openai_compat" | "anthropic" | <custom>. */
|
|
209
|
+
provider: string;
|
|
210
|
+
/** Model id understood by the provider. */
|
|
211
|
+
model: string;
|
|
212
|
+
/**
|
|
213
|
+
* Full message list for the turn (OpenAI chat shape). This doubles as the
|
|
214
|
+
* WS3 history seed: the sidecar reconciles it against the session record.
|
|
215
|
+
*/
|
|
216
|
+
messages: Array<{
|
|
217
|
+
role: string;
|
|
218
|
+
content: unknown;
|
|
219
|
+
[key: string]: unknown;
|
|
220
|
+
}>;
|
|
221
|
+
baseUrl?: string;
|
|
222
|
+
apiKey?: string;
|
|
223
|
+
/** History seed window the host already rendered (see WS3 contract). */
|
|
224
|
+
historySeed?: unknown[];
|
|
225
|
+
/** Orchestration opt-in: {maxDepth?, maxParallel?, childMaxRounds?,
|
|
226
|
+
* childMaxToolErrors?}; child limits default to the parent loop's. */
|
|
227
|
+
orchestration?: {
|
|
228
|
+
maxDepth?: number;
|
|
229
|
+
maxParallel?: number;
|
|
230
|
+
childMaxRounds?: number;
|
|
231
|
+
childMaxToolErrors?: number;
|
|
232
|
+
};
|
|
233
|
+
/** Per-request tool domain narrowing (fail-closed on the loop side). */
|
|
234
|
+
toolFilter?: string[];
|
|
235
|
+
/** Approval policy for this turn. */
|
|
236
|
+
approval?: Record<string, unknown>;
|
|
237
|
+
/** Anything else the sidecar accepts is passed through untouched. */
|
|
238
|
+
[key: string]: unknown;
|
|
239
|
+
}
|
|
240
|
+
export interface AgentRuntimeOptions extends SidecarProcessOptions {
|
|
241
|
+
/**
|
|
242
|
+
* Host tool handlers for the reverse channel: the CoreLoop calls these
|
|
243
|
+
* via `tool.invoke` while a turn runs. Register at construction or with
|
|
244
|
+
* `registerTool`.
|
|
245
|
+
*/
|
|
246
|
+
tools?: Record<string, (args: Record<string, unknown>) => Promise<Partial<ToolResult> | string>>;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Host confined-spawn capability (W2.2.1): the sidecar sends
|
|
250
|
+
* `host.process.spawn` when the platform has no command-rewriting sandbox
|
|
251
|
+
* backend (Windows) and the request opted into host spawn. The host spawns
|
|
252
|
+
* the command confined (restricted token + JobObject on Windows) and reports
|
|
253
|
+
* the enforcement it actually applied. Contract: docs/spec/safety.md
|
|
254
|
+
* "Host capability surface".
|
|
255
|
+
*/
|
|
256
|
+
export interface HostSpawnRequest {
|
|
257
|
+
command: string;
|
|
258
|
+
cwd?: string;
|
|
259
|
+
policy: {
|
|
260
|
+
writableRoots: string[];
|
|
261
|
+
network: boolean;
|
|
262
|
+
allowedHosts: string[];
|
|
263
|
+
};
|
|
264
|
+
context?: {
|
|
265
|
+
chatId?: string;
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
export interface HostSpawnResult {
|
|
269
|
+
exitCode: number;
|
|
270
|
+
stdout: string;
|
|
271
|
+
stderr: string;
|
|
272
|
+
truncated?: boolean;
|
|
273
|
+
/** Enforcement the host actually applied; omitting it reports `none`. */
|
|
274
|
+
sandbox?: {
|
|
275
|
+
backend: string;
|
|
276
|
+
enforcement: 'full' | 'partial' | 'none';
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
export declare class AgentRuntime {
|
|
280
|
+
readonly process: SidecarProcess;
|
|
281
|
+
private readonly toolHandlers;
|
|
282
|
+
private spawnHandler;
|
|
283
|
+
private readonly streams;
|
|
284
|
+
constructor(options?: AgentRuntimeOptions);
|
|
285
|
+
/** Spawn the sidecar and wait for readiness. */
|
|
286
|
+
start(): Promise<void>;
|
|
287
|
+
/** Graceful drain and exit; in-flight streams finish or fail first. */
|
|
288
|
+
close(): Promise<void>;
|
|
289
|
+
/** Register a host tool the CoreLoop may call back during turns. */
|
|
290
|
+
registerTool(name: string, handler: (args: Record<string, unknown>) => Promise<Partial<ToolResult> | string>): void;
|
|
291
|
+
/**
|
|
292
|
+
* Register the host confined-spawn capability. Without a handler,
|
|
293
|
+
* `host.process.spawn` reverse calls are rejected and the sidecar fails
|
|
294
|
+
* closed (the command never runs unsandboxed on no-backend platforms).
|
|
295
|
+
*/
|
|
296
|
+
onProcessSpawn(handler: (request: HostSpawnRequest) => Promise<HostSpawnResult>): void;
|
|
297
|
+
ping(): Promise<SidecarHealth>;
|
|
298
|
+
createSession(input: {
|
|
299
|
+
chatId: string;
|
|
300
|
+
userId: string;
|
|
301
|
+
projectId?: string | null;
|
|
302
|
+
scenario?: string;
|
|
303
|
+
stageData?: Record<string, unknown> | null;
|
|
304
|
+
}): Promise<AgentSession>;
|
|
305
|
+
resumeSession(sessionId: string): Promise<AgentSession>;
|
|
306
|
+
listSessions(filter?: {
|
|
307
|
+
userId?: string;
|
|
308
|
+
chatId?: string;
|
|
309
|
+
activeOnly?: boolean;
|
|
310
|
+
}): Promise<AgentSession[]>;
|
|
311
|
+
/** Fork a record into a new branch without running a turn. */
|
|
312
|
+
forkSession(params: {
|
|
313
|
+
sessionId: string;
|
|
314
|
+
recordId: string;
|
|
315
|
+
label?: string;
|
|
316
|
+
}): Promise<BranchPoint>;
|
|
317
|
+
/** Branch-family view for a lineage. */
|
|
318
|
+
sessionBranches(lineage: string): Promise<BranchFamily>;
|
|
319
|
+
/**
|
|
320
|
+
* Projected post-boundary message span of a history record — what the
|
|
321
|
+
* model would see on resume. Fails loud on unknown records.
|
|
322
|
+
*/
|
|
323
|
+
sessionMessages(recordId: string): Promise<SessionMessages>;
|
|
324
|
+
/**
|
|
325
|
+
* Start one CoreLoop turn. Resolves with a handle as soon as the sidecar
|
|
326
|
+
* assigns a stream id; consume `handle.events` for the turn and await
|
|
327
|
+
* `handle.done` for the terminal status.
|
|
328
|
+
*/
|
|
329
|
+
chatStream(params: ChatStreamParams): Promise<ChatStreamHandle>;
|
|
330
|
+
/** Cooperative cancel: the loop winds down at the next safe point. */
|
|
331
|
+
cancelChat(streamId: string): Promise<void>;
|
|
332
|
+
/** Mid-turn steer; resolves true when the running turn accepted it. */
|
|
333
|
+
steerChat(streamId: string, content: string): Promise<boolean>;
|
|
334
|
+
/** Fork the record of a running turn. */
|
|
335
|
+
forkChat(streamId: string, label?: string): Promise<BranchPoint>;
|
|
336
|
+
listTools(): Promise<ToolDescriptor[]>;
|
|
337
|
+
invokeTool(call: ToolCall): Promise<ToolResult>;
|
|
338
|
+
listSkills(roots: string[]): Promise<{
|
|
339
|
+
skills: SkillInfo[];
|
|
340
|
+
}>;
|
|
341
|
+
applyEdits(params: {
|
|
342
|
+
content: string;
|
|
343
|
+
edits: unknown[];
|
|
344
|
+
}): Promise<ApplyEditsResult>;
|
|
345
|
+
fetchTrace(traceId: string): Promise<TraceFetchResult>;
|
|
346
|
+
exportTrace(traceId: string): Promise<TraceExportResult>;
|
|
347
|
+
/** POST turn-outcome counters to a collector's `/v1/metrics`. */
|
|
348
|
+
exportMetrics(params: {
|
|
349
|
+
endpoint: string;
|
|
350
|
+
samples: MetricsExportSample[];
|
|
351
|
+
serviceName?: string;
|
|
352
|
+
}): Promise<MetricsExportResult>;
|
|
353
|
+
getConfig(): Promise<Record<string, unknown>>;
|
|
354
|
+
setConfig(patch: Record<string, unknown>): Promise<void>;
|
|
355
|
+
/**
|
|
356
|
+
* The framework-owned OpenAI-compat flag vocabulary (`describe_compat_flags`
|
|
357
|
+
* on the Python side). Host settings UIs render their compat section from
|
|
358
|
+
* these descriptors instead of hardcoding flag names, so a new flag needs
|
|
359
|
+
* no host-side constant to stay in sync.
|
|
360
|
+
*/
|
|
361
|
+
describeCompatFlags(): Promise<{
|
|
362
|
+
flags: CompatFlagDescriptor[];
|
|
363
|
+
}>;
|
|
364
|
+
/**
|
|
365
|
+
* Per-exec enforcement this host can actually reach (`sandbox.describe`),
|
|
366
|
+
* given the egress arguments a turn will send. Hosts that set
|
|
367
|
+
* `execSandbox.requireFull` from a platform guess refuse every shell call
|
|
368
|
+
* on backends that cannot pin per-host (bwrap, Landlock, Windows). Probe
|
|
369
|
+
* once and require full only when the reply is `full`.
|
|
370
|
+
*/
|
|
371
|
+
describeSandbox(params?: {
|
|
372
|
+
network?: boolean;
|
|
373
|
+
allowedHosts?: string[];
|
|
374
|
+
shell?: string;
|
|
375
|
+
}): Promise<{
|
|
376
|
+
backend: string;
|
|
377
|
+
enforcement: 'full' | 'partial' | 'none';
|
|
378
|
+
}>;
|
|
379
|
+
/**
|
|
380
|
+
* The framework-owned harness vocabulary (`harness.describe`, W1.2.2):
|
|
381
|
+
* every dimension's available implementations with their assumption
|
|
382
|
+
* contracts, plus the active default selection. Host harness pickers
|
|
383
|
+
* render from this payload; a new strategy needs no host-side constant.
|
|
384
|
+
*/
|
|
385
|
+
describeHarness(): Promise<HarnessDescription>;
|
|
386
|
+
/**
|
|
387
|
+
* The gateway's live model catalog (`models.list`): the ids the
|
|
388
|
+
* configured `STEERABLE_BASE_URL` actually accepts, joined with
|
|
389
|
+
* models.dev capabilities — reasoning levels included — by the same
|
|
390
|
+
* resolution the request path's clamp uses, so a picker and the wire
|
|
391
|
+
* never disagree about a model's knob. Host model pickers render from
|
|
392
|
+
* this payload and badge the `stale`/`offline` states.
|
|
393
|
+
*/
|
|
394
|
+
listModels(params?: {
|
|
395
|
+
baseUrl?: string;
|
|
396
|
+
apiKey?: string;
|
|
397
|
+
refresh?: boolean;
|
|
398
|
+
provider?: string;
|
|
399
|
+
}): Promise<GatewayModelCatalog>;
|
|
400
|
+
/** Every plugin the sidecar registry knows, with lifecycle state. */
|
|
401
|
+
listPlugins(): Promise<{
|
|
402
|
+
plugins: PluginRecord[];
|
|
403
|
+
}>;
|
|
404
|
+
/** Enable a registered plugin; rejects invalid_params on unknown names. */
|
|
405
|
+
enablePlugin(name: string): Promise<{
|
|
406
|
+
plugin: PluginRecord;
|
|
407
|
+
}>;
|
|
408
|
+
/** Disable a plugin without unloading its code. */
|
|
409
|
+
disablePlugin(name: string): Promise<{
|
|
410
|
+
plugin: PluginRecord;
|
|
411
|
+
}>;
|
|
412
|
+
/** Hot-reload a reloadable plugin from its source. */
|
|
413
|
+
reloadPlugin(name: string): Promise<{
|
|
414
|
+
plugin: PluginRecord;
|
|
415
|
+
}>;
|
|
416
|
+
/**
|
|
417
|
+
* Descriptors for every tool an enabled plugin provides. Hosts that own
|
|
418
|
+
* the model-visible tool list advertise these and call them with
|
|
419
|
+
* `tool.invoke`; disabled plugins contribute none.
|
|
420
|
+
*/
|
|
421
|
+
describePluginTools(): Promise<{
|
|
422
|
+
tools: PluginToolDescriptor[];
|
|
423
|
+
}>;
|
|
424
|
+
/** The framework-owned provider-preset table for host settings UIs. */
|
|
425
|
+
describePresets(): Promise<{
|
|
426
|
+
presets: ProviderPresetDescriptor[];
|
|
427
|
+
}>;
|
|
428
|
+
/**
|
|
429
|
+
* The bundled serving-provider catalog (`catalog.describe`): default
|
|
430
|
+
* URLs, sidecar wire kinds, and chat-capable model ids. Host vendor
|
|
431
|
+
* pickers render from this payload so a catalog refresh needs no
|
|
432
|
+
* host-side constant.
|
|
433
|
+
*/
|
|
434
|
+
describeCatalog(): Promise<{
|
|
435
|
+
providers: Array<{
|
|
436
|
+
id: string;
|
|
437
|
+
apiBaseUrl: string | null;
|
|
438
|
+
envVars: string[];
|
|
439
|
+
wireKind: string;
|
|
440
|
+
models: string[];
|
|
441
|
+
}>;
|
|
442
|
+
}>;
|
|
443
|
+
/** Which preset a (baseUrl, model) pair would auto-match; null when none. */
|
|
444
|
+
resolvePreset(input: {
|
|
445
|
+
baseUrl?: string;
|
|
446
|
+
model?: string;
|
|
447
|
+
}): Promise<{
|
|
448
|
+
preset: ProviderPreset | null;
|
|
449
|
+
}>;
|
|
450
|
+
/** The full branch family containing a record (pi-style tree view). */
|
|
451
|
+
sessionTree(recordId: string): Promise<SessionTreeResult>;
|
|
452
|
+
/**
|
|
453
|
+
* Ask a running turn to compact its transcript at the next pre_step
|
|
454
|
+
* boundary (CC `/compact` parity). Soft-fails false when the stream
|
|
455
|
+
* already completed, mirroring steerChat.
|
|
456
|
+
*/
|
|
457
|
+
compactChat(streamId: string): Promise<boolean>;
|
|
458
|
+
private handleReverse;
|
|
459
|
+
private routeStreamNotification;
|
|
460
|
+
}
|