@hexis-ai/engram-sdk 0.10.0 → 0.11.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/dist/buffered.d.ts +110 -0
- package/dist/buffered.js +228 -0
- package/dist/client.d.ts +36 -0
- package/dist/client.js +57 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +22 -22
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Buffered / fire-and-forget telemetry layer for `Engram`.
|
|
3
|
+
*
|
|
4
|
+
* Modelled after the Langfuse SDK ergonomics so existing observability
|
|
5
|
+
* code translates one-for-one:
|
|
6
|
+
*
|
|
7
|
+
* import { Engram } from "@hexis-ai/engram-sdk";
|
|
8
|
+
* const engram = new Engram({ baseUrl, apiKey, flushIntervalMs: 5000 });
|
|
9
|
+
*
|
|
10
|
+
* engram.session({ id: convId, channel: "slack_dm" });
|
|
11
|
+
* engram.message({ sessionId: convId, role: "user", content: "hi" });
|
|
12
|
+
* engram.message({ sessionId: convId, role: "assistant", content: out, model });
|
|
13
|
+
* engram.event({ sessionId: convId, type: "title", title: "Trip planning" });
|
|
14
|
+
*
|
|
15
|
+
* await engram.flush(); // process exit
|
|
16
|
+
* await engram.shutdown();
|
|
17
|
+
*
|
|
18
|
+
* Guarantees:
|
|
19
|
+
* - Every method returns synchronously (no `await` required at the call site).
|
|
20
|
+
* - Errors are surfaced via the `onError` hook configured on the Engram
|
|
21
|
+
* client; nothing throws to the caller.
|
|
22
|
+
* - The first message() for a session implicitly waits for the
|
|
23
|
+
* corresponding POST /v1/sessions to complete (per-session ready
|
|
24
|
+
* promise), so the host doesn't need to await session() before
|
|
25
|
+
* starting to record events.
|
|
26
|
+
* - When `baseUrl` is unset on the parent Engram, the buffer is a
|
|
27
|
+
* no-op (the Engram constructor would have thrown earlier, so this
|
|
28
|
+
* is enforced upstream; here we just document the intent).
|
|
29
|
+
*/
|
|
30
|
+
import type { Engram } from "./client";
|
|
31
|
+
import type { MessageContentBlock, SessionEvent, SessionInit } from "./types";
|
|
32
|
+
export interface TelemetrySession extends Omit<SessionInit, "id"> {
|
|
33
|
+
/** Host-supplied session id. Required for telemetry mode. */
|
|
34
|
+
id: string;
|
|
35
|
+
}
|
|
36
|
+
export interface TelemetryMessage {
|
|
37
|
+
sessionId: string;
|
|
38
|
+
role: string;
|
|
39
|
+
/** Plain string is wrapped into a single `text` block; arrays pass through. */
|
|
40
|
+
content: string | MessageContentBlock[];
|
|
41
|
+
at?: string;
|
|
42
|
+
model?: string;
|
|
43
|
+
tokens?: {
|
|
44
|
+
input: number;
|
|
45
|
+
output: number;
|
|
46
|
+
};
|
|
47
|
+
/** Stable host-side id (mirrors engram's MessageEvent.message_id). */
|
|
48
|
+
message_id?: string;
|
|
49
|
+
}
|
|
50
|
+
export type TelemetryEvent = {
|
|
51
|
+
sessionId: string;
|
|
52
|
+
type: "participant";
|
|
53
|
+
personId: string;
|
|
54
|
+
at?: string;
|
|
55
|
+
} | {
|
|
56
|
+
sessionId: string;
|
|
57
|
+
type: "title";
|
|
58
|
+
title: string;
|
|
59
|
+
at?: string;
|
|
60
|
+
} | {
|
|
61
|
+
sessionId: string;
|
|
62
|
+
type: "step";
|
|
63
|
+
tool: string;
|
|
64
|
+
input?: Record<string, unknown>;
|
|
65
|
+
result?: unknown;
|
|
66
|
+
resources?: string[];
|
|
67
|
+
at?: string;
|
|
68
|
+
} | {
|
|
69
|
+
sessionId: string;
|
|
70
|
+
type: "end";
|
|
71
|
+
at?: string;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Internal coordinator that owns per-session buffers and gates flushes
|
|
75
|
+
* on session-creation acks. Exposed on the parent Engram via
|
|
76
|
+
* `engram.session() / .message() / .event() / .flush() / .shutdown()`.
|
|
77
|
+
*/
|
|
78
|
+
export declare class BufferedTelemetry {
|
|
79
|
+
private readonly engram;
|
|
80
|
+
private readonly handles;
|
|
81
|
+
constructor(engram: Engram);
|
|
82
|
+
/**
|
|
83
|
+
* Observe a new (or already-known) session. Idempotent for the same
|
|
84
|
+
* id — subsequent calls with new metadata are folded into an
|
|
85
|
+
* updateSession() rather than re-creating.
|
|
86
|
+
*/
|
|
87
|
+
session(input: TelemetrySession): void;
|
|
88
|
+
/**
|
|
89
|
+
* Observe a message turn. Lazily creates a session handle if none
|
|
90
|
+
* exists yet — but without a prior `session({id, ...})` call the
|
|
91
|
+
* subsequent flush will fail (engram-server returns 404) and the
|
|
92
|
+
* error surfaces via onError. Pass session() first.
|
|
93
|
+
*/
|
|
94
|
+
message(input: TelemetryMessage): void;
|
|
95
|
+
/** Observe an arbitrary session event (participant / title / step / end). */
|
|
96
|
+
event(input: TelemetryEvent): void;
|
|
97
|
+
/**
|
|
98
|
+
* Drain every per-session buffer in parallel. Safe to call at any
|
|
99
|
+
* point; failures route to onError, never thrown.
|
|
100
|
+
*/
|
|
101
|
+
flush(): Promise<void>;
|
|
102
|
+
/**
|
|
103
|
+
* Final flush + stop timers. After shutdown the buffer is closed and
|
|
104
|
+
* further telemetry calls drop with onError.
|
|
105
|
+
*/
|
|
106
|
+
shutdown(): Promise<void>;
|
|
107
|
+
/** Test helper. Drops all in-memory state without flushing. */
|
|
108
|
+
resetForTests(): void;
|
|
109
|
+
}
|
|
110
|
+
export type { SessionEvent };
|
package/dist/buffered.js
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Buffered / fire-and-forget telemetry layer for `Engram`.
|
|
3
|
+
*
|
|
4
|
+
* Modelled after the Langfuse SDK ergonomics so existing observability
|
|
5
|
+
* code translates one-for-one:
|
|
6
|
+
*
|
|
7
|
+
* import { Engram } from "@hexis-ai/engram-sdk";
|
|
8
|
+
* const engram = new Engram({ baseUrl, apiKey, flushIntervalMs: 5000 });
|
|
9
|
+
*
|
|
10
|
+
* engram.session({ id: convId, channel: "slack_dm" });
|
|
11
|
+
* engram.message({ sessionId: convId, role: "user", content: "hi" });
|
|
12
|
+
* engram.message({ sessionId: convId, role: "assistant", content: out, model });
|
|
13
|
+
* engram.event({ sessionId: convId, type: "title", title: "Trip planning" });
|
|
14
|
+
*
|
|
15
|
+
* await engram.flush(); // process exit
|
|
16
|
+
* await engram.shutdown();
|
|
17
|
+
*
|
|
18
|
+
* Guarantees:
|
|
19
|
+
* - Every method returns synchronously (no `await` required at the call site).
|
|
20
|
+
* - Errors are surfaced via the `onError` hook configured on the Engram
|
|
21
|
+
* client; nothing throws to the caller.
|
|
22
|
+
* - The first message() for a session implicitly waits for the
|
|
23
|
+
* corresponding POST /v1/sessions to complete (per-session ready
|
|
24
|
+
* promise), so the host doesn't need to await session() before
|
|
25
|
+
* starting to record events.
|
|
26
|
+
* - When `baseUrl` is unset on the parent Engram, the buffer is a
|
|
27
|
+
* no-op (the Engram constructor would have thrown earlier, so this
|
|
28
|
+
* is enforced upstream; here we just document the intent).
|
|
29
|
+
*/
|
|
30
|
+
import { EngramSession } from "./client";
|
|
31
|
+
// --- BufferedTelemetry ---------------------------------------------------
|
|
32
|
+
/**
|
|
33
|
+
* Internal coordinator that owns per-session buffers and gates flushes
|
|
34
|
+
* on session-creation acks. Exposed on the parent Engram via
|
|
35
|
+
* `engram.session() / .message() / .event() / .flush() / .shutdown()`.
|
|
36
|
+
*/
|
|
37
|
+
export class BufferedTelemetry {
|
|
38
|
+
engram;
|
|
39
|
+
handles = new Map();
|
|
40
|
+
constructor(engram) {
|
|
41
|
+
this.engram = engram;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Observe a new (or already-known) session. Idempotent for the same
|
|
45
|
+
* id — subsequent calls with new metadata are folded into an
|
|
46
|
+
* updateSession() rather than re-creating.
|
|
47
|
+
*/
|
|
48
|
+
session(input) {
|
|
49
|
+
const existing = this.handles.get(input.id);
|
|
50
|
+
if (existing) {
|
|
51
|
+
existing.update(input);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
this.handles.set(input.id, new BufferedSession(this.engram, input));
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Observe a message turn. Lazily creates a session handle if none
|
|
58
|
+
* exists yet — but without a prior `session({id, ...})` call the
|
|
59
|
+
* subsequent flush will fail (engram-server returns 404) and the
|
|
60
|
+
* error surfaces via onError. Pass session() first.
|
|
61
|
+
*/
|
|
62
|
+
message(input) {
|
|
63
|
+
const handle = this.handles.get(input.sessionId);
|
|
64
|
+
if (!handle) {
|
|
65
|
+
this.engram.config.onError(new Error(`engram telemetry: message() for unknown session ${input.sessionId}; call session({id}) first`));
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
handle.message(input);
|
|
69
|
+
}
|
|
70
|
+
/** Observe an arbitrary session event (participant / title / step / end). */
|
|
71
|
+
event(input) {
|
|
72
|
+
const handle = this.handles.get(input.sessionId);
|
|
73
|
+
if (!handle) {
|
|
74
|
+
this.engram.config.onError(new Error(`engram telemetry: event() for unknown session ${input.sessionId}; call session({id}) first`));
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
handle.event(input);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Drain every per-session buffer in parallel. Safe to call at any
|
|
81
|
+
* point; failures route to onError, never thrown.
|
|
82
|
+
*/
|
|
83
|
+
async flush() {
|
|
84
|
+
await Promise.all([...this.handles.values()].map((h) => h.flush().catch((e) => this.engram.config.onError(e))));
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Final flush + stop timers. After shutdown the buffer is closed and
|
|
88
|
+
* further telemetry calls drop with onError.
|
|
89
|
+
*/
|
|
90
|
+
async shutdown() {
|
|
91
|
+
const all = [...this.handles.values()];
|
|
92
|
+
this.handles.clear();
|
|
93
|
+
await Promise.all(all.map((h) => h.shutdown().catch((e) => this.engram.config.onError(e))));
|
|
94
|
+
}
|
|
95
|
+
/** Test helper. Drops all in-memory state without flushing. */
|
|
96
|
+
resetForTests() {
|
|
97
|
+
this.handles.clear();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// --- Per-session buffer --------------------------------------------------
|
|
101
|
+
/**
|
|
102
|
+
* One BufferedSession per session id. Wraps the existing EngramSession
|
|
103
|
+
* (which already implements batched flush + retry) and gates the first
|
|
104
|
+
* flush on the session's create ack.
|
|
105
|
+
*/
|
|
106
|
+
class BufferedSession {
|
|
107
|
+
engram;
|
|
108
|
+
id;
|
|
109
|
+
ready;
|
|
110
|
+
inner;
|
|
111
|
+
ended = false;
|
|
112
|
+
constructor(engram, init) {
|
|
113
|
+
this.engram = engram;
|
|
114
|
+
this.id = init.id;
|
|
115
|
+
this.inner = new EngramSession(engram, init.id);
|
|
116
|
+
// Fire-and-forget POST /v1/sessions. The ready promise is awaited
|
|
117
|
+
// before the first flush so messages enqueued before the create
|
|
118
|
+
// ack don't race.
|
|
119
|
+
this.ready = engram
|
|
120
|
+
.startSessionWithoutHandle(init)
|
|
121
|
+
.catch((e) => {
|
|
122
|
+
engram.config.onError(e);
|
|
123
|
+
throw e;
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
message(input) {
|
|
127
|
+
try {
|
|
128
|
+
this.inner.recordMessage({
|
|
129
|
+
role: input.role,
|
|
130
|
+
content: normalizeContent(input.content),
|
|
131
|
+
...(input.at !== undefined ? { at: input.at } : {}),
|
|
132
|
+
...(input.model !== undefined ? { model: input.model } : {}),
|
|
133
|
+
...(input.tokens !== undefined ? { tokens: input.tokens } : {}),
|
|
134
|
+
...(input.message_id !== undefined ? { message_id: input.message_id } : {}),
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
catch (e) {
|
|
138
|
+
this.engram.config.onError(e);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
event(input) {
|
|
142
|
+
try {
|
|
143
|
+
switch (input.type) {
|
|
144
|
+
case "participant":
|
|
145
|
+
this.inner.addParticipant(input.personId);
|
|
146
|
+
break;
|
|
147
|
+
case "title":
|
|
148
|
+
this.inner.setTitle(input.title);
|
|
149
|
+
break;
|
|
150
|
+
case "step":
|
|
151
|
+
this.inner.recordStep({
|
|
152
|
+
tool: input.tool,
|
|
153
|
+
...(input.resources !== undefined ? { resources: input.resources } : {}),
|
|
154
|
+
...(input.input !== undefined ? { input: input.input } : {}),
|
|
155
|
+
...(input.result !== undefined ? { result: input.result } : {}),
|
|
156
|
+
});
|
|
157
|
+
break;
|
|
158
|
+
case "end":
|
|
159
|
+
void this.shutdown().catch((e) => this.engram.config.onError(e));
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
catch (e) {
|
|
164
|
+
this.engram.config.onError(e);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Merge updated session metadata via the patch endpoint. Fire-and-
|
|
169
|
+
* forget. Useful when a session was observed earlier with partial
|
|
170
|
+
* info and the host now has more (e.g. resolved channel later).
|
|
171
|
+
*/
|
|
172
|
+
update(input) {
|
|
173
|
+
// Only patch the fields callers might actually mutate post-creation;
|
|
174
|
+
// skip `participants` / `viewable_by` which are append-only via
|
|
175
|
+
// participant events.
|
|
176
|
+
const patch = {};
|
|
177
|
+
if (input.title !== undefined)
|
|
178
|
+
patch.title = input.title;
|
|
179
|
+
if (input.channel !== undefined)
|
|
180
|
+
patch.channel = input.channel;
|
|
181
|
+
if (input.status !== undefined)
|
|
182
|
+
patch.status = input.status;
|
|
183
|
+
if (input.summary !== undefined)
|
|
184
|
+
patch.summary = input.summary;
|
|
185
|
+
if (input.model !== undefined)
|
|
186
|
+
patch.model = input.model;
|
|
187
|
+
if (input.trigger_conversation_id !== undefined)
|
|
188
|
+
patch.trigger_conversation_id = input.trigger_conversation_id;
|
|
189
|
+
if (input.trigger_event_id !== undefined)
|
|
190
|
+
patch.trigger_event_id = input.trigger_event_id;
|
|
191
|
+
if (Object.keys(patch).length === 0)
|
|
192
|
+
return;
|
|
193
|
+
void this.ready
|
|
194
|
+
.then(() => this.engram.updateSession(this.id, patch))
|
|
195
|
+
.catch((e) => this.engram.config.onError(e));
|
|
196
|
+
}
|
|
197
|
+
async flush() {
|
|
198
|
+
// Don't fail downstream flushes if the create eventually succeeds
|
|
199
|
+
// after a retry — but skip flushing if the create has permanently
|
|
200
|
+
// failed (ready rejected).
|
|
201
|
+
try {
|
|
202
|
+
await this.ready;
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
await this.inner.flush();
|
|
208
|
+
}
|
|
209
|
+
async shutdown() {
|
|
210
|
+
if (this.ended)
|
|
211
|
+
return;
|
|
212
|
+
this.ended = true;
|
|
213
|
+
try {
|
|
214
|
+
await this.ready;
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
await this.inner.end();
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// --- Helpers --------------------------------------------------------------
|
|
223
|
+
function normalizeContent(content) {
|
|
224
|
+
if (typeof content === "string") {
|
|
225
|
+
return content.length > 0 ? [{ type: "text", text: content }] : [];
|
|
226
|
+
}
|
|
227
|
+
return content;
|
|
228
|
+
}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ScoredSession, SearchOptions, Session, SessionStep } from "@hexis-ai/engram-core";
|
|
2
2
|
import { type RefCandidate } from "./extract";
|
|
3
3
|
import type { AliasInfo, AliasUpsert, EventBatch, IdentityInfo, IdentityUpsert, MessageContentBlock, PersonCreate, PersonInfo, PersonMap, PersonUpdate, SessionEvent, SessionInit, SessionUpdate } from "./types";
|
|
4
|
+
import { type TelemetryEvent, type TelemetryMessage, type TelemetrySession } from "./buffered";
|
|
4
5
|
/**
|
|
5
6
|
* Envelope returned by session endpoints. The persons map is deduped
|
|
6
7
|
* across whatever sessions the response carries so display info isn't
|
|
@@ -93,13 +94,48 @@ export declare class Engram {
|
|
|
93
94
|
private readonly authHeaders?;
|
|
94
95
|
readonly maxRetries: number;
|
|
95
96
|
readonly retryBackoffMs: number;
|
|
97
|
+
private telemetry;
|
|
96
98
|
constructor(opts: EngramOptions);
|
|
99
|
+
/**
|
|
100
|
+
* Langfuse-style fire-and-forget telemetry surface. Lazily initialised
|
|
101
|
+
* so apps that never observe (search-only consumers) pay no overhead.
|
|
102
|
+
*/
|
|
103
|
+
private get bufferedTelemetry();
|
|
104
|
+
/**
|
|
105
|
+
* Observe a new (or already-known) session. Idempotent for the same id.
|
|
106
|
+
* Fire-and-forget — returns synchronously, transport failures route
|
|
107
|
+
* to `onError`.
|
|
108
|
+
*/
|
|
109
|
+
session(input: TelemetrySession): void;
|
|
110
|
+
/**
|
|
111
|
+
* Observe a message turn against an existing session. Call
|
|
112
|
+
* `session({id})` first so the create ack is queued.
|
|
113
|
+
*/
|
|
114
|
+
message(input: TelemetryMessage): void;
|
|
115
|
+
/**
|
|
116
|
+
* Observe an arbitrary session event (participant added, title set,
|
|
117
|
+
* tool step, end). Same fire-and-forget contract.
|
|
118
|
+
*/
|
|
119
|
+
event(input: TelemetryEvent): void;
|
|
120
|
+
/**
|
|
121
|
+
* Drain every per-session buffer. Call before short-lived processes
|
|
122
|
+
* exit; long-lived servers can rely on auto-flush (flushIntervalMs).
|
|
123
|
+
*/
|
|
124
|
+
flush(): Promise<void>;
|
|
125
|
+
/** Final flush + stop. Use at process exit. */
|
|
126
|
+
shutdown(): Promise<void>;
|
|
97
127
|
/** Probe identity — returns the workspace the configured key resolves to. */
|
|
98
128
|
me(): Promise<{
|
|
99
129
|
workspaceId: string;
|
|
100
130
|
}>;
|
|
101
131
|
/** Begin a new session. Returns a handle for buffering events. */
|
|
102
132
|
startSession(init?: SessionInit): Promise<EngramSession>;
|
|
133
|
+
/**
|
|
134
|
+
* POST /v1/sessions without constructing a handle. Used by
|
|
135
|
+
* BufferedTelemetry, which manages its own per-session handles and
|
|
136
|
+
* just needs the create ack.
|
|
137
|
+
*/
|
|
138
|
+
startSessionWithoutHandle(init: SessionInit): Promise<void>;
|
|
103
139
|
/** Fetch a single session by id, plus the persons map for its participants/viewers. */
|
|
104
140
|
getSession(id: string): Promise<SessionEnvelope>;
|
|
105
141
|
/**
|
package/dist/client.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { encodeResourceId, extractReferences } from "./extract";
|
|
2
2
|
import { parseToolName } from "./tool-name";
|
|
3
|
+
import { BufferedTelemetry, } from "./buffered";
|
|
3
4
|
export class Engram {
|
|
4
5
|
apiKey;
|
|
5
6
|
baseUrl;
|
|
@@ -11,6 +12,7 @@ export class Engram {
|
|
|
11
12
|
authHeaders;
|
|
12
13
|
maxRetries;
|
|
13
14
|
retryBackoffMs;
|
|
15
|
+
telemetry = null;
|
|
14
16
|
constructor(opts) {
|
|
15
17
|
if (!opts.apiKey)
|
|
16
18
|
throw new Error("Engram: apiKey is required");
|
|
@@ -27,6 +29,53 @@ export class Engram {
|
|
|
27
29
|
this.maxRetries = opts.maxRetries ?? 4;
|
|
28
30
|
this.retryBackoffMs = opts.retryBackoffMs ?? 500;
|
|
29
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Langfuse-style fire-and-forget telemetry surface. Lazily initialised
|
|
34
|
+
* so apps that never observe (search-only consumers) pay no overhead.
|
|
35
|
+
*/
|
|
36
|
+
get bufferedTelemetry() {
|
|
37
|
+
if (!this.telemetry)
|
|
38
|
+
this.telemetry = new BufferedTelemetry(this);
|
|
39
|
+
return this.telemetry;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Observe a new (or already-known) session. Idempotent for the same id.
|
|
43
|
+
* Fire-and-forget — returns synchronously, transport failures route
|
|
44
|
+
* to `onError`.
|
|
45
|
+
*/
|
|
46
|
+
session(input) {
|
|
47
|
+
this.bufferedTelemetry.session(input);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Observe a message turn against an existing session. Call
|
|
51
|
+
* `session({id})` first so the create ack is queued.
|
|
52
|
+
*/
|
|
53
|
+
message(input) {
|
|
54
|
+
this.bufferedTelemetry.message(input);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Observe an arbitrary session event (participant added, title set,
|
|
58
|
+
* tool step, end). Same fire-and-forget contract.
|
|
59
|
+
*/
|
|
60
|
+
event(input) {
|
|
61
|
+
this.bufferedTelemetry.event(input);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Drain every per-session buffer. Call before short-lived processes
|
|
65
|
+
* exit; long-lived servers can rely on auto-flush (flushIntervalMs).
|
|
66
|
+
*/
|
|
67
|
+
async flush() {
|
|
68
|
+
if (!this.telemetry)
|
|
69
|
+
return;
|
|
70
|
+
await this.telemetry.flush();
|
|
71
|
+
}
|
|
72
|
+
/** Final flush + stop. Use at process exit. */
|
|
73
|
+
async shutdown() {
|
|
74
|
+
if (!this.telemetry)
|
|
75
|
+
return;
|
|
76
|
+
await this.telemetry.shutdown();
|
|
77
|
+
this.telemetry = null;
|
|
78
|
+
}
|
|
30
79
|
/** Probe identity — returns the workspace the configured key resolves to. */
|
|
31
80
|
async me() {
|
|
32
81
|
return this.request("GET", "/v1/me");
|
|
@@ -36,6 +85,14 @@ export class Engram {
|
|
|
36
85
|
const ack = await this.request("POST", "/v1/sessions", init);
|
|
37
86
|
return new EngramSession(this, ack.id);
|
|
38
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* POST /v1/sessions without constructing a handle. Used by
|
|
90
|
+
* BufferedTelemetry, which manages its own per-session handles and
|
|
91
|
+
* just needs the create ack.
|
|
92
|
+
*/
|
|
93
|
+
async startSessionWithoutHandle(init) {
|
|
94
|
+
await this.request("POST", "/v1/sessions", init);
|
|
95
|
+
}
|
|
39
96
|
/** Fetch a single session by id, plus the persons map for its participants/viewers. */
|
|
40
97
|
async getSession(id) {
|
|
41
98
|
return this.request("GET", `/v1/sessions/${encodeURIComponent(id)}`);
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { Engram, EngramSession, type EngramOptions, type RecordStepInput, type SearchRequest, type SearchResponse, type SearchEnvelope, type SessionEnvelope, type SessionListEnvelope, } from "./client";
|
|
2
2
|
export { extractReferences, encodeResourceId, type RefCandidate, type ReferenceService, type ReferenceAction, } from "./extract";
|
|
3
3
|
export { parseToolName, type ParsedToolName } from "./tool-name";
|
|
4
|
+
export { BufferedTelemetry, type TelemetrySession, type TelemetryMessage, type TelemetryEvent, } from "./buffered";
|
|
4
5
|
export { fetchIdToken, cloudRunIdTokenAuth } from "./id-token";
|
|
5
6
|
export { EngramAdmin, createAdminClient, type AdminClientOptions, type CreateWorkspaceInput, type CreateWorkspaceResult, type Workspace as AdminWorkspace, type ApiKey as AdminApiKey, type IssuedKey as AdminIssuedKey, } from "./admin";
|
|
6
7
|
export type { SessionInit, SessionUpdate, SessionAck, SessionEvent, StepEvent, ParticipantEvent, TitleEvent, EndEvent, MessageContentBlock, MessageEvent, EventBatch, PersonInfo, PersonCreate, PersonUpdate, PersonMap, AliasInfo, AliasUpsert, IdentityInfo, IdentityUpsert, } from "./types";
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { Engram, EngramSession, } from "./client";
|
|
2
2
|
export { extractReferences, encodeResourceId, } from "./extract";
|
|
3
3
|
export { parseToolName } from "./tool-name";
|
|
4
|
+
export { BufferedTelemetry, } from "./buffered";
|
|
4
5
|
export { fetchIdToken, cloudRunIdTokenAuth } from "./id-token";
|
|
5
6
|
export { EngramAdmin, createAdminClient, } from "./admin";
|
package/package.json
CHANGED
|
@@ -1,27 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hexis-ai/engram-sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"keywords": [
|
|
6
|
-
"engram",
|
|
7
|
-
"agents",
|
|
8
|
-
"claude",
|
|
9
|
-
"anthropic",
|
|
10
|
-
"sdk",
|
|
11
|
-
"observability"
|
|
12
|
-
],
|
|
13
|
-
"homepage": "https://github.com/hexis-ltd/engram#readme",
|
|
3
|
+
"version": "0.11.0",
|
|
4
|
+
"author": "hexis ltd.",
|
|
14
5
|
"repository": {
|
|
15
6
|
"type": "git",
|
|
16
7
|
"url": "git+https://github.com/hexis-ltd/engram.git",
|
|
17
8
|
"directory": "packages/sdk"
|
|
18
9
|
},
|
|
19
|
-
"bugs": "https://github.com/hexis-ltd/engram/issues",
|
|
20
|
-
"author": "hexis ltd.",
|
|
21
|
-
"license": "MIT",
|
|
22
|
-
"type": "module",
|
|
23
10
|
"main": "dist/index.js",
|
|
24
|
-
"
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@hexis-ai/engram-core": "^0.2.0"
|
|
13
|
+
},
|
|
25
14
|
"exports": {
|
|
26
15
|
".": {
|
|
27
16
|
"types": "./dist/index.d.ts",
|
|
@@ -36,19 +25,30 @@
|
|
|
36
25
|
"default": "./dist/tool-name.js"
|
|
37
26
|
}
|
|
38
27
|
},
|
|
28
|
+
"bugs": "https://github.com/hexis-ltd/engram/issues",
|
|
29
|
+
"description": "Host SDK for engram. Records agent session steps and ships them to an engram server.",
|
|
39
30
|
"files": [
|
|
40
31
|
"dist"
|
|
41
32
|
],
|
|
33
|
+
"homepage": "https://github.com/hexis-ltd/engram#readme",
|
|
34
|
+
"keywords": [
|
|
35
|
+
"engram",
|
|
36
|
+
"agents",
|
|
37
|
+
"claude",
|
|
38
|
+
"anthropic",
|
|
39
|
+
"sdk",
|
|
40
|
+
"observability"
|
|
41
|
+
],
|
|
42
|
+
"license": "MIT",
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"access": "public"
|
|
45
|
+
},
|
|
42
46
|
"scripts": {
|
|
43
47
|
"build": "rm -rf dist && tsc -p tsconfig.build.json",
|
|
44
48
|
"pack": "bun run build && bun pm pack",
|
|
45
49
|
"test": "bun test",
|
|
46
50
|
"type-check": "tsc --noEmit"
|
|
47
51
|
},
|
|
48
|
-
"
|
|
49
|
-
|
|
50
|
-
},
|
|
51
|
-
"publishConfig": {
|
|
52
|
-
"access": "public"
|
|
53
|
-
}
|
|
52
|
+
"type": "module",
|
|
53
|
+
"types": "dist/index.d.ts"
|
|
54
54
|
}
|