@statewavedev/sdk 0.7.1 → 0.9.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/README.md +71 -13
- package/dist/client.d.ts +17 -2
- package/dist/client.js +95 -14
- package/dist/types.d.ts +148 -30
- package/dist/types.js +10 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,6 +10,8 @@ Official TypeScript SDK for [Statewave](https://github.com/smaramwbc/statewave)
|
|
|
10
10
|
>
|
|
11
11
|
> 📋 **Issues & feature requests:** [statewave/issues](https://github.com/smaramwbc/statewave/issues) (centralized tracker)
|
|
12
12
|
|
|
13
|
+
> ⚠️ **v0.9.0 is a breaking change.** The entire SDK surface — request params *and* response fields — is now idiomatic **camelCase** (`subjectId`, `maxTokens`, `createdAt`, `receiptId`, …). The wire protocol is unchanged; the client maps to/from the server's snake_case transparently. `payload`, `metadata`, and `provenance` are passed through verbatim — their inner keys are never rewritten. See [CHANGELOG](CHANGELOG.md#090) for the full rename table and migration steps.
|
|
14
|
+
|
|
13
15
|
## Install
|
|
14
16
|
|
|
15
17
|
```bash
|
|
@@ -33,7 +35,7 @@ const swAuth = new StatewaveClient({
|
|
|
33
35
|
|
|
34
36
|
// Record an episode
|
|
35
37
|
await sw.createEpisode({
|
|
36
|
-
|
|
38
|
+
subjectId: "user-42",
|
|
37
39
|
source: "support-chat",
|
|
38
40
|
type: "conversation",
|
|
39
41
|
payload: {
|
|
@@ -46,31 +48,31 @@ await sw.createEpisode({
|
|
|
46
48
|
|
|
47
49
|
// Compile memories (idempotent)
|
|
48
50
|
const result = await sw.compileMemories("user-42");
|
|
49
|
-
console.log(`Created ${result.
|
|
51
|
+
console.log(`Created ${result.memoriesCreated} memories`);
|
|
50
52
|
|
|
51
53
|
// Retrieve ranked, token-bounded context
|
|
52
54
|
const ctx = await sw.getContext({
|
|
53
|
-
|
|
55
|
+
subjectId: "user-42",
|
|
54
56
|
task: "Help with billing",
|
|
55
|
-
|
|
57
|
+
maxTokens: 300,
|
|
56
58
|
});
|
|
57
|
-
console.log(ctx.
|
|
59
|
+
console.log(ctx.assembledContext);
|
|
58
60
|
|
|
59
61
|
// Batch ingestion (up to 100)
|
|
60
62
|
await sw.createEpisodesBatch([
|
|
61
|
-
{
|
|
62
|
-
{
|
|
63
|
+
{ subjectId: "user-42", source: "crm", type: "note", payload: { text: "Prefers email" } },
|
|
64
|
+
{ subjectId: "user-42", source: "crm", type: "note", payload: { text: "Enterprise plan" } },
|
|
63
65
|
]);
|
|
64
66
|
|
|
65
67
|
// Search memories
|
|
66
68
|
const facts = await sw.searchMemories({
|
|
67
|
-
|
|
69
|
+
subjectId: "user-42",
|
|
68
70
|
kind: "profile_fact",
|
|
69
71
|
});
|
|
70
72
|
|
|
71
73
|
// Semantic search (requires embeddings)
|
|
72
74
|
const results = await sw.searchMemories({
|
|
73
|
-
|
|
75
|
+
subjectId: "user-42",
|
|
74
76
|
query: "billing",
|
|
75
77
|
semantic: true,
|
|
76
78
|
});
|
|
@@ -78,7 +80,7 @@ const results = await sw.searchMemories({
|
|
|
78
80
|
// List all known subjects
|
|
79
81
|
const subjects = await sw.listSubjects();
|
|
80
82
|
for (const s of subjects.subjects) {
|
|
81
|
-
console.log(`${s.
|
|
83
|
+
console.log(`${s.subjectId}: ${s.episodeCount} episodes, ${s.memoryCount} memories`);
|
|
82
84
|
}
|
|
83
85
|
|
|
84
86
|
// Get timeline
|
|
@@ -89,6 +91,60 @@ console.log(`${timeline.episodes.length} episodes, ${timeline.memories.length} m
|
|
|
89
91
|
await sw.deleteSubject("user-42");
|
|
90
92
|
```
|
|
91
93
|
|
|
94
|
+
## Governance & audit (v0.8)
|
|
95
|
+
|
|
96
|
+
The SDK surfaces the [state-assembly receipts](https://github.com/smaramwbc/statewave-docs/blob/main/receipts.md) and [sensitivity-labels / policy](https://github.com/smaramwbc/statewave-docs/blob/main/sensitivity-labels.md) layer added in server v0.8.
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
import { StatewaveClient } from "@statewavedev/sdk";
|
|
100
|
+
|
|
101
|
+
const sw = new StatewaveClient({
|
|
102
|
+
baseUrl: "http://localhost:8100",
|
|
103
|
+
apiKey: "your-key",
|
|
104
|
+
tenantId: "acme",
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Per-request opt-in for an immutable audit receipt of the assembly.
|
|
108
|
+
// callerId / callerType feed the sensitivity-label policy engine —
|
|
109
|
+
// when the tenant config sets require_caller_identity=true, missing
|
|
110
|
+
// values 401.
|
|
111
|
+
const bundle = await sw.getContext({
|
|
112
|
+
subjectId: "user-42",
|
|
113
|
+
task: "What plan is this customer on?",
|
|
114
|
+
emitReceipt: true,
|
|
115
|
+
callerId: "agent-7",
|
|
116
|
+
callerType: "support_agent",
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
if (bundle.receiptId) {
|
|
120
|
+
// Receipts are ULID-addressable, tenant-scoped, append-only.
|
|
121
|
+
const receipt = await sw.getReceipt(bundle.receiptId);
|
|
122
|
+
// output.contextHash is a SHA-256 of the bytes delivered to the
|
|
123
|
+
// agent — recompute from bundle.assembledContext to verify integrity.
|
|
124
|
+
console.log(receipt.output.contextHash);
|
|
125
|
+
console.log(`${receipt.selectedEntries.length} entries influenced this bundle`);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// List receipts for a subject, cursor-paginated, newest-first.
|
|
129
|
+
const { receipts, nextCursor } = await sw.listReceipts({
|
|
130
|
+
subjectId: "user-42",
|
|
131
|
+
limit: 10,
|
|
132
|
+
});
|
|
133
|
+
for (const r of receipts) {
|
|
134
|
+
console.log(r.receiptId, r.task);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Set per-memory sensitivity labels (server normalizes — dedup, lowercase, trim).
|
|
138
|
+
// Memories with labels become subject to any active policy bundle for the tenant.
|
|
139
|
+
const updated = await sw.setMemoryLabels({
|
|
140
|
+
memoryId: "mem-uuid",
|
|
141
|
+
sensitivityLabels: ["pii", "financial"],
|
|
142
|
+
});
|
|
143
|
+
console.log(updated.sensitivityLabels); // → ["financial", "pii"]
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Receipts and the policy engine cooperate: every assembly call records its policy decisions into `receipt.policy.filtersApplied` (one entry per memory the policy fired on) and `receipt.policy.filtersSkipped` (per-rule summary of what didn't fire). In `log_only` mode (the tenant default) the receipt is the full audit trail without filtering; under `enforce` denied memories are dropped before they reach the assembly and the deny is still recorded. See [`receipts.md`](https://github.com/smaramwbc/statewave-docs/blob/main/receipts.md) and [`sensitivity-labels.md`](https://github.com/smaramwbc/statewave-docs/blob/main/sensitivity-labels.md) for the full schemas and policy YAML format.
|
|
147
|
+
|
|
92
148
|
## Error handling
|
|
93
149
|
|
|
94
150
|
```typescript
|
|
@@ -122,17 +178,19 @@ See [Privacy & Data Flow](https://github.com/smaramwbc/statewave-docs/blob/main/
|
|
|
122
178
|
All response types are fully typed:
|
|
123
179
|
|
|
124
180
|
- `Episode` — raw interaction record
|
|
125
|
-
- `Memory` — compiled memory with provenance
|
|
181
|
+
- `Memory` — compiled memory with provenance + optional `sensitivityLabels`
|
|
126
182
|
- `CompileResult` — compilation response
|
|
127
183
|
- `SearchResult` — search response
|
|
128
|
-
- `ContextBundle` — assembled context with facts, episodes, provenance
|
|
184
|
+
- `ContextBundle` — assembled context with facts, episodes, provenance, optional `receiptId` / `receiptEmitted`
|
|
129
185
|
- `Timeline` — chronological subject history
|
|
130
186
|
- `DeleteResult` — deletion confirmation
|
|
131
187
|
- `BatchCreateResult` — batch ingestion response
|
|
132
188
|
- `SubjectSummary` — subject with episode/memory counts
|
|
133
189
|
- `ListSubjectsResult` — paginated subject listing
|
|
190
|
+
- `Receipt` + `ReceiptSelectedEntry` + `ReceiptPolicy` + `ReceiptOutput` — state-assembly audit artifact (v0.8) and its nested shapes
|
|
191
|
+
- `ReceiptList` — cursor-paginated receipt listing
|
|
134
192
|
|
|
135
|
-
Param types: `CreateEpisodeParams`, `SearchMemoriesParams`, `GetContextParams`
|
|
193
|
+
Param types: `CreateEpisodeParams`, `SearchMemoriesParams`, `GetContextParams`, `ListReceiptsParams`, `SetMemoryLabelsParams`
|
|
136
194
|
|
|
137
195
|
## Running tests
|
|
138
196
|
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BatchCreateResult, ClientOptions, CompileJob, CompileResult, ContextBundle, CreateEpisodeParams, DeleteResult, Episode, GetContextParams, ListSubjectsResult, SearchMemoriesParams, SearchResult, Timeline } from "./types.js";
|
|
1
|
+
import type { BatchCreateResult, ClientOptions, CompileJob, CompileResult, ContextBundle, CreateEpisodeParams, DeleteResult, Episode, GetContextParams, ListReceiptsParams, ListSubjectsResult, Memory, Receipt, ReceiptList, SearchMemoriesParams, SearchResult, SetMemoryLabelsParams, Timeline } from "./types.js";
|
|
2
2
|
/** Structured error from the Statewave API. */
|
|
3
3
|
export declare class StatewaveAPIError extends Error {
|
|
4
4
|
readonly statusCode: number;
|
|
@@ -19,7 +19,7 @@ export declare class StatewaveClient {
|
|
|
19
19
|
createEpisode(params: CreateEpisodeParams): Promise<Episode>;
|
|
20
20
|
createEpisodesBatch(episodes: CreateEpisodeParams[]): Promise<BatchCreateResult>;
|
|
21
21
|
compileMemories(subjectId: string): Promise<CompileResult>;
|
|
22
|
-
/** Submit async compilation — returns immediately with a
|
|
22
|
+
/** Submit async compilation — returns immediately with a jobId. */
|
|
23
23
|
compileMemoriesAsync(subjectId: string): Promise<CompileJob>;
|
|
24
24
|
/** Poll the status of an async compile job. */
|
|
25
25
|
getCompileStatus(jobId: string): Promise<CompileJob>;
|
|
@@ -30,8 +30,23 @@ export declare class StatewaveClient {
|
|
|
30
30
|
}): Promise<CompileJob>;
|
|
31
31
|
searchMemories(params: SearchMemoriesParams): Promise<SearchResult>;
|
|
32
32
|
getContext(params: GetContextParams): Promise<ContextBundle>;
|
|
33
|
+
/**
|
|
34
|
+
* Replace a memory's sensitivityLabels. Server normalizes
|
|
35
|
+
* (dedup + lowercase + trim) and caps at 32 entries. Empty array
|
|
36
|
+
* clears all labels — the memory becomes untagged and any policy
|
|
37
|
+
* rule that depends on a label match falls through to default-allow.
|
|
38
|
+
*/
|
|
39
|
+
setMemoryLabels(params: SetMemoryLabelsParams): Promise<Memory>;
|
|
33
40
|
/** Return just the assembled context string, ready to inject into a prompt. */
|
|
34
41
|
getContextString(params: GetContextParams): Promise<string>;
|
|
42
|
+
/** Fetch a single state-assembly receipt by ULID. */
|
|
43
|
+
getReceipt(receiptId: string): Promise<Receipt>;
|
|
44
|
+
/**
|
|
45
|
+
* List state-assembly receipts for a subject, newest first.
|
|
46
|
+
* Cursor-paginated — pass back the previous response's `nextCursor`
|
|
47
|
+
* to fetch the next page.
|
|
48
|
+
*/
|
|
49
|
+
listReceipts(params: ListReceiptsParams): Promise<ReceiptList>;
|
|
35
50
|
getTimeline(subjectId: string): Promise<Timeline>;
|
|
36
51
|
deleteSubject(subjectId: string): Promise<DeleteResult>;
|
|
37
52
|
listSubjects(params?: {
|
package/dist/client.js
CHANGED
|
@@ -1,3 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Free-form bags whose contents are user-owned. Their *inner* keys are
|
|
3
|
+
* never rewritten in either direction so arbitrary caller data (which
|
|
4
|
+
* may itself contain snake_case or camelCase keys) round-trips
|
|
5
|
+
* byte-for-byte. The key names themselves are single words, so they are
|
|
6
|
+
* unchanged by case conversion regardless.
|
|
7
|
+
*/
|
|
8
|
+
const OPAQUE_KEYS = new Set(["payload", "metadata", "provenance"]);
|
|
9
|
+
function snakeKeyToCamel(key) {
|
|
10
|
+
return key.replace(/_+([a-zA-Z0-9])/g, (_, c) => c.toUpperCase());
|
|
11
|
+
}
|
|
12
|
+
function camelKeyToSnake(key) {
|
|
13
|
+
return key.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);
|
|
14
|
+
}
|
|
15
|
+
function isPlainObject(v) {
|
|
16
|
+
return v !== null && typeof v === "object" && !Array.isArray(v);
|
|
17
|
+
}
|
|
18
|
+
function mapKeys(value, convert) {
|
|
19
|
+
if (Array.isArray(value)) {
|
|
20
|
+
return value.map((v) => mapKeys(v, convert));
|
|
21
|
+
}
|
|
22
|
+
if (isPlainObject(value)) {
|
|
23
|
+
const out = {};
|
|
24
|
+
for (const [k, v] of Object.entries(value)) {
|
|
25
|
+
// Opaque bag: keep the verbatim value, don't recurse into it.
|
|
26
|
+
out[convert(k)] = OPAQUE_KEYS.has(k) ? v : mapKeys(v, convert);
|
|
27
|
+
}
|
|
28
|
+
return out;
|
|
29
|
+
}
|
|
30
|
+
return value;
|
|
31
|
+
}
|
|
32
|
+
/** Wire (snake_case) → public SDK shape (camelCase). */
|
|
33
|
+
function fromWire(value) {
|
|
34
|
+
return mapKeys(value, snakeKeyToCamel);
|
|
35
|
+
}
|
|
36
|
+
/** Public SDK shape (camelCase) → wire (snake_case). */
|
|
37
|
+
function toWire(value) {
|
|
38
|
+
return mapKeys(value, camelKeyToSnake);
|
|
39
|
+
}
|
|
1
40
|
/** Structured error from the Statewave API. */
|
|
2
41
|
export class StatewaveAPIError extends Error {
|
|
3
42
|
statusCode;
|
|
@@ -47,7 +86,7 @@ export class StatewaveClient {
|
|
|
47
86
|
}
|
|
48
87
|
async createEpisode(params) {
|
|
49
88
|
return this.post("/v1/episodes", {
|
|
50
|
-
|
|
89
|
+
subjectId: params.subjectId,
|
|
51
90
|
source: params.source,
|
|
52
91
|
type: params.type,
|
|
53
92
|
payload: params.payload,
|
|
@@ -57,7 +96,7 @@ export class StatewaveClient {
|
|
|
57
96
|
}
|
|
58
97
|
async createEpisodesBatch(episodes) {
|
|
59
98
|
return this.post("/v1/episodes/batch", { episodes: episodes.map(e => ({
|
|
60
|
-
|
|
99
|
+
subjectId: e.subjectId,
|
|
61
100
|
source: e.source,
|
|
62
101
|
type: e.type,
|
|
63
102
|
payload: e.payload,
|
|
@@ -66,11 +105,11 @@ export class StatewaveClient {
|
|
|
66
105
|
})) });
|
|
67
106
|
}
|
|
68
107
|
async compileMemories(subjectId) {
|
|
69
|
-
return this.post("/v1/memories/compile", {
|
|
108
|
+
return this.post("/v1/memories/compile", { subjectId });
|
|
70
109
|
}
|
|
71
|
-
/** Submit async compilation — returns immediately with a
|
|
110
|
+
/** Submit async compilation — returns immediately with a jobId. */
|
|
72
111
|
async compileMemoriesAsync(subjectId) {
|
|
73
|
-
return this.post("/v1/memories/compile", {
|
|
112
|
+
return this.post("/v1/memories/compile", { subjectId, async: true });
|
|
74
113
|
}
|
|
75
114
|
/** Poll the status of an async compile job. */
|
|
76
115
|
async getCompileStatus(jobId) {
|
|
@@ -84,15 +123,15 @@ export class StatewaveClient {
|
|
|
84
123
|
const start = Date.now();
|
|
85
124
|
while (Date.now() - start < timeout) {
|
|
86
125
|
await new Promise(r => setTimeout(r, pollInterval));
|
|
87
|
-
const status = await this.getCompileStatus(job.
|
|
126
|
+
const status = await this.getCompileStatus(job.jobId);
|
|
88
127
|
if (status.status === "completed" || status.status === "failed") {
|
|
89
128
|
return status;
|
|
90
129
|
}
|
|
91
130
|
}
|
|
92
|
-
throw new Error(`Compile job ${job.
|
|
131
|
+
throw new Error(`Compile job ${job.jobId} did not complete within ${timeout}ms`);
|
|
93
132
|
}
|
|
94
133
|
async searchMemories(params) {
|
|
95
|
-
const qs = new URLSearchParams({ subject_id: params.
|
|
134
|
+
const qs = new URLSearchParams({ subject_id: params.subjectId });
|
|
96
135
|
if (params.kind)
|
|
97
136
|
qs.set("kind", params.kind);
|
|
98
137
|
if (params.query)
|
|
@@ -105,15 +144,56 @@ export class StatewaveClient {
|
|
|
105
144
|
}
|
|
106
145
|
async getContext(params) {
|
|
107
146
|
return this.post("/v1/context", {
|
|
108
|
-
|
|
147
|
+
subjectId: params.subjectId,
|
|
109
148
|
task: params.task,
|
|
110
|
-
...(params.
|
|
149
|
+
...(params.maxTokens !== undefined && { maxTokens: params.maxTokens }),
|
|
150
|
+
...(params.sessionId !== undefined && { sessionId: params.sessionId }),
|
|
151
|
+
...(params.emitReceipt !== undefined && { emitReceipt: params.emitReceipt }),
|
|
152
|
+
...(params.queryId !== undefined && { queryId: params.queryId }),
|
|
153
|
+
...(params.taskId !== undefined && { taskId: params.taskId }),
|
|
154
|
+
...(params.parentReceiptId !== undefined && {
|
|
155
|
+
parentReceiptId: params.parentReceiptId,
|
|
156
|
+
}),
|
|
157
|
+
...(params.callerId !== undefined && { callerId: params.callerId }),
|
|
158
|
+
...(params.callerType !== undefined && { callerType: params.callerType }),
|
|
111
159
|
});
|
|
112
160
|
}
|
|
161
|
+
// -- Memory labels (#50) ----------------------------------------------
|
|
162
|
+
/**
|
|
163
|
+
* Replace a memory's sensitivityLabels. Server normalizes
|
|
164
|
+
* (dedup + lowercase + trim) and caps at 32 entries. Empty array
|
|
165
|
+
* clears all labels — the memory becomes untagged and any policy
|
|
166
|
+
* rule that depends on a label match falls through to default-allow.
|
|
167
|
+
*/
|
|
168
|
+
async setMemoryLabels(params) {
|
|
169
|
+
return this.request("PATCH", `/v1/memories/${encodeURIComponent(params.memoryId)}/labels`, { sensitivityLabels: params.sensitivityLabels });
|
|
170
|
+
}
|
|
113
171
|
/** Return just the assembled context string, ready to inject into a prompt. */
|
|
114
172
|
async getContextString(params) {
|
|
115
173
|
const bundle = await this.getContext(params);
|
|
116
|
-
return bundle.
|
|
174
|
+
return bundle.assembledContext;
|
|
175
|
+
}
|
|
176
|
+
// -- Receipts --------------------------------------------------------
|
|
177
|
+
/** Fetch a single state-assembly receipt by ULID. */
|
|
178
|
+
async getReceipt(receiptId) {
|
|
179
|
+
return this.get(`/v1/receipts/${encodeURIComponent(receiptId)}`);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* List state-assembly receipts for a subject, newest first.
|
|
183
|
+
* Cursor-paginated — pass back the previous response's `nextCursor`
|
|
184
|
+
* to fetch the next page.
|
|
185
|
+
*/
|
|
186
|
+
async listReceipts(params) {
|
|
187
|
+
const qs = new URLSearchParams({ subject_id: params.subjectId });
|
|
188
|
+
if (params.since !== undefined)
|
|
189
|
+
qs.set("since", params.since);
|
|
190
|
+
if (params.until !== undefined)
|
|
191
|
+
qs.set("until", params.until);
|
|
192
|
+
if (params.cursor !== undefined)
|
|
193
|
+
qs.set("cursor", params.cursor);
|
|
194
|
+
if (params.limit !== undefined)
|
|
195
|
+
qs.set("limit", String(params.limit));
|
|
196
|
+
return this.get(`/v1/receipts?${qs}`);
|
|
117
197
|
}
|
|
118
198
|
async getTimeline(subjectId) {
|
|
119
199
|
return this.get(`/v1/timeline?subject_id=${encodeURIComponent(subjectId)}`);
|
|
@@ -139,16 +219,17 @@ export class StatewaveClient {
|
|
|
139
219
|
}
|
|
140
220
|
async request(method, path, body) {
|
|
141
221
|
let lastError;
|
|
222
|
+
const wireBody = body === undefined ? undefined : toWire(body);
|
|
142
223
|
for (let attempt = 0; attempt <= this.retryConfig.maxRetries; attempt++) {
|
|
143
224
|
let resp;
|
|
144
225
|
try {
|
|
145
226
|
const headers = { ...this.defaultHeaders };
|
|
146
|
-
if (
|
|
227
|
+
if (wireBody !== undefined)
|
|
147
228
|
headers["Content-Type"] = "application/json";
|
|
148
229
|
resp = await fetch(`${this.baseUrl}${path}`, {
|
|
149
230
|
method,
|
|
150
231
|
headers,
|
|
151
|
-
body:
|
|
232
|
+
body: wireBody !== undefined ? JSON.stringify(wireBody) : undefined,
|
|
152
233
|
});
|
|
153
234
|
}
|
|
154
235
|
catch (err) {
|
|
@@ -161,7 +242,7 @@ export class StatewaveClient {
|
|
|
161
242
|
throw new StatewaveConnectionError(lastError.message);
|
|
162
243
|
}
|
|
163
244
|
if (resp.ok) {
|
|
164
|
-
return resp.json();
|
|
245
|
+
return fromWire(await resp.json());
|
|
165
246
|
}
|
|
166
247
|
// Check if retryable status
|
|
167
248
|
if (this.retryConfig.retryOnStatus.includes(resp.status) && attempt < this.retryConfig.maxRetries) {
|
package/dist/types.d.ts
CHANGED
|
@@ -1,65 +1,157 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* Statewave API types.
|
|
3
|
+
*
|
|
4
|
+
* The public SDK surface is camelCase, idiomatic TypeScript. The
|
|
5
|
+
* Statewave HTTP API speaks snake_case on the wire; `StatewaveClient`
|
|
6
|
+
* transparently maps between the two in both directions, so callers
|
|
7
|
+
* never see a snake_case key. The free-form `payload`, `metadata`, and
|
|
8
|
+
* `provenance` bags are passed through verbatim — their inner keys are
|
|
9
|
+
* never rewritten, so arbitrary user data round-trips losslessly.
|
|
10
|
+
*/
|
|
2
11
|
export interface Episode {
|
|
3
12
|
id: string;
|
|
4
|
-
|
|
13
|
+
subjectId: string;
|
|
5
14
|
source: string;
|
|
6
15
|
type: string;
|
|
7
16
|
payload: Record<string, unknown>;
|
|
8
17
|
metadata: Record<string, unknown>;
|
|
9
18
|
provenance: Record<string, unknown>;
|
|
10
|
-
|
|
19
|
+
createdAt: string;
|
|
11
20
|
}
|
|
12
21
|
export interface Memory {
|
|
13
22
|
id: string;
|
|
14
|
-
|
|
23
|
+
subjectId: string;
|
|
15
24
|
kind: string;
|
|
16
25
|
content: string;
|
|
17
26
|
summary: string;
|
|
18
27
|
confidence: number;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
28
|
+
validFrom: string;
|
|
29
|
+
validTo: string | null;
|
|
30
|
+
sourceEpisodeIds: string[];
|
|
22
31
|
metadata: Record<string, unknown>;
|
|
23
32
|
status: string;
|
|
24
|
-
|
|
25
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Per-memory capability tags consumed by the sensitivity-label
|
|
35
|
+
* policy layer (#50). Empty = untagged = policy default-allow.
|
|
36
|
+
* Older servers without the policy layer omit the field.
|
|
37
|
+
*/
|
|
38
|
+
sensitivityLabels?: string[];
|
|
39
|
+
createdAt: string;
|
|
40
|
+
updatedAt: string;
|
|
26
41
|
}
|
|
27
42
|
export interface CompileResult {
|
|
28
|
-
|
|
29
|
-
|
|
43
|
+
subjectId: string;
|
|
44
|
+
memoriesCreated: number;
|
|
30
45
|
memories: Memory[];
|
|
31
46
|
}
|
|
32
47
|
export interface SearchResult {
|
|
33
48
|
memories: Memory[];
|
|
34
49
|
}
|
|
35
50
|
export interface ContextBundle {
|
|
36
|
-
|
|
51
|
+
subjectId: string;
|
|
37
52
|
task: string;
|
|
38
53
|
facts: Memory[];
|
|
39
54
|
episodes: Episode[];
|
|
40
55
|
procedures: Memory[];
|
|
41
56
|
provenance: Record<string, unknown>;
|
|
42
|
-
|
|
43
|
-
|
|
57
|
+
assembledContext: string;
|
|
58
|
+
tokenEstimate: number;
|
|
59
|
+
/** ULID of the state-assembly receipt, when one was emitted. */
|
|
60
|
+
receiptId?: string | null;
|
|
61
|
+
/** True iff a receipt was successfully written for this call. */
|
|
62
|
+
receiptEmitted?: boolean;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* One entry inside a state-assembly receipt. Strict-superset shape —
|
|
66
|
+
* fields not relevant to the entry's `type` are null. See
|
|
67
|
+
* `docs/state-assembly-receipts.md` in the server repository for the
|
|
68
|
+
* full schema.
|
|
69
|
+
*/
|
|
70
|
+
export interface ReceiptSelectedEntry {
|
|
71
|
+
type: "memory" | "episode";
|
|
72
|
+
/** Present when type === "memory". */
|
|
73
|
+
memoryId?: string;
|
|
74
|
+
/** Present when type === "memory". */
|
|
75
|
+
kind?: string;
|
|
76
|
+
validFrom?: string | null;
|
|
77
|
+
validTo?: string | null;
|
|
78
|
+
supersessionStatus?: "active" | "superseded" | "tombstoned";
|
|
79
|
+
sourceEpisodeIds?: string[];
|
|
80
|
+
provenanceHash?: string;
|
|
81
|
+
factKey?: string | null;
|
|
82
|
+
conflictStatus?: "none" | "merged" | "overridden" | "unresolved";
|
|
83
|
+
/** Present when type === "episode". */
|
|
84
|
+
episodeId?: string;
|
|
85
|
+
source?: string;
|
|
86
|
+
eventType?: string;
|
|
87
|
+
occurredAt?: string | null;
|
|
88
|
+
/** Final position in the assembled bundle. */
|
|
89
|
+
rank: number;
|
|
90
|
+
score?: number | null;
|
|
91
|
+
}
|
|
92
|
+
export interface ReceiptPolicy {
|
|
93
|
+
policyBundleHash: string | null;
|
|
94
|
+
filtersApplied: unknown[];
|
|
95
|
+
filtersSkipped: unknown[];
|
|
96
|
+
mode: "log_only" | "enforce";
|
|
97
|
+
}
|
|
98
|
+
export interface ReceiptOutput {
|
|
99
|
+
contextHash: string;
|
|
100
|
+
contextSizeBytes: number;
|
|
101
|
+
canonicalizationVersion: number;
|
|
102
|
+
tokenEstimate: number;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Immutable per-retrieval audit artifact for a single context assembly.
|
|
106
|
+
* See `docs/state-assembly-receipts.md` in the server repository.
|
|
107
|
+
*/
|
|
108
|
+
export interface Receipt {
|
|
109
|
+
receiptId: string;
|
|
110
|
+
parentReceiptId: string | null;
|
|
111
|
+
mode: "retrieval" | string;
|
|
112
|
+
queryId: string | null;
|
|
113
|
+
taskId: string | null;
|
|
114
|
+
tenantId: string | null;
|
|
115
|
+
subjectId: string;
|
|
116
|
+
task: string;
|
|
117
|
+
asOf: string;
|
|
118
|
+
createdAt: string;
|
|
119
|
+
selectedEntries: ReceiptSelectedEntry[];
|
|
120
|
+
policy: ReceiptPolicy;
|
|
121
|
+
output: ReceiptOutput;
|
|
122
|
+
region: string | null;
|
|
123
|
+
receiptSignature: string | null;
|
|
124
|
+
}
|
|
125
|
+
export interface ReceiptList {
|
|
126
|
+
receipts: Receipt[];
|
|
127
|
+
/** Pass back as the `cursor` param to fetch the next page; null when no more. */
|
|
128
|
+
nextCursor: string | null;
|
|
129
|
+
}
|
|
130
|
+
export interface ListReceiptsParams {
|
|
131
|
+
subjectId: string;
|
|
132
|
+
since?: string;
|
|
133
|
+
until?: string;
|
|
134
|
+
cursor?: string;
|
|
135
|
+
limit?: number;
|
|
44
136
|
}
|
|
45
137
|
export interface Timeline {
|
|
46
|
-
|
|
138
|
+
subjectId: string;
|
|
47
139
|
episodes: Episode[];
|
|
48
140
|
memories: Memory[];
|
|
49
141
|
}
|
|
50
142
|
export interface DeleteResult {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
143
|
+
subjectId: string;
|
|
144
|
+
episodesDeleted: number;
|
|
145
|
+
memoriesDeleted: number;
|
|
54
146
|
}
|
|
55
147
|
export interface BatchCreateResult {
|
|
56
|
-
|
|
148
|
+
episodesCreated: number;
|
|
57
149
|
episodes: Episode[];
|
|
58
150
|
}
|
|
59
151
|
export interface SubjectSummary {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
152
|
+
subjectId: string;
|
|
153
|
+
episodeCount: number;
|
|
154
|
+
memoryCount: number;
|
|
63
155
|
}
|
|
64
156
|
export interface ListSubjectsResult {
|
|
65
157
|
subjects: SubjectSummary[];
|
|
@@ -67,33 +159,59 @@ export interface ListSubjectsResult {
|
|
|
67
159
|
}
|
|
68
160
|
/** Status of an async compile job. */
|
|
69
161
|
export interface CompileJob {
|
|
70
|
-
|
|
162
|
+
jobId: string;
|
|
71
163
|
status: "pending" | "running" | "completed" | "failed";
|
|
72
|
-
|
|
73
|
-
|
|
164
|
+
subjectId: string;
|
|
165
|
+
memoriesCreated?: number;
|
|
74
166
|
memories?: Memory[];
|
|
75
167
|
error?: string;
|
|
76
168
|
}
|
|
77
169
|
export interface CreateEpisodeParams {
|
|
78
|
-
|
|
170
|
+
subjectId: string;
|
|
79
171
|
source: string;
|
|
80
172
|
type: string;
|
|
81
173
|
payload: Record<string, unknown>;
|
|
82
174
|
metadata?: Record<string, unknown>;
|
|
83
175
|
provenance?: Record<string, unknown>;
|
|
84
|
-
|
|
176
|
+
sessionId?: string;
|
|
85
177
|
}
|
|
86
178
|
export interface SearchMemoriesParams {
|
|
87
|
-
|
|
179
|
+
subjectId: string;
|
|
88
180
|
kind?: string;
|
|
89
181
|
query?: string;
|
|
90
182
|
semantic?: boolean;
|
|
91
183
|
limit?: number;
|
|
92
184
|
}
|
|
93
185
|
export interface GetContextParams {
|
|
94
|
-
|
|
186
|
+
subjectId: string;
|
|
95
187
|
task: string;
|
|
96
|
-
|
|
188
|
+
maxTokens?: number;
|
|
189
|
+
sessionId?: string;
|
|
190
|
+
/**
|
|
191
|
+
* Opt in to emitting a state-assembly receipt for this call. The
|
|
192
|
+
* tenant config can also force emission on or off independently of
|
|
193
|
+
* this flag. See `docs/state-assembly-receipts.md` in the server
|
|
194
|
+
* repository.
|
|
195
|
+
*/
|
|
196
|
+
emitReceipt?: boolean;
|
|
197
|
+
queryId?: string;
|
|
198
|
+
taskId?: string;
|
|
199
|
+
parentReceiptId?: string;
|
|
200
|
+
/**
|
|
201
|
+
* Caller identity consumed by the sensitivity-label policy layer
|
|
202
|
+
* (#50). When the tenant config sets `require_caller_identity:
|
|
203
|
+
* true`, both `callerId` and `callerType` are mandatory.
|
|
204
|
+
*/
|
|
205
|
+
callerId?: string;
|
|
206
|
+
callerType?: string;
|
|
207
|
+
}
|
|
208
|
+
export interface SetMemoryLabelsParams {
|
|
209
|
+
memoryId: string;
|
|
210
|
+
/**
|
|
211
|
+
* Replacement label list. Server normalizes (dedup + lowercase +
|
|
212
|
+
* trim) and caps at 32 entries. Empty list clears all labels.
|
|
213
|
+
*/
|
|
214
|
+
sensitivityLabels: string[];
|
|
97
215
|
}
|
|
98
216
|
export interface ClientOptions {
|
|
99
217
|
baseUrl?: string;
|
package/dist/types.js
CHANGED
|
@@ -1,2 +1,11 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* Statewave API types.
|
|
3
|
+
*
|
|
4
|
+
* The public SDK surface is camelCase, idiomatic TypeScript. The
|
|
5
|
+
* Statewave HTTP API speaks snake_case on the wire; `StatewaveClient`
|
|
6
|
+
* transparently maps between the two in both directions, so callers
|
|
7
|
+
* never see a snake_case key. The free-form `payload`, `metadata`, and
|
|
8
|
+
* `provenance` bags are passed through verbatim — their inner keys are
|
|
9
|
+
* never rewritten, so arbitrary user data round-trips losslessly.
|
|
10
|
+
*/
|
|
2
11
|
export {};
|