@subcortex-ai/sdk 0.2.0 → 0.3.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/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 +1 -1
package/dist/index.js
CHANGED
|
@@ -1060,6 +1060,242 @@ function enc2(s) {
|
|
|
1060
1060
|
return encodeURIComponent(s);
|
|
1061
1061
|
}
|
|
1062
1062
|
|
|
1063
|
+
// src/types/rules.ts
|
|
1064
|
+
var RulePredicates = {
|
|
1065
|
+
BANNED_PATTERN: "rule:banned_pattern",
|
|
1066
|
+
REQUIRED_PATTERN: "rule:required_pattern",
|
|
1067
|
+
FILE_CONSTRAINT: "rule:file_constraint",
|
|
1068
|
+
REQUIRES_PROPAGATION: "rule:requires_propagation"
|
|
1069
|
+
};
|
|
1070
|
+
|
|
1071
|
+
// src/rules.ts
|
|
1072
|
+
var RULE_PREDICATE_PREFIX = "rule:";
|
|
1073
|
+
var TYPE_TO_PREDICATE = {
|
|
1074
|
+
banned_pattern: RulePredicates.BANNED_PATTERN,
|
|
1075
|
+
required_pattern: RulePredicates.REQUIRED_PATTERN,
|
|
1076
|
+
file_constraint: RulePredicates.FILE_CONSTRAINT,
|
|
1077
|
+
requires_propagation: RulePredicates.REQUIRES_PROPAGATION
|
|
1078
|
+
};
|
|
1079
|
+
function defaultSeverity(confidence) {
|
|
1080
|
+
if (confidence >= 1) return "block";
|
|
1081
|
+
if (confidence >= 0.7) return "warn";
|
|
1082
|
+
return "info";
|
|
1083
|
+
}
|
|
1084
|
+
var RulesNamespace = class {
|
|
1085
|
+
http;
|
|
1086
|
+
tenantId;
|
|
1087
|
+
constructor(http, tenantId) {
|
|
1088
|
+
this.http = http;
|
|
1089
|
+
this.tenantId = tenantId;
|
|
1090
|
+
}
|
|
1091
|
+
/**
|
|
1092
|
+
* Create a new rule.
|
|
1093
|
+
*
|
|
1094
|
+
* Stores an assertion with a `rule:*` predicate and a typed value.
|
|
1095
|
+
* Defaults to confidence 1.0 (enforcement) if not specified.
|
|
1096
|
+
*
|
|
1097
|
+
* @example
|
|
1098
|
+
* ```typescript
|
|
1099
|
+
* await subcortex.rules.create({
|
|
1100
|
+
* subject: 'project:my-project',
|
|
1101
|
+
* type: 'banned_pattern',
|
|
1102
|
+
* pattern: 'as any',
|
|
1103
|
+
* description: 'No any casts — use proper types',
|
|
1104
|
+
* })
|
|
1105
|
+
* ```
|
|
1106
|
+
*/
|
|
1107
|
+
async create(input) {
|
|
1108
|
+
const confidence = input.confidence ?? 1;
|
|
1109
|
+
const severity = input.severity ?? defaultSeverity(confidence);
|
|
1110
|
+
const ruleValue = {
|
|
1111
|
+
description: input.description,
|
|
1112
|
+
pattern: input.pattern,
|
|
1113
|
+
fileScope: input.fileScope,
|
|
1114
|
+
propagatesTo: input.propagatesTo
|
|
1115
|
+
};
|
|
1116
|
+
const assertion = await this.http.post(
|
|
1117
|
+
`/api/v1/assertions`,
|
|
1118
|
+
{
|
|
1119
|
+
subject: input.subject,
|
|
1120
|
+
predicate: TYPE_TO_PREDICATE[input.type],
|
|
1121
|
+
value: { ...ruleValue, severity },
|
|
1122
|
+
confidence,
|
|
1123
|
+
tenant_id: input.tenantId ?? this.tenantId
|
|
1124
|
+
},
|
|
1125
|
+
input.tenantId ?? this.tenantId
|
|
1126
|
+
);
|
|
1127
|
+
return parseRule(assertion);
|
|
1128
|
+
}
|
|
1129
|
+
/**
|
|
1130
|
+
* Get a rule by its assertion ID.
|
|
1131
|
+
*/
|
|
1132
|
+
async get(ruleId, options) {
|
|
1133
|
+
const tenant = options?.tenantId ?? this.tenantId;
|
|
1134
|
+
const assertion = await this.http.get(
|
|
1135
|
+
`/api/v1/assertions/${enc3(tenant)}/${enc3(ruleId)}`
|
|
1136
|
+
);
|
|
1137
|
+
return parseRule(assertion);
|
|
1138
|
+
}
|
|
1139
|
+
/**
|
|
1140
|
+
* List all rules for this project, optionally filtered by type or severity.
|
|
1141
|
+
*/
|
|
1142
|
+
async list(options) {
|
|
1143
|
+
const tenant = options?.tenantId ?? this.tenantId;
|
|
1144
|
+
const assertions = await this.http.get(
|
|
1145
|
+
`/api/v1/assertions/list/${enc3(tenant)}`
|
|
1146
|
+
);
|
|
1147
|
+
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);
|
|
1148
|
+
}
|
|
1149
|
+
/**
|
|
1150
|
+
* Get all rules whose fileScope matches the given file path.
|
|
1151
|
+
*
|
|
1152
|
+
* This is the primary query for the PreToolUse hook — "what rules apply
|
|
1153
|
+
* to the file I'm about to modify?"
|
|
1154
|
+
*
|
|
1155
|
+
* @example
|
|
1156
|
+
* ```typescript
|
|
1157
|
+
* const rules = await subcortex.rules.forFile('app/api/users/route.ts')
|
|
1158
|
+
* // Returns banned_pattern and required_pattern rules whose fileScope
|
|
1159
|
+
* // matches the path, plus any project-wide rules without a fileScope.
|
|
1160
|
+
* ```
|
|
1161
|
+
*/
|
|
1162
|
+
async forFile(filePath, options) {
|
|
1163
|
+
const allRules = await this.list(options);
|
|
1164
|
+
return allRules.filter((rule) => {
|
|
1165
|
+
if (!rule.value.fileScope) return true;
|
|
1166
|
+
try {
|
|
1167
|
+
const regex = new RegExp(rule.value.fileScope);
|
|
1168
|
+
return regex.test(filePath);
|
|
1169
|
+
} catch {
|
|
1170
|
+
return false;
|
|
1171
|
+
}
|
|
1172
|
+
});
|
|
1173
|
+
}
|
|
1174
|
+
/**
|
|
1175
|
+
* Get all rules scoped to a specific intent subject.
|
|
1176
|
+
*
|
|
1177
|
+
* @example
|
|
1178
|
+
* ```typescript
|
|
1179
|
+
* const apiRules = await subcortex.rules.forIntent('api')
|
|
1180
|
+
* // Queries subject "intent:api" for all rule assertions
|
|
1181
|
+
* ```
|
|
1182
|
+
*/
|
|
1183
|
+
async forIntent(intent, options) {
|
|
1184
|
+
const tenant = options?.tenantId ?? this.tenantId;
|
|
1185
|
+
const subject2 = intent.startsWith("intent:") ? intent : `intent:${intent}`;
|
|
1186
|
+
const assertions = await this.http.get(
|
|
1187
|
+
`/api/v1/assertions/query/${enc3(tenant)}/${enc3(subject2)}`
|
|
1188
|
+
);
|
|
1189
|
+
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);
|
|
1190
|
+
}
|
|
1191
|
+
/**
|
|
1192
|
+
* Get all rules scoped to a specific subject (project, file, intent, etc.).
|
|
1193
|
+
*/
|
|
1194
|
+
async forSubject(subject2, options) {
|
|
1195
|
+
const tenant = options?.tenantId ?? this.tenantId;
|
|
1196
|
+
const assertions = await this.http.get(
|
|
1197
|
+
`/api/v1/assertions/query/${enc3(tenant)}/${enc3(subject2)}`
|
|
1198
|
+
);
|
|
1199
|
+
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);
|
|
1200
|
+
}
|
|
1201
|
+
/**
|
|
1202
|
+
* Update a rule by superseding it.
|
|
1203
|
+
*
|
|
1204
|
+
* The old rule is marked as superseded, a new one is created.
|
|
1205
|
+
* Full assertion history is preserved.
|
|
1206
|
+
*/
|
|
1207
|
+
async update(input) {
|
|
1208
|
+
const tenant = input.tenantId ?? this.tenantId;
|
|
1209
|
+
const existing = await this.get(input.ruleId, { tenantId: tenant });
|
|
1210
|
+
const confidence = input.confidence ?? existing.confidence;
|
|
1211
|
+
const severity = input.severity ?? existing.severity;
|
|
1212
|
+
const ruleValue = {
|
|
1213
|
+
description: input.description ?? existing.value.description,
|
|
1214
|
+
pattern: input.pattern ?? existing.value.pattern,
|
|
1215
|
+
fileScope: input.fileScope ?? existing.value.fileScope,
|
|
1216
|
+
propagatesTo: input.propagatesTo ?? existing.value.propagatesTo
|
|
1217
|
+
};
|
|
1218
|
+
const assertion = await this.http.post(
|
|
1219
|
+
`/api/v1/assertions/supersede`,
|
|
1220
|
+
{
|
|
1221
|
+
original_assertion_id: input.ruleId,
|
|
1222
|
+
subject: existing.subject,
|
|
1223
|
+
predicate: existing.predicate,
|
|
1224
|
+
value: { ...ruleValue, severity },
|
|
1225
|
+
confidence,
|
|
1226
|
+
tenant_id: tenant
|
|
1227
|
+
},
|
|
1228
|
+
tenant
|
|
1229
|
+
);
|
|
1230
|
+
return parseRule(assertion);
|
|
1231
|
+
}
|
|
1232
|
+
/**
|
|
1233
|
+
* Retract (deactivate) a rule.
|
|
1234
|
+
*
|
|
1235
|
+
* The assertion's temporal bounds are closed. The rule stops matching
|
|
1236
|
+
* in future queries but its history is preserved.
|
|
1237
|
+
*/
|
|
1238
|
+
async retract(ruleId, options) {
|
|
1239
|
+
const tenant = options?.tenantId ?? this.tenantId;
|
|
1240
|
+
await this.http.post(
|
|
1241
|
+
`/api/v1/assertions/retract/${enc3(tenant)}/${enc3(ruleId)}`,
|
|
1242
|
+
{},
|
|
1243
|
+
tenant
|
|
1244
|
+
);
|
|
1245
|
+
}
|
|
1246
|
+
};
|
|
1247
|
+
function isRuleAssertion(assertion) {
|
|
1248
|
+
return assertion.predicate?.startsWith(RULE_PREDICATE_PREFIX) ?? false;
|
|
1249
|
+
}
|
|
1250
|
+
function parseRule(assertion) {
|
|
1251
|
+
const predicate = assertion.predicate;
|
|
1252
|
+
const type = predicate.replace(RULE_PREDICATE_PREFIX, "");
|
|
1253
|
+
let ruleValue;
|
|
1254
|
+
let severity;
|
|
1255
|
+
if (typeof assertion.value === "object" && assertion.value !== null) {
|
|
1256
|
+
const val = assertion.value;
|
|
1257
|
+
ruleValue = {
|
|
1258
|
+
description: String(val.description ?? ""),
|
|
1259
|
+
pattern: val.pattern != null ? String(val.pattern) : void 0,
|
|
1260
|
+
fileScope: val.fileScope != null ? String(val.fileScope) : void 0,
|
|
1261
|
+
propagatesTo: Array.isArray(val.propagatesTo) ? val.propagatesTo.map(String) : void 0
|
|
1262
|
+
};
|
|
1263
|
+
severity = val.severity ?? defaultSeverity(assertion.confidence);
|
|
1264
|
+
} else if (typeof assertion.value === "string") {
|
|
1265
|
+
try {
|
|
1266
|
+
const parsed = JSON.parse(assertion.value);
|
|
1267
|
+
ruleValue = {
|
|
1268
|
+
description: String(parsed.description ?? ""),
|
|
1269
|
+
pattern: parsed.pattern != null ? String(parsed.pattern) : void 0,
|
|
1270
|
+
fileScope: parsed.filePattern != null ? String(parsed.filePattern) : void 0,
|
|
1271
|
+
propagatesTo: Array.isArray(parsed.propagatesTo) ? parsed.propagatesTo.map(String) : void 0
|
|
1272
|
+
};
|
|
1273
|
+
severity = parsed.severity ?? defaultSeverity(assertion.confidence);
|
|
1274
|
+
} catch {
|
|
1275
|
+
ruleValue = { description: String(assertion.value) };
|
|
1276
|
+
severity = defaultSeverity(assertion.confidence);
|
|
1277
|
+
}
|
|
1278
|
+
} else {
|
|
1279
|
+
ruleValue = { description: "" };
|
|
1280
|
+
severity = defaultSeverity(assertion.confidence);
|
|
1281
|
+
}
|
|
1282
|
+
return {
|
|
1283
|
+
id: assertion.id,
|
|
1284
|
+
tenantId: assertion.tenantId,
|
|
1285
|
+
subject: assertion.subject,
|
|
1286
|
+
type,
|
|
1287
|
+
predicate,
|
|
1288
|
+
value: ruleValue,
|
|
1289
|
+
severity,
|
|
1290
|
+
confidence: assertion.confidence,
|
|
1291
|
+
validFrom: assertion.validFrom,
|
|
1292
|
+
isSuperseded: assertion.isSuperseded
|
|
1293
|
+
};
|
|
1294
|
+
}
|
|
1295
|
+
function enc3(s) {
|
|
1296
|
+
return encodeURIComponent(s);
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1063
1299
|
// src/client.ts
|
|
1064
1300
|
var AssertionsNamespace = class {
|
|
1065
1301
|
constructor(http, tenantId) {
|
|
@@ -1081,21 +1317,21 @@ var AssertionsNamespace = class {
|
|
|
1081
1317
|
async get(assertionId, options) {
|
|
1082
1318
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1083
1319
|
return this.http.get(
|
|
1084
|
-
`/api/v1/assertions/${
|
|
1320
|
+
`/api/v1/assertions/${enc4(tenantId)}/${enc4(assertionId)}`
|
|
1085
1321
|
);
|
|
1086
1322
|
}
|
|
1087
1323
|
/** Query assertions by subject. */
|
|
1088
1324
|
async query(subject2, options) {
|
|
1089
1325
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1090
1326
|
return this.http.get(
|
|
1091
|
-
`/api/v1/assertions/query/${
|
|
1327
|
+
`/api/v1/assertions/query/${enc4(tenantId)}/${enc4(subject2)}`
|
|
1092
1328
|
);
|
|
1093
1329
|
}
|
|
1094
1330
|
/** List all active assertions for the tenant. */
|
|
1095
1331
|
async list(options) {
|
|
1096
1332
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1097
1333
|
return this.http.get(
|
|
1098
|
-
`/api/v1/assertions/list/${
|
|
1334
|
+
`/api/v1/assertions/list/${enc4(tenantId)}`
|
|
1099
1335
|
);
|
|
1100
1336
|
}
|
|
1101
1337
|
/** Supersede an existing assertion with updated values. */
|
|
@@ -1114,7 +1350,7 @@ var AssertionsNamespace = class {
|
|
|
1114
1350
|
async retract(assertionId, options) {
|
|
1115
1351
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1116
1352
|
return this.http.post(
|
|
1117
|
-
`/api/v1/assertions/retract/${
|
|
1353
|
+
`/api/v1/assertions/retract/${enc4(tenantId)}/${enc4(assertionId)}`,
|
|
1118
1354
|
{}
|
|
1119
1355
|
);
|
|
1120
1356
|
}
|
|
@@ -1141,14 +1377,14 @@ var RelationshipsNamespace = class {
|
|
|
1141
1377
|
async query(subject2, options) {
|
|
1142
1378
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1143
1379
|
return this.http.get(
|
|
1144
|
-
`/api/v1/relationships/${
|
|
1380
|
+
`/api/v1/relationships/${enc4(tenantId)}/${enc4(subject2)}`
|
|
1145
1381
|
);
|
|
1146
1382
|
}
|
|
1147
1383
|
/** List all relationships for the tenant. */
|
|
1148
1384
|
async list(options) {
|
|
1149
1385
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1150
1386
|
return this.http.get(
|
|
1151
|
-
`/api/v1/relationships/list/${
|
|
1387
|
+
`/api/v1/relationships/list/${enc4(tenantId)}`
|
|
1152
1388
|
);
|
|
1153
1389
|
}
|
|
1154
1390
|
};
|
|
@@ -1175,14 +1411,14 @@ var AgentsNamespace = class {
|
|
|
1175
1411
|
async get(agentId, options) {
|
|
1176
1412
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1177
1413
|
return this.http.get(
|
|
1178
|
-
`/api/v1/agents/${
|
|
1414
|
+
`/api/v1/agents/${enc4(tenantId)}/${enc4(agentId)}`
|
|
1179
1415
|
);
|
|
1180
1416
|
}
|
|
1181
1417
|
/** Update an agent. */
|
|
1182
1418
|
async update(agentId, input, options) {
|
|
1183
1419
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1184
1420
|
return this.http.put(
|
|
1185
|
-
`/api/v1/agents/${
|
|
1421
|
+
`/api/v1/agents/${enc4(tenantId)}/${enc4(agentId)}`,
|
|
1186
1422
|
{
|
|
1187
1423
|
tenant_id: tenantId,
|
|
1188
1424
|
name: input.name,
|
|
@@ -1199,20 +1435,20 @@ var AgentsNamespace = class {
|
|
|
1199
1435
|
/** Delete an agent. */
|
|
1200
1436
|
async delete(agentId, options) {
|
|
1201
1437
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1202
|
-
await this.http.delete(`/api/v1/agents/${
|
|
1438
|
+
await this.http.delete(`/api/v1/agents/${enc4(tenantId)}/${enc4(agentId)}`);
|
|
1203
1439
|
}
|
|
1204
1440
|
/** List all agents for the tenant. */
|
|
1205
1441
|
async list(options) {
|
|
1206
1442
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1207
1443
|
return this.http.get(
|
|
1208
|
-
`/api/v1/agents/list/${
|
|
1444
|
+
`/api/v1/agents/list/${enc4(tenantId)}`
|
|
1209
1445
|
);
|
|
1210
1446
|
}
|
|
1211
1447
|
/** Get composed system instructions for an agent. */
|
|
1212
1448
|
async getInstructions(agentId, options) {
|
|
1213
1449
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1214
1450
|
return this.http.get(
|
|
1215
|
-
`/api/v1/agents/${
|
|
1451
|
+
`/api/v1/agents/${enc4(tenantId)}/${enc4(agentId)}/instructions`
|
|
1216
1452
|
);
|
|
1217
1453
|
}
|
|
1218
1454
|
};
|
|
@@ -1262,14 +1498,14 @@ var MemoryNamespace = class {
|
|
|
1262
1498
|
async recall(subject2, options) {
|
|
1263
1499
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1264
1500
|
return this.http.get(
|
|
1265
|
-
`/api/v1/assertions/query/${
|
|
1501
|
+
`/api/v1/assertions/query/${enc4(tenantId)}/${enc4(subject2)}`
|
|
1266
1502
|
);
|
|
1267
1503
|
}
|
|
1268
1504
|
/** Forget a specific memory (retract the assertion). */
|
|
1269
1505
|
async forget(assertionId, options) {
|
|
1270
1506
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1271
1507
|
return this.http.post(
|
|
1272
|
-
`/api/v1/assertions/retract/${
|
|
1508
|
+
`/api/v1/assertions/retract/${enc4(tenantId)}/${enc4(assertionId)}`,
|
|
1273
1509
|
{}
|
|
1274
1510
|
);
|
|
1275
1511
|
}
|
|
@@ -1301,7 +1537,7 @@ var IntakeNamespace = class {
|
|
|
1301
1537
|
}
|
|
1302
1538
|
/** Get pending intake results for an agent. */
|
|
1303
1539
|
async pending(agentId, options) {
|
|
1304
|
-
let path = `/api/v1/intake/pending/${
|
|
1540
|
+
let path = `/api/v1/intake/pending/${enc4(agentId)}`;
|
|
1305
1541
|
const params = [];
|
|
1306
1542
|
if (options?.status) params.push(`status=${options.status.join(",")}`);
|
|
1307
1543
|
if (options?.limit) params.push(`limit=${options.limit}`);
|
|
@@ -1310,18 +1546,18 @@ var IntakeNamespace = class {
|
|
|
1310
1546
|
}
|
|
1311
1547
|
/** Acknowledge an intake result (mark as consumed). */
|
|
1312
1548
|
async acknowledge(itemId) {
|
|
1313
|
-
await this.http.post(`/api/v1/intake/acknowledge/${
|
|
1549
|
+
await this.http.post(`/api/v1/intake/acknowledge/${enc4(itemId)}`, {});
|
|
1314
1550
|
}
|
|
1315
1551
|
/** Acknowledge all pending items for an agent. */
|
|
1316
1552
|
async acknowledgeAll(agentId) {
|
|
1317
1553
|
return this.http.post(
|
|
1318
|
-
`/api/v1/intake/acknowledge-all/${
|
|
1554
|
+
`/api/v1/intake/acknowledge-all/${enc4(agentId)}`,
|
|
1319
1555
|
{}
|
|
1320
1556
|
);
|
|
1321
1557
|
}
|
|
1322
1558
|
/** Get intake processing stats for an agent. */
|
|
1323
1559
|
async stats(agentId) {
|
|
1324
|
-
return this.http.get(`/api/v1/intake/stats/${
|
|
1560
|
+
return this.http.get(`/api/v1/intake/stats/${enc4(agentId)}`);
|
|
1325
1561
|
}
|
|
1326
1562
|
};
|
|
1327
1563
|
var ExperiencesNamespace = class {
|
|
@@ -1337,14 +1573,14 @@ var ExperiencesNamespace = class {
|
|
|
1337
1573
|
if (input?.limit) params.set("limit", String(input.limit));
|
|
1338
1574
|
const qs = params.toString();
|
|
1339
1575
|
return this.http.get(
|
|
1340
|
-
`/api/v1/experiences/${
|
|
1576
|
+
`/api/v1/experiences/${enc4(tenantId)}${qs ? `?${qs}` : ""}`
|
|
1341
1577
|
);
|
|
1342
1578
|
}
|
|
1343
1579
|
/** Get a single experience by ID. */
|
|
1344
1580
|
async get(experienceId, options) {
|
|
1345
1581
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1346
1582
|
return this.http.get(
|
|
1347
|
-
`/api/v1/experiences/${
|
|
1583
|
+
`/api/v1/experiences/${enc4(tenantId)}/${enc4(experienceId)}`
|
|
1348
1584
|
);
|
|
1349
1585
|
}
|
|
1350
1586
|
};
|
|
@@ -1359,7 +1595,7 @@ var RecallNamespace = class {
|
|
|
1359
1595
|
const params = new URLSearchParams({ q: input.query });
|
|
1360
1596
|
if (input.limit) params.set("limit", String(input.limit));
|
|
1361
1597
|
return this.http.get(
|
|
1362
|
-
`/api/v1/recall/${
|
|
1598
|
+
`/api/v1/recall/${enc4(tenantId)}?${params.toString()}`
|
|
1363
1599
|
);
|
|
1364
1600
|
}
|
|
1365
1601
|
};
|
|
@@ -1372,7 +1608,7 @@ var GraphNamespace = class {
|
|
|
1372
1608
|
async findPaths(input) {
|
|
1373
1609
|
const tenantId = input.tenantId || this.tenantId;
|
|
1374
1610
|
return this.http.post(
|
|
1375
|
-
`/api/v1/graph/${
|
|
1611
|
+
`/api/v1/graph/${enc4(tenantId)}/paths`,
|
|
1376
1612
|
{
|
|
1377
1613
|
from: input.from,
|
|
1378
1614
|
to: input.to,
|
|
@@ -1386,7 +1622,7 @@ var GraphNamespace = class {
|
|
|
1386
1622
|
async traverse(input) {
|
|
1387
1623
|
const tenantId = input.tenantId || this.tenantId;
|
|
1388
1624
|
return this.http.post(
|
|
1389
|
-
`/api/v1/graph/${
|
|
1625
|
+
`/api/v1/graph/${enc4(tenantId)}/traverse`,
|
|
1390
1626
|
{
|
|
1391
1627
|
start_subject: input.startSubject,
|
|
1392
1628
|
max_depth: input.maxDepth,
|
|
@@ -1407,7 +1643,7 @@ var TemporalNamespace = class {
|
|
|
1407
1643
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1408
1644
|
const pointStr = point instanceof Date ? point.toISOString() : point;
|
|
1409
1645
|
return this.http.get(
|
|
1410
|
-
`/api/v1/temporal/${
|
|
1646
|
+
`/api/v1/temporal/${enc4(tenantId)}/${enc4(subject2)}/at?point=${enc4(pointStr)}`
|
|
1411
1647
|
);
|
|
1412
1648
|
}
|
|
1413
1649
|
/** Get assertions within a date range. */
|
|
@@ -1416,7 +1652,7 @@ var TemporalNamespace = class {
|
|
|
1416
1652
|
const startStr = start instanceof Date ? start.toISOString() : start;
|
|
1417
1653
|
const endStr = end instanceof Date ? end.toISOString() : end;
|
|
1418
1654
|
return this.http.get(
|
|
1419
|
-
`/api/v1/temporal/${
|
|
1655
|
+
`/api/v1/temporal/${enc4(tenantId)}/${enc4(subject2)}/range?start=${enc4(startStr)}&end=${enc4(endStr)}`
|
|
1420
1656
|
);
|
|
1421
1657
|
}
|
|
1422
1658
|
};
|
|
@@ -1429,7 +1665,7 @@ var SearchNamespace = class {
|
|
|
1429
1665
|
async semantic(input) {
|
|
1430
1666
|
const tenantId = input.tenantId || this.tenantId;
|
|
1431
1667
|
return this.http.post(
|
|
1432
|
-
`/api/v1/search/${
|
|
1668
|
+
`/api/v1/search/${enc4(tenantId)}/semantic`,
|
|
1433
1669
|
{
|
|
1434
1670
|
embedding: input.embedding,
|
|
1435
1671
|
top_k: input.topK
|
|
@@ -1519,10 +1755,10 @@ var EntitiesNamespace = class {
|
|
|
1519
1755
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1520
1756
|
const subject2 = `entity:${entityName.toLowerCase().replace(/\s+/g, "-")}`;
|
|
1521
1757
|
const assertions = await this.http.get(
|
|
1522
|
-
`/api/v1/assertions/query/${
|
|
1758
|
+
`/api/v1/assertions/query/${enc4(tenantId)}/${enc4(subject2)}`
|
|
1523
1759
|
);
|
|
1524
1760
|
const relationships = await this.http.get(
|
|
1525
|
-
`/api/v1/relationships/query/${
|
|
1761
|
+
`/api/v1/relationships/query/${enc4(tenantId)}/${enc4(subject2)}`
|
|
1526
1762
|
);
|
|
1527
1763
|
const typeAssertion = assertions.find((a) => a.predicate === "type" && !a.isSuperseded);
|
|
1528
1764
|
const descAssertion = assertions.find((a) => a.predicate === "description" && !a.isSuperseded);
|
|
@@ -1530,7 +1766,7 @@ var EntitiesNamespace = class {
|
|
|
1530
1766
|
const properties = await Promise.all(
|
|
1531
1767
|
propertyRels.map(async (rel) => {
|
|
1532
1768
|
const propAssertions = await this.http.get(
|
|
1533
|
-
`/api/v1/assertions/query/${
|
|
1769
|
+
`/api/v1/assertions/query/${enc4(tenantId)}/${enc4(rel.toSubject)}`
|
|
1534
1770
|
);
|
|
1535
1771
|
const fieldType = propAssertions.find((a) => a.predicate === "field_type" && !a.isSuperseded);
|
|
1536
1772
|
const required = propAssertions.find((a) => a.predicate === "required" && !a.isSuperseded);
|
|
@@ -1560,7 +1796,7 @@ var EntitiesNamespace = class {
|
|
|
1560
1796
|
async list(options) {
|
|
1561
1797
|
const tenantId = options?.tenantId || this.tenantId;
|
|
1562
1798
|
const all = await this.http.get(
|
|
1563
|
-
`/api/v1/assertions/list/${
|
|
1799
|
+
`/api/v1/assertions/list/${enc4(tenantId)}`
|
|
1564
1800
|
);
|
|
1565
1801
|
return all.filter((a) => a.subject.startsWith("entity:") && a.predicate === "type" && !a.isSuperseded);
|
|
1566
1802
|
}
|
|
@@ -1592,6 +1828,8 @@ var SubCortexClient = class {
|
|
|
1592
1828
|
experiences;
|
|
1593
1829
|
/** Entity schema management — create, describe, and manage data models */
|
|
1594
1830
|
entities;
|
|
1831
|
+
/** Code guardrails — typed rules stored as assertions with file-scope matching */
|
|
1832
|
+
rules;
|
|
1595
1833
|
http;
|
|
1596
1834
|
constructor(options) {
|
|
1597
1835
|
if (!options.apiKey && !options.token) {
|
|
@@ -1621,13 +1859,14 @@ var SubCortexClient = class {
|
|
|
1621
1859
|
this.recall = new RecallNamespace(this.http, options.tenantId);
|
|
1622
1860
|
this.experiences = new ExperiencesNamespace(this.http, options.tenantId);
|
|
1623
1861
|
this.entities = new EntitiesNamespace(this.http, options.tenantId);
|
|
1862
|
+
this.rules = new RulesNamespace(this.http, options.tenantId);
|
|
1624
1863
|
}
|
|
1625
1864
|
/** Check SubCortex server health. */
|
|
1626
1865
|
async health() {
|
|
1627
1866
|
return this.http.get("/health");
|
|
1628
1867
|
}
|
|
1629
1868
|
};
|
|
1630
|
-
function
|
|
1869
|
+
function enc4(s) {
|
|
1631
1870
|
return encodeURIComponent(s);
|
|
1632
1871
|
}
|
|
1633
1872
|
|
|
@@ -1816,6 +2055,8 @@ export {
|
|
|
1816
2055
|
RecallNamespace,
|
|
1817
2056
|
RelationshipTypes,
|
|
1818
2057
|
RelationshipsNamespace,
|
|
2058
|
+
RulePredicates,
|
|
2059
|
+
RulesNamespace,
|
|
1819
2060
|
SIGNAL_DECAY_CONFIG,
|
|
1820
2061
|
SYSTEM_SIGNAL_TYPES,
|
|
1821
2062
|
SearchNamespace,
|