@hexis-ai/engram-sdk 0.11.0 → 0.12.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 +52 -0
- package/dist/buffered.js +62 -25
- package/dist/client.d.ts +19 -1
- package/dist/client.js +24 -0
- package/dist/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/buffered.d.ts
CHANGED
|
@@ -70,6 +70,47 @@ export type TelemetryEvent = {
|
|
|
70
70
|
type: "end";
|
|
71
71
|
at?: string;
|
|
72
72
|
};
|
|
73
|
+
/**
|
|
74
|
+
* Person observation. Same Langfuse-style semantics as session():
|
|
75
|
+
* host-supplied id, idempotent on the engram side (PUT /v1/persons/:id).
|
|
76
|
+
* Subsequent calls with the same id COALESCE — partial-info updates
|
|
77
|
+
* never clobber richer fields set earlier.
|
|
78
|
+
*/
|
|
79
|
+
export interface TelemetryPerson {
|
|
80
|
+
id: string;
|
|
81
|
+
displayName?: string;
|
|
82
|
+
role?: string | null;
|
|
83
|
+
team?: string | null;
|
|
84
|
+
source?: string;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Identity observation — links a global ref like `slack:U12345` or
|
|
88
|
+
* `email:foo@bar.com` to a person id. Idempotent (PUT
|
|
89
|
+
* /v1/identities/:ref); writing a new person_id reroutes the ref.
|
|
90
|
+
*/
|
|
91
|
+
export interface TelemetryIdentity {
|
|
92
|
+
ref: string;
|
|
93
|
+
personId: string;
|
|
94
|
+
service: string;
|
|
95
|
+
externalId: string;
|
|
96
|
+
displayName?: string | null;
|
|
97
|
+
source?: string | null;
|
|
98
|
+
picture?: string | null;
|
|
99
|
+
isPrimary?: boolean | null;
|
|
100
|
+
linkedAt: string;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Alias observation — a name the person goes by. The engram side
|
|
104
|
+
* key-collapses on (person_id, lower(name)); same name twice with
|
|
105
|
+
* `increment: true` bumps usage_count (default).
|
|
106
|
+
*/
|
|
107
|
+
export interface TelemetryAlias {
|
|
108
|
+
personId: string;
|
|
109
|
+
name: string;
|
|
110
|
+
caller: string;
|
|
111
|
+
lastUsed: string;
|
|
112
|
+
increment?: boolean;
|
|
113
|
+
}
|
|
73
114
|
/**
|
|
74
115
|
* Internal coordinator that owns per-session buffers and gates flushes
|
|
75
116
|
* on session-creation acks. Exposed on the parent Engram via
|
|
@@ -94,6 +135,17 @@ export declare class BufferedTelemetry {
|
|
|
94
135
|
message(input: TelemetryMessage): void;
|
|
95
136
|
/** Observe an arbitrary session event (participant / title / step / end). */
|
|
96
137
|
event(input: TelemetryEvent): void;
|
|
138
|
+
/**
|
|
139
|
+
* Observe a person. Unlike session events these don't fan out to a
|
|
140
|
+
* per-session buffer — each call is an immediate fire-and-forget
|
|
141
|
+
* PUT via the SDK's low-level `persons.upsert`. Transport failures
|
|
142
|
+
* surface via onError and are not retried.
|
|
143
|
+
*/
|
|
144
|
+
person(input: TelemetryPerson): void;
|
|
145
|
+
/** Observe an identity (ref → person_id link). */
|
|
146
|
+
identity(input: TelemetryIdentity): void;
|
|
147
|
+
/** Observe an alias (person nickname). */
|
|
148
|
+
alias(input: TelemetryAlias): void;
|
|
97
149
|
/**
|
|
98
150
|
* Drain every per-session buffer in parallel. Safe to call at any
|
|
99
151
|
* point; failures route to onError, never thrown.
|
package/dist/buffered.js
CHANGED
|
@@ -76,6 +76,47 @@ export class BufferedTelemetry {
|
|
|
76
76
|
}
|
|
77
77
|
handle.event(input);
|
|
78
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Observe a person. Unlike session events these don't fan out to a
|
|
81
|
+
* per-session buffer — each call is an immediate fire-and-forget
|
|
82
|
+
* PUT via the SDK's low-level `persons.upsert`. Transport failures
|
|
83
|
+
* surface via onError and are not retried.
|
|
84
|
+
*/
|
|
85
|
+
person(input) {
|
|
86
|
+
void this.engram.persons
|
|
87
|
+
.upsert(input.id, {
|
|
88
|
+
...(input.displayName !== undefined ? { display_name: input.displayName } : {}),
|
|
89
|
+
...(input.role !== undefined ? { role: input.role } : {}),
|
|
90
|
+
...(input.team !== undefined ? { team: input.team } : {}),
|
|
91
|
+
...(input.source !== undefined ? { source: input.source } : {}),
|
|
92
|
+
})
|
|
93
|
+
.catch((e) => this.engram.config.onError(e));
|
|
94
|
+
}
|
|
95
|
+
/** Observe an identity (ref → person_id link). */
|
|
96
|
+
identity(input) {
|
|
97
|
+
void this.engram.identities
|
|
98
|
+
.upsert(input.ref, {
|
|
99
|
+
person_id: input.personId,
|
|
100
|
+
service: input.service,
|
|
101
|
+
external_id: input.externalId,
|
|
102
|
+
...(input.displayName !== undefined ? { display_name: input.displayName } : {}),
|
|
103
|
+
...(input.source !== undefined ? { source: input.source } : {}),
|
|
104
|
+
...(input.picture !== undefined ? { picture: input.picture } : {}),
|
|
105
|
+
...(input.isPrimary !== undefined ? { is_primary: input.isPrimary } : {}),
|
|
106
|
+
linked_at: input.linkedAt,
|
|
107
|
+
})
|
|
108
|
+
.catch((e) => this.engram.config.onError(e));
|
|
109
|
+
}
|
|
110
|
+
/** Observe an alias (person nickname). */
|
|
111
|
+
alias(input) {
|
|
112
|
+
void this.engram.persons
|
|
113
|
+
.upsertAlias(input.personId, input.name, {
|
|
114
|
+
caller: input.caller,
|
|
115
|
+
last_used: input.lastUsed,
|
|
116
|
+
...(input.increment !== undefined ? { increment: input.increment } : {}),
|
|
117
|
+
})
|
|
118
|
+
.catch((e) => this.engram.config.onError(e));
|
|
119
|
+
}
|
|
79
120
|
/**
|
|
80
121
|
* Drain every per-session buffer in parallel. Safe to call at any
|
|
81
122
|
* point; failures route to onError, never thrown.
|
|
@@ -106,6 +147,12 @@ export class BufferedTelemetry {
|
|
|
106
147
|
class BufferedSession {
|
|
107
148
|
engram;
|
|
108
149
|
id;
|
|
150
|
+
/**
|
|
151
|
+
* Resolves to `true` when POST /v1/sessions acked, `false` on
|
|
152
|
+
* transport failure. Never rejects — preserves Bun's strict
|
|
153
|
+
* unhandled-rejection contract even when callers don't await
|
|
154
|
+
* the buffer (Langfuse-style fire-and-forget).
|
|
155
|
+
*/
|
|
109
156
|
ready;
|
|
110
157
|
inner;
|
|
111
158
|
ended = false;
|
|
@@ -113,14 +160,12 @@ class BufferedSession {
|
|
|
113
160
|
this.engram = engram;
|
|
114
161
|
this.id = init.id;
|
|
115
162
|
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
163
|
this.ready = engram
|
|
120
164
|
.startSessionWithoutHandle(init)
|
|
165
|
+
.then(() => true)
|
|
121
166
|
.catch((e) => {
|
|
122
167
|
engram.config.onError(e);
|
|
123
|
-
|
|
168
|
+
return false;
|
|
124
169
|
});
|
|
125
170
|
}
|
|
126
171
|
message(input) {
|
|
@@ -170,9 +215,6 @@ class BufferedSession {
|
|
|
170
215
|
* info and the host now has more (e.g. resolved channel later).
|
|
171
216
|
*/
|
|
172
217
|
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
218
|
const patch = {};
|
|
177
219
|
if (input.title !== undefined)
|
|
178
220
|
patch.title = input.title;
|
|
@@ -190,33 +232,28 @@ class BufferedSession {
|
|
|
190
232
|
patch.trigger_event_id = input.trigger_event_id;
|
|
191
233
|
if (Object.keys(patch).length === 0)
|
|
192
234
|
return;
|
|
193
|
-
void this.ready
|
|
194
|
-
|
|
195
|
-
|
|
235
|
+
void this.ready.then((ok) => {
|
|
236
|
+
if (!ok)
|
|
237
|
+
return;
|
|
238
|
+
return this.engram
|
|
239
|
+
.updateSession(this.id, patch)
|
|
240
|
+
.catch((e) => this.engram.config.onError(e));
|
|
241
|
+
});
|
|
196
242
|
}
|
|
197
243
|
async flush() {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
// failed (ready rejected).
|
|
201
|
-
try {
|
|
202
|
-
await this.ready;
|
|
203
|
-
}
|
|
204
|
-
catch {
|
|
244
|
+
const ok = await this.ready;
|
|
245
|
+
if (!ok)
|
|
205
246
|
return;
|
|
206
|
-
|
|
207
|
-
await this.inner.flush();
|
|
247
|
+
await this.inner.flush().catch((e) => this.engram.config.onError(e));
|
|
208
248
|
}
|
|
209
249
|
async shutdown() {
|
|
210
250
|
if (this.ended)
|
|
211
251
|
return;
|
|
212
252
|
this.ended = true;
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
}
|
|
216
|
-
catch {
|
|
253
|
+
const ok = await this.ready;
|
|
254
|
+
if (!ok)
|
|
217
255
|
return;
|
|
218
|
-
|
|
219
|
-
await this.inner.end();
|
|
256
|
+
await this.inner.end().catch((e) => this.engram.config.onError(e));
|
|
220
257
|
}
|
|
221
258
|
}
|
|
222
259
|
// --- Helpers --------------------------------------------------------------
|
package/dist/client.d.ts
CHANGED
|
@@ -1,7 +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
|
+
import { type TelemetryAlias, type TelemetryEvent, type TelemetryIdentity, type TelemetryMessage, type TelemetryPerson, type TelemetrySession } from "./buffered";
|
|
5
5
|
/**
|
|
6
6
|
* Envelope returned by session endpoints. The persons map is deduped
|
|
7
7
|
* across whatever sessions the response carries so display info isn't
|
|
@@ -117,6 +117,24 @@ export declare class Engram {
|
|
|
117
117
|
* tool step, end). Same fire-and-forget contract.
|
|
118
118
|
*/
|
|
119
119
|
event(input: TelemetryEvent): void;
|
|
120
|
+
/**
|
|
121
|
+
* Observe a person record (display_name / role / team / source).
|
|
122
|
+
* Idempotent on the engram side — partial-info updates COALESCE.
|
|
123
|
+
* Fire-and-forget; transport failures route to `onError`.
|
|
124
|
+
*/
|
|
125
|
+
person(input: TelemetryPerson): void;
|
|
126
|
+
/**
|
|
127
|
+
* Observe an identity (`slack:U1`, `email:foo@bar.com`, …) and link
|
|
128
|
+
* it to a person id. Writing a new person_id to an existing ref
|
|
129
|
+
* reroutes the ref. Fire-and-forget.
|
|
130
|
+
*/
|
|
131
|
+
identity(input: TelemetryIdentity): void;
|
|
132
|
+
/**
|
|
133
|
+
* Observe an alias (a name the person goes by). Engram side
|
|
134
|
+
* collapses on (person_id, lower(name)); same name twice with
|
|
135
|
+
* `increment: true` bumps usage_count. Fire-and-forget.
|
|
136
|
+
*/
|
|
137
|
+
alias(input: TelemetryAlias): void;
|
|
120
138
|
/**
|
|
121
139
|
* Drain every per-session buffer. Call before short-lived processes
|
|
122
140
|
* exit; long-lived servers can rely on auto-flush (flushIntervalMs).
|
package/dist/client.js
CHANGED
|
@@ -60,6 +60,30 @@ export class Engram {
|
|
|
60
60
|
event(input) {
|
|
61
61
|
this.bufferedTelemetry.event(input);
|
|
62
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Observe a person record (display_name / role / team / source).
|
|
65
|
+
* Idempotent on the engram side — partial-info updates COALESCE.
|
|
66
|
+
* Fire-and-forget; transport failures route to `onError`.
|
|
67
|
+
*/
|
|
68
|
+
person(input) {
|
|
69
|
+
this.bufferedTelemetry.person(input);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Observe an identity (`slack:U1`, `email:foo@bar.com`, …) and link
|
|
73
|
+
* it to a person id. Writing a new person_id to an existing ref
|
|
74
|
+
* reroutes the ref. Fire-and-forget.
|
|
75
|
+
*/
|
|
76
|
+
identity(input) {
|
|
77
|
+
this.bufferedTelemetry.identity(input);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Observe an alias (a name the person goes by). Engram side
|
|
81
|
+
* collapses on (person_id, lower(name)); same name twice with
|
|
82
|
+
* `increment: true` bumps usage_count. Fire-and-forget.
|
|
83
|
+
*/
|
|
84
|
+
alias(input) {
|
|
85
|
+
this.bufferedTelemetry.alias(input);
|
|
86
|
+
}
|
|
63
87
|
/**
|
|
64
88
|
* Drain every per-session buffer. Call before short-lived processes
|
|
65
89
|
* exit; long-lived servers can rely on auto-flush (flushIntervalMs).
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +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
|
+
export { BufferedTelemetry, type TelemetrySession, type TelemetryMessage, type TelemetryEvent, type TelemetryPerson, type TelemetryIdentity, type TelemetryAlias, } from "./buffered";
|
|
5
5
|
export { fetchIdToken, cloudRunIdTokenAuth } from "./id-token";
|
|
6
6
|
export { EngramAdmin, createAdminClient, type AdminClientOptions, type CreateWorkspaceInput, type CreateWorkspaceResult, type Workspace as AdminWorkspace, type ApiKey as AdminApiKey, type IssuedKey as AdminIssuedKey, } from "./admin";
|
|
7
7
|
export type { SessionInit, SessionUpdate, SessionAck, SessionEvent, StepEvent, ParticipantEvent, TitleEvent, EndEvent, MessageContentBlock, MessageEvent, EventBatch, PersonInfo, PersonCreate, PersonUpdate, PersonMap, AliasInfo, AliasUpsert, IdentityInfo, IdentityUpsert, } from "./types";
|