@sapiom/tools 0.15.0 → 0.17.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/CHANGELOG.md +32 -0
- package/README.md +23 -1
- package/dist/cjs/_client/analytics.d.ts +66 -0
- package/dist/cjs/_client/analytics.d.ts.map +1 -0
- package/dist/cjs/_client/analytics.js +283 -0
- package/dist/cjs/_client/analytics.js.map +1 -0
- package/dist/cjs/_client/index.d.ts +28 -20
- package/dist/cjs/_client/index.d.ts.map +1 -1
- package/dist/cjs/_client/index.js +76 -13
- package/dist/cjs/_client/index.js.map +1 -1
- package/dist/cjs/_generated/version.d.ts +7 -0
- package/dist/cjs/_generated/version.d.ts.map +1 -0
- package/dist/cjs/_generated/version.js +10 -0
- package/dist/cjs/_generated/version.js.map +1 -0
- package/dist/{esm/orchestrations → cjs/agents}/index.d.ts +15 -15
- package/dist/cjs/agents/index.d.ts.map +1 -0
- package/dist/cjs/{orchestrations → agents}/index.js +21 -24
- package/dist/cjs/agents/index.js.map +1 -0
- package/dist/cjs/client.d.ts +24 -11
- package/dist/cjs/client.d.ts.map +1 -1
- package/dist/cjs/client.js +5 -4
- package/dist/cjs/client.js.map +1 -1
- package/dist/cjs/index.d.ts +11 -11
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +21 -21
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/{agent → models}/index.d.ts +26 -26
- package/dist/cjs/models/index.d.ts.map +1 -0
- package/dist/cjs/{agent → models}/index.js +24 -23
- package/dist/cjs/models/index.js.map +1 -0
- package/dist/cjs/stub/index.d.ts.map +1 -1
- package/dist/cjs/stub/index.js +26 -23
- package/dist/cjs/stub/index.js.map +1 -1
- package/dist/esm/_client/analytics.d.ts +66 -0
- package/dist/esm/_client/analytics.d.ts.map +1 -0
- package/dist/esm/_client/analytics.js +242 -0
- package/dist/esm/_client/analytics.js.map +1 -0
- package/dist/esm/_client/index.d.ts +28 -20
- package/dist/esm/_client/index.d.ts.map +1 -1
- package/dist/esm/_client/index.js +72 -9
- package/dist/esm/_client/index.js.map +1 -1
- package/dist/esm/_generated/version.d.ts +7 -0
- package/dist/esm/_generated/version.d.ts.map +1 -0
- package/dist/esm/_generated/version.js +7 -0
- package/dist/esm/_generated/version.js.map +1 -0
- package/dist/{cjs/orchestrations → esm/agents}/index.d.ts +15 -15
- package/dist/esm/agents/index.d.ts.map +1 -0
- package/dist/esm/{orchestrations → agents}/index.js +19 -22
- package/dist/esm/agents/index.js.map +1 -0
- package/dist/esm/client.d.ts +24 -11
- package/dist/esm/client.d.ts.map +1 -1
- package/dist/esm/client.js +9 -8
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/index.d.ts +11 -11
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +14 -14
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/{agent → models}/index.d.ts +26 -26
- package/dist/esm/models/index.d.ts.map +1 -0
- package/dist/esm/{agent → models}/index.js +22 -21
- package/dist/esm/models/index.js.map +1 -0
- package/dist/esm/stub/index.d.ts.map +1 -1
- package/dist/esm/stub/index.js +26 -23
- package/dist/esm/stub/index.js.map +1 -1
- package/dist/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +15 -11
- package/src/{orchestrations → agents}/README.md +13 -13
- package/dist/cjs/agent/index.d.ts.map +0 -1
- package/dist/cjs/agent/index.js.map +0 -1
- package/dist/cjs/orchestrations/index.d.ts.map +0 -1
- package/dist/cjs/orchestrations/index.js.map +0 -1
- package/dist/esm/agent/index.d.ts.map +0 -1
- package/dist/esm/agent/index.js.map +0 -1
- package/dist/esm/orchestrations/index.d.ts.map +0 -1
- package/dist/esm/orchestrations/index.js.map +0 -1
- /package/src/{agent → models}/README.md +0 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Usage analytics for `@sapiom/tools` — the Transport (this package's single
|
|
3
|
+
* HTTP choke point) enqueues ONE `capability.call` event per capability HTTP
|
|
4
|
+
* call through `@sapiom/analytics-core`.
|
|
5
|
+
*
|
|
6
|
+
* Non-negotiables, guaranteed regardless of configuration:
|
|
7
|
+
* - Live by default: the emitter delivers to the hosted Sapiom collector unless
|
|
8
|
+
* opted out. Opt out with `SAPIOM_TELEMETRY_DISABLED=1`, `DO_NOT_TRACK=1`,
|
|
9
|
+
* or `disabled: true` in the config — any of these makes the emitter a
|
|
10
|
+
* complete no-op (zero network calls, zero disk writes, no notice).
|
|
11
|
+
* `SAPIOM_ANALYTICS_ENDPOINT` overrides the destination (useful in tests).
|
|
12
|
+
* - Enqueue-only on the call path: `track()` is synchronous, delivery is
|
|
13
|
+
* batched off the call path, and no failure here can surface to a caller.
|
|
14
|
+
*/
|
|
15
|
+
import * as fs from "node:fs";
|
|
16
|
+
import * as path from "node:path";
|
|
17
|
+
import { fileURLToPath } from "node:url";
|
|
18
|
+
import { createAnalytics, } from "@sapiom/analytics-core";
|
|
19
|
+
import { VERSION } from "../_generated/version.js";
|
|
20
|
+
/** The one event this package emits: one per capability HTTP call. Dot-form is canonical. */
|
|
21
|
+
export const CAPABILITY_CALL_EVENT = "capability.call";
|
|
22
|
+
/** Get (creating on first use) the holder's emitter. Never throws — `createAnalytics` can't. */
|
|
23
|
+
export function analyticsFor(holder, apiKey) {
|
|
24
|
+
return (holder.instance ?? (holder.instance = createAnalytics({
|
|
25
|
+
source: "tools",
|
|
26
|
+
sdkName: "@sapiom/tools",
|
|
27
|
+
sdkVersion: resolveSdkVersion(),
|
|
28
|
+
// Sent as `x-sapiom-api-key` on collector batches so the server can
|
|
29
|
+
// enrich events with the tenant — never placed in event payloads.
|
|
30
|
+
apiKey,
|
|
31
|
+
})));
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Build the `capability.call` event `data`. All requests are Sapiom-bound, so
|
|
35
|
+
* request metadata (method, sizes, attribution) is captured; per-field size
|
|
36
|
+
* caps are enforced downstream by the emitter (~16 KB). The recorded `url` is
|
|
37
|
+
* the request URL PATH only — query strings and fragments are stripped, so a
|
|
38
|
+
* caller putting a secret in a query parameter can never leak it into an
|
|
39
|
+
* event. Request/response BODIES are never captured — only the request body size.
|
|
40
|
+
*/
|
|
41
|
+
export function capabilityCallData(info) {
|
|
42
|
+
const data = {
|
|
43
|
+
capability: capabilityFromUrl(info.url),
|
|
44
|
+
method: (info.method ?? "GET").toUpperCase(),
|
|
45
|
+
url: urlWithoutQuery(info.url),
|
|
46
|
+
ok: info.ok,
|
|
47
|
+
duration_ms: info.durationMs,
|
|
48
|
+
};
|
|
49
|
+
if (info.status !== undefined)
|
|
50
|
+
data.status = info.status;
|
|
51
|
+
const requestBytes = bodySize(info.requestBody);
|
|
52
|
+
if (requestBytes !== undefined)
|
|
53
|
+
data.request_bytes = requestBytes;
|
|
54
|
+
if (info.error !== undefined) {
|
|
55
|
+
data.error = errorLabel(info.error);
|
|
56
|
+
const message = errorMessage(info.error);
|
|
57
|
+
if (message !== undefined)
|
|
58
|
+
data.error_message = message;
|
|
59
|
+
}
|
|
60
|
+
const a = info.attribution;
|
|
61
|
+
if (a.agentId)
|
|
62
|
+
data.agent_id = a.agentId;
|
|
63
|
+
if (a.agentName)
|
|
64
|
+
data.agent_name = a.agentName;
|
|
65
|
+
if (a.traceId)
|
|
66
|
+
data.trace_id = a.traceId;
|
|
67
|
+
if (a.traceExternalId)
|
|
68
|
+
data.trace_external_id = a.traceExternalId;
|
|
69
|
+
if (a.metadata)
|
|
70
|
+
data.attribution_metadata = a.metadata;
|
|
71
|
+
return data;
|
|
72
|
+
}
|
|
73
|
+
/** Matches the routed-capability seam's path shape: `/v1/capabilities/<id>`. */
|
|
74
|
+
const ROUTED_CAPABILITY_PATH = /^\/v1\/capabilities\/([^/]+)\/?$/;
|
|
75
|
+
/**
|
|
76
|
+
* Derive the capability name from the request URL:
|
|
77
|
+
* - a routed call (`POST <core>/v1/capabilities/<id>`) → the capability id
|
|
78
|
+
* (`web.scrape`, `email.verify`, …);
|
|
79
|
+
* - anything else (service-gateway capabilities) → the URL path, which is the
|
|
80
|
+
* stable per-operation identifier on those hosts (`/v1/sandboxes`, …);
|
|
81
|
+
* - an unparseable URL → the raw string (capped downstream).
|
|
82
|
+
*/
|
|
83
|
+
export function capabilityFromUrl(url) {
|
|
84
|
+
try {
|
|
85
|
+
const parsed = new URL(url);
|
|
86
|
+
const routed = ROUTED_CAPABILITY_PATH.exec(parsed.pathname);
|
|
87
|
+
if (routed)
|
|
88
|
+
return safeDecode(routed[1]);
|
|
89
|
+
return parsed.pathname || url;
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return url;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function safeDecode(segment) {
|
|
96
|
+
try {
|
|
97
|
+
return decodeURIComponent(segment);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return segment;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* The request URL with query string and fragment stripped (origin + pathname),
|
|
105
|
+
* consistent with {@link capabilityFromUrl}. Query parameters are deliberately
|
|
106
|
+
* never recorded: today's capabilities carry no secrets there, but a future or
|
|
107
|
+
* direct `transport.fetch(urlWithSecretQuery)` must not silently exfiltrate one.
|
|
108
|
+
*/
|
|
109
|
+
export function urlWithoutQuery(url) {
|
|
110
|
+
try {
|
|
111
|
+
const parsed = new URL(url);
|
|
112
|
+
return `${parsed.origin}${parsed.pathname}`;
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
// Unparseable — strip conservatively at the first `?` or `#`.
|
|
116
|
+
return url.split(/[?#]/)[0] ?? url;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/** Size in bytes of a request body when cheaply knowable (string / Blob / buffer views). */
|
|
120
|
+
function bodySize(body) {
|
|
121
|
+
try {
|
|
122
|
+
if (typeof body === "string")
|
|
123
|
+
return Buffer.byteLength(body);
|
|
124
|
+
if (body !== null && typeof body === "object") {
|
|
125
|
+
const { size, byteLength } = body;
|
|
126
|
+
if (typeof size === "number")
|
|
127
|
+
return size;
|
|
128
|
+
if (typeof byteLength === "number")
|
|
129
|
+
return byteLength;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
// Analytics never throws; an unknown body simply has no recorded size.
|
|
134
|
+
}
|
|
135
|
+
return undefined;
|
|
136
|
+
}
|
|
137
|
+
function errorLabel(error) {
|
|
138
|
+
if (error instanceof Error)
|
|
139
|
+
return error.name || "Error";
|
|
140
|
+
return typeof error;
|
|
141
|
+
}
|
|
142
|
+
function errorMessage(error) {
|
|
143
|
+
return error instanceof Error ? error.message : undefined;
|
|
144
|
+
}
|
|
145
|
+
// ---------------------------------------------------------------------------
|
|
146
|
+
// SDK version
|
|
147
|
+
// ---------------------------------------------------------------------------
|
|
148
|
+
let cachedSdkVersion = null;
|
|
149
|
+
/**
|
|
150
|
+
* This package's own version. Primary source is the build-time constant
|
|
151
|
+
* generated from package.json (`src/_generated/version.ts`, regenerated by
|
|
152
|
+
* `gen:version` on every build/test/typecheck) — a constant survives bundlers,
|
|
153
|
+
* which inline it where no package.json exists on disk near the bundled
|
|
154
|
+
* module. The runtime package.json walk-up remains only as a fallback for the
|
|
155
|
+
* (should-be-impossible) case of an empty constant, and degrades to
|
|
156
|
+
* `"unknown"` rather than ever throwing.
|
|
157
|
+
*/
|
|
158
|
+
export function resolveSdkVersion() {
|
|
159
|
+
return (cachedSdkVersion ?? (cachedSdkVersion = typeof VERSION === "string" && VERSION.length > 0
|
|
160
|
+
? VERSION
|
|
161
|
+
: readOwnPackageVersion()));
|
|
162
|
+
}
|
|
163
|
+
function readOwnPackageVersion() {
|
|
164
|
+
try {
|
|
165
|
+
let dir = resolveModuleDir();
|
|
166
|
+
for (let hops = 0; dir !== ""; hops++) {
|
|
167
|
+
if (hops >= 8)
|
|
168
|
+
break;
|
|
169
|
+
const version = versionIfOwnPackage(path.join(dir, "package.json"));
|
|
170
|
+
if (version !== undefined)
|
|
171
|
+
return version;
|
|
172
|
+
const parent = path.dirname(dir);
|
|
173
|
+
if (parent === dir)
|
|
174
|
+
break;
|
|
175
|
+
dir = parent;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
// Version resolution must never break a capability call.
|
|
180
|
+
}
|
|
181
|
+
return "unknown";
|
|
182
|
+
}
|
|
183
|
+
/** The `version` of the manifest at `manifestPath` iff it is this package's own. */
|
|
184
|
+
function versionIfOwnPackage(manifestPath) {
|
|
185
|
+
try {
|
|
186
|
+
const raw = fs.readFileSync(manifestPath, "utf8");
|
|
187
|
+
const manifest = JSON.parse(raw);
|
|
188
|
+
if (manifest.name === "@sapiom/tools" &&
|
|
189
|
+
typeof manifest.version === "string") {
|
|
190
|
+
return manifest.version;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
// Missing or unparseable manifest at this level — keep walking up.
|
|
195
|
+
}
|
|
196
|
+
return undefined;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Directory of this compiled module, resolved for BOTH build formats:
|
|
200
|
+
* - CommonJS build (and ts-jest) → `__dirname` (a real global);
|
|
201
|
+
* - ESM build → recovered from a stack trace, where V8 reports this module
|
|
202
|
+
* as a `file://` URL.
|
|
203
|
+
*
|
|
204
|
+
* The stack route is used because a literal `import.meta` is a hard compile
|
|
205
|
+
* error (TS1343) in this single source file's CommonJS compilation, and
|
|
206
|
+
* `eval("import.meta.url")` throws at runtime — eval'd code is parsed as a
|
|
207
|
+
* script, where `import.meta` is invalid. A stack frame is the one anchor
|
|
208
|
+
* available to both formats; any failure degrades to `"unknown"`, never throws.
|
|
209
|
+
*/
|
|
210
|
+
function resolveModuleDir() {
|
|
211
|
+
if (typeof __dirname !== "undefined")
|
|
212
|
+
return __dirname;
|
|
213
|
+
try {
|
|
214
|
+
const file = ownFileFromStack();
|
|
215
|
+
if (file !== undefined) {
|
|
216
|
+
return path.dirname(file.startsWith("file:") ? fileURLToPath(file) : file);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
// No usable anchor — version resolution degrades to "unknown".
|
|
221
|
+
}
|
|
222
|
+
return "";
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* This module's own file (path or `file://` URL), read from the top-most
|
|
226
|
+
* user frame of a fresh stack — which is this function itself, i.e. this file.
|
|
227
|
+
*/
|
|
228
|
+
function ownFileFromStack() {
|
|
229
|
+
const stack = new Error().stack;
|
|
230
|
+
if (typeof stack !== "string")
|
|
231
|
+
return undefined;
|
|
232
|
+
for (const line of stack.split("\n").slice(1)) {
|
|
233
|
+
// V8 frames: " at fn (file:///p/analytics.js:1:2)" / " at /p/analytics.js:1:2"
|
|
234
|
+
const match = /(?:\(|at )((?:file:\/\/)?[^\s()]+):\d+:\d+\)?\s*$/.exec(line);
|
|
235
|
+
const file = match?.[1];
|
|
236
|
+
if (!file || file.startsWith("node:") || file === "<anonymous>")
|
|
237
|
+
continue;
|
|
238
|
+
return file;
|
|
239
|
+
}
|
|
240
|
+
return undefined;
|
|
241
|
+
}
|
|
242
|
+
//# sourceMappingURL=analytics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../../src/_client/analytics.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,23 +1,3 @@
|
|
|
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
1
|
/**
|
|
22
2
|
* Per-request attribution recorded with the gateway transaction. Every field is
|
|
23
3
|
* optional and maps 1:1 to an `x-sapiom-*` header the collapsed flow understands.
|
|
@@ -85,6 +65,12 @@ export declare class Transport {
|
|
|
85
65
|
* which injects `SAPIOM_CAPABILITY_RESUME_TOKEN` — keeps working unchanged.
|
|
86
66
|
*/
|
|
87
67
|
readonly resumeToken: string | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* Lazily-created usage-analytics emitter (see `./analytics.ts`). Not readonly:
|
|
70
|
+
* `withAttribution` re-points the derived transport at ITS holder so one client
|
|
71
|
+
* keeps one emitter no matter how many attributed views are derived from it.
|
|
72
|
+
*/
|
|
73
|
+
private analyticsHolder;
|
|
88
74
|
constructor(config?: TransportConfig);
|
|
89
75
|
/**
|
|
90
76
|
* A new transport sharing this one's credential, fetch, and resume token, with
|
|
@@ -93,6 +79,20 @@ export declare class Transport {
|
|
|
93
79
|
* step-authoring code reaches for.
|
|
94
80
|
*/
|
|
95
81
|
withAttribution(attribution: Attribution): Transport;
|
|
82
|
+
/**
|
|
83
|
+
* Flush and shut down this client's usage-analytics emitter: buffered events
|
|
84
|
+
* are delivered best-effort and the emitter's `beforeExit` hook is detached.
|
|
85
|
+
* Resolves immediately when no emitter was ever created (no calls made, or
|
|
86
|
+
* analytics disabled); idempotent; never rejects. One call covers every
|
|
87
|
+
* transport derived via {@link withAttribution} (they share the emitter).
|
|
88
|
+
*
|
|
89
|
+
* Call this once per client in hosts that construct MANY clients in one
|
|
90
|
+
* process — e.g. an engine worker building a per-execution client — so exit
|
|
91
|
+
* hooks don't accumulate across executions. One-shot processes don't need
|
|
92
|
+
* it: the emitter flushes on process exit by itself. Capability calls made
|
|
93
|
+
* after shutdown still work; they just no longer emit analytics.
|
|
94
|
+
*/
|
|
95
|
+
shutdown(): Promise<void>;
|
|
96
96
|
/**
|
|
97
97
|
* Authenticated raw fetch — capabilities that need streaming or custom
|
|
98
98
|
* response handling (filesystem, log streams) use this and inspect the
|
|
@@ -104,6 +104,14 @@ export declare class Transport {
|
|
|
104
104
|
* instead (the value is identical — the Transport owns the key either way).
|
|
105
105
|
*/
|
|
106
106
|
fetch(url: string, init?: RequestInit, options?: TransportRequestOptions): Promise<Response>;
|
|
107
|
+
/**
|
|
108
|
+
* Enqueue ONE `capability.call` usage event for a finished (or failed) HTTP
|
|
109
|
+
* call. Synchronous — nothing on the call path is awaited — and never throws;
|
|
110
|
+
* a silent no-op unless a collector endpoint is configured (see `./analytics.ts`).
|
|
111
|
+
* `request()` funnels through `fetch()`, so every capability call is counted
|
|
112
|
+
* exactly once.
|
|
113
|
+
*/
|
|
114
|
+
private trackCapabilityCall;
|
|
107
115
|
/** Authenticated JSON request — parses the body and throws on a non-2xx status. */
|
|
108
116
|
request<T>(url: string, init?: RequestInit, options?: TransportRequestOptions): Promise<T>;
|
|
109
117
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/_client/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/_client/index.ts"],"names":[],"mappings":"AA+BA;;;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;IAC1B;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG,kBAAkB,GAAG,WAAW,CAAC;AAI1D,0FAA0F;AAC1F,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAYD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,IAAI,WAAW,CAShD;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;IACpD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C;;;;OAIG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC;;;;OAIG;IACH,OAAO,CAAC,eAAe,CAAuB;gBAElC,MAAM,GAAE,eAAoB;IAUxC;;;;;OAKG;IACH,eAAe,CAAC,WAAW,EAAE,WAAW,GAAG,SAAS;IAWpD;;;;;;;;;;;;OAYG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/B;;;;;;;;;OASG;IACG,KAAK,CACT,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,WAAgB,EACtB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,QAAQ,CAAC;IA0BpB;;;;;;OAMG;IACH,OAAO,CAAC,mBAAmB;IA0B3B,mFAAmF;IAC7E,OAAO,CAAC,CAAC,EACb,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,WAAgB,EACtB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,CAAC,CAAC;CAmBd;AAID,wBAAgB,gBAAgB,IAAI,SAAS,CAE5C;AAED,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,KAAK,qBAAqB,GAC3B,MAAM,sBAAsB,CAAC"}
|
|
@@ -17,7 +17,12 @@
|
|
|
17
17
|
* router / standalone cases. Capability method signatures deliberately have no
|
|
18
18
|
* attribution argument: that absence keeps LLM-authored step code from setting
|
|
19
19
|
* (and getting wrong) context it doesn't own.
|
|
20
|
+
*
|
|
21
|
+
* Being the single HTTP choke point also makes this the (one) instrumentation
|
|
22
|
+
* seam: every call enqueues a `capability.call` usage event — synchronously,
|
|
23
|
+
* never awaited, live by default. See `./analytics.ts`.
|
|
20
24
|
*/
|
|
25
|
+
import { CAPABILITY_CALL_EVENT, analyticsFor, capabilityCallData, } from "./analytics.js";
|
|
21
26
|
const DEFAULT_AUTH_HEADER = "x-sapiom-api-key";
|
|
22
27
|
function attributionToHeaders(a) {
|
|
23
28
|
const h = {};
|
|
@@ -54,6 +59,12 @@ export function attributionFromEnv() {
|
|
|
54
59
|
}
|
|
55
60
|
export class Transport {
|
|
56
61
|
constructor(config = {}) {
|
|
62
|
+
/**
|
|
63
|
+
* Lazily-created usage-analytics emitter (see `./analytics.ts`). Not readonly:
|
|
64
|
+
* `withAttribution` re-points the derived transport at ITS holder so one client
|
|
65
|
+
* keeps one emitter no matter how many attributed views are derived from it.
|
|
66
|
+
*/
|
|
67
|
+
this.analyticsHolder = {};
|
|
57
68
|
this.apiKey = config.apiKey ?? process.env.SAPIOM_API_KEY ?? undefined;
|
|
58
69
|
this.fetchImpl = config.fetch ?? globalThis.fetch;
|
|
59
70
|
this.attribution = config.attribution ?? {};
|
|
@@ -69,12 +80,30 @@ export class Transport {
|
|
|
69
80
|
* step-authoring code reaches for.
|
|
70
81
|
*/
|
|
71
82
|
withAttribution(attribution) {
|
|
72
|
-
|
|
83
|
+
const derived = new Transport({
|
|
73
84
|
apiKey: this.apiKey,
|
|
74
85
|
fetch: this.fetchImpl,
|
|
75
86
|
attribution: { ...this.attribution, ...attribution },
|
|
76
87
|
resumeToken: this.resumeToken,
|
|
77
88
|
});
|
|
89
|
+
derived.analyticsHolder = this.analyticsHolder;
|
|
90
|
+
return derived;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Flush and shut down this client's usage-analytics emitter: buffered events
|
|
94
|
+
* are delivered best-effort and the emitter's `beforeExit` hook is detached.
|
|
95
|
+
* Resolves immediately when no emitter was ever created (no calls made, or
|
|
96
|
+
* analytics disabled); idempotent; never rejects. One call covers every
|
|
97
|
+
* transport derived via {@link withAttribution} (they share the emitter).
|
|
98
|
+
*
|
|
99
|
+
* Call this once per client in hosts that construct MANY clients in one
|
|
100
|
+
* process — e.g. an engine worker building a per-execution client — so exit
|
|
101
|
+
* hooks don't accumulate across executions. One-shot processes don't need
|
|
102
|
+
* it: the emitter flushes on process exit by itself. Capability calls made
|
|
103
|
+
* after shutdown still work; they just no longer emit analytics.
|
|
104
|
+
*/
|
|
105
|
+
async shutdown() {
|
|
106
|
+
await this.analyticsHolder.instance?.shutdown();
|
|
78
107
|
}
|
|
79
108
|
/**
|
|
80
109
|
* Authenticated raw fetch — capabilities that need streaming or custom
|
|
@@ -91,14 +120,48 @@ export class Transport {
|
|
|
91
120
|
throw new Error("@sapiom/tools: no tenant credential. Pass createClient({ apiKey }) for standalone use, " +
|
|
92
121
|
"or run inside a Sapiom workflow (the engine injects SAPIOM_API_KEY).");
|
|
93
122
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
...
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
123
|
+
const startedAt = Date.now();
|
|
124
|
+
let response;
|
|
125
|
+
try {
|
|
126
|
+
response = await this.fetchImpl(url, {
|
|
127
|
+
...init,
|
|
128
|
+
headers: {
|
|
129
|
+
[options.authHeader ?? DEFAULT_AUTH_HEADER]: this.apiKey,
|
|
130
|
+
...attributionToHeaders(this.attribution),
|
|
131
|
+
...(init.headers ?? {}),
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
this.trackCapabilityCall(url, init, startedAt, undefined, error);
|
|
137
|
+
throw error;
|
|
138
|
+
}
|
|
139
|
+
this.trackCapabilityCall(url, init, startedAt, response);
|
|
140
|
+
return response;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Enqueue ONE `capability.call` usage event for a finished (or failed) HTTP
|
|
144
|
+
* call. Synchronous — nothing on the call path is awaited — and never throws;
|
|
145
|
+
* a silent no-op unless a collector endpoint is configured (see `./analytics.ts`).
|
|
146
|
+
* `request()` funnels through `fetch()`, so every capability call is counted
|
|
147
|
+
* exactly once.
|
|
148
|
+
*/
|
|
149
|
+
trackCapabilityCall(url, init, startedAt, response, error) {
|
|
150
|
+
try {
|
|
151
|
+
analyticsFor(this.analyticsHolder, this.apiKey).track(CAPABILITY_CALL_EVENT, capabilityCallData({
|
|
152
|
+
url,
|
|
153
|
+
method: init.method,
|
|
154
|
+
requestBody: init.body,
|
|
155
|
+
durationMs: Date.now() - startedAt,
|
|
156
|
+
status: response?.status,
|
|
157
|
+
ok: response?.ok ?? false,
|
|
158
|
+
error,
|
|
159
|
+
attribution: this.attribution,
|
|
160
|
+
}));
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
// Usage analytics must never affect a capability call.
|
|
164
|
+
}
|
|
102
165
|
}
|
|
103
166
|
/** Authenticated JSON request — parses the body and throws on a non-2xx status. */
|
|
104
167
|
async request(url, init = {}, options = {}) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/_client/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/_client/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED FILE — do not edit, not committed. Regenerated from package.json
|
|
3
|
+
* by `scripts/generate-version.mjs` (wired into the build/test/typecheck
|
|
4
|
+
* scripts as `gen:version`).
|
|
5
|
+
*/
|
|
6
|
+
export declare const VERSION = "0.17.0";
|
|
7
|
+
//# sourceMappingURL=version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../src/_generated/version.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,OAAO,WAAW,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/_generated/version.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAC"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* // dispatch another orchestration and pause this step on its result:
|
|
7
7
|
* const child = await orchestrations.launch({ definition: "enrich-lead", input });
|
|
8
8
|
* return pauseUntilSignal(child, { resumeStep: "use-result" });
|
|
9
|
-
* // the resumed step receives an
|
|
9
|
+
* // the resumed step receives an AgentRunResultPayload
|
|
10
10
|
*
|
|
11
11
|
* `launch` returns a handle to pass straight to `pauseUntilSignal` (the waiting
|
|
12
12
|
* step resumes when the run finishes) or to `wait()` inline for standalone use.
|
|
@@ -22,10 +22,10 @@ import type { DispatchHandle } from "../dispatch.js";
|
|
|
22
22
|
* orchestration handle resumes on this; it is the value carried in the handle's
|
|
23
23
|
* `dispatch.resultSignal`.
|
|
24
24
|
*/
|
|
25
|
-
export declare const
|
|
25
|
+
export declare const AGENTS_RESULT_SIGNAL = "agents.result";
|
|
26
26
|
/** Run lifecycle status. */
|
|
27
27
|
export type ExecutionStatus = "running" | "paused" | "completed" | "failed" | "cancelled";
|
|
28
|
-
export interface
|
|
28
|
+
export interface AgentRunSpec {
|
|
29
29
|
/** Slug of the deployed orchestration to run (its stable handle). */
|
|
30
30
|
definition: string;
|
|
31
31
|
/** Input passed to the orchestration's entry step. */
|
|
@@ -43,7 +43,7 @@ export interface OrchestrationRunSpec {
|
|
|
43
43
|
at?: string | Date;
|
|
44
44
|
}
|
|
45
45
|
/** A live, awaited run (the standalone `run()`/`wait()` result). */
|
|
46
|
-
export interface
|
|
46
|
+
export interface AgentRunResult {
|
|
47
47
|
executionId: string;
|
|
48
48
|
status: ExecutionStatus;
|
|
49
49
|
output: unknown;
|
|
@@ -56,12 +56,12 @@ export interface OrchestrationRunResult {
|
|
|
56
56
|
*
|
|
57
57
|
* const useResult = defineStep({
|
|
58
58
|
* name: "use-result",
|
|
59
|
-
* async run(result:
|
|
59
|
+
* async run(result: AgentRunResultPayload, ctx) {
|
|
60
60
|
* if (result.status === "failed") { … }
|
|
61
61
|
* },
|
|
62
62
|
* });
|
|
63
63
|
*/
|
|
64
|
-
export type
|
|
64
|
+
export type AgentRunResultPayload<TOutput = unknown> = {
|
|
65
65
|
status: "completed";
|
|
66
66
|
executionId: string;
|
|
67
67
|
definition: string;
|
|
@@ -78,17 +78,17 @@ export type OrchestrationRunResultPayload<TOutput = unknown> = {
|
|
|
78
78
|
startedAt: string;
|
|
79
79
|
finishedAt: string;
|
|
80
80
|
};
|
|
81
|
-
/** Thrown by {@link
|
|
82
|
-
export declare class
|
|
81
|
+
/** Thrown by {@link agentResultSchema}.parse on a malformed resume payload. */
|
|
82
|
+
export declare class AgentResultSchemaError extends Error {
|
|
83
83
|
}
|
|
84
84
|
/**
|
|
85
|
-
* Runtime validator for {@link
|
|
86
|
-
* value typed on success and throws an {@link
|
|
85
|
+
* Runtime validator for {@link AgentRunResultPayload}. `parse` returns the
|
|
86
|
+
* value typed on success and throws an {@link AgentResultSchemaError} on any
|
|
87
87
|
* divergence. Generic in the caller's expected `output` type — the shape of
|
|
88
88
|
* `output` itself is the child orchestration's contract, not validated here.
|
|
89
89
|
*/
|
|
90
|
-
export declare const
|
|
91
|
-
parse<TOutput = unknown>(value: unknown):
|
|
90
|
+
export declare const agentResultSchema: {
|
|
91
|
+
parse<TOutput = unknown>(value: unknown): AgentRunResultPayload<TOutput>;
|
|
92
92
|
};
|
|
93
93
|
/**
|
|
94
94
|
* A launched-but-not-awaited child run. Satisfies {@link DispatchHandle}, so it can
|
|
@@ -103,8 +103,8 @@ export interface RunHandle extends DispatchHandle {
|
|
|
103
103
|
wait(opts?: {
|
|
104
104
|
timeoutMs?: number;
|
|
105
105
|
pollMs?: number;
|
|
106
|
-
}): Promise<
|
|
106
|
+
}): Promise<AgentRunResult>;
|
|
107
107
|
}
|
|
108
|
-
export declare function launch(spec:
|
|
109
|
-
export declare function run(spec:
|
|
108
|
+
export declare function launch(spec: AgentRunSpec, transport?: Transport, baseUrl?: string): Promise<RunHandle>;
|
|
109
|
+
export declare function run(spec: AgentRunSpec, transport?: Transport, baseUrl?: string): Promise<AgentRunResult>;
|
|
110
110
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agents/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,SAAS,EAAoB,MAAM,qBAAqB,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAOrD;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,kBAAkB,CAAC;AAEpD,4BAA4B;AAC5B,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,QAAQ,GACR,WAAW,GACX,QAAQ,GACR,WAAW,CAAC;AAGhB,MAAM,WAAW,YAAY;IAC3B,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,sFAAsF;IACtF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;OAOG;IACH,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAED,oEAAoE;AACpE,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,qBAAqB,CAAC,OAAO,GAAG,OAAO,IAC/C;IACE,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB,GACD;IACE,MAAM,EAAE,QAAQ,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEN,+EAA+E;AAC/E,qBAAa,sBAAuB,SAAQ,KAAK;CAAG;AAEpD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB;UACtB,OAAO,mBACJ,OAAO,GACb,qBAAqB,CAAC,OAAO,CAAC;CAuBlC,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,SAAU,SAAQ,cAAc;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,MAAM,IAAI,OAAO,CAAC,eAAe,CAAC,CAAC;IACnC,2DAA2D;IAC3D,IAAI,CAAC,IAAI,CAAC,EAAE;QACV,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CAC7B;AAuDD,wBAAsB,MAAM,CAC1B,IAAI,EAAE,YAAY,EAClB,SAAS,GAAE,SAA8B,EACzC,OAAO,SAAmB,GACzB,OAAO,CAAC,SAAS,CAAC,CAuDpB;AAED,wBAAsB,GAAG,CACvB,IAAI,EAAE,YAAY,EAClB,SAAS,GAAE,SAA8B,EACzC,OAAO,SAAmB,GACzB,OAAO,CAAC,cAAc,CAAC,CAGzB"}
|