@coalex-ai/sdk 2.7.0-beta.700 → 2.9.0-beta.705
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 +31 -1
- package/dist/content-capture.d.ts +56 -0
- package/dist/content-capture.d.ts.map +1 -0
- package/dist/content-capture.js +122 -0
- package/dist/content-capture.js.map +1 -0
- package/dist/evaluate.d.ts.map +1 -1
- package/dist/evaluate.js +8 -1
- package/dist/evaluate.js.map +1 -1
- package/dist/ext/context-bridge.d.ts +19 -2
- package/dist/ext/context-bridge.d.ts.map +1 -1
- package/dist/ext/context-bridge.js +58 -11
- package/dist/ext/context-bridge.js.map +1 -1
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +134 -9
- package/dist/index.js.map +1 -1
- package/dist/ungoverned.d.ts.map +1 -1
- package/dist/ungoverned.js +70 -2
- package/dist/ungoverned.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +8 -3
package/README.md
CHANGED
|
@@ -49,9 +49,24 @@ register({
|
|
|
49
49
|
serviceName: "my-agent",
|
|
50
50
|
filterNonAiSpans: false, // filter out non-AI spans
|
|
51
51
|
suppressExportErrors: true, // suppress OTLP export errors (default)
|
|
52
|
+
captureContent: true, // false: export spans without prompts and responses
|
|
52
53
|
});
|
|
53
54
|
```
|
|
54
55
|
|
|
56
|
+
`captureContent: false` exports each span's structure and none of its content: the prompts and
|
|
57
|
+
responses (`llm.input_messages.*` and `llm.output_messages.*` apart from roles and tool names),
|
|
58
|
+
`input.value` and `output.value`, the `gen_ai.*` messages, tool arguments, retrieved documents,
|
|
59
|
+
reranked documents and embedded text are removed from every span and span event as the last step
|
|
60
|
+
before the span is exported. Model, token counts, timing, status and the `coalex.*` attributes are
|
|
61
|
+
kept, so cost and latency still reach the dashboard. A span that cannot be stripped is not exported.
|
|
62
|
+
The Python SDK's `capture_content=False` removes the same keys. Other exporters on the same
|
|
63
|
+
provider still receive the content, and `promptRefs` has no effect with it off.
|
|
64
|
+
|
|
65
|
+
`register()` installs the SDK's tracer provider and exporter. It throws, naming the options, rather than
|
|
66
|
+
ignoring them when they cannot take effect: a second `register()` with different options (call it once, or
|
|
67
|
+
again with the same options, which does nothing), and an application whose own tracer provider is already
|
|
68
|
+
installed (call `register()` before that setup, or pass a `tracerProvider` to `autoInstrument()`).
|
|
69
|
+
|
|
55
70
|
To have the agent appear in the Console without anyone registering it by hand, pass `declare`. The
|
|
56
71
|
declaration is best-effort: a failure is logged and the agent still starts and traces. Without
|
|
57
72
|
`declare`, `register()` makes no network call.
|
|
@@ -78,6 +93,20 @@ the default service name is never used as an id. `declare()` sends a declaration
|
|
|
78
93
|
`register()`. An agent that declares no `displayName`, `description` or `suggestedPrompts` is shown by its name
|
|
79
94
|
alone. Whether a tool is governed and who may approve it are set in the dashboard, not here.
|
|
80
95
|
|
|
96
|
+
### `forceFlush()` and `shutdown()`
|
|
97
|
+
|
|
98
|
+
Spans are batched for five seconds before they are sent. A script, a job or a serverless handler that
|
|
99
|
+
finishes sooner must send them itself:
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
await forceFlush(); // send what has ended, keep exporting
|
|
103
|
+
await shutdown(); // send it and stop; register() can install a fresh provider afterwards
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The SDK also flushes when the process runs out of work (`beforeExit`), which covers a script that simply
|
|
107
|
+
ends. It cannot cover `process.exit()` or a serverless runtime that freezes the process once the handler
|
|
108
|
+
returns: await one of these before them.
|
|
109
|
+
|
|
81
110
|
### `autoInstrumentAsync(options?)`
|
|
82
111
|
|
|
83
112
|
Instrument AI libraries using dynamic `import()`. Use this in ESM projects.
|
|
@@ -89,7 +118,8 @@ const results = await autoInstrumentAsync();
|
|
|
89
118
|
|
|
90
119
|
### `autoInstrument(options?)`
|
|
91
120
|
|
|
92
|
-
Synchronous variant using `require()`. Use this in CommonJS projects.
|
|
121
|
+
Synchronous variant using `require()`. Use this in CommonJS projects. The package itself loads with
|
|
122
|
+
`require("@coalex-ai/sdk")` on Node 20.19 or 22.12 and later.
|
|
93
123
|
|
|
94
124
|
```typescript
|
|
95
125
|
const results = autoInstrument();
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Export a span's structure without its content: `register({ captureContent: false })`.
|
|
3
|
+
*
|
|
4
|
+
* An instrumented LLM call puts the prompt and the answer on its span. OpenInference writes them
|
|
5
|
+
* twice, as the flattened messages and as the raw request and response (`input.value` /
|
|
6
|
+
* `output.value`); OpenLLMetry and the OTel GenAI conventions use their own keys; and this SDK's
|
|
7
|
+
* extension spans record tool arguments, retrieved documents and embedded text. With capture off,
|
|
8
|
+
* every one of those keys is removed from the span's attributes and from its events' attributes
|
|
9
|
+
* before the span is exported.
|
|
10
|
+
*
|
|
11
|
+
* What survives is what describes the call rather than repeats it: span kind, model, provider,
|
|
12
|
+
* token counts, finish reason, timing, status, the `coalex.*` attributes, message roles and tool
|
|
13
|
+
* names. That is enough for cost, latency and volume, and for an LLM span to pass
|
|
14
|
+
* `filterNonAiSpans`.
|
|
15
|
+
*
|
|
16
|
+
* The rule is by key, so it holds whatever the value is. A new instrumentation that puts content
|
|
17
|
+
* under a key this module does not name exports it: the families below are the ones the supported
|
|
18
|
+
* instrumentors and conventions use. The Python SDK's `coalex/content_capture.py` holds the same
|
|
19
|
+
* lists, and `test_sdk_parity.py` holds the two equal.
|
|
20
|
+
*/
|
|
21
|
+
import type { Attributes } from "@opentelemetry/api";
|
|
22
|
+
import type { ReadableSpan, SpanExporter } from "@opentelemetry/sdk-trace-base";
|
|
23
|
+
interface ExportResult {
|
|
24
|
+
code: number;
|
|
25
|
+
error?: Error;
|
|
26
|
+
}
|
|
27
|
+
/** A key that is content whole. */
|
|
28
|
+
export declare const CONTENT_KEYS: ReadonlySet<string>;
|
|
29
|
+
/** A family whose every member is content (`llm.prompts.0.prompt.text`, `gen_ai.prompt.0.content`). */
|
|
30
|
+
export declare const CONTENT_PREFIXES: readonly string[];
|
|
31
|
+
/**
|
|
32
|
+
* The flattened messages keep only the fields that name a message's shape; everything else under
|
|
33
|
+
* them (content, multimodal parts, tool-call arguments, reasoning) is content. A keep list, because
|
|
34
|
+
* the instrumentors add content fields under these prefixes faster than a remove list would follow.
|
|
35
|
+
*/
|
|
36
|
+
export declare const MESSAGE_PREFIXES: readonly string[];
|
|
37
|
+
export declare const MESSAGE_SHAPE_SUFFIXES: readonly string[];
|
|
38
|
+
/** Whether `key` holds a prompt, a response, or another piece of what the call carried. */
|
|
39
|
+
export declare function isContentAttribute(key: string): boolean;
|
|
40
|
+
/** The attributes without their content keys. */
|
|
41
|
+
export declare function stripContent(attributes: Attributes): Attributes;
|
|
42
|
+
/**
|
|
43
|
+
* A view of `span` without its content, or `span` itself when it carries none. The span as
|
|
44
|
+
* instrumented is left alone, so another exporter on the same provider still receives it whole.
|
|
45
|
+
*/
|
|
46
|
+
export declare function stripSpan(span: ReadableSpan): ReadableSpan;
|
|
47
|
+
/** Removes every content attribute from a span and its events, then delegates. */
|
|
48
|
+
export declare class ContentStrippingExporter implements SpanExporter {
|
|
49
|
+
private readonly wrappedExporter;
|
|
50
|
+
constructor(wrappedExporter: SpanExporter);
|
|
51
|
+
export(spans: ReadableSpan[], resultCallback: (result: ExportResult) => void): void;
|
|
52
|
+
shutdown(): Promise<void>;
|
|
53
|
+
forceFlush(): Promise<void>;
|
|
54
|
+
}
|
|
55
|
+
export {};
|
|
56
|
+
//# sourceMappingURL=content-capture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-capture.d.ts","sourceRoot":"","sources":["../src/content-capture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAGhF,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAGD,mCAAmC;AACnC,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,MAAM,CAwB3C,CAAC;AAEH,uGAAuG;AACvG,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAQ7C,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAAoD,CAAC;AACnG,eAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,EAOnD,CAAC;AAEF,2FAA2F;AAC3F,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAMvD;AAED,iDAAiD;AACjD,wBAAgB,YAAY,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,CAM/D;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,YAAY,GAAG,YAAY,CAgB1D;AAED,kFAAkF;AAClF,qBAAa,wBAAyB,YAAW,YAAY;IAC/C,OAAO,CAAC,QAAQ,CAAC,eAAe;gBAAf,eAAe,EAAE,YAAY;IAE1D,MAAM,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE,cAAc,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,GAAG,IAAI;IAmBnF,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAIzB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAG5B"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { log } from "./logger.js";
|
|
2
|
+
const ExportResultCode = { SUCCESS: 0 };
|
|
3
|
+
/** A key that is content whole. */
|
|
4
|
+
export const CONTENT_KEYS = new Set([
|
|
5
|
+
// OpenInference: the raw request and response, and the derived message lists.
|
|
6
|
+
"input.value",
|
|
7
|
+
"output.value",
|
|
8
|
+
"input.images",
|
|
9
|
+
"output.images",
|
|
10
|
+
"llm.prompts",
|
|
11
|
+
"llm.prompt_template.template",
|
|
12
|
+
"llm.prompt_template.variables",
|
|
13
|
+
"retrieval.documents",
|
|
14
|
+
"reranker.query",
|
|
15
|
+
"reranker.input_documents",
|
|
16
|
+
"reranker.output_documents",
|
|
17
|
+
"embedding.embeddings",
|
|
18
|
+
"embedding.text",
|
|
19
|
+
"tool.parameters",
|
|
20
|
+
// OTel GenAI conventions.
|
|
21
|
+
"gen_ai.input.messages",
|
|
22
|
+
"gen_ai.output.messages",
|
|
23
|
+
"gen_ai.system_instructions",
|
|
24
|
+
"gen_ai.prompt",
|
|
25
|
+
"gen_ai.completion",
|
|
26
|
+
"gen_ai.tool.call.arguments",
|
|
27
|
+
"gen_ai.tool.call.result",
|
|
28
|
+
]);
|
|
29
|
+
/** A family whose every member is content (`llm.prompts.0.prompt.text`, `gen_ai.prompt.0.content`). */
|
|
30
|
+
export const CONTENT_PREFIXES = [
|
|
31
|
+
"llm.prompts.",
|
|
32
|
+
"retrieval.documents.",
|
|
33
|
+
"reranker.input_documents.",
|
|
34
|
+
"reranker.output_documents.",
|
|
35
|
+
"embedding.embeddings.",
|
|
36
|
+
"gen_ai.prompt.",
|
|
37
|
+
"gen_ai.completion.",
|
|
38
|
+
];
|
|
39
|
+
/**
|
|
40
|
+
* The flattened messages keep only the fields that name a message's shape; everything else under
|
|
41
|
+
* them (content, multimodal parts, tool-call arguments, reasoning) is content. A keep list, because
|
|
42
|
+
* the instrumentors add content fields under these prefixes faster than a remove list would follow.
|
|
43
|
+
*/
|
|
44
|
+
export const MESSAGE_PREFIXES = ["llm.input_messages.", "llm.output_messages."];
|
|
45
|
+
export const MESSAGE_SHAPE_SUFFIXES = [
|
|
46
|
+
".message.role",
|
|
47
|
+
".message.name",
|
|
48
|
+
".message.tool_call_id",
|
|
49
|
+
".tool_call.id",
|
|
50
|
+
".tool_call.function.name",
|
|
51
|
+
".message_content.type",
|
|
52
|
+
];
|
|
53
|
+
/** Whether `key` holds a prompt, a response, or another piece of what the call carried. */
|
|
54
|
+
export function isContentAttribute(key) {
|
|
55
|
+
if (CONTENT_KEYS.has(key) || CONTENT_PREFIXES.some((prefix) => key.startsWith(prefix)))
|
|
56
|
+
return true;
|
|
57
|
+
if (MESSAGE_PREFIXES.some((prefix) => key.startsWith(prefix))) {
|
|
58
|
+
return !MESSAGE_SHAPE_SUFFIXES.some((suffix) => key.endsWith(suffix));
|
|
59
|
+
}
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
/** The attributes without their content keys. */
|
|
63
|
+
export function stripContent(attributes) {
|
|
64
|
+
const kept = {};
|
|
65
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
66
|
+
if (!isContentAttribute(key))
|
|
67
|
+
kept[key] = value;
|
|
68
|
+
}
|
|
69
|
+
return kept;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* A view of `span` without its content, or `span` itself when it carries none. The span as
|
|
73
|
+
* instrumented is left alone, so another exporter on the same provider still receives it whole.
|
|
74
|
+
*/
|
|
75
|
+
export function stripSpan(span) {
|
|
76
|
+
const attributes = span.attributes ?? {};
|
|
77
|
+
const events = span.events ?? [];
|
|
78
|
+
const stripAttributes = Object.keys(attributes).some(isContentAttribute);
|
|
79
|
+
const stripEvents = events.some((event) => Object.keys(event.attributes ?? {}).some(isContentAttribute));
|
|
80
|
+
if (!stripAttributes && !stripEvents)
|
|
81
|
+
return span;
|
|
82
|
+
const view = Object.create(span);
|
|
83
|
+
if (stripAttributes) {
|
|
84
|
+
Object.defineProperty(view, "attributes", { value: stripContent(attributes), enumerable: true });
|
|
85
|
+
}
|
|
86
|
+
if (stripEvents) {
|
|
87
|
+
const stripped = events.map((event) => ({ ...event, attributes: stripContent(event.attributes ?? {}) }));
|
|
88
|
+
Object.defineProperty(view, "events", { value: stripped, enumerable: true });
|
|
89
|
+
}
|
|
90
|
+
return view;
|
|
91
|
+
}
|
|
92
|
+
/** Removes every content attribute from a span and its events, then delegates. */
|
|
93
|
+
export class ContentStrippingExporter {
|
|
94
|
+
wrappedExporter;
|
|
95
|
+
constructor(wrappedExporter) {
|
|
96
|
+
this.wrappedExporter = wrappedExporter;
|
|
97
|
+
}
|
|
98
|
+
export(spans, resultCallback) {
|
|
99
|
+
const kept = [];
|
|
100
|
+
for (const span of spans) {
|
|
101
|
+
try {
|
|
102
|
+
kept.push(stripSpan(span));
|
|
103
|
+
}
|
|
104
|
+
catch (e) {
|
|
105
|
+
// A span that cannot be stripped is dropped, never sent whole.
|
|
106
|
+
log.warn(`Content stripping failed for a span, which is not exported: ${e instanceof Error ? e.name : typeof e}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (kept.length === 0) {
|
|
110
|
+
resultCallback({ code: ExportResultCode.SUCCESS });
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
this.wrappedExporter.export(kept, resultCallback);
|
|
114
|
+
}
|
|
115
|
+
shutdown() {
|
|
116
|
+
return this.wrappedExporter.shutdown();
|
|
117
|
+
}
|
|
118
|
+
forceFlush() {
|
|
119
|
+
return this.wrappedExporter.forceFlush?.() ?? Promise.resolve();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=content-capture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-capture.js","sourceRoot":"","sources":["../src/content-capture.ts"],"names":[],"mappings":"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"}
|
package/dist/evaluate.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../src/evaluate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../src/evaluate.ts"],"names":[],"mappings":"AAIA,OAAO,EAAuB,KAAK,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAI7E;;0DAE0D;AAC1D,eAAO,MAAM,aAAa,aAQxB,CAAC;AAEH,MAAM,WAAW,kBAAkB;IACjC;;sFAEkF;IAClF,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,WAAW,CAAC;IAC/C;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AA2BD,wBAAsB,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA6FpF"}
|
package/dist/evaluate.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
1
2
|
import { getConfig, getApiKey } from "./index.js";
|
|
2
3
|
import { flushUngoverned } from "./ungoverned.js";
|
|
3
4
|
import { currentAgentId, currentParentAgentId, currentRunId } from "./context.js";
|
|
@@ -87,9 +88,15 @@ export async function evaluate(options) {
|
|
|
87
88
|
if (options.toolName !== undefined) {
|
|
88
89
|
payload.tool_name = options.toolName;
|
|
89
90
|
}
|
|
91
|
+
// One key per invocation, minted here and never taken from the payload: `requestId` can be a
|
|
92
|
+
// session id shared by every governed call of a conversation, and deduplicating on it would
|
|
93
|
+
// collapse a transfer and a later email into one. A transport replay resends these exact bytes
|
|
94
|
+
// with this exact key, so the platform replays the first decision and a person approves the
|
|
95
|
+
// action once; an agent that calls evaluate() twice on purpose mints two keys and gets two.
|
|
96
|
+
const idempotencyKey = randomUUID();
|
|
90
97
|
const resp = await coalexFetch("evaluate()", `${config.endpoint}/api/v1/evaluate`, {
|
|
91
98
|
method: "POST",
|
|
92
|
-
headers: sdkHeaders(apiKey, { "Content-Type": "application/json" }),
|
|
99
|
+
headers: sdkHeaders(apiKey, { "Content-Type": "application/json", "Idempotency-Key": idempotencyKey }),
|
|
93
100
|
body: JSON.stringify(payload),
|
|
94
101
|
});
|
|
95
102
|
if (!resp.ok) {
|
package/dist/evaluate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../src/evaluate.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../src/evaluate.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,18 +2,35 @@
|
|
|
2
2
|
* Span context bridge for fixing OTel context propagation across
|
|
3
3
|
* async execution boundaries (e.g. LangGraph.js task executors).
|
|
4
4
|
*
|
|
5
|
-
* Tracks active
|
|
5
|
+
* Tracks active spans in a global registry so that ext wrappers
|
|
6
6
|
* (retrievalSpan, etc.) can find the correct parent context.
|
|
7
|
+
*
|
|
8
|
+
* The registry never keeps a span alive. A span that never ends (an abandoned stream, a cancelled
|
|
9
|
+
* task) is registered until it ends, and a strong reference would hold it, and the prompt it
|
|
10
|
+
* carries, for the life of the process. Entries hold a `WeakRef`: once the application drops the
|
|
11
|
+
* span its entry is dead and is swept. Every `sweepEvery` pushes a sweep walks all traces, dropping
|
|
12
|
+
* dead and stale entries, and the total is capped at `maxEntries` (oldest first) so a registry of
|
|
13
|
+
* live but forgotten spans stays bounded too.
|
|
14
|
+
*
|
|
15
|
+
* A parent context is rebuilt at lookup from the active context with the registered span set in
|
|
16
|
+
* it, rather than stored at push time: a stored context holds its own parent span strongly.
|
|
7
17
|
*/
|
|
8
18
|
import { type Context, trace } from "@opentelemetry/api";
|
|
9
19
|
declare class SpanContextBridge {
|
|
20
|
+
readonly maxEntries = 10000;
|
|
21
|
+
readonly sweepEvery = 256;
|
|
10
22
|
private readonly stacks;
|
|
11
|
-
|
|
23
|
+
private pushes;
|
|
24
|
+
push(span: ReturnType<typeof trace.getSpan>, _ctx: Context): void;
|
|
12
25
|
pop(spanCtx: {
|
|
13
26
|
traceId: string;
|
|
14
27
|
spanId: string;
|
|
15
28
|
}): void;
|
|
29
|
+
/** Drop dead and stale entries in every trace, then the oldest beyond the cap. */
|
|
30
|
+
private sweep;
|
|
16
31
|
getNearestParent(): Context | null;
|
|
32
|
+
/** How many entries are registered (for tests). */
|
|
33
|
+
size(): number;
|
|
17
34
|
clear(): void;
|
|
18
35
|
}
|
|
19
36
|
export declare const spanContextBridge: SpanContextBridge;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-bridge.d.ts","sourceRoot":"","sources":["../../src/ext/context-bridge.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"context-bridge.d.ts","sourceRoot":"","sources":["../../src/ext/context-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,KAAK,OAAO,EAAsB,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAU7E,cAAM,iBAAiB;IACrB,QAAQ,CAAC,UAAU,SAAU;IAC7B,QAAQ,CAAC,UAAU,OAAO;IAE1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoC;IAC3D,OAAO,CAAC,MAAM,CAAK;IAEnB,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,OAAO,KAAK,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI;IAWjE,GAAG,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAYvD,kFAAkF;IAClF,OAAO,CAAC,KAAK;IAuBb,gBAAgB,IAAI,OAAO,GAAG,IAAI;IAmBlC,mDAAmD;IACnD,IAAI,IAAI,MAAM;IAMd,KAAK,IAAI,IAAI;CAGd;AAED,eAAO,MAAM,iBAAiB,mBAA0B,CAAC"}
|
|
@@ -2,25 +2,38 @@
|
|
|
2
2
|
* Span context bridge for fixing OTel context propagation across
|
|
3
3
|
* async execution boundaries (e.g. LangGraph.js task executors).
|
|
4
4
|
*
|
|
5
|
-
* Tracks active
|
|
5
|
+
* Tracks active spans in a global registry so that ext wrappers
|
|
6
6
|
* (retrievalSpan, etc.) can find the correct parent context.
|
|
7
|
+
*
|
|
8
|
+
* The registry never keeps a span alive. A span that never ends (an abandoned stream, a cancelled
|
|
9
|
+
* task) is registered until it ends, and a strong reference would hold it, and the prompt it
|
|
10
|
+
* carries, for the life of the process. Entries hold a `WeakRef`: once the application drops the
|
|
11
|
+
* span its entry is dead and is swept. Every `sweepEvery` pushes a sweep walks all traces, dropping
|
|
12
|
+
* dead and stale entries, and the total is capped at `maxEntries` (oldest first) so a registry of
|
|
13
|
+
* live but forgotten spans stays bounded too.
|
|
14
|
+
*
|
|
15
|
+
* A parent context is rebuilt at lookup from the active context with the registered span set in
|
|
16
|
+
* it, rather than stored at push time: a stored context holds its own parent span strongly.
|
|
7
17
|
*/
|
|
8
18
|
import { context, trace } from "@opentelemetry/api";
|
|
9
19
|
const STALE_TTL_MS = 300_000; // 5 minutes
|
|
10
20
|
class SpanContextBridge {
|
|
21
|
+
maxEntries = 10_000;
|
|
22
|
+
sweepEvery = 256;
|
|
11
23
|
stacks = new Map();
|
|
12
|
-
|
|
24
|
+
pushes = 0;
|
|
25
|
+
push(span, _ctx) {
|
|
13
26
|
if (!span)
|
|
14
27
|
return;
|
|
15
28
|
const spanCtx = span.spanContext();
|
|
16
29
|
if (!spanCtx.traceId)
|
|
17
30
|
return;
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
31
|
+
const stack = this.stacks.get(spanCtx.traceId) ?? [];
|
|
32
|
+
stack.push({ spanId: spanCtx.spanId, span: new WeakRef(span), timestamp: Date.now() });
|
|
33
|
+
this.stacks.set(spanCtx.traceId, stack);
|
|
34
|
+
this.pushes += 1;
|
|
35
|
+
if (this.pushes % this.sweepEvery === 0)
|
|
36
|
+
this.sweep();
|
|
24
37
|
}
|
|
25
38
|
pop(spanCtx) {
|
|
26
39
|
if (!spanCtx.traceId)
|
|
@@ -36,6 +49,32 @@ class SpanContextBridge {
|
|
|
36
49
|
this.stacks.set(spanCtx.traceId, filtered);
|
|
37
50
|
}
|
|
38
51
|
}
|
|
52
|
+
/** Drop dead and stale entries in every trace, then the oldest beyond the cap. */
|
|
53
|
+
sweep() {
|
|
54
|
+
const now = Date.now();
|
|
55
|
+
let total = 0;
|
|
56
|
+
for (const [traceId, stack] of this.stacks) {
|
|
57
|
+
const live = stack.filter((e) => e.span.deref() !== undefined && now - e.timestamp < STALE_TTL_MS);
|
|
58
|
+
if (live.length === 0) {
|
|
59
|
+
this.stacks.delete(traceId);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
this.stacks.set(traceId, live);
|
|
63
|
+
total += live.length;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (total <= this.maxEntries)
|
|
67
|
+
return;
|
|
68
|
+
const oldestFirst = [];
|
|
69
|
+
for (const [traceId, stack] of this.stacks) {
|
|
70
|
+
for (const e of stack)
|
|
71
|
+
oldestFirst.push({ timestamp: e.timestamp, traceId, spanId: e.spanId });
|
|
72
|
+
}
|
|
73
|
+
oldestFirst.sort((a, b) => a.timestamp - b.timestamp);
|
|
74
|
+
for (const { traceId, spanId } of oldestFirst.slice(0, total - this.maxEntries)) {
|
|
75
|
+
this.pop({ traceId, spanId });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
39
78
|
getNearestParent() {
|
|
40
79
|
const current = trace.getSpan(context.active());
|
|
41
80
|
if (!current)
|
|
@@ -47,14 +86,22 @@ class SpanContextBridge {
|
|
|
47
86
|
if (!stack || stack.length === 0)
|
|
48
87
|
return null;
|
|
49
88
|
const now = Date.now();
|
|
50
|
-
// Clean stale entries
|
|
51
|
-
const fresh = stack.filter((e) => now - e.timestamp < STALE_TTL_MS);
|
|
89
|
+
// Clean stale and dead entries
|
|
90
|
+
const fresh = stack.filter((e) => e.span.deref() !== undefined && now - e.timestamp < STALE_TTL_MS);
|
|
52
91
|
if (fresh.length === 0) {
|
|
53
92
|
this.stacks.delete(traceId);
|
|
54
93
|
return null;
|
|
55
94
|
}
|
|
56
95
|
this.stacks.set(traceId, fresh);
|
|
57
|
-
|
|
96
|
+
const span = fresh[fresh.length - 1].span.deref();
|
|
97
|
+
return span ? trace.setSpan(context.active(), span) : null;
|
|
98
|
+
}
|
|
99
|
+
/** How many entries are registered (for tests). */
|
|
100
|
+
size() {
|
|
101
|
+
let total = 0;
|
|
102
|
+
for (const stack of this.stacks.values())
|
|
103
|
+
total += stack.length;
|
|
104
|
+
return total;
|
|
58
105
|
}
|
|
59
106
|
clear() {
|
|
60
107
|
this.stacks.clear();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-bridge.js","sourceRoot":"","sources":["../../src/ext/context-bridge.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"context-bridge.js","sourceRoot":"","sources":["../../src/ext/context-bridge.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -59,8 +59,47 @@ export interface RegisterOptions {
|
|
|
59
59
|
* (`1`/`true`/`yes`/`on`), or false when unset.
|
|
60
60
|
*/
|
|
61
61
|
promptRefs?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Set to false to export spans without their content: the prompts, the responses,
|
|
64
|
+
* `input.value` / `output.value`, the `gen_ai.*` messages, tool arguments, retrieved documents
|
|
65
|
+
* and embedded text are removed from every span and span event before export. Model, token
|
|
66
|
+
* counts, timing, status and the `coalex.*` attributes are kept. Default true: content is
|
|
67
|
+
* exported. Other exporters on the same provider still receive the content. A span that cannot be
|
|
68
|
+
* stripped is not exported. `promptRefs` has no effect with this off, which exports no prompt
|
|
69
|
+
* text at all.
|
|
70
|
+
*/
|
|
71
|
+
captureContent?: boolean;
|
|
62
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* Register the Coalex exporter as the global tracer provider.
|
|
75
|
+
*
|
|
76
|
+
* Call once at startup. Throws when the options cannot take effect rather than ignoring them:
|
|
77
|
+
*
|
|
78
|
+
* - a second `register()` with different span options (the exporter chain is built once; the error
|
|
79
|
+
* names each option that differs), and
|
|
80
|
+
* - an application whose own tracer provider is already installed (OpenTelemetry's SDK 2.x gives a
|
|
81
|
+
* provider no way to take another processor afterwards; the error names each option that would
|
|
82
|
+
* be ignored). Call `register()` before the application's own setup, or add the Coalex span
|
|
83
|
+
* processor to that provider yourself.
|
|
84
|
+
*
|
|
85
|
+
* A second `register()` with the same options does nothing.
|
|
86
|
+
*/
|
|
63
87
|
export declare function register(options?: RegisterOptions): void;
|
|
88
|
+
/**
|
|
89
|
+
* Send every span that has ended and not yet left, and wait for it.
|
|
90
|
+
*
|
|
91
|
+
* Spans are batched for five seconds, so a script, a job or a serverless handler that finishes
|
|
92
|
+
* sooner exports nothing unless it awaits this (or `shutdown()`) first. The SDK also flushes when
|
|
93
|
+
* the process runs out of work (`beforeExit`), which covers a script that simply ends but not a
|
|
94
|
+
* `process.exit()` and not a serverless runtime that freezes the process after the handler.
|
|
95
|
+
* Resolves without doing anything before `register()`.
|
|
96
|
+
*/
|
|
97
|
+
export declare function forceFlush(): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* Flush, then stop exporting. For the end of a process that calls `process.exit()` itself, and for
|
|
100
|
+
* tests. After it, `register()` can install a fresh provider.
|
|
101
|
+
*/
|
|
102
|
+
export declare function shutdown(): Promise<void>;
|
|
64
103
|
/**
|
|
65
104
|
* Declare one agent, or several, with the endpoint and key `register()` configured.
|
|
66
105
|
*
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { trace } from "@opentelemetry/api";
|
|
1
2
|
import { resourceFromAttributes } from "@opentelemetry/resources";
|
|
2
3
|
import { sdkHeaders } from "./http.js";
|
|
3
4
|
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
|
|
@@ -7,6 +8,7 @@ import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
|
|
|
7
8
|
import { SafeOTLPSpanExporter } from "./safe-exporter.js";
|
|
8
9
|
import { FilteringSpanExporter } from "./filtering-exporter.js";
|
|
9
10
|
import { PromptReferenceExporter } from "./prompt-refs.js";
|
|
11
|
+
import { ContentStrippingExporter } from "./content-capture.js";
|
|
10
12
|
import { CoalexAttributePropagator } from "./span-processor.js";
|
|
11
13
|
import { declareMany } from "./inventory.js";
|
|
12
14
|
import { setLogger } from "./logger.js";
|
|
@@ -44,25 +46,74 @@ export function getApiKey() {
|
|
|
44
46
|
}
|
|
45
47
|
return _apiKey;
|
|
46
48
|
}
|
|
49
|
+
/** The provider this SDK installed, and the span options it was given. */
|
|
50
|
+
let _provider = null;
|
|
51
|
+
let _spanOptions = null;
|
|
52
|
+
/** The provider behind the global proxy, or undefined when none has been installed. */
|
|
53
|
+
function installedProvider() {
|
|
54
|
+
const proxy = trace.getTracerProvider();
|
|
55
|
+
const delegate = proxy.getDelegate?.();
|
|
56
|
+
return delegate?.constructor?.name === "NoopTracerProvider" ? undefined : delegate;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Register the Coalex exporter as the global tracer provider.
|
|
60
|
+
*
|
|
61
|
+
* Call once at startup. Throws when the options cannot take effect rather than ignoring them:
|
|
62
|
+
*
|
|
63
|
+
* - a second `register()` with different span options (the exporter chain is built once; the error
|
|
64
|
+
* names each option that differs), and
|
|
65
|
+
* - an application whose own tracer provider is already installed (OpenTelemetry's SDK 2.x gives a
|
|
66
|
+
* provider no way to take another processor afterwards; the error names each option that would
|
|
67
|
+
* be ignored). Call `register()` before the application's own setup, or add the Coalex span
|
|
68
|
+
* processor to that provider yourself.
|
|
69
|
+
*
|
|
70
|
+
* A second `register()` with the same options does nothing.
|
|
71
|
+
*/
|
|
47
72
|
export function register(options) {
|
|
48
73
|
const endpoint = options?.endpoint ?? "https://traces.coalex.ai";
|
|
49
74
|
const apiKey = options?.apiKey ?? "dev";
|
|
50
75
|
const serviceName = options?.serviceName ?? "coalex-sdk-typescript";
|
|
51
76
|
const filterNonAiSpans = options?.filterNonAiSpans ?? false;
|
|
52
77
|
const suppressExportErrors = options?.suppressExportErrors ?? true;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
78
|
+
const promptRefs = options?.promptRefs ??
|
|
79
|
+
["1", "true", "yes", "on"].includes((process.env.COALEX_PROMPT_REFS ?? "").trim().toLowerCase());
|
|
80
|
+
const captureContent = options?.captureContent ?? true;
|
|
81
|
+
const spanOptions = {
|
|
82
|
+
endpoint,
|
|
83
|
+
apiKey,
|
|
84
|
+
serviceName,
|
|
85
|
+
filterNonAiSpans,
|
|
86
|
+
suppressExportErrors,
|
|
87
|
+
promptRefs,
|
|
88
|
+
captureContent,
|
|
89
|
+
};
|
|
90
|
+
// Decided against what is installed BEFORE anything is stored: a refused call must leave the
|
|
91
|
+
// first registration exactly as it was, so that evaluate() and the spans keep agreeing on one
|
|
92
|
+
// endpoint and key.
|
|
93
|
+
const alreadyOurs = _provider !== null && installedProvider() === _provider;
|
|
94
|
+
if (alreadyOurs) {
|
|
95
|
+
const changed = Object.keys(spanOptions).filter((name) => _spanOptions?.[name] !== spanOptions[name]);
|
|
96
|
+
if (changed.length > 0) {
|
|
97
|
+
throw new Error(`register() was already called with different options: ${changed.join(", ")}. ` +
|
|
98
|
+
"The span exporter is built once, so these cannot take effect on spans. " +
|
|
99
|
+
"Call register() once, or call it again with the same options.");
|
|
100
|
+
}
|
|
101
|
+
setLogger(options?.logger);
|
|
102
|
+
declareAfterRegister(options, apiKey);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
58
105
|
const resource = resourceFromAttributes({ [ATTR_SERVICE_NAME]: serviceName });
|
|
59
106
|
const baseExporter = new OTLPTraceExporter({
|
|
60
107
|
url: `${endpoint}/v1/traces`,
|
|
61
108
|
headers: sdkHeaders(apiKey),
|
|
62
109
|
});
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const wireExporter =
|
|
110
|
+
// Stripping is the last step before the OTLP exporter, so nothing added earlier in the chain can
|
|
111
|
+
// reach the wire with content; with it on there is no prompt text left to replace by a reference.
|
|
112
|
+
const wireExporter = !captureContent
|
|
113
|
+
? new ContentStrippingExporter(baseExporter)
|
|
114
|
+
: promptRefs
|
|
115
|
+
? new PromptReferenceExporter(baseExporter)
|
|
116
|
+
: baseExporter;
|
|
66
117
|
const safeExporter = new SafeOTLPSpanExporter(wireExporter, suppressExportErrors);
|
|
67
118
|
const finalExporter = filterNonAiSpans
|
|
68
119
|
? new FilteringSpanExporter(safeExporter)
|
|
@@ -75,13 +126,85 @@ export function register(options) {
|
|
|
75
126
|
spanProcessors: [new CoalexAttributePropagator(), new BatchSpanProcessor(finalExporter)],
|
|
76
127
|
});
|
|
77
128
|
provider.register();
|
|
78
|
-
if (
|
|
129
|
+
if (installedProvider() !== provider) {
|
|
130
|
+
// The application's own provider was installed first and OpenTelemetry keeps it. This one
|
|
131
|
+
// never became global, so nothing it was given would take effect.
|
|
132
|
+
void provider.shutdown();
|
|
133
|
+
throw new Error("A tracer provider is already installed and cannot take another span processor, so register() " +
|
|
134
|
+
"cannot send spans through it. These options would be ignored: " +
|
|
135
|
+
`${Object.keys(spanOptions).join(", ")}. Call register() before the application's own ` +
|
|
136
|
+
"tracer setup, or add the Coalex span processor to that provider yourself.");
|
|
137
|
+
}
|
|
138
|
+
// First, so anything the rest of register() reports already goes where the caller asked.
|
|
139
|
+
setLogger(options?.logger);
|
|
140
|
+
_config = { endpoint, serviceName };
|
|
141
|
+
_apiKey = apiKey;
|
|
142
|
+
_explicitServiceName = options?.serviceName;
|
|
143
|
+
_provider = provider;
|
|
144
|
+
_spanOptions = spanOptions;
|
|
145
|
+
installExitHook();
|
|
146
|
+
declareAfterRegister(options, apiKey);
|
|
147
|
+
}
|
|
148
|
+
function declareAfterRegister(options, apiKey) {
|
|
149
|
+
if (options?.declare && _config) {
|
|
79
150
|
// Deliberately last, and deliberately not awaited: tracing is configured before we talk to
|
|
80
151
|
// anyone, and register() stays synchronous so an unreachable control plane cannot delay or
|
|
81
152
|
// block an agent's startup. declareMany never rejects.
|
|
82
153
|
void declareMany(options.declare, { config: _config, apiKey, serviceName: _explicitServiceName });
|
|
83
154
|
}
|
|
84
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* Send every span that has ended and not yet left, and wait for it.
|
|
158
|
+
*
|
|
159
|
+
* Spans are batched for five seconds, so a script, a job or a serverless handler that finishes
|
|
160
|
+
* sooner exports nothing unless it awaits this (or `shutdown()`) first. The SDK also flushes when
|
|
161
|
+
* the process runs out of work (`beforeExit`), which covers a script that simply ends but not a
|
|
162
|
+
* `process.exit()` and not a serverless runtime that freezes the process after the handler.
|
|
163
|
+
* Resolves without doing anything before `register()`.
|
|
164
|
+
*/
|
|
165
|
+
export async function forceFlush() {
|
|
166
|
+
await _provider?.forceFlush();
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Flush, then stop exporting. For the end of a process that calls `process.exit()` itself, and for
|
|
170
|
+
* tests. After it, `register()` can install a fresh provider.
|
|
171
|
+
*/
|
|
172
|
+
export async function shutdown() {
|
|
173
|
+
const provider = _provider;
|
|
174
|
+
if (!provider)
|
|
175
|
+
return;
|
|
176
|
+
_provider = null;
|
|
177
|
+
_spanOptions = null;
|
|
178
|
+
try {
|
|
179
|
+
await provider.shutdown();
|
|
180
|
+
}
|
|
181
|
+
finally {
|
|
182
|
+
// Release the global slot, or a later register() would find a dead provider installed.
|
|
183
|
+
trace.disable();
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
let exitHookInstalled = false;
|
|
187
|
+
let flushingOnExit = false;
|
|
188
|
+
/** Flush when the process runs out of work, once per process however often register() is called. */
|
|
189
|
+
function installExitHook() {
|
|
190
|
+
if (exitHookInstalled)
|
|
191
|
+
return;
|
|
192
|
+
exitHookInstalled = true;
|
|
193
|
+
process.on("beforeExit", () => {
|
|
194
|
+
const provider = _provider;
|
|
195
|
+
if (!provider || flushingOnExit)
|
|
196
|
+
return;
|
|
197
|
+
flushingOnExit = true;
|
|
198
|
+
// The network call keeps the event loop alive until it settles; a second `beforeExit` then
|
|
199
|
+
// finds nothing to send and the process ends.
|
|
200
|
+
void provider
|
|
201
|
+
.forceFlush()
|
|
202
|
+
.catch(() => undefined)
|
|
203
|
+
.finally(() => {
|
|
204
|
+
flushingOnExit = false;
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
}
|
|
85
208
|
export async function declare(inventory) {
|
|
86
209
|
const config = getConfig();
|
|
87
210
|
const apiKey = getApiKey();
|
|
@@ -90,6 +213,8 @@ export async function declare(inventory) {
|
|
|
90
213
|
}
|
|
91
214
|
/** Reset SDK state — for testing only. */
|
|
92
215
|
export function _resetForTesting() {
|
|
216
|
+
_provider = null;
|
|
217
|
+
_spanOptions = null;
|
|
93
218
|
_config = null;
|
|
94
219
|
_apiKey = null;
|
|
95
220
|
_explicitServiceName = undefined;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAGxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EAAE,SAAS,EAAqB,MAAM,aAAa,CAAC;AAG3D,OAAO,EACL,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,YAAY,GACb,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAExD,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACxD,iGAAiG;AACjG,iGAAiG;AACjG,2FAA2F;AAC3F,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGpE,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,WAAW,EACX,oBAAoB,EACpB,gBAAgB;AAChB,+FAA+F;AAC/F,iFAAiF;AACjF,mBAAmB,EACnB,cAAc,GACf,MAAM,uBAAuB,CAAC;AAc/B,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGhF,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAIvI,IAAI,OAAO,GAAwB,IAAI,CAAC;AACxC,IAAI,OAAO,GAAkB,IAAI,CAAC;AAClC;;;GAGG;AACH,IAAI,oBAAwC,CAAC;AAE7C,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/ungoverned.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ungoverned.d.ts","sourceRoot":"","sources":["../src/ungoverned.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAyCH,0CAA0C;AAC1C,MAAM,WAAW,gBAAgB;IAC/B,sFAAsF;IACtF,SAAS,EAAE,MAAM,CAAC;IAClB,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;CACf;
|
|
1
|
+
{"version":3,"file":"ungoverned.d.ts","sourceRoot":"","sources":["../src/ungoverned.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAyCH,0CAA0C;AAC1C,MAAM,WAAW,gBAAgB;IAC/B,sFAAsF;IACtF,SAAS,EAAE,MAAM,CAAC;IAClB,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;CACf;AA2CD,iFAAiF;AACjF,wBAAgB,oBAAoB,IAAI,MAAM,CAK7C;AAyLD;;;;;;GAMG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAkBvD;AAoDD;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiC9E"}
|
package/dist/ungoverned.js
CHANGED
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
* Nothing here ever throws. It is called from the caller's `catch`, and a governance recorder that
|
|
35
35
|
* can break the thing it is recording is worse than none.
|
|
36
36
|
*/
|
|
37
|
-
import { createHash } from "node:crypto";
|
|
37
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
38
38
|
import { appendFileSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync, } from "node:fs";
|
|
39
39
|
import { tmpdir } from "node:os";
|
|
40
40
|
import { basename, dirname, join } from "node:path";
|
|
@@ -98,12 +98,30 @@ export function _spoolPathForTesting() {
|
|
|
98
98
|
return join(base, "unregistered.jsonl");
|
|
99
99
|
return spoolPath(endpoint, apiKey);
|
|
100
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* A working file this old belongs to a flush that is not coming back, whatever its pid says (a pid
|
|
103
|
+
* is only meaningful on the host that wrote it, and a pid is reused). A flush sends at most
|
|
104
|
+
* `FLUSH_BATCH` records of `TIMEOUT_MS` each, a little over four minutes at the very worst.
|
|
105
|
+
*/
|
|
106
|
+
const STRANDED_AFTER_MS = 600_000;
|
|
107
|
+
/**
|
|
108
|
+
* The id every delivery of this record carries, so a repeat can be recognised as a repeat.
|
|
109
|
+
*
|
|
110
|
+
* Written into the record when it is created. A record spooled without one is given an id derived
|
|
111
|
+
* from its content, which is the same every time it is read.
|
|
112
|
+
*/
|
|
113
|
+
function recordId(entry) {
|
|
114
|
+
if (typeof entry.id === "string" && entry.id)
|
|
115
|
+
return entry.id;
|
|
116
|
+
const basis = JSON.stringify([entry.request_id, entry.action, entry.error, entry.at]);
|
|
117
|
+
return createHash("sha256").update(basis).digest("hex").slice(0, 32);
|
|
118
|
+
}
|
|
101
119
|
async function post(endpoint, apiKey, entry, late) {
|
|
102
120
|
let resp;
|
|
103
121
|
try {
|
|
104
122
|
resp = await coalexFetch("ungoverned record", `${endpoint}/api/v1/gateway-audit`, {
|
|
105
123
|
method: "POST",
|
|
106
|
-
headers: sdkHeaders(apiKey, { "Content-Type": "application/json" }),
|
|
124
|
+
headers: sdkHeaders(apiKey, { "Content-Type": "application/json", "Idempotency-Key": recordId(entry) }),
|
|
107
125
|
body: JSON.stringify({
|
|
108
126
|
tool_name: entry.action,
|
|
109
127
|
arguments: null,
|
|
@@ -118,6 +136,7 @@ async function post(endpoint, apiKey, entry, late) {
|
|
|
118
136
|
governed: null,
|
|
119
137
|
governance_error: entry.error,
|
|
120
138
|
recorded_late: late,
|
|
139
|
+
record_id: recordId(entry),
|
|
121
140
|
},
|
|
122
141
|
}),
|
|
123
142
|
}, TIMEOUT_MS);
|
|
@@ -198,6 +217,35 @@ function trim(path) {
|
|
|
198
217
|
log.warn("could not trim the ungoverned spool");
|
|
199
218
|
}
|
|
200
219
|
}
|
|
220
|
+
function pidIsAlive(pid) {
|
|
221
|
+
try {
|
|
222
|
+
process.kill(pid, 0);
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
catch (err) {
|
|
226
|
+
// ESRCH: no such process. EPERM: it exists and is not ours to signal.
|
|
227
|
+
return err.code !== "ESRCH";
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Whether a working file belongs to a flush that is not coming back.
|
|
232
|
+
*
|
|
233
|
+
* The name is `<spool>.<pid>.<ms>.sending` (Python writes nanoseconds). A flush that is still
|
|
234
|
+
* running, in this process or in another one sharing the spool, owns its file; taking it would send
|
|
235
|
+
* its records a second time. So only a file whose process is gone, or one old enough that its flush
|
|
236
|
+
* must have died, is taken back.
|
|
237
|
+
*/
|
|
238
|
+
function isStranded(name, spoolName) {
|
|
239
|
+
const [pidText, startedText] = name.slice(spoolName.length + 1).split(".");
|
|
240
|
+
const pid = Number(pidText);
|
|
241
|
+
const started = Number(startedText);
|
|
242
|
+
if (!Number.isInteger(pid) || !Number.isFinite(started))
|
|
243
|
+
return true; // not a name we wrote
|
|
244
|
+
const startedMs = started > 1e17 ? started / 1e6 : started;
|
|
245
|
+
if (Date.now() - startedMs > STRANDED_AFTER_MS)
|
|
246
|
+
return true;
|
|
247
|
+
return !pidIsAlive(pid);
|
|
248
|
+
}
|
|
201
249
|
/**
|
|
202
250
|
* Batches left behind by a process that died mid-drain, returned to the live spool.
|
|
203
251
|
*
|
|
@@ -217,6 +265,8 @@ function reclaimStranded(path) {
|
|
|
217
265
|
for (const name of names) {
|
|
218
266
|
if (!name.startsWith(prefix) || !name.endsWith(".sending"))
|
|
219
267
|
continue;
|
|
268
|
+
if (!isStranded(name, basename(path)))
|
|
269
|
+
continue;
|
|
220
270
|
const stranded = join(dirname(path), name);
|
|
221
271
|
appendEntries(path, readEntries(stranded));
|
|
222
272
|
try {
|
|
@@ -235,6 +285,23 @@ function reclaimStranded(path) {
|
|
|
235
285
|
* would keep the backlog exactly as long as the outage lasts, and then some.
|
|
236
286
|
*/
|
|
237
287
|
export async function flushUngoverned() {
|
|
288
|
+
// One flush at a time per process. A second caller waits for the one already sending and reports
|
|
289
|
+
// nothing of its own: two flushes at once used to send every record twice, and a compliance
|
|
290
|
+
// report counts an ungoverned action as often as it is recorded.
|
|
291
|
+
if (inFlight) {
|
|
292
|
+
await inFlight;
|
|
293
|
+
return 0;
|
|
294
|
+
}
|
|
295
|
+
const running = drain();
|
|
296
|
+
inFlight = running
|
|
297
|
+
.then(() => undefined, () => undefined)
|
|
298
|
+
.then(() => {
|
|
299
|
+
inFlight = null;
|
|
300
|
+
});
|
|
301
|
+
return running;
|
|
302
|
+
}
|
|
303
|
+
let inFlight = null;
|
|
304
|
+
async function drain() {
|
|
238
305
|
const { endpoint, apiKey } = identity();
|
|
239
306
|
if (!endpoint || !apiKey)
|
|
240
307
|
return 0;
|
|
@@ -300,6 +367,7 @@ export async function recordUngoverned(record) {
|
|
|
300
367
|
return;
|
|
301
368
|
}
|
|
302
369
|
const entry = {
|
|
370
|
+
id: randomUUID(),
|
|
303
371
|
request_id: record.requestId,
|
|
304
372
|
action: record.action,
|
|
305
373
|
error: String(record.error).slice(0, MAX_ERROR_CHARS),
|
package/dist/ungoverned.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ungoverned.js","sourceRoot":"","sources":["../src/ungoverned.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"ungoverned.js","sourceRoot":"","sources":["../src/ungoverned.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "2.
|
|
1
|
+
export declare const VERSION = "2.9.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SDK version, sent in the X-SDK-Version header so the platform can see which
|
|
2
2
|
// SDK releases customers run before removing a deprecated field (COA-261).
|
|
3
3
|
// Keep in sync with package.json "version".
|
|
4
|
-
export const VERSION = "2.
|
|
4
|
+
export const VERSION = "2.9.0";
|
|
5
5
|
//# sourceMappingURL=version.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coalex-ai/sdk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.9.0-beta.705",
|
|
4
4
|
"description": "Coalex TypeScript SDK for AI governance observability",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -17,13 +17,18 @@
|
|
|
17
17
|
"exports": {
|
|
18
18
|
".": {
|
|
19
19
|
"types": "./dist/index.d.ts",
|
|
20
|
-
"import": "./dist/index.js"
|
|
20
|
+
"import": "./dist/index.js",
|
|
21
|
+
"default": "./dist/index.js"
|
|
21
22
|
},
|
|
22
23
|
"./ext": {
|
|
23
24
|
"types": "./dist/ext/index.d.ts",
|
|
24
|
-
"import": "./dist/ext/index.js"
|
|
25
|
+
"import": "./dist/ext/index.js",
|
|
26
|
+
"default": "./dist/ext/index.js"
|
|
25
27
|
}
|
|
26
28
|
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=20.19.0"
|
|
31
|
+
},
|
|
27
32
|
"files": [
|
|
28
33
|
"dist"
|
|
29
34
|
],
|