@sapiom/tools 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +87 -0
- package/dist/cjs/_client/index.d.ts +68 -0
- package/dist/cjs/_client/index.d.ts.map +1 -0
- package/dist/cjs/_client/index.js +115 -0
- package/dist/cjs/_client/index.js.map +1 -0
- package/dist/cjs/agent/index.d.ts +90 -0
- package/dist/cjs/agent/index.d.ts.map +1 -0
- package/dist/cjs/agent/index.js +108 -0
- package/dist/cjs/agent/index.js.map +1 -0
- package/dist/cjs/client.d.ts +51 -0
- package/dist/cjs/client.d.ts.map +1 -0
- package/dist/cjs/client.js +50 -0
- package/dist/cjs/client.js.map +1 -0
- package/dist/cjs/index.d.ts +22 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +59 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/repositories/index.d.ts +59 -0
- package/dist/cjs/repositories/index.d.ts.map +1 -0
- package/dist/cjs/repositories/index.js +107 -0
- package/dist/cjs/repositories/index.js.map +1 -0
- package/dist/cjs/sandboxes/index.d.ts +67 -0
- package/dist/cjs/sandboxes/index.d.ts.map +1 -0
- package/dist/cjs/sandboxes/index.js +255 -0
- package/dist/cjs/sandboxes/index.js.map +1 -0
- package/dist/cjs/sandboxes/types.d.ts +111 -0
- package/dist/cjs/sandboxes/types.d.ts.map +1 -0
- package/dist/cjs/sandboxes/types.js +3 -0
- package/dist/cjs/sandboxes/types.js.map +1 -0
- package/dist/esm/_client/index.d.ts +68 -0
- package/dist/esm/_client/index.d.ts.map +1 -0
- package/dist/esm/_client/index.js +110 -0
- package/dist/esm/_client/index.js.map +1 -0
- package/dist/esm/agent/index.d.ts +90 -0
- package/dist/esm/agent/index.d.ts.map +1 -0
- package/dist/esm/agent/index.js +103 -0
- package/dist/esm/agent/index.js.map +1 -0
- package/dist/esm/client.d.ts +51 -0
- package/dist/esm/client.d.ts.map +1 -0
- package/dist/esm/client.js +47 -0
- package/dist/esm/client.js.map +1 -0
- package/dist/esm/index.d.ts +22 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +20 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/repositories/index.d.ts +59 -0
- package/dist/esm/repositories/index.d.ts.map +1 -0
- package/dist/esm/repositories/index.js +99 -0
- package/dist/esm/repositories/index.js.map +1 -0
- package/dist/esm/sandboxes/index.d.ts +67 -0
- package/dist/esm/sandboxes/index.d.ts.map +1 -0
- package/dist/esm/sandboxes/index.js +249 -0
- package/dist/esm/sandboxes/index.js.map +1 -0
- package/dist/esm/sandboxes/types.d.ts +111 -0
- package/dist/esm/sandboxes/types.d.ts.map +1 -0
- package/dist/esm/sandboxes/types.js +2 -0
- package/dist/esm/sandboxes/types.js.map +1 -0
- package/dist/tsconfig.cjs.tsbuildinfo +1 -0
- package/dist/tsconfig.esm.tsbuildinfo +1 -0
- package/package.json +69 -0
- package/src/agent/README.md +36 -0
- package/src/repositories/README.md +29 -0
- package/src/sandboxes/README.md +30 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/** Memory tier for sandbox allocation. */
|
|
2
|
+
export type SandboxTier = "xs" | "s" | "m" | "l" | "xl";
|
|
3
|
+
/** Port specification for an exposed port. */
|
|
4
|
+
export interface PortSpec {
|
|
5
|
+
port: number;
|
|
6
|
+
[key: string]: unknown;
|
|
7
|
+
}
|
|
8
|
+
/** Options for creating a sandbox. */
|
|
9
|
+
export interface SandboxCreateOptions {
|
|
10
|
+
/** Sandbox name. Lowercase alphanumeric and hyphens, 2-63 characters. */
|
|
11
|
+
name: string;
|
|
12
|
+
/** Memory tier. @default 's' */
|
|
13
|
+
tier?: SandboxTier;
|
|
14
|
+
/** Time-to-live (e.g. '1h', '24h', '7d'). */
|
|
15
|
+
ttl?: string;
|
|
16
|
+
/** Environment variables to set in the sandbox. */
|
|
17
|
+
envs?: Record<string, string>;
|
|
18
|
+
/** Single port to expose. Mutually exclusive with `ports`. */
|
|
19
|
+
port?: number;
|
|
20
|
+
/** Ports to expose. Mutually exclusive with `port`. */
|
|
21
|
+
ports?: PortSpec[];
|
|
22
|
+
/**
|
|
23
|
+
* Pre-built image reference to launch from. The image must be reachable by the
|
|
24
|
+
* Sapiom sandbox service (e.g. a managed `sapiom/...` image or one your tenant
|
|
25
|
+
* has access to).
|
|
26
|
+
*
|
|
27
|
+
* NOTE: building a custom image from a Dockerfile is intentionally NOT exposed
|
|
28
|
+
* here yet — it requires the platform to inject the sandbox runtime agent, which
|
|
29
|
+
* shouldn't leak into the author's Dockerfile. It lands later as a properly
|
|
30
|
+
* abstracted capability. See docs/plans/capability-authoring-sdk.md.
|
|
31
|
+
*/
|
|
32
|
+
image?: string;
|
|
33
|
+
/** Override the sandbox service base URL (platform routing detail; rarely needed). */
|
|
34
|
+
baseUrl?: string;
|
|
35
|
+
}
|
|
36
|
+
/** Options for executing a command (non-streaming). */
|
|
37
|
+
export interface ExecOptions {
|
|
38
|
+
/** Working directory, resolved relative to the sandbox workspace root. */
|
|
39
|
+
cwd?: string;
|
|
40
|
+
/** Environment variables for the process. */
|
|
41
|
+
env?: Record<string, string>;
|
|
42
|
+
/**
|
|
43
|
+
* Wait for the process to finish before returning. When false, returns
|
|
44
|
+
* immediately after process creation (fire-and-forget). @default true
|
|
45
|
+
*/
|
|
46
|
+
waitForCompletion?: boolean;
|
|
47
|
+
/** Polling interval in ms while waiting for completion. @default 1000 */
|
|
48
|
+
pollInterval?: number;
|
|
49
|
+
/** Timeout in ms while waiting for completion. @default 60000 */
|
|
50
|
+
timeout?: number;
|
|
51
|
+
/** Keep the sandbox awake (no standby) while this process runs. */
|
|
52
|
+
keepAlive?: boolean;
|
|
53
|
+
/** Auto-terminate the process after this many seconds (0 = no auto-termination). */
|
|
54
|
+
processTimeout?: number;
|
|
55
|
+
/** AbortSignal to cancel the operation. */
|
|
56
|
+
signal?: AbortSignal;
|
|
57
|
+
}
|
|
58
|
+
/** Options for streaming command execution. */
|
|
59
|
+
export interface ExecStreamOptions {
|
|
60
|
+
/** Working directory, resolved relative to the sandbox workspace root. */
|
|
61
|
+
cwd?: string;
|
|
62
|
+
/** Environment variables for the process. */
|
|
63
|
+
env?: Record<string, string>;
|
|
64
|
+
/** AbortSignal to cancel the operation. */
|
|
65
|
+
signal?: AbortSignal;
|
|
66
|
+
}
|
|
67
|
+
/** A single line of process output from a streaming exec. */
|
|
68
|
+
export interface OutputLine {
|
|
69
|
+
stream: "stdout" | "stderr";
|
|
70
|
+
data: string;
|
|
71
|
+
}
|
|
72
|
+
/** Result of a (non-streaming) process execution. */
|
|
73
|
+
export interface ExecResult {
|
|
74
|
+
/** Process ID in the sandbox. */
|
|
75
|
+
pid: string;
|
|
76
|
+
/** Exit code. -1 when `waitForCompletion` is false and the process hasn't finished. */
|
|
77
|
+
exitCode: number;
|
|
78
|
+
stdout: string;
|
|
79
|
+
stderr: string;
|
|
80
|
+
}
|
|
81
|
+
/** Result of a streaming process execution. Iterate `output`; `exitCode` populates after it drains. */
|
|
82
|
+
export interface StreamingExecResult {
|
|
83
|
+
readonly pid: string;
|
|
84
|
+
readonly exitCode: number;
|
|
85
|
+
readonly output: AsyncIterable<OutputLine>;
|
|
86
|
+
}
|
|
87
|
+
/** Process status as reported by the sandbox service. */
|
|
88
|
+
export interface ProcessStatus {
|
|
89
|
+
pid: string;
|
|
90
|
+
status: string;
|
|
91
|
+
exitCode?: number;
|
|
92
|
+
stdout?: string;
|
|
93
|
+
stderr?: string;
|
|
94
|
+
[key: string]: unknown;
|
|
95
|
+
}
|
|
96
|
+
/** @internal Raw create response. */
|
|
97
|
+
export interface CreateResponse {
|
|
98
|
+
name: string;
|
|
99
|
+
workspaceRoot: string;
|
|
100
|
+
[key: string]: unknown;
|
|
101
|
+
}
|
|
102
|
+
/** @internal Raw process-create response. */
|
|
103
|
+
export interface ProcessCreateResponse {
|
|
104
|
+
pid: string;
|
|
105
|
+
status: string;
|
|
106
|
+
stdout?: string;
|
|
107
|
+
stderr?: string;
|
|
108
|
+
exitCode?: number;
|
|
109
|
+
[key: string]: unknown;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/sandboxes/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/sandboxes/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth + transport core for `@sapiom/tools` — the private "runtime half" every
|
|
3
|
+
* capability namespace wraps. Capability modules call THIS; they never import each
|
|
4
|
+
* other's runtime, so the cross-capability mesh (`repo.pushFromSandbox(sandbox)`)
|
|
5
|
+
* has no package/module cycles. See docs/plans/capability-authoring-sdk.md.
|
|
6
|
+
*
|
|
7
|
+
* The credential resolves from one of two sources, same surface either way:
|
|
8
|
+
* - explicit: createClient({ apiKey }) — standalone / open-source use
|
|
9
|
+
* - ambient: SAPIOM_API_KEY (env), which the workflow engine injects per
|
|
10
|
+
* execution so step authors write zero auth plumbing.
|
|
11
|
+
*
|
|
12
|
+
* Attribution (which agent / trace a call belongs to) is execution context the
|
|
13
|
+
* runtime owns, NOT a parameter of any operation — so it lives here on the
|
|
14
|
+
* transport, set once and injected on every request, never threaded through
|
|
15
|
+
* capability methods. The engine sets it per execution by constructing the
|
|
16
|
+
* per-execution client; `withAttribution(...)` is a quiet escape hatch for the
|
|
17
|
+
* router / standalone cases. Capability method signatures deliberately have no
|
|
18
|
+
* attribution argument: that absence keeps LLM-authored step code from setting
|
|
19
|
+
* (and getting wrong) context it doesn't own.
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Per-request attribution recorded with the gateway transaction. Every field is
|
|
23
|
+
* optional and maps 1:1 to an `x-sapiom-*` header the collapsed flow understands.
|
|
24
|
+
*/
|
|
25
|
+
export interface Attribution {
|
|
26
|
+
/** Human-readable agent name. Mutually exclusive with `agentId` (gateway-enforced). */
|
|
27
|
+
agentName?: string;
|
|
28
|
+
/** Agent UUID. Mutually exclusive with `agentName` (gateway-enforced). */
|
|
29
|
+
agentId?: string;
|
|
30
|
+
/** Sapiom trace id to attribute this call to. */
|
|
31
|
+
traceId?: string;
|
|
32
|
+
/** Your own external trace / correlation id. */
|
|
33
|
+
traceExternalId?: string;
|
|
34
|
+
/** Arbitrary JSON object stored with the transaction. Must be an object. */
|
|
35
|
+
metadata?: Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
export interface TransportConfig {
|
|
38
|
+
/** Explicit tenant API key. Omit inside a workflow step — the engine injects it ambiently. */
|
|
39
|
+
apiKey?: string;
|
|
40
|
+
/** Inject a fetch (tests / non-standard runtimes). Defaults to global fetch. */
|
|
41
|
+
fetch?: typeof globalThis.fetch;
|
|
42
|
+
/** Default attribution applied to every request this transport makes (see class doc). */
|
|
43
|
+
attribution?: Attribution;
|
|
44
|
+
}
|
|
45
|
+
export declare class Transport {
|
|
46
|
+
private readonly apiKey;
|
|
47
|
+
private readonly fetchImpl;
|
|
48
|
+
private readonly attribution;
|
|
49
|
+
constructor(config?: TransportConfig);
|
|
50
|
+
/**
|
|
51
|
+
* A new transport sharing this one's credential and fetch, with `attribution`
|
|
52
|
+
* merged over the current defaults. The escape hatch for the cases where one
|
|
53
|
+
* process attributes to many agents/traces (a router) — not something
|
|
54
|
+
* step-authoring code reaches for.
|
|
55
|
+
*/
|
|
56
|
+
withAttribution(attribution: Attribution): Transport;
|
|
57
|
+
/**
|
|
58
|
+
* Authenticated raw fetch — capabilities that need streaming or custom
|
|
59
|
+
* response handling (filesystem, log streams) use this and inspect the
|
|
60
|
+
* `Response` themselves. Injects the tenant credential + attribution headers;
|
|
61
|
+
* sets no content-type.
|
|
62
|
+
*/
|
|
63
|
+
fetch(url: string, init?: RequestInit): Promise<Response>;
|
|
64
|
+
/** Authenticated JSON request — parses the body and throws on a non-2xx status. */
|
|
65
|
+
request<T>(url: string, init?: RequestInit): Promise<T>;
|
|
66
|
+
}
|
|
67
|
+
export declare function defaultTransport(): Transport;
|
|
68
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/_client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,uFAAuF;IACvF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,eAAe;IAC9B,8FAA8F;IAC9F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gFAAgF;IAChF,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,yFAAyF;IACzF,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AA4BD,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;IACpD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;gBAE9B,MAAM,GAAE,eAAoB;IAMxC;;;;;OAKG;IACH,eAAe,CAAC,WAAW,EAAE,WAAW,GAAG,SAAS;IAQpD;;;;;OAKG;IACG,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAiBnE,mFAAmF;IAC7E,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,CAAC,CAAC;CAUlE;AAID,wBAAgB,gBAAgB,IAAI,SAAS,CAE5C"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth + transport core for `@sapiom/tools` — the private "runtime half" every
|
|
3
|
+
* capability namespace wraps. Capability modules call THIS; they never import each
|
|
4
|
+
* other's runtime, so the cross-capability mesh (`repo.pushFromSandbox(sandbox)`)
|
|
5
|
+
* has no package/module cycles. See docs/plans/capability-authoring-sdk.md.
|
|
6
|
+
*
|
|
7
|
+
* The credential resolves from one of two sources, same surface either way:
|
|
8
|
+
* - explicit: createClient({ apiKey }) — standalone / open-source use
|
|
9
|
+
* - ambient: SAPIOM_API_KEY (env), which the workflow engine injects per
|
|
10
|
+
* execution so step authors write zero auth plumbing.
|
|
11
|
+
*
|
|
12
|
+
* Attribution (which agent / trace a call belongs to) is execution context the
|
|
13
|
+
* runtime owns, NOT a parameter of any operation — so it lives here on the
|
|
14
|
+
* transport, set once and injected on every request, never threaded through
|
|
15
|
+
* capability methods. The engine sets it per execution by constructing the
|
|
16
|
+
* per-execution client; `withAttribution(...)` is a quiet escape hatch for the
|
|
17
|
+
* router / standalone cases. Capability method signatures deliberately have no
|
|
18
|
+
* attribution argument: that absence keeps LLM-authored step code from setting
|
|
19
|
+
* (and getting wrong) context it doesn't own.
|
|
20
|
+
*/
|
|
21
|
+
function attributionToHeaders(a) {
|
|
22
|
+
const h = {};
|
|
23
|
+
if (a.agentName)
|
|
24
|
+
h["x-sapiom-agent-name"] = a.agentName;
|
|
25
|
+
if (a.agentId)
|
|
26
|
+
h["x-sapiom-agent-id"] = a.agentId;
|
|
27
|
+
if (a.traceId)
|
|
28
|
+
h["x-sapiom-trace-id"] = a.traceId;
|
|
29
|
+
if (a.traceExternalId)
|
|
30
|
+
h["x-sapiom-trace-external-id"] = a.traceExternalId;
|
|
31
|
+
if (a.metadata)
|
|
32
|
+
h["x-sapiom-metadata"] = JSON.stringify(a.metadata);
|
|
33
|
+
return h;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Standalone-only ambient attribution. Read once for the process-global default
|
|
37
|
+
* transport. NOT the engine's injection channel — `process.env` is process-wide,
|
|
38
|
+
* so it would bleed across step executions that share a worker. The engine sets
|
|
39
|
+
* attribution by constructing the per-execution client instead. Safe only for the
|
|
40
|
+
* one-execution-per-process case (CLI, scripts).
|
|
41
|
+
*/
|
|
42
|
+
function attributionFromEnv() {
|
|
43
|
+
const a = {};
|
|
44
|
+
if (process.env.SAPIOM_AGENT_ID)
|
|
45
|
+
a.agentId = process.env.SAPIOM_AGENT_ID;
|
|
46
|
+
if (process.env.SAPIOM_AGENT_NAME)
|
|
47
|
+
a.agentName = process.env.SAPIOM_AGENT_NAME;
|
|
48
|
+
if (process.env.SAPIOM_TRACE_ID)
|
|
49
|
+
a.traceId = process.env.SAPIOM_TRACE_ID;
|
|
50
|
+
if (process.env.SAPIOM_TRACE_EXTERNAL_ID)
|
|
51
|
+
a.traceExternalId = process.env.SAPIOM_TRACE_EXTERNAL_ID;
|
|
52
|
+
return a;
|
|
53
|
+
}
|
|
54
|
+
export class Transport {
|
|
55
|
+
constructor(config = {}) {
|
|
56
|
+
this.apiKey = config.apiKey ?? process.env.SAPIOM_API_KEY ?? undefined;
|
|
57
|
+
this.fetchImpl = config.fetch ?? globalThis.fetch;
|
|
58
|
+
this.attribution = config.attribution ?? {};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* A new transport sharing this one's credential and fetch, with `attribution`
|
|
62
|
+
* merged over the current defaults. The escape hatch for the cases where one
|
|
63
|
+
* process attributes to many agents/traces (a router) — not something
|
|
64
|
+
* step-authoring code reaches for.
|
|
65
|
+
*/
|
|
66
|
+
withAttribution(attribution) {
|
|
67
|
+
return new Transport({
|
|
68
|
+
apiKey: this.apiKey,
|
|
69
|
+
fetch: this.fetchImpl,
|
|
70
|
+
attribution: { ...this.attribution, ...attribution },
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Authenticated raw fetch — capabilities that need streaming or custom
|
|
75
|
+
* response handling (filesystem, log streams) use this and inspect the
|
|
76
|
+
* `Response` themselves. Injects the tenant credential + attribution headers;
|
|
77
|
+
* sets no content-type.
|
|
78
|
+
*/
|
|
79
|
+
async fetch(url, init = {}) {
|
|
80
|
+
if (!this.apiKey) {
|
|
81
|
+
throw new Error("@sapiom/tools: no tenant credential. Pass createClient({ apiKey }) for standalone use, " +
|
|
82
|
+
"or run inside a Sapiom workflow (the engine injects SAPIOM_API_KEY).");
|
|
83
|
+
}
|
|
84
|
+
return this.fetchImpl(url, {
|
|
85
|
+
...init,
|
|
86
|
+
headers: {
|
|
87
|
+
"x-sapiom-api-key": this.apiKey,
|
|
88
|
+
...attributionToHeaders(this.attribution),
|
|
89
|
+
...(init.headers ?? {}),
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
/** Authenticated JSON request — parses the body and throws on a non-2xx status. */
|
|
94
|
+
async request(url, init = {}) {
|
|
95
|
+
const res = await this.fetch(url, {
|
|
96
|
+
...init,
|
|
97
|
+
headers: { "content-type": "application/json", ...(init.headers ?? {}) },
|
|
98
|
+
});
|
|
99
|
+
if (!res.ok) {
|
|
100
|
+
throw new Error(`${init.method ?? "GET"} ${url} → ${res.status} ${await res.text()}`);
|
|
101
|
+
}
|
|
102
|
+
return (await res.json());
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/** The ambient default transport used by barrel-imported capabilities when no client is supplied. */
|
|
106
|
+
let _default;
|
|
107
|
+
export function defaultTransport() {
|
|
108
|
+
return (_default ?? (_default = new Transport({ attribution: attributionFromEnv() })));
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/_client/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `agent` capability — LLM execution (coding agents). The fuzzy counterpart to a
|
|
3
|
+
* deterministic step: hand it a task in natural language, it edits a checkout in a
|
|
4
|
+
* sandbox.
|
|
5
|
+
*
|
|
6
|
+
* import { agent, repositories } from "@sapiom/tools";
|
|
7
|
+
* const repo = await repositories.create("landing");
|
|
8
|
+
* const run = await agent.coding.run({
|
|
9
|
+
* task: "Build a one-page landing site in index.html.",
|
|
10
|
+
* gitRepository: repo, // auto-cloned into the sandbox at /workspace/<slug>
|
|
11
|
+
* });
|
|
12
|
+
* await repo.pushFromSandbox(run.sandbox, { message: "build: landing" });
|
|
13
|
+
*
|
|
14
|
+
* `run` awaits completion; `launch` returns a handle to poll yourself. Both return
|
|
15
|
+
* a live `Sandbox` handle so a later step can read files, exec, or push from it.
|
|
16
|
+
* The cross-capability inputs (`gitRepository: Repository`, `sandbox: Sandbox`) are
|
|
17
|
+
* passed as instances and resolved here to their wire ids.
|
|
18
|
+
*
|
|
19
|
+
* The wire contract is the gateway's JSON:API-shaped envelope (`data.attributes` /
|
|
20
|
+
* `data.relationships.execution_environment`). Attributes are snake_case on the
|
|
21
|
+
* wire; this module maps them to the camelCase SDK surface below.
|
|
22
|
+
*/
|
|
23
|
+
import { Transport } from "../_client/index.js";
|
|
24
|
+
import { Sandbox } from "../sandboxes/index.js";
|
|
25
|
+
import type { Repository } from "../repositories/index.js";
|
|
26
|
+
/** Run lifecycle, mirrored from the gateway's `AgentsRunStatus`. */
|
|
27
|
+
export type RunStatus = "pending" | "queued" | "running" | "completed" | "failed";
|
|
28
|
+
export interface CodingRunSpec {
|
|
29
|
+
/** Natural-language instruction for the coding agent. */
|
|
30
|
+
task: string;
|
|
31
|
+
/** Repo to clone into the sandbox at `/workspace/<slug>` and operate on. */
|
|
32
|
+
gitRepository?: Repository;
|
|
33
|
+
/** Reuse an existing sandbox instead of provisioning a fresh one. */
|
|
34
|
+
sandbox?: Sandbox;
|
|
35
|
+
/** Subdirectory (under the runner root) the agent SDK runs in. */
|
|
36
|
+
workingDirectory?: string;
|
|
37
|
+
/** Keep the sandbox alive after the run finishes. SDK default: true (the mesh needs it). */
|
|
38
|
+
keepSandbox?: boolean;
|
|
39
|
+
/** Override the model the agent runs on. */
|
|
40
|
+
model?: string;
|
|
41
|
+
}
|
|
42
|
+
export interface CodingRunUsage {
|
|
43
|
+
inputTokens: number;
|
|
44
|
+
outputTokens: number;
|
|
45
|
+
cacheReadTokens: number;
|
|
46
|
+
cacheCreateTokens: number;
|
|
47
|
+
thinkingTokens: number;
|
|
48
|
+
}
|
|
49
|
+
export interface CodingRunOutcome {
|
|
50
|
+
success: boolean;
|
|
51
|
+
turns: number;
|
|
52
|
+
modelUsed: string | null;
|
|
53
|
+
durationMs: number;
|
|
54
|
+
toolCallCount: number;
|
|
55
|
+
usage: CodingRunUsage;
|
|
56
|
+
}
|
|
57
|
+
export interface CodingRunError {
|
|
58
|
+
/** `launch` (failed before the agent ran) vs `run` (failed mid-execution). */
|
|
59
|
+
stage: string;
|
|
60
|
+
message: string;
|
|
61
|
+
}
|
|
62
|
+
export interface CodingRunResult {
|
|
63
|
+
runId: string;
|
|
64
|
+
status: RunStatus;
|
|
65
|
+
summary: string | null;
|
|
66
|
+
result: CodingRunOutcome | null;
|
|
67
|
+
error: CodingRunError | null;
|
|
68
|
+
/** Live handle to the sandbox the run executed in. */
|
|
69
|
+
sandbox: Sandbox;
|
|
70
|
+
}
|
|
71
|
+
/** A launched-but-not-awaited run. */
|
|
72
|
+
export interface RunHandle {
|
|
73
|
+
runId: string;
|
|
74
|
+
sandbox: Sandbox;
|
|
75
|
+
/** Fetch the current status without blocking. */
|
|
76
|
+
status(): Promise<RunStatus>;
|
|
77
|
+
/** Poll to a terminal state and resolve the full result. */
|
|
78
|
+
wait(opts?: {
|
|
79
|
+
timeoutMs?: number;
|
|
80
|
+
pollMs?: number;
|
|
81
|
+
}): Promise<CodingRunResult>;
|
|
82
|
+
}
|
|
83
|
+
export declare function launch(spec: CodingRunSpec, transport?: Transport, baseUrl?: string): Promise<RunHandle>;
|
|
84
|
+
export declare function run(spec: CodingRunSpec, transport?: Transport, baseUrl?: string): Promise<CodingRunResult>;
|
|
85
|
+
/** Ambient-bound `agent.coding` namespace. */
|
|
86
|
+
export declare const coding: {
|
|
87
|
+
run: typeof run;
|
|
88
|
+
launch: typeof launch;
|
|
89
|
+
};
|
|
90
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agent/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,SAAS,EAAoB,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAI3D,oEAAoE;AACpE,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;AAGlF,MAAM,WAAW,aAAa;IAC5B,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,aAAa,CAAC,EAAE,UAAU,CAAC;IAC3B,qEAAqE;IACrE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,4FAA4F;IAC5F,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,cAAc,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAChC,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;IAC7B,sDAAsD;IACtD,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,sCAAsC;AACtC,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,iDAAiD;IACjD,MAAM,IAAI,OAAO,CAAC,SAAS,CAAC,CAAC;IAC7B,4DAA4D;IAC5D,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CAChF;AA6DD,wBAAsB,MAAM,CAC1B,IAAI,EAAE,aAAa,EACnB,SAAS,GAAE,SAA8B,EACzC,OAAO,SAAmB,GACzB,OAAO,CAAC,SAAS,CAAC,CA0CpB;AAED,wBAAsB,GAAG,CACvB,IAAI,EAAE,aAAa,EACnB,SAAS,GAAE,SAA8B,EACzC,OAAO,SAAmB,GACzB,OAAO,CAAC,eAAe,CAAC,CAG1B;AAED,8CAA8C;AAC9C,eAAO,MAAM,MAAM;;;CAAkB,CAAC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `agent` capability — LLM execution (coding agents). The fuzzy counterpart to a
|
|
3
|
+
* deterministic step: hand it a task in natural language, it edits a checkout in a
|
|
4
|
+
* sandbox.
|
|
5
|
+
*
|
|
6
|
+
* import { agent, repositories } from "@sapiom/tools";
|
|
7
|
+
* const repo = await repositories.create("landing");
|
|
8
|
+
* const run = await agent.coding.run({
|
|
9
|
+
* task: "Build a one-page landing site in index.html.",
|
|
10
|
+
* gitRepository: repo, // auto-cloned into the sandbox at /workspace/<slug>
|
|
11
|
+
* });
|
|
12
|
+
* await repo.pushFromSandbox(run.sandbox, { message: "build: landing" });
|
|
13
|
+
*
|
|
14
|
+
* `run` awaits completion; `launch` returns a handle to poll yourself. Both return
|
|
15
|
+
* a live `Sandbox` handle so a later step can read files, exec, or push from it.
|
|
16
|
+
* The cross-capability inputs (`gitRepository: Repository`, `sandbox: Sandbox`) are
|
|
17
|
+
* passed as instances and resolved here to their wire ids.
|
|
18
|
+
*
|
|
19
|
+
* The wire contract is the gateway's JSON:API-shaped envelope (`data.attributes` /
|
|
20
|
+
* `data.relationships.execution_environment`). Attributes are snake_case on the
|
|
21
|
+
* wire; this module maps them to the camelCase SDK surface below.
|
|
22
|
+
*/
|
|
23
|
+
import { defaultTransport } from "../_client/index.js";
|
|
24
|
+
import { Sandbox } from "../sandboxes/index.js";
|
|
25
|
+
const DEFAULT_BASE_URL = process.env.SAPIOM_AGENTS_URL || "https://agents.services.sapiom.ai";
|
|
26
|
+
const TERMINAL = new Set(["completed", "failed"]);
|
|
27
|
+
function mapResult(r) {
|
|
28
|
+
if (!r)
|
|
29
|
+
return null;
|
|
30
|
+
return {
|
|
31
|
+
success: r.success,
|
|
32
|
+
turns: r.turns,
|
|
33
|
+
modelUsed: r.model_used ?? null,
|
|
34
|
+
durationMs: r.duration_ms,
|
|
35
|
+
toolCallCount: r.tool_call_count,
|
|
36
|
+
usage: {
|
|
37
|
+
inputTokens: r.usage?.input_tokens ?? 0,
|
|
38
|
+
outputTokens: r.usage?.output_tokens ?? 0,
|
|
39
|
+
cacheReadTokens: r.usage?.cache_read_tokens ?? 0,
|
|
40
|
+
cacheCreateTokens: r.usage?.cache_create_tokens ?? 0,
|
|
41
|
+
thinkingTokens: r.usage?.thinking_tokens ?? 0,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function buildBody(spec) {
|
|
46
|
+
return {
|
|
47
|
+
task: spec.task,
|
|
48
|
+
git_repository: spec.gitRepository?.slug,
|
|
49
|
+
execution_environment_id: spec.sandbox?.name,
|
|
50
|
+
working_directory: spec.workingDirectory,
|
|
51
|
+
keep_sandbox: spec.keepSandbox ?? true,
|
|
52
|
+
model: spec.model,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export async function launch(spec, transport = defaultTransport(), baseUrl = DEFAULT_BASE_URL) {
|
|
56
|
+
// 202 + a launch document; the execution_environment relationship is always present.
|
|
57
|
+
const doc = await transport.request(`${baseUrl}/v1/coding/runs`, {
|
|
58
|
+
method: "POST",
|
|
59
|
+
body: JSON.stringify(buildBody(spec)),
|
|
60
|
+
});
|
|
61
|
+
const runId = doc.data.id;
|
|
62
|
+
const envId = doc.data.relationships?.execution_environment?.data?.id;
|
|
63
|
+
// Reuse the caller's sandbox handle when they supplied one; otherwise adopt the
|
|
64
|
+
// environment the run provisioned (its id is the sandbox name) so later steps
|
|
65
|
+
// can act on it.
|
|
66
|
+
const sandbox = spec.sandbox ?? Sandbox.attach(envId ?? runId, {}, transport);
|
|
67
|
+
const fetchDoc = () => transport.request(`${baseUrl}/v1/coding/runs/${encodeURIComponent(runId)}`);
|
|
68
|
+
const toResult = (d) => ({
|
|
69
|
+
runId,
|
|
70
|
+
status: d.data.attributes.status,
|
|
71
|
+
summary: d.data.attributes.summary ?? null,
|
|
72
|
+
result: mapResult(d.data.attributes.result),
|
|
73
|
+
error: d.data.attributes.error ?? null,
|
|
74
|
+
sandbox,
|
|
75
|
+
});
|
|
76
|
+
return {
|
|
77
|
+
runId,
|
|
78
|
+
sandbox,
|
|
79
|
+
async status() {
|
|
80
|
+
return (await fetchDoc()).data.attributes.status;
|
|
81
|
+
},
|
|
82
|
+
async wait({ timeoutMs = 20 * 60000, pollMs = 3000 } = {}) {
|
|
83
|
+
const deadline = Date.now() + timeoutMs;
|
|
84
|
+
// eslint-disable-next-line no-constant-condition
|
|
85
|
+
while (true) {
|
|
86
|
+
const d = await fetchDoc();
|
|
87
|
+
if (TERMINAL.has(d.data.attributes.status))
|
|
88
|
+
return toResult(d);
|
|
89
|
+
if (Date.now() > deadline) {
|
|
90
|
+
throw new Error(`coding run ${runId} timed out after ${timeoutMs}ms (last status: ${d.data.attributes.status})`);
|
|
91
|
+
}
|
|
92
|
+
await new Promise((r) => setTimeout(r, pollMs));
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
export async function run(spec, transport = defaultTransport(), baseUrl = DEFAULT_BASE_URL) {
|
|
98
|
+
const handle = await launch(spec, transport, baseUrl);
|
|
99
|
+
return handle.wait();
|
|
100
|
+
}
|
|
101
|
+
/** Ambient-bound `agent.coding` namespace. */
|
|
102
|
+
export const coding = { run, launch };
|
|
103
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/agent/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `createClient` — builds a `Sapiom` client whose capability namespaces are bound
|
|
3
|
+
* to an explicit credential. This is the standalone / open-source entry point:
|
|
4
|
+
*
|
|
5
|
+
* import { createClient } from "@sapiom/tools";
|
|
6
|
+
* const sapiom = createClient({ apiKey: process.env.SAPIOM_API_KEY });
|
|
7
|
+
* const box = await sapiom.sandboxes.create({ name: "demo" });
|
|
8
|
+
*
|
|
9
|
+
* Inside a workflow step the engine hands you an already-auth'd `sapiom` of this
|
|
10
|
+
* same shape; you can also barrel-import the ambient-bound namespaces directly
|
|
11
|
+
* (`import { sandboxes } from "@sapiom/tools"`).
|
|
12
|
+
*
|
|
13
|
+
* Attribution is set once (the engine constructs the per-execution client with
|
|
14
|
+
* it; standalone callers pass it to `createClient`), never per capability call.
|
|
15
|
+
* `withAttribution(...)` derives a client for the router case — see `_client`.
|
|
16
|
+
*/
|
|
17
|
+
import { type TransportConfig, type Attribution } from "./_client/index.js";
|
|
18
|
+
import { Sandbox } from "./sandboxes/index.js";
|
|
19
|
+
import type { SandboxCreateOptions } from "./sandboxes/index.js";
|
|
20
|
+
import { Repository } from "./repositories/index.js";
|
|
21
|
+
import type { CodingRunSpec, CodingRunResult, RunHandle } from "./agent/index.js";
|
|
22
|
+
export interface Sapiom {
|
|
23
|
+
readonly sandboxes: {
|
|
24
|
+
create(opts: SandboxCreateOptions): Promise<Sandbox>;
|
|
25
|
+
attach(name: string, opts?: {
|
|
26
|
+
workspaceRoot?: string;
|
|
27
|
+
baseUrl?: string;
|
|
28
|
+
}): Sandbox;
|
|
29
|
+
};
|
|
30
|
+
readonly repositories: {
|
|
31
|
+
create(slug: string): Promise<Repository>;
|
|
32
|
+
get(slug: string): Promise<Repository>;
|
|
33
|
+
list(): Promise<Repository[]>;
|
|
34
|
+
delete(slug: string): Promise<void>;
|
|
35
|
+
attach(slug: string, cloneUrl: string): Repository;
|
|
36
|
+
};
|
|
37
|
+
readonly agent: {
|
|
38
|
+
coding: {
|
|
39
|
+
run(spec: CodingRunSpec): Promise<CodingRunResult>;
|
|
40
|
+
launch(spec: CodingRunSpec): Promise<RunHandle>;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Derive a client that attributes its calls to a different agent/trace. For the
|
|
45
|
+
* router case (one process acting for many agents); step-authoring code doesn't
|
|
46
|
+
* need this — attribution is set once when the client is constructed.
|
|
47
|
+
*/
|
|
48
|
+
withAttribution(attribution: Attribution): Sapiom;
|
|
49
|
+
}
|
|
50
|
+
export declare function createClient(config?: TransportConfig): Sapiom;
|
|
51
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAa,KAAK,eAAe,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACvF,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElF,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,SAAS,EAAE;QAClB,MAAM,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QACrD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;YAAE,aAAa,CAAC,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC;KACpF,CAAC;IACF,QAAQ,CAAC,YAAY,EAAE;QACrB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;QAC1C,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;QACvC,IAAI,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QAC9B,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAC;KACpD,CAAC;IACF,QAAQ,CAAC,KAAK,EAAE;QACd,MAAM,EAAE;YACN,GAAG,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;YACnD,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;SACjD,CAAC;KACH,CAAC;IACF;;;;OAIG;IACH,eAAe,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,CAAC;CAEnD;AA0BD,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,CAE7D"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `createClient` — builds a `Sapiom` client whose capability namespaces are bound
|
|
3
|
+
* to an explicit credential. This is the standalone / open-source entry point:
|
|
4
|
+
*
|
|
5
|
+
* import { createClient } from "@sapiom/tools";
|
|
6
|
+
* const sapiom = createClient({ apiKey: process.env.SAPIOM_API_KEY });
|
|
7
|
+
* const box = await sapiom.sandboxes.create({ name: "demo" });
|
|
8
|
+
*
|
|
9
|
+
* Inside a workflow step the engine hands you an already-auth'd `sapiom` of this
|
|
10
|
+
* same shape; you can also barrel-import the ambient-bound namespaces directly
|
|
11
|
+
* (`import { sandboxes } from "@sapiom/tools"`).
|
|
12
|
+
*
|
|
13
|
+
* Attribution is set once (the engine constructs the per-execution client with
|
|
14
|
+
* it; standalone callers pass it to `createClient`), never per capability call.
|
|
15
|
+
* `withAttribution(...)` derives a client for the router case — see `_client`.
|
|
16
|
+
*/
|
|
17
|
+
import { Transport } from "./_client/index.js";
|
|
18
|
+
import { Sandbox } from "./sandboxes/index.js";
|
|
19
|
+
import { Repository } from "./repositories/index.js";
|
|
20
|
+
import { run as codingRun, launch as codingLaunch } from "./agent/index.js";
|
|
21
|
+
/** Bind every capability namespace to a transport. `withAttribution` rebinds to a derived one. */
|
|
22
|
+
function bind(transport) {
|
|
23
|
+
return {
|
|
24
|
+
sandboxes: {
|
|
25
|
+
create: (opts) => Sandbox.create(opts, transport),
|
|
26
|
+
attach: (name, opts) => Sandbox.attach(name, opts, transport),
|
|
27
|
+
},
|
|
28
|
+
repositories: {
|
|
29
|
+
create: (slug) => Repository.create(slug, transport),
|
|
30
|
+
get: (slug) => Repository.get(slug, transport),
|
|
31
|
+
list: () => Repository.list(transport),
|
|
32
|
+
delete: (slug) => Repository.delete(slug, transport),
|
|
33
|
+
attach: (slug, cloneUrl) => Repository.attach(slug, cloneUrl, transport),
|
|
34
|
+
},
|
|
35
|
+
agent: {
|
|
36
|
+
coding: {
|
|
37
|
+
run: (spec) => codingRun(spec, transport),
|
|
38
|
+
launch: (spec) => codingLaunch(spec, transport),
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
withAttribution: (attribution) => bind(transport.withAttribution(attribution)),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export function createClient(config) {
|
|
45
|
+
return bind(new Transport(config));
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,SAAS,EAA0C,MAAM,oBAAoB,CAAC;AACvF,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE/C,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,GAAG,IAAI,SAAS,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,kBAAkB,CAAC;AA8B5E,kGAAkG;AAClG,SAAS,IAAI,CAAC,SAAoB;IAChC,OAAO;QACL,SAAS,EAAE;YACT,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC;YACjD,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC;SAC9D;QACD,YAAY,EAAE;YACZ,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC;YACpD,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC;YAC9C,IAAI,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC;YACtC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC;YACpD,MAAM,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,CAAC;SACzE;QACD,KAAK,EAAE;YACL,MAAM,EAAE;gBACN,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC;gBACzC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,SAAS,CAAC;aAChD;SACF;QACD,eAAe,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;KAC/E,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAwB;IACnD,OAAO,IAAI,CAAC,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;AACrC,CAAC"}
|