@graphorin/core 0.6.1 → 0.7.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 +82 -0
- package/README.md +8 -5
- package/dist/channels/index.d.ts +2 -2
- package/dist/channels/index.js +2 -2
- package/dist/channels/pause.d.ts +47 -2
- package/dist/channels/pause.d.ts.map +1 -1
- package/dist/channels/pause.js +62 -2
- package/dist/channels/pause.js.map +1 -1
- package/dist/contracts/checkpoint-store.d.ts +97 -1
- package/dist/contracts/checkpoint-store.d.ts.map +1 -1
- package/dist/contracts/checkpoint-store.js.map +1 -1
- package/dist/contracts/index.d.ts +5 -5
- package/dist/contracts/index.js +2 -1
- package/dist/contracts/memory-store.d.ts +59 -2
- package/dist/contracts/memory-store.d.ts.map +1 -1
- package/dist/contracts/provider.d.ts +20 -6
- package/dist/contracts/provider.d.ts.map +1 -1
- package/dist/contracts/session-store.d.ts +10 -2
- package/dist/contracts/session-store.d.ts.map +1 -1
- package/dist/contracts/tool.d.ts +75 -1
- package/dist/contracts/tool.d.ts.map +1 -1
- package/dist/contracts/tool.js +57 -0
- package/dist/contracts/tool.js.map +1 -0
- package/dist/contracts/tracer.d.ts +53 -5
- package/dist/contracts/tracer.d.ts.map +1 -1
- package/dist/contracts/tracer.js.map +1 -1
- package/dist/index.d.ts +9 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -5
- package/dist/package.js +1 -1
- package/dist/package.js.map +1 -1
- package/dist/types/agent-event-wire.d.ts +74 -0
- package/dist/types/agent-event-wire.d.ts.map +1 -0
- package/dist/types/agent-event-wire.js +130 -0
- package/dist/types/agent-event-wire.js.map +1 -0
- package/dist/types/agent-event.d.ts +48 -6
- package/dist/types/agent-event.d.ts.map +1 -1
- package/dist/types/index.d.ts +3 -2
- package/dist/types/index.js +2 -1
- package/dist/types/memory.d.ts +11 -0
- package/dist/types/memory.d.ts.map +1 -1
- package/dist/types/run.d.ts +86 -4
- package/dist/types/run.d.ts.map +1 -1
- package/dist/types/run.js.map +1 -1
- package/dist/types/tool.d.ts +10 -0
- package/dist/types/tool.d.ts.map +1 -1
- package/dist/types/usage.d.ts +11 -1
- package/dist/types/usage.d.ts.map +1 -1
- package/dist/types/usage.js.map +1 -1
- package/dist/utils/binary-json.d.ts +165 -0
- package/dist/utils/binary-json.d.ts.map +1 -0
- package/dist/utils/binary-json.js +240 -0
- package/dist/utils/binary-json.js.map +1 -0
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/index.js +2 -1
- package/dist/utils/validation.d.ts +10 -1
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +1 -1
- package/dist/utils/validation.js.map +1 -1
- package/package.json +9 -7
- package/src/channels/channels.ts +206 -0
- package/src/channels/directive.ts +41 -0
- package/src/channels/dispatch.ts +37 -0
- package/src/channels/durable.ts +151 -0
- package/src/channels/index.ts +62 -0
- package/src/channels/pause.ts +216 -0
- package/src/contracts/auth-token-store.ts +42 -0
- package/src/contracts/checkpoint-store.ts +256 -0
- package/src/contracts/embedder.ts +42 -0
- package/src/contracts/eval-scorer.ts +44 -0
- package/src/contracts/index.ts +112 -0
- package/src/contracts/local-provider-trust.ts +33 -0
- package/src/contracts/logger.ts +61 -0
- package/src/contracts/memory-store.ts +187 -0
- package/src/contracts/oauth-server-store.ts +78 -0
- package/src/contracts/preferred-model.ts +56 -0
- package/src/contracts/provider.ts +316 -0
- package/src/contracts/reasoning-retention.ts +52 -0
- package/src/contracts/redaction-validator.ts +56 -0
- package/src/contracts/sandbox.ts +70 -0
- package/src/contracts/secret-ref.ts +22 -0
- package/src/contracts/secret-value.ts +117 -0
- package/src/contracts/secrets-store.ts +90 -0
- package/src/contracts/session-store.ts +163 -0
- package/src/contracts/token-counter.ts +23 -0
- package/src/contracts/tool.ts +397 -0
- package/src/contracts/tracer.ts +219 -0
- package/src/contracts/trigger-store.ts +40 -0
- package/src/index.ts +23 -0
- package/src/types/agent-event-wire.ts +193 -0
- package/src/types/agent-event.ts +579 -0
- package/src/types/handoff.ts +111 -0
- package/src/types/index.ts +148 -0
- package/src/types/memory.ts +427 -0
- package/src/types/message.ts +174 -0
- package/src/types/run.ts +312 -0
- package/src/types/sensitivity.ts +35 -0
- package/src/types/session-scope.ts +18 -0
- package/src/types/stop-condition.ts +108 -0
- package/src/types/tool-call.ts +24 -0
- package/src/types/tool.ts +324 -0
- package/src/types/usage.ts +120 -0
- package/src/types/workflow-event.ts +132 -0
- package/src/utils/assert-never.ts +24 -0
- package/src/utils/async-context.ts +55 -0
- package/src/utils/binary-json.ts +425 -0
- package/src/utils/hash.ts +122 -0
- package/src/utils/index.ts +57 -0
- package/src/utils/streams.ts +233 -0
- package/src/utils/validation.ts +82 -0
|
@@ -13,6 +13,19 @@ import { SessionScope } from "../types/session-scope.js";
|
|
|
13
13
|
* pick its own physical layout (one big table, six tables, mixed) while
|
|
14
14
|
* preserving append-only semantics - soft-delete only.
|
|
15
15
|
*
|
|
16
|
+
* **Baseline vs full adapter (W-048).** This interface is the MINIMUM a
|
|
17
|
+
* third-party adapter must implement; `@graphorin/memory` accepts it and
|
|
18
|
+
* degrades gracefully (vector search, decay, consolidation, insights,
|
|
19
|
+
* graph expansion, conflict audit switch off where the surface is
|
|
20
|
+
* absent). Full feature parity with `@graphorin/store-sqlite` (asOf
|
|
21
|
+
* reads, vector KNN, decay signals, insights, entity graph, conflicts,
|
|
22
|
+
* consolidator state/DLQ) is described by `MemoryStoreAdapter` and the
|
|
23
|
+
* `*MemoryStoreExt` interfaces exported from the root of
|
|
24
|
+
* `@graphorin/memory`. Every Ext addition over the six tier namespaces
|
|
25
|
+
* is optional BY CONTRACT - a type test in `@graphorin/memory` pins
|
|
26
|
+
* `MemoryStore extends MemoryStoreAdapter`, so a core-only adapter can
|
|
27
|
+
* never stop compiling.
|
|
28
|
+
*
|
|
16
29
|
* @stable
|
|
17
30
|
*/
|
|
18
31
|
interface MemoryStore {
|
|
@@ -27,6 +40,28 @@ interface MemoryStore {
|
|
|
27
40
|
/** Cleanly close any underlying handles. Idempotent. */
|
|
28
41
|
close(): Promise<void>;
|
|
29
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Maintenance extension over {@link MemoryStore} (W-066), mirroring
|
|
45
|
+
* the `SessionStoreExt` precedent: capabilities the sqlite adapter
|
|
46
|
+
* guarantees but a custom `MemoryStore` is not obliged to implement.
|
|
47
|
+
* The base contract is unchanged - existing implementations keep
|
|
48
|
+
* compiling.
|
|
49
|
+
*
|
|
50
|
+
* @stable
|
|
51
|
+
*/
|
|
52
|
+
interface MemoryStoreExt extends MemoryStore {
|
|
53
|
+
/**
|
|
54
|
+
* Delete `memory_history` rows older than the given AGE in
|
|
55
|
+
* milliseconds. The argument is an AGE (the implementation computes
|
|
56
|
+
* `cutoff = now - olderThanMs`), never an epoch cutoff - passing an
|
|
57
|
+
* epoch value would compute a nonsense cutoff far in the past and
|
|
58
|
+
* silently prune nothing. Returns the number of rows removed.
|
|
59
|
+
* History grows by design (every supersede / quarantine transition
|
|
60
|
+
* appends) and `purge()` already scrubs sensitive text; this is the
|
|
61
|
+
* storage-cost hygiene lever - nothing prunes automatically.
|
|
62
|
+
*/
|
|
63
|
+
pruneHistory(olderThanMs: number): Promise<number>;
|
|
64
|
+
}
|
|
30
65
|
/** @stable */
|
|
31
66
|
interface WorkingMemoryStore {
|
|
32
67
|
list(scope: SessionScope): Promise<ReadonlyArray<Block>>;
|
|
@@ -67,6 +102,17 @@ interface SessionMemoryStore {
|
|
|
67
102
|
* don't implement it fall back to `list` + fabricated ids on the export path.
|
|
68
103
|
*/
|
|
69
104
|
listWithMetadata?(scope: SessionScope, opts?: SessionListOptions): Promise<ReadonlyArray<SessionMessageWithMetadata>>;
|
|
105
|
+
/**
|
|
106
|
+
* Full-text search over the scoped session messages.
|
|
107
|
+
*
|
|
108
|
+
* Query precedence (W-127): the POSITIONAL `query` parameter is
|
|
109
|
+
* authoritative; when the caller also sets `opts.query` (the field
|
|
110
|
+
* exists because {@link MemorySearchOptions} is shared with the
|
|
111
|
+
* option-object search surfaces), implementations MUST ignore it.
|
|
112
|
+
* The duplication is a known wart: narrowing `opts` to
|
|
113
|
+
* `Omit<MemorySearchOptions, 'query'>` is a candidate for the next
|
|
114
|
+
* major, not a change this line can make compatibly.
|
|
115
|
+
*/
|
|
70
116
|
search(scope: SessionScope, query: string, opts?: MemorySearchOptions): Promise<ReadonlyArray<MemoryHit>>;
|
|
71
117
|
}
|
|
72
118
|
/** @stable */
|
|
@@ -87,7 +133,18 @@ interface SemanticMemoryStore {
|
|
|
87
133
|
remember(fact: Fact): Promise<void>;
|
|
88
134
|
search(scope: SessionScope, opts: MemorySearchOptions): Promise<ReadonlyArray<MemoryHit<Fact>>>;
|
|
89
135
|
supersede(oldId: string, newFact: Fact, reason?: string): Promise<void>;
|
|
90
|
-
|
|
136
|
+
/**
|
|
137
|
+
* Soft-delete a fact. W-154: when `scope` is supplied, adapters that
|
|
138
|
+
* support tenant isolation MUST treat a fact outside the scope as a
|
|
139
|
+
* deterministic no-op (0 rows changed) - defense in depth so a
|
|
140
|
+
* leaked / cross-user id reaching a mutator cannot touch another
|
|
141
|
+
* user's memory. Omitting `scope` preserves the historical unscoped
|
|
142
|
+
* behaviour (trusted internal callers: consolidator, erasure
|
|
143
|
+
* cascades). The parameter is additive - existing adapter
|
|
144
|
+
* implementations with the narrower arity remain structurally
|
|
145
|
+
* compatible.
|
|
146
|
+
*/
|
|
147
|
+
forget(id: string, reason?: string, scope?: SessionScope): Promise<void>;
|
|
91
148
|
}
|
|
92
149
|
/** @stable */
|
|
93
150
|
interface ProceduralMemoryStore {
|
|
@@ -102,5 +159,5 @@ interface SharedMemoryStore {
|
|
|
102
159
|
listFor(agentId: string): Promise<ReadonlyArray<MemoryRecord>>;
|
|
103
160
|
}
|
|
104
161
|
//#endregion
|
|
105
|
-
export { EpisodicMemoryStore, MemoryStore, MessageRef, ProceduralMemoryStore, SemanticMemoryStore, SessionListOptions, SessionMemoryStore, SessionMessageWithMetadata, SharedMemoryStore, WorkingMemoryStore };
|
|
162
|
+
export { EpisodicMemoryStore, MemoryStore, MemoryStoreExt, MessageRef, ProceduralMemoryStore, SemanticMemoryStore, SessionListOptions, SessionMemoryStore, SessionMessageWithMetadata, SharedMemoryStore, WorkingMemoryStore };
|
|
106
163
|
//# sourceMappingURL=memory-store.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-store.d.ts","names":[],"sources":["../../src/contracts/memory-store.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAuBA
|
|
1
|
+
{"version":3,"file":"memory-store.d.ts","names":[],"sources":["../../src/contracts/memory-store.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAoCA;;;;;;;;;;AAuBA;AAeA;;;;;;;;;;;AAIgB,UA1CC,WAAA,CA0CD;EAA+C,SAAA,OAAA,EAzC3C,kBAyC2C;EAAO,SAAA,OAAA,EAxClD,kBAwCkD;EASrD,SAAA,QAAU,EAhDN,mBAgDM;EAaV,SAAA,QAAA,EA5DI,mBA4DsB;EAQ1B,SAAA,UAAA,EAnEM,qBAmEY;EACrB,SAAA,MAAA,EAnEK,iBAmEL;EAAuB;EAAkB,IAAA,EAAA,EAhE7C,OAgE6C,CAAA,IAAA,CAAA;EAAR;EACjC,KAAA,EAAA,EA/DH,OA+DG,CAAA,IAAA,CAAA;;;;;;;;;;;AAuBH,UA1EM,cAAA,SAAuB,WA0E7B,CAAA;EACgB;;;;AAI3B;AAQA;;;;;EAKqC,YAAA,CAAA,WAAA,EAAA,MAAA,CAAA,EAjFA,OAiFA,CAAA,MAAA,CAAA;;;AAAhC,UA7EY,kBAAA,CA6EZ;EACsB,IAAA,CAAA,KAAA,EA7Eb,YA6Ea,CAAA,EA7EE,OA6EF,CA7EU,aA6EV,CA7EwB,KA6ExB,CAAA,CAAA;EAAR,GAAA,CAAA,KAAA,EA5EN,YA4EM,EAAA,KAAA,EAAA,MAAA,CAAA,EA5EwB,OA4ExB,CA5EgC,KA4EhC,GAAA,IAAA,CAAA;EAAO,MAAA,CAAA,KAAA,EA3EV,YA2EU,EAAA,KAAA,EA3EW,KA2EX,CAAA,EA3EmB,OA2EnB,CAAA,IAAA,CAAA;EAIT,MAAA,CAAA,KAAA,EA9ED,YA8EoB,EAAA,KAAA,EAAA,MAAA,EAAA,MAAA,CAAA,EAAA,MAAA,CAAA,EA9E2B,OA8E3B,CAAA,IAAA,CAAA;;;;;;;;AAEsB,UAvEzC,UAAA,CAuEyC;EACtB,SAAA,SAAA,EAAA,MAAA;EAAwB,SAAA,QAAA,EAAA,MAAA;EAYd,SAAA,WAAA,EAAA,MAAA;;;AAI9C;;;;;;AAE6B,UA7EZ,0BAAA,CA6EY;EACU,SAAA,OAAA,EA7EnB,OA6EmB;EAAO,SAAA,SAAA,EAAA,MAAA;EAI7B,SAAA,QAAA,EAAA,MAAiB;EACW,SAAA,SAAA,EAAA,MAAA;;;AAET,UA7EnB,kBAAA,CA6EmB;EAAR,IAAA,CAAA,KAAA,EA5Ed,YA4Ec,EAAA,OAAA,EA5ES,OA4ET,CAAA,EA5EmB,OA4EnB,CA5E2B,UA4E3B,CAAA;EAAO,IAAA,CAAA,KAAA,EA3ErB,YA2EqB,EAAA,IAAA,CAAA,EA3EA,kBA2EA,CAAA,EA3EqB,OA2ErB,CA3E6B,aA2E7B,CA3E2C,OA2E3C,CAAA,CAAA;;;;;2BArExB,qBACA,qBACN,QAAQ,cAAc;;;;;;;;;;;;gBAahB,oCAEA,sBACN,QAAQ,cAAc;;;UAIV,kBAAA;;;;;;;UAQA,mBAAA;eACF,UAAU;gBAEd,oBACD,sBACL,QAAQ,cAAc,UAAU;mBAClB,QAAQ;;;UAIV,mBAAA;iBACA,OAAO;gBACR,oBAAoB,sBAAsB,QAAQ,cAAc,UAAU;oCACtD,wBAAwB;;;;;;;;;;;;8CAYd,eAAe;;;UAI5C,qBAAA;YACL,OAAO;cACL,eAAe,QAAQ,cAAc;uCACZ;;;UAItB,iBAAA;6CAC4B;6CACA;4BACjB,QAAQ,cAAc"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Sensitivity } from "../types/sensitivity.js";
|
|
2
|
-
import {
|
|
2
|
+
import { ToolCall } from "../types/tool-call.js";
|
|
3
|
+
import { Message, ReasoningContentMeta } from "../types/message.js";
|
|
3
4
|
import { AISpan } from "./tracer.js";
|
|
4
5
|
import { Usage } from "../types/usage.js";
|
|
5
6
|
import { ReasoningContract, ReasoningRetention } from "./reasoning-retention.js";
|
|
@@ -132,11 +133,12 @@ interface ProviderRequestMetadata {
|
|
|
132
133
|
*/
|
|
133
134
|
interface ProviderResponse {
|
|
134
135
|
readonly text?: string;
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
136
|
+
/**
|
|
137
|
+
* Tool invocations the model requested. W-127: reuses the canonical
|
|
138
|
+
* {@link ToolCall} (the inline shape here was structurally identical
|
|
139
|
+
* and only invited drift).
|
|
140
|
+
*/
|
|
141
|
+
readonly toolCalls?: ReadonlyArray<ToolCall>;
|
|
140
142
|
readonly usage: Usage;
|
|
141
143
|
readonly finishReason: FinishReason;
|
|
142
144
|
readonly providerMetadata?: Readonly<Record<string, unknown>>;
|
|
@@ -159,6 +161,18 @@ type ProviderEvent = {
|
|
|
159
161
|
} | {
|
|
160
162
|
readonly type: 'reasoning-delta';
|
|
161
163
|
readonly delta: string;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Closes the current reasoning block (W-024). Deltas stay textual;
|
|
167
|
+
* this terminator carries the provider's opaque round-trip metadata
|
|
168
|
+
* (e.g. the Anthropic thinking-block `signature`, or `data` for a
|
|
169
|
+
* redacted block) so multi-step tool use with extended thinking can
|
|
170
|
+
* replay the block byte-equal on the next request. Adapters without
|
|
171
|
+
* per-block structure simply never emit it - consumers fall back to
|
|
172
|
+
* collapsing the deltas.
|
|
173
|
+
*/ | {
|
|
174
|
+
readonly type: 'reasoning-end';
|
|
175
|
+
readonly meta?: ReasoningContentMeta;
|
|
162
176
|
} | {
|
|
163
177
|
readonly type: 'text-delta';
|
|
164
178
|
readonly delta: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.d.ts","names":[],"sources":["../../src/contracts/provider.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"provider.d.ts","names":[],"sources":["../../src/contracts/provider.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;AAiBA;;;;;;;;AAYoB,UAZH,QAAA,CAYG;EAAkB,SAAA,IAAA,EAAA,MAAA;EAOQ,SAAA,OAAA,EAAA,MAAA;EAAd,SAAA,YAAA,EAhBP,oBAgBO;EAAa;EAQ5B,MAAA,CAAA,GAAA,EArBH,eAqBuB,CAAA,EArBL,aA0CD,CA1Ce,aA0CE,CAAA;EAgB/B;EAUA,QAAA,CAAA,GAAA,EAjED,eAiEgB,CAAA,EAjEE,OAiEF,CAjEU,gBAiEV,CAAA;EACG;EAAd,WAAA,EAAA,GAAA,EA/DD,eA+DC,CAAA,EA/DiB,OA+DjB,CAAA,MAAA,CAAA;EACY;;;;;EAOK,SAAA,kBAAA,CAAA,EAhEN,aAgEM,CAhEQ,WAgER,CAAA;;;;;;;AA0BrB,UAlFA,oBAAA,CAkFuB;EAavB,SAAA,SAAA,EAAgB,OAAA;EAOI,SAAA,WAAA,EAAA,OAAA;EAAd,SAAA,iBAAA,EAAA,OAAA;EACL,SAAA,UAAA,EAAA,OAAA;EACO,SAAA,gBAAA,EAAA,OAAA;EACc,SAAA,SAAA,EAAA,OAAA;EAAT;EAAQ,SAAA,aAAA,EAAA,MAAA;EAQ1B;EAcA,SAAA,SAAa,EAAA,MAAA;EAC+B;;;;;;;AA8BxD;AAYA;AAOA;EAgBiB,SAAA,iBAAc,CAAA,EA5KA,iBA4KA;;;;;;;;AA6B/B;AAWA;AAQA;AAeA;AAaA;;;AAEK,UA1OY,mBAAA,CA0OZ;EAAkB,SAAA,WAAA,EAAA,MAAA,GAAA,MAAA;;;;;;;;UAhON,eAAA;qBACI,cAAc;mBAChB,cAAc;wBACT;wBACA;;;;oBAIJ;6BACS,SAAS;yBACb;;;;;;;wBAAmB;sBAQtB;;;;;;;;;gCASU;;;;;;;UAQf,uBAAA;;;;;;;;;;;;UAaA,gBAAA;;;;;;;uBAOM,cAAc;kBACnB;yBACO;8BACK,SAAS;;;;;;;KAQ3B,YAAA;;;;;;;KAcA,aAAA;;qBAC4C;;;;;;;;;;;;;;;kBAWF;;;;;;;;;;;;;;;;;;;iBASiB;;;;;;;yBAEjB;kBAA8B;;;kBACtC;;;;;;;UAO7B,gBAAA;;;;;;;;;;;UAYA,aAAA;iBACA;;;;;KAML,iBAAA;;;;;;;UAgBK,cAAA;;;wBAGO,SAAS;;;;;;;0BAOP,SAAS;;;;;;;;sBAQb,cAAc;;;;;;;;;;UAWnB,qBAAA;;;;;;;;;;KAWL,UAAA;;;;;;;;;UAQK,UAAA;;;wBAGO,SAAS;;;;;;;;;;;KAYrB,kBAAA,UAA4B,aAAa;;;;;;;;;;;;KAazC,yBAAA,iBACG,cAAc,wBACxB"}
|
|
@@ -124,8 +124,16 @@ interface SessionStoreExt extends SessionStore {
|
|
|
124
124
|
* workflow-run attachments, and audit entries (RP-6) - **plus the
|
|
125
125
|
* session's content**: its `session_messages` rows (with their FTS and
|
|
126
126
|
* vector index entries) and any episodes scoped to the session
|
|
127
|
-
* (store-01).
|
|
128
|
-
*
|
|
127
|
+
* (store-01). The cascade also erases the checkpoints of suspended
|
|
128
|
+
* runs (W-005): `workflow_checkpoints` / `workflow_pending_writes`
|
|
129
|
+
* rows for every thread linked to the session, whether through the
|
|
130
|
+
* workflow-run attachment mapping or through the `sessionId`
|
|
131
|
+
* checkpoint metadata the agent runtime stamps on HITL suspends -
|
|
132
|
+
* those snapshots embed the full conversation. After this call the
|
|
133
|
+
* conversation is no longer retrievable through `memory.session.*`
|
|
134
|
+
* search surfaces nor resumable from its checkpoints. A no-op for an
|
|
135
|
+
* unknown id. Custom implementations must honour the same contract in
|
|
136
|
+
* full - leaving any of these surfaces behind defeats erasure.
|
|
129
137
|
*/
|
|
130
138
|
deleteSession(sessionId: string): Promise<void>;
|
|
131
139
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-store.d.ts","names":[],"sources":["../../src/contracts/session-store.ts"],"sourcesContent":[],"mappings":";;;;;;;AAUA;AAmBA;AAcA;AAqBA;AAmBA;AAC0B,UA1ET,eAAA,CA0ES;EAAkB,SAAA,EAAA,EAAA,MAAA;EACH,SAAA,MAAA,EAAA,MAAA;EAAR,SAAA,OAAA,EAAA,MAAA;EAEjB,SAAA,KAAA,CAAA,EAAA,MAAA;EAAL,SAAA,SAAA,EAAA,MAAA;EACgB,SAAA,SAAA,CAAA,EAAA,MAAA;EAAd,SAAA,QAAA,CAAA,EAAA,MAAA;EAAR,SAAA,IAAA,CAAA,EAtEa,aAsEb,CAAA,MAAA,CAAA;;;;;;;;;;AAQsC,UAnE1B,kBAAA,CAmE0B;EAAgB,SAAA,EAAA,EAAA,MAAA;EACF,SAAA,WAAA,EAAA,MAAA;EAAd,SAAA,YAAA,EAAA,MAAA;EAAR,SAAA,SAAA,CAAA,EAAA,MAAA;EAEV,SAAA,IAAA,CAAA,EAjEP,aAiEO,CAAA,MAAA,CAAA;;;;;;AAezB;;AAIsC,UA3ErB,kBAAA,CA2EqB;EAAd,SAAA,SAAA,EAAA,MAAA;EAAR,SAAA,UAAA,EAAA,MAAA;EAMJ,SAAA,QAAA,EAAA,MAAA;EACP,SAAA,UAAA,EAAA,MAAA;EAEqB,SAAA,MAAA,EAAA,SAAA,GAAA,WAAA,GAAA,WAAA,GAAA,QAAA;;;;;;;;;;;;;;;UA/DT,iBAAA;;;;;;;;;;sBAUK,SAAS;;;;;;;;UASd,YAAA;0BACS,kBAAkB;iCACX,QAAQ;sBAE9B,KAAK,sCACX,QAAQ,cAAc;0CACe,QAAQ,mBAAmB;qDAChB;uBAE9B,qBAAqB;mDACO;iCAClB,QAAQ;2CAEE,gBAAgB;mCACxB,QAAQ,cAAc;yBAEhC,qBAAqB;uCACP,QAAQ,cAAc;;;;;;;;;;;;;UAc5C,eAAA,SAAwB;;gCAET;;gBAEhB,QAAQ,cAAc;;2FAM1B,+BACP;;0BAEqB,oBAAoB;;;;MAKzC,QAAQ,cAAc;;4CAEiB
|
|
1
|
+
{"version":3,"file":"session-store.d.ts","names":[],"sources":["../../src/contracts/session-store.ts"],"sourcesContent":[],"mappings":";;;;;;;AAUA;AAmBA;AAcA;AAqBA;AAmBA;AAC0B,UA1ET,eAAA,CA0ES;EAAkB,SAAA,EAAA,EAAA,MAAA;EACH,SAAA,MAAA,EAAA,MAAA;EAAR,SAAA,OAAA,EAAA,MAAA;EAEjB,SAAA,KAAA,CAAA,EAAA,MAAA;EAAL,SAAA,SAAA,EAAA,MAAA;EACgB,SAAA,SAAA,CAAA,EAAA,MAAA;EAAd,SAAA,QAAA,CAAA,EAAA,MAAA;EAAR,SAAA,IAAA,CAAA,EAtEa,aAsEb,CAAA,MAAA,CAAA;;;;;;;;;;AAQsC,UAnE1B,kBAAA,CAmE0B;EAAgB,SAAA,EAAA,EAAA,MAAA;EACF,SAAA,WAAA,EAAA,MAAA;EAAd,SAAA,YAAA,EAAA,MAAA;EAAR,SAAA,SAAA,CAAA,EAAA,MAAA;EAEV,SAAA,IAAA,CAAA,EAjEP,aAiEO,CAAA,MAAA,CAAA;;;;;;AAezB;;AAIsC,UA3ErB,kBAAA,CA2EqB;EAAd,SAAA,SAAA,EAAA,MAAA;EAAR,SAAA,UAAA,EAAA,MAAA;EAMJ,SAAA,QAAA,EAAA,MAAA;EACP,SAAA,UAAA,EAAA,MAAA;EAEqB,SAAA,MAAA,EAAA,SAAA,GAAA,WAAA,GAAA,WAAA,GAAA,QAAA;;;;;;;;;;;;;;;UA/DT,iBAAA;;;;;;;;;;sBAUK,SAAS;;;;;;;;UASd,YAAA;0BACS,kBAAkB;iCACX,QAAQ;sBAE9B,KAAK,sCACX,QAAQ,cAAc;0CACe,QAAQ,mBAAmB;qDAChB;uBAE9B,qBAAqB;mDACO;iCAClB,QAAQ;2CAEE,gBAAgB;mCACxB,QAAQ,cAAc;yBAEhC,qBAAqB;uCACP,QAAQ,cAAc;;;;;;;;;;;;;UAc5C,eAAA,SAAwB;;gCAET;;gBAEhB,QAAQ,cAAc;;2FAM1B,+BACP;;0BAEqB,oBAAoB;;;;MAKzC,QAAQ,cAAc;;4CAEiB;;;;;;;;;;;;;;;;;oCAiBR;;;;;;;;;;MAU9B"}
|
package/dist/contracts/tool.d.ts
CHANGED
|
@@ -94,6 +94,12 @@ interface Tool<TInput = unknown, TOutput = unknown, TDeps = unknown> {
|
|
|
94
94
|
* the input-token cost bounded for installations with dozens of
|
|
95
95
|
* MCP-derived tools.
|
|
96
96
|
*
|
|
97
|
+
* Naming note (W-127): the snake_case is DELIBERATE - this field
|
|
98
|
+
* mirrors the wire-level `defer_loading` flag of the Anthropic
|
|
99
|
+
* tool-use surface one-to-one, so grep and serialized payloads
|
|
100
|
+
* match. It is the only snake_case field on `Tool` by design, not
|
|
101
|
+
* an oversight.
|
|
102
|
+
*
|
|
97
103
|
* @default `false`
|
|
98
104
|
*/
|
|
99
105
|
readonly defer_loading?: boolean;
|
|
@@ -159,6 +165,24 @@ interface Tool<TInput = unknown, TOutput = unknown, TDeps = unknown> {
|
|
|
159
165
|
*/
|
|
160
166
|
execute(input: TInput, ctx: ToolExecutionContext<TDeps>): Promise<TOutput | ToolReturn<TOutput> | undefined>;
|
|
161
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* Existentially-typed {@link Tool} for collection seams (W-100).
|
|
170
|
+
*
|
|
171
|
+
* `Tool` is invariant in `TInput` (the `needsApproval` /
|
|
172
|
+
* `idempotencyKey` predicate properties are contravariant in it), so a
|
|
173
|
+
* concretely-typed `Tool<{ q: string }, number, D>` is NOT assignable
|
|
174
|
+
* to `Tool<unknown, unknown, D>` - which forced `as unknown as Tool`
|
|
175
|
+
* casts wherever tools are collected. `AnyTool` erases `TInput` /
|
|
176
|
+
* `TOutput` existentially, following the `HandoffEntry` precedent in
|
|
177
|
+
* `@graphorin/agent`.
|
|
178
|
+
*
|
|
179
|
+
* Use it on COLLECTION seams (`createAgent({ tools })`, executor
|
|
180
|
+
* options, registries); implement tools against the typed `Tool` via
|
|
181
|
+
* the `tool({...})` factory.
|
|
182
|
+
*
|
|
183
|
+
* @stable
|
|
184
|
+
*/
|
|
185
|
+
type AnyTool<TDeps = unknown> = Tool<any, any, TDeps>;
|
|
162
186
|
/**
|
|
163
187
|
* Worked example for a `Tool`. Type-parameterized on the same generics
|
|
164
188
|
* as `Tool`, so a `ToolExample` for `Tool<{ q: string }, { hits: T[] }>`
|
|
@@ -197,6 +221,15 @@ interface ResolvedTool<TInput = unknown, TOutput = unknown, TDeps = unknown> ext
|
|
|
197
221
|
* @stable
|
|
198
222
|
*/
|
|
199
223
|
interface ToolReturn<TOutput = unknown> {
|
|
224
|
+
/**
|
|
225
|
+
* W-115: envelope brand set by the {@link toolReturn} factory.
|
|
226
|
+
* `Symbol.for`, so duplicate package copies agree. Prefer branding:
|
|
227
|
+
* the structural fallback in the executor is deliberately narrow
|
|
228
|
+
* (own keys within `{output, contentParts, taint}`), and plain data
|
|
229
|
+
* that happens to be exactly `{ output: X }` is ambiguous by
|
|
230
|
+
* construction - brand it (or rename the field) to disambiguate.
|
|
231
|
+
*/
|
|
232
|
+
readonly [TOOL_RETURN_BRAND]?: true;
|
|
200
233
|
readonly output: TOutput;
|
|
201
234
|
readonly contentParts?: ReadonlyArray<MessageContent>;
|
|
202
235
|
/**
|
|
@@ -213,6 +246,47 @@ interface ToolReturn<TOutput = unknown> {
|
|
|
213
246
|
readonly sourceKind?: string;
|
|
214
247
|
};
|
|
215
248
|
}
|
|
249
|
+
/**
|
|
250
|
+
* W-115: cross-realm brand for the {@link ToolReturn} envelope
|
|
251
|
+
* (`SECRET_VALUE_BRAND` precedent - `Symbol.for` survives duplicate
|
|
252
|
+
* package copies).
|
|
253
|
+
*
|
|
254
|
+
* @stable
|
|
255
|
+
*/
|
|
256
|
+
declare const TOOL_RETURN_BRAND: unique symbol;
|
|
257
|
+
/**
|
|
258
|
+
* W-115: build a BRANDED {@link ToolReturn} envelope. The executor
|
|
259
|
+
* unwraps branded envelopes unconditionally; unbranded objects fall to
|
|
260
|
+
* a deliberately narrow structural sniff (own keys within
|
|
261
|
+
* `{output, contentParts, taint}`), so a tool legitimately returning
|
|
262
|
+
* `{ output, exitCode, stderr }` is no longer silently stripped to its
|
|
263
|
+
* `output` field.
|
|
264
|
+
*
|
|
265
|
+
* @stable
|
|
266
|
+
*/
|
|
267
|
+
declare function toolReturn<TOutput>(fields: {
|
|
268
|
+
readonly output: TOutput;
|
|
269
|
+
readonly contentParts?: ReadonlyArray<MessageContent>;
|
|
270
|
+
readonly taint?: ToolReturn<TOutput>['taint'];
|
|
271
|
+
}): ToolReturn<TOutput>;
|
|
272
|
+
/**
|
|
273
|
+
* W-115: the ONE guard for the ToolReturn envelope (the executor and
|
|
274
|
+
* the registry example-normalizer both consume it). Brand first; the
|
|
275
|
+
* structural fallback accepts only objects whose OWN enumerable keys
|
|
276
|
+
* all belong to the canonical envelope shape - `{output, exitCode}`
|
|
277
|
+
* style process results pass through intact.
|
|
278
|
+
*
|
|
279
|
+
* @stable
|
|
280
|
+
*/
|
|
281
|
+
declare function isToolReturnEnvelope<TOutput = unknown>(value: unknown): value is ToolReturn<TOutput>;
|
|
282
|
+
/**
|
|
283
|
+
* W-115: `true` when {@link isToolReturnEnvelope} matched WITHOUT the
|
|
284
|
+
* brand - observability for the future deprecation of the structural
|
|
285
|
+
* sniff.
|
|
286
|
+
*
|
|
287
|
+
* @stable
|
|
288
|
+
*/
|
|
289
|
+
declare function isUnbrandedToolReturn(value: unknown): boolean;
|
|
216
290
|
/**
|
|
217
291
|
* Per-call execution context handed to `Tool.execute(...)`. Carries the
|
|
218
292
|
* stable `toolCallId`, the parent `RunContext`, an `AbortSignal` tied to
|
|
@@ -273,5 +347,5 @@ interface ToolSecretsAccessor {
|
|
|
273
347
|
}): Promise<SecretValue | null>;
|
|
274
348
|
}
|
|
275
349
|
//#endregion
|
|
276
|
-
export { ResolvedTool, Tool, ToolExample, ToolExecutionContext, ToolReturn, ToolSecretsAccessor };
|
|
350
|
+
export { AnyTool, ResolvedTool, TOOL_RETURN_BRAND, Tool, ToolExample, ToolExecutionContext, ToolReturn, ToolSecretsAccessor, isToolReturnEnvelope, isUnbrandedToolReturn, toolReturn };
|
|
277
351
|
//# sourceMappingURL=tool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.d.ts","names":[],"sources":["../../src/contracts/tool.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;AAkCA;;;;;;;;;;;;;AAmD6B,UAnDZ,IAmDY,CAAA,SAAA,OAAA,EAAA,UAAA,OAAA,EAAA,QAAA,OAAA,CAAA,CAAA;EAEI,SAAA,IAAA,EAAA,MAAA;
|
|
1
|
+
{"version":3,"file":"tool.d.ts","names":[],"sources":["../../src/contracts/tool.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;AAkCA;;;;;;;;;;;;;AAmD6B,UAnDZ,IAmDY,CAAA,SAAA,OAAA,EAAA,UAAA,OAAA,EAAA,QAAA,OAAA,CAAA,CAAA;EAEI,SAAA,IAAA,EAAA,MAAA;EAmCD,SAAA,WAAA,EAAA,MAAA;EAOgB,SAAA,WAAA,EA5FxB,aA4FwB,CA5FV,MA4FU,CAAA;EAAQ,SAAA,YAAA,CAAA,EA3F9B,aA2F8B,CA3FhB,OA2FgB,CAAA;EAApB;;;;;EAuB3B,SAAA,aAAA,CAAA,EAAA,OAAA,GAAA,CAAA,CAAA,KAAA,EA1GM,MA0GN,EAAA,GAAA,EA1GmB,oBA0GnB,CA1GwC,KA0GxC,CAAA,EAAA,GAAA,OAAA,GA1G6D,OA0G7D,CAAA,OAAA,CAAA,CAAA;EACO;;;;;;;;EAyBO,SAAA,aAAA,CAAA,EA3HI,aA2HJ;EAAlB;EAAO,SAAA,IAAA,CAAA,EAzHM,aAyHN,CAAA,MAAA,CAAA;EAqBA;AASZ;;;;;;EAciB,SAAA,aAAY,CAAA,EAAA,UAAA,GAAA,YAAA;EACd;;;;;EAIe,SAAA,cAAA,CAAA,EA5JF,aA4JE,CAAA,MAAA,CAAA;EAIA;;;;AAU9B;EASY,SAAA,WAAA,CAAA,EAnL6B,WAmL7B;EACO;;;;AAwBnB;AAYA;;EAEwC,SAAA,eAAA,CAAA,EA5MX,eA4MW;EAAd;EACI,SAAA,mBAAA,CAAA,EA3MG,yBA2MH;EAAX;;;;AAmBnB;AAmBA;AAgBA;EAEkC,SAAA,UAAA,CAAA,EAAA,OAAA;EAAX;;;;;;;AAmCvB;;;;;;;;;;;;;;;;;;;gCAnQgC;;;;;;;sBAOV,cAAc,YAAY,QAAQ;;;;;;;;;;;;;;6BAc3B;;;;;;;oCAQlB,aACF,qBAAqB,oBACd;;;;;;;;;;;;;;4BAcY,YAAY;;;;;;;;iBAS7B,aACF,qBAAqB,SACzB,QAAQ,UAAU,WAAW;;;;;;;;;;;;;;;;;;;KAqBtB,2BAA2B,eAAe;;;;;;;;UASrC;kBACC;mBACC,UAAU,WAAW;;;;;;;;;;;UAYvB,2EACP,KAAK,QAAQ,SAAS;yBACP;qBACJ;;8BAES;;;;8BAIA,YAAY;;;;;;;;;UAUzB;;;;;;;;;YASL,iBAAA;mBACO;0BACO,cAAc;;;;;;;;;;;;;;;;;;;;;;cAuB3B;;;;;;;;;;;iBAYG;mBACG;0BACO,cAAc;mBACrB,WAAW;IAC1B,WAAW;;;;;;;;;;iBAkBC,kEAEJ,WAAW;;;;;;;;iBAiBP,qBAAA;;;;;;;;;;UAgBC;;uBAEM,WAAW;mBACf;mBACA;mBACA;;;;;;oBAMC;;;;;;;;;;;;;uBAaG;;;;;;;;;;;;UAaN,mBAAA;;;;;;;;;MAUZ,QAV+B,WAAA;;;MAc/B,QAJO,WAAA"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
//#region src/contracts/tool.ts
|
|
2
|
+
/**
|
|
3
|
+
* W-115: cross-realm brand for the {@link ToolReturn} envelope
|
|
4
|
+
* (`SECRET_VALUE_BRAND` precedent - `Symbol.for` survives duplicate
|
|
5
|
+
* package copies).
|
|
6
|
+
*
|
|
7
|
+
* @stable
|
|
8
|
+
*/
|
|
9
|
+
const TOOL_RETURN_BRAND = Symbol.for("graphorin.ToolReturn");
|
|
10
|
+
/**
|
|
11
|
+
* W-115: build a BRANDED {@link ToolReturn} envelope. The executor
|
|
12
|
+
* unwraps branded envelopes unconditionally; unbranded objects fall to
|
|
13
|
+
* a deliberately narrow structural sniff (own keys within
|
|
14
|
+
* `{output, contentParts, taint}`), so a tool legitimately returning
|
|
15
|
+
* `{ output, exitCode, stderr }` is no longer silently stripped to its
|
|
16
|
+
* `output` field.
|
|
17
|
+
*
|
|
18
|
+
* @stable
|
|
19
|
+
*/
|
|
20
|
+
function toolReturn(fields) {
|
|
21
|
+
return {
|
|
22
|
+
[TOOL_RETURN_BRAND]: true,
|
|
23
|
+
output: fields.output,
|
|
24
|
+
...fields.contentParts !== void 0 ? { contentParts: fields.contentParts } : {},
|
|
25
|
+
...fields.taint !== void 0 ? { taint: fields.taint } : {}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* W-115: the ONE guard for the ToolReturn envelope (the executor and
|
|
30
|
+
* the registry example-normalizer both consume it). Brand first; the
|
|
31
|
+
* structural fallback accepts only objects whose OWN enumerable keys
|
|
32
|
+
* all belong to the canonical envelope shape - `{output, exitCode}`
|
|
33
|
+
* style process results pass through intact.
|
|
34
|
+
*
|
|
35
|
+
* @stable
|
|
36
|
+
*/
|
|
37
|
+
function isToolReturnEnvelope(value) {
|
|
38
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
39
|
+
if (value[TOOL_RETURN_BRAND] === true) return true;
|
|
40
|
+
if (!Object.hasOwn(value, "output")) return false;
|
|
41
|
+
for (const key of Object.keys(value)) if (key !== "output" && key !== "contentParts" && key !== "taint") return false;
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* W-115: `true` when {@link isToolReturnEnvelope} matched WITHOUT the
|
|
46
|
+
* brand - observability for the future deprecation of the structural
|
|
47
|
+
* sniff.
|
|
48
|
+
*
|
|
49
|
+
* @stable
|
|
50
|
+
*/
|
|
51
|
+
function isUnbrandedToolReturn(value) {
|
|
52
|
+
return isToolReturnEnvelope(value) && value[TOOL_RETURN_BRAND] !== true;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
//#endregion
|
|
56
|
+
export { TOOL_RETURN_BRAND, isToolReturnEnvelope, isUnbrandedToolReturn, toolReturn };
|
|
57
|
+
//# sourceMappingURL=tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool.js","names":["TOOL_RETURN_BRAND: unique symbol"],"sources":["../../src/contracts/tool.ts"],"sourcesContent":["import type { MessageContent } from '../types/message.js';\nimport type { RunContext } from '../types/run.js';\nimport type {\n ContentChunk,\n InboundSanitizationPolicy,\n MemoryGuardTier,\n SandboxPolicy,\n SideEffectClass,\n ToolSource,\n ToolTrustClass,\n TruncationStrategy,\n} from '../types/tool.js';\nimport type { ZodLikeSchema } from '../utils/validation.js';\nimport type { Logger } from './logger.js';\nimport type { ModelHint, ModelSpec } from './preferred-model.js';\nimport type { Tracer } from './tracer.js';\n\n/**\n * Pluggable function call exposed to an LLM. Concrete `Tool` instances\n * are produced by the `tool({...})` factory in `@graphorin/tools` and\n * by the MCP / Skills loaders. The interface lives in core because every\n * package above the persistence layer (agent runtime, workflow engine,\n * server, sessions, observability, …) carries `Tool[]` references on\n * its public surface.\n *\n * The interface is intentionally minimal - extension fields covered by\n * later phases (per-tool `secretsAllowed` ACL, inbound sanitization\n * policy, result truncation strategy, streaming hint, …) are added\n * **additively** by their owning packages so that v0.1 consumers can\n * type their tool list against `Tool<...>` today without having to\n * worry about future fields.\n *\n * @stable\n */\nexport interface Tool<TInput = unknown, TOutput = unknown, TDeps = unknown> {\n readonly name: string;\n readonly description: string;\n readonly inputSchema: ZodLikeSchema<TInput>;\n readonly outputSchema?: ZodLikeSchema<TOutput>;\n /**\n * Either a static boolean or a predicate consulted at runtime against\n * the realized input. `true` means the runtime suspends the run with a\n * `tool.approval.requested` event before the tool executes.\n */\n readonly needsApproval?:\n | boolean\n | ((input: TInput, ctx: ToolExecutionContext<TDeps>) => boolean | Promise<boolean>);\n /**\n * Sandbox isolation level. Defaults are picked by\n * `@graphorin/security`. ADVISORY in the default agent build (AG-18):\n * inline `config.tools` closures cannot be serialised out-of-process,\n * so the resolved policy is surfaced on the `tool.execute` span /\n * audit but the tool runs in-process. Real isolation applies to\n * module-loadable (skill / MCP) tools.\n */\n readonly sandboxPolicy?: SandboxPolicy;\n /** Free-form labels surfaced to operators and to the model. */\n readonly tags?: ReadonlyArray<string>;\n /**\n * Sequential execution mode hints. Tools tagged `'sequential'` are\n * never executed in parallel with each other; the executor serializes\n * them inside the per-step batch.\n *\n * @default `'parallel'`\n */\n readonly executionMode?: 'parallel' | 'sequential';\n /**\n * Per-tool secrets ACL. Tool execution is wrapped in a scope where\n * `ctx.secrets.require(...)` only resolves keys present here.\n * Empty / undefined means the tool may not request any secret.\n */\n readonly secretsAllowed?: ReadonlyArray<string>;\n /**\n * Sensitivity ceiling of the tool's input + output payload. Used by\n * the redaction validator to decide whether the result may flow to a\n * given sink (provider / exporter).\n */\n readonly sensitivity?: import('../types/sensitivity.js').Sensitivity;\n /**\n * Memory-modification guard tier (DEC-153). ACTIVE when the agent is\n * created with `memory` wired (SDF-1): the runtime binds a scope-aware\n * region reader over working memory and the executor snapshots/verifies\n * the region around guarded calls. Without `memory` the guard is\n * skipped and the agent emits a one-time WARN.\n */\n readonly memoryGuardTier?: MemoryGuardTier;\n /** Inbound prompt-injection sanitization policy. */\n readonly inboundSanitization?: InboundSanitizationPolicy;\n /**\n * When `true`, an inbound-sanitization hit returns `ToolError({ kind:\n * 'inbound_sanitization_blocked' })` instead of forwarding the\n * (sanitized) result. Intended for regulated deployments.\n *\n * @default `false`\n */\n readonly failClosed?: boolean;\n /**\n * Defer the tool from the per-step catalogue until the model invokes\n * the built-in `tool_search` to look it up. Tools with deferred\n * loading are not advertised to the model on every step, which keeps\n * the input-token cost bounded for installations with dozens of\n * MCP-derived tools.\n *\n * Naming note (W-127): the snake_case is DELIBERATE - this field\n * mirrors the wire-level `defer_loading` flag of the Anthropic\n * tool-use surface one-to-one, so grep and serialized payloads\n * match. It is the only snake_case field on `Tool` by design, not\n * an oversight.\n *\n * @default `false`\n */\n readonly defer_loading?: boolean;\n /**\n * Maximum number of tokens the assembled tool result may carry into\n * the conversation history. `0` disables the cap (logs a one-time\n * WARN at registration). Counted against text-shaped output and\n * text-shaped `contentParts` entries; non-text parts pass through.\n *\n * @default `16384`\n */\n readonly maxResultTokens?: number;\n /** Truncation strategy applied when `maxResultTokens` is exceeded. */\n readonly truncationStrategy?: TruncationStrategy;\n /**\n * Worked examples shown to the model alongside the tool's\n * description. Bounded `[1, 5]` - overflow emits a one-time WARN at\n * registration. Each example's `input` and `output` is validated\n * against the tool's `inputSchema` / `outputSchema`.\n */\n readonly examples?: ReadonlyArray<ToolExample<TInput, TOutput>>;\n /**\n * Render examples eagerly (every step) regardless of\n * `defer_loading`. When undefined the runtime applies the auto-rule:\n * `defer_loading: true` ⇒ `false`; `defer_loading: false` ⇒ `true`;\n * neither ⇒ `undefined` (the agent runtime decides at assembly time).\n */\n readonly examplesEagerlyRendered?: boolean;\n /**\n * REQUIRED side-effect classification. v0.1 transition mode emits a\n * one-time WARN per tool name on missing classification and applies\n * the conservative deferred default `'side-effecting'`; v0.2 may\n * promote the WARN to a registration error.\n */\n readonly sideEffectClass?: SideEffectClass;\n /**\n * Optional callback returning a deterministic dedup key per\n * `(input, ctx)` tuple. REQUIRED-by-WARN for `'side-effecting'` /\n * `'external-stateful'` tools. The framework does not validate\n * determinism - that is the operator's contract.\n */\n readonly idempotencyKey?: (\n input: TInput,\n ctx: ToolExecutionContext<TDeps>,\n ) => string | Promise<string>;\n /**\n * Opt-in flag for streaming-tool execution. The `?: true` typing\n * rejects `streamingHint: false` on purpose - absence is the\n * canonical \"non-streaming\" signal preserving v0.1 behaviour. When\n * `true`, `Tool.execute(...)` may call `ctx.streamContent(...)` /\n * `ctx.reportProgress(...)` and may return `Promise<void>`.\n */\n readonly streamingHint?: true;\n /**\n * Per-tool author-time model hint. Either a cost-tier vocabulary\n * literal (`'fast' | 'balanced' | 'smart'`) OR an explicit\n * `ModelSpec` that always wins over the agent-side tier mapping.\n */\n readonly preferredModel?: ModelHint | ModelSpec;\n /**\n * Execute the tool. Concrete implementations may return either a raw\n * `TOutput` or a `ToolReturn<TOutput>` envelope when extra content\n * parts (images, files, …) need to be appended to the conversation.\n * Streaming-hint tools may also return `void` once the per-chunk\n * buffer has been populated.\n */\n execute(\n input: TInput,\n ctx: ToolExecutionContext<TDeps>,\n ): Promise<TOutput | ToolReturn<TOutput> | undefined>;\n}\n\n/**\n * Existentially-typed {@link Tool} for collection seams (W-100).\n *\n * `Tool` is invariant in `TInput` (the `needsApproval` /\n * `idempotencyKey` predicate properties are contravariant in it), so a\n * concretely-typed `Tool<{ q: string }, number, D>` is NOT assignable\n * to `Tool<unknown, unknown, D>` - which forced `as unknown as Tool`\n * casts wherever tools are collected. `AnyTool` erases `TInput` /\n * `TOutput` existentially, following the `HandoffEntry` precedent in\n * `@graphorin/agent`.\n *\n * Use it on COLLECTION seams (`createAgent({ tools })`, executor\n * options, registries); implement tools against the typed `Tool` via\n * the `tool({...})` factory.\n *\n * @stable\n */\n// biome-ignore lint/suspicious/noExplicitAny: existential TInput/TOutput (see above)\nexport type AnyTool<TDeps = unknown> = Tool<any, any, TDeps>;\n\n/**\n * Worked example for a `Tool`. Type-parameterized on the same generics\n * as `Tool`, so a `ToolExample` for `Tool<{ q: string }, { hits: T[] }>`\n * cannot specify an `input` shape that does not match.\n *\n * @stable\n */\nexport interface ToolExample<TInput = unknown, TOutput = unknown> {\n readonly input: TInput;\n readonly output: TOutput | ToolReturn<TOutput>;\n readonly comment?: string;\n}\n\n/**\n * Resolved record returned by the `ToolRegistry` getter. Carries every\n * non-public registration-time field downstream layers consume\n * (sanitization, audit, retrieval, side-effect classification,\n * collision resolution, …) so consumers do not have to recompute it.\n *\n * @stable\n */\nexport interface ResolvedTool<TInput = unknown, TOutput = unknown, TDeps = unknown>\n extends Tool<TInput, TOutput, TDeps> {\n readonly __trustClass: ToolTrustClass;\n readonly __source: ToolSource;\n readonly __effectiveDeferLoading: boolean;\n readonly __sideEffectClass: SideEffectClass;\n readonly __hasIdempotencyKey: boolean;\n readonly __streamingHint: boolean;\n readonly __exampleCount: number;\n readonly __preferredModel?: ModelHint | ModelSpec;\n}\n\n/**\n * Optional return envelope: pairs a typed `output` (passed to the model)\n * with extra `contentParts` that are appended verbatim to the\n * conversation (images, files, audio, …).\n *\n * @stable\n */\nexport interface ToolReturn<TOutput = unknown> {\n /**\n * W-115: envelope brand set by the {@link toolReturn} factory.\n * `Symbol.for`, so duplicate package copies agree. Prefer branding:\n * the structural fallback in the executor is deliberately narrow\n * (own keys within `{output, contentParts, taint}`), and plain data\n * that happens to be exactly `{ output: X }` is ambiguous by\n * construction - brand it (or rename the field) to disambiguate.\n */\n readonly [TOOL_RETURN_BRAND]?: true;\n readonly output: TOutput;\n readonly contentParts?: ReadonlyArray<MessageContent>;\n /**\n * C6: per-result taint override the data-flow ledger honours when\n * recording this output. Lets a FIRST-PARTY tool whose CONTENT is not\n * first-party (e.g. memory recall returning quarantined /\n * foreign-provenance facts) re-arm the taint ledger, closing the\n * cross-session poisoning leg. Flags only ever WIDEN the derived label\n * (they cannot launder an untrusted tool's output into trusted).\n */\n readonly taint?: {\n readonly untrusted?: boolean;\n readonly sensitive?: boolean;\n readonly sourceKind?: string;\n };\n}\n\n/**\n * W-115: cross-realm brand for the {@link ToolReturn} envelope\n * (`SECRET_VALUE_BRAND` precedent - `Symbol.for` survives duplicate\n * package copies).\n *\n * @stable\n */\nexport const TOOL_RETURN_BRAND: unique symbol = Symbol.for('graphorin.ToolReturn');\n\n/**\n * W-115: build a BRANDED {@link ToolReturn} envelope. The executor\n * unwraps branded envelopes unconditionally; unbranded objects fall to\n * a deliberately narrow structural sniff (own keys within\n * `{output, contentParts, taint}`), so a tool legitimately returning\n * `{ output, exitCode, stderr }` is no longer silently stripped to its\n * `output` field.\n *\n * @stable\n */\nexport function toolReturn<TOutput>(fields: {\n readonly output: TOutput;\n readonly contentParts?: ReadonlyArray<MessageContent>;\n readonly taint?: ToolReturn<TOutput>['taint'];\n}): ToolReturn<TOutput> {\n return {\n [TOOL_RETURN_BRAND]: true,\n output: fields.output,\n ...(fields.contentParts !== undefined ? { contentParts: fields.contentParts } : {}),\n ...(fields.taint !== undefined ? { taint: fields.taint } : {}),\n };\n}\n\n/**\n * W-115: the ONE guard for the ToolReturn envelope (the executor and\n * the registry example-normalizer both consume it). Brand first; the\n * structural fallback accepts only objects whose OWN enumerable keys\n * all belong to the canonical envelope shape - `{output, exitCode}`\n * style process results pass through intact.\n *\n * @stable\n */\nexport function isToolReturnEnvelope<TOutput = unknown>(\n value: unknown,\n): value is ToolReturn<TOutput> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n if ((value as Record<PropertyKey, unknown>)[TOOL_RETURN_BRAND] === true) return true;\n if (!Object.hasOwn(value, 'output')) return false;\n for (const key of Object.keys(value)) {\n if (key !== 'output' && key !== 'contentParts' && key !== 'taint') return false;\n }\n return true;\n}\n\n/**\n * W-115: `true` when {@link isToolReturnEnvelope} matched WITHOUT the\n * brand - observability for the future deprecation of the structural\n * sniff.\n *\n * @stable\n */\nexport function isUnbrandedToolReturn(value: unknown): boolean {\n return (\n isToolReturnEnvelope(value) &&\n (value as unknown as Record<PropertyKey, unknown>)[TOOL_RETURN_BRAND] !== true\n );\n}\n\n/**\n * Per-call execution context handed to `Tool.execute(...)`. Carries the\n * stable `toolCallId`, the parent `RunContext`, an `AbortSignal` tied to\n * the surrounding agent run, structured tracer / logger handles, the\n * streaming progress / content emitters, and a per-call secrets accessor\n * scoped to the tool's `secretsAllowed` ACL.\n *\n * @stable\n */\nexport interface ToolExecutionContext<TDeps = unknown> {\n readonly toolCallId: string;\n readonly runContext: RunContext<TDeps>;\n readonly signal: AbortSignal;\n readonly tracer: Tracer;\n readonly logger: Logger;\n /**\n * Per-call secrets accessor. The accessor enforces the tool's\n * `secretsAllowed` ACL - calling `require(...)` for a key that is\n * not on the allowlist throws `SecretAccessDeniedError`.\n */\n readonly secrets: ToolSecretsAccessor;\n /**\n * Emit a progress event to subscribers of `agent.stream(...)`. No-op\n * on tools without `streamingHint: true` AND on aborted streams. The\n * counter pair `(current, total?)` is consumer-rendered as a\n * percentage when both fields are present.\n */\n reportProgress(current: number, total?: number, message?: string): void;\n /**\n * Emit one chunk of content. Concatenated into the tool's assembled\n * `output` per the buffer-becomes-output discipline. No-op on tools\n * without `streamingHint: true` AND on aborted streams.\n */\n streamContent(chunk: ContentChunk): void;\n}\n\n/**\n * Per-call secrets accessor surface. Implemented by the executor; the\n * tool author calls `require(...)` to obtain a `SecretValue` wrapper.\n *\n * The accessor is intentionally narrow - the ACL enforcement happens\n * inside `require(...)`, so the tool author never accidentally\n * unwraps a secret outside the tool's permitted set.\n *\n * @stable\n */\nexport interface ToolSecretsAccessor {\n /**\n * Resolve a secret by key. Throws `SecretAccessDeniedError` if the\n * key is not in the tool's `secretsAllowed` allowlist; throws\n * `SecretRequiredError` (or returns `null` when `optional: true`)\n * if the key resolves to no value.\n */\n require(\n key: string,\n options?: { readonly optional?: false },\n ): Promise<import('./secret-value.js').SecretValue>;\n require(\n key: string,\n options: { readonly optional: true },\n ): Promise<import('./secret-value.js').SecretValue | null>;\n}\n"],"mappings":";;;;;;;;AAmRA,MAAaA,oBAAmC,OAAO,IAAI,uBAAuB;;;;;;;;;;;AAYlF,SAAgB,WAAoB,QAIZ;AACtB,QAAO;GACJ,oBAAoB;EACrB,QAAQ,OAAO;EACf,GAAI,OAAO,iBAAiB,SAAY,EAAE,cAAc,OAAO,cAAc,GAAG,EAAE;EAClF,GAAI,OAAO,UAAU,SAAY,EAAE,OAAO,OAAO,OAAO,GAAG,EAAE;EAC9D;;;;;;;;;;;AAYH,SAAgB,qBACd,OAC8B;AAC9B,KAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,MAAM,CAAE,QAAO;AAChF,KAAK,MAAuC,uBAAuB,KAAM,QAAO;AAChF,KAAI,CAAC,OAAO,OAAO,OAAO,SAAS,CAAE,QAAO;AAC5C,MAAK,MAAM,OAAO,OAAO,KAAK,MAAM,CAClC,KAAI,QAAQ,YAAY,QAAQ,kBAAkB,QAAQ,QAAS,QAAO;AAE5E,QAAO;;;;;;;;;AAUT,SAAgB,sBAAsB,OAAyB;AAC7D,QACE,qBAAqB,MAAM,IAC1B,MAAkD,uBAAuB"}
|
|
@@ -1,13 +1,42 @@
|
|
|
1
|
+
import { Sensitivity } from "../types/sensitivity.js";
|
|
2
|
+
|
|
1
3
|
//#region src/contracts/tracer.d.ts
|
|
4
|
+
|
|
2
5
|
/**
|
|
3
|
-
*
|
|
6
|
+
* Framework-known discriminators for typed observability spans.
|
|
4
7
|
*
|
|
5
8
|
* The list mirrors the span taxonomy documented for the observability
|
|
6
9
|
* layer; concrete implementations live in `@graphorin/observability`.
|
|
10
|
+
* Promoting a frequently-used custom span kind (see
|
|
11
|
+
* {@link CustomSpanType}) into this union is an additive minor change.
|
|
7
12
|
*
|
|
8
13
|
* @stable
|
|
9
14
|
*/
|
|
10
|
-
type
|
|
15
|
+
type KnownSpanType = 'agent.run' | 'agent.step' | 'agent.handoff' | 'agent.suspend' | 'agent.resume' | 'provider.generate' | 'provider.stream' | 'tool.execute' | 'tool.approval' | 'memory.read.working' | 'memory.read.session' | 'memory.read.episodic' | 'memory.read.semantic' | 'memory.read.procedural' | 'memory.read.shared' | 'memory.write.working' | 'memory.write.session' | 'memory.write.episodic' | 'memory.write.semantic' | 'memory.write.procedural' | 'memory.write.shared' | 'memory.search.working' | 'memory.search.session' | 'memory.search.episodic' | 'memory.search.semantic' | 'memory.search.procedural' | 'memory.search.shared' | 'memory.consolidate.light' | 'memory.consolidate.standard' | 'memory.consolidate.deep' | 'memory.consolidate.reflect' | 'memory.consolidate.learned-context' | 'memory.search.insight' | 'memory.read.insight' | 'memory.write.insight' | 'memory.conflict' | 'memory.embed' | 'workflow.run' | 'workflow.step' | 'workflow.task' | 'workflow.checkpoint' | 'skill.activate' | 'skill.load' | 'mcp.connect' | 'mcp.call' | 'mcp.list-tools';
|
|
16
|
+
/**
|
|
17
|
+
* Namespaced escape hatch for user-defined span kinds (W-126): any
|
|
18
|
+
* string under the `x.` prefix, e.g. `'x.acme.rerank'`. The prefix
|
|
19
|
+
* keeps typo-safety for the known literals - `'memory.serch.semantic'`
|
|
20
|
+
* is still a compile error because it does not start with `x.` -
|
|
21
|
+
* which is why this is a template-literal type and not `string & {}`.
|
|
22
|
+
*
|
|
23
|
+
* Convention: `x.<vendor>.<operation>`. Backends and analytics must
|
|
24
|
+
* tolerate unknown span-type strings (the same policy events already
|
|
25
|
+
* follow). When a custom kind becomes common, promote it into
|
|
26
|
+
* {@link KnownSpanType} (additive minor).
|
|
27
|
+
*
|
|
28
|
+
* @stable
|
|
29
|
+
*/
|
|
30
|
+
type CustomSpanType = `x.${string}`;
|
|
31
|
+
/**
|
|
32
|
+
* Discriminator union for typed observability spans: every
|
|
33
|
+
* {@link KnownSpanType} literal plus the {@link CustomSpanType}
|
|
34
|
+
* namespaced escape. Exhaustive switches over `SpanType` need a
|
|
35
|
+
* default branch for the custom domain.
|
|
36
|
+
*
|
|
37
|
+
* @stable
|
|
38
|
+
*/
|
|
39
|
+
type SpanType = KnownSpanType | CustomSpanType;
|
|
11
40
|
/**
|
|
12
41
|
* Status of a finished span. Mirrors the OTel status convention with
|
|
13
42
|
* `'ok' | 'error'` short forms instead of the verbose tristate.
|
|
@@ -23,6 +52,19 @@ type SpanStatus = 'ok' | 'error' | 'cancelled';
|
|
|
23
52
|
type SpanAttributes = Readonly<Record<string, SpanAttributeValue>>;
|
|
24
53
|
/** @stable */
|
|
25
54
|
type SpanAttributeValue = string | number | boolean | null | ReadonlyArray<string> | ReadonlyArray<number> | ReadonlyArray<boolean>;
|
|
55
|
+
/**
|
|
56
|
+
* W-094: sensitivity opts for {@link AISpan.addEvent}. Event attributes
|
|
57
|
+
* used to be un-taggable, so a default-`'public'` export floor dropped
|
|
58
|
+
* ALL of them - including `exception.type` from `recordException`.
|
|
59
|
+
*
|
|
60
|
+
* @stable
|
|
61
|
+
*/
|
|
62
|
+
interface AddEventOptions {
|
|
63
|
+
/** Default tier applied to every attribute of this event. */
|
|
64
|
+
readonly sensitivity?: Sensitivity;
|
|
65
|
+
/** Per-attribute overrides; win over {@link AddEventOptions.sensitivity}. */
|
|
66
|
+
readonly sensitivityByAttribute?: Readonly<Record<string, Sensitivity>>;
|
|
67
|
+
}
|
|
26
68
|
/**
|
|
27
69
|
* Typed span. Generic over `SpanType` so consumers can specialize a
|
|
28
70
|
* function on a particular span kind without losing the discriminator.
|
|
@@ -36,8 +78,14 @@ interface AISpan<T extends SpanType = SpanType> {
|
|
|
36
78
|
readonly parentId?: string;
|
|
37
79
|
/** Add or replace attributes. Repeated calls are merged (last write wins). */
|
|
38
80
|
setAttributes(attrs: SpanAttributes): void;
|
|
39
|
-
/**
|
|
40
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Append a span event (attribute-bearing time-stamped marker). The
|
|
83
|
+
* optional `opts` (W-094) tags the event's attributes with a
|
|
84
|
+
* sensitivity tier so the validation exporter can pass safe ones
|
|
85
|
+
* through the default-deny floor - untagged attributes keep being
|
|
86
|
+
* dropped below the floor.
|
|
87
|
+
*/
|
|
88
|
+
addEvent(name: string, attrs?: SpanAttributes, opts?: AddEventOptions): void;
|
|
41
89
|
/** Record an exception. Multiple calls are kept in the span event log. */
|
|
42
90
|
recordException(err: unknown): void;
|
|
43
91
|
/** Set the terminal status. */
|
|
@@ -80,5 +128,5 @@ interface Tracer {
|
|
|
80
128
|
*/
|
|
81
129
|
declare const NOOP_TRACER: Tracer;
|
|
82
130
|
//#endregion
|
|
83
|
-
export { AISpan, NOOP_TRACER, SpanAttributeValue, SpanAttributes, SpanStatus, SpanType, StartSpanOptions, Tracer };
|
|
131
|
+
export { AISpan, AddEventOptions, CustomSpanType, KnownSpanType, NOOP_TRACER, SpanAttributeValue, SpanAttributes, SpanStatus, SpanType, StartSpanOptions, Tracer };
|
|
84
132
|
//# sourceMappingURL=tracer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracer.d.ts","names":[],"sources":["../../src/contracts/tracer.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tracer.d.ts","names":[],"sources":["../../src/contracts/tracer.ts"],"sourcesContent":[],"mappings":";;;;;;;AAUA;AA8DA;AAUA;AAQA;AAOA;;;AAA6B,KAvFjB,aAAA,GAuFiB,WAAA,GAAA,YAAA,GAAA,eAAA,GAAA,eAAA,GAAA,cAAA,GAAA,mBAAA,GAAA,iBAAA,GAAA,cAAA,GAAA,eAAA,GAAA,qBAAA,GAAA,qBAAA,GAAA,sBAAA,GAAA,sBAAA,GAAA,wBAAA,GAAA,oBAAA,GAAA,sBAAA,GAAA,sBAAA,GAAA,uBAAA,GAAA,uBAAA,GAAA,yBAAA,GAAA,qBAAA,GAAA,uBAAA,GAAA,uBAAA,GAAA,wBAAA,GAAA,wBAAA,GAAA,0BAAA,GAAA,sBAAA,GAAA,0BAAA,GAAA,6BAAA,GAAA,yBAAA,GAAA,4BAAA,GAAA,oCAAA,GAAA,uBAAA,GAAA,qBAAA,GAAA,sBAAA,GAAA,iBAAA,GAAA,cAAA,GAAA,cAAA,GAAA,eAAA,GAAA,eAAA,GAAA,qBAAA,GAAA,gBAAA,GAAA,YAAA,GAAA,aAAA,GAAA,UAAA,GAAA,gBAAA;;AAG7B;;;;;AAgBA;;;;;;AAeA;;AAA6C,KA3DjC,cAAA,GA2DiC,KAAA,MAAA,EAAA;;;;;;;AA4B7C;;AAAuD,KA7E3C,QAAA,GAAW,aA6EgC,GA7EhB,cA6EgB;;;;;AAavD;;AACuD,KAnF3C,UAAA,GAmF2C,IAAA,GAAA,OAAA,GAAA,WAAA;;;;;;AAM7C,KAlFE,cAAA,GAAiB,QAkFnB,CAlF4B,MAkF5B,CAAA,MAAA,EAlF2C,kBAkF3C,CAAA,CAAA;;AACK,KAhFH,kBAAA,GAgFG,MAAA,GAAA,MAAA,GAAA,OAAA,GAAA,IAAA,GA3EX,aA2EW,CAAA,MAAA,CAAA,GA1EX,aA0EW,CAAA,MAAA,CAAA,GAzEX,aAyEW,CAAA,OAAA,CAAA;;;;;;;;AAYF,UA5EI,eAAA,CA4ES;;yBA5EM;;oCAII,SAChC,eAHkE,WAAA;;;;;;;;UAarD,iBAAiB,WAAW;iBAC5B;;;;;uBAKM;;;;;;;;iCAQU,uBAAuB;;;;oBAIpC;;;;;;;;;UAUH,2BAA2B,WAAW;iBACtC;mBACE;oBACC;;;;;;;;;UAUH,MAAA;sBACK,gBAAgB,iBAAiB,KAAK,OAAO;;;;;iBAKlD,mBACP,iBAAiB,eACZ,OAAO,OAAO,IAAI,QAAQ,KACpC,QAAQ;;cAEC;;;;;;;;cASD,aAAa"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracer.js","names":["NOOP_TRACER: Tracer"],"sources":["../../src/contracts/tracer.ts"],"sourcesContent":["/**\n *
|
|
1
|
+
{"version":3,"file":"tracer.js","names":["NOOP_TRACER: Tracer"],"sources":["../../src/contracts/tracer.ts"],"sourcesContent":["/**\n * Framework-known discriminators for typed observability spans.\n *\n * The list mirrors the span taxonomy documented for the observability\n * layer; concrete implementations live in `@graphorin/observability`.\n * Promoting a frequently-used custom span kind (see\n * {@link CustomSpanType}) into this union is an additive minor change.\n *\n * @stable\n */\nexport type KnownSpanType =\n | 'agent.run'\n | 'agent.step'\n | 'agent.handoff'\n | 'agent.suspend'\n | 'agent.resume'\n | 'provider.generate'\n | 'provider.stream'\n | 'tool.execute'\n | 'tool.approval'\n | 'memory.read.working'\n | 'memory.read.session'\n | 'memory.read.episodic'\n | 'memory.read.semantic'\n | 'memory.read.procedural'\n | 'memory.read.shared'\n | 'memory.write.working'\n | 'memory.write.session'\n | 'memory.write.episodic'\n | 'memory.write.semantic'\n | 'memory.write.procedural'\n | 'memory.write.shared'\n | 'memory.search.working'\n | 'memory.search.session'\n | 'memory.search.episodic'\n | 'memory.search.semantic'\n | 'memory.search.procedural'\n | 'memory.search.shared'\n | 'memory.consolidate.light'\n | 'memory.consolidate.standard'\n | 'memory.consolidate.deep'\n | 'memory.consolidate.reflect'\n | 'memory.consolidate.learned-context'\n | 'memory.search.insight'\n | 'memory.read.insight'\n | 'memory.write.insight'\n | 'memory.conflict'\n | 'memory.embed'\n | 'workflow.run'\n | 'workflow.step'\n | 'workflow.task'\n | 'workflow.checkpoint'\n | 'skill.activate'\n | 'skill.load'\n | 'mcp.connect'\n | 'mcp.call'\n | 'mcp.list-tools';\n\n/**\n * Namespaced escape hatch for user-defined span kinds (W-126): any\n * string under the `x.` prefix, e.g. `'x.acme.rerank'`. The prefix\n * keeps typo-safety for the known literals - `'memory.serch.semantic'`\n * is still a compile error because it does not start with `x.` -\n * which is why this is a template-literal type and not `string & {}`.\n *\n * Convention: `x.<vendor>.<operation>`. Backends and analytics must\n * tolerate unknown span-type strings (the same policy events already\n * follow). When a custom kind becomes common, promote it into\n * {@link KnownSpanType} (additive minor).\n *\n * @stable\n */\nexport type CustomSpanType = `x.${string}`;\n\n/**\n * Discriminator union for typed observability spans: every\n * {@link KnownSpanType} literal plus the {@link CustomSpanType}\n * namespaced escape. Exhaustive switches over `SpanType` need a\n * default branch for the custom domain.\n *\n * @stable\n */\nexport type SpanType = KnownSpanType | CustomSpanType;\n\n/**\n * Status of a finished span. Mirrors the OTel status convention with\n * `'ok' | 'error'` short forms instead of the verbose tristate.\n *\n * @stable\n */\nexport type SpanStatus = 'ok' | 'error' | 'cancelled';\n\n/**\n * Free-form attributes attached to a span.\n *\n * @stable\n */\nexport type SpanAttributes = Readonly<Record<string, SpanAttributeValue>>;\n\n/** @stable */\nexport type SpanAttributeValue =\n | string\n | number\n | boolean\n | null\n | ReadonlyArray<string>\n | ReadonlyArray<number>\n | ReadonlyArray<boolean>;\n\n/**\n * W-094: sensitivity opts for {@link AISpan.addEvent}. Event attributes\n * used to be un-taggable, so a default-`'public'` export floor dropped\n * ALL of them - including `exception.type` from `recordException`.\n *\n * @stable\n */\nexport interface AddEventOptions {\n /** Default tier applied to every attribute of this event. */\n readonly sensitivity?: import('../types/sensitivity.js').Sensitivity;\n /** Per-attribute overrides; win over {@link AddEventOptions.sensitivity}. */\n readonly sensitivityByAttribute?: Readonly<\n Record<string, import('../types/sensitivity.js').Sensitivity>\n >;\n}\n\n/**\n * Typed span. Generic over `SpanType` so consumers can specialize a\n * function on a particular span kind without losing the discriminator.\n *\n * @stable\n */\nexport interface AISpan<T extends SpanType = SpanType> {\n readonly type: T;\n readonly id: string;\n readonly traceId: string;\n readonly parentId?: string;\n /** Add or replace attributes. Repeated calls are merged (last write wins). */\n setAttributes(attrs: SpanAttributes): void;\n /**\n * Append a span event (attribute-bearing time-stamped marker). The\n * optional `opts` (W-094) tags the event's attributes with a\n * sensitivity tier so the validation exporter can pass safe ones\n * through the default-deny floor - untagged attributes keep being\n * dropped below the floor.\n */\n addEvent(name: string, attrs?: SpanAttributes, opts?: AddEventOptions): void;\n /** Record an exception. Multiple calls are kept in the span event log. */\n recordException(err: unknown): void;\n /** Set the terminal status. */\n setStatus(status: SpanStatus, message?: string): void;\n /** End the span. Idempotent. */\n end(): void;\n}\n\n/**\n * Span constructor parameters.\n *\n * @stable\n */\nexport interface StartSpanOptions<T extends SpanType = SpanType> {\n readonly type: T;\n readonly attrs?: SpanAttributes;\n readonly parent?: AISpan;\n}\n\n/**\n * Pluggable tracer. Implementations live in `@graphorin/observability`.\n * The interface intentionally mirrors a subset of the OTel API so that\n * adapter code is a thin pass-through.\n *\n * @stable\n */\nexport interface Tracer {\n startSpan<T extends SpanType>(opts: StartSpanOptions<T>): AISpan<T>;\n /**\n * Convenience wrapper: start a span, run `fn` inside, and call\n * `setStatus('ok' | 'error')` + `end()` based on the outcome.\n */\n span<T extends SpanType, R>(\n opts: StartSpanOptions<T>,\n fn: (span: AISpan<T>) => R | Promise<R>,\n ): Promise<R>;\n /** Force-flush any pending spans. */\n shutdown(): Promise<void>;\n}\n\n/**\n * Minimal no-op tracer. Useful as a typed default when downstream code\n * needs a non-null `Tracer` without taking the observability dependency.\n *\n * @stable\n */\nexport const NOOP_TRACER: Tracer = {\n startSpan<T extends SpanType>(opts: StartSpanOptions<T>): AISpan<T> {\n const span: AISpan<T> = {\n type: opts.type,\n id: '',\n traceId: '',\n setAttributes(): void {},\n addEvent(): void {},\n recordException(): void {},\n setStatus(): void {},\n end(): void {},\n };\n return span;\n },\n async span<T extends SpanType, R>(\n opts: StartSpanOptions<T>,\n fn: (span: AISpan<T>) => R | Promise<R>,\n ): Promise<R> {\n const span = this.startSpan(opts);\n try {\n return await fn(span);\n } finally {\n span.end();\n }\n },\n async shutdown(): Promise<void> {},\n};\n"],"mappings":";;;;;;;AAgMA,MAAaA,cAAsB;CACjC,UAA8B,MAAsC;AAWlE,SAVwB;GACtB,MAAM,KAAK;GACX,IAAI;GACJ,SAAS;GACT,gBAAsB;GACtB,WAAiB;GACjB,kBAAwB;GACxB,YAAkB;GAClB,MAAY;GACb;;CAGH,MAAM,KACJ,MACA,IACY;EACZ,MAAM,OAAO,KAAK,UAAU,KAAK;AACjC,MAAI;AACF,UAAO,MAAM,GAAG,KAAK;YACb;AACR,QAAK,KAAK;;;CAGd,MAAM,WAA0B;CACjC"}
|