@agentproto/runtime 0.8.0 → 1.0.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/dist/index.d.ts +1038 -95
- package/dist/index.mjs +2014 -338
- package/dist/index.mjs.map +1 -1
- package/dist/resume-strategies.mjs +42 -13
- package/dist/resume-strategies.mjs.map +1 -1
- package/package.json +14 -12
package/dist/index.d.ts
CHANGED
|
@@ -2,9 +2,12 @@ import { DoctypeSpec } from '@agentproto/manifest';
|
|
|
2
2
|
import { B as BuildHeartbeatAgent } from './heartbeat-COGpMrJS.js';
|
|
3
3
|
export { H as HeartbeatAgent, a as HeartbeatRunner, R as RuntimeEvent, b as RuntimeEvents, p as parseDuration } from './heartbeat-COGpMrJS.js';
|
|
4
4
|
import { AcpPermissionResolution, AcpMcpServer } from '@agentproto/acp';
|
|
5
|
+
import { SessionMode } from '@agentproto/acp/client';
|
|
6
|
+
export { SessionMode } from '@agentproto/acp/client';
|
|
5
7
|
import { ChildProcess } from 'node:child_process';
|
|
6
|
-
import { W as WorktreeIsolationMode,
|
|
8
|
+
import { W as WorktreeIsolationMode, A as AdapterAuthDescriptor, R as ResolvedAuthSpec, D as DeclaredAdapterOption } from './config-BRKy_SAF.js';
|
|
7
9
|
export { a as AuthEcho, b as AuthResolutionError, C as CredentialSource, c as DefaultsAdapterAuthConfig, d as DefaultsAdapterConfig, e as ResolvedSpawnAuthMaterial, f as ResolvedSpawnDefaults, S as SpawnDefaultsConfig, g as credentialFingerprint, n as normalizeSkillsOption, r as resolveAuthSpec, h as resolveSpawnDefaults } from './config-BRKy_SAF.js';
|
|
10
|
+
import { AuthProfile } from '@agentproto/auth';
|
|
8
11
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
9
12
|
import { AdapterHandle, SetupField, AdapterResolver, AdapterLister, AdapterEntry } from '@agentproto/provider-kit';
|
|
10
13
|
import { SandboxProvider } from '@agentproto/sandbox';
|
|
@@ -132,6 +135,177 @@ interface UsageDescriptorFields {
|
|
|
132
135
|
*/
|
|
133
136
|
declare function projectSessionUsage(desc: UsageDescriptorFields): SessionUsage;
|
|
134
137
|
|
|
138
|
+
/**
|
|
139
|
+
* SessionConfig — the unified per-session config surface, decomposed into
|
|
140
|
+
* orthogonal axes (SPEC §3.1, out-of-repo design doc
|
|
141
|
+
* `agentproto-session-config-axes/SPEC.md`). Pure types + a `decomposeMode`/
|
|
142
|
+
* `composeMode` shim over the legacy AIP-45 `mode` string — no I/O, no runtime
|
|
143
|
+
* wiring, no adapter behavior change. This is the additive type foundation
|
|
144
|
+
* (SPEC §7.2 build step 1); the live spawn-path extraction (deleting gateway
|
|
145
|
+
* modes, sourcing posture from the ACP registry) is a separate later step.
|
|
146
|
+
*
|
|
147
|
+
* Boundary note: this module deliberately does NOT import from
|
|
148
|
+
* `@agentproto/auth`. `packages/runtime` intentionally has no dependency on
|
|
149
|
+
* that package (`mcp-credential-deps.ts:1-9`), so the named-profile record it
|
|
150
|
+
* owns — `AuthProfile` (`packages/auth/src/profile-types.ts:24`, shipped in
|
|
151
|
+
* #470) — is referenced by citation, never redefined here: the `access` axis
|
|
152
|
+
* only needs a `profileRef` string, and the profile record itself stays in
|
|
153
|
+
* `@agentproto/auth`. The narrow `AuthMethod` *facet*, by contrast, is
|
|
154
|
+
* structurally mirrored below (§3.1) — the descriptor's `accessProfile` echo
|
|
155
|
+
* (§3.7) names it, and mirroring a two-value string union is cheaper than
|
|
156
|
+
* taking a package dependency on `@agentproto/auth` for it, the same
|
|
157
|
+
* structural-mirror rationale as `DeclaredAdapterMode` (below) and
|
|
158
|
+
* `DeclaredAdapterOption` (`spawn-defaults.ts:447`).
|
|
159
|
+
*
|
|
160
|
+
* It DOES, however, import a VALUE — the legacy AIP-45 mode-id classification
|
|
161
|
+
* (`inferLegacyModeKind`) — from `@agentproto/driver-agent-cli` (a lean,
|
|
162
|
+
* acyclic runtime → driver edge; the driver never depends back on the runtime).
|
|
163
|
+
* Unlike the type mirrors above (a mirror can't silently break — the compiler
|
|
164
|
+
* still checks structural compatibility), the gateway/posture id SET is a value
|
|
165
|
+
* list needed on BOTH sides of the driver/runtime boundary — here for
|
|
166
|
+
* `decomposeMode` and in the driver's `composeSpawn` back-compat shim — so it
|
|
167
|
+
* is single-sourced in the driver (its AIP-45 home) rather than copied, which
|
|
168
|
+
* for a value list WOULD silently drift. Only the daemon-domain canonical-
|
|
169
|
+
* posture VALUE mapping (`POSTURE_MODE_VALUES`) stays local.
|
|
170
|
+
*/
|
|
171
|
+
/**
|
|
172
|
+
* Reasoning / compute budget label.
|
|
173
|
+
*
|
|
174
|
+
* SUPERSET ONLY — this flat union is the documented ceiling, NOT the valid set.
|
|
175
|
+
* The real accepted values are a function of (adapter × model), resolved at
|
|
176
|
+
* runtime (SPEC §3.9): the same label maps to a different compute budget across
|
|
177
|
+
* models, and `"max"` / `"ultracode"` are session-only and model-gated (opus
|
|
178
|
+
* offers `ultracode`, haiku does not —
|
|
179
|
+
* `adapters/claude-code/src/index.ts:310-321`). Consumers must resolve the
|
|
180
|
+
* offerable set per session/model, never treat this enum as authoritative.
|
|
181
|
+
*/
|
|
182
|
+
type EffortLevel = "low" | "medium" | "high" | "xhigh" | "max" | "ultracode";
|
|
183
|
+
/**
|
|
184
|
+
* agentproto-canonical posture — a portable, normalized vocabulary for "what
|
|
185
|
+
* the agent may DO" (SPEC §3.1/§3.4a). A canonical posture resolves to a
|
|
186
|
+
* harness `SessionModeId` when the session's advertised `availableModes` has an
|
|
187
|
+
* equivalent (native, enforced, live via `setSessionMode`); otherwise it is
|
|
188
|
+
* applied as an injected system-prompt preamble (advisory, not a permission
|
|
189
|
+
* boundary — SPEC risk Rw).
|
|
190
|
+
*/
|
|
191
|
+
type CanonicalPosture = "default" | "plan" | "accept-edits" | "bypass" | "read-only";
|
|
192
|
+
/**
|
|
193
|
+
* The posture axis: either an agentproto-canonical posture OR a raw harness
|
|
194
|
+
* mode id sourced directly from the harness's own ACP mode registry
|
|
195
|
+
* (`SessionModeState.availableModes` — SDK `types.gen.d.ts:4227`). Postures are
|
|
196
|
+
* NOT a manifest mode list going forward (SPEC §3.4a); the `{ harnessModeId }`
|
|
197
|
+
* form carries a native mode the canonical vocabulary doesn't name.
|
|
198
|
+
*/
|
|
199
|
+
type Posture = CanonicalPosture | {
|
|
200
|
+
harnessModeId: string;
|
|
201
|
+
};
|
|
202
|
+
/**
|
|
203
|
+
* Endpoint / billing rail — model/route config, NOT a mode (SPEC §3.4a). A
|
|
204
|
+
* gateway is reached by resolving the model's `@route` against the catalog
|
|
205
|
+
* (`packages/model-catalog/src/route-identity/index.ts:1-46`) and applying its
|
|
206
|
+
* base_url + credential-scrub on the route apply-path; `access` (which profile
|
|
207
|
+
* is eligible) is downstream of THIS axis (SPEC §1c).
|
|
208
|
+
*/
|
|
209
|
+
interface RouteSpec {
|
|
210
|
+
/** Preset id ("anthropic"/direct, "moonshot", "openrouter", "requesty",
|
|
211
|
+
* "deepseek") or a custom id paired with an explicit `baseUrl`. */
|
|
212
|
+
gateway: string;
|
|
213
|
+
/** Resolved base URL; carried only for a custom gateway the catalog can't
|
|
214
|
+
* resolve. The attached profile's credential is resolved separately (§1c),
|
|
215
|
+
* never inlined here. */
|
|
216
|
+
baseUrl?: string;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* What enters context. `"lean"` drops bundled skills
|
|
220
|
+
* (`adapters/claude-code/src/index.ts:196-204`); `"full"` is the default. The
|
|
221
|
+
* `(string & {})` arm keeps a future adapter-declared context profile from
|
|
222
|
+
* being blocked while preserving literal autocompletion for the known values.
|
|
223
|
+
*/
|
|
224
|
+
type ContextProfile = "full" | "lean" | (string & {});
|
|
225
|
+
/**
|
|
226
|
+
* How an attached auth profile authenticates — the narrow eligibility gate,
|
|
227
|
+
* a *facet* of a named profile (SPEC §1c/§3.1), NOT a session-level enum. A
|
|
228
|
+
* structural mirror of `@agentproto/auth`'s `AuthMethod`
|
|
229
|
+
* (`packages/auth/src/profile-types.ts:21`, #470): `"api-key"` ↔ `tokenKind
|
|
230
|
+
* "pat"`, `"oauth-bearer"` ↔ `tokenKind "oat"` (a subscription bearer). Kept
|
|
231
|
+
* here — rather than imported — because `packages/runtime` has no dependency
|
|
232
|
+
* on `@agentproto/auth` (see the boundary note above); only the descriptor's
|
|
233
|
+
* `accessProfile` echo (§3.7) needs to name it.
|
|
234
|
+
*/
|
|
235
|
+
type AuthMethod = "oauth-bearer" | "api-key";
|
|
236
|
+
/**
|
|
237
|
+
* The complete per-session config surface, decomposed into orthogonal axes
|
|
238
|
+
* (SPEC §3.1). Every field optional; omission = "adapter default" for that
|
|
239
|
+
* axis. The decomposed axes are the canonical form — persistence and transport
|
|
240
|
+
* use these fields, never a recomposed legacy `mode` string (SPEC §3.8).
|
|
241
|
+
*/
|
|
242
|
+
interface SessionConfig {
|
|
243
|
+
/** Route-identity ref: `[route:]vendor/product[:pin][@route]`
|
|
244
|
+
* (`packages/model-catalog/src/route-identity/index.ts:1-46`). */
|
|
245
|
+
model?: string;
|
|
246
|
+
effort?: EffortLevel;
|
|
247
|
+
/** Attach a NAMED auth profile by id (SPEC §1c). The profile record —
|
|
248
|
+
* `AuthProfile { id, vendor, method, credentialRef, label? }` — lives in
|
|
249
|
+
* `@agentproto/auth` (`packages/auth/src/profile-types.ts:24`, #470), NOT on
|
|
250
|
+
* the session and NOT in `providers.json`. Omit ⇒ default profile. */
|
|
251
|
+
access?: {
|
|
252
|
+
profileRef?: string;
|
|
253
|
+
};
|
|
254
|
+
/** Endpoint / gateway rail; `access` is downstream of this (SPEC §1c). */
|
|
255
|
+
route?: RouteSpec;
|
|
256
|
+
/** What the agent may DO. */
|
|
257
|
+
posture?: Posture;
|
|
258
|
+
/** What enters context. */
|
|
259
|
+
contextProfile?: ContextProfile;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Manifest-declared AIP-45 mode id + axis discriminant — the minimum
|
|
263
|
+
* `decomposeMode`/`composeMode` need from `AgentCliMode` (driver `types.ts`).
|
|
264
|
+
* Mirrors its `id`/`kind` fields structurally rather than importing the full
|
|
265
|
+
* `AgentCliMode` TYPE surface from `@agentproto/driver-agent-cli` — the same
|
|
266
|
+
* structural-mirror pattern as `DeclaredAdapterOption` (`spawn-defaults.ts:447`)
|
|
267
|
+
* and `DeclaredAdapterPreset` (`preset-tools.ts`). (The module does take a
|
|
268
|
+
* value-level import — `inferLegacyModeKind` — from that package; see the
|
|
269
|
+
* boundary note at the top for why a shared value list is single-sourced, not
|
|
270
|
+
* mirrored.)
|
|
271
|
+
*
|
|
272
|
+
* `kind` narrows to a single meaningful value going forward — `"context"` (the
|
|
273
|
+
* one axis with no ACP-protocol home); routes come from the catalog and
|
|
274
|
+
* postures from the harness's ACP registry (SPEC §3.4a). `"posture"`/`"route"`
|
|
275
|
+
* remain accepted so `decomposeMode` can still classify a LEGACY tagged
|
|
276
|
+
* manifest during migration.
|
|
277
|
+
*/
|
|
278
|
+
interface DeclaredAdapterMode {
|
|
279
|
+
id: string;
|
|
280
|
+
kind?: "posture" | "route" | "context";
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Map ONE legacy `mode` id (AIP-45 `modes[]`) onto its orthogonal axis
|
|
284
|
+
* (SPEC §3.5). Classification order: (1) the mode's own explicit `kind` tag;
|
|
285
|
+
* (2) inference over well-known ids (gateway ids ⇒ route, known posture ids ⇒
|
|
286
|
+
* posture); (3) a truly-unknown id defaults to `contextProfile` —
|
|
287
|
+
* least-privilege, since defaulting to `posture` or `route` could silently
|
|
288
|
+
* grant elevated permissions or reroute billing (SPEC risk R4).
|
|
289
|
+
*
|
|
290
|
+
* Always yields a `CanonicalPosture` for the posture axis, never a
|
|
291
|
+
* `{ harnessModeId }` — the shim speaks the portable vocabulary only; raw
|
|
292
|
+
* harness modes come from the ACP registry, not a legacy `mode` id.
|
|
293
|
+
*/
|
|
294
|
+
declare function decomposeMode(modes: readonly DeclaredAdapterMode[], modeId: string): Partial<SessionConfig>;
|
|
295
|
+
/**
|
|
296
|
+
* The reverse of `decomposeMode` — picks the single legacy mode id whose
|
|
297
|
+
* decomposition matches `cfg`.
|
|
298
|
+
*
|
|
299
|
+
* LOSSY / display-and-back-compat ONLY (SPEC §3.8). A single legacy `mode`
|
|
300
|
+
* string cannot represent an orthogonal combination — `{ posture: "plan",
|
|
301
|
+
* route: { gateway: "moonshot" } }` has no single legacy id — so `composeMode`
|
|
302
|
+
* returns the FIRST declared mode whose axis matches and silently drops the
|
|
303
|
+
* rest. It is NEVER a storage or transport form: the driver applies each axis's
|
|
304
|
+
* env/argv patch directly, and anything that must persist/transmit config uses
|
|
305
|
+
* the decomposed axes. Returns undefined when no declared mode matches.
|
|
306
|
+
*/
|
|
307
|
+
declare function composeMode(cfg: Partial<SessionConfig>, modes: readonly DeclaredAdapterMode[]): string | undefined;
|
|
308
|
+
|
|
135
309
|
/**
|
|
136
310
|
* In-process pub/sub bus for session lifecycle events. Separate from
|
|
137
311
|
* RuntimeEvents (global daemon bus) — session events are scoped to
|
|
@@ -141,7 +315,8 @@ declare function projectSessionUsage(desc: UsageDescriptorFields): SessionUsage;
|
|
|
141
315
|
* (fire-and-forget HTTP), RoutineRunner (state machine fan-in),
|
|
142
316
|
* and session_monitor MCP tool (long-poll multiplexed).
|
|
143
317
|
*/
|
|
144
|
-
|
|
318
|
+
|
|
319
|
+
type SessionEventType = "session:turn-end" | "session:awaiting-input" | "session:permission-request" | "session:permission-resolved" | "session:exited" | "session:command-done" | "session:model-changed" | "session:config-changed" | "policy:passed" | "policy:failed" | "policy:commit-ready" | "policy:committed" | "cron:fired" | "cron:succeeded" | "cron:failed";
|
|
145
320
|
/**
|
|
146
321
|
* Structured detail on why a session is awaiting input, when derivable.
|
|
147
322
|
* `source: "structured"` — a driver-reported ACP-style prompt (e.g. a tool
|
|
@@ -241,6 +416,60 @@ interface SessionCommandDoneEvent {
|
|
|
241
416
|
exitCode: number;
|
|
242
417
|
ts: string;
|
|
243
418
|
}
|
|
419
|
+
/**
|
|
420
|
+
* Emitted when `SessionsRegistry.setModel` successfully switches a LIVE
|
|
421
|
+
* agent-cli session's model (`POST /sessions/:id/model`, `session_set_model`
|
|
422
|
+
* MCP tool). Only fires on `applied: true` — a rejected switch changes
|
|
423
|
+
* nothing about the session, so there's nothing to announce. `model` is the
|
|
424
|
+
* new value now reflected on `SessionDescriptor.model` (and therefore on the
|
|
425
|
+
* next `session_list` / SSE `sessionUpdate` a client sees). Consumers:
|
|
426
|
+
* `session_events_poll`, the webhook notifier, and the routine engine —
|
|
427
|
+
* same distribution as every other lifecycle event on this bus.
|
|
428
|
+
*/
|
|
429
|
+
interface SessionModelChangedEvent {
|
|
430
|
+
type: "session:model-changed";
|
|
431
|
+
sessionId: string;
|
|
432
|
+
model: string;
|
|
433
|
+
label?: string;
|
|
434
|
+
ts: string;
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* The `SessionConfig` axis a `session:config-changed` event reports. Reuses
|
|
438
|
+
* the axis vocabulary of `SessionConfig` itself (`session-config.ts`, SPEC
|
|
439
|
+
* §3.1) so there's a single source of truth for the axis names — model /
|
|
440
|
+
* effort / access / route / posture / contextProfile.
|
|
441
|
+
*/
|
|
442
|
+
type SessionConfigAxis = keyof SessionConfig;
|
|
443
|
+
/**
|
|
444
|
+
* Emitted when a SINGLE `SessionConfig` axis is changed on a session and the
|
|
445
|
+
* change actually took effect (SPEC §7.2 build step 4). This is the shared,
|
|
446
|
+
* axis-generic successor to `session:model-changed`: the live config verbs
|
|
447
|
+
* (`agent_set_effort` / `agent_set_posture`, step 5) and restart-with-override
|
|
448
|
+
* (step 6) all announce their single-axis change through THIS event, carrying
|
|
449
|
+
* which axis moved and the new value now reflected on the descriptor.
|
|
450
|
+
*
|
|
451
|
+
* A model change still ALSO emits `session:model-changed` as a back-compat
|
|
452
|
+
* alias (`sessions.ts` `setModel`) so existing subscribers keep working; new
|
|
453
|
+
* consumers should prefer this event and switch on `axis`.
|
|
454
|
+
*
|
|
455
|
+
* Discriminated by `axis`, with `value` typed to that axis's `SessionConfig`
|
|
456
|
+
* field — a `model` change carries a `string`, an `effort` change an
|
|
457
|
+
* `EffortLevel`, a `route` change a `RouteSpec`, and so on. Same bus
|
|
458
|
+
* distribution as every other lifecycle event (`session_events_poll`, the
|
|
459
|
+
* webhook notifier, the routine engine).
|
|
460
|
+
*/
|
|
461
|
+
type SessionConfigChangedEvent = {
|
|
462
|
+
[A in SessionConfigAxis]: {
|
|
463
|
+
type: "session:config-changed";
|
|
464
|
+
sessionId: string;
|
|
465
|
+
/** Which `SessionConfig` axis changed. */
|
|
466
|
+
axis: A;
|
|
467
|
+
/** The axis's new value, as now reflected on `SessionDescriptor`. */
|
|
468
|
+
value: NonNullable<SessionConfig[A]>;
|
|
469
|
+
label?: string;
|
|
470
|
+
ts: string;
|
|
471
|
+
};
|
|
472
|
+
}[SessionConfigAxis];
|
|
244
473
|
/** Emitted by the supervisor when a completion policy's gate passes. */
|
|
245
474
|
interface PolicyPassedEvent {
|
|
246
475
|
type: "policy:passed";
|
|
@@ -305,7 +534,7 @@ interface CronFailedEvent {
|
|
|
305
534
|
error: string;
|
|
306
535
|
ts: string;
|
|
307
536
|
}
|
|
308
|
-
type SessionEvent = SessionTurnEndEvent | SessionAwaitingInputEvent | SessionPermissionRequestEvent | SessionPermissionResolvedEvent | SessionExitedEvent | SessionCommandDoneEvent | PolicyPassedEvent | PolicyFailedEvent | PolicyCommitReadyEvent | PolicyCommittedEvent | CronFiredEvent | CronSucceededEvent | CronFailedEvent;
|
|
537
|
+
type SessionEvent = SessionTurnEndEvent | SessionAwaitingInputEvent | SessionPermissionRequestEvent | SessionPermissionResolvedEvent | SessionExitedEvent | SessionCommandDoneEvent | SessionModelChangedEvent | SessionConfigChangedEvent | PolicyPassedEvent | PolicyFailedEvent | PolicyCommitReadyEvent | PolicyCommittedEvent | CronFiredEvent | CronSucceededEvent | CronFailedEvent;
|
|
309
538
|
interface SessionEventBus {
|
|
310
539
|
emit(ev: SessionEvent): void;
|
|
311
540
|
/** Subscribe to a specific event type. Returns an unsubscribe fn. */
|
|
@@ -375,8 +604,117 @@ interface AgentSessionLike {
|
|
|
375
604
|
* drivers that don't model held permissions (sandbox proxy, future
|
|
376
605
|
* transports). */
|
|
377
606
|
respondPermission?(requestId: string, resolution: AcpPermissionResolution): boolean | Promise<boolean>;
|
|
607
|
+
/**
|
|
608
|
+
* Switch the active model on this LIVE session — mirrors
|
|
609
|
+
* `@agentproto/driver-agent-cli`'s `AgentCliRuntimeSession.setModel`
|
|
610
|
+
* without importing it (this package stays driver-decoupled, same
|
|
611
|
+
* reasoning as the rest of this structural interface). Optional: absent
|
|
612
|
+
* for a session shape that doesn't support live model switching (a
|
|
613
|
+
* sandboxed proxy session, or a future non-agent-cli transport) —
|
|
614
|
+
* `SessionsRegistry.setModel` treats a missing method as
|
|
615
|
+
* `{applied:false, reason:"not-supported"}` rather than throwing.
|
|
616
|
+
*/
|
|
617
|
+
setModel?(modelId: string): Promise<SetSessionModelResult>;
|
|
618
|
+
/**
|
|
619
|
+
* Switch the reasoning/compute budget on this LIVE session — mirrors
|
|
620
|
+
* `@agentproto/driver-agent-cli`'s `AgentCliRuntimeSession.setEffort`
|
|
621
|
+
* (ACP `session/set_config_option(configId:"effort")`), same driver-decoupled
|
|
622
|
+
* structural-mirror reasoning as `setModel` above. Optional: absent for a
|
|
623
|
+
* session shape with no live config surface (sandboxed proxy, future
|
|
624
|
+
* transport) — `SessionsRegistry.setEffort` treats a missing method as
|
|
625
|
+
* `{applied:false, reason:"not-supported"}` rather than throwing.
|
|
626
|
+
*/
|
|
627
|
+
setEffort?(effort: string): Promise<SetSessionEffortResult>;
|
|
628
|
+
/**
|
|
629
|
+
* Switch the native posture (harness mode) on this LIVE session — mirrors
|
|
630
|
+
* `@agentproto/driver-agent-cli`'s `AgentCliRuntimeSession.setSessionMode`
|
|
631
|
+
* (ACP `session/set_mode`). Optional, same treatment as `setModel`/`setEffort`.
|
|
632
|
+
*/
|
|
633
|
+
setSessionMode?(modeId: string): Promise<SetSessionModeResult>;
|
|
634
|
+
/**
|
|
635
|
+
* The harness's advertised session modes captured at connect time
|
|
636
|
+
* (`SessionModeState.availableModes`, #482 ACP capability read-surface).
|
|
637
|
+
* `SessionsRegistry.setPosture` resolves a requested posture against this to
|
|
638
|
+
* decide native-live vs restart (SPEC §3.4a). Absent/empty for arms with no
|
|
639
|
+
* native mode registry — treated as "no native mode", so any posture pick
|
|
640
|
+
* routes to restart.
|
|
641
|
+
*/
|
|
642
|
+
readonly availableModes?: readonly SessionMode[];
|
|
378
643
|
close(): Promise<void>;
|
|
379
644
|
}
|
|
645
|
+
/** Result of `SessionsRegistry.setModel` — see that method's doc comment. */
|
|
646
|
+
interface SetSessionModelResult {
|
|
647
|
+
applied: boolean;
|
|
648
|
+
/** The model id now active. Present only when `applied` is true. */
|
|
649
|
+
model?: string;
|
|
650
|
+
/** Present only when `applied` is false — see
|
|
651
|
+
* `@agentproto/driver-agent-cli`'s `SetModelResult` for the reason
|
|
652
|
+
* vocabulary this passes through verbatim. */
|
|
653
|
+
reason?: string;
|
|
654
|
+
/**
|
|
655
|
+
* Present only on the model↔route guard refusal (SPEC risk R2 / §4.4): the
|
|
656
|
+
* requested model's route-identity crosses the session's current route/vendor
|
|
657
|
+
* boundary, which a live `setModel` cannot perform (route is a spawn-time
|
|
658
|
+
* `ANTHROPIC_BASE_URL`, not a live ACP config option). The daemon refuses the
|
|
659
|
+
* live switch (`applied:false, reason:"requires-restart"`) rather than
|
|
660
|
+
* silently keeping the old endpoint, and hands back the override a
|
|
661
|
+
* restart-with-override (step 6) should carry to apply model + route together.
|
|
662
|
+
*/
|
|
663
|
+
suggestedOverride?: {
|
|
664
|
+
route: RouteSpec;
|
|
665
|
+
model: string;
|
|
666
|
+
};
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* Result of `SessionsRegistry.setEffort` — mirrors the driver's
|
|
670
|
+
* `SetEffortResult` (see `AgentSessionLike.setEffort`). Effort is a per-model
|
|
671
|
+
* capability (SPEC §3.9); a rejected label is a soft `{applied:false, reason}`
|
|
672
|
+
* (SPEC risk R7), never thrown.
|
|
673
|
+
*/
|
|
674
|
+
interface SetSessionEffortResult {
|
|
675
|
+
applied: boolean;
|
|
676
|
+
/** The effort label now active. Present only when `applied` is true. */
|
|
677
|
+
effort?: string;
|
|
678
|
+
/** Present only when `applied` is false — passes the driver's reason through
|
|
679
|
+
* verbatim (`"not-supported"`, or the wrapper's own rejection detail). */
|
|
680
|
+
reason?: string;
|
|
681
|
+
}
|
|
682
|
+
/** Result of a mid-session `setSessionMode` attempt on the driver session —
|
|
683
|
+
* structural mirror of `@agentproto/driver-agent-cli`'s `SetSessionModeResult`,
|
|
684
|
+
* used by {@link AgentSessionLike.setSessionMode}. */
|
|
685
|
+
interface SetSessionModeResult {
|
|
686
|
+
applied: boolean;
|
|
687
|
+
/** The mode id that took effect. Present only when `applied` is true. */
|
|
688
|
+
modeId?: string;
|
|
689
|
+
/** Present only when `applied` is false — the driver's reason verbatim. */
|
|
690
|
+
reason?: string;
|
|
691
|
+
}
|
|
692
|
+
/**
|
|
693
|
+
* Result of `SessionsRegistry.setPosture` (SPEC §4.2, build step 5). A posture
|
|
694
|
+
* that maps to a native advertised harness mode is switched LIVE via
|
|
695
|
+
* `setSessionMode` (`applied:true`); one with no native mode (prompt-injected /
|
|
696
|
+
* env-applied) is NOT forced live — it resolves
|
|
697
|
+
* `{applied:false, reason:"requires-restart"}` so the caller routes it through
|
|
698
|
+
* the restart-with-override path (step 6, not implemented here).
|
|
699
|
+
*/
|
|
700
|
+
interface SetSessionPostureResult {
|
|
701
|
+
applied: boolean;
|
|
702
|
+
/** The posture now active. Present only when `applied` is true. */
|
|
703
|
+
posture?: Posture;
|
|
704
|
+
/** The native harness mode id switched to — present only on a native
|
|
705
|
+
* (`applied:true`) switch, so a caller can echo exactly what took effect. */
|
|
706
|
+
modeId?: string;
|
|
707
|
+
/** Present only when `applied` is false — `"requires-restart"` when the
|
|
708
|
+
* posture has no native mode (prompt/env apply-path needs a fresh spawn),
|
|
709
|
+
* `"not-supported"` for a session with no live mode surface, or the harness's
|
|
710
|
+
* own rejection detail when a native switch was attempted and refused. */
|
|
711
|
+
reason?: string;
|
|
712
|
+
/** How the requested posture resolved against the harness's advertised modes
|
|
713
|
+
* (`native` | `prompt` | `noop` | `unavailable`, from `resolvePosture`) —
|
|
714
|
+
* lets the caller distinguish "needs restart because prompt-injected" from a
|
|
715
|
+
* genuine native-switch rejection. */
|
|
716
|
+
resolution?: "native" | "prompt" | "noop" | "unavailable";
|
|
717
|
+
}
|
|
380
718
|
/**
|
|
381
719
|
* Minimal PTY surface — structurally compatible with
|
|
382
720
|
* @agentproto/acp/tunnel's PtyProcess (node-pty's IPty wrapper). The
|
|
@@ -473,6 +811,24 @@ interface SessionAuthEcho {
|
|
|
473
811
|
credentialSource?: "explicit-config" | "providers-store" | "none";
|
|
474
812
|
setEnv?: string;
|
|
475
813
|
}
|
|
814
|
+
/**
|
|
815
|
+
* The `access` axis's descriptor ECHO (SPEC §3.6/§3.7) — a non-secret
|
|
816
|
+
* description of the NAMED auth profile attached to the session, recorded so a
|
|
817
|
+
* client chip can NAME the wallet ("Jeremy Max") without re-resolving it. This
|
|
818
|
+
* is deliberately separate from {@link SessionAuthEcho}, which stays as-is: the
|
|
819
|
+
* `auth` echo is the resolver's observable output (mode + credential
|
|
820
|
+
* fingerprint), this is the profile IDENTITY the operator selected. NEVER the
|
|
821
|
+
* credential — `profileRef` resolves through `@agentproto/auth` at read time
|
|
822
|
+
* (`packages/auth/src/profile-types.ts:24`, #470). `profileRef` is always set
|
|
823
|
+
* when this object is present (the profile is the reason it exists); the rest
|
|
824
|
+
* mirror the `AuthProfile` fields the chip renders.
|
|
825
|
+
*/
|
|
826
|
+
interface SessionAccessProfileEcho {
|
|
827
|
+
profileRef: string;
|
|
828
|
+
label?: string;
|
|
829
|
+
vendor: string;
|
|
830
|
+
method: AuthMethod;
|
|
831
|
+
}
|
|
476
832
|
interface SessionDescriptor {
|
|
477
833
|
id: string;
|
|
478
834
|
kind: SessionKind;
|
|
@@ -535,6 +891,19 @@ interface SessionDescriptor {
|
|
|
535
891
|
* about, for a UI that would otherwise show the adapter's argv. Distinct
|
|
536
892
|
* from `label`, which the spawner supplies and which always wins. */
|
|
537
893
|
title?: string;
|
|
894
|
+
/** Housekeeping-only visibility flag: hides the session from `list()`'s
|
|
895
|
+
* default view (`session_list`, `GET /sessions`, panels) once set. Never
|
|
896
|
+
* touches the daemon otherwise — the process is already gone by the time
|
|
897
|
+
* this is set (see the terminal-status guard on `archiveSession`), the
|
|
898
|
+
* transcript stays fully readable via `get()`/`findByIdOrName` (neither
|
|
899
|
+
* filters on it), and `list({ includeArchived: true })` still returns it.
|
|
900
|
+
* Set by `archiveSession`/`unarchiveSession` (session-tools.ts's
|
|
901
|
+
* `session_archive`/`session_unarchive`), persisted like every other
|
|
902
|
+
* descriptor field, and round-trips through `loadHistorySnapshot` on
|
|
903
|
+
* reboot since it's carried by the same `...desc` spread every other
|
|
904
|
+
* field is. Absent (not `false`) for every descriptor from before this
|
|
905
|
+
* field existed — treated the same as `false` everywhere it's read. */
|
|
906
|
+
archived?: boolean;
|
|
538
907
|
/** True when the session was spawned under a real PTY (node-pty)
|
|
539
908
|
* instead of `child_process.spawn`. PTY sessions carry raw ANSI
|
|
540
909
|
* bytes (alt-screen, key bindings, colors); attach goes through
|
|
@@ -573,8 +942,38 @@ interface SessionDescriptor {
|
|
|
573
942
|
* `/sessions/agent` to spin up a fresh ACP runtime. Undefined for
|
|
574
943
|
* pty/command kinds. */
|
|
575
944
|
adapterSlug?: string;
|
|
945
|
+
/**
|
|
946
|
+
* AIP-45 mode the session was spawned with (`AgentCliStartOptions.config.
|
|
947
|
+
* mode` — e.g. claude-code's `plan`/`accept-edits`, a gateway preset mode
|
|
948
|
+
* like `moonshot`). Undefined for the adapter's default/native mode.
|
|
949
|
+
* Recorded so a client can tell whether a candidate model switch stays
|
|
950
|
+
* within THIS mode (live-switchable via `setModel`) or needs a different
|
|
951
|
+
* one (`AgentCliModelEntry.mode` on the target) — a mode change is
|
|
952
|
+
* spawn-time env/argv rewiring (e.g. `ANTHROPIC_BASE_URL`), which
|
|
953
|
+
* `POST /sessions/:id/model` cannot perform on a live process; that case
|
|
954
|
+
* is surfaced to clients as `requires-restart`, never silently attempted.
|
|
955
|
+
*/
|
|
956
|
+
mode?: string;
|
|
576
957
|
/** The model the session was requested to run (echoed back at spawn). */
|
|
577
958
|
model?: string;
|
|
959
|
+
/** Reasoning / compute budget the session resolved to (SPEC §3.1 axis 2).
|
|
960
|
+
* A LIVE-switchable axis; echoed here so the effort chip re-opens on it. */
|
|
961
|
+
effort?: EffortLevel;
|
|
962
|
+
/** What the agent may DO (SPEC §3.1 axis 5) — an agentproto-canonical
|
|
963
|
+
* posture or a raw `{ harnessModeId }` sourced from the harness's ACP mode
|
|
964
|
+
* registry (SPEC §3.4a). */
|
|
965
|
+
posture?: Posture;
|
|
966
|
+
/** Endpoint / gateway rail (SPEC §3.1 axis 4). `baseUrl` is carried only
|
|
967
|
+
* for a custom gateway the catalog can't resolve; `access` is downstream
|
|
968
|
+
* of this axis (SPEC §1c). */
|
|
969
|
+
route?: RouteSpec;
|
|
970
|
+
/** What enters context (SPEC §3.1 axis 5b) — `"lean"` drops bundled skills. */
|
|
971
|
+
contextProfile?: ContextProfile;
|
|
972
|
+
/** The `access` axis echo (SPEC §3.6/§3.7): the NAMED auth profile attached
|
|
973
|
+
* to the session, so the access chip can name the wallet. Distinct from the
|
|
974
|
+
* `auth` fingerprint echo below, which stays as-is — see
|
|
975
|
+
* {@link SessionAccessProfileEcho}. NEVER the credential. */
|
|
976
|
+
accessProfile?: SessionAccessProfileEcho;
|
|
578
977
|
/**
|
|
579
978
|
* Deterministic billing-auth mode + a non-secret credential fingerprint,
|
|
580
979
|
* recorded at spawn time for adapters that resolved an explicit
|
|
@@ -710,6 +1109,26 @@ interface SessionDescriptor {
|
|
|
710
1109
|
* matching command session; absent otherwise (including for legacy
|
|
711
1110
|
* rows persisted before this field existed). */
|
|
712
1111
|
priorCommandSessionId?: string;
|
|
1112
|
+
/** Id of the prior session this one continues from — set when this
|
|
1113
|
+
* session was spawned by `session_restart` (or the cron scheduler's
|
|
1114
|
+
* `prompt-session` action), even when the resume attempt itself
|
|
1115
|
+
* couldn't establish continuity: a fresh fallback spawn (adapter
|
|
1116
|
+
* rejected the resume id as "not found") is still "restarted from"
|
|
1117
|
+
* the prior session, just without conversation history carried over.
|
|
1118
|
+
* Absent for a session spawned directly (not via restart). Persisted
|
|
1119
|
+
* on the STORED descriptor (not just grafted onto the restart
|
|
1120
|
+
* result's JSON, as it used to be) so it survives a `list()`/`get()`
|
|
1121
|
+
* poll refresh and a daemon restart — see `resumeVia` for how the
|
|
1122
|
+
* continuity was (or wasn't) established, and the transcript panel's
|
|
1123
|
+
* chain-walk (vscode package) for the read side. */
|
|
1124
|
+
resumedFrom?: string;
|
|
1125
|
+
/** Human-readable resume path used to arrive at `resumedFrom` — e.g.
|
|
1126
|
+
* "resumed via claude --resume" (provider-native PTY resume) or
|
|
1127
|
+
* "resumed via ACP" (adapter-level resume), or `""` when no
|
|
1128
|
+
* continuity was established (a fresh fallback spawn — see
|
|
1129
|
+
* `resumedFrom`). Only meaningful alongside `resumedFrom`; absent
|
|
1130
|
+
* (never `""`) for a session that wasn't spawned via restart. */
|
|
1131
|
+
resumeVia?: string;
|
|
713
1132
|
/** Adapter id that drives this session (e.g. "camofox", "bureau"). */
|
|
714
1133
|
browserAdapterId?: string;
|
|
715
1134
|
/** Port the browser service listens on. */
|
|
@@ -874,6 +1293,67 @@ interface SessionsRegistry {
|
|
|
874
1293
|
interruptSession(id: string): Promise<{
|
|
875
1294
|
wasBusy: boolean;
|
|
876
1295
|
}>;
|
|
1296
|
+
/**
|
|
1297
|
+
* Switch the model on a LIVE agent-cli session without restarting it —
|
|
1298
|
+
* the mid-session counterpart to `spawnAgent`'s `input.model` (which
|
|
1299
|
+
* only applies at spawn time). Delegates to the driver session's own
|
|
1300
|
+
* `setModel` (see `AgentSessionLike.setModel`), which dispatches on the
|
|
1301
|
+
* adapter's `models.apply` strategy (`config`/`command`/`arg`) and never
|
|
1302
|
+
* throws on a rejected switch.
|
|
1303
|
+
*
|
|
1304
|
+
* On `{applied:true}`, updates `SessionDescriptor.model` so
|
|
1305
|
+
* `session_list`/SSE reflect the switch and emits a
|
|
1306
|
+
* `session:config-changed {axis:"model"}` event on the session event bus
|
|
1307
|
+
* (plus a back-compat `session:model-changed` alias). On `{applied:false}`
|
|
1308
|
+
* the descriptor and event bus are untouched — nothing changed, so nothing
|
|
1309
|
+
* to announce.
|
|
1310
|
+
*
|
|
1311
|
+
* Throws (not a structured result) for the two "this request doesn't
|
|
1312
|
+
* even make sense" cases: an unknown session id, or a session that
|
|
1313
|
+
* isn't an agent-cli kind (or whose driver session predates `setModel`
|
|
1314
|
+
* entirely) — both are caller errors, not an adapter's refusal.
|
|
1315
|
+
*/
|
|
1316
|
+
setModel(id: string, modelId: string): Promise<SetSessionModelResult>;
|
|
1317
|
+
/**
|
|
1318
|
+
* Announce a single `SessionConfig` axis change on the session event bus
|
|
1319
|
+
* (SPEC step 6). `setModel` emits its `session:config-changed` event inline,
|
|
1320
|
+
* but restart-with-override (`restartAgentSession`, session-restart-core.ts)
|
|
1321
|
+
* lives OUTSIDE the registry — it re-resolves auth and re-spawns a fresh
|
|
1322
|
+
* session — so it announces each changed axis (access/route/posture/…) of the
|
|
1323
|
+
* new session through this one method rather than reaching into the private
|
|
1324
|
+
* event bus. No-op when the registry was constructed without a `sessionEvents`
|
|
1325
|
+
* bus (the emit is best-effort observability, never load-bearing). The caller
|
|
1326
|
+
* builds the fully-typed event (axis + value already reflected on the new
|
|
1327
|
+
* descriptor); the registry only forwards it. */
|
|
1328
|
+
emitConfigChanged(ev: SessionConfigChangedEvent): void;
|
|
1329
|
+
/**
|
|
1330
|
+
* Switch the reasoning/compute budget (effort) on a LIVE agent-cli session
|
|
1331
|
+
* without restarting it — the live-effort verb (SPEC §4.2, build step 5),
|
|
1332
|
+
* `POST /sessions/:id/effort` + `agent_set_effort`. Delegates to the driver
|
|
1333
|
+
* session's `setEffort` (ACP `set_config_option(configId:"effort")`); effort
|
|
1334
|
+
* is model-dependent (SPEC §3.9), so a label the current model rejects is a
|
|
1335
|
+
* soft `{applied:false, reason}` (SPEC risk R7), never thrown.
|
|
1336
|
+
*
|
|
1337
|
+
* On `{applied:true}` updates `SessionDescriptor.effort` and emits
|
|
1338
|
+
* `session:config-changed {axis:"effort"}`; on `{applied:false}` the
|
|
1339
|
+
* descriptor and bus are untouched. Throws (caller error, not an adapter
|
|
1340
|
+
* refusal) for an unknown session id or a non-agent-cli session — same
|
|
1341
|
+
* contract as `setModel`.
|
|
1342
|
+
*/
|
|
1343
|
+
setEffort(id: string, effort: string): Promise<SetSessionEffortResult>;
|
|
1344
|
+
/**
|
|
1345
|
+
* Switch the posture on a LIVE agent-cli session (SPEC §4.2, build step 5),
|
|
1346
|
+
* `POST /sessions/:id/posture` + `agent_set_posture`. When the requested
|
|
1347
|
+
* posture maps to a NATIVE advertised harness mode (`resolvePosture` →
|
|
1348
|
+
* `native`), it's switched live via the driver's `setSessionMode`
|
|
1349
|
+
* (`applied:true`, descriptor + `session:config-changed {axis:"posture"}`
|
|
1350
|
+
* emitted). When there is NO native mode (prompt-injected / env-applied /
|
|
1351
|
+
* a raw mode the session no longer advertises), it is NOT forced live — it
|
|
1352
|
+
* resolves `{applied:false, reason:"requires-restart"}` so the caller routes
|
|
1353
|
+
* it through restart-with-override (step 6, not implemented here). Throws for
|
|
1354
|
+
* an unknown session id or a non-agent-cli session, same as `setModel`.
|
|
1355
|
+
*/
|
|
1356
|
+
setPosture(id: string, posture: Posture): Promise<SetSessionPostureResult>;
|
|
877
1357
|
/** Stamp `lastActivityAt` on a live agent-cli session's descriptor
|
|
878
1358
|
* and schedule a debounced persist. Called from the `onActivity`
|
|
879
1359
|
* callback threaded down through the driver → ACP client, which
|
|
@@ -881,8 +1361,36 @@ interface SessionsRegistry {
|
|
|
881
1361
|
* output) — see `SessionDescriptor.lastActivityAt`. No-op when the
|
|
882
1362
|
* id is unknown (session already forgotten). */
|
|
883
1363
|
pulseActivity(id: string): void;
|
|
884
|
-
|
|
1364
|
+
/** Every non-archived session, newest `startedAt` first — the daemon's
|
|
1365
|
+
* canonical lister (`session_list`, `GET /sessions`, panels, subtree
|
|
1366
|
+
* scoping). Archived sessions are excluded UNLESS `includeArchived` is
|
|
1367
|
+
* true — the default keeps a housekeeping flag from becoming a second,
|
|
1368
|
+
* silent filter every caller has to know about, while
|
|
1369
|
+
* `{ includeArchived: true }` is there for `session_list`'s own opt-in
|
|
1370
|
+
* and for any subtree/authorization computation (`collectSubtree`) that
|
|
1371
|
+
* needs the FULL parent→child graph to stay connected — a subtree BFS
|
|
1372
|
+
* fed the filtered list would silently orphan the non-archived
|
|
1373
|
+
* descendants of an archived ancestor, since each edge is keyed off the
|
|
1374
|
+
* CHILD's own record. `get()`/`findByIdOrName()` are unaffected by this
|
|
1375
|
+
* flag entirely — a transcript stays directly openable by id no matter
|
|
1376
|
+
* how it's archived. */
|
|
1377
|
+
list(opts?: {
|
|
1378
|
+
includeArchived?: boolean;
|
|
1379
|
+
}): SessionDescriptor[];
|
|
885
1380
|
get(id: string): SessionDescriptor | undefined;
|
|
1381
|
+
/** Archive a TERMINAL-status session (exited/killed/error) — sets
|
|
1382
|
+
* `archived: true` and persists. Pure housekeeping: hides the row from
|
|
1383
|
+
* `list()`'s default view, nothing else. Refuses (throws) a still-alive
|
|
1384
|
+
* session (running/starting) — archiving one would hide it from the
|
|
1385
|
+
* daemon's own default view while it keeps working unattended, which is
|
|
1386
|
+
* a worse foot-gun than the flag is trying to solve. Idempotent: already
|
|
1387
|
+
* archived is a no-op success. Throws when the id is unknown. */
|
|
1388
|
+
archiveSession(id: string): SessionDescriptor;
|
|
1389
|
+
/** Unarchive — the inverse, no status guard (an archived session was
|
|
1390
|
+
* terminal when archived, and archiving never touched daemon state, so
|
|
1391
|
+
* there is nothing to re-validate). Throws only when the id is
|
|
1392
|
+
* unknown. */
|
|
1393
|
+
unarchiveSession(id: string): SessionDescriptor;
|
|
886
1394
|
/** Subscribe to a session's output. Returns an unsubscribe fn.
|
|
887
1395
|
* Initial backfill: synchronously invokes `onLine` once for each
|
|
888
1396
|
* line currently in the ring buffer so attaches show context. */
|
|
@@ -1009,11 +1517,35 @@ interface SpawnAgentInput {
|
|
|
1009
1517
|
depth?: number;
|
|
1010
1518
|
/** Requested model id — recorded on the descriptor for display + echo. */
|
|
1011
1519
|
model?: string;
|
|
1520
|
+
/** AIP-45 mode the session was spawned with — recorded onto
|
|
1521
|
+
* {@link SessionDescriptor.mode}. See that field's doc for why a client
|
|
1522
|
+
* needs it (mode-mismatch detection for mid-session model switching). */
|
|
1523
|
+
mode?: string;
|
|
1012
1524
|
/** Resolved auth echo (mode + fingerprint + provider/source/setEnv) —
|
|
1013
1525
|
* recorded verbatim onto {@link SessionDescriptor.auth}. See that field's
|
|
1014
1526
|
* doc for the full contract; the caller (`session-spawn.ts`) computes this
|
|
1015
1527
|
* via the billing-auth resolver, never passing the raw credential here. */
|
|
1016
1528
|
auth?: SessionAuthEcho;
|
|
1529
|
+
/** Decomposed config-axis echoes (SPEC §3.7) — recorded verbatim onto the
|
|
1530
|
+
* matching {@link SessionDescriptor} fields, the same optional-spread way
|
|
1531
|
+
* `model`/`mode`/`auth` are. All optional; a caller that resolved an axis
|
|
1532
|
+
* passes its echo so the descriptor round-trips it and the picker re-opens
|
|
1533
|
+
* on it. See each descriptor field's doc for the axis contract. */
|
|
1534
|
+
effort?: EffortLevel;
|
|
1535
|
+
posture?: Posture;
|
|
1536
|
+
route?: RouteSpec;
|
|
1537
|
+
contextProfile?: ContextProfile;
|
|
1538
|
+
/** Named auth-profile echo for the `access` axis (SPEC §3.6). Non-secret —
|
|
1539
|
+
* see {@link SessionAccessProfileEcho}. */
|
|
1540
|
+
accessProfile?: SessionAccessProfileEcho;
|
|
1541
|
+
/** Prior session id this spawn continues from — set by `restartAgentSession`
|
|
1542
|
+
* (session-restart-core.ts) when this is a restart, recorded verbatim onto
|
|
1543
|
+
* {@link SessionDescriptor.resumedFrom}. Absent for a direct (non-restart)
|
|
1544
|
+
* spawn. */
|
|
1545
|
+
resumedFrom?: string;
|
|
1546
|
+
/** Human-readable resume path, recorded onto {@link SessionDescriptor.resumeVia}.
|
|
1547
|
+
* Threaded through alongside `resumedFrom` — see that field's doc. */
|
|
1548
|
+
resumeVia?: string;
|
|
1017
1549
|
/** Hard ceiling on cumulative session cost (USD). When set and the
|
|
1018
1550
|
* adapter's usage reader reports a higher cost at a turn-end, the session
|
|
1019
1551
|
* is stopped (best-effort, turn-granular — caps continuation, can't abort
|
|
@@ -1087,6 +1619,17 @@ interface SpawnPtyInput {
|
|
|
1087
1619
|
* collide with an existing session's name. */
|
|
1088
1620
|
name?: string;
|
|
1089
1621
|
label?: string;
|
|
1622
|
+
/** Parent attribution + depth — same semantics as `SpawnAgentInput`
|
|
1623
|
+
* (orchestrator WP4): set when the spawn came through a scoped
|
|
1624
|
+
* sub-gateway so `session_tree` shows the PTY under its spawner. */
|
|
1625
|
+
parentSessionId?: string;
|
|
1626
|
+
depth?: number;
|
|
1627
|
+
/** Restart lineage — same semantics as `SpawnAgentInput.resumedFrom` /
|
|
1628
|
+
* `resumeVia`, recorded onto {@link SessionDescriptor.resumedFrom} /
|
|
1629
|
+
* {@link SessionDescriptor.resumeVia}. Set by `session_restart` for the
|
|
1630
|
+
* pty-native/pty-plain branches (session-tools.ts). */
|
|
1631
|
+
resumedFrom?: string;
|
|
1632
|
+
resumeVia?: string;
|
|
1090
1633
|
}
|
|
1091
1634
|
interface RecordCommandInput {
|
|
1092
1635
|
workspaceSlug: string;
|
|
@@ -1568,6 +2111,95 @@ interface WebhookNotifier {
|
|
|
1568
2111
|
onSessionEvent(ev: SessionEvent): void;
|
|
1569
2112
|
}
|
|
1570
2113
|
|
|
2114
|
+
/**
|
|
2115
|
+
* Shared types for pluggable sandbox providers.
|
|
2116
|
+
*
|
|
2117
|
+
* The sandbox family is a `@agentproto/provider-kit` consumer, same shape as
|
|
2118
|
+
* the tunnel family (`remote-providers/types.ts`): {@link SandboxProviderHandle}
|
|
2119
|
+
* extends the kit's generic `AdapterHandle` (slug/name/version/description/
|
|
2120
|
+
* requiresSetup/check) with the AIP-36 capability namespace and the concrete
|
|
2121
|
+
* `@agentproto/sandbox` `SandboxProvider` (`boot()`) the handle wraps.
|
|
2122
|
+
*/
|
|
2123
|
+
|
|
2124
|
+
/**
|
|
2125
|
+
* Declared capabilities of a sandbox provider — pure metadata, surfaced in
|
|
2126
|
+
* `list_sandbox_providers`. Never carries secrets. Namespace mirrors AIP-36
|
|
2127
|
+
* SANDBOX.md (`network.egress`, `mounts`, `lifecycle.pause_after_idle`,
|
|
2128
|
+
* `read_only`, `limits.timeout_ms`).
|
|
2129
|
+
*/
|
|
2130
|
+
interface SandboxProviderCapabilities {
|
|
2131
|
+
/** Sandbox can be given a network egress allowlist (AIP-36 `network.egress`). */
|
|
2132
|
+
networkEgress: boolean;
|
|
2133
|
+
/** Sandbox supports mounting external filesystems (AIP-36 `mounts`). */
|
|
2134
|
+
mounts: boolean;
|
|
2135
|
+
/** Sandbox can be paused (not just killed) between turns (AIP-36 `lifecycle.pause_after_idle`). */
|
|
2136
|
+
lifecyclePause: boolean;
|
|
2137
|
+
/** Sandbox can be started read-only (AIP-36 `read_only`). */
|
|
2138
|
+
readOnly: boolean;
|
|
2139
|
+
/** Hard cap on `limits.timeout_ms`, when the provider enforces one. */
|
|
2140
|
+
maxTimeoutMs?: number;
|
|
2141
|
+
}
|
|
2142
|
+
/**
|
|
2143
|
+
* A sandbox provider as an adapter-kit handle. Rides on the kit's generic
|
|
2144
|
+
* {@link AdapterHandle} and adds the sandbox-specific `capabilities` plus
|
|
2145
|
+
* the `@agentproto/sandbox` `SandboxProvider` the handle wraps — the thing
|
|
2146
|
+
* `createSandboxAgentSessionHost` actually boots.
|
|
2147
|
+
*/
|
|
2148
|
+
interface SandboxProviderHandle extends AdapterHandle {
|
|
2149
|
+
readonly provider: SandboxProvider;
|
|
2150
|
+
readonly capabilities: SandboxProviderCapabilities;
|
|
2151
|
+
/**
|
|
2152
|
+
* Credential fields this provider accepts via `setup_sandbox_provider`
|
|
2153
|
+
* (e.g. e2b's `apiKey`). Omit (or empty) when the provider needs no
|
|
2154
|
+
* credentials (e.g. `local`).
|
|
2155
|
+
*/
|
|
2156
|
+
readonly setupFields?: readonly SetupField[];
|
|
2157
|
+
}
|
|
2158
|
+
|
|
2159
|
+
/**
|
|
2160
|
+
* Sandbox family on top of `@agentproto/provider-kit` — mirrors
|
|
2161
|
+
* `tunnel-adapters.ts`. This module is the entire bridge between the
|
|
2162
|
+
* generic kit and `@agentproto/sandbox`'s `SandboxProvider` concept: it
|
|
2163
|
+
* contributes nothing the kit already owns (catalog/status/creds/ledger/
|
|
2164
|
+
* list/MCP-tool plumbing); it only supplies the sandbox-family `TInfo`
|
|
2165
|
+
* (`SandboxAdapterInfo`), the static `SANDBOX_CATALOG`, and the resolver
|
|
2166
|
+
* that maps a catalog slug to a concrete {@link SandboxProviderHandle}
|
|
2167
|
+
* (`./sandbox-providers/registry.js`).
|
|
2168
|
+
*
|
|
2169
|
+
* Kit primitives used:
|
|
2170
|
+
* - `makeCredsStore` → per-slug 0600 creds under `~/.agentproto/sandbox-creds/`
|
|
2171
|
+
* - `makeSetupLedger` → `~/.agentproto/setup/<slug>.json`
|
|
2172
|
+
* - `makeAdapterResolver` → wraps the throwing `load` into null-on-miss
|
|
2173
|
+
* - `makeAdapterLister` → catalog → status-classified `AdapterEntry[]`
|
|
2174
|
+
* - `makeListTool` → registers `list_sandbox_providers`
|
|
2175
|
+
* - `makeSetupTool` → registers `setup_sandbox_provider` (multi-field
|
|
2176
|
+
* form: e2b's `apiKey`, sensitive)
|
|
2177
|
+
*
|
|
2178
|
+
* This is pure additive plumbing (introspection + setup) — it does NOT wire
|
|
2179
|
+
* a `sandbox` field into `agent_start`. That lands in a follow-up PR; the
|
|
2180
|
+
* `resolveSandboxProvider`/`listSandboxProviders` overrides below exist now
|
|
2181
|
+
* so that later wiring can inject the same resolver/lister this module
|
|
2182
|
+
* builds by default, mirroring `resolveAgentAdapter`/`listAgentAdapters`.
|
|
2183
|
+
*
|
|
2184
|
+
* Security: `toSandboxInfo` exposes only `capabilities` — never a cred
|
|
2185
|
+
* value (Appendix B). The setup tool's fields are marked SENSITIVE and the
|
|
2186
|
+
* result NEVER echoes any field value back.
|
|
2187
|
+
*/
|
|
2188
|
+
|
|
2189
|
+
/**
|
|
2190
|
+
* Family descriptor (`TInfo`). Pure metadata surfaced in
|
|
2191
|
+
* `list_sandbox_providers`. The kit's `AdapterEntry` already carries
|
|
2192
|
+
* slug/name/description/status/version, so the only sandbox-specific field
|
|
2193
|
+
* is the declared capability set. NEVER carries a cred value.
|
|
2194
|
+
*/
|
|
2195
|
+
interface SandboxAdapterInfo {
|
|
2196
|
+
capabilities: SandboxProviderCapabilities;
|
|
2197
|
+
}
|
|
2198
|
+
/** Resolve a sandbox provider slug to a handle, or null when unavailable. */
|
|
2199
|
+
type SandboxProviderResolver = AdapterResolver<SandboxProviderHandle>;
|
|
2200
|
+
/** List every sandbox provider with its live status + capabilities. */
|
|
2201
|
+
type SandboxProviderLister = AdapterLister<SandboxAdapterInfo>;
|
|
2202
|
+
|
|
1571
2203
|
/**
|
|
1572
2204
|
* Cursor-based ring buffer for session events. Bridges the in-process
|
|
1573
2205
|
* SessionEventBus (push) to the session_events_poll MCP tool (pull).
|
|
@@ -2133,95 +2765,6 @@ type OrchestratorInjector = (opts?: {
|
|
|
2133
2765
|
*/
|
|
2134
2766
|
declare function createOrchestratorInjector(deps: OrchestratorInjectorDeps): OrchestratorInjector;
|
|
2135
2767
|
|
|
2136
|
-
/**
|
|
2137
|
-
* Shared types for pluggable sandbox providers.
|
|
2138
|
-
*
|
|
2139
|
-
* The sandbox family is a `@agentproto/provider-kit` consumer, same shape as
|
|
2140
|
-
* the tunnel family (`remote-providers/types.ts`): {@link SandboxProviderHandle}
|
|
2141
|
-
* extends the kit's generic `AdapterHandle` (slug/name/version/description/
|
|
2142
|
-
* requiresSetup/check) with the AIP-36 capability namespace and the concrete
|
|
2143
|
-
* `@agentproto/sandbox` `SandboxProvider` (`boot()`) the handle wraps.
|
|
2144
|
-
*/
|
|
2145
|
-
|
|
2146
|
-
/**
|
|
2147
|
-
* Declared capabilities of a sandbox provider — pure metadata, surfaced in
|
|
2148
|
-
* `list_sandbox_providers`. Never carries secrets. Namespace mirrors AIP-36
|
|
2149
|
-
* SANDBOX.md (`network.egress`, `mounts`, `lifecycle.pause_after_idle`,
|
|
2150
|
-
* `read_only`, `limits.timeout_ms`).
|
|
2151
|
-
*/
|
|
2152
|
-
interface SandboxProviderCapabilities {
|
|
2153
|
-
/** Sandbox can be given a network egress allowlist (AIP-36 `network.egress`). */
|
|
2154
|
-
networkEgress: boolean;
|
|
2155
|
-
/** Sandbox supports mounting external filesystems (AIP-36 `mounts`). */
|
|
2156
|
-
mounts: boolean;
|
|
2157
|
-
/** Sandbox can be paused (not just killed) between turns (AIP-36 `lifecycle.pause_after_idle`). */
|
|
2158
|
-
lifecyclePause: boolean;
|
|
2159
|
-
/** Sandbox can be started read-only (AIP-36 `read_only`). */
|
|
2160
|
-
readOnly: boolean;
|
|
2161
|
-
/** Hard cap on `limits.timeout_ms`, when the provider enforces one. */
|
|
2162
|
-
maxTimeoutMs?: number;
|
|
2163
|
-
}
|
|
2164
|
-
/**
|
|
2165
|
-
* A sandbox provider as an adapter-kit handle. Rides on the kit's generic
|
|
2166
|
-
* {@link AdapterHandle} and adds the sandbox-specific `capabilities` plus
|
|
2167
|
-
* the `@agentproto/sandbox` `SandboxProvider` the handle wraps — the thing
|
|
2168
|
-
* `createSandboxAgentSessionHost` actually boots.
|
|
2169
|
-
*/
|
|
2170
|
-
interface SandboxProviderHandle extends AdapterHandle {
|
|
2171
|
-
readonly provider: SandboxProvider;
|
|
2172
|
-
readonly capabilities: SandboxProviderCapabilities;
|
|
2173
|
-
/**
|
|
2174
|
-
* Credential fields this provider accepts via `setup_sandbox_provider`
|
|
2175
|
-
* (e.g. e2b's `apiKey`). Omit (or empty) when the provider needs no
|
|
2176
|
-
* credentials (e.g. `local`).
|
|
2177
|
-
*/
|
|
2178
|
-
readonly setupFields?: readonly SetupField[];
|
|
2179
|
-
}
|
|
2180
|
-
|
|
2181
|
-
/**
|
|
2182
|
-
* Sandbox family on top of `@agentproto/provider-kit` — mirrors
|
|
2183
|
-
* `tunnel-adapters.ts`. This module is the entire bridge between the
|
|
2184
|
-
* generic kit and `@agentproto/sandbox`'s `SandboxProvider` concept: it
|
|
2185
|
-
* contributes nothing the kit already owns (catalog/status/creds/ledger/
|
|
2186
|
-
* list/MCP-tool plumbing); it only supplies the sandbox-family `TInfo`
|
|
2187
|
-
* (`SandboxAdapterInfo`), the static `SANDBOX_CATALOG`, and the resolver
|
|
2188
|
-
* that maps a catalog slug to a concrete {@link SandboxProviderHandle}
|
|
2189
|
-
* (`./sandbox-providers/registry.js`).
|
|
2190
|
-
*
|
|
2191
|
-
* Kit primitives used:
|
|
2192
|
-
* - `makeCredsStore` → per-slug 0600 creds under `~/.agentproto/sandbox-creds/`
|
|
2193
|
-
* - `makeSetupLedger` → `~/.agentproto/setup/<slug>.json`
|
|
2194
|
-
* - `makeAdapterResolver` → wraps the throwing `load` into null-on-miss
|
|
2195
|
-
* - `makeAdapterLister` → catalog → status-classified `AdapterEntry[]`
|
|
2196
|
-
* - `makeListTool` → registers `list_sandbox_providers`
|
|
2197
|
-
* - `makeSetupTool` → registers `setup_sandbox_provider` (multi-field
|
|
2198
|
-
* form: e2b's `apiKey`, sensitive)
|
|
2199
|
-
*
|
|
2200
|
-
* This is pure additive plumbing (introspection + setup) — it does NOT wire
|
|
2201
|
-
* a `sandbox` field into `agent_start`. That lands in a follow-up PR; the
|
|
2202
|
-
* `resolveSandboxProvider`/`listSandboxProviders` overrides below exist now
|
|
2203
|
-
* so that later wiring can inject the same resolver/lister this module
|
|
2204
|
-
* builds by default, mirroring `resolveAgentAdapter`/`listAgentAdapters`.
|
|
2205
|
-
*
|
|
2206
|
-
* Security: `toSandboxInfo` exposes only `capabilities` — never a cred
|
|
2207
|
-
* value (Appendix B). The setup tool's fields are marked SENSITIVE and the
|
|
2208
|
-
* result NEVER echoes any field value back.
|
|
2209
|
-
*/
|
|
2210
|
-
|
|
2211
|
-
/**
|
|
2212
|
-
* Family descriptor (`TInfo`). Pure metadata surfaced in
|
|
2213
|
-
* `list_sandbox_providers`. The kit's `AdapterEntry` already carries
|
|
2214
|
-
* slug/name/description/status/version, so the only sandbox-specific field
|
|
2215
|
-
* is the declared capability set. NEVER carries a cred value.
|
|
2216
|
-
*/
|
|
2217
|
-
interface SandboxAdapterInfo {
|
|
2218
|
-
capabilities: SandboxProviderCapabilities;
|
|
2219
|
-
}
|
|
2220
|
-
/** Resolve a sandbox provider slug to a handle, or null when unavailable. */
|
|
2221
|
-
type SandboxProviderResolver = AdapterResolver<SandboxProviderHandle>;
|
|
2222
|
-
/** List every sandbox provider with its live status + capabilities. */
|
|
2223
|
-
type SandboxProviderLister = AdapterLister<SandboxAdapterInfo>;
|
|
2224
|
-
|
|
2225
2768
|
/**
|
|
2226
2769
|
* Policy layer for `agent_start.worktree` — the config-driven decision of
|
|
2227
2770
|
* WHETHER to isolate a spawn into its own git worktree, kept deliberately
|
|
@@ -2343,6 +2886,108 @@ declare function loadWorktreeIsolation(loadCfg?: () => Promise<{
|
|
|
2343
2886
|
};
|
|
2344
2887
|
}>): Promise<WorktreeIsolationMode>;
|
|
2345
2888
|
|
|
2889
|
+
/**
|
|
2890
|
+
* Read-only catalog/vendor endpoint (`agentproto-session-config-axes`
|
|
2891
|
+
* SPEC §5) — `GET /catalog/models` + `catalog_models` MCP tool wire into
|
|
2892
|
+
* {@link buildCatalogModels}, the pure join this module owns.
|
|
2893
|
+
*
|
|
2894
|
+
* Reuses three already-shipped pieces instead of rebuilding them:
|
|
2895
|
+
* - the vendor/product/route model + router widening (OpenRouter/
|
|
2896
|
+
* Requesty/HuggingFace) from `@agentproto/model-catalog/route-identity`
|
|
2897
|
+
* (`resolveLlmModelRoute`, `route-identity/index.ts:396-511`) — this is
|
|
2898
|
+
* what keeps the catalog from being capped at any one adapter's
|
|
2899
|
+
* `models.allowed` list (SPEC §5.1);
|
|
2900
|
+
* - the profile eligibility predicate shipped in #470
|
|
2901
|
+
* (`@agentproto/auth`'s `eligibleProfiles`, `packages/auth/src/
|
|
2902
|
+
* eligibility.ts:81-89`) for the profile-aware `runnable` flag (SPEC
|
|
2903
|
+
* §5.3) — the old bare `hasKey` check (`packages/cli/src/commands/
|
|
2904
|
+
* models.ts:113-117`) is the degenerate one-profile-per-provider case
|
|
2905
|
+
* this predicate subsumes;
|
|
2906
|
+
* - `AdapterAuthDescriptor` (`spawn-defaults.ts:226`), the SAME
|
|
2907
|
+
* provider/authSubscription projection `resolveAuthSpec` reads, as the
|
|
2908
|
+
* source for which auth methods an adapter can present on its direct
|
|
2909
|
+
* route (SPEC §3.4's derivable replacement for a hand-maintained
|
|
2910
|
+
* `authSubscription` boolean).
|
|
2911
|
+
*
|
|
2912
|
+
* A gateway/router route (anything where the resolved route differs from
|
|
2913
|
+
* the model's vendor — `openrouter`, `requesty`, `huggingface`, or an
|
|
2914
|
+
* adapter's own gateway mode id like `moonshot`) always bills against the
|
|
2915
|
+
* route's own id and is always reached with an api-key credential — never
|
|
2916
|
+
* oauth-bearer, since no third-party gateway has an Anthropic-style
|
|
2917
|
+
* subscription bearer path (SPEC §1c: "a moonshot profile, not the Claude
|
|
2918
|
+
* sub"). That structural rule is what lets this module compute
|
|
2919
|
+
* `runnable`/`eligibleProfiles` for the widened, non-curated rows without
|
|
2920
|
+
* per-adapter gateway-vendor tables.
|
|
2921
|
+
*/
|
|
2922
|
+
|
|
2923
|
+
/** One model entry as declared in an adapter's `models.allowed`
|
|
2924
|
+
* (`AdapterModelInfo`, `packages/cli/src/registry/resolve.ts:134-142`) —
|
|
2925
|
+
* the subset this module needs. */
|
|
2926
|
+
interface CatalogAdapterModelInput {
|
|
2927
|
+
/** Model id exactly as declared — bare (`"claude-opus-4-8"`) or
|
|
2928
|
+
* `vendor/product` form. */
|
|
2929
|
+
id: string;
|
|
2930
|
+
/** The adapter mode id that must be applied to reach this model on a
|
|
2931
|
+
* non-direct route (`AdapterModelInfo.mode`) — e.g. `"moonshot"`.
|
|
2932
|
+
* Undefined ⇒ direct route (the model's own vendor). */
|
|
2933
|
+
mode?: string;
|
|
2934
|
+
}
|
|
2935
|
+
/** One installed adapter's contribution to the catalog. */
|
|
2936
|
+
interface CatalogAdapterInput {
|
|
2937
|
+
slug: string;
|
|
2938
|
+
models: readonly CatalogAdapterModelInput[];
|
|
2939
|
+
/** This adapter's billing-auth capability on its DIRECT route — the same
|
|
2940
|
+
* projection `resolveAuthSpec` reads (`spawn-defaults.ts:226`). Omitted
|
|
2941
|
+
* ⇒ the adapter presents no auth method, so rows it curates are
|
|
2942
|
+
* discoverable but never runnable through it alone. */
|
|
2943
|
+
authDescriptor?: AdapterAuthDescriptor;
|
|
2944
|
+
}
|
|
2945
|
+
interface CatalogModelsQuery {
|
|
2946
|
+
/** Keep only routes reachable via this adapter slug. */
|
|
2947
|
+
adapter?: string;
|
|
2948
|
+
/** Keep only this vendor's entry. */
|
|
2949
|
+
vendor?: string;
|
|
2950
|
+
/** Keep only routes with this route id. */
|
|
2951
|
+
route?: string;
|
|
2952
|
+
/** Drop every route with `runnable: false`. */
|
|
2953
|
+
runnableOnly?: boolean;
|
|
2954
|
+
}
|
|
2955
|
+
interface CatalogPricing {
|
|
2956
|
+
inPer1M: number;
|
|
2957
|
+
outPer1M: number;
|
|
2958
|
+
}
|
|
2959
|
+
interface CatalogRoute {
|
|
2960
|
+
route: string;
|
|
2961
|
+
ref: string;
|
|
2962
|
+
baseUrl: string | null;
|
|
2963
|
+
pricing: CatalogPricing | null;
|
|
2964
|
+
runnable: boolean;
|
|
2965
|
+
eligibleProfiles: string[];
|
|
2966
|
+
adapterModes: string[];
|
|
2967
|
+
adapters: string[];
|
|
2968
|
+
curated: boolean;
|
|
2969
|
+
}
|
|
2970
|
+
interface CatalogProduct {
|
|
2971
|
+
product: string;
|
|
2972
|
+
routes: CatalogRoute[];
|
|
2973
|
+
}
|
|
2974
|
+
interface CatalogVendor {
|
|
2975
|
+
vendor: string;
|
|
2976
|
+
products: CatalogProduct[];
|
|
2977
|
+
}
|
|
2978
|
+
interface CatalogModelsResponse {
|
|
2979
|
+
vendors: CatalogVendor[];
|
|
2980
|
+
}
|
|
2981
|
+
interface BuildCatalogModelsInput {
|
|
2982
|
+
adapters: readonly CatalogAdapterInput[];
|
|
2983
|
+
profiles: readonly AuthProfile[];
|
|
2984
|
+
query?: CatalogModelsQuery;
|
|
2985
|
+
}
|
|
2986
|
+
/** The pure join (SPEC §5): adapter-declared models + router widening +
|
|
2987
|
+
* the #470 eligibility predicate → the vendor/product/route tree. No I/O —
|
|
2988
|
+
* callers (the HTTP route / MCP tool) own loading adapters + profiles. */
|
|
2989
|
+
declare function buildCatalogModels(input: BuildCatalogModelsInput): CatalogModelsResponse;
|
|
2990
|
+
|
|
2346
2991
|
/**
|
|
2347
2992
|
* Pluggable adapter resolver — keeps the runtime package free of any
|
|
2348
2993
|
* @agentproto/cli dep. The host (cli `serve`, playground, embedding
|
|
@@ -2482,6 +3127,13 @@ interface AdapterListEntry {
|
|
|
2482
3127
|
modes: AdapterListMode[];
|
|
2483
3128
|
}
|
|
2484
3129
|
type AgentAdapterLister = () => Promise<AdapterListEntry[]>;
|
|
3130
|
+
/** Loads the read-only vendor/product/route catalog (SPEC §5) for
|
|
3131
|
+
* `GET /catalog/models` + the `catalog_models` MCP tool. A host wires this
|
|
3132
|
+
* from `buildCatalogModels` (`catalog-models.ts`) fed by its installed
|
|
3133
|
+
* adapters + `@agentproto/auth`'s `listAuthProfiles()` — the query params
|
|
3134
|
+
* are forwarded verbatim from the request. Omitted ⇒ the route/tool
|
|
3135
|
+
* report "not enabled" (same convention as `listAgentAdapters`). */
|
|
3136
|
+
type CatalogModelsLister = (query: CatalogModelsQuery) => Promise<CatalogModelsResponse>;
|
|
2485
3137
|
interface AuthOptions {
|
|
2486
3138
|
mode: "none" | "bearer";
|
|
2487
3139
|
token?: string;
|
|
@@ -2756,6 +3408,131 @@ declare function declaredPresetToProviderPreset(decl: DeclaredAdapterPreset): Pr
|
|
|
2756
3408
|
*/
|
|
2757
3409
|
declare function listPresets(env?: Record<string, string | undefined>, adapterPresets?: readonly DeclaredAdapterPreset[]): AdapterEntry<PresetInfo>[];
|
|
2758
3410
|
|
|
3411
|
+
/**
|
|
3412
|
+
* Canonical-posture layer (SPEC §3.4a, build step 2c, out-of-repo design doc
|
|
3413
|
+
* `agentproto-session-config-axes/SPEC.md`). Pure: a map + preambles + a
|
|
3414
|
+
* resolution helper, no I/O, no daemon wiring. It is the piece that makes the
|
|
3415
|
+
* agentproto-canonical posture vocabulary (`CanonicalPosture` from
|
|
3416
|
+
* `./session-config.js`) portable across harnesses:
|
|
3417
|
+
*
|
|
3418
|
+
* 1. **Native enforcement.** A canonical posture is resolved to a *harness*
|
|
3419
|
+
* `SessionModeId` when the session's advertised `availableModes`
|
|
3420
|
+
* (`SessionModeState.availableModes`, surfaced read-only by the ACP
|
|
3421
|
+
* capability layer landed in #482, `packages/acp/src/client/index.ts`) has
|
|
3422
|
+
* an equivalent. That mode is switched live via `setSessionMode` (step 5)
|
|
3423
|
+
* or applied on restart (step 6) — a real permission boundary.
|
|
3424
|
+
* 2. **Prompt-injection fallback.** When no advertised mode matches, the
|
|
3425
|
+
* posture is honoured as an injected system-prompt PREAMBLE — advisory,
|
|
3426
|
+
* NOT a permission boundary (SPEC risk Rw). This module returns the
|
|
3427
|
+
* preamble text; steps 5/6 ride it onto the system prompt at spawn.
|
|
3428
|
+
*
|
|
3429
|
+
* This module deliberately does NOT implement the live-posture verb (step 5) or
|
|
3430
|
+
* the posture restart-override (step 6) — it only tells them WHICH of the two
|
|
3431
|
+
* apply-paths a given (posture × session) resolves to, and supplies the
|
|
3432
|
+
* preamble for the fallback path.
|
|
3433
|
+
*
|
|
3434
|
+
* Read-surface dependency: `availableModes` comes from the #482 ACP capability
|
|
3435
|
+
* read surface (`AcpClientSession.availableModes` →
|
|
3436
|
+
* `AgentCliRuntimeSession.availableModes`) — this module consumes it, never
|
|
3437
|
+
* reimplements it.
|
|
3438
|
+
*/
|
|
3439
|
+
|
|
3440
|
+
/**
|
|
3441
|
+
* Per-posture system-prompt preamble — the prompt-injection fallback applied
|
|
3442
|
+
* when a canonical posture has NO native advertised mode on the current harness
|
|
3443
|
+
* (SPEC §3.4a). This is ADVISORY text the model can ignore, never a permission
|
|
3444
|
+
* boundary (SPEC risk Rw) — a consumer must present a prompt-enforced posture
|
|
3445
|
+
* as "advisory", never imply it sandboxes tools.
|
|
3446
|
+
*
|
|
3447
|
+
* `"default"` has no preamble: it is the neutral posture (no constraint to
|
|
3448
|
+
* announce), so it resolves to a no-op rather than an injected string when the
|
|
3449
|
+
* harness advertises no native `default` mode.
|
|
3450
|
+
*/
|
|
3451
|
+
declare const POSTURE_PREAMBLES: Readonly<Record<Exclude<CanonicalPosture, "default">, string>>;
|
|
3452
|
+
/**
|
|
3453
|
+
* agentproto-canonical posture → the harness `SessionModeId`s that mean the
|
|
3454
|
+
* same thing. This is the "canonical posture ↔ advertised ACP mode id" map
|
|
3455
|
+
* (SPEC §3.4a): the daemon resolves a portable posture onto whichever native
|
|
3456
|
+
* mode a given harness happens to advertise, since harnesses spell the same
|
|
3457
|
+
* concept differently — claude-code's ACP wrapper uses `acceptEdits` /
|
|
3458
|
+
* `bypassPermissions` (`adapters/claude-code/src/index.ts:216,223`), the
|
|
3459
|
+
* manifest posture ids use `accept-edits` / `bypass-permissions`, codex uses
|
|
3460
|
+
* `full-access`, opencode uses `build`, etc.
|
|
3461
|
+
*
|
|
3462
|
+
* Matching is case- and separator-insensitive (see {@link normalizeModeId}), so
|
|
3463
|
+
* ONE readable spelling here covers every casing/hyphenation a harness might
|
|
3464
|
+
* advertise — `"accept-edits"` already matches claude-code's `acceptEdits`, so
|
|
3465
|
+
* both spellings need not be listed. Aliases are disjoint across postures — no
|
|
3466
|
+
* advertised id maps to two canonical postures — so {@link canonicalForModeId}
|
|
3467
|
+
* is unambiguous. Kept consistent with the legacy `mode`-id normalization in
|
|
3468
|
+
* `session-config.ts` (`POSTURE_MODE_VALUES`).
|
|
3469
|
+
*/
|
|
3470
|
+
declare const POSTURE_NATIVE_ALIASES: Readonly<Record<CanonicalPosture, readonly string[]>>;
|
|
3471
|
+
/**
|
|
3472
|
+
* Normalize a mode id for matching: lowercase and strip every non-alphanumeric
|
|
3473
|
+
* character, so `"acceptEdits"`, `"accept-edits"`, and `"Accept_Edits"` all
|
|
3474
|
+
* collapse to `"acceptedits"`. Lets one readable alias in
|
|
3475
|
+
* {@link POSTURE_NATIVE_ALIASES} cover any casing/separator a harness advertises.
|
|
3476
|
+
*/
|
|
3477
|
+
declare function normalizeModeId(id: string): string;
|
|
3478
|
+
/**
|
|
3479
|
+
* Inverse of the alias map: which canonical posture (if any) a harness mode id
|
|
3480
|
+
* normalizes to. `undefined` for a harness-specific mode the canonical
|
|
3481
|
+
* vocabulary doesn't name (e.g. opencode's `architect`) — such a mode is still
|
|
3482
|
+
* offerable as a raw `{ harnessModeId }` posture, it just has no portable name.
|
|
3483
|
+
*/
|
|
3484
|
+
declare function canonicalForModeId(modeId: string): CanonicalPosture | undefined;
|
|
3485
|
+
/**
|
|
3486
|
+
* Find the advertised harness mode that natively enforces `posture`, or
|
|
3487
|
+
* `undefined` if none does.
|
|
3488
|
+
*
|
|
3489
|
+
* - A `CanonicalPosture` matches an advertised mode whose id normalizes to one
|
|
3490
|
+
* of that posture's aliases.
|
|
3491
|
+
* - A raw `{ harnessModeId }` matches an advertised mode with the (normalized)
|
|
3492
|
+
* same id — it's already a native id, we only confirm the session still
|
|
3493
|
+
* advertises it.
|
|
3494
|
+
*/
|
|
3495
|
+
declare function findNativeMode(posture: Posture, availableModes: readonly SessionMode[]): SessionMode | undefined;
|
|
3496
|
+
/**
|
|
3497
|
+
* How a requested posture resolves against a session's advertised modes.
|
|
3498
|
+
*
|
|
3499
|
+
* - `native` — an advertised mode enforces it; switch via `setSessionMode`
|
|
3500
|
+
* (live, step 5) or apply on restart (step 6). A real permission boundary.
|
|
3501
|
+
* - `prompt` — no native mode; honour it as an injected system-prompt preamble
|
|
3502
|
+
* (advisory only, SPEC risk Rw). Rides the system prompt, so it applies at
|
|
3503
|
+
* spawn/restart, never live.
|
|
3504
|
+
* - `noop` — the `default` (neutral) posture with no advertised `default` mode:
|
|
3505
|
+
* nothing to enforce and nothing to announce.
|
|
3506
|
+
* - `unavailable` — a raw `{ harnessModeId }` the session no longer advertises;
|
|
3507
|
+
* it has no canonical name, so there is no preamble to fall back to. The
|
|
3508
|
+
* caller surfaces this rather than silently doing nothing.
|
|
3509
|
+
*/
|
|
3510
|
+
type PostureResolution = {
|
|
3511
|
+
readonly kind: "native";
|
|
3512
|
+
readonly mode: SessionMode;
|
|
3513
|
+
} | {
|
|
3514
|
+
readonly kind: "prompt";
|
|
3515
|
+
readonly posture: Exclude<CanonicalPosture, "default">;
|
|
3516
|
+
readonly preamble: string;
|
|
3517
|
+
} | {
|
|
3518
|
+
readonly kind: "noop";
|
|
3519
|
+
readonly posture: "default";
|
|
3520
|
+
} | {
|
|
3521
|
+
readonly kind: "unavailable";
|
|
3522
|
+
readonly requestedModeId: string;
|
|
3523
|
+
};
|
|
3524
|
+
/**
|
|
3525
|
+
* Resolve a requested posture against the session's advertised `availableModes`
|
|
3526
|
+
* (from the #482 read surface) into one of the {@link PostureResolution} arms.
|
|
3527
|
+
* Pure and total — the single decision function steps 5 (live) and 6 (restart
|
|
3528
|
+
* override) call to learn whether a posture pick is native-enforced or
|
|
3529
|
+
* prompt-injected, without either of them re-deriving the map.
|
|
3530
|
+
*
|
|
3531
|
+
* Native enforcement is always preferred: a canonical posture resolves to
|
|
3532
|
+
* `prompt` ONLY when the harness advertises no equivalent mode.
|
|
3533
|
+
*/
|
|
3534
|
+
declare function resolvePosture(posture: Posture, availableModes: readonly SessionMode[]): PostureResolution;
|
|
3535
|
+
|
|
2759
3536
|
/**
|
|
2760
3537
|
* Per-workspace state buckets — AIP-46 §State partitioning.
|
|
2761
3538
|
*
|
|
@@ -2867,7 +3644,18 @@ declare function resolveBucketSlug(workspaceSlug: string | undefined | null, reg
|
|
|
2867
3644
|
* silently pooling into `default` until restart. Never throws: a
|
|
2868
3645
|
* missing/corrupt registry degrades to "nothing is registered", i.e.
|
|
2869
3646
|
* everything lands in `default` — today's pooled behaviour, which is
|
|
2870
|
-
* the right failure direction.
|
|
3647
|
+
* the right failure direction.
|
|
3648
|
+
*
|
|
3649
|
+
* A registry read that fails transiently (a race with a concurrent
|
|
3650
|
+
* `saveWorkspacesConfig` tmp+rename) is indistinguishable here from one
|
|
3651
|
+
* that's genuinely empty — but the persist path never actually needs to
|
|
3652
|
+
* tell them apart: `sessions.ts`'s `sourceBucketOf` already keeps a
|
|
3653
|
+
* loaded row homed to the bucket it came from regardless of what this
|
|
3654
|
+
* returns, so a bad read here degrades a NEW session's placement (still
|
|
3655
|
+
* `default`, same as always) and nothing else. See the 2026-07-18
|
|
3656
|
+
* bucket-clobber incident for why that distinction matters for loaded
|
|
3657
|
+
* rows, and `sourceBucketOf`'s docblock in `sessions.ts` for where it's
|
|
3658
|
+
* actually enforced. */
|
|
2871
3659
|
declare function readRegisteredSlugs(configPath?: string): ReadonlySet<string>;
|
|
2872
3660
|
/** Bucket directories that exist on disk. Order is not meaningful. */
|
|
2873
3661
|
declare function listBuckets(root: string): string[];
|
|
@@ -2908,6 +3696,118 @@ declare function migrateLegacySessionsFile(opts: {
|
|
|
2908
3696
|
registered: ReadonlySet<string>;
|
|
2909
3697
|
}): MigrationMarker | null;
|
|
2910
3698
|
|
|
3699
|
+
/**
|
|
3700
|
+
* Persisted conversation index — the session ↔ native-transcript link,
|
|
3701
|
+
* stored instead of re-derived (DESIGN.md `agentproto-state-multitenancy`
|
|
3702
|
+
* §6).
|
|
3703
|
+
*
|
|
3704
|
+
* Today the link between an agentproto session and the original
|
|
3705
|
+
* claude/hermes conversation file is DERIVED on every read, through
|
|
3706
|
+
* `claudeCodeProjectDir`/`claudeProjectSlug` (conversation-store.ts) — and
|
|
3707
|
+
* until that function was fixed, derived *wrong* for any cwd containing a
|
|
3708
|
+
* dot. Re-deriving is also blind to cwd drift (a worktree that moved) and
|
|
3709
|
+
* carries no record of subagent transcripts at all.
|
|
3710
|
+
*
|
|
3711
|
+
* This module is the fix: an **append-only** `conversations.jsonl`, one
|
|
3712
|
+
* per workspace bucket (co-located with that bucket's `sessions.json`,
|
|
3713
|
+
* `workspace-buckets.ts`), upserted by `sessionId` — readers take the LAST
|
|
3714
|
+
* record per id. Append-only is deliberate, not incidental: it is immune
|
|
3715
|
+
* to the wholesale-rewrite clobber `sessions.ts`'s `persistSnapshot`
|
|
3716
|
+
* already has (see DESIGN.md §1) — a writer can only ever ADD a line, so a
|
|
3717
|
+
* second process racing a first can't shrink what's on disk.
|
|
3718
|
+
*
|
|
3719
|
+
* Write points (best-effort, mirroring how `transcriptWriter`/
|
|
3720
|
+
* `persistSnapshot` never throw into the turn path): session spawn, an
|
|
3721
|
+
* ACP-level resume, and a native graceful-exit resume-hint — see
|
|
3722
|
+
* `sessions.ts`'s calls into `recordConversationLink`.
|
|
3723
|
+
*
|
|
3724
|
+
* No tenant layer yet — the index lives directly under the workspace
|
|
3725
|
+
* bucket dir today (`bucketDir(bucketsRoot, slug)/conversations.jsonl`);
|
|
3726
|
+
* DESIGN.md §9 notes it migrates under `tenants/<t>/…` at a later PR.
|
|
3727
|
+
*/
|
|
3728
|
+
/** The claude-code native store: one jsonl per conversation, plus any
|
|
3729
|
+
* subagent transcripts nested under `<sessionId>/subagents/agent-*.jsonl`. */
|
|
3730
|
+
interface ClaudeNativeRef {
|
|
3731
|
+
kind: "claude-jsonl";
|
|
3732
|
+
path: string;
|
|
3733
|
+
subagents: string[];
|
|
3734
|
+
}
|
|
3735
|
+
/** The hermes native store: a row in a shared sqlite db, keyed by the same
|
|
3736
|
+
* id agentproto already records as `adapterSessionId` — no path to derive. */
|
|
3737
|
+
interface HermesNativeRef {
|
|
3738
|
+
kind: "hermes-sqlite";
|
|
3739
|
+
dbPath: string;
|
|
3740
|
+
rowId: string;
|
|
3741
|
+
}
|
|
3742
|
+
type ConversationNativeRef = ClaudeNativeRef | HermesNativeRef;
|
|
3743
|
+
interface ConversationIndexRecord {
|
|
3744
|
+
sessionId: string;
|
|
3745
|
+
workspace: string;
|
|
3746
|
+
cwd: string;
|
|
3747
|
+
adapterSlug: string;
|
|
3748
|
+
adapterSessionId: string;
|
|
3749
|
+
/** Absent when `adapterSlug` has no known native store (an adapter
|
|
3750
|
+
* outside claude-code/hermes) — the record still links session ↔
|
|
3751
|
+
* cwd ↔ adapterSessionId, it just can't point at a native file. */
|
|
3752
|
+
native?: ConversationNativeRef;
|
|
3753
|
+
agentprotoTranscript: string;
|
|
3754
|
+
title?: string;
|
|
3755
|
+
startedAt: string;
|
|
3756
|
+
endedAt?: string;
|
|
3757
|
+
}
|
|
3758
|
+
/** Absolute path to a workspace bucket's conversation index. Sibling of
|
|
3759
|
+
* `bucketSessionsFile` in `workspace-buckets.ts`, same root/slug rule. */
|
|
3760
|
+
declare function conversationIndexPath(bucketsRoot: string, slug: string): string;
|
|
3761
|
+
interface ResolveNativeLinkInput {
|
|
3762
|
+
cwd: string;
|
|
3763
|
+
adapterSlug: string;
|
|
3764
|
+
adapterSessionId: string;
|
|
3765
|
+
}
|
|
3766
|
+
/**
|
|
3767
|
+
* Resolve where THIS provider keeps this conversation, computed once (at
|
|
3768
|
+
* a write point) rather than re-derived on every read. Claude-code's path
|
|
3769
|
+
* uses the corrected `claudeProjectSlug` via `claudeCodeProjectDir` — the
|
|
3770
|
+
* whole point of pairing this module with the encoder fix in the same PR.
|
|
3771
|
+
* Returns `undefined` for an adapter with no known native store (e.g.
|
|
3772
|
+
* mastracode, claude-sdk) — a record without `native` is still useful
|
|
3773
|
+
* (session ↔ cwd ↔ adapterSessionId), it just has nothing further to add.
|
|
3774
|
+
*/
|
|
3775
|
+
declare function resolveNativeLink(input: ResolveNativeLinkInput): Promise<ConversationNativeRef | undefined>;
|
|
3776
|
+
/** Append one record. Never rewrites — the caller decides when a fresher
|
|
3777
|
+
* snapshot of the same session is worth a new line; readers always take
|
|
3778
|
+
* the last one. Creates the bucket dir if this is its first conversation
|
|
3779
|
+
* record (a bucket that has only ever held terminal/command sessions
|
|
3780
|
+
* won't have one yet). */
|
|
3781
|
+
declare function appendConversationRecord(bucketsRoot: string, slug: string, record: ConversationIndexRecord): Promise<void>;
|
|
3782
|
+
/** Read one bucket's index, upserted by `sessionId` — a line later in the
|
|
3783
|
+
* file always wins over an earlier one for the same id, append-only's
|
|
3784
|
+
* upsert semantics. A malformed line (partial write, hand-edited garbage)
|
|
3785
|
+
* is skipped, not fatal — the rest of the file still reads. `[]` (not a
|
|
3786
|
+
* throw) when the bucket has no index yet. */
|
|
3787
|
+
declare function readConversationIndex(bucketsRoot: string, slug: string): Promise<ConversationIndexRecord[]>;
|
|
3788
|
+
/** Forward lookup within one already-known bucket. */
|
|
3789
|
+
declare function findConversationRecord(bucketsRoot: string, slug: string, sessionId: string): Promise<ConversationIndexRecord | undefined>;
|
|
3790
|
+
interface LocatedConversation {
|
|
3791
|
+
workspace: string;
|
|
3792
|
+
record: ConversationIndexRecord;
|
|
3793
|
+
}
|
|
3794
|
+
/** Forward lookup: sessionId → its record, scanning every bucket (the
|
|
3795
|
+
* caller doesn't have to know which workspace a session landed in).
|
|
3796
|
+
* `undefined` when no bucket's index has ever recorded this session. */
|
|
3797
|
+
declare function locateConversationBySessionId(bucketsRoot: string, listBuckets: () => string[], sessionId: string): Promise<LocatedConversation | undefined>;
|
|
3798
|
+
interface LocatedConversationByPath extends LocatedConversation {
|
|
3799
|
+
/** Set when the match was a subagent transcript rather than the root
|
|
3800
|
+
* conversation file — the path that actually matched. */
|
|
3801
|
+
matchedSubagentPath?: string;
|
|
3802
|
+
}
|
|
3803
|
+
/** Reverse lookup: a native jsonl path (root conversation OR a subagent
|
|
3804
|
+
* transcript) → the agentproto session/workspace that owns it. Scans
|
|
3805
|
+
* every bucket's index; paths are compared after `path.resolve` so a
|
|
3806
|
+
* relative or `..`-bearing argument still matches an absolute recorded
|
|
3807
|
+
* one. Only meaningful for claude-code's `native.path`/`native.subagents`
|
|
3808
|
+
* — hermes has no per-conversation file to reverse-lookup from. */
|
|
3809
|
+
declare function locateConversationByNativePath(bucketsRoot: string, listBuckets: () => string[], nativePath: string): Promise<LocatedConversationByPath | undefined>;
|
|
3810
|
+
|
|
2911
3811
|
/** A journal-file StepCache scoped to one cacheKey. Best-effort: read/parse
|
|
2912
3812
|
* failures degrade to "no cache" (a miss), never throw into the run. */
|
|
2913
3813
|
declare function createFileStepCache(cacheKey: string, opts?: {
|
|
@@ -3032,6 +3932,44 @@ declare function readRuntimeMeta(workspace: string): Promise<{
|
|
|
3032
3932
|
*/
|
|
3033
3933
|
declare function sweepStaleRuntimeMetas(workspaces: readonly string[], currentWorkspace: string): Promise<string[]>;
|
|
3034
3934
|
|
|
3935
|
+
/**
|
|
3936
|
+
* Conversation as pivot: one store abstraction per provider, read on any
|
|
3937
|
+
* session. A "conversation" is the provider's own persisted session — the
|
|
3938
|
+
* durable object. An agentproto session (ACP or PTY) is just an attachment
|
|
3939
|
+
* to it. `CONVERSATION_STORES` is the single source of truth for "where does
|
|
3940
|
+
* this provider keep its conversations, and how do I read/attach to one" —
|
|
3941
|
+
* `RESUME_STRATEGIES` (resume-strategies.ts) and `EXPORT_STRATEGIES`
|
|
3942
|
+
* (transcript-export.ts) are thin adapters over it so the two historically
|
|
3943
|
+
* drifted tables can never diverge again.
|
|
3944
|
+
*/
|
|
3945
|
+
|
|
3946
|
+
/**
|
|
3947
|
+
* Claude Code's own `cwd` → project-dir-name encoder.
|
|
3948
|
+
*
|
|
3949
|
+
* The real rule (verified empirically against `~/.claude/projects/`
|
|
3950
|
+
* directory names for dozens of known cwds, including dotted worktree
|
|
3951
|
+
* paths and macOS temp dirs): every character that is NOT `[a-zA-Z0-9]`
|
|
3952
|
+
* is replaced 1:1 with `-`. Crucially, runs of consecutive non-alnum
|
|
3953
|
+
* characters are NOT collapsed — each input character produces exactly
|
|
3954
|
+
* one output character.
|
|
3955
|
+
*
|
|
3956
|
+
* This used to be `cwd.replace(/\//g, "-")` — slashes only. That's wrong
|
|
3957
|
+
* for any cwd containing a dot (every `.agentproto` worktree, any
|
|
3958
|
+
* dotdir), an underscore-prefixed segment, a space, etc., because those
|
|
3959
|
+
* characters are left untouched instead of becoming `-`, so the computed
|
|
3960
|
+
* directory never matches the one claude actually created.
|
|
3961
|
+
*
|
|
3962
|
+
* Reconstruction proof (both real, both `ls ~/.claude/projects/`-verified):
|
|
3963
|
+
* cwd /Users/jeremy/.agentproto/worktrees/ts/gc-fresh-hold
|
|
3964
|
+
* → -Users-jeremy--agentproto-worktrees-ts-gc-fresh-hold
|
|
3965
|
+
* (note the "--" from "/." — one dash for "/", one for ".", not collapsed)
|
|
3966
|
+
*
|
|
3967
|
+
* cwd /Volumes/SSDExternalMacStudio/Code/_agentproto-worktrees/adapter-claude-sdk
|
|
3968
|
+
* → -Volumes-SSDExternalMacStudio-Code--agentproto-worktrees-adapter-claude-sdk
|
|
3969
|
+
* (same double-dash shape, this time from "/_")
|
|
3970
|
+
*/
|
|
3971
|
+
declare function claudeProjectSlug(cwd: string): string;
|
|
3972
|
+
|
|
3035
3973
|
/**
|
|
3036
3974
|
* Read-only probe: does a credential actually RESOLVE for an adapter slug's
|
|
3037
3975
|
* billing auth? Used by `adapter_list` to report an HONEST status instead of
|
|
@@ -3194,6 +4132,11 @@ interface CreateGatewayOptions {
|
|
|
3194
4132
|
* `GET /adapters` HTTP route + `adapter_list` MCP tool so UIs
|
|
3195
4133
|
* can discover what's installed on the host. */
|
|
3196
4134
|
listAgentAdapters?: AgentAdapterLister;
|
|
4135
|
+
/** Optional catalog lister — when provided, enables
|
|
4136
|
+
* `GET /catalog/models` HTTP route + `catalog_models` MCP tool
|
|
4137
|
+
* (SPEC §5) so UIs can discover every runnable model + route without
|
|
4138
|
+
* trial-and-error against a spawn. */
|
|
4139
|
+
listCatalogModels?: CatalogModelsLister;
|
|
3197
4140
|
/** Optional browser adapter resolver — when provided, enables the
|
|
3198
4141
|
* `start_browser` MCP tool (launches Camofox / Bureau / Chromium). */
|
|
3199
4142
|
resolveBrowserAdapter?: BrowserAdapterResolver;
|
|
@@ -3334,4 +4277,4 @@ interface GatewayHandle {
|
|
|
3334
4277
|
*/
|
|
3335
4278
|
declare function createGateway(opts: CreateGatewayOptions): Promise<GatewayHandle>;
|
|
3336
4279
|
|
|
3337
|
-
export { AdapterAuthDescriptor, type AdapterListEntry, type AgentAdapterLister, type AgentAdapterResolver, type AgentSessionLike, type AgentStreamEvent, type AttachPolicyInput, BUCKETS_ROOT, type BrowserAdapterHandle, type BrowserAdapterInfo, type BrowserAdapterLister, type BrowserAdapterResolver, BuildHeartbeatAgent, type CommitSpec, type CompletionPolicySupervisor, type CreateGatewayOptions, type CreateOfferInput, type CreatedOffer, DEFAULT_BUCKET, DEFAULT_ORCHESTRATOR_TOOLS, DEFAULT_WORKTREE_ISOLATION, DeclaredAdapterOption, type DeclaredAdapterPreset, type GateSpec, type GatewayHandle, type InboundWatcher, type JudgeGateSpec, LEGACY_SESSIONS_FILE, type McpCredentialDeps, type MigrationMarker, type OnFailSpec, type OrchestratorGatewayDeps, type OrchestratorInjection, type OrchestratorInjector, type OrchestratorInjectorDeps, type OrchestratorMcpServerFactory, type OrchestratorScope, PAIRINGS_VERSION, type PairingChannelContext, type PairingChannelHandle, type PairingChannelMode, type PairingRecord, type PairingRegistry, type PairingRegistryDeps, type PendingPermission, type PermissionRespondInput, type PermissionRespondResult, type PolicyRunState, type PolicyRunStatus, type PresetInfo, type PricingResolver, type RegisterBrowserInput, type RegisterPairingToolsOptions, type RegisterSessionInput, ResolvedAuthSpec, type RuntimeMeta, type SandboxAdapterInfo, type SandboxProviderCapabilities, type SandboxProviderHandle, type SandboxProviderLister, type SandboxProviderResolver, type ScopeTokenRegistry, type SessionDescriptor, type SessionKind, type SessionObserver, type SessionStatus, type SessionUsage, type SessionWaitEvent, type SessionWaitResult, type SessionsRegistry, type ShellGateSpec, type SpawnAgentInput, type SpawnSessionInput, type TokenPricing, type TunnelDescriptor, type TunnelProvider, type TunnelStatus, type UsageComputeInput, type UsageSource, WORKTREE_ISOLATION_ENV, type WatcherDescriptor, type WatcherStartInput, WorkspaceFs, type WorktreeDecision, type WorktreeField, WorktreeIsolationMode, type WorktreeProvisionOutcome, type WorktreeProvisionRequest, type WorktreeProvisioner, type WorktreeRequest, bucketDir, bucketSessionsFile, bucketTranscriptDir, composeSessionObservers, createFileStepCache, createGateway, createOrchestratorInjector, createOrchestratorMcpServerFactory, createPairingRegistry, createScopeTokenRegistry, daemonRegistryDir, decideWorktreeIsolation, declaredPresetToProviderPreset, deriveSessionUsage, formatToolCall, formatToolResult, getMcpCredentialDeps, isAgentCliAuthConfigured, isSafeBucketSlug, listBuckets, listPresets, loadWorktreeIsolation, makeBrowserAdapterLister, migrateLegacySessionsFile, migrationMarkerPath, monitorPolicyWait, monitorSessionWait, narrowOrchestratorTools, normalizeWorktreeField, parseWorktreeIsolationMode, policyWatchesSession, projectSessionUsage, readDaemonRegistry, readRegisteredSlugs, readRuntimeMeta, registerPairingTools, resolveBucketSlug, setMcpCredentialDeps, sweepStaleDaemonRegistry, sweepStaleRuntimeMetas, unlinkDaemonRegistryEntry, unlinkRuntimeMeta, writeDaemonRegistryEntry };
|
|
4280
|
+
export { AdapterAuthDescriptor, type AdapterListEntry, type AgentAdapterLister, type AgentAdapterResolver, type AgentSessionLike, type AgentStreamEvent, type AttachPolicyInput, type AuthMethod, BUCKETS_ROOT, type BrowserAdapterHandle, type BrowserAdapterInfo, type BrowserAdapterLister, type BrowserAdapterResolver, BuildHeartbeatAgent, type CanonicalPosture, type CatalogAdapterInput, type CatalogAdapterModelInput, type CatalogModelsLister, type CatalogModelsQuery, type CatalogModelsResponse, type CatalogPricing, type CatalogProduct, type CatalogRoute, type CatalogVendor, type ClaudeNativeRef, type CommitSpec, type CompletionPolicySupervisor, type ContextProfile, type ConversationIndexRecord, type ConversationNativeRef, type CreateGatewayOptions, type CreateOfferInput, type CreatedOffer, DEFAULT_BUCKET, DEFAULT_ORCHESTRATOR_TOOLS, DEFAULT_WORKTREE_ISOLATION, type DeclaredAdapterMode, DeclaredAdapterOption, type DeclaredAdapterPreset, type EffortLevel, type GateSpec, type GatewayHandle, type HermesNativeRef, type InboundWatcher, type JudgeGateSpec, LEGACY_SESSIONS_FILE, type LocatedConversation, type LocatedConversationByPath, type McpCredentialDeps, type MigrationMarker, type OnFailSpec, type OrchestratorGatewayDeps, type OrchestratorInjection, type OrchestratorInjector, type OrchestratorInjectorDeps, type OrchestratorMcpServerFactory, type OrchestratorScope, PAIRINGS_VERSION, POSTURE_NATIVE_ALIASES, POSTURE_PREAMBLES, type PairingChannelContext, type PairingChannelHandle, type PairingChannelMode, type PairingRecord, type PairingRegistry, type PairingRegistryDeps, type PendingPermission, type PermissionRespondInput, type PermissionRespondResult, type PolicyRunState, type PolicyRunStatus, type Posture, type PostureResolution, type PresetInfo, type PricingResolver, type RegisterBrowserInput, type RegisterPairingToolsOptions, type RegisterSessionInput, type ResolveNativeLinkInput, ResolvedAuthSpec, type RouteSpec, type RuntimeMeta, type SandboxAdapterInfo, type SandboxProviderCapabilities, type SandboxProviderHandle, type SandboxProviderLister, type SandboxProviderResolver, type ScopeTokenRegistry, type SessionConfig, type SessionDescriptor, type SessionKind, type SessionObserver, type SessionStatus, type SessionUsage, type SessionWaitEvent, type SessionWaitResult, type SessionsRegistry, type ShellGateSpec, type SpawnAgentInput, type SpawnSessionInput, type TokenPricing, type TunnelDescriptor, type TunnelProvider, type TunnelStatus, type UsageComputeInput, type UsageSource, WORKTREE_ISOLATION_ENV, type WatcherDescriptor, type WatcherStartInput, WorkspaceFs, type WorktreeDecision, type WorktreeField, WorktreeIsolationMode, type WorktreeProvisionOutcome, type WorktreeProvisionRequest, type WorktreeProvisioner, type WorktreeRequest, appendConversationRecord, bucketDir, bucketSessionsFile, bucketTranscriptDir, buildCatalogModels, canonicalForModeId, claudeProjectSlug, composeMode, composeSessionObservers, conversationIndexPath, createFileStepCache, createGateway, createOrchestratorInjector, createOrchestratorMcpServerFactory, createPairingRegistry, createScopeTokenRegistry, daemonRegistryDir, decideWorktreeIsolation, declaredPresetToProviderPreset, decomposeMode, deriveSessionUsage, findConversationRecord, findNativeMode, formatToolCall, formatToolResult, getMcpCredentialDeps, isAgentCliAuthConfigured, isSafeBucketSlug, listBuckets, listPresets, loadWorktreeIsolation, locateConversationByNativePath, locateConversationBySessionId, makeBrowserAdapterLister, migrateLegacySessionsFile, migrationMarkerPath, monitorPolicyWait, monitorSessionWait, narrowOrchestratorTools, normalizeModeId, normalizeWorktreeField, parseWorktreeIsolationMode, policyWatchesSession, projectSessionUsage, readConversationIndex, readDaemonRegistry, readRegisteredSlugs, readRuntimeMeta, registerPairingTools, resolveBucketSlug, resolveNativeLink, resolvePosture, setMcpCredentialDeps, sweepStaleDaemonRegistry, sweepStaleRuntimeMetas, unlinkDaemonRegistryEntry, unlinkRuntimeMeta, writeDaemonRegistryEntry };
|