@subcortex-ai/sdk 0.3.7 → 0.3.9

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 CHANGED
@@ -242,6 +242,27 @@ const subcortex = new SubCortexClient({
242
242
  })
243
243
  ```
244
244
 
245
+ ## Framework Integration
246
+
247
+ ### Next.js (App Router)
248
+
249
+ Next.js patches `globalThis.fetch` with aggressive caching. GET requests — including assertion queries, user identification, and signal snapshots — will return stale data unless you bypass the cache. **This is critical for cognitive data that changes between sessions.**
250
+
251
+ ```typescript
252
+ // app/api/my-agent/route.ts
253
+ const noCacheFetch: typeof fetch = (input, init) =>
254
+ fetch(input, { ...init, cache: 'no-store' })
255
+
256
+ const subcortex = new SubCortexClient({
257
+ endpoint: process.env.SUBCORTEX_ENDPOINT!,
258
+ tenantId: process.env.SUBCORTEX_TENANT_ID!,
259
+ apiKey: process.env.SUBCORTEX_API_KEY,
260
+ fetch: noCacheFetch, // ← Required in Next.js
261
+ })
262
+ ```
263
+
264
+ Without this, `users.identify()`, `assertions.query()`, and `signals.query()` may return cached results — meaning new assertions added between sessions (by other agents, users, or the SubCortex console) will be invisible until a hard page refresh.
265
+
245
266
  ## What is SubCortex?
246
267
 
247
268
  SubCortex is a purpose-built cognitive engine for AI agents — persistent memory, identity, emotional signals, and knowledge graph in one system.
package/dist/index.cjs CHANGED
@@ -1114,7 +1114,7 @@ ${connectedPeople.map((p) => {
1114
1114
  agent_id: "sdk",
1115
1115
  tenant_id: this.tenantId,
1116
1116
  candidates,
1117
- ...input.sessionId ? { context: { sessionId: input.sessionId } } : {}
1117
+ ...input.sessionId ? { context: { session_id: input.sessionId } } : {}
1118
1118
  });
1119
1119
  return { success: true };
1120
1120
  }
@@ -1614,7 +1614,12 @@ var IntakeNamespace = class {
1614
1614
  provenance: c.provenance,
1615
1615
  person_name: c.personName
1616
1616
  })),
1617
- context: input.context
1617
+ context: input.context ? {
1618
+ topic: input.context.topic,
1619
+ emotional_state: input.context.emotionalState,
1620
+ session_id: input.context.sessionId,
1621
+ excerpt: input.context.excerpt
1622
+ } : void 0
1618
1623
  });
1619
1624
  }
1620
1625
  /** Get pending intake results for an agent. */
@@ -2053,16 +2058,25 @@ function toContextXml(user, options = {}) {
2053
2058
  if (knowledge.length > 0) {
2054
2059
  lines.push(` <knowledge count="${knowledge.length}">`);
2055
2060
  for (const mem of knowledge) {
2061
+ if (mem.predicate.startsWith("signal:")) {
2062
+ const sigType = mem.predicate.slice(7);
2063
+ const val = mem.value;
2064
+ const content = typeof val === "object" && val?.content ? String(val.content) : formatValue(mem.value);
2065
+ const intensity = typeof val === "object" && val?.intensity ? Number(val.intensity) : mem.confidence;
2066
+ const about = typeof val === "object" && val?.aboutSubject ? ` about="${esc(String(val.aboutSubject))}"` : "";
2067
+ lines.push(` <signal type="${esc(sigType)}" intensity="${fmtConf(intensity)}"${about}>${esc(content)}</signal>`);
2068
+ continue;
2069
+ }
2056
2070
  const memSignals = findSignalsForFact(mem, signalsByAbout);
2057
2071
  if (memSignals.length > 0) {
2058
2072
  lines.push(` <fact predicate="${esc(mem.predicate)}" confidence="${fmtConf(mem.confidence)}">`);
2059
- lines.push(` ${esc(String(mem.value))}`);
2073
+ lines.push(` ${esc(formatValue(mem.value))}`);
2060
2074
  for (const sig of memSignals) {
2061
2075
  lines.push(` ${renderSignal(sig)}`);
2062
2076
  }
2063
2077
  lines.push(` </fact>`);
2064
2078
  } else {
2065
- lines.push(` <fact predicate="${esc(mem.predicate)}" confidence="${fmtConf(mem.confidence)}">${esc(String(mem.value))}</fact>`);
2079
+ lines.push(` <fact predicate="${esc(mem.predicate)}" confidence="${fmtConf(mem.confidence)}">${esc(formatValue(mem.value))}</fact>`);
2066
2080
  }
2067
2081
  }
2068
2082
  lines.push(` </knowledge>`);
@@ -2104,6 +2118,12 @@ function findSignalsForFact(fact, signalsByAbout) {
2104
2118
  }
2105
2119
  return results;
2106
2120
  }
2121
+ function formatValue(v) {
2122
+ if (v === null || v === void 0) return "";
2123
+ if (typeof v === "string") return v;
2124
+ if (typeof v === "object" && "content" in v) return String(v.content);
2125
+ return JSON.stringify(v);
2126
+ }
2107
2127
  function fmtConf(n) {
2108
2128
  return n.toFixed(2);
2109
2129
  }