@subcortex-ai/sdk 0.1.3 → 0.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/dist/index.js CHANGED
@@ -905,49 +905,10 @@ ${connectedPeople.map((p) => {
905
905
  let assertionsCreated = 0;
906
906
  let relationshipsCreated = 0;
907
907
  const warnings = [];
908
- await this.http.post("/api/v1/assertions", {
909
- tenant_id: this.tenantId,
910
- subject: personSubject,
911
- predicate: "name",
912
- value: input.name,
913
- confidence: conf
914
- });
915
- assertionsCreated++;
908
+ const candidates = [];
909
+ candidates.push({ subject: personSubject, predicate: "name", value: input.name, source_confidence: conf, provenance: "agent" });
916
910
  if (input.role) {
917
- try {
918
- const existing = await this.http.get(
919
- `/api/v1/assertions/query/${enc2(this.tenantId)}/${enc2(personSubject)}`
920
- );
921
- const existingRole = existing.find((a) => a.predicate === "role" && !a.isSuperseded);
922
- if (existingRole && existingRole.value !== input.role) {
923
- warnings.push(`${input.name} was previously "${existingRole.value}" \u2014 now being set as "${input.role}". Role change or mistake?`);
924
- await this.http.post("/api/v1/assertions/supersede", {
925
- tenant_id: this.tenantId,
926
- original_assertion_id: existingRole.id,
927
- subject: personSubject,
928
- predicate: "role",
929
- value: input.role,
930
- confidence: conf
931
- });
932
- } else if (!existingRole) {
933
- await this.http.post("/api/v1/assertions", {
934
- tenant_id: this.tenantId,
935
- subject: personSubject,
936
- predicate: "role",
937
- value: input.role,
938
- confidence: conf
939
- });
940
- }
941
- } catch {
942
- await this.http.post("/api/v1/assertions", {
943
- tenant_id: this.tenantId,
944
- subject: personSubject,
945
- predicate: "role",
946
- value: input.role,
947
- confidence: conf
948
- });
949
- }
950
- assertionsCreated++;
911
+ candidates.push({ subject: personSubject, predicate: "role", value: input.role, source_confidence: conf, provenance: "agent" });
951
912
  try {
952
913
  const allAssertions = await this.http.get(
953
914
  `/api/v1/assertions/list/${enc2(this.tenantId)}`
@@ -964,6 +925,35 @@ ${connectedPeople.map((p) => {
964
925
  }
965
926
  } catch {
966
927
  }
928
+ }
929
+ if (input.details) {
930
+ candidates.push({ subject: personSubject, predicate: "details", value: input.details, source_confidence: conf, provenance: "agent" });
931
+ }
932
+ candidates.push({
933
+ subject: personSubject,
934
+ predicate: "status",
935
+ value: input.relationship === "candidate" ? "candidate" : "active",
936
+ source_confidence: conf,
937
+ provenance: "agent"
938
+ });
939
+ const correlationId = `register_person_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;
940
+ const intakeResult = await this.http.post("/api/v1/intake/submit", {
941
+ correlation_id: correlationId,
942
+ agent_id: "sdk",
943
+ tenant_id: this.tenantId,
944
+ candidates,
945
+ context: input.sessionId ? { sessionId: input.sessionId } : void 0
946
+ });
947
+ assertionsCreated = intakeResult.accepted + intakeResult.reinforced;
948
+ if (intakeResult.conflicts > 0) {
949
+ const conflictItems = (intakeResult.items || []).filter(
950
+ (i) => i.status === "conflict_detected"
951
+ );
952
+ for (const item of conflictItems) {
953
+ warnings.push(item.surfacingHint || "A conflict was detected with existing data.");
954
+ }
955
+ }
956
+ if (input.role) {
967
957
  const roleSubject = subject("role" /* ROLE */, input.role);
968
958
  await this.http.post("/api/v1/assertions", {
969
959
  tenant_id: this.tenantId,
@@ -979,34 +969,13 @@ ${connectedPeople.map((p) => {
979
969
  relationship_type: "holds_role" /* HOLDS_ROLE */,
980
970
  confidence: conf
981
971
  });
982
- assertionsCreated++;
983
972
  relationshipsCreated++;
984
973
  }
985
- if (input.details) {
986
- await this.http.post("/api/v1/assertions", {
987
- tenant_id: this.tenantId,
988
- subject: personSubject,
989
- predicate: "details",
990
- value: input.details,
991
- confidence: conf
992
- });
993
- assertionsCreated++;
994
- }
995
- await this.http.post("/api/v1/assertions", {
996
- tenant_id: this.tenantId,
997
- subject: personSubject,
998
- predicate: "status",
999
- value: input.relationship === "candidate" ? "candidate" : "active",
1000
- confidence: conf
1001
- });
1002
- assertionsCreated++;
1003
974
  const FORWARD_MAP = {
1004
975
  "direct_report": "manages" /* MANAGES */,
1005
976
  "team_member": "has_member" /* HAS_MEMBER */,
1006
977
  "candidate": "manages" /* MANAGES */,
1007
- // user manages the hiring
1008
978
  "manager": "reports_to" /* REPORTS_TO */,
1009
- // user reports to this person
1010
979
  "stakeholder": "stakeholder_in" /* STAKEHOLDER_IN */,
1011
980
  "collaborator": "collaborates_with" /* COLLABORATES_WITH */,
1012
981
  "mentor": "mentors" /* MENTORS */
@@ -1047,31 +1016,26 @@ ${connectedPeople.map((p) => {
1047
1016
  async recordRapport(input) {
1048
1017
  const userSubject = subject("user" /* USER */, input.userId);
1049
1018
  const conf = typeof input.confidence === "number" ? input.confidence : confidenceToScore(input.confidence || "high" /* HIGH */);
1050
- await this.http.post("/api/v1/assertions", {
1051
- tenant_id: this.tenantId,
1052
- subject: userSubject,
1053
- predicate: input.type,
1054
- value: input.value,
1055
- confidence: conf
1056
- });
1019
+ const candidates = [
1020
+ { subject: userSubject, predicate: input.type, value: input.value, source_confidence: conf, provenance: "agent" }
1021
+ ];
1057
1022
  if (input.aboutPerson) {
1058
1023
  const personSubject = subject("person" /* PERSON */, input.aboutPerson);
1059
- try {
1060
- const personAssertions = await this.http.get(
1061
- `/api/v1/assertions/query/${enc2(this.tenantId)}/${enc2(personSubject)}`
1062
- );
1063
- if (personAssertions.length > 0) {
1064
- await this.http.post("/api/v1/assertions", {
1065
- tenant_id: this.tenantId,
1066
- subject: personSubject,
1067
- predicate: "timeline",
1068
- value: input.value,
1069
- confidence: conf
1070
- });
1071
- }
1072
- } catch {
1073
- }
1024
+ candidates.push({
1025
+ subject: personSubject,
1026
+ predicate: "timeline",
1027
+ value: input.value,
1028
+ source_confidence: conf,
1029
+ provenance: "agent"
1030
+ });
1074
1031
  }
1032
+ const correlationId = `rapport_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;
1033
+ await this.http.post("/api/v1/intake/submit", {
1034
+ correlation_id: correlationId,
1035
+ agent_id: "sdk",
1036
+ tenant_id: this.tenantId,
1037
+ candidates
1038
+ });
1075
1039
  return { success: true };
1076
1040
  }
1077
1041
  /**
@@ -1360,11 +1324,247 @@ var IntakeNamespace = class {
1360
1324
  return this.http.get(`/api/v1/intake/stats/${enc3(agentId)}`);
1361
1325
  }
1362
1326
  };
1327
+ var ExperiencesNamespace = class {
1328
+ constructor(http, tenantId) {
1329
+ this.http = http;
1330
+ this.tenantId = tenantId;
1331
+ }
1332
+ /** List experiences, optionally filtered by subject. */
1333
+ async list(input) {
1334
+ const tenantId = input?.tenantId || this.tenantId;
1335
+ const params = new URLSearchParams();
1336
+ if (input?.subject) params.set("subject", input.subject);
1337
+ if (input?.limit) params.set("limit", String(input.limit));
1338
+ const qs = params.toString();
1339
+ return this.http.get(
1340
+ `/api/v1/experiences/${enc3(tenantId)}${qs ? `?${qs}` : ""}`
1341
+ );
1342
+ }
1343
+ /** Get a single experience by ID. */
1344
+ async get(experienceId, options) {
1345
+ const tenantId = options?.tenantId || this.tenantId;
1346
+ return this.http.get(
1347
+ `/api/v1/experiences/${enc3(tenantId)}/${enc3(experienceId)}`
1348
+ );
1349
+ }
1350
+ };
1351
+ var RecallNamespace = class {
1352
+ constructor(http, tenantId) {
1353
+ this.http = http;
1354
+ this.tenantId = tenantId;
1355
+ }
1356
+ /** BM25 full-text search across assertions. */
1357
+ async search(input) {
1358
+ const tenantId = input.tenantId || this.tenantId;
1359
+ const params = new URLSearchParams({ q: input.query });
1360
+ if (input.limit) params.set("limit", String(input.limit));
1361
+ return this.http.get(
1362
+ `/api/v1/recall/${enc3(tenantId)}?${params.toString()}`
1363
+ );
1364
+ }
1365
+ };
1366
+ var GraphNamespace = class {
1367
+ constructor(http, tenantId) {
1368
+ this.http = http;
1369
+ this.tenantId = tenantId;
1370
+ }
1371
+ /** Find paths between two subjects. */
1372
+ async findPaths(input) {
1373
+ const tenantId = input.tenantId || this.tenantId;
1374
+ return this.http.post(
1375
+ `/api/v1/graph/${enc3(tenantId)}/paths`,
1376
+ {
1377
+ from: input.from,
1378
+ to: input.to,
1379
+ max_depth: input.maxDepth,
1380
+ min_confidence: input.minConfidence,
1381
+ strategy: input.strategy
1382
+ }
1383
+ );
1384
+ }
1385
+ /** BFS traversal from a starting subject. */
1386
+ async traverse(input) {
1387
+ const tenantId = input.tenantId || this.tenantId;
1388
+ return this.http.post(
1389
+ `/api/v1/graph/${enc3(tenantId)}/traverse`,
1390
+ {
1391
+ start_subject: input.startSubject,
1392
+ max_depth: input.maxDepth,
1393
+ relationship_types: input.relationshipTypes,
1394
+ min_confidence: input.minConfidence,
1395
+ max_nodes: input.maxNodes
1396
+ }
1397
+ );
1398
+ }
1399
+ };
1400
+ var TemporalNamespace = class {
1401
+ constructor(http, tenantId) {
1402
+ this.http = http;
1403
+ this.tenantId = tenantId;
1404
+ }
1405
+ /** Get assertions valid at a specific point in time. */
1406
+ async at(subject2, point, options) {
1407
+ const tenantId = options?.tenantId || this.tenantId;
1408
+ const pointStr = point instanceof Date ? point.toISOString() : point;
1409
+ return this.http.get(
1410
+ `/api/v1/temporal/${enc3(tenantId)}/${enc3(subject2)}/at?point=${enc3(pointStr)}`
1411
+ );
1412
+ }
1413
+ /** Get assertions within a date range. */
1414
+ async range(subject2, start, end, options) {
1415
+ const tenantId = options?.tenantId || this.tenantId;
1416
+ const startStr = start instanceof Date ? start.toISOString() : start;
1417
+ const endStr = end instanceof Date ? end.toISOString() : end;
1418
+ return this.http.get(
1419
+ `/api/v1/temporal/${enc3(tenantId)}/${enc3(subject2)}/range?start=${enc3(startStr)}&end=${enc3(endStr)}`
1420
+ );
1421
+ }
1422
+ };
1423
+ var SearchNamespace = class {
1424
+ constructor(http, tenantId) {
1425
+ this.http = http;
1426
+ this.tenantId = tenantId;
1427
+ }
1428
+ /** Semantic nearest-neighbor search over assertion embeddings. */
1429
+ async semantic(input) {
1430
+ const tenantId = input.tenantId || this.tenantId;
1431
+ return this.http.post(
1432
+ `/api/v1/search/${enc3(tenantId)}/semantic`,
1433
+ {
1434
+ embedding: input.embedding,
1435
+ top_k: input.topK
1436
+ }
1437
+ );
1438
+ }
1439
+ };
1363
1440
  var DEFAULT_RETRY = {
1364
1441
  maxRetries: 3,
1365
1442
  baseDelayMs: 500,
1366
1443
  maxDelayMs: 1e4
1367
1444
  };
1445
+ var EntitiesNamespace = class {
1446
+ constructor(http, tenantId) {
1447
+ this.http = http;
1448
+ this.tenantId = tenantId;
1449
+ }
1450
+ /** Create an entity with optional description and type. */
1451
+ async create(input) {
1452
+ const tenantId = input.tenantId || this.tenantId;
1453
+ const subject2 = `entity:${input.name.toLowerCase().replace(/\s+/g, "-")}`;
1454
+ const typeAssertion = await this.http.post(
1455
+ `/api/v1/assertions`,
1456
+ {
1457
+ tenant_id: tenantId,
1458
+ subject: subject2,
1459
+ predicate: "type",
1460
+ value: input.type || "model",
1461
+ confidence: 1
1462
+ }
1463
+ );
1464
+ if (input.description) {
1465
+ await this.http.post(
1466
+ `/api/v1/assertions`,
1467
+ {
1468
+ tenant_id: tenantId,
1469
+ subject: subject2,
1470
+ predicate: "description",
1471
+ value: input.description,
1472
+ confidence: 1
1473
+ }
1474
+ );
1475
+ }
1476
+ return typeAssertion;
1477
+ }
1478
+ /** Add a property to an entity. */
1479
+ async addProperty(input) {
1480
+ const tenantId = input.tenantId || this.tenantId;
1481
+ const entitySubject = `entity:${input.entityName.toLowerCase().replace(/\s+/g, "-")}`;
1482
+ const propertySubject = `property:${input.entityName.toLowerCase().replace(/\s+/g, "-")}.${input.name.toLowerCase().replace(/\s+/g, "-")}`;
1483
+ const assertion = await this.http.post(
1484
+ `/api/v1/assertions`,
1485
+ {
1486
+ tenant_id: tenantId,
1487
+ subject: propertySubject,
1488
+ predicate: "field_type",
1489
+ value: input.fieldType,
1490
+ confidence: 1
1491
+ }
1492
+ );
1493
+ const relationship = await this.http.post(
1494
+ `/api/v1/relationships`,
1495
+ {
1496
+ tenant_id: tenantId,
1497
+ from_subject: entitySubject,
1498
+ to_subject: propertySubject,
1499
+ relationship_type: "has_property",
1500
+ confidence: 1
1501
+ }
1502
+ );
1503
+ if (input.required) {
1504
+ await this.http.post(
1505
+ `/api/v1/assertions`,
1506
+ {
1507
+ tenant_id: tenantId,
1508
+ subject: propertySubject,
1509
+ predicate: "required",
1510
+ value: true,
1511
+ confidence: 1
1512
+ }
1513
+ );
1514
+ }
1515
+ return { assertion, relationship };
1516
+ }
1517
+ /** Describe an entity by reconstructing its properties and relationships from assertions. */
1518
+ async describe(entityName, options) {
1519
+ const tenantId = options?.tenantId || this.tenantId;
1520
+ const subject2 = `entity:${entityName.toLowerCase().replace(/\s+/g, "-")}`;
1521
+ const assertions = await this.http.get(
1522
+ `/api/v1/assertions/query/${enc3(tenantId)}/${enc3(subject2)}`
1523
+ );
1524
+ const relationships = await this.http.get(
1525
+ `/api/v1/relationships/query/${enc3(tenantId)}/${enc3(subject2)}`
1526
+ );
1527
+ const typeAssertion = assertions.find((a) => a.predicate === "type" && !a.isSuperseded);
1528
+ const descAssertion = assertions.find((a) => a.predicate === "description" && !a.isSuperseded);
1529
+ const propertyRels = relationships.filter((r) => r.relationshipType === "has_property");
1530
+ const properties = await Promise.all(
1531
+ propertyRels.map(async (rel) => {
1532
+ const propAssertions = await this.http.get(
1533
+ `/api/v1/assertions/query/${enc3(tenantId)}/${enc3(rel.toSubject)}`
1534
+ );
1535
+ const fieldType = propAssertions.find((a) => a.predicate === "field_type" && !a.isSuperseded);
1536
+ const required = propAssertions.find((a) => a.predicate === "required" && !a.isSuperseded);
1537
+ const name = rel.toSubject.replace(/^property:[^.]+\./, "");
1538
+ return {
1539
+ name,
1540
+ fieldType: fieldType ? String(fieldType.value) : null,
1541
+ required: required ? Boolean(required.value) : false
1542
+ };
1543
+ })
1544
+ );
1545
+ const otherRels = relationships.filter((r) => r.relationshipType !== "has_property").map((r) => ({
1546
+ type: r.relationshipType,
1547
+ target: r.toSubject,
1548
+ confidence: r.confidence
1549
+ }));
1550
+ return {
1551
+ subject: subject2,
1552
+ name: entityName,
1553
+ type: typeAssertion ? String(typeAssertion.value) : null,
1554
+ description: descAssertion ? String(descAssertion.value) : null,
1555
+ properties,
1556
+ relationships: otherRels
1557
+ };
1558
+ }
1559
+ /** List all entities for a tenant (subjects with entity: prefix that have a type predicate). */
1560
+ async list(options) {
1561
+ const tenantId = options?.tenantId || this.tenantId;
1562
+ const all = await this.http.get(
1563
+ `/api/v1/assertions/list/${enc3(tenantId)}`
1564
+ );
1565
+ return all.filter((a) => a.subject.startsWith("entity:") && a.predicate === "type" && !a.isSuperseded);
1566
+ }
1567
+ };
1368
1568
  var SubCortexClient = class {
1369
1569
  /** Assertion operations (low-level knowledge primitives) */
1370
1570
  assertions;
@@ -1380,6 +1580,18 @@ var SubCortexClient = class {
1380
1580
  users;
1381
1581
  /** Emotional signals — record, query, and resolve */
1382
1582
  signals;
1583
+ /** Graph queries — pathfinding and traversal */
1584
+ graph;
1585
+ /** Temporal queries — point-in-time snapshots and range queries */
1586
+ temporal;
1587
+ /** Semantic search over assertion embeddings */
1588
+ search;
1589
+ /** BM25 full-text recall search */
1590
+ recall;
1591
+ /** Episodic memory — experiences grouped by session */
1592
+ experiences;
1593
+ /** Entity schema management — create, describe, and manage data models */
1594
+ entities;
1383
1595
  http;
1384
1596
  constructor(options) {
1385
1597
  if (!options.apiKey && !options.token) {
@@ -1403,6 +1615,12 @@ var SubCortexClient = class {
1403
1615
  this.intake = new IntakeNamespace(this.http, options.tenantId);
1404
1616
  this.users = new UsersNamespace(this.http, options.tenantId);
1405
1617
  this.signals = new SignalsNamespace(this.http, options.tenantId);
1618
+ this.graph = new GraphNamespace(this.http, options.tenantId);
1619
+ this.temporal = new TemporalNamespace(this.http, options.tenantId);
1620
+ this.search = new SearchNamespace(this.http, options.tenantId);
1621
+ this.recall = new RecallNamespace(this.http, options.tenantId);
1622
+ this.experiences = new ExperiencesNamespace(this.http, options.tenantId);
1623
+ this.entities = new EntitiesNamespace(this.http, options.tenantId);
1406
1624
  }
1407
1625
  /** Check SubCortex server health. */
1408
1626
  async health() {
@@ -1577,9 +1795,12 @@ export {
1577
1795
  CONTEXT_SCHEMA_VERSION,
1578
1796
  ConfidenceLevel,
1579
1797
  ConfidenceScores,
1798
+ EntitiesNamespace,
1580
1799
  EntityPredicate,
1581
1800
  EntityRelationship,
1582
1801
  EventPredicate,
1802
+ ExperiencesNamespace,
1803
+ GraphNamespace,
1583
1804
  IdentityPredicate,
1584
1805
  IntakeNamespace,
1585
1806
  MULTI_VALUE_PREDICATES,
@@ -1592,10 +1813,12 @@ export {
1592
1813
  RELATIONSHIP_LABELS,
1593
1814
  REVERSE_RELATIONSHIPS,
1594
1815
  RapportPredicate,
1816
+ RecallNamespace,
1595
1817
  RelationshipTypes,
1596
1818
  RelationshipsNamespace,
1597
1819
  SIGNAL_DECAY_CONFIG,
1598
1820
  SYSTEM_SIGNAL_TYPES,
1821
+ SearchNamespace,
1599
1822
  SignalsNamespace,
1600
1823
  SubCortexAuthenticationError,
1601
1824
  SubCortexAuthorizationError,
@@ -1609,6 +1832,7 @@ export {
1609
1832
  SubCortexTimeoutError,
1610
1833
  SubCortexValidationError,
1611
1834
  SubjectPrefix,
1835
+ TemporalNamespace,
1612
1836
  UsersNamespace,
1613
1837
  WorkPredicate,
1614
1838
  confidenceToScore,