@subcortex-ai/sdk 0.2.0 → 0.3.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/dist/index.cjs +273 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +211 -1
- package/dist/index.d.ts +211 -1
- package/dist/index.js +271 -30
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -46,6 +46,8 @@ __export(index_exports, {
|
|
|
46
46
|
RecallNamespace: () => RecallNamespace,
|
|
47
47
|
RelationshipTypes: () => RelationshipTypes,
|
|
48
48
|
RelationshipsNamespace: () => RelationshipsNamespace,
|
|
49
|
+
RulePredicates: () => RulePredicates,
|
|
50
|
+
RulesNamespace: () => RulesNamespace,
|
|
49
51
|
SIGNAL_DECAY_CONFIG: () => SIGNAL_DECAY_CONFIG,
|
|
50
52
|
SYSTEM_SIGNAL_TYPES: () => SYSTEM_SIGNAL_TYPES,
|
|
51
53
|
SearchNamespace: () => SearchNamespace,
|
|
@@ -1137,6 +1139,242 @@ function enc2(s) {
|
|
|
1137
1139
|
return encodeURIComponent(s);
|
|
1138
1140
|
}
|
|
1139
1141
|
|
|
1142
|
+
// src/types/rules.ts
|
|
1143
|
+
var RulePredicates = {
|
|
1144
|
+
BANNED_PATTERN: "rule:banned_pattern",
|
|
1145
|
+
REQUIRED_PATTERN: "rule:required_pattern",
|
|
1146
|
+
FILE_CONSTRAINT: "rule:file_constraint",
|
|
1147
|
+
REQUIRES_PROPAGATION: "rule:requires_propagation"
|
|
1148
|
+
};
|
|
1149
|
+
|
|
1150
|
+
// src/rules.ts
|
|
1151
|
+
var RULE_PREDICATE_PREFIX = "rule:";
|
|
1152
|
+
var TYPE_TO_PREDICATE = {
|
|
1153
|
+
banned_pattern: RulePredicates.BANNED_PATTERN,
|
|
1154
|
+
required_pattern: RulePredicates.REQUIRED_PATTERN,
|
|
1155
|
+
file_constraint: RulePredicates.FILE_CONSTRAINT,
|
|
1156
|
+
requires_propagation: RulePredicates.REQUIRES_PROPAGATION
|
|
1157
|
+
};
|
|
1158
|
+
function defaultSeverity(confidence) {
|
|
1159
|
+
if (confidence >= 1) return "block";
|
|
1160
|
+
if (confidence >= 0.7) return "warn";
|
|
1161
|
+
return "info";
|
|
1162
|
+
}
|
|
1163
|
+
var RulesNamespace = class {
|
|
1164
|
+
http;
|
|
1165
|
+
tenantId;
|
|
1166
|
+
constructor(http, tenantId) {
|
|
1167
|
+
this.http = http;
|
|
1168
|
+
this.tenantId = tenantId;
|
|
1169
|
+
}
|
|
1170
|
+
/**
|
|
1171
|
+
* Create a new rule.
|
|
1172
|
+
*
|
|
1173
|
+
* Stores an assertion with a `rule:*` predicate and a typed value.
|
|
1174
|
+
* Defaults to confidence 1.0 (enforcement) if not specified.
|
|
1175
|
+
*
|
|
1176
|
+
* @example
|
|
1177
|
+
* ```typescript
|
|
1178
|
+
* await subcortex.rules.create({
|
|
1179
|
+
* subject: 'project:my-project',
|
|
1180
|
+
* type: 'banned_pattern',
|
|
1181
|
+
* pattern: 'as any',
|
|
1182
|
+
* description: 'No any casts — use proper types',
|
|
1183
|
+
* })
|
|
1184
|
+
* ```
|
|
1185
|
+
*/
|
|
1186
|
+
async create(input) {
|
|
1187
|
+
const confidence = input.confidence ?? 1;
|
|
1188
|
+
const severity = input.severity ?? defaultSeverity(confidence);
|
|
1189
|
+
const ruleValue = {
|
|
1190
|
+
description: input.description,
|
|
1191
|
+
pattern: input.pattern,
|
|
1192
|
+
fileScope: input.fileScope,
|
|
1193
|
+
propagatesTo: input.propagatesTo
|
|
1194
|
+
};
|
|
1195
|
+
const assertion = await this.http.post(
|
|
1196
|
+
`/api/v1/assertions`,
|
|
1197
|
+
{
|
|
1198
|
+
subject: input.subject,
|
|
1199
|
+
predicate: TYPE_TO_PREDICATE[input.type],
|
|
1200
|
+
value: { ...ruleValue, severity },
|
|
1201
|
+
confidence,
|
|
1202
|
+
tenant_id: input.tenantId ?? this.tenantId
|
|
1203
|
+
},
|
|
1204
|
+
input.tenantId ?? this.tenantId
|
|
1205
|
+
);
|
|
1206
|
+
return parseRule(assertion);
|
|
1207
|
+
}
|
|
1208
|
+
/**
|
|
1209
|
+
* Get a rule by its assertion ID.
|
|
1210
|
+
*/
|
|
1211
|
+
async get(ruleId, options) {
|
|
1212
|
+
const tenant = options?.tenantId ?? this.tenantId;
|
|
1213
|
+
const assertion = await this.http.get(
|
|
1214
|
+
`/api/v1/assertions/${enc3(tenant)}/${enc3(ruleId)}`
|
|
1215
|
+
);
|
|
1216
|
+
return parseRule(assertion);
|
|
1217
|
+
}
|
|
1218
|
+
/**
|
|
1219
|
+
* List all rules for this project, optionally filtered by type or severity.
|
|
1220
|
+
*/
|
|
1221
|
+
async list(options) {
|
|
1222
|
+
const tenant = options?.tenantId ?? this.tenantId;
|
|
1223
|
+
const assertions = await this.http.get(
|
|
1224
|
+
`/api/v1/assertions/list/${enc3(tenant)}`
|
|
1225
|
+
);
|
|
1226
|
+
return assertions.filter((a) => isRuleAssertion(a)).filter((a) => options?.includeSuperseded || !a.isSuperseded).map(parseRule).filter((r) => !options?.type || r.type === options.type).filter((r) => !options?.severity || r.severity === options.severity);
|
|
1227
|
+
}
|
|
1228
|
+
/**
|
|
1229
|
+
* Get all rules whose fileScope matches the given file path.
|
|
1230
|
+
*
|
|
1231
|
+
* This is the primary query for the PreToolUse hook — "what rules apply
|
|
1232
|
+
* to the file I'm about to modify?"
|
|
1233
|
+
*
|
|
1234
|
+
* @example
|
|
1235
|
+
* ```typescript
|
|
1236
|
+
* const rules = await subcortex.rules.forFile('app/api/users/route.ts')
|
|
1237
|
+
* // Returns banned_pattern and required_pattern rules whose fileScope
|
|
1238
|
+
* // matches the path, plus any project-wide rules without a fileScope.
|
|
1239
|
+
* ```
|
|
1240
|
+
*/
|
|
1241
|
+
async forFile(filePath, options) {
|
|
1242
|
+
const allRules = await this.list(options);
|
|
1243
|
+
return allRules.filter((rule) => {
|
|
1244
|
+
if (!rule.value.fileScope) return true;
|
|
1245
|
+
try {
|
|
1246
|
+
const regex = new RegExp(rule.value.fileScope);
|
|
1247
|
+
return regex.test(filePath);
|
|
1248
|
+
} catch {
|
|
1249
|
+
return false;
|
|
1250
|
+
}
|
|
1251
|
+
});
|
|
1252
|
+
}
|
|
1253
|
+
/**
|
|
1254
|
+
* Get all rules scoped to a specific intent subject.
|
|
1255
|
+
*
|
|
1256
|
+
* @example
|
|
1257
|
+
* ```typescript
|
|
1258
|
+
* const apiRules = await subcortex.rules.forIntent('api')
|
|
1259
|
+
* // Queries subject "intent:api" for all rule assertions
|
|
1260
|
+
* ```
|
|
1261
|
+
*/
|
|
1262
|
+
async forIntent(intent, options) {
|
|
1263
|
+
const tenant = options?.tenantId ?? this.tenantId;
|
|
1264
|
+
const subject2 = intent.startsWith("intent:") ? intent : `intent:${intent}`;
|
|
1265
|
+
const assertions = await this.http.get(
|
|
1266
|
+
`/api/v1/assertions/query/${enc3(tenant)}/${enc3(subject2)}`
|
|
1267
|
+
);
|
|
1268
|
+
return assertions.filter((a) => isRuleAssertion(a)).filter((a) => options?.includeSuperseded || !a.isSuperseded).map(parseRule).filter((r) => !options?.type || r.type === options.type).filter((r) => !options?.severity || r.severity === options.severity);
|
|
1269
|
+
}
|
|
1270
|
+
/**
|
|
1271
|
+
* Get all rules scoped to a specific subject (project, file, intent, etc.).
|
|
1272
|
+
*/
|
|
1273
|
+
async forSubject(subject2, options) {
|
|
1274
|
+
const tenant = options?.tenantId ?? this.tenantId;
|
|
1275
|
+
const assertions = await this.http.get(
|
|
1276
|
+
`/api/v1/assertions/query/${enc3(tenant)}/${enc3(subject2)}`
|
|
1277
|
+
);
|
|
1278
|
+
return assertions.filter((a) => isRuleAssertion(a)).filter((a) => options?.includeSuperseded || !a.isSuperseded).map(parseRule).filter((r) => !options?.type || r.type === options.type).filter((r) => !options?.severity || r.severity === options.severity);
|
|
1279
|
+
}
|
|
1280
|
+
/**
|
|
1281
|
+
* Update a rule by superseding it.
|
|
1282
|
+
*
|
|
1283
|
+
* The old rule is marked as superseded, a new one is created.
|
|
1284
|
+
* Full assertion history is preserved.
|
|
1285
|
+
*/
|
|
1286
|
+
async update(input) {
|
|
1287
|
+
const tenant = input.tenantId ?? this.tenantId;
|
|
1288
|
+
const existing = await this.get(input.ruleId, { tenantId: tenant });
|
|
1289
|
+
const confidence = input.confidence ?? existing.confidence;
|
|
1290
|
+
const severity = input.severity ?? existing.severity;
|
|
1291
|
+
const ruleValue = {
|
|
1292
|
+
description: input.description ?? existing.value.description,
|
|
1293
|
+
pattern: input.pattern ?? existing.value.pattern,
|
|
1294
|
+
fileScope: input.fileScope ?? existing.value.fileScope,
|
|
1295
|
+
propagatesTo: input.propagatesTo ?? existing.value.propagatesTo
|
|
1296
|
+
};
|
|
1297
|
+
const assertion = await this.http.post(
|
|
1298
|
+
`/api/v1/assertions/supersede`,
|
|
1299
|
+
{
|
|
1300
|
+
original_assertion_id: input.ruleId,
|
|
1301
|
+
subject: existing.subject,
|
|
1302
|
+
predicate: existing.predicate,
|
|
1303
|
+
value: { ...ruleValue, severity },
|
|
1304
|
+
confidence,
|
|
1305
|
+
tenant_id: tenant
|
|
1306
|
+
},
|
|
1307
|
+
tenant
|
|
1308
|
+
);
|
|
1309
|
+
return parseRule(assertion);
|
|
1310
|
+
}
|
|
1311
|
+
/**
|
|
1312
|
+
* Retract (deactivate) a rule.
|
|
1313
|
+
*
|
|
1314
|
+
* The assertion's temporal bounds are closed. The rule stops matching
|
|
1315
|
+
* in future queries but its history is preserved.
|
|
1316
|
+
*/
|
|
1317
|
+
async retract(ruleId, options) {
|
|
1318
|
+
const tenant = options?.tenantId ?? this.tenantId;
|
|
1319
|
+
await this.http.post(
|
|
1320
|
+
`/api/v1/assertions/retract/${enc3(tenant)}/${enc3(ruleId)}`,
|
|
1321
|
+
{},
|
|
1322
|
+
tenant
|
|
1323
|
+
);
|
|
1324
|
+
}
|
|
1325
|
+
};
|
|
1326
|
+
function isRuleAssertion(assertion) {
|
|
1327
|
+
return assertion.predicate?.startsWith(RULE_PREDICATE_PREFIX) ?? false;
|
|
1328
|
+
}
|
|
1329
|
+
function parseRule(assertion) {
|
|
1330
|
+
const predicate = assertion.predicate;
|
|
1331
|
+
const type = predicate.replace(RULE_PREDICATE_PREFIX, "");
|
|
1332
|
+
let ruleValue;
|
|
1333
|
+
let severity;
|
|
1334
|
+
if (typeof assertion.value === "object" && assertion.value !== null) {
|
|
1335
|
+
const val = assertion.value;
|
|
1336
|
+
ruleValue = {
|
|
1337
|
+
description: String(val.description ?? ""),
|
|
1338
|
+
pattern: val.pattern != null ? String(val.pattern) : void 0,
|
|
1339
|
+
fileScope: val.fileScope != null ? String(val.fileScope) : void 0,
|
|
1340
|
+
propagatesTo: Array.isArray(val.propagatesTo) ? val.propagatesTo.map(String) : void 0
|
|
1341
|
+
};
|
|
1342
|
+
severity = val.severity ?? defaultSeverity(assertion.confidence);
|
|
1343
|
+
} else if (typeof assertion.value === "string") {
|
|
1344
|
+
try {
|
|
1345
|
+
const parsed = JSON.parse(assertion.value);
|
|
1346
|
+
ruleValue = {
|
|
1347
|
+
description: String(parsed.description ?? ""),
|
|
1348
|
+
pattern: parsed.pattern != null ? String(parsed.pattern) : void 0,
|
|
1349
|
+
fileScope: parsed.filePattern != null ? String(parsed.filePattern) : void 0,
|
|
1350
|
+
propagatesTo: Array.isArray(parsed.propagatesTo) ? parsed.propagatesTo.map(String) : void 0
|
|
1351
|
+
};
|
|
1352
|
+
severity = parsed.severity ?? defaultSeverity(assertion.confidence);
|
|
1353
|
+
} catch {
|
|
1354
|
+
ruleValue = { description: String(assertion.value) };
|
|
1355
|
+
severity = defaultSeverity(assertion.confidence);
|
|
1356
|
+
}
|
|
1357
|
+
} else {
|
|
1358
|
+
ruleValue = { description: "" };
|
|
1359
|
+
severity = defaultSeverity(assertion.confidence);
|
|
1360
|
+
}
|
|
1361
|
+
return {
|
|
1362
|
+
id: assertion.id,
|
|
1363
|
+
tenantId: assertion.tenantId,
|
|
1364
|
+
subject: assertion.subject,
|
|
1365
|
+
type,
|
|
1366
|
+
predicate,
|
|
1367
|
+
value: ruleValue,
|
|
1368
|
+
severity,
|
|
1369
|
+
confidence: assertion.confidence,
|
|
1370
|
+
validFrom: assertion.validFrom,
|
|
1371
|
+
isSuperseded: assertion.isSuperseded
|
|
1372
|
+
};
|
|
1373
|
+
}
|
|
1374
|
+
function enc3(s) {
|
|
1375
|
+
return encodeURIComponent(s);
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1140
1378
|
// src/client.ts
|
|
1141
1379
|
var AssertionsNamespace = class {
|
|
1142
1380
|
constructor(http, tenantId) {
|
|
@@ -1158,21 +1396,21 @@ var AssertionsNamespace = class {
|
|
|
1158
1396
|
async get(assertionId, options) {
|
|
1159
1397
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1160
1398
|
return this.http.get(
|
|
1161
|
-
`/api/v1/assertions/${
|
|
1399
|
+
`/api/v1/assertions/${enc4(tenantId)}/${enc4(assertionId)}`
|
|
1162
1400
|
);
|
|
1163
1401
|
}
|
|
1164
1402
|
/** Query assertions by subject. */
|
|
1165
1403
|
async query(subject2, options) {
|
|
1166
1404
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1167
1405
|
return this.http.get(
|
|
1168
|
-
`/api/v1/assertions/query/${
|
|
1406
|
+
`/api/v1/assertions/query/${enc4(tenantId)}/${enc4(subject2)}`
|
|
1169
1407
|
);
|
|
1170
1408
|
}
|
|
1171
1409
|
/** List all active assertions for the tenant. */
|
|
1172
1410
|
async list(options) {
|
|
1173
1411
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1174
1412
|
return this.http.get(
|
|
1175
|
-
`/api/v1/assertions/list/${
|
|
1413
|
+
`/api/v1/assertions/list/${enc4(tenantId)}`
|
|
1176
1414
|
);
|
|
1177
1415
|
}
|
|
1178
1416
|
/** Supersede an existing assertion with updated values. */
|
|
@@ -1191,7 +1429,7 @@ var AssertionsNamespace = class {
|
|
|
1191
1429
|
async retract(assertionId, options) {
|
|
1192
1430
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1193
1431
|
return this.http.post(
|
|
1194
|
-
`/api/v1/assertions/retract/${
|
|
1432
|
+
`/api/v1/assertions/retract/${enc4(tenantId)}/${enc4(assertionId)}`,
|
|
1195
1433
|
{}
|
|
1196
1434
|
);
|
|
1197
1435
|
}
|
|
@@ -1218,14 +1456,14 @@ var RelationshipsNamespace = class {
|
|
|
1218
1456
|
async query(subject2, options) {
|
|
1219
1457
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1220
1458
|
return this.http.get(
|
|
1221
|
-
`/api/v1/relationships/${
|
|
1459
|
+
`/api/v1/relationships/${enc4(tenantId)}/${enc4(subject2)}`
|
|
1222
1460
|
);
|
|
1223
1461
|
}
|
|
1224
1462
|
/** List all relationships for the tenant. */
|
|
1225
1463
|
async list(options) {
|
|
1226
1464
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1227
1465
|
return this.http.get(
|
|
1228
|
-
`/api/v1/relationships/list/${
|
|
1466
|
+
`/api/v1/relationships/list/${enc4(tenantId)}`
|
|
1229
1467
|
);
|
|
1230
1468
|
}
|
|
1231
1469
|
};
|
|
@@ -1252,14 +1490,14 @@ var AgentsNamespace = class {
|
|
|
1252
1490
|
async get(agentId, options) {
|
|
1253
1491
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1254
1492
|
return this.http.get(
|
|
1255
|
-
`/api/v1/agents/${
|
|
1493
|
+
`/api/v1/agents/${enc4(tenantId)}/${enc4(agentId)}`
|
|
1256
1494
|
);
|
|
1257
1495
|
}
|
|
1258
1496
|
/** Update an agent. */
|
|
1259
1497
|
async update(agentId, input, options) {
|
|
1260
1498
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1261
1499
|
return this.http.put(
|
|
1262
|
-
`/api/v1/agents/${
|
|
1500
|
+
`/api/v1/agents/${enc4(tenantId)}/${enc4(agentId)}`,
|
|
1263
1501
|
{
|
|
1264
1502
|
tenant_id: tenantId,
|
|
1265
1503
|
name: input.name,
|
|
@@ -1276,20 +1514,20 @@ var AgentsNamespace = class {
|
|
|
1276
1514
|
/** Delete an agent. */
|
|
1277
1515
|
async delete(agentId, options) {
|
|
1278
1516
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1279
|
-
await this.http.delete(`/api/v1/agents/${
|
|
1517
|
+
await this.http.delete(`/api/v1/agents/${enc4(tenantId)}/${enc4(agentId)}`);
|
|
1280
1518
|
}
|
|
1281
1519
|
/** List all agents for the tenant. */
|
|
1282
1520
|
async list(options) {
|
|
1283
1521
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1284
1522
|
return this.http.get(
|
|
1285
|
-
`/api/v1/agents/list/${
|
|
1523
|
+
`/api/v1/agents/list/${enc4(tenantId)}`
|
|
1286
1524
|
);
|
|
1287
1525
|
}
|
|
1288
1526
|
/** Get composed system instructions for an agent. */
|
|
1289
1527
|
async getInstructions(agentId, options) {
|
|
1290
1528
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1291
1529
|
return this.http.get(
|
|
1292
|
-
`/api/v1/agents/${
|
|
1530
|
+
`/api/v1/agents/${enc4(tenantId)}/${enc4(agentId)}/instructions`
|
|
1293
1531
|
);
|
|
1294
1532
|
}
|
|
1295
1533
|
};
|
|
@@ -1339,14 +1577,14 @@ var MemoryNamespace = class {
|
|
|
1339
1577
|
async recall(subject2, options) {
|
|
1340
1578
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1341
1579
|
return this.http.get(
|
|
1342
|
-
`/api/v1/assertions/query/${
|
|
1580
|
+
`/api/v1/assertions/query/${enc4(tenantId)}/${enc4(subject2)}`
|
|
1343
1581
|
);
|
|
1344
1582
|
}
|
|
1345
1583
|
/** Forget a specific memory (retract the assertion). */
|
|
1346
1584
|
async forget(assertionId, options) {
|
|
1347
1585
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1348
1586
|
return this.http.post(
|
|
1349
|
-
`/api/v1/assertions/retract/${
|
|
1587
|
+
`/api/v1/assertions/retract/${enc4(tenantId)}/${enc4(assertionId)}`,
|
|
1350
1588
|
{}
|
|
1351
1589
|
);
|
|
1352
1590
|
}
|
|
@@ -1378,7 +1616,7 @@ var IntakeNamespace = class {
|
|
|
1378
1616
|
}
|
|
1379
1617
|
/** Get pending intake results for an agent. */
|
|
1380
1618
|
async pending(agentId, options) {
|
|
1381
|
-
let path = `/api/v1/intake/pending/${
|
|
1619
|
+
let path = `/api/v1/intake/pending/${enc4(agentId)}`;
|
|
1382
1620
|
const params = [];
|
|
1383
1621
|
if (options?.status) params.push(`status=${options.status.join(",")}`);
|
|
1384
1622
|
if (options?.limit) params.push(`limit=${options.limit}`);
|
|
@@ -1387,18 +1625,18 @@ var IntakeNamespace = class {
|
|
|
1387
1625
|
}
|
|
1388
1626
|
/** Acknowledge an intake result (mark as consumed). */
|
|
1389
1627
|
async acknowledge(itemId) {
|
|
1390
|
-
await this.http.post(`/api/v1/intake/acknowledge/${
|
|
1628
|
+
await this.http.post(`/api/v1/intake/acknowledge/${enc4(itemId)}`, {});
|
|
1391
1629
|
}
|
|
1392
1630
|
/** Acknowledge all pending items for an agent. */
|
|
1393
1631
|
async acknowledgeAll(agentId) {
|
|
1394
1632
|
return this.http.post(
|
|
1395
|
-
`/api/v1/intake/acknowledge-all/${
|
|
1633
|
+
`/api/v1/intake/acknowledge-all/${enc4(agentId)}`,
|
|
1396
1634
|
{}
|
|
1397
1635
|
);
|
|
1398
1636
|
}
|
|
1399
1637
|
/** Get intake processing stats for an agent. */
|
|
1400
1638
|
async stats(agentId) {
|
|
1401
|
-
return this.http.get(`/api/v1/intake/stats/${
|
|
1639
|
+
return this.http.get(`/api/v1/intake/stats/${enc4(agentId)}`);
|
|
1402
1640
|
}
|
|
1403
1641
|
};
|
|
1404
1642
|
var ExperiencesNamespace = class {
|
|
@@ -1414,14 +1652,14 @@ var ExperiencesNamespace = class {
|
|
|
1414
1652
|
if (input?.limit) params.set("limit", String(input.limit));
|
|
1415
1653
|
const qs = params.toString();
|
|
1416
1654
|
return this.http.get(
|
|
1417
|
-
`/api/v1/experiences/${
|
|
1655
|
+
`/api/v1/experiences/${enc4(tenantId)}${qs ? `?${qs}` : ""}`
|
|
1418
1656
|
);
|
|
1419
1657
|
}
|
|
1420
1658
|
/** Get a single experience by ID. */
|
|
1421
1659
|
async get(experienceId, options) {
|
|
1422
1660
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1423
1661
|
return this.http.get(
|
|
1424
|
-
`/api/v1/experiences/${
|
|
1662
|
+
`/api/v1/experiences/${enc4(tenantId)}/${enc4(experienceId)}`
|
|
1425
1663
|
);
|
|
1426
1664
|
}
|
|
1427
1665
|
};
|
|
@@ -1436,7 +1674,7 @@ var RecallNamespace = class {
|
|
|
1436
1674
|
const params = new URLSearchParams({ q: input.query });
|
|
1437
1675
|
if (input.limit) params.set("limit", String(input.limit));
|
|
1438
1676
|
return this.http.get(
|
|
1439
|
-
`/api/v1/recall/${
|
|
1677
|
+
`/api/v1/recall/${enc4(tenantId)}?${params.toString()}`
|
|
1440
1678
|
);
|
|
1441
1679
|
}
|
|
1442
1680
|
};
|
|
@@ -1449,7 +1687,7 @@ var GraphNamespace = class {
|
|
|
1449
1687
|
async findPaths(input) {
|
|
1450
1688
|
const tenantId = input.tenantId || this.tenantId;
|
|
1451
1689
|
return this.http.post(
|
|
1452
|
-
`/api/v1/graph/${
|
|
1690
|
+
`/api/v1/graph/${enc4(tenantId)}/paths`,
|
|
1453
1691
|
{
|
|
1454
1692
|
from: input.from,
|
|
1455
1693
|
to: input.to,
|
|
@@ -1463,7 +1701,7 @@ var GraphNamespace = class {
|
|
|
1463
1701
|
async traverse(input) {
|
|
1464
1702
|
const tenantId = input.tenantId || this.tenantId;
|
|
1465
1703
|
return this.http.post(
|
|
1466
|
-
`/api/v1/graph/${
|
|
1704
|
+
`/api/v1/graph/${enc4(tenantId)}/traverse`,
|
|
1467
1705
|
{
|
|
1468
1706
|
start_subject: input.startSubject,
|
|
1469
1707
|
max_depth: input.maxDepth,
|
|
@@ -1484,7 +1722,7 @@ var TemporalNamespace = class {
|
|
|
1484
1722
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1485
1723
|
const pointStr = point instanceof Date ? point.toISOString() : point;
|
|
1486
1724
|
return this.http.get(
|
|
1487
|
-
`/api/v1/temporal/${
|
|
1725
|
+
`/api/v1/temporal/${enc4(tenantId)}/${enc4(subject2)}/at?point=${enc4(pointStr)}`
|
|
1488
1726
|
);
|
|
1489
1727
|
}
|
|
1490
1728
|
/** Get assertions within a date range. */
|
|
@@ -1493,7 +1731,7 @@ var TemporalNamespace = class {
|
|
|
1493
1731
|
const startStr = start instanceof Date ? start.toISOString() : start;
|
|
1494
1732
|
const endStr = end instanceof Date ? end.toISOString() : end;
|
|
1495
1733
|
return this.http.get(
|
|
1496
|
-
`/api/v1/temporal/${
|
|
1734
|
+
`/api/v1/temporal/${enc4(tenantId)}/${enc4(subject2)}/range?start=${enc4(startStr)}&end=${enc4(endStr)}`
|
|
1497
1735
|
);
|
|
1498
1736
|
}
|
|
1499
1737
|
};
|
|
@@ -1506,7 +1744,7 @@ var SearchNamespace = class {
|
|
|
1506
1744
|
async semantic(input) {
|
|
1507
1745
|
const tenantId = input.tenantId || this.tenantId;
|
|
1508
1746
|
return this.http.post(
|
|
1509
|
-
`/api/v1/search/${
|
|
1747
|
+
`/api/v1/search/${enc4(tenantId)}/semantic`,
|
|
1510
1748
|
{
|
|
1511
1749
|
embedding: input.embedding,
|
|
1512
1750
|
top_k: input.topK
|
|
@@ -1596,10 +1834,10 @@ var EntitiesNamespace = class {
|
|
|
1596
1834
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1597
1835
|
const subject2 = `entity:${entityName.toLowerCase().replace(/\s+/g, "-")}`;
|
|
1598
1836
|
const assertions = await this.http.get(
|
|
1599
|
-
`/api/v1/assertions/query/${
|
|
1837
|
+
`/api/v1/assertions/query/${enc4(tenantId)}/${enc4(subject2)}`
|
|
1600
1838
|
);
|
|
1601
1839
|
const relationships = await this.http.get(
|
|
1602
|
-
`/api/v1/relationships/query/${
|
|
1840
|
+
`/api/v1/relationships/query/${enc4(tenantId)}/${enc4(subject2)}`
|
|
1603
1841
|
);
|
|
1604
1842
|
const typeAssertion = assertions.find((a) => a.predicate === "type" && !a.isSuperseded);
|
|
1605
1843
|
const descAssertion = assertions.find((a) => a.predicate === "description" && !a.isSuperseded);
|
|
@@ -1607,7 +1845,7 @@ var EntitiesNamespace = class {
|
|
|
1607
1845
|
const properties = await Promise.all(
|
|
1608
1846
|
propertyRels.map(async (rel) => {
|
|
1609
1847
|
const propAssertions = await this.http.get(
|
|
1610
|
-
`/api/v1/assertions/query/${
|
|
1848
|
+
`/api/v1/assertions/query/${enc4(tenantId)}/${enc4(rel.toSubject)}`
|
|
1611
1849
|
);
|
|
1612
1850
|
const fieldType = propAssertions.find((a) => a.predicate === "field_type" && !a.isSuperseded);
|
|
1613
1851
|
const required = propAssertions.find((a) => a.predicate === "required" && !a.isSuperseded);
|
|
@@ -1637,7 +1875,7 @@ var EntitiesNamespace = class {
|
|
|
1637
1875
|
async list(options) {
|
|
1638
1876
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1639
1877
|
const all = await this.http.get(
|
|
1640
|
-
`/api/v1/assertions/list/${
|
|
1878
|
+
`/api/v1/assertions/list/${enc4(tenantId)}`
|
|
1641
1879
|
);
|
|
1642
1880
|
return all.filter((a) => a.subject.startsWith("entity:") && a.predicate === "type" && !a.isSuperseded);
|
|
1643
1881
|
}
|
|
@@ -1669,6 +1907,8 @@ var SubCortexClient = class {
|
|
|
1669
1907
|
experiences;
|
|
1670
1908
|
/** Entity schema management — create, describe, and manage data models */
|
|
1671
1909
|
entities;
|
|
1910
|
+
/** Code guardrails — typed rules stored as assertions with file-scope matching */
|
|
1911
|
+
rules;
|
|
1672
1912
|
http;
|
|
1673
1913
|
constructor(options) {
|
|
1674
1914
|
if (!options.apiKey && !options.token) {
|
|
@@ -1698,13 +1938,14 @@ var SubCortexClient = class {
|
|
|
1698
1938
|
this.recall = new RecallNamespace(this.http, options.tenantId);
|
|
1699
1939
|
this.experiences = new ExperiencesNamespace(this.http, options.tenantId);
|
|
1700
1940
|
this.entities = new EntitiesNamespace(this.http, options.tenantId);
|
|
1941
|
+
this.rules = new RulesNamespace(this.http, options.tenantId);
|
|
1701
1942
|
}
|
|
1702
1943
|
/** Check SubCortex server health. */
|
|
1703
1944
|
async health() {
|
|
1704
1945
|
return this.http.get("/health");
|
|
1705
1946
|
}
|
|
1706
1947
|
};
|
|
1707
|
-
function
|
|
1948
|
+
function enc4(s) {
|
|
1708
1949
|
return encodeURIComponent(s);
|
|
1709
1950
|
}
|
|
1710
1951
|
|
|
@@ -1894,6 +2135,8 @@ function esc(s) {
|
|
|
1894
2135
|
RecallNamespace,
|
|
1895
2136
|
RelationshipTypes,
|
|
1896
2137
|
RelationshipsNamespace,
|
|
2138
|
+
RulePredicates,
|
|
2139
|
+
RulesNamespace,
|
|
1897
2140
|
SIGNAL_DECAY_CONFIG,
|
|
1898
2141
|
SYSTEM_SIGNAL_TYPES,
|
|
1899
2142
|
SearchNamespace,
|