cognia-sdk 0.2.0 → 0.2.1
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 +14 -0
- package/dist/cjs/client.js +28 -21
- package/dist/cjs/index.js +2 -1
- package/dist/esm/client.d.ts +8 -0
- package/dist/esm/client.js +27 -20
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/types.d.ts +7 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -107,3 +107,17 @@ Every context call then carries that namespace. A private memory saved under it
|
|
|
107
107
|
namespace: the `mine` scope never crosses from one of your users to another, and the `organization` and `network`
|
|
108
108
|
scopes add only what is shared with your organizations or public. Omit the namespace for a single-agent integration.
|
|
109
109
|
Your own Cognia Cloud still shows everything the key owns: you are the data controller for your users' memories.
|
|
110
|
+
|
|
111
|
+
## Memory lifecycle: supersede, contradict, expire (API, 2026-10-08)
|
|
112
|
+
|
|
113
|
+
A long-running agent accumulates private memories that go stale. Three private-only fields on `POST /v1/memories/author`
|
|
114
|
+
keep retrieval honest without deleting anything:
|
|
115
|
+
|
|
116
|
+
- `supersedes: "<memoryId>"` — this memory replaces one of yours (same namespace). The old one stays readable by id, says
|
|
117
|
+
what replaced it, and never comes back in context or search.
|
|
118
|
+
- `contradicts: "<memoryId>"` — same mechanics, recorded as a contradiction.
|
|
119
|
+
- `validUntil: "<ISO date-time>"` — retrieved only until then.
|
|
120
|
+
|
|
121
|
+
`PATCH /v1/memories/:id/lifecycle` sets or clears `validUntil` and `supersededBy` later. Session learning
|
|
122
|
+
(`session.end()`) marks a proposal with `supersedes` when its title matches one of your live private memories, so your
|
|
123
|
+
accept step can pass it through and update instead of duplicating.
|
package/dist/cjs/client.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Cognia = exports.CogniaError = void 0;
|
|
3
|
+
exports.Cognia = exports.CogniaError = exports.SDK_VERSION = void 0;
|
|
4
4
|
exports.shapeContext = shapeContext;
|
|
5
5
|
/** Accept only what the contract promises; anything else is treated as unavailable so the model call proceeds (fail-open). */
|
|
6
6
|
function shapeContext(r) {
|
|
@@ -42,6 +42,8 @@ function shapeContext(r) {
|
|
|
42
42
|
const abstain = decision === "ABSTAIN" ? { reason: (o.abstain && typeof o.abstain.reason === "string" ? o.abstain.reason : o.decision === "INJECT" ? "malformed_items" : "abstain") } : undefined;
|
|
43
43
|
return { contextId: o.contextId, decision, ...(abstain ? { abstain } : {}), scope, items: items, receipts, metrics };
|
|
44
44
|
}
|
|
45
|
+
/** kept in step with package.json by the version test */
|
|
46
|
+
exports.SDK_VERSION = "0.2.1";
|
|
45
47
|
class CogniaError extends Error {
|
|
46
48
|
status;
|
|
47
49
|
body;
|
|
@@ -63,8 +65,10 @@ class Cognia {
|
|
|
63
65
|
f;
|
|
64
66
|
onError;
|
|
65
67
|
namespace;
|
|
68
|
+
receiptTimeoutMs;
|
|
66
69
|
constructor(o) {
|
|
67
70
|
this.namespace = o.namespace;
|
|
71
|
+
this.receiptTimeoutMs = o.receiptTimeoutMs ?? 10_000;
|
|
68
72
|
if (!o.apiKey && !o.tokenProvider)
|
|
69
73
|
throw new Error("Cognia: apiKey or tokenProvider is required");
|
|
70
74
|
this.key = o.apiKey ?? null;
|
|
@@ -136,7 +140,7 @@ class Cognia {
|
|
|
136
140
|
token = this.key;
|
|
137
141
|
if (!token)
|
|
138
142
|
throw new CogniaError(`Cognia ${method} ${path} → no credential`, 0, null);
|
|
139
|
-
const r = await this.f(this.baseUrl + path, { method, headers: { authorization: `Bearer ${token}`, "content-type": "application/json", "user-agent": "cognia-sdk
|
|
143
|
+
const r = await this.f(this.baseUrl + path, { method, headers: { authorization: `Bearer ${token}`, "content-type": "application/json", "user-agent": "cognia-sdk/${SDK_VERSION}" }, body: body === undefined ? undefined : JSON.stringify(body), signal: ac.signal });
|
|
140
144
|
let j = null;
|
|
141
145
|
try {
|
|
142
146
|
j = await r.json();
|
|
@@ -186,39 +190,42 @@ class Cognia {
|
|
|
186
190
|
return { contextId: null, decision: "UNAVAILABLE", items: [], reason: err.name === "AbortError" ? "timeout" : err.message };
|
|
187
191
|
}
|
|
188
192
|
}
|
|
193
|
+
/** A usage receipt (injected / cited / used): never on the model call's critical path, so it gets a generous budget
|
|
194
|
+
* (RECEIPT_TIMEOUT_MS, default 10 s) and one retry; a failure is reported to onError and never thrown (NEW-RECEIPT). */
|
|
195
|
+
async receipt(kind, contextId, body) {
|
|
196
|
+
const url = `/v1/context/${encodeURIComponent(contextId)}/${kind}`;
|
|
197
|
+
let last = null;
|
|
198
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
199
|
+
try {
|
|
200
|
+
return await this.call(url.startsWith("/") ? "POST" : "POST", url, body, this.receiptTimeoutMs);
|
|
201
|
+
}
|
|
202
|
+
catch (e) {
|
|
203
|
+
last = e instanceof Error ? e : new Error(String(e));
|
|
204
|
+
if (!/timed out|AbortError|fetch failed|ECONN|5\d\d/.test(last.message + last.name))
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
if (last)
|
|
209
|
+
this.onError?.(last);
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
189
212
|
/** Tell Cognia which returned items were actually placed in front of the model. A usage receipt, never evidence. */
|
|
190
213
|
async injected(contextId, itemIds) {
|
|
191
214
|
if (!contextId || !itemIds.length)
|
|
192
215
|
return;
|
|
193
|
-
|
|
194
|
-
await this.call("POST", `/v1/context/${encodeURIComponent(contextId)}/injected`, { itemIds }, 2000);
|
|
195
|
-
}
|
|
196
|
-
catch (e) {
|
|
197
|
-
this.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
198
|
-
}
|
|
216
|
+
await this.receipt("injected", contextId, { itemIds });
|
|
199
217
|
}
|
|
200
218
|
/** CITED: the model's reply referenced these items (the middleware detects this by itself). A usage receipt, never evidence. */
|
|
201
219
|
async cited(contextId, itemIds) {
|
|
202
220
|
if (!contextId || !itemIds.length)
|
|
203
221
|
return;
|
|
204
|
-
|
|
205
|
-
await this.call("POST", `/v1/context/${encodeURIComponent(contextId)}/cited`, { itemIds }, 2000);
|
|
206
|
-
}
|
|
207
|
-
catch (e) {
|
|
208
|
-
this.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
209
|
-
}
|
|
222
|
+
await this.receipt("cited", contextId, { itemIds });
|
|
210
223
|
}
|
|
211
224
|
/** USED: your agent actually used these items, whether or not you know yet how it turned out. The cheapest honest signal. */
|
|
212
225
|
async used(contextId, itemIds) {
|
|
213
226
|
if (!contextId || !itemIds.length)
|
|
214
227
|
return null;
|
|
215
|
-
|
|
216
|
-
return await this.call("POST", `/v1/context/${encodeURIComponent(contextId)}/used`, { itemIds }, 3000);
|
|
217
|
-
}
|
|
218
|
-
catch (e) {
|
|
219
|
-
this.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
220
|
-
return null;
|
|
221
|
-
}
|
|
228
|
+
return (await this.receipt("used", contextId, { itemIds }));
|
|
222
229
|
}
|
|
223
230
|
/** Report what happened with one item: used or not, success / failure (/ neutral for a Skill). This is the only path to success. */
|
|
224
231
|
outcome(contextId, input) {
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.provenanceLine = exports.renderContextBlock = exports.textOf = exports.prependSystem = exports.contextFor = exports.afterReply = exports.citedItems = exports.withCognia = exports.CogniaSession = exports.shapeContext = exports.CogniaError = exports.Cognia = void 0;
|
|
3
|
+
exports.provenanceLine = exports.renderContextBlock = exports.textOf = exports.prependSystem = exports.contextFor = exports.afterReply = exports.citedItems = exports.withCognia = exports.CogniaSession = exports.shapeContext = exports.SDK_VERSION = exports.CogniaError = exports.Cognia = void 0;
|
|
4
4
|
var client_js_1 = require("./client.js");
|
|
5
5
|
Object.defineProperty(exports, "Cognia", { enumerable: true, get: function () { return client_js_1.Cognia; } });
|
|
6
6
|
Object.defineProperty(exports, "CogniaError", { enumerable: true, get: function () { return client_js_1.CogniaError; } });
|
|
7
|
+
Object.defineProperty(exports, "SDK_VERSION", { enumerable: true, get: function () { return client_js_1.SDK_VERSION; } });
|
|
7
8
|
Object.defineProperty(exports, "shapeContext", { enumerable: true, get: function () { return client_js_1.shapeContext; } });
|
|
8
9
|
var session_js_1 = require("./session.js");
|
|
9
10
|
Object.defineProperty(exports, "CogniaSession", { enumerable: true, get: function () { return session_js_1.CogniaSession; } });
|
package/dist/esm/client.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { ReceiptResponse, ContextRequest, ContextResponse, ContextResult, OutcomeInput, OutcomeResponse, ExtractResponse, Scope } from "./types.js";
|
|
2
2
|
export interface CogniaOptions {
|
|
3
|
+
/** budget for usage receipts (injected / cited / used), which never block the model call; default 10 000 ms, one retry */
|
|
4
|
+
receiptTimeoutMs?: number;
|
|
3
5
|
/** end-user namespace sent on every context call (0.2.0). Use one per end user of YOUR app: their private memories
|
|
4
6
|
* are then invisible to every other namespace under the same key. Omit for a single-agent integration. */
|
|
5
7
|
namespace?: string;
|
|
@@ -25,6 +27,8 @@ export interface CogniaOptions {
|
|
|
25
27
|
}
|
|
26
28
|
/** Accept only what the contract promises; anything else is treated as unavailable so the model call proceeds (fail-open). */
|
|
27
29
|
export declare function shapeContext(r: unknown): ContextResponse | null;
|
|
30
|
+
/** kept in step with package.json by the version test */
|
|
31
|
+
export declare const SDK_VERSION = "0.2.1";
|
|
28
32
|
export declare class CogniaError extends Error {
|
|
29
33
|
readonly status: number;
|
|
30
34
|
readonly body: unknown;
|
|
@@ -43,6 +47,7 @@ export declare class Cognia {
|
|
|
43
47
|
private readonly f;
|
|
44
48
|
private readonly onError;
|
|
45
49
|
readonly namespace: string | undefined;
|
|
50
|
+
readonly receiptTimeoutMs: number;
|
|
46
51
|
constructor(o: CogniaOptions);
|
|
47
52
|
/** Every string that reaches the host through an error or a reason has the bearer removed first (independent E2E F28). */
|
|
48
53
|
private scrub;
|
|
@@ -53,6 +58,9 @@ export declare class Cognia {
|
|
|
53
58
|
* A bad credential is also reported this way, with the reason, so a misconfigured app degrades instead of breaking.
|
|
54
59
|
*/
|
|
55
60
|
context(req: ContextRequest | string): Promise<ContextResult>;
|
|
61
|
+
/** A usage receipt (injected / cited / used): never on the model call's critical path, so it gets a generous budget
|
|
62
|
+
* (RECEIPT_TIMEOUT_MS, default 10 s) and one retry; a failure is reported to onError and never thrown (NEW-RECEIPT). */
|
|
63
|
+
private receipt;
|
|
56
64
|
/** Tell Cognia which returned items were actually placed in front of the model. A usage receipt, never evidence. */
|
|
57
65
|
injected(contextId: string, itemIds: string[]): Promise<void>;
|
|
58
66
|
/** CITED: the model's reply referenced these items (the middleware detects this by itself). A usage receipt, never evidence. */
|
package/dist/esm/client.js
CHANGED
|
@@ -38,6 +38,8 @@ export function shapeContext(r) {
|
|
|
38
38
|
const abstain = decision === "ABSTAIN" ? { reason: (o.abstain && typeof o.abstain.reason === "string" ? o.abstain.reason : o.decision === "INJECT" ? "malformed_items" : "abstain") } : undefined;
|
|
39
39
|
return { contextId: o.contextId, decision, ...(abstain ? { abstain } : {}), scope, items: items, receipts, metrics };
|
|
40
40
|
}
|
|
41
|
+
/** kept in step with package.json by the version test */
|
|
42
|
+
export const SDK_VERSION = "0.2.1";
|
|
41
43
|
export class CogniaError extends Error {
|
|
42
44
|
status;
|
|
43
45
|
body;
|
|
@@ -58,8 +60,10 @@ export class Cognia {
|
|
|
58
60
|
f;
|
|
59
61
|
onError;
|
|
60
62
|
namespace;
|
|
63
|
+
receiptTimeoutMs;
|
|
61
64
|
constructor(o) {
|
|
62
65
|
this.namespace = o.namespace;
|
|
66
|
+
this.receiptTimeoutMs = o.receiptTimeoutMs ?? 10_000;
|
|
63
67
|
if (!o.apiKey && !o.tokenProvider)
|
|
64
68
|
throw new Error("Cognia: apiKey or tokenProvider is required");
|
|
65
69
|
this.key = o.apiKey ?? null;
|
|
@@ -131,7 +135,7 @@ export class Cognia {
|
|
|
131
135
|
token = this.key;
|
|
132
136
|
if (!token)
|
|
133
137
|
throw new CogniaError(`Cognia ${method} ${path} → no credential`, 0, null);
|
|
134
|
-
const r = await this.f(this.baseUrl + path, { method, headers: { authorization: `Bearer ${token}`, "content-type": "application/json", "user-agent": "cognia-sdk
|
|
138
|
+
const r = await this.f(this.baseUrl + path, { method, headers: { authorization: `Bearer ${token}`, "content-type": "application/json", "user-agent": "cognia-sdk/${SDK_VERSION}" }, body: body === undefined ? undefined : JSON.stringify(body), signal: ac.signal });
|
|
135
139
|
let j = null;
|
|
136
140
|
try {
|
|
137
141
|
j = await r.json();
|
|
@@ -181,39 +185,42 @@ export class Cognia {
|
|
|
181
185
|
return { contextId: null, decision: "UNAVAILABLE", items: [], reason: err.name === "AbortError" ? "timeout" : err.message };
|
|
182
186
|
}
|
|
183
187
|
}
|
|
188
|
+
/** A usage receipt (injected / cited / used): never on the model call's critical path, so it gets a generous budget
|
|
189
|
+
* (RECEIPT_TIMEOUT_MS, default 10 s) and one retry; a failure is reported to onError and never thrown (NEW-RECEIPT). */
|
|
190
|
+
async receipt(kind, contextId, body) {
|
|
191
|
+
const url = `/v1/context/${encodeURIComponent(contextId)}/${kind}`;
|
|
192
|
+
let last = null;
|
|
193
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
194
|
+
try {
|
|
195
|
+
return await this.call(url.startsWith("/") ? "POST" : "POST", url, body, this.receiptTimeoutMs);
|
|
196
|
+
}
|
|
197
|
+
catch (e) {
|
|
198
|
+
last = e instanceof Error ? e : new Error(String(e));
|
|
199
|
+
if (!/timed out|AbortError|fetch failed|ECONN|5\d\d/.test(last.message + last.name))
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (last)
|
|
204
|
+
this.onError?.(last);
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
184
207
|
/** Tell Cognia which returned items were actually placed in front of the model. A usage receipt, never evidence. */
|
|
185
208
|
async injected(contextId, itemIds) {
|
|
186
209
|
if (!contextId || !itemIds.length)
|
|
187
210
|
return;
|
|
188
|
-
|
|
189
|
-
await this.call("POST", `/v1/context/${encodeURIComponent(contextId)}/injected`, { itemIds }, 2000);
|
|
190
|
-
}
|
|
191
|
-
catch (e) {
|
|
192
|
-
this.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
193
|
-
}
|
|
211
|
+
await this.receipt("injected", contextId, { itemIds });
|
|
194
212
|
}
|
|
195
213
|
/** CITED: the model's reply referenced these items (the middleware detects this by itself). A usage receipt, never evidence. */
|
|
196
214
|
async cited(contextId, itemIds) {
|
|
197
215
|
if (!contextId || !itemIds.length)
|
|
198
216
|
return;
|
|
199
|
-
|
|
200
|
-
await this.call("POST", `/v1/context/${encodeURIComponent(contextId)}/cited`, { itemIds }, 2000);
|
|
201
|
-
}
|
|
202
|
-
catch (e) {
|
|
203
|
-
this.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
204
|
-
}
|
|
217
|
+
await this.receipt("cited", contextId, { itemIds });
|
|
205
218
|
}
|
|
206
219
|
/** USED: your agent actually used these items, whether or not you know yet how it turned out. The cheapest honest signal. */
|
|
207
220
|
async used(contextId, itemIds) {
|
|
208
221
|
if (!contextId || !itemIds.length)
|
|
209
222
|
return null;
|
|
210
|
-
|
|
211
|
-
return await this.call("POST", `/v1/context/${encodeURIComponent(contextId)}/used`, { itemIds }, 3000);
|
|
212
|
-
}
|
|
213
|
-
catch (e) {
|
|
214
|
-
this.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
215
|
-
return null;
|
|
216
|
-
}
|
|
223
|
+
return (await this.receipt("used", contextId, { itemIds }));
|
|
217
224
|
}
|
|
218
225
|
/** Report what happened with one item: used or not, success / failure (/ neutral for a Skill). This is the only path to success. */
|
|
219
226
|
outcome(contextId, input) {
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { Cognia, CogniaError, shapeContext, type CogniaOptions } from "./client.js";
|
|
1
|
+
export { Cognia, CogniaError, SDK_VERSION, shapeContext, type CogniaOptions } from "./client.js";
|
|
2
2
|
export { CogniaSession, type SessionTurn } from "./session.js";
|
|
3
3
|
export { withCognia, citedItems, afterReply, contextFor, prependSystem, textOf, type WithCogniaOptions } from "./middleware.js";
|
|
4
4
|
export { renderContextBlock, provenanceLine } from "./render.js";
|
package/dist/esm/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { Cognia, CogniaError, shapeContext } from "./client.js";
|
|
1
|
+
export { Cognia, CogniaError, SDK_VERSION, shapeContext } from "./client.js";
|
|
2
2
|
export { CogniaSession } from "./session.js";
|
|
3
3
|
export { withCognia, citedItems, afterReply, contextFor, prependSystem, textOf } from "./middleware.js";
|
|
4
4
|
export { renderContextBlock, provenanceLine } from "./render.js";
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -121,6 +121,13 @@ export interface OutcomeResponse {
|
|
|
121
121
|
export interface ExtractProposal {
|
|
122
122
|
title?: string;
|
|
123
123
|
summary?: string;
|
|
124
|
+
/** lifecycle V1: this proposal matches one of your live private memories by title; accept it WITH `supersedes` to replace instead of adding a copy */
|
|
125
|
+
supersedes?: {
|
|
126
|
+
memoryId: string;
|
|
127
|
+
displayId: string | null;
|
|
128
|
+
title: string;
|
|
129
|
+
why: string;
|
|
130
|
+
};
|
|
124
131
|
[k: string]: unknown;
|
|
125
132
|
}
|
|
126
133
|
export interface ExtractResponse {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cognia-sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Cognia for your model calls: one line gives any agent the Memories and Skills it may use, with provenance and honest receipts. Fails open.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Cognia",
|