hebbrix 2.0.2 → 2.2.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/LICENSE +21 -0
- package/README.md +23 -0
- package/dist/index.d.mts +234 -15
- package/dist/index.d.ts +234 -15
- package/dist/index.js +218 -12
- package/dist/index.mjs +213 -11
- package/package.json +8 -5
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,55 @@
|
|
|
1
|
+
// src/safety.ts
|
|
2
|
+
var REQUIRED_FIELDS = [
|
|
3
|
+
"no_match",
|
|
4
|
+
"abstain_recommended",
|
|
5
|
+
"query_confidence",
|
|
6
|
+
"grounding",
|
|
7
|
+
"evidence_ids",
|
|
8
|
+
"safety_contract_version"
|
|
9
|
+
];
|
|
10
|
+
function enforceSearchSafety(response, rowsKey = "results") {
|
|
11
|
+
const data = { ...response };
|
|
12
|
+
const rawRows = data[rowsKey];
|
|
13
|
+
const rows = Array.isArray(rawRows) ? rawRows.filter((row) => typeof row === "object" && row !== null) : [];
|
|
14
|
+
const missing = REQUIRED_FIELDS.filter(
|
|
15
|
+
(field) => !Object.prototype.hasOwnProperty.call(data, field)
|
|
16
|
+
);
|
|
17
|
+
let reason;
|
|
18
|
+
if (missing.length > 0) {
|
|
19
|
+
reason = `missing_safety_fields:${missing.join(",")}`;
|
|
20
|
+
} else if (typeof data.no_match !== "boolean" || typeof data.abstain_recommended !== "boolean") {
|
|
21
|
+
reason = "invalid_abstention_fields";
|
|
22
|
+
} else if (typeof data.query_confidence !== "number" || !Number.isFinite(data.query_confidence) || data.query_confidence < 0 || data.query_confidence > 1) {
|
|
23
|
+
reason = "invalid_query_confidence";
|
|
24
|
+
} else if (typeof data.grounding !== "object" || data.grounding === null || Array.isArray(data.grounding)) {
|
|
25
|
+
reason = "invalid_grounding_receipt";
|
|
26
|
+
} else if (!Array.isArray(data.evidence_ids)) {
|
|
27
|
+
reason = "invalid_evidence_ids";
|
|
28
|
+
} else {
|
|
29
|
+
const evidenceIds = new Set(data.evidence_ids.map(String));
|
|
30
|
+
const rowIds = rows.map((row) => row.memory_id ?? row.id).filter((value) => typeof value === "string" && value.length > 0);
|
|
31
|
+
if (rowIds.some((value) => !evidenceIds.has(value))) {
|
|
32
|
+
reason = "rows_not_bound_to_evidence_ids";
|
|
33
|
+
} else if (data.no_match && (rowIds.length > 0 || evidenceIds.size > 0)) {
|
|
34
|
+
reason = "no_match_contains_evidence";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (reason || data.degraded === true || data.no_match === true || data.abstain_recommended === true) {
|
|
38
|
+
data[rowsKey] = [];
|
|
39
|
+
if (rowsKey === "results") data.total = 0;
|
|
40
|
+
data.no_match = true;
|
|
41
|
+
data.abstain_recommended = true;
|
|
42
|
+
data.query_confidence = 0;
|
|
43
|
+
data.evidence_ids = [];
|
|
44
|
+
data.evidence_claims = [];
|
|
45
|
+
if (reason) {
|
|
46
|
+
data.sdk_safety_reason = reason;
|
|
47
|
+
data.grounding = { status: "no_grounded_match", reason };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return data;
|
|
51
|
+
}
|
|
52
|
+
|
|
1
53
|
// src/resources.ts
|
|
2
54
|
var BaseResource = class {
|
|
3
55
|
constructor(client) {
|
|
@@ -77,14 +129,32 @@ var MemoriesResource = class extends BaseResource {
|
|
|
77
129
|
* Create a new memory
|
|
78
130
|
*/
|
|
79
131
|
async create(params) {
|
|
80
|
-
|
|
132
|
+
if (!params.content?.trim() && !params.messages?.length) {
|
|
133
|
+
throw new TypeError("content or messages must be provided");
|
|
134
|
+
}
|
|
135
|
+
const { idempotency_key, ...input } = params;
|
|
136
|
+
return this.client.request("POST", "/v1/memories", {
|
|
137
|
+
headers: idempotency_key ? { "Idempotency-Key": idempotency_key } : void 0,
|
|
138
|
+
body: JSON.stringify({
|
|
139
|
+
source_type: "text",
|
|
140
|
+
metadata: {},
|
|
141
|
+
infer: false,
|
|
142
|
+
wait_for_index: false,
|
|
143
|
+
...input
|
|
144
|
+
})
|
|
145
|
+
});
|
|
81
146
|
}
|
|
82
147
|
/**
|
|
83
148
|
* List memories
|
|
84
149
|
*/
|
|
85
|
-
async
|
|
150
|
+
async listPage(params = {}) {
|
|
86
151
|
return this.client.get("/v1/memories", params);
|
|
87
152
|
}
|
|
153
|
+
/** Back-compatible one-page convenience; use listPage for cursor metadata. */
|
|
154
|
+
async list(params = {}) {
|
|
155
|
+
const page = await this.listPage(params);
|
|
156
|
+
return page.items;
|
|
157
|
+
}
|
|
88
158
|
/**
|
|
89
159
|
* Get a specific memory
|
|
90
160
|
*/
|
|
@@ -104,19 +174,79 @@ var MemoriesResource = class extends BaseResource {
|
|
|
104
174
|
await this.client.delete(`/v1/memories/${memoryId}`);
|
|
105
175
|
}
|
|
106
176
|
};
|
|
177
|
+
var MemoryJobsResource = class extends BaseResource {
|
|
178
|
+
async get(jobId) {
|
|
179
|
+
return this.client.get(`/v1/memory-jobs/${jobId}`);
|
|
180
|
+
}
|
|
181
|
+
async wait(jobId, options = {}) {
|
|
182
|
+
const timeoutMs = Math.max(0, options.timeoutMs ?? 6e4);
|
|
183
|
+
const pollIntervalMs = Math.max(50, options.pollIntervalMs ?? 500);
|
|
184
|
+
const deadline = Date.now() + timeoutMs;
|
|
185
|
+
while (true) {
|
|
186
|
+
const receipt = await this.get(jobId);
|
|
187
|
+
const status = String(receipt.status || "").toLowerCase();
|
|
188
|
+
if (["completed", "failed", "cancelled", "canceled"].includes(status)) {
|
|
189
|
+
return receipt;
|
|
190
|
+
}
|
|
191
|
+
if (Date.now() >= deadline) {
|
|
192
|
+
throw new Error(`memory job ${jobId} did not finish in ${timeoutMs}ms`);
|
|
193
|
+
}
|
|
194
|
+
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
var CorrectionsResource = class extends BaseResource {
|
|
199
|
+
async create(params) {
|
|
200
|
+
const { idempotency_key, ...body } = params;
|
|
201
|
+
return this.client.request("POST", "/v1/corrections", {
|
|
202
|
+
headers: idempotency_key ? { "Idempotency-Key": idempotency_key } : void 0,
|
|
203
|
+
body: JSON.stringify({
|
|
204
|
+
correction_type: "preference",
|
|
205
|
+
confidence: 1,
|
|
206
|
+
...body
|
|
207
|
+
})
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
async relevant(params) {
|
|
211
|
+
return this.client.get("/v1/corrections/relevant", {
|
|
212
|
+
include_global: false,
|
|
213
|
+
limit: 10,
|
|
214
|
+
...params
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
async get(correctionId) {
|
|
218
|
+
return this.client.get(`/v1/corrections/${correctionId}`);
|
|
219
|
+
}
|
|
220
|
+
async delete(correctionId) {
|
|
221
|
+
return this.client.delete(`/v1/corrections/${correctionId}`);
|
|
222
|
+
}
|
|
223
|
+
};
|
|
107
224
|
var SearchResource = class extends BaseResource {
|
|
108
225
|
/**
|
|
109
226
|
* Search memories
|
|
110
227
|
*/
|
|
111
228
|
async search(params) {
|
|
229
|
+
const response = await this.searchWithProof(params);
|
|
230
|
+
return response.results;
|
|
231
|
+
}
|
|
232
|
+
/** Search while preserving the automatic ProofLoop evidence context. */
|
|
233
|
+
async searchWithProof(params) {
|
|
112
234
|
const response = await this.client.post("/v1/search", {
|
|
113
235
|
query: params.query,
|
|
114
236
|
collection_id: params.collection_id,
|
|
237
|
+
user_id: params.user_id,
|
|
238
|
+
agent_id: params.agent_id,
|
|
239
|
+
run_id: params.run_id,
|
|
115
240
|
limit: params.limit || 10,
|
|
116
241
|
search_type: params.search_type || "hybrid",
|
|
117
|
-
filters: params.filters || {}
|
|
242
|
+
filters: params.filters || {},
|
|
243
|
+
fast: params.fast,
|
|
244
|
+
threshold: params.threshold,
|
|
245
|
+
include_low_confidence: params.include_low_confidence ?? false,
|
|
246
|
+
group_by_source: params.group_by_source ?? true,
|
|
247
|
+
debug: params.debug ?? false
|
|
118
248
|
});
|
|
119
|
-
return response
|
|
249
|
+
return enforceSearchSafety(response);
|
|
120
250
|
}
|
|
121
251
|
/**
|
|
122
252
|
* Find similar memories
|
|
@@ -132,11 +262,69 @@ var SearchResource = class extends BaseResource {
|
|
|
132
262
|
* Perform reasoning over memories
|
|
133
263
|
*/
|
|
134
264
|
async reason(params) {
|
|
135
|
-
|
|
136
|
-
|
|
265
|
+
const response = await this.client.post(
|
|
266
|
+
"/v1/search/reason",
|
|
267
|
+
{
|
|
268
|
+
query: params.query,
|
|
269
|
+
collection_id: params.collection_id,
|
|
270
|
+
provider: params.provider,
|
|
271
|
+
include_steps: params.include_steps ?? false,
|
|
272
|
+
user_id: params.user_id,
|
|
273
|
+
agent_id: params.agent_id,
|
|
274
|
+
run_id: params.run_id,
|
|
275
|
+
facets: params.facets ?? []
|
|
276
|
+
}
|
|
277
|
+
);
|
|
278
|
+
return enforceSearchSafety(response, "sources");
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
var ProofLoopResource = class extends BaseResource {
|
|
282
|
+
/** Create a causal decision bound to search/chat evidence automatically. */
|
|
283
|
+
async decide(params) {
|
|
284
|
+
const context = params.proof_context;
|
|
285
|
+
const token = typeof context === "string" ? context : context?.token;
|
|
286
|
+
const { proof_context: _context, ...body } = params;
|
|
287
|
+
return this.client.post("/v1/learning/decisions", {
|
|
288
|
+
...body,
|
|
289
|
+
...token ? { proof_context_token: token } : {}
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
async recordOutcome(decisionId, body) {
|
|
293
|
+
return this.client.post(`/v1/learning/decisions/${decisionId}/outcomes`, {
|
|
294
|
+
observations: [],
|
|
295
|
+
...body
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
async getDecision(decisionId) {
|
|
299
|
+
return this.client.get(`/v1/learning/decisions/${decisionId}`);
|
|
300
|
+
}
|
|
301
|
+
async defineMetric(params) {
|
|
302
|
+
return this.client.post("/v1/learning/metrics", params);
|
|
303
|
+
}
|
|
304
|
+
async listMetrics(params = {}) {
|
|
305
|
+
return this.client.get("/v1/learning/metrics", params);
|
|
306
|
+
}
|
|
307
|
+
async policyInsights(policyKey, params = {}) {
|
|
308
|
+
return this.client.get(`/v1/learning/policies/${policyKey}/insights`, {
|
|
309
|
+
collection_id: params.collection_id,
|
|
310
|
+
user_id: params.user_id,
|
|
311
|
+
action_key: params.action_keys,
|
|
312
|
+
context: params.context ? JSON.stringify(params.context) : void 0
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
async evaluatePolicy(policyKey, params = {}) {
|
|
316
|
+
return this.client.post(`/v1/learning/policies/${policyKey}/evaluate`, {
|
|
137
317
|
collection_id: params.collection_id,
|
|
138
|
-
|
|
139
|
-
|
|
318
|
+
user_id: params.user_id,
|
|
319
|
+
limit: params.limit ?? 500
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
async proof(decisionId) {
|
|
323
|
+
return this.client.get(`/v1/learning/decisions/${decisionId}/proof`);
|
|
324
|
+
}
|
|
325
|
+
async publicKey(keyId) {
|
|
326
|
+
return this.client.get("/v1/learning/proof-key", {
|
|
327
|
+
key_id: keyId
|
|
140
328
|
});
|
|
141
329
|
}
|
|
142
330
|
};
|
|
@@ -434,6 +622,8 @@ var MemoryClient = class {
|
|
|
434
622
|
this.auth = new AuthResource(this);
|
|
435
623
|
this.collections = new CollectionsResource(this);
|
|
436
624
|
this.memories = new MemoriesResource(this);
|
|
625
|
+
this.memoryJobs = new MemoryJobsResource(this);
|
|
626
|
+
this.corrections = new CorrectionsResource(this);
|
|
437
627
|
this.searchResource = new SearchResource(this);
|
|
438
628
|
this.rl = new RLResource(this);
|
|
439
629
|
this.procedural = new ProceduralResource(this);
|
|
@@ -442,11 +632,12 @@ var MemoryClient = class {
|
|
|
442
632
|
this.consolidation = new ConsolidationResource(this);
|
|
443
633
|
this.memoryTools = new MemoryToolsResource(this);
|
|
444
634
|
this.worldModel = new WorldModelResource(this);
|
|
635
|
+
this.proofloop = new ProofLoopResource(this);
|
|
445
636
|
}
|
|
446
637
|
getHeaders() {
|
|
447
638
|
const headers = {
|
|
448
639
|
"Content-Type": "application/json",
|
|
449
|
-
"User-Agent": "hebbrix-typescript/2.
|
|
640
|
+
"User-Agent": "hebbrix-typescript/2.2.0"
|
|
450
641
|
};
|
|
451
642
|
if (this.apiKey) {
|
|
452
643
|
headers["Authorization"] = `Bearer ${this.apiKey}`;
|
|
@@ -500,7 +691,11 @@ var MemoryClient = class {
|
|
|
500
691
|
const searchParams = new URLSearchParams();
|
|
501
692
|
Object.entries(params).forEach(([key, value]) => {
|
|
502
693
|
if (value !== void 0 && value !== null) {
|
|
503
|
-
|
|
694
|
+
if (Array.isArray(value)) {
|
|
695
|
+
value.forEach((item) => searchParams.append(key, String(item)));
|
|
696
|
+
} else {
|
|
697
|
+
searchParams.append(key, String(value));
|
|
698
|
+
}
|
|
504
699
|
}
|
|
505
700
|
});
|
|
506
701
|
url += `?${searchParams.toString()}`;
|
|
@@ -524,6 +719,9 @@ var MemoryClient = class {
|
|
|
524
719
|
async search(params) {
|
|
525
720
|
return this.searchResource.search(params);
|
|
526
721
|
}
|
|
722
|
+
async searchWithProof(params) {
|
|
723
|
+
return this.searchResource.searchWithProof(params);
|
|
724
|
+
}
|
|
527
725
|
async reason(params) {
|
|
528
726
|
return this.searchResource.reason(params);
|
|
529
727
|
}
|
|
@@ -533,12 +731,15 @@ export {
|
|
|
533
731
|
AuthenticationError,
|
|
534
732
|
CollectionsResource,
|
|
535
733
|
ConsolidationResource,
|
|
734
|
+
CorrectionsResource,
|
|
536
735
|
HebbrixError,
|
|
537
736
|
MemoriesResource,
|
|
538
737
|
MemoryClient,
|
|
738
|
+
MemoryJobsResource,
|
|
539
739
|
MemoryToolsResource,
|
|
540
740
|
NotFoundError,
|
|
541
741
|
ProceduralResource,
|
|
742
|
+
ProofLoopResource,
|
|
542
743
|
RLResource,
|
|
543
744
|
RateLimitError,
|
|
544
745
|
SearchResource,
|
|
@@ -546,5 +747,6 @@ export {
|
|
|
546
747
|
TemporalResource,
|
|
547
748
|
ValidationError,
|
|
548
749
|
WorkingMemoryResource,
|
|
549
|
-
WorldModelResource
|
|
750
|
+
WorldModelResource,
|
|
751
|
+
enforceSearchSafety
|
|
550
752
|
};
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hebbrix",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Advanced Memory API for AI Agents with Reinforcement Learning - TypeScript/JavaScript SDK",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
10
11
|
"import": "./dist/index.mjs",
|
|
11
|
-
"require": "./dist/index.js"
|
|
12
|
-
"types": "./dist/index.d.ts"
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"scripts": {
|
|
20
20
|
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
21
21
|
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
22
|
-
"test": "
|
|
22
|
+
"test": "npm run build && node --test tests/*.test.mjs",
|
|
23
23
|
"lint": "eslint src --ext .ts",
|
|
24
24
|
"format": "prettier --write \"src/**/*.ts\"",
|
|
25
25
|
"prepublishOnly": "npm run build"
|
|
@@ -47,12 +47,15 @@
|
|
|
47
47
|
"license": "MIT",
|
|
48
48
|
"repository": {
|
|
49
49
|
"type": "git",
|
|
50
|
-
"url": "https://github.com/
|
|
50
|
+
"url": "git+https://github.com/Hebbrix/hebbrix-typescript.git"
|
|
51
51
|
},
|
|
52
52
|
"bugs": {
|
|
53
53
|
"url": "https://github.com/hebbrix/hebbrix-typescript/issues"
|
|
54
54
|
},
|
|
55
55
|
"homepage": "https://hebbrix.com",
|
|
56
|
+
"publishConfig": {
|
|
57
|
+
"access": "public"
|
|
58
|
+
},
|
|
56
59
|
"devDependencies": {
|
|
57
60
|
"@types/node": "^20.10.0",
|
|
58
61
|
"@typescript-eslint/eslint-plugin": "^6.15.0",
|