@hexis-ai/engram-sdk 0.4.0 → 0.6.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/client.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { ScoredSession, SearchOptions, Session, SessionStep } from "@hexis-ai/engram-core";
2
2
  import { type RefCandidate } from "./extract";
3
- import type { AliasInfo, AliasUpsert, EventBatch, PersonCreate, PersonInfo, PersonMap, PersonUpdate, SessionEvent, SessionInit } from "./types";
3
+ import type { AliasInfo, AliasUpsert, EventBatch, IdentityInfo, IdentityUpsert, MessageContentBlock, PersonCreate, PersonInfo, PersonMap, PersonUpdate, SessionEvent, SessionInit } from "./types";
4
4
  /**
5
5
  * Envelope returned by session endpoints. The persons map is deduped
6
6
  * across whatever sessions the response carries so display info isn't
@@ -151,6 +151,20 @@ export declare class Engram {
151
151
  aliases: (id: string) => Promise<{
152
152
  aliases: AliasInfo[];
153
153
  }>;
154
+ /** This person's identities, newest-linked-first. */
155
+ identities: (id: string) => Promise<{
156
+ identities: IdentityInfo[];
157
+ }>;
158
+ };
159
+ /** Identity operations — resolve a global ref (`slack:U…`, `email:…`)
160
+ * to its identity record + person id. */
161
+ readonly identities: {
162
+ /** Upsert by ref. Refs are reassignable — writing with a new
163
+ * `person_id` reroutes the ref. Returns 404 if `person_id` is
164
+ * unknown. */
165
+ upsert: (ref: string, input: IdentityUpsert) => Promise<IdentityInfo>;
166
+ /** Look up by ref. Returns 404 if the ref is unknown. */
167
+ get: (ref: string) => Promise<IdentityInfo>;
154
168
  };
155
169
  /** Internal: ship an event batch to the server. */
156
170
  sendBatch(sessionId: string, batch: EventBatch): Promise<void>;
@@ -176,6 +190,28 @@ export declare class EngramSession {
176
190
  * resolved by the host (engram-server does not resolve platform identities). */
177
191
  addParticipant(personId: string): void;
178
192
  setTitle(title: string): void;
193
+ /**
194
+ * Append a turn to the session. `content` is an Anthropic-shaped
195
+ * block array — the same shape monet stores in
196
+ * `conversation_messages.trace`, with `text` + `tool_use` +
197
+ * `tool_result` blocks. Re-emitting with the same `message_id` is
198
+ * intentional: the host may want to refresh content (e.g. after
199
+ * summarisation rewrites the user-visible text).
200
+ */
201
+ recordMessage(input: {
202
+ role: string;
203
+ content: MessageContentBlock[];
204
+ message_id?: string;
205
+ model?: string;
206
+ tokens?: {
207
+ input: number;
208
+ output: number;
209
+ };
210
+ /** When omitted, the SDK stamps `at` to the wall-clock moment of
211
+ * enqueue — appropriate for live agent emission. Pass an explicit
212
+ * ISO string to mirror an existing host record's timestamp. */
213
+ at?: string;
214
+ }): void;
179
215
  /** Mark the session ended and flush buffered events. */
180
216
  end(): Promise<void>;
181
217
  /**
package/dist/client.js CHANGED
@@ -104,6 +104,18 @@ export class Engram {
104
104
  upsertAlias: (id, name, input) => this.request("PUT", `/v1/persons/${encodeURIComponent(id)}/aliases/${encodeURIComponent(name)}`, input),
105
105
  /** This person's aliases, newest-used-first. */
106
106
  aliases: (id) => this.request("GET", `/v1/persons/${encodeURIComponent(id)}/aliases`),
107
+ /** This person's identities, newest-linked-first. */
108
+ identities: (id) => this.request("GET", `/v1/persons/${encodeURIComponent(id)}/identities`),
109
+ };
110
+ /** Identity operations — resolve a global ref (`slack:U…`, `email:…`)
111
+ * to its identity record + person id. */
112
+ identities = {
113
+ /** Upsert by ref. Refs are reassignable — writing with a new
114
+ * `person_id` reroutes the ref. Returns 404 if `person_id` is
115
+ * unknown. */
116
+ upsert: (ref, input) => this.request("PUT", `/v1/identities/${encodeURIComponent(ref)}`, input),
117
+ /** Look up by ref. Returns 404 if the ref is unknown. */
118
+ get: (ref) => this.request("GET", `/v1/identities/${encodeURIComponent(ref)}`),
107
119
  };
108
120
  /** Internal: ship an event batch to the server. */
109
121
  async sendBatch(sessionId, batch) {
@@ -187,6 +199,27 @@ export class EngramSession {
187
199
  };
188
200
  this.enqueue(ev);
189
201
  }
202
+ /**
203
+ * Append a turn to the session. `content` is an Anthropic-shaped
204
+ * block array — the same shape monet stores in
205
+ * `conversation_messages.trace`, with `text` + `tool_use` +
206
+ * `tool_result` blocks. Re-emitting with the same `message_id` is
207
+ * intentional: the host may want to refresh content (e.g. after
208
+ * summarisation rewrites the user-visible text).
209
+ */
210
+ recordMessage(input) {
211
+ const ev = {
212
+ type: "message",
213
+ seq: this.seq++,
214
+ at: input.at ?? new Date().toISOString(),
215
+ role: input.role,
216
+ content: input.content,
217
+ ...(input.message_id !== undefined ? { message_id: input.message_id } : {}),
218
+ ...(input.model !== undefined ? { model: input.model } : {}),
219
+ ...(input.tokens !== undefined ? { tokens: input.tokens } : {}),
220
+ };
221
+ this.enqueue(ev);
222
+ }
190
223
  /** Mark the session ended and flush buffered events. */
191
224
  async end() {
192
225
  if (this.ended)
package/dist/index.d.ts CHANGED
@@ -3,4 +3,4 @@ export { extractReferences, encodeResourceId, type RefCandidate, type ReferenceS
3
3
  export { parseToolName, type ParsedToolName } from "./tool-name";
4
4
  export { fetchIdToken, cloudRunIdTokenAuth } from "./id-token";
5
5
  export { EngramAdmin, createAdminClient, type AdminClientOptions, type CreateWorkspaceInput, type CreateWorkspaceResult, type Workspace as AdminWorkspace, type ApiKey as AdminApiKey, type IssuedKey as AdminIssuedKey, } from "./admin";
6
- export type { SessionInit, SessionAck, SessionEvent, StepEvent, ParticipantEvent, TitleEvent, EndEvent, EventBatch, PersonInfo, PersonCreate, PersonUpdate, PersonMap, AliasInfo, AliasUpsert, } from "./types";
6
+ export type { SessionInit, SessionAck, SessionEvent, StepEvent, ParticipantEvent, TitleEvent, EndEvent, MessageContentBlock, MessageEvent, EventBatch, PersonInfo, PersonCreate, PersonUpdate, PersonMap, AliasInfo, AliasUpsert, IdentityInfo, IdentityUpsert, } from "./types";
package/dist/types.d.ts CHANGED
@@ -54,7 +54,64 @@ export interface EndEvent {
54
54
  seq: number;
55
55
  at: string;
56
56
  }
57
- export type SessionEvent = StepEvent | ParticipantEvent | TitleEvent | EndEvent;
57
+ /**
58
+ * One block within a message's content. Modelled after Anthropic's
59
+ * Messages API content blocks so SDK callers can pass agent runtime
60
+ * output through with zero translation. The discriminated union covers
61
+ * the standard block types; unknown `type` values pass through
62
+ * untouched so future Anthropic / vendor blocks don't require an SDK
63
+ * upgrade to ingest.
64
+ */
65
+ export type MessageContentBlock = {
66
+ type: "text";
67
+ text: string;
68
+ } | {
69
+ type: "tool_use";
70
+ id: string;
71
+ name: string;
72
+ input: unknown;
73
+ } | {
74
+ type: "tool_result";
75
+ tool_use_id: string;
76
+ content: unknown;
77
+ is_error?: boolean;
78
+ } | {
79
+ type: "thinking";
80
+ thinking: string;
81
+ } | {
82
+ type: string;
83
+ [k: string]: unknown;
84
+ };
85
+ /**
86
+ * One turn in a session — the canonical record of what someone or the
87
+ * agent actually said/did. Carries the full Anthropic-shaped content
88
+ * (text + tool_use + tool_result + thinking + …) so engram is lossless
89
+ * relative to monet's PG transcript.
90
+ *
91
+ * `role` is intentionally `string` rather than `user|assistant` because
92
+ * monet-style channel-originated turns use richer role labels (`system`,
93
+ * `resume`, identity refs like `slack:U…`). Tighten to a union on the
94
+ * read side if a consumer needs it; the wire stays permissive.
95
+ */
96
+ export interface MessageEvent {
97
+ type: "message";
98
+ seq: number;
99
+ at: string;
100
+ /** Stable host-side id (monet's `conversation_messages` row id). The
101
+ * same logical message can be re-emitted idempotently if the host
102
+ * needs to update content (e.g. summarisation rewrite). */
103
+ message_id?: string;
104
+ role: string;
105
+ content: MessageContentBlock[];
106
+ /** Model + usage metadata captured at write time. Optional because
107
+ * inbound channel messages (slack, calendar) don't have these. */
108
+ model?: string;
109
+ tokens?: {
110
+ input: number;
111
+ output: number;
112
+ };
113
+ }
114
+ export type SessionEvent = StepEvent | ParticipantEvent | TitleEvent | EndEvent | MessageEvent;
58
115
  export interface EventBatch {
59
116
  events: SessionEvent[];
60
117
  }
@@ -105,6 +162,38 @@ export interface AliasUpsert {
105
162
  */
106
163
  increment?: boolean;
107
164
  }
165
+ /**
166
+ * One external identity mapped to an engram person. Hosts (monet) use
167
+ * the same ref convention they always have — `slack:U12345`,
168
+ * `email:foo@bar.com`, `google:1234567890` — so engram can serve as
169
+ * the resolver for any system that already speaks that vocabulary.
170
+ */
171
+ export interface IdentityInfo {
172
+ /** Stable global handle, e.g. `slack:U12345`. */
173
+ ref: string;
174
+ person_id: string;
175
+ service: string;
176
+ external_id: string;
177
+ display_name: string | null;
178
+ source: string | null;
179
+ is_primary: boolean | null;
180
+ picture: string | null;
181
+ /** `YYYY-MM-DD`. */
182
+ linked_at: string;
183
+ created_at: string;
184
+ updated_at: string;
185
+ }
186
+ export interface IdentityUpsert {
187
+ person_id: string;
188
+ service: string;
189
+ external_id: string;
190
+ display_name?: string | null;
191
+ source?: string | null;
192
+ is_primary?: boolean | null;
193
+ picture?: string | null;
194
+ /** `YYYY-MM-DD`. */
195
+ linked_at: string;
196
+ }
108
197
  /**
109
198
  * Map of person_id → PersonInfo, deduped across whatever `Session`s the
110
199
  * response contains. Returned at the envelope level so list responses
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hexis-ai/engram-sdk",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "Host SDK for engram. Records agent session steps and ships them to an engram server.",
5
5
  "keywords": [
6
6
  "engram",