@telemai/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,369 @@
1
+ type Json = Record<string, unknown>;
2
+ /** What one event node needs to identify itself, before derivation. Every id here
3
+ * is an OPAQUE host string; the UUIDs that reach the wire are derived from them by
4
+ * `buildMetadata`, never forwarded. */
5
+ type TrajectoryArgs = {
6
+ harness: string;
7
+ conversationId: string;
8
+ windowId: string;
9
+ messageId: string;
10
+ toolCallId: string;
11
+ /** The flattened conversation history, in the backend's `{role, content}` shape. */
12
+ history: readonly Record<string, string>[];
13
+ /** The root-first ancestor chain; its LAST entry is the direct parent. */
14
+ ancestors: readonly Json[];
15
+ };
16
+ /** A derived, wire-ready trajectory envelope: the output of `buildMetadata`, and the
17
+ * only thing `withTrajectory` should be handed. Its keys are the reserved lineage
18
+ * keys the freeform `metadata` bag may not carry, so they are snake_case — they land
19
+ * on the wire `metadata` verbatim, with the node's `kind` stamped by the call that
20
+ * sends it. Build it with `buildMetadata`; do not hand-assemble one, or the derived
21
+ * ids will not join the backend's rows. */
22
+ type TrajectoryEnvelope = {
23
+ message_history: readonly Record<string, string>[];
24
+ session_key: string;
25
+ fingerprint: string;
26
+ node_key: string;
27
+ parent_node_key: string | null;
28
+ ancestors: readonly Json[];
29
+ };
30
+ /** What freezes one agent at a delegation boundary, before derivation. */
31
+ type SnapshotArgs = {
32
+ harness: string;
33
+ conversationId: string;
34
+ windowId: string;
35
+ /** The model turn that delegated; subagents started in one turn share the node. */
36
+ messageId: string;
37
+ /** The agent's conversation so far, frozen at the boundary. */
38
+ context: readonly Record<string, string>[];
39
+ /** The agent's own root-first ancestor chain. */
40
+ ancestors: readonly Json[];
41
+ /** ISO timestamp; defaults to now. */
42
+ spawnedAt?: string;
43
+ };
44
+ /** One entry of a child's `ancestors`: the output of `buildSnapshot`. */
45
+ type TrajectorySnapshot = {
46
+ session_key: string;
47
+ fingerprint: string;
48
+ node_key: string;
49
+ parent_node_key: string | null;
50
+ context: readonly Record<string, string>[];
51
+ spawned_at: string;
52
+ };
53
+ /** Search options. `undefined` is unset (client default, then server default);
54
+ * `[]`/`{}`/`false` are explicit values sent to the server as-is. */
55
+ type SearchOptions = {
56
+ tier?: string;
57
+ fields?: string[];
58
+ providersInclude?: string[];
59
+ providersExclude?: string[];
60
+ providerOverrides?: Record<string, Json>;
61
+ numResults?: number;
62
+ includeRaw?: boolean;
63
+ includeFullContent?: boolean;
64
+ /** Opt this request into the server's rerank stage. It is the only path where
65
+ * `context`, the reasoning on the last assistant entry of the lineage history
66
+ * (that entry only), and `goal` change result ORDER (in that precedence) —
67
+ * otherwise they are recorded only. Per-call intent, like `includeRaw`; the
68
+ * server default is off, and rerank is metered. */
69
+ rerank?: boolean;
70
+ goal?: string;
71
+ context?: string;
72
+ session?: string;
73
+ /** Freeform metadata for the wire. Reserved trajectory-lineage keys
74
+ * (`RESERVED_METADATA`) are STRIPPED from here — lineage may only be attached
75
+ * through `withTrajectory`, fed by `buildMetadata`, never smuggled in as data. */
76
+ metadata?: Json;
77
+ };
78
+ /** The subset of search options that may also be set as a client default.
79
+ * `numResults`/`includeRaw`/`rerank`/`providerOverrides` are per-call intent only. */
80
+ type SearchDefaults = Pick<SearchOptions, "tier" | "fields" | "providersInclude" | "providersExclude" | "includeFullContent">;
81
+ type FetchOptions = {
82
+ providers?: string[];
83
+ inlineContent?: boolean;
84
+ inlineMaxChars?: number;
85
+ contentFormat?: string;
86
+ session?: string;
87
+ metadata?: Json;
88
+ };
89
+ type TelemOptions = SearchDefaults & {
90
+ apiKey?: string;
91
+ baseUrl?: string;
92
+ timeoutMs?: number;
93
+ maxRetries?: number;
94
+ /** Injectable transport — embedded runtimes, edge workers, and tests. */
95
+ fetch?: typeof globalThis.fetch;
96
+ userAgent?: string;
97
+ /** Retry backoff seam. Defaults to a real timer; tests pass a recorder. */
98
+ sleep?: (ms: number) => Promise<void>;
99
+ };
100
+ type SearchResult = {
101
+ url: string;
102
+ title: string;
103
+ summary: string | null;
104
+ excerpt: string[] | null;
105
+ fullContent: Json | null;
106
+ publishDate: string | null;
107
+ rank: number | null;
108
+ thumbnail: string | null;
109
+ favicon: string | null;
110
+ source: Json | null;
111
+ enrichments: Json | null;
112
+ fetchMeta: Json | null;
113
+ provider: string;
114
+ raw: Json;
115
+ };
116
+ type ProviderRun = {
117
+ provider: string;
118
+ status: string;
119
+ results: SearchResult[];
120
+ error: Json | null;
121
+ latencyMs: number | null;
122
+ preprocessorRunId: string | null;
123
+ tier: string | null;
124
+ fields: string[];
125
+ query: string;
126
+ batchIndex: number;
127
+ answer: string | null;
128
+ entities: Json | unknown[] | null;
129
+ related: Json | null;
130
+ verticals: Json | null;
131
+ usage: Json | unknown[] | null;
132
+ warnings: Json[];
133
+ raw: Json | null;
134
+ };
135
+ type SearchResponse = {
136
+ /** Flattened across providers: provider run order, then envelope row order. */
137
+ results: SearchResult[];
138
+ /** Per-provider breakdown, preserving partial failures. */
139
+ byProvider: ProviderRun[];
140
+ sessionId: string;
141
+ interactionId: string;
142
+ status: string;
143
+ normalizedSchemaVersion: number | null;
144
+ raw: Json;
145
+ };
146
+ type FetchResult = {
147
+ url: string;
148
+ canonicalUrl: string | null;
149
+ title: string;
150
+ status: string;
151
+ content: string | null;
152
+ contentTruncated: boolean | null;
153
+ contentFormat: string | null;
154
+ contentSha256: string | null;
155
+ contentType: string | null;
156
+ contentRef: Json | null;
157
+ provider: string;
158
+ httpStatus: number | null;
159
+ fetchedAt: string | null;
160
+ latencyMs: number | null;
161
+ providerMetadata: Json | null;
162
+ error: Json | null;
163
+ batchIndex: number;
164
+ raw: Json;
165
+ };
166
+ type FetchResponse = {
167
+ /** One result per requested URL, in request (batchIndex) order. */
168
+ results: FetchResult[];
169
+ sessionId: string;
170
+ interactionId: string;
171
+ status: string;
172
+ raw: Json;
173
+ };
174
+ type ProviderInfo = {
175
+ name: string;
176
+ type: string;
177
+ activeByDefault: boolean;
178
+ description: string | null;
179
+ method: string | null;
180
+ url: string | null;
181
+ normalized: boolean;
182
+ tiers: string[];
183
+ };
184
+ /** One session as `sessions.list()` reports it. */
185
+ type SessionSummary = {
186
+ id: string;
187
+ createdAt: string | null;
188
+ updatedAt: string | null;
189
+ interactionCount: number;
190
+ latestInteractionAt: string | null;
191
+ raw: Json;
192
+ };
193
+ /** Aggregated websearch preprocessor results for a session. `query`, `goal` and
194
+ * `context` are always strings — a server that said nothing sends `""`, never null. */
195
+ type SessionResults = {
196
+ sessionId: string;
197
+ query: string;
198
+ goal: string;
199
+ context: string;
200
+ previousPreprocessorResults: Json[];
201
+ raw: Json;
202
+ };
203
+ /** The `telem.sessions` namespace. */
204
+ type SessionsResource = {
205
+ list(): Promise<SessionSummary[]>;
206
+ results(sessionId: string): Promise<SessionResults>;
207
+ };
208
+
209
+ /**
210
+ * The CLOSED set of codes the client itself assigns, for failures that never
211
+ * reached the server or that the server's own envelope does not describe. Any
212
+ * other value came off the wire (the `/v1/fetch` envelope's `error.code`) and is
213
+ * passed through untouched.
214
+ *
215
+ * Branch on these, never on message text — messages are not a contract.
216
+ */
217
+ type TelemClientErrorCode =
218
+ /** The arguments were rejected before any request was made. */
219
+ "invalid_request"
220
+ /** A 2xx search response did not echo `normalized_schema_version >= 2`. */
221
+ | "unsupported_server_version"
222
+ /** The request never produced a response (DNS, refused, reset, TLS). */
223
+ | "connection_error"
224
+ /** The request was still outstanding when the timeout fired. */
225
+ | "timeout";
226
+ type TelemErrorOptions = {
227
+ /** HTTP status that produced this error; absent for transport failures. */
228
+ status?: number;
229
+ /** A `TelemClientErrorCode`, or the stable code the server's envelope carried.
230
+ * Absent when a non-2xx response named no code of its own. */
231
+ code?: TelemClientErrorCode | (string & {});
232
+ /** Parsed response body (or raw text when it would not parse). */
233
+ details?: unknown;
234
+ cause?: unknown;
235
+ };
236
+ declare class TelemError extends Error {
237
+ status?: number;
238
+ code?: TelemClientErrorCode | (string & {});
239
+ details?: unknown;
240
+ constructor(message: string, options?: TelemErrorOptions);
241
+ }
242
+ /** The request never produced a response in time. Always `code: "timeout"`. */
243
+ declare class TimeoutError extends TelemError {
244
+ constructor(message: string, cause?: unknown);
245
+ }
246
+
247
+ /** Metadata keys the trajectory payload owns. A caller-supplied value for any of
248
+ * these is dropped rather than allowed to forge identity. */
249
+ declare const RESERVED_METADATA: ReadonlySet<string>;
250
+ /** Stable, non-reversible conversation identity. */
251
+ declare function fingerprint(harness: string, conversationId: string): Promise<string>;
252
+ /** Deterministic identity of one context-window generation. */
253
+ declare function sessionKey(harness: string, conversationId: string, windowId: string): Promise<string>;
254
+ /** Replay-stable event node key for one model tool call. */
255
+ declare function eventNodeKey(harness: string, session: string, messageId: string, toolCallId: string): Promise<string>;
256
+ /** Identity of an agent snapshot at a delegation boundary. */
257
+ declare function snapshotNodeKey(harness: string, conversationId: string, messageId: string): Promise<string>;
258
+ /** Stable anchor id for content a host did not assign an id to.
259
+ * Length-prefixed like every other key component, so concatenation stays injective. */
260
+ declare function contentAnchor(...parts: string[]): Promise<string>;
261
+ /**
262
+ * Identify this context-window generation by its first message.
263
+ *
264
+ * Messages carry no ids of their own, so the anchor is a content hash. When a
265
+ * caller trims or summarizes the front of the history — the equivalent of a
266
+ * compaction — the anchor moves and a new generation begins.
267
+ *
268
+ * @returns The anchor, or `NONE` when there are no messages at all.
269
+ */
270
+ declare function windowAnchor(messages: readonly Json[]): Promise<string>;
271
+ /**
272
+ * Assemble the trajectory-v5 metadata block for one event node.
273
+ *
274
+ * Built from the ALLOWLIST (`RESERVED_METADATA`) and nothing else — never by
275
+ * merging caller data — so nothing smuggled in through a host envelope can ride
276
+ * out to the wire. `parent_node_key` is the DIRECT parent's snapshot key, which is
277
+ * the last entry of the root-first chain, or `null` when there is no parent.
278
+ */
279
+ declare function buildMetadata(args: TrajectoryArgs): Promise<TrajectoryEnvelope>;
280
+ /**
281
+ * Freeze one agent at a delegation boundary into the entry its subagents carry in
282
+ * `ancestors`.
283
+ *
284
+ * Keyed on the delegating turn, so subagents started in one turn share one parent
285
+ * node. `context` is the agent's conversation at that moment; the caller copies it
286
+ * if the live history keeps growing.
287
+ */
288
+ declare function buildSnapshot(args: SnapshotArgs): Promise<TrajectorySnapshot>;
289
+ /** The seam key. A SYMBOL, so an envelope can never arrive from parsed JSON, never
290
+ * survives a `structuredClone` of caller options, and never appears on the published
291
+ * option surface or in the `.d.ts` — the ONLY way to attach lineage is
292
+ * `withTrajectory`, which is why lineage cannot be forged through freeform metadata.
293
+ * A REGISTERED symbol, so the ESM and CJS builds of this package share one key: an
294
+ * envelope attached by one copy is read by the other. Not re-exported from the
295
+ * package root; the seam is the function, not the key. */
296
+ declare const TRAJECTORY: unique symbol;
297
+ /** Search / fetch options carrying a pre-built trajectory envelope. Package-internal. */
298
+ type TrajectorySearchOptions = SearchOptions & {
299
+ [TRAJECTORY]?: TrajectoryEnvelope;
300
+ };
301
+ type TrajectoryFetchOptions = FetchOptions & {
302
+ [TRAJECTORY]?: TrajectoryEnvelope;
303
+ };
304
+ /**
305
+ * Attach a derived lineage envelope to one call's options — the public seam an
306
+ * example or adapter uses to thread trajectory identity onto a search or a fetch.
307
+ *
308
+ * The envelope must come from {@link buildMetadata}: it lands on the wire `metadata`
309
+ * whole, so it is the allowlist — not this function — that keeps caller data out of
310
+ * it, and a `session_key` in it makes the call's own `session` id drop out. One
311
+ * envelope serves both calls; the sending call stamps the node's kind.
312
+ */
313
+ declare function withTrajectory(options: SearchOptions, envelope: TrajectoryEnvelope): TrajectorySearchOptions;
314
+ declare function withTrajectory(options: FetchOptions, envelope: TrajectoryEnvelope): TrajectoryFetchOptions;
315
+
316
+ /**
317
+ * The Telem client.
318
+ *
319
+ * @example
320
+ * ```ts
321
+ * const telem = new Telem() // env / credentials-file resolution
322
+ * const telem = new Telem("tlm_...") // bare API-key shorthand
323
+ * const telem = new Telem({ apiKey, baseUrl, tier: "max" })
324
+ * ```
325
+ */
326
+ declare class Telem {
327
+ #private;
328
+ /** Resolved API key, or `undefined` for an anonymous client. */
329
+ readonly apiKey?: string;
330
+ /** Resolved base URL, trailing slash stripped. */
331
+ readonly baseUrl: string;
332
+ /** Resolved per-request timeout in milliseconds. */
333
+ readonly timeoutMs: number;
334
+ /** Resolved retry budget (attempts after the first). */
335
+ readonly maxRetries: number;
336
+ /** The session read surface: `list()` and `results(id)`. */
337
+ readonly sessions: SessionsResource;
338
+ /**
339
+ * @param options - An API key string, or an options object. Anything left unset
340
+ * resolves from `TELEM_*` env vars, then `~/.telem/credentials.json` (credentials
341
+ * only, read lazily), then the defaults.
342
+ */
343
+ constructor(options?: string | TelemOptions);
344
+ /**
345
+ * Run a web search.
346
+ *
347
+ * @param query - One query, or an array of queries batched into one interaction.
348
+ * @param options - Per-call options; each overrides the matching client default.
349
+ * `null` and `undefined` both mean none.
350
+ * @returns The flattened results plus the per-provider breakdown.
351
+ */
352
+ search(query: string | string[], options?: SearchOptions | null): Promise<SearchResponse>;
353
+ /**
354
+ * Fetch the readable content of one or more URLs.
355
+ *
356
+ * @param url - One URL, or an array of URLs fetched in one request.
357
+ * @param options - Per-call fetch options. `null` and `undefined` both mean none.
358
+ * @returns One result per requested URL, in request order.
359
+ */
360
+ fetch(url: string | string[], options?: FetchOptions | null): Promise<FetchResponse>;
361
+ /**
362
+ * List the search providers this deployment can run.
363
+ *
364
+ * @returns One entry per configured provider, in the server's own order.
365
+ */
366
+ providers(): Promise<ProviderInfo[]>;
367
+ }
368
+
369
+ export { type FetchOptions, type FetchResponse, type FetchResult, type Json, type ProviderInfo, type ProviderRun, RESERVED_METADATA, type SearchDefaults, type SearchOptions, type SearchResponse, type SearchResult, type SessionResults, type SessionSummary, type SessionsResource, type SnapshotArgs, Telem, type TelemClientErrorCode, TelemError, type TelemErrorOptions, type TelemOptions, TimeoutError, type TrajectoryArgs, type TrajectoryEnvelope, type TrajectorySnapshot, buildMetadata, buildSnapshot, contentAnchor, Telem as default, eventNodeKey, fingerprint, sessionKey, snapshotNodeKey, windowAnchor, withTrajectory };