@remnic/core 9.3.597 → 9.3.598

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.
Files changed (91) hide show
  1. package/dist/access-cli.js +17 -17
  2. package/dist/access-http.js +6 -6
  3. package/dist/access-mcp.js +5 -5
  4. package/dist/access-service.js +4 -4
  5. package/dist/behavior-learner.js +2 -1
  6. package/dist/behavior-learner.js.map +1 -1
  7. package/dist/causal-behavior.js +3 -3
  8. package/dist/causal-chain.js +3 -3
  9. package/dist/causal-consolidation.js +4 -4
  10. package/dist/causal-retrieval.js +3 -3
  11. package/dist/causal-trajectory.js +2 -2
  12. package/dist/{chunk-A2Z6UCWT.js → chunk-33JBK2XP.js} +2 -2
  13. package/dist/{chunk-D2MMMTDV.js → chunk-5SQ5CQJP.js} +2 -2
  14. package/dist/{chunk-F4LM4ULA.js → chunk-65JSA4MP.js} +12 -12
  15. package/dist/{chunk-SKGV326D.js → chunk-6GDHLVJC.js} +2 -2
  16. package/dist/chunk-6HEM6HTQ.js +359 -0
  17. package/dist/chunk-6HEM6HTQ.js.map +1 -0
  18. package/dist/{chunk-WXACKLKP.js → chunk-75O6YQ63.js} +22 -7
  19. package/dist/chunk-75O6YQ63.js.map +1 -0
  20. package/dist/{chunk-D65TSG24.js → chunk-7DZRO2DC.js} +2 -2
  21. package/dist/{chunk-TYICDVQW.js → chunk-BDCCWRHR.js} +4 -4
  22. package/dist/{chunk-LYPDMKUT.js → chunk-CL3MWNNQ.js} +2 -2
  23. package/dist/{chunk-YQMZ7IH2.js → chunk-D4KJ74JJ.js} +65 -27
  24. package/dist/chunk-D4KJ74JJ.js.map +1 -0
  25. package/dist/{chunk-W5O2FQTZ.js → chunk-GUPISBV2.js} +2 -2
  26. package/dist/{chunk-472U7RDF.js → chunk-JGSKJHF7.js} +2 -2
  27. package/dist/{chunk-IEFHBIU2.js → chunk-KDUVQU6Y.js} +14 -14
  28. package/dist/{chunk-6HZ6AO2P.js → chunk-LBJBNWS2.js} +37 -10
  29. package/dist/chunk-LBJBNWS2.js.map +1 -0
  30. package/dist/{chunk-Z4R6RI2N.js → chunk-NSKYFGDL.js} +2 -2
  31. package/dist/{chunk-OD5LFAPZ.js → chunk-V67GWXM2.js} +1 -1
  32. package/dist/{chunk-5NXIJZFX.js → chunk-WR64DQFE.js} +3 -3
  33. package/dist/{chunk-5BUGGPBR.js → chunk-WZA5Y6AC.js} +3 -3
  34. package/dist/chunk-ZBJMUXZH.js +121 -0
  35. package/dist/chunk-ZBJMUXZH.js.map +1 -0
  36. package/dist/{chunk-XPXEJRUB.js → chunk-ZRWB5D4H.js} +2 -2
  37. package/dist/{chunk-MA5MWGKP.js → chunk-ZT3EGNLR.js} +2 -2
  38. package/dist/{chunk-LMPHTYJC.js → chunk-ZZYF3BUL.js} +2 -2
  39. package/dist/cli.js +14 -14
  40. package/dist/compounding/engine.js +1 -1
  41. package/dist/direct-answer-wiring.js +3 -3
  42. package/dist/direct-answer.d.ts +1 -1
  43. package/dist/direct-answer.js +2 -2
  44. package/dist/harmonic-retrieval.js +2 -2
  45. package/dist/index.js +21 -21
  46. package/dist/orchestrator.js +16 -16
  47. package/dist/policy-runtime.js +3 -2
  48. package/dist/recall-query-policy.js +2 -1
  49. package/dist/recall-tokenization.d.ts +5 -1
  50. package/dist/recall-tokenization.js +3 -1
  51. package/dist/resume-bundles.js +3 -3
  52. package/dist/retrieval-agents.js +2 -2
  53. package/dist/schemas.d.ts +22 -22
  54. package/dist/semantic-consolidation.js +2 -2
  55. package/dist/semantic-rule-verifier.js +2 -2
  56. package/dist/temporal-index.js +1 -1
  57. package/dist/transfer/types.d.ts +12 -12
  58. package/dist/trust-zones.js +2 -2
  59. package/dist/verified-recall.js +2 -2
  60. package/dist/work-product-ledger.js +2 -2
  61. package/package.json +1 -1
  62. package/src/causal-chain.ts +80 -42
  63. package/src/direct-answer.test.ts +618 -15
  64. package/src/direct-answer.ts +259 -20
  65. package/src/recall-query-policy.ts +49 -27
  66. package/src/recall-tokenization.ts +131 -21
  67. package/src/temporal-index.ts +23 -6
  68. package/dist/chunk-6HZ6AO2P.js.map +0 -1
  69. package/dist/chunk-DT5TVLJE.js +0 -32
  70. package/dist/chunk-DT5TVLJE.js.map +0 -1
  71. package/dist/chunk-WXACKLKP.js.map +0 -1
  72. package/dist/chunk-Y4FHOFJ2.js +0 -140
  73. package/dist/chunk-Y4FHOFJ2.js.map +0 -1
  74. package/dist/chunk-YQMZ7IH2.js.map +0 -1
  75. /package/dist/{chunk-A2Z6UCWT.js.map → chunk-33JBK2XP.js.map} +0 -0
  76. /package/dist/{chunk-D2MMMTDV.js.map → chunk-5SQ5CQJP.js.map} +0 -0
  77. /package/dist/{chunk-F4LM4ULA.js.map → chunk-65JSA4MP.js.map} +0 -0
  78. /package/dist/{chunk-SKGV326D.js.map → chunk-6GDHLVJC.js.map} +0 -0
  79. /package/dist/{chunk-D65TSG24.js.map → chunk-7DZRO2DC.js.map} +0 -0
  80. /package/dist/{chunk-TYICDVQW.js.map → chunk-BDCCWRHR.js.map} +0 -0
  81. /package/dist/{chunk-LYPDMKUT.js.map → chunk-CL3MWNNQ.js.map} +0 -0
  82. /package/dist/{chunk-W5O2FQTZ.js.map → chunk-GUPISBV2.js.map} +0 -0
  83. /package/dist/{chunk-472U7RDF.js.map → chunk-JGSKJHF7.js.map} +0 -0
  84. /package/dist/{chunk-IEFHBIU2.js.map → chunk-KDUVQU6Y.js.map} +0 -0
  85. /package/dist/{chunk-Z4R6RI2N.js.map → chunk-NSKYFGDL.js.map} +0 -0
  86. /package/dist/{chunk-OD5LFAPZ.js.map → chunk-V67GWXM2.js.map} +0 -0
  87. /package/dist/{chunk-5NXIJZFX.js.map → chunk-WR64DQFE.js.map} +0 -0
  88. /package/dist/{chunk-5BUGGPBR.js.map → chunk-WZA5Y6AC.js.map} +0 -0
  89. /package/dist/{chunk-XPXEJRUB.js.map → chunk-ZRWB5D4H.js.map} +0 -0
  90. /package/dist/{chunk-MA5MWGKP.js.map → chunk-ZT3EGNLR.js.map} +0 -0
  91. /package/dist/{chunk-LMPHTYJC.js.map → chunk-ZZYF3BUL.js.map} +0 -0
@@ -6,20 +6,15 @@
6
6
  * another session. Persists edges in a graph index for later retrieval.
7
7
  */
8
8
 
9
- import path from "node:path";
10
- import { mkdir, readFile, writeFile } from "node:fs/promises";
11
9
  import { createHash } from "node:crypto";
12
- import { listJsonFiles, readJsonFile } from "./json-store.js";
13
- import { resolveCausalTrajectoryStoreDir, type CausalTrajectoryRecord } from "./causal-trajectory.js";
10
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
11
+ import path from "node:path";
14
12
  import { topicOverlapScore } from "./boxes.js";
15
- import { countRecallTokenOverlap, normalizeRecallTokens } from "./recall-tokenization.js";
16
- import {
17
- assertIsoRecordedAt,
18
- assertString,
19
- isRecord,
20
- recordStoreDay,
21
- } from "./store-contract.js";
13
+ import { type CausalTrajectoryRecord, resolveCausalTrajectoryStoreDir } from "./causal-trajectory.js";
14
+ import { listJsonFiles, readJsonFile } from "./json-store.js";
22
15
  import { log } from "./logger.js";
16
+ import { normalizeRecallTokens } from "./recall-tokenization.js";
17
+ import { assertIsoRecordedAt, assertString, isRecord, recordStoreDay } from "./store-contract.js";
23
18
 
24
19
  // ─── Types ───────────────────────────────────────────────────────────────────
25
20
 
@@ -65,6 +60,59 @@ const STITCH_WEIGHTS = {
65
60
  temporalProximity: 1.0,
66
61
  } as const;
67
62
 
63
+ function hasUnsegmentableRecallChar(token: string): boolean {
64
+ if (token.includes("ー") || token.includes("ー")) return true;
65
+ return /[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}]/u.test(token);
66
+ }
67
+
68
+ function extractUnsegmentableStitchPhrases(value: string): string[] {
69
+ const phrases = new Set<string>();
70
+ let segment = "";
71
+
72
+ const flushSegment = () => {
73
+ if ([...segment].length >= 4) {
74
+ phrases.add(segment);
75
+ }
76
+ segment = "";
77
+ };
78
+
79
+ for (const ch of value.toLowerCase().normalize("NFC")) {
80
+ if (hasUnsegmentableRecallChar(ch)) {
81
+ segment += ch;
82
+ continue;
83
+ }
84
+ if (/\p{M}/u.test(ch) && segment.length > 0) {
85
+ segment += ch;
86
+ continue;
87
+ }
88
+ if (/\s/u.test(ch) && segment.length > 0) {
89
+ continue;
90
+ }
91
+ flushSegment();
92
+ }
93
+ flushSegment();
94
+
95
+ return [...phrases];
96
+ }
97
+
98
+ function normalizeStitchLexicalTokens(value: string, extraStopWords: string[] = []): string[] {
99
+ const tokens = new Set(
100
+ normalizeRecallTokens(value, extraStopWords).filter((token) => !hasUnsegmentableRecallChar(token))
101
+ );
102
+ for (const phrase of extractUnsegmentableStitchPhrases(value)) {
103
+ tokens.add(phrase);
104
+ }
105
+ return [...tokens];
106
+ }
107
+
108
+ function countTokenSetOverlap(queryTokens: Set<string>, valueTokens: Set<string>): number {
109
+ let matches = 0;
110
+ for (const token of queryTokens) {
111
+ if (valueTokens.has(token)) matches += 1;
112
+ }
113
+ return matches;
114
+ }
115
+
68
116
  // ─── Validation ──────────────────────────────────────────────────────────────
69
117
 
70
118
  export function validateCausalEdge(raw: unknown): CausalEdge {
@@ -97,9 +145,7 @@ export function validateCausalEdge(raw: unknown): CausalEdge {
97
145
  createdAt: assertIsoRecordedAt(assertString(raw.createdAt, "createdAt")),
98
146
  metadata: isRecord(raw.metadata)
99
147
  ? Object.fromEntries(
100
- Object.entries(raw.metadata).filter(
101
- (entry): entry is [string, string] => typeof entry[1] === "string",
102
- ),
148
+ Object.entries(raw.metadata).filter((entry): entry is [string, string] => typeof entry[1] === "string")
103
149
  )
104
150
  : undefined,
105
151
  };
@@ -108,10 +154,7 @@ export function validateCausalEdge(raw: unknown): CausalEdge {
108
154
  // ─── Stable Edge ID ──────────────────────────────────────────────────────────
109
155
 
110
156
  export function makeEdgeId(fromId: string, toId: string): string {
111
- const digest = createHash("sha256")
112
- .update(`${fromId}\0${toId}`)
113
- .digest("hex")
114
- .slice(0, 12);
157
+ const digest = createHash("sha256").update(`${fromId}\0${toId}`).digest("hex").slice(0, 12);
115
158
  return `edge-${digest}`;
116
159
  }
117
160
 
@@ -153,9 +196,9 @@ export async function readChainIndex(chainsDir: string): Promise<CausalChainInde
153
196
  try {
154
197
  const raw = JSON.parse(await readFile(chainIndexPath(chainsDir), "utf8"));
155
198
  return {
156
- outgoing: isRecord(raw.outgoing) ? raw.outgoing as Record<string, string[]> : {},
157
- incoming: isRecord(raw.incoming) ? raw.incoming as Record<string, string[]> : {},
158
- edges: isRecord(raw.edges) ? raw.edges as Record<string, CausalEdge> : {},
199
+ outgoing: isRecord(raw.outgoing) ? (raw.outgoing as Record<string, string[]>) : {},
200
+ incoming: isRecord(raw.incoming) ? (raw.incoming as Record<string, string[]>) : {},
201
+ edges: isRecord(raw.edges) ? (raw.edges as Record<string, CausalEdge>) : {},
159
202
  updatedAt: typeof raw.updatedAt === "string" ? raw.updatedAt : new Date().toISOString(),
160
203
  };
161
204
  } catch {
@@ -202,19 +245,18 @@ function addEdgeToIndex(index: CausalChainIndex, edge: CausalEdge): void {
202
245
  */
203
246
  export function scoreStitchCandidate(
204
247
  newTrajectory: CausalTrajectoryRecord,
205
- candidate: CausalTrajectoryRecord,
248
+ candidate: CausalTrajectoryRecord
206
249
  ): StitchCandidate {
207
250
  let score = 0;
208
251
  let dominantMethod: CausalEdge["stitchMethod"] = "lexical";
209
252
  let maxComponent = 0;
210
253
 
211
254
  // 1. Follow-up → Goal match (token overlap)
212
- const newFollowUpTokens = new Set(
213
- normalizeRecallTokens(newTrajectory.followUpSummary ?? "", []),
214
- );
215
- const candidateGoalTokens = normalizeRecallTokens(candidate.goal, []);
255
+ const newFollowUpTokens = new Set(normalizeStitchLexicalTokens(newTrajectory.followUpSummary ?? "", []));
256
+ const candidateGoalTokens = normalizeStitchLexicalTokens(candidate.goal, []);
257
+ const candidateGoalTokenSet = new Set(candidateGoalTokens);
216
258
  if (newFollowUpTokens.size > 0 && candidateGoalTokens.length > 0) {
217
- const overlap = countRecallTokenOverlap(newFollowUpTokens, candidate.goal, []);
259
+ const overlap = countTokenSetOverlap(newFollowUpTokens, candidateGoalTokenSet);
218
260
  const normalized = overlap / Math.max(newFollowUpTokens.size, candidateGoalTokens.length);
219
261
  const component = normalized * STITCH_WEIGHTS.followUpToGoal;
220
262
  score += component;
@@ -225,12 +267,11 @@ export function scoreStitchCandidate(
225
267
  }
226
268
 
227
269
  // 1b. Candidate follow-up → New goal match (reverse direction)
228
- const candidateFollowUpTokens = new Set(
229
- normalizeRecallTokens(candidate.followUpSummary ?? "", []),
230
- );
231
- const newGoalTokens = normalizeRecallTokens(newTrajectory.goal, []);
270
+ const candidateFollowUpTokens = new Set(normalizeStitchLexicalTokens(candidate.followUpSummary ?? "", []));
271
+ const newGoalTokens = normalizeStitchLexicalTokens(newTrajectory.goal, []);
272
+ const newGoalTokenSet = new Set(newGoalTokens);
232
273
  if (candidateFollowUpTokens.size > 0 && newGoalTokens.length > 0) {
233
- const overlap = countRecallTokenOverlap(candidateFollowUpTokens, newTrajectory.goal, []);
274
+ const overlap = countTokenSetOverlap(candidateFollowUpTokens, newGoalTokenSet);
234
275
  const normalized = overlap / Math.max(candidateFollowUpTokens.size, newGoalTokens.length);
235
276
  const component = normalized * 3.0;
236
277
  score += component;
@@ -241,11 +282,9 @@ export function scoreStitchCandidate(
241
282
  }
242
283
 
243
284
  // 2. Outcome → Goal match
244
- const newOutcomeTokens = new Set(
245
- normalizeRecallTokens(newTrajectory.outcomeSummary, []),
246
- );
285
+ const newOutcomeTokens = new Set(normalizeStitchLexicalTokens(newTrajectory.outcomeSummary, []));
247
286
  if (newOutcomeTokens.size > 0) {
248
- const overlap = countRecallTokenOverlap(newOutcomeTokens, candidate.goal, []);
287
+ const overlap = countTokenSetOverlap(newOutcomeTokens, candidateGoalTokenSet);
249
288
  const normalized = overlap / Math.max(newOutcomeTokens.size, candidateGoalTokens.length || 1);
250
289
  const component = normalized * STITCH_WEIGHTS.outcomeToGoal;
251
290
  score += component;
@@ -297,9 +336,8 @@ export function scoreStitchCandidate(
297
336
 
298
337
  // Determine edge type by heuristic
299
338
  let edgeType: CausalEdge["edgeType"] = "continuation";
300
- const goalTokens = new Set(normalizeRecallTokens(newTrajectory.goal, []));
301
- const candidateGoalSet = new Set(candidateGoalTokens);
302
- const goalOverlap = [...goalTokens].filter((t) => candidateGoalSet.has(t)).length;
339
+ const goalTokens = new Set(newGoalTokens);
340
+ const goalOverlap = countTokenSetOverlap(goalTokens, candidateGoalTokenSet);
303
341
  const goalSimilarity = goalTokens.size > 0 ? goalOverlap / goalTokens.size : 0;
304
342
 
305
343
  if (goalSimilarity > 0.7 && candidate.outcomeKind === "failure") {
@@ -307,7 +345,7 @@ export function scoreStitchCandidate(
307
345
  } else if (goalSimilarity > 0.7 && newTrajectory.outcomeKind !== candidate.outcomeKind) {
308
346
  edgeType = "correction";
309
347
  } else if (newFollowUpTokens.size > 0 && candidateGoalTokens.length > 0) {
310
- const followUpGoalOverlap = countRecallTokenOverlap(newFollowUpTokens, candidate.goal, []);
348
+ const followUpGoalOverlap = countTokenSetOverlap(newFollowUpTokens, candidateGoalTokenSet);
311
349
  if (followUpGoalOverlap > 0) {
312
350
  edgeType = "follow_up_to_goal";
313
351
  }
@@ -324,7 +362,7 @@ async function readRecentTrajectories(
324
362
  memoryDir: string,
325
363
  causalTrajectoryStoreDir: string | undefined,
326
364
  currentSessionKey: string,
327
- lookbackDays: number,
365
+ lookbackDays: number
328
366
  ): Promise<CausalTrajectoryRecord[]> {
329
367
  const root = resolveCausalTrajectoryStoreDir(memoryDir, causalTrajectoryStoreDir);
330
368
  const trajectoriesDir = path.join(root, "trajectories");
@@ -370,7 +408,7 @@ export async function stitchCausalChain(options: {
370
408
  memoryDir,
371
409
  causalTrajectoryStoreDir,
372
410
  newTrajectory.sessionKey,
373
- stitchConfig.lookbackDays,
411
+ stitchConfig.lookbackDays
374
412
  );
375
413
 
376
414
  if (candidates.length === 0) return [];