@sealant/sdk 0.3.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +107 -12
- package/dist/client.d.ts +12 -7
- package/dist/client.js +33 -21
- package/dist/effect/api-client.d.ts +408 -250
- package/dist/effect/exec-workspace.d.ts +5 -0
- package/dist/effect/exec-workspace.js +60 -0
- package/dist/effect/index.d.ts +27 -0
- package/dist/effect/index.js +31 -0
- package/dist/effect/operations.d.ts +90 -22
- package/dist/effect/operations.js +7 -4
- package/dist/effect/run-harness.d.ts +2 -2
- package/dist/effect/run-harness.js +4 -4
- package/dist/errors.d.ts +1 -1
- package/dist/errors.js +1 -1
- package/dist/facade/record.d.ts +17 -1
- package/dist/facade/record.js +17 -3
- package/dist/facade/run.d.ts +1 -1
- package/dist/facade/{sandbox.d.ts → workspace.d.ts} +6 -6
- package/dist/facade/{sandbox.js → workspace.js} +19 -17
- package/dist/harness.d.ts +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +4 -4
- package/dist/internal/blueprint.d.ts +1 -1
- package/dist/internal/blueprint.js +8 -8
- package/dist/internal/config.d.ts +2 -2
- package/dist/internal/credentials.d.ts +7 -7
- package/dist/internal/credentials.js +2 -2
- package/dist/internal/inference.d.ts +47 -0
- package/dist/internal/inference.js +78 -0
- package/dist/internal/map-error.d.ts +1 -1
- package/dist/internal/map-error.js +1 -1
- package/dist/types.d.ts +310 -39
- package/dist/types.js +2 -2
- package/package.json +7 -3
package/dist/types.d.ts
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This is the fluent object model the marketing site commits to verbatim:
|
|
5
5
|
*
|
|
6
|
-
* const
|
|
7
|
-
* const run = await
|
|
6
|
+
* const workspace = await sealant.workspaces.create({ repository, harness: opencode() })
|
|
7
|
+
* const run = await workspace.harness.run("Round invoice totals once, after applying the discount.")
|
|
8
8
|
* await run.record.replay()
|
|
9
9
|
*
|
|
10
10
|
* Design rule (load-bearing): these public types are HAND-WRITTEN and DECOUPLED from the Effect-core
|
|
@@ -30,7 +30,7 @@ export interface SealantConfig {
|
|
|
30
30
|
}
|
|
31
31
|
/** The harnesses with first-class integrations baked into the platform today. */
|
|
32
32
|
export type HarnessId = "opencode" | "codex" | "claude-code";
|
|
33
|
-
/** A single one-shot command to invoke a harness against a prompt inside the
|
|
33
|
+
/** A single one-shot command to invoke a harness against a prompt inside the workspace. */
|
|
34
34
|
export interface HarnessRunCommand {
|
|
35
35
|
/** The executable to run (e.g. `"opencode"`). */
|
|
36
36
|
readonly executable: string;
|
|
@@ -56,19 +56,19 @@ export interface Harness {
|
|
|
56
56
|
/** Optional launch command for an interactive session (defaults to the executable). */
|
|
57
57
|
readonly launchCommand?: string;
|
|
58
58
|
}
|
|
59
|
-
/** Lifecycle status of a
|
|
60
|
-
export type
|
|
61
|
-
/** A coarse lifecycle event observed while a
|
|
62
|
-
export interface
|
|
59
|
+
/** Lifecycle status of a workspace. `stopped`/`expired` arrive with lifecycle close-out (Phase 3). */
|
|
60
|
+
export type WorkspaceStatus = "queued" | "running" | "ready" | "failed" | "cancelled";
|
|
61
|
+
/** A coarse lifecycle event observed while a workspace is being provisioned. */
|
|
62
|
+
export interface WorkspaceEvent {
|
|
63
63
|
readonly type: string;
|
|
64
64
|
readonly occurredAt: string;
|
|
65
65
|
readonly message?: string;
|
|
66
66
|
}
|
|
67
|
-
/** The supported
|
|
68
|
-
export type
|
|
67
|
+
/** The supported workspace OS families (maps to the blueprint target). */
|
|
68
|
+
export type WorkspaceOs = "fedora" | "arch" | "nix";
|
|
69
69
|
/**
|
|
70
|
-
* Connected-account credentials to attach to a
|
|
71
|
-
* harness inside the
|
|
70
|
+
* Connected-account credentials to attach to a workspace at creation time, per provider — so the
|
|
71
|
+
* harness inside the workspace authenticates as the caller's own Claude / Codex / GitHub identity
|
|
72
72
|
* instead of running unauthenticated.
|
|
73
73
|
*
|
|
74
74
|
* For each provider: `true` means "my default account" (the one named `"default"`), and a `string`
|
|
@@ -80,7 +80,7 @@ export type SandboxOs = "fedora" | "arch" | "nix";
|
|
|
80
80
|
* `auth.json` contents, and any other secret material never do. The control plane resolves references
|
|
81
81
|
* to encrypted credentials server-side and injects them at launch.
|
|
82
82
|
*/
|
|
83
|
-
export interface
|
|
83
|
+
export interface WorkspaceCredentialsOptions {
|
|
84
84
|
/** Profile id whose per-provider account bindings apply first. */
|
|
85
85
|
readonly profile?: string;
|
|
86
86
|
/** `true` for the caller's default Claude account, or a string naming a specific one. */
|
|
@@ -91,46 +91,72 @@ export interface SandboxCredentialsOptions {
|
|
|
91
91
|
readonly github?: boolean | string;
|
|
92
92
|
}
|
|
93
93
|
export interface CreateOptions {
|
|
94
|
-
/** Source git repository to build the
|
|
94
|
+
/** Source git repository to build the workspace around (e.g. `"github.com/acme/billing-service"`). */
|
|
95
95
|
readonly repository: string;
|
|
96
|
-
/** The harness to run inside the
|
|
96
|
+
/** The harness to run inside the workspace. */
|
|
97
97
|
readonly harness: Harness;
|
|
98
98
|
/** Git ref to check out (defaults to the repository's default branch). */
|
|
99
99
|
readonly ref?: string;
|
|
100
|
-
/** Human-friendly name for the
|
|
100
|
+
/** Human-friendly name for the workspace. */
|
|
101
101
|
readonly name?: string;
|
|
102
|
-
/** OS family for the
|
|
103
|
-
readonly os?:
|
|
104
|
-
/** Extra OS packages to install in the
|
|
102
|
+
/** OS family for the workspace image. */
|
|
103
|
+
readonly os?: WorkspaceOs;
|
|
104
|
+
/** Extra OS packages to install in the workspace. */
|
|
105
105
|
readonly packages?: readonly string[];
|
|
106
|
-
/** When true (default), resolve only once the
|
|
106
|
+
/** When true (default), resolve only once the workspace runtime is live. */
|
|
107
107
|
readonly wait?: boolean;
|
|
108
108
|
/** Observe provisioning events as they happen. */
|
|
109
|
-
readonly onEvent?: (event:
|
|
110
|
-
/** Connected-account credentials to attach to the
|
|
111
|
-
readonly credentials?:
|
|
109
|
+
readonly onEvent?: (event: WorkspaceEvent) => void;
|
|
110
|
+
/** Connected-account credentials to attach to the workspace (see `WorkspaceCredentialsOptions`). */
|
|
111
|
+
readonly credentials?: WorkspaceCredentialsOptions;
|
|
112
112
|
}
|
|
113
113
|
export interface ListOptions {
|
|
114
|
-
readonly status?:
|
|
114
|
+
readonly status?: WorkspaceStatus;
|
|
115
115
|
readonly limit?: number;
|
|
116
116
|
}
|
|
117
|
+
/** Options for a deterministic `workspace.exec()`. */
|
|
118
|
+
export interface WorkspaceExecOptions {
|
|
119
|
+
/** Working directory inside the workspace (defaults to the repository root). */
|
|
120
|
+
readonly cwd?: string;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* The settled result of a deterministic `workspace.exec()`. The exit code is a check DATUM — a
|
|
124
|
+
* nonzero exit resolves normally (that's the point: `base fails` is a recorded fact, not an error).
|
|
125
|
+
* `exec()` rejects only when the execution machinery itself broke, i.e. when the exit code cannot
|
|
126
|
+
* be trusted.
|
|
127
|
+
*/
|
|
128
|
+
export interface WorkspaceExecResult {
|
|
129
|
+
/** Exit code of the executed command. */
|
|
130
|
+
readonly exitCode: number;
|
|
131
|
+
/** Everything the command wrote to stdout, decoded as UTF-8. */
|
|
132
|
+
readonly stdout: string;
|
|
133
|
+
/** Everything the command wrote to stderr, decoded as UTF-8. */
|
|
134
|
+
readonly stderr: string;
|
|
135
|
+
/** The run this exec was recorded as — its `record` is the durable, replayable evidence. */
|
|
136
|
+
readonly run: Run;
|
|
137
|
+
}
|
|
117
138
|
/** A live, disposable development environment around a real repository. */
|
|
118
|
-
export interface
|
|
139
|
+
export interface Workspace {
|
|
119
140
|
readonly id: string;
|
|
120
141
|
readonly name: string;
|
|
121
142
|
/** Current lifecycle status. */
|
|
122
|
-
status(): Promise<
|
|
123
|
-
/** Resolves once the
|
|
143
|
+
status(): Promise<WorkspaceStatus>;
|
|
144
|
+
/** Resolves once the workspace runtime is live and ready to accept a run. */
|
|
124
145
|
ready(): Promise<this>;
|
|
125
|
-
/** Run a harness in this
|
|
146
|
+
/** Run a harness in this workspace. */
|
|
126
147
|
readonly harness: HarnessRunner;
|
|
148
|
+
/**
|
|
149
|
+
* Execute one command deterministically in the workspace — no agent in the loop — recorded into a
|
|
150
|
+
* run record like any other process. `argv[0]` is the executable, the rest its arguments.
|
|
151
|
+
*/
|
|
152
|
+
exec(argv: readonly string[], options?: WorkspaceExecOptions): Promise<WorkspaceExecResult>;
|
|
127
153
|
/** Lifecycle events as an async stream. */
|
|
128
|
-
events(): AsyncIterable<
|
|
129
|
-
/** Stop the
|
|
154
|
+
events(): AsyncIterable<WorkspaceEvent>;
|
|
155
|
+
/** Stop the workspace now (Phase 3). */
|
|
130
156
|
stop(): Promise<void>;
|
|
131
|
-
/** Restart the
|
|
132
|
-
restart(): Promise<
|
|
133
|
-
/** Schedule the
|
|
157
|
+
/** Restart the workspace into a fresh runtime (Phase 3). */
|
|
158
|
+
restart(): Promise<Workspace>;
|
|
159
|
+
/** Schedule the workspace to expire (Phase 3). */
|
|
134
160
|
expire(options?: {
|
|
135
161
|
readonly in?: string;
|
|
136
162
|
}): Promise<void>;
|
|
@@ -144,13 +170,13 @@ export interface RunOptions {
|
|
|
144
170
|
export interface SessionOptions {
|
|
145
171
|
readonly signal?: AbortSignal;
|
|
146
172
|
}
|
|
147
|
-
/** Runs a harness in a
|
|
173
|
+
/** Runs a harness in a workspace, one-shot or interactive. */
|
|
148
174
|
export interface HarnessRunner {
|
|
149
175
|
/** BLOCKING: resolves once the harness has terminally completed; `result`/`changes` are settled. */
|
|
150
176
|
run(prompt: string, options?: RunOptions): Promise<Run>;
|
|
151
177
|
/** NON-BLOCKING: returns a live handle immediately for streaming via `run.record.stream()`. */
|
|
152
178
|
start(prompt: string, options?: RunOptions): Promise<Run>;
|
|
153
|
-
/** Interactive session reusing the live
|
|
179
|
+
/** Interactive session reusing the live workspace (Phase 3). */
|
|
154
180
|
session(options?: SessionOptions): Promise<InteractiveSession>;
|
|
155
181
|
}
|
|
156
182
|
export type RunOutcome = "completed" | "failed";
|
|
@@ -185,13 +211,171 @@ export interface RunArtifacts {
|
|
|
185
211
|
list(): Promise<readonly ArtifactRef[]>;
|
|
186
212
|
get(name: string): Promise<Uint8Array>;
|
|
187
213
|
}
|
|
188
|
-
/**
|
|
189
|
-
export interface
|
|
214
|
+
/** The runtime daemon's lifecycle state changed. `state` is a numeric `RuntimeState`. */
|
|
215
|
+
export interface RuntimeStateChangedEvent {
|
|
216
|
+
readonly state: number;
|
|
217
|
+
readonly reason?: string | undefined;
|
|
218
|
+
}
|
|
219
|
+
/** Periodic runtime liveness signal. `state` is a numeric `RuntimeState`. */
|
|
220
|
+
export interface RuntimeHeartbeatEvent {
|
|
221
|
+
readonly state: number;
|
|
222
|
+
}
|
|
223
|
+
/** A supervised process began executing. */
|
|
224
|
+
export interface ProcessStartedEvent {
|
|
225
|
+
readonly pid: number;
|
|
226
|
+
readonly pgid: number;
|
|
227
|
+
readonly pidfd: boolean;
|
|
228
|
+
readonly executable: string;
|
|
229
|
+
readonly args: readonly string[];
|
|
230
|
+
readonly cwd: string;
|
|
231
|
+
/** Wall clock at start, microseconds (decimal string). */
|
|
232
|
+
readonly startedAt: string;
|
|
233
|
+
}
|
|
234
|
+
/** A supervised process ended. `reason` is a numeric `ExitReason`. */
|
|
235
|
+
export interface ProcessExitedEvent {
|
|
236
|
+
readonly exitCode?: number | undefined;
|
|
237
|
+
readonly signal?: number | undefined;
|
|
238
|
+
readonly reason: number;
|
|
239
|
+
/** Wall-clock duration, microseconds (decimal string). */
|
|
240
|
+
readonly durationMicros: string;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* A run of process output. Raw bytes live in the artifact store (fetch byte-exact text via
|
|
244
|
+
* `record.scrollback()`); the event carries counts and a content hash. `stream` is a numeric
|
|
245
|
+
* `StreamKind` (stdout = 2, stderr = 3).
|
|
246
|
+
*/
|
|
247
|
+
export interface IoChunkEvent {
|
|
248
|
+
readonly stream: number;
|
|
249
|
+
readonly byteCount: string;
|
|
250
|
+
readonly streamOffset: string;
|
|
251
|
+
readonly contentAlgo?: string | undefined;
|
|
252
|
+
readonly contentHash?: string | undefined;
|
|
253
|
+
readonly transform?: {
|
|
254
|
+
readonly redacted: boolean;
|
|
255
|
+
readonly truncated: boolean;
|
|
256
|
+
readonly coalesced: boolean;
|
|
257
|
+
readonly originalByteCount?: string | undefined;
|
|
258
|
+
} | undefined;
|
|
259
|
+
}
|
|
260
|
+
/** The runtime dropped events under pressure. `priority` is a numeric `EventPriority`. */
|
|
261
|
+
export interface TelemetryDroppedEvent {
|
|
262
|
+
readonly reason: string;
|
|
263
|
+
readonly count: string;
|
|
264
|
+
readonly priority: number;
|
|
265
|
+
}
|
|
266
|
+
/** Filesystem entry metadata attached to a change. `fileType` is a numeric `FileType`. */
|
|
267
|
+
export interface FileEntryData {
|
|
268
|
+
readonly path: string;
|
|
269
|
+
readonly fileType: number;
|
|
270
|
+
readonly size: string;
|
|
271
|
+
readonly mtimeMicros: string;
|
|
272
|
+
readonly mode: number;
|
|
273
|
+
readonly hash?: string | undefined;
|
|
274
|
+
readonly symlinkTarget?: string | undefined;
|
|
275
|
+
}
|
|
276
|
+
/** A watched file changed. `kind` is a numeric `FileChangeKind`. */
|
|
277
|
+
export interface FileChangeEvent {
|
|
278
|
+
readonly kind: number;
|
|
279
|
+
readonly path: string;
|
|
280
|
+
readonly renameFrom?: string | undefined;
|
|
281
|
+
readonly entry?: FileEntryData | undefined;
|
|
282
|
+
readonly certain: boolean;
|
|
283
|
+
}
|
|
284
|
+
/** The file watcher overflowed — changes under `root` may have been missed. */
|
|
285
|
+
export interface FileWatchOverflowEvent {
|
|
286
|
+
readonly root: string;
|
|
287
|
+
}
|
|
288
|
+
/** A filesystem snapshot pass finished. */
|
|
289
|
+
export interface FileSnapshotCompletedEvent {
|
|
290
|
+
readonly root: string;
|
|
291
|
+
readonly fileCount: string;
|
|
292
|
+
}
|
|
293
|
+
/** Aggregate before/after diff counts became available. */
|
|
294
|
+
export interface FileDiffAvailableEvent {
|
|
295
|
+
readonly added: string;
|
|
296
|
+
readonly modified: string;
|
|
297
|
+
readonly deleted: string;
|
|
298
|
+
readonly renamed: string;
|
|
299
|
+
}
|
|
300
|
+
/** An outbound network request the run made. `scheme` is a numeric `NetworkScheme`. */
|
|
301
|
+
export interface NetworkRequestEvent {
|
|
302
|
+
readonly scheme: number;
|
|
303
|
+
readonly method?: string | undefined;
|
|
304
|
+
readonly host: string;
|
|
305
|
+
readonly port: number;
|
|
306
|
+
readonly path?: string | undefined;
|
|
307
|
+
readonly status?: number | undefined;
|
|
308
|
+
readonly bytesSent: string;
|
|
309
|
+
readonly bytesReceived: string;
|
|
310
|
+
readonly durationMicros: string;
|
|
311
|
+
}
|
|
312
|
+
/** A network source the run touched — the raw material of a "sources the agent opened" trail. */
|
|
313
|
+
export interface NetworkSourceObservedEvent {
|
|
314
|
+
readonly host: string;
|
|
315
|
+
readonly resolvedIps: readonly string[];
|
|
316
|
+
readonly port: number;
|
|
317
|
+
readonly scheme?: number | undefined;
|
|
318
|
+
readonly method?: string | undefined;
|
|
319
|
+
readonly path?: string | undefined;
|
|
320
|
+
readonly status?: number | undefined;
|
|
321
|
+
}
|
|
322
|
+
/** Fields shared by every timeline entry, independent of its kind. */
|
|
323
|
+
export interface TimelineEntryBase {
|
|
190
324
|
readonly sequence: bigint;
|
|
191
|
-
readonly kind: string;
|
|
192
325
|
readonly occurredAt: string;
|
|
193
|
-
|
|
326
|
+
/** One-line human summary of the event. */
|
|
327
|
+
readonly summary: string;
|
|
328
|
+
/** Correlation id of the producing process, when attributable. */
|
|
329
|
+
readonly processId?: string | undefined;
|
|
194
330
|
}
|
|
331
|
+
/**
|
|
332
|
+
* A single ordered entry in the execution record's timeline, DISCRIMINATED by `kind`: switch on it
|
|
333
|
+
* and `data` narrows to the event's typed payload. The `"unknown"` case is the forward-compatibility
|
|
334
|
+
* path — it carries kinds newer than this SDK (or payloads that failed their schema) with the wire
|
|
335
|
+
* kind preserved in `rawKind` and the payload verbatim in `data`.
|
|
336
|
+
*/
|
|
337
|
+
export type TimelineEntry = (TimelineEntryBase & {
|
|
338
|
+
readonly kind: "runtimeStateChanged";
|
|
339
|
+
readonly data: RuntimeStateChangedEvent;
|
|
340
|
+
}) | (TimelineEntryBase & {
|
|
341
|
+
readonly kind: "runtimeHeartbeat";
|
|
342
|
+
readonly data: RuntimeHeartbeatEvent;
|
|
343
|
+
}) | (TimelineEntryBase & {
|
|
344
|
+
readonly kind: "processStarted";
|
|
345
|
+
readonly data: ProcessStartedEvent;
|
|
346
|
+
}) | (TimelineEntryBase & {
|
|
347
|
+
readonly kind: "processExited";
|
|
348
|
+
readonly data: ProcessExitedEvent;
|
|
349
|
+
}) | (TimelineEntryBase & {
|
|
350
|
+
readonly kind: "ioChunk";
|
|
351
|
+
readonly data: IoChunkEvent;
|
|
352
|
+
}) | (TimelineEntryBase & {
|
|
353
|
+
readonly kind: "telemetryDropped";
|
|
354
|
+
readonly data: TelemetryDroppedEvent;
|
|
355
|
+
}) | (TimelineEntryBase & {
|
|
356
|
+
readonly kind: "fileChange";
|
|
357
|
+
readonly data: FileChangeEvent;
|
|
358
|
+
}) | (TimelineEntryBase & {
|
|
359
|
+
readonly kind: "fileWatchOverflow";
|
|
360
|
+
readonly data: FileWatchOverflowEvent;
|
|
361
|
+
}) | (TimelineEntryBase & {
|
|
362
|
+
readonly kind: "fileSnapshotCompleted";
|
|
363
|
+
readonly data: FileSnapshotCompletedEvent;
|
|
364
|
+
}) | (TimelineEntryBase & {
|
|
365
|
+
readonly kind: "fileDiffAvailable";
|
|
366
|
+
readonly data: FileDiffAvailableEvent;
|
|
367
|
+
}) | (TimelineEntryBase & {
|
|
368
|
+
readonly kind: "networkRequest";
|
|
369
|
+
readonly data: NetworkRequestEvent;
|
|
370
|
+
}) | (TimelineEntryBase & {
|
|
371
|
+
readonly kind: "networkSourceObserved";
|
|
372
|
+
readonly data: NetworkSourceObservedEvent;
|
|
373
|
+
}) | (TimelineEntryBase & {
|
|
374
|
+
readonly kind: "unknown";
|
|
375
|
+
/** The kind as received on the wire — set when this SDK version doesn't model it. */
|
|
376
|
+
readonly rawKind: string;
|
|
377
|
+
readonly data: unknown;
|
|
378
|
+
});
|
|
195
379
|
/** A re-fold of the record up to some point — scrubable by sequence. */
|
|
196
380
|
export interface RunReplay {
|
|
197
381
|
readonly entries: readonly TimelineEntry[];
|
|
@@ -283,9 +467,96 @@ export interface Run {
|
|
|
283
467
|
/** Resolves once the run has terminally completed (no-op if already settled). */
|
|
284
468
|
wait(): Promise<Run>;
|
|
285
469
|
}
|
|
286
|
-
/** An interactive harness session over the live
|
|
470
|
+
/** An interactive harness session over the live workspace (Phase 3). */
|
|
287
471
|
export interface InteractiveSession {
|
|
288
472
|
send(input: string): Promise<void>;
|
|
289
473
|
output(): AsyncIterable<Uint8Array>;
|
|
290
474
|
close(): Promise<void>;
|
|
291
475
|
}
|
|
476
|
+
/**
|
|
477
|
+
* Connected-account selection for inference — the same reference shape as workspace creation,
|
|
478
|
+
* minus GitHub (not a model provider). `true` means "my default account"; a string names one.
|
|
479
|
+
* Only claude accounts are supported today; a codex selection is rejected until Codex inference
|
|
480
|
+
* ships. SECURITY: only account references cross this surface — never token material.
|
|
481
|
+
*/
|
|
482
|
+
export interface InferenceCredentialsOptions {
|
|
483
|
+
/** Profile id whose claude binding applies when `claude` is not set explicitly. */
|
|
484
|
+
readonly profile?: string;
|
|
485
|
+
/** `true` for the caller's default claude account, or a string naming a specific one. */
|
|
486
|
+
readonly claude?: boolean | string;
|
|
487
|
+
/** Reserved — rejected until Codex inference ships. */
|
|
488
|
+
readonly codex?: boolean | string;
|
|
489
|
+
}
|
|
490
|
+
/** A caller-defined tool the model may call. `inputSchema` is a JSON Schema object, verbatim. */
|
|
491
|
+
export interface InferenceToolDefinition {
|
|
492
|
+
readonly name: string;
|
|
493
|
+
readonly description?: string;
|
|
494
|
+
readonly inputSchema: unknown;
|
|
495
|
+
}
|
|
496
|
+
/** A tool call the model made. Execute it YOUR side, then respond with an `InferenceToolResult`. */
|
|
497
|
+
export interface InferenceToolCall {
|
|
498
|
+
readonly toolCallId: string;
|
|
499
|
+
readonly name: string;
|
|
500
|
+
readonly input: unknown;
|
|
501
|
+
}
|
|
502
|
+
/** Your result for one tool call, keyed by its `toolCallId`. */
|
|
503
|
+
export interface InferenceToolResult {
|
|
504
|
+
readonly toolCallId: string;
|
|
505
|
+
readonly content: string;
|
|
506
|
+
readonly isError?: boolean;
|
|
507
|
+
}
|
|
508
|
+
/** The assistant turn: the final text (with parsed `json` when requested) or pending tool calls. */
|
|
509
|
+
export type InferenceTurn = {
|
|
510
|
+
readonly type: "text";
|
|
511
|
+
readonly text: string;
|
|
512
|
+
readonly json?: unknown;
|
|
513
|
+
} | {
|
|
514
|
+
readonly type: "toolCalls";
|
|
515
|
+
readonly calls: readonly InferenceToolCall[];
|
|
516
|
+
};
|
|
517
|
+
export interface InferenceUsage {
|
|
518
|
+
readonly inputTokens: number;
|
|
519
|
+
readonly outputTokens: number;
|
|
520
|
+
}
|
|
521
|
+
export interface InferenceResponse {
|
|
522
|
+
/** Continuation handle for the tool loop (held in memory server-side; expires after idle). */
|
|
523
|
+
readonly sessionId: string;
|
|
524
|
+
readonly turn: InferenceTurn;
|
|
525
|
+
/** Usage for the exchange, present on the final text turn. */
|
|
526
|
+
readonly usage?: InferenceUsage;
|
|
527
|
+
}
|
|
528
|
+
/** Starts a new inference exchange on a connected account. */
|
|
529
|
+
export interface InferenceRespondOptions {
|
|
530
|
+
readonly prompt: string;
|
|
531
|
+
readonly system?: string;
|
|
532
|
+
readonly model?: string;
|
|
533
|
+
/** Upper bound on agentic turns within the exchange (server default 16). */
|
|
534
|
+
readonly maxTurns?: number;
|
|
535
|
+
readonly tools?: readonly InferenceToolDefinition[];
|
|
536
|
+
/** Structured output: reply as JSON (schema-constrained when `schema` is given). */
|
|
537
|
+
readonly responseFormat?: {
|
|
538
|
+
readonly type: "json";
|
|
539
|
+
readonly schema?: unknown;
|
|
540
|
+
};
|
|
541
|
+
readonly credentials: InferenceCredentialsOptions;
|
|
542
|
+
}
|
|
543
|
+
/** Continues an exchange by posting the results of the previous turn's tool calls. */
|
|
544
|
+
export interface InferenceContinueOptions {
|
|
545
|
+
readonly sessionId: string;
|
|
546
|
+
readonly toolResults: readonly InferenceToolResult[];
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Inference on connected accounts. The model call runs SERVER-SIDE through the official agent SDKs
|
|
550
|
+
* on the resolved account's credential (never raw model-API calls); the tool loop is CALLER-
|
|
551
|
+
* EXECUTED — a `toolCalls` turn parks server-side until you `respond()` with the results:
|
|
552
|
+
*
|
|
553
|
+
* let response = await sealant.inference.respond({ prompt, tools, credentials: { claude: true } })
|
|
554
|
+
* while (response.turn.type === "toolCalls") {
|
|
555
|
+
* const toolResults = await runTools(response.turn.calls)
|
|
556
|
+
* response = await sealant.inference.respond({ sessionId: response.sessionId, toolResults })
|
|
557
|
+
* }
|
|
558
|
+
* response.turn.text
|
|
559
|
+
*/
|
|
560
|
+
export interface InferenceNamespace {
|
|
561
|
+
respond(options: InferenceRespondOptions | InferenceContinueOptions): Promise<InferenceResponse>;
|
|
562
|
+
}
|
package/dist/types.js
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This is the fluent object model the marketing site commits to verbatim:
|
|
5
5
|
*
|
|
6
|
-
* const
|
|
7
|
-
* const run = await
|
|
6
|
+
* const workspace = await sealant.workspaces.create({ repository, harness: opencode() })
|
|
7
|
+
* const run = await workspace.harness.run("Round invoice totals once, after applying the discount.")
|
|
8
8
|
* await run.record.replay()
|
|
9
9
|
*
|
|
10
10
|
* Design rule (load-bearing): these public types are HAND-WRITTEN and DECOUPLED from the Effect-core
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sealant/sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "The fluent public SDK for Sealant — create a
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "The fluent public SDK for Sealant — create a workspace, run a harness, replay the record.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -16,6 +16,10 @@
|
|
|
16
16
|
".": {
|
|
17
17
|
"types": "./dist/index.d.ts",
|
|
18
18
|
"import": "./dist/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./effect": {
|
|
21
|
+
"types": "./dist/effect/index.d.ts",
|
|
22
|
+
"import": "./dist/effect/index.js"
|
|
19
23
|
}
|
|
20
24
|
},
|
|
21
25
|
"publishConfig": {
|
|
@@ -23,7 +27,7 @@
|
|
|
23
27
|
},
|
|
24
28
|
"dependencies": {
|
|
25
29
|
"effect": "^4.0.0-beta.85",
|
|
26
|
-
"@sealant/api-contracts": "^0.
|
|
30
|
+
"@sealant/api-contracts": "^0.5.0"
|
|
27
31
|
},
|
|
28
32
|
"devDependencies": {
|
|
29
33
|
"@effect/vitest": "^4.0.0-beta.85",
|