@remnic/core 9.6.29 → 9.6.31
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/access-admin-ops-surface.d.ts +1 -0
- package/dist/access-admin-ops-surface.js +2 -1
- package/dist/access-boundary.d.ts +1 -0
- package/dist/access-boundary.js +3 -2
- package/dist/access-cli.js +18 -17
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +1 -0
- package/dist/access-http.js +7 -6
- package/dist/access-identity-continuity-surface.d.ts +1 -0
- package/dist/access-identity-continuity-surface.js +2 -1
- package/dist/access-lcm-surface.d.ts +1 -0
- package/dist/access-lcm-surface.js +2 -1
- package/dist/access-mcp.d.ts +1 -0
- package/dist/access-mcp.js +6 -5
- package/dist/access-observe-write-surface.d.ts +1 -0
- package/dist/access-observe-write-surface.js +2 -1
- package/dist/access-operations-batch.js +4 -3
- package/dist/access-operations.d.ts +1 -0
- package/dist/access-operations.js +5 -4
- package/dist/access-recall-surface.d.ts +1 -0
- package/dist/access-recall-surface.js +2 -1
- package/dist/access-service.d.ts +1 -0
- package/dist/access-service.js +2 -1
- package/dist/access-surface-catalog.d.ts +1 -0
- package/dist/bootstrap.d.ts +1 -0
- package/dist/causal-behavior.d.ts +1 -0
- package/dist/{chunk-L6W77GWW.js → chunk-6TCXIRP5.js} +25 -13
- package/dist/chunk-6TCXIRP5.js.map +1 -0
- package/dist/chunk-C37ZRXX7.js +36 -0
- package/dist/chunk-C37ZRXX7.js.map +1 -0
- package/dist/{chunk-SGYTQKC2.js → chunk-C6TKSI35.js} +3 -3
- package/dist/{chunk-C2SEH754.js → chunk-DAAJUA6Q.js} +4 -4
- package/dist/{chunk-FV5FVO2J.js → chunk-DEOYTFA6.js} +9 -5
- package/dist/chunk-DEOYTFA6.js.map +1 -0
- package/dist/{chunk-PYPOFEMK.js → chunk-DGFU5MSX.js} +16 -1
- package/dist/chunk-DGFU5MSX.js.map +1 -0
- package/dist/{chunk-EAREADWV.js → chunk-GQURC4B7.js} +2 -2
- package/dist/{chunk-XA4PWKBW.js → chunk-MXAGJHTA.js} +3 -3
- package/dist/{chunk-LZTFCAKE.js → chunk-OH7QLI6W.js} +28 -15
- package/dist/chunk-OH7QLI6W.js.map +1 -0
- package/dist/{chunk-5BHIGBHQ.js → chunk-OXVKR5OU.js} +6 -3
- package/dist/{chunk-5BHIGBHQ.js.map → chunk-OXVKR5OU.js.map} +1 -1
- package/dist/{chunk-IF7THCGJ.js → chunk-PUQZIS6A.js} +3 -3
- package/dist/{chunk-4SBW47WK.js → chunk-T67LUYCR.js} +28 -15
- package/dist/chunk-T67LUYCR.js.map +1 -0
- package/dist/{chunk-4463LUIE.js → chunk-TVIVY7KU.js} +180 -70
- package/dist/chunk-TVIVY7KU.js.map +1 -0
- package/dist/{chunk-KCYE2MZM.js → chunk-UXPUUL3G.js} +29 -8
- package/dist/chunk-UXPUUL3G.js.map +1 -0
- package/dist/chunk-VDC6RZI4.js +1 -0
- package/dist/{chunk-3RROR5KV.js → chunk-VJRJTRYF.js} +4 -4
- package/dist/{chunk-5WJ4LBFR.js → chunk-WSOEYOHN.js} +8 -8
- package/dist/{chunk-5AJIDEFT.js → chunk-XFTPUXCE.js} +11 -7
- package/dist/chunk-XFTPUXCE.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +8 -7
- package/dist/compounding/preference-consolidator.d.ts +1 -0
- package/dist/event-order-recall.d.ts +1 -0
- package/dist/event-order-recall.js +3 -2
- package/dist/evidence-pack.d.ts +18 -1
- package/dist/evidence-pack.js +1 -1
- package/dist/explicit-capture.d.ts +1 -0
- package/dist/explicit-cue-recall.d.ts +19 -1
- package/dist/explicit-cue-recall.js +3 -2
- package/dist/focused-list-recall.d.ts +1 -0
- package/dist/focused-list-recall.js +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +18 -17
- package/dist/lcm/engine.d.ts +3 -0
- package/dist/lcm/engine.js +2 -2
- package/dist/lcm/index.d.ts +23 -1
- package/dist/lcm/index.js +14 -4
- package/dist/lcm/recall.d.ts +15 -1
- package/dist/lcm/recall.js +5 -3
- package/dist/lcm/tools.d.ts +1 -0
- package/dist/mcp-memory-inspector-app.d.ts +1 -0
- package/dist/orchestrator.d.ts +1 -0
- package/dist/orchestrator.js +18 -17
- package/dist/response-guidance-recall.d.ts +1 -0
- package/dist/response-guidance-recall.js +3 -2
- package/dist/targeted-fact-recall.d.ts +1 -0
- package/dist/targeted-fact-recall.js +3 -2
- package/package.json +2 -2
- package/src/access-lcm-surface.ts +20 -5
- package/src/access-recall-surface.ts +2 -1
- package/src/event-order-recall.ts +5 -3
- package/src/evidence-pack.test.ts +66 -1
- package/src/evidence-pack.ts +41 -0
- package/src/explicit-cue-recall.ts +291 -133
- package/src/focused-list-recall.ts +25 -16
- package/src/index.ts +3 -0
- package/src/lcm/engine.ts +17 -5
- package/src/lcm/evidence-identity.ts +59 -0
- package/src/lcm/index.ts +13 -1
- package/src/lcm/recall.ts +48 -5
- package/src/lcm-engine.test.ts +46 -0
- package/src/lcm-recall.test.ts +48 -1
- package/src/lcm-retrieval-lineage.test.ts +236 -0
- package/src/recall-trace-receipts.test.ts +380 -0
- package/src/response-guidance-recall.ts +22 -14
- package/src/targeted-fact-recall.ts +25 -16
- package/dist/chunk-4463LUIE.js.map +0 -1
- package/dist/chunk-4SBW47WK.js.map +0 -1
- package/dist/chunk-5AJIDEFT.js.map +0 -1
- package/dist/chunk-FV5FVO2J.js.map +0 -1
- package/dist/chunk-HHLLAQGZ.js +0 -1
- package/dist/chunk-KCYE2MZM.js.map +0 -1
- package/dist/chunk-L6W77GWW.js.map +0 -1
- package/dist/chunk-LZTFCAKE.js.map +0 -1
- package/dist/chunk-PYPOFEMK.js.map +0 -1
- /package/dist/{chunk-SGYTQKC2.js.map → chunk-C6TKSI35.js.map} +0 -0
- /package/dist/{chunk-C2SEH754.js.map → chunk-DAAJUA6Q.js.map} +0 -0
- /package/dist/{chunk-EAREADWV.js.map → chunk-GQURC4B7.js.map} +0 -0
- /package/dist/{chunk-XA4PWKBW.js.map → chunk-MXAGJHTA.js.map} +0 -0
- /package/dist/{chunk-IF7THCGJ.js.map → chunk-PUQZIS6A.js.map} +0 -0
- /package/dist/{chunk-HHLLAQGZ.js.map → chunk-VDC6RZI4.js.map} +0 -0
- /package/dist/{chunk-3RROR5KV.js.map → chunk-VJRJTRYF.js.map} +0 -0
- /package/dist/{chunk-5WJ4LBFR.js.map → chunk-WSOEYOHN.js.map} +0 -0
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
buildEvidencePack,
|
|
3
|
+
type EvidencePackSelectionReceipt,
|
|
4
|
+
} from "./evidence-pack.js";
|
|
2
5
|
import {
|
|
3
6
|
gatherAcrossReadSessions,
|
|
4
7
|
resolveLcmReadSessionIds,
|
|
5
8
|
} from "./lcm-fallback-read.js";
|
|
6
9
|
import { unifiedDedupeAndRank } from "./recall-pipeline-stages.js";
|
|
10
|
+
import {
|
|
11
|
+
lcmArchiveRowId,
|
|
12
|
+
lcmEvidenceIdentity,
|
|
13
|
+
} from "./lcm/evidence-identity.js";
|
|
7
14
|
|
|
8
15
|
export interface ExplicitCueRecallEngine {
|
|
9
16
|
expandContext(
|
|
@@ -11,7 +18,15 @@ export interface ExplicitCueRecallEngine {
|
|
|
11
18
|
fromTurn: number,
|
|
12
19
|
toTurn: number,
|
|
13
20
|
maxTokens: number,
|
|
14
|
-
): Promise<
|
|
21
|
+
): Promise<
|
|
22
|
+
Array<{
|
|
23
|
+
id?: number;
|
|
24
|
+
session_id?: string;
|
|
25
|
+
turn_index: number;
|
|
26
|
+
role: string;
|
|
27
|
+
content: string;
|
|
28
|
+
}>
|
|
29
|
+
>;
|
|
15
30
|
getStats?(sessionId?: string): Promise<{
|
|
16
31
|
totalMessages: number;
|
|
17
32
|
maxTurnIndex?: number;
|
|
@@ -22,6 +37,7 @@ export interface ExplicitCueRecallEngine {
|
|
|
22
37
|
sessionId?: string,
|
|
23
38
|
): Promise<
|
|
24
39
|
Array<{
|
|
40
|
+
id?: number;
|
|
25
41
|
turn_index: number;
|
|
26
42
|
role: string;
|
|
27
43
|
content: string;
|
|
@@ -48,6 +64,8 @@ export interface ExplicitCueRecallOptions {
|
|
|
48
64
|
includeBenchmarkAnchorCues?: boolean;
|
|
49
65
|
includeContentLexicalCues?: boolean;
|
|
50
66
|
includeStructuredPlanCues?: boolean;
|
|
67
|
+
/** Observe selected evidence blocks without changing rendered output. */
|
|
68
|
+
onEvidenceSelected?: (receipt: EvidencePackSelectionReceipt) => void;
|
|
51
69
|
}
|
|
52
70
|
|
|
53
71
|
export interface TrajectoryAnalysisRecallOptions {
|
|
@@ -55,6 +73,18 @@ export interface TrajectoryAnalysisRecallOptions {
|
|
|
55
73
|
sessionId?: string;
|
|
56
74
|
query: string;
|
|
57
75
|
maxChars: number;
|
|
76
|
+
/** Observe only emitted lines; unavailable lineage is never guessed. */
|
|
77
|
+
onLineSelected?: (receipt: TrajectoryAnalysisLineReceipt) => void;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface TrajectoryAnalysisLineReceipt {
|
|
81
|
+
/** Half-open offsets within the returned trajectory section. */
|
|
82
|
+
lineStart: number;
|
|
83
|
+
lineEnd: number;
|
|
84
|
+
/** Whether the source row set is structurally exact or unavailable. */
|
|
85
|
+
lineageStatus: "exact" | "unavailable";
|
|
86
|
+
actionArchiveRowIds: number[];
|
|
87
|
+
observationArchiveRowIds: number[];
|
|
58
88
|
}
|
|
59
89
|
|
|
60
90
|
export type ExplicitTurnReference = {
|
|
@@ -62,6 +92,16 @@ export type ExplicitTurnReference = {
|
|
|
62
92
|
includeDirectTurn: boolean;
|
|
63
93
|
};
|
|
64
94
|
|
|
95
|
+
interface ExplicitCueEvidenceItem {
|
|
96
|
+
id: string;
|
|
97
|
+
archiveRowId?: number;
|
|
98
|
+
sessionId: string;
|
|
99
|
+
turnIndex: number;
|
|
100
|
+
role: string;
|
|
101
|
+
content: string;
|
|
102
|
+
score?: number;
|
|
103
|
+
}
|
|
104
|
+
|
|
65
105
|
const DEFAULT_MAX_CHARS = 2_400;
|
|
66
106
|
const DEFAULT_MAX_ITEM_CHARS = 1_200;
|
|
67
107
|
const DEFAULT_MAX_REFERENCES = 24;
|
|
@@ -326,23 +366,17 @@ export async function buildExplicitCueRecallSection(
|
|
|
326
366
|
return "";
|
|
327
367
|
}
|
|
328
368
|
|
|
329
|
-
const evidenceItems:
|
|
330
|
-
id: string;
|
|
331
|
-
sessionId: string;
|
|
332
|
-
turnIndex: number;
|
|
333
|
-
role: string;
|
|
334
|
-
content: string;
|
|
335
|
-
score?: number;
|
|
336
|
-
}> = [];
|
|
369
|
+
const evidenceItems: ExplicitCueEvidenceItem[] = [];
|
|
337
370
|
const seenTurns = new Set<string>();
|
|
338
371
|
|
|
339
372
|
// #1505 codex P2: gather cue evidence across the ordered LCM read key set
|
|
340
373
|
// (primary overlay → project/root fallbacks) into ONE shared accumulator
|
|
341
374
|
// (`evidenceItems` / `seenTurns`), so a branch-scoped session's project/root
|
|
342
375
|
// fallback cues are RECOVERED instead of being skipped by the old
|
|
343
|
-
// first-non-empty short-circuit. `seenTurns`
|
|
344
|
-
//
|
|
345
|
-
// `
|
|
376
|
+
// first-non-empty short-circuit. `seenTurns` is the historical local name;
|
|
377
|
+
// its keys use archive-row identity when available and fall back to
|
|
378
|
+
// `session_id`+`turn_index` for legacy engines. The budget is applied exactly
|
|
379
|
+
// once in the `buildEvidencePack` call below. `gatherAcrossReadSessions` isolates a
|
|
346
380
|
// per-key read failure (a corrupt/locked fallback index must not discard the
|
|
347
381
|
// other keys' cues); single-key recall runs each collector directly, so a
|
|
348
382
|
// failure propagates exactly as before.
|
|
@@ -438,6 +472,9 @@ export async function buildExplicitCueRecallSection(
|
|
|
438
472
|
options.maxItemChars,
|
|
439
473
|
DEFAULT_MAX_ITEM_CHARS,
|
|
440
474
|
),
|
|
475
|
+
...(options.onEvidenceSelected
|
|
476
|
+
? { onSelection: options.onEvidenceSelected }
|
|
477
|
+
: {}),
|
|
441
478
|
});
|
|
442
479
|
}
|
|
443
480
|
|
|
@@ -502,7 +539,32 @@ export async function buildTrajectoryAnalysisRecallSection(
|
|
|
502
539
|
}
|
|
503
540
|
|
|
504
541
|
const clipped = truncateTrajectoryAnalysisLines(lines, bodyBudget);
|
|
505
|
-
|
|
542
|
+
if (clipped.length === 0) return "";
|
|
543
|
+
const text = `${header}\n${clipped.map((line) => line.text).join("\n")}`;
|
|
544
|
+
if (options.onLineSelected) {
|
|
545
|
+
let lineStart = header.length + 1;
|
|
546
|
+
for (const line of clipped) {
|
|
547
|
+
const lineEnd = lineStart + line.text.length;
|
|
548
|
+
options.onLineSelected({
|
|
549
|
+
lineStart,
|
|
550
|
+
lineEnd,
|
|
551
|
+
lineageStatus: line.lineageStatus,
|
|
552
|
+
actionArchiveRowIds: [...line.actionArchiveRowIds],
|
|
553
|
+
observationArchiveRowIds: [...line.observationArchiveRowIds],
|
|
554
|
+
});
|
|
555
|
+
lineStart = lineEnd + 1;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
return text;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
function uniqueSortedArchiveRowIds(
|
|
562
|
+
values: readonly (number | undefined)[],
|
|
563
|
+
): number[] {
|
|
564
|
+
return [...new Set(values.filter(
|
|
565
|
+
(value): value is number =>
|
|
566
|
+
typeof value === "number" && Number.isSafeInteger(value) && value > 0,
|
|
567
|
+
))].sort((left, right) => left - right);
|
|
506
568
|
}
|
|
507
569
|
|
|
508
570
|
async function collectTurnReferenceEvidence(options: {
|
|
@@ -510,13 +572,7 @@ async function collectTurnReferenceEvidence(options: {
|
|
|
510
572
|
sessionId?: string;
|
|
511
573
|
query: string;
|
|
512
574
|
maxReferences: number;
|
|
513
|
-
evidenceItems:
|
|
514
|
-
id: string;
|
|
515
|
-
sessionId: string;
|
|
516
|
-
turnIndex: number;
|
|
517
|
-
role: string;
|
|
518
|
-
content: string;
|
|
519
|
-
}>;
|
|
575
|
+
evidenceItems: ExplicitCueEvidenceItem[];
|
|
520
576
|
seenTurns: Set<string>;
|
|
521
577
|
}): Promise<void> {
|
|
522
578
|
if (!options.sessionId) {
|
|
@@ -575,13 +631,7 @@ async function collectFocusedTranscriptCueEvidence(options: {
|
|
|
575
631
|
engine: ExplicitCueRecallEngine;
|
|
576
632
|
sessionId?: string;
|
|
577
633
|
query: string;
|
|
578
|
-
evidenceItems:
|
|
579
|
-
id: string;
|
|
580
|
-
sessionId: string;
|
|
581
|
-
turnIndex: number;
|
|
582
|
-
role: string;
|
|
583
|
-
content: string;
|
|
584
|
-
}>;
|
|
634
|
+
evidenceItems: ExplicitCueEvidenceItem[];
|
|
585
635
|
seenTurns: Set<string>;
|
|
586
636
|
}): Promise<void> {
|
|
587
637
|
if (!options.sessionId || !options.engine.getStats) {
|
|
@@ -611,8 +661,8 @@ async function collectFocusedTranscriptCueEvidence(options: {
|
|
|
611
661
|
continue;
|
|
612
662
|
}
|
|
613
663
|
appendEvidenceItem(options.evidenceItems, options.seenTurns, {
|
|
614
|
-
|
|
615
|
-
sessionId: options.sessionId,
|
|
664
|
+
...lcmEvidenceIdentity(message, options.sessionId),
|
|
665
|
+
sessionId: message.session_id ?? options.sessionId,
|
|
616
666
|
turnIndex: message.turn_index,
|
|
617
667
|
role: message.role,
|
|
618
668
|
content: message.content,
|
|
@@ -772,13 +822,7 @@ async function collectContentLabelReferenceEvidence(options: {
|
|
|
772
822
|
sessionId?: string;
|
|
773
823
|
query: string;
|
|
774
824
|
references: ExplicitTurnReference[];
|
|
775
|
-
evidenceItems:
|
|
776
|
-
id: string;
|
|
777
|
-
sessionId: string;
|
|
778
|
-
turnIndex: number;
|
|
779
|
-
role: string;
|
|
780
|
-
content: string;
|
|
781
|
-
}>;
|
|
825
|
+
evidenceItems: ExplicitCueEvidenceItem[];
|
|
782
826
|
seenTurns: Set<string>;
|
|
783
827
|
}): Promise<Set<number>> {
|
|
784
828
|
const resolved = new Set<number>();
|
|
@@ -818,7 +862,7 @@ async function collectContentLabelReferenceEvidence(options: {
|
|
|
818
862
|
}
|
|
819
863
|
if (expanded.length === 0) {
|
|
820
864
|
appendEvidenceItem(options.evidenceItems, options.seenTurns, {
|
|
821
|
-
|
|
865
|
+
...lcmEvidenceIdentity(hit, hit.session_id),
|
|
822
866
|
sessionId: hit.session_id,
|
|
823
867
|
turnIndex: hit.turn_index,
|
|
824
868
|
role: hit.role,
|
|
@@ -845,6 +889,7 @@ async function searchReferenceContentLabels(
|
|
|
845
889
|
sessionId?: string,
|
|
846
890
|
): Promise<
|
|
847
891
|
Array<{
|
|
892
|
+
id?: number;
|
|
848
893
|
turn_index: number;
|
|
849
894
|
role: string;
|
|
850
895
|
content: string;
|
|
@@ -855,6 +900,7 @@ async function searchReferenceContentLabels(
|
|
|
855
900
|
const hits = new Map<
|
|
856
901
|
string,
|
|
857
902
|
{
|
|
903
|
+
id?: number;
|
|
858
904
|
turn_index: number;
|
|
859
905
|
role: string;
|
|
860
906
|
content: string;
|
|
@@ -878,7 +924,8 @@ async function searchReferenceContentLabels(
|
|
|
878
924
|
) {
|
|
879
925
|
continue;
|
|
880
926
|
}
|
|
881
|
-
hits.set(`${result.session_id
|
|
927
|
+
hits.set(`${lcmEvidenceIdentity(result, result.session_id).id}:${labelKind}`, {
|
|
928
|
+
...(typeof result.id === "number" ? { id: result.id } : {}),
|
|
882
929
|
turn_index: result.turn_index,
|
|
883
930
|
role: result.role,
|
|
884
931
|
content: result.content,
|
|
@@ -1054,14 +1101,7 @@ async function collectLexicalCueEvidence(options: {
|
|
|
1054
1101
|
includeBenchmarkAnchorCues?: boolean;
|
|
1055
1102
|
includeContentLexicalCues?: boolean;
|
|
1056
1103
|
includeStructuredPlanCues?: boolean;
|
|
1057
|
-
evidenceItems:
|
|
1058
|
-
id: string;
|
|
1059
|
-
sessionId: string;
|
|
1060
|
-
turnIndex: number;
|
|
1061
|
-
role: string;
|
|
1062
|
-
content: string;
|
|
1063
|
-
score?: number;
|
|
1064
|
-
}>;
|
|
1104
|
+
evidenceItems: ExplicitCueEvidenceItem[];
|
|
1065
1105
|
seenTurns: Set<string>;
|
|
1066
1106
|
}): Promise<void> {
|
|
1067
1107
|
const cues = prioritizeLexicalCueSearchCues(
|
|
@@ -1096,7 +1136,7 @@ async function collectLexicalCueEvidence(options: {
|
|
|
1096
1136
|
);
|
|
1097
1137
|
if (expanded.length === 0) {
|
|
1098
1138
|
appendEvidenceItem(options.evidenceItems, options.seenTurns, {
|
|
1099
|
-
|
|
1139
|
+
...lcmEvidenceIdentity(result, result.session_id),
|
|
1100
1140
|
sessionId: result.session_id,
|
|
1101
1141
|
turnIndex: result.turn_index,
|
|
1102
1142
|
role: result.role,
|
|
@@ -1107,7 +1147,7 @@ async function collectLexicalCueEvidence(options: {
|
|
|
1107
1147
|
}
|
|
1108
1148
|
if (exactHitFirst) {
|
|
1109
1149
|
appendEvidenceItem(options.evidenceItems, options.seenTurns, {
|
|
1110
|
-
|
|
1150
|
+
...lcmEvidenceIdentity(result, result.session_id),
|
|
1111
1151
|
sessionId: result.session_id,
|
|
1112
1152
|
turnIndex: result.turn_index,
|
|
1113
1153
|
role: result.role,
|
|
@@ -1131,6 +1171,67 @@ interface LabeledTrajectoryStep {
|
|
|
1131
1171
|
observation?: string;
|
|
1132
1172
|
actionTurnIndex?: number;
|
|
1133
1173
|
observationTurnIndex?: number;
|
|
1174
|
+
actionArchiveRowId?: number;
|
|
1175
|
+
observationArchiveRowId?: number;
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
interface TrajectoryLineSource {
|
|
1179
|
+
lineageStatus: "exact" | "unavailable";
|
|
1180
|
+
actionArchiveRowIds: number[];
|
|
1181
|
+
observationArchiveRowIds: number[];
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
interface SelectedTrajectoryLine extends TrajectoryLineSource {
|
|
1185
|
+
text: string;
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
class TrajectoryAnalysisLines extends Array<string> {
|
|
1189
|
+
private readonly sources = new Map<number, TrajectoryLineSource>();
|
|
1190
|
+
|
|
1191
|
+
pushWithSources(
|
|
1192
|
+
text: string,
|
|
1193
|
+
actionSteps: readonly LabeledTrajectoryStep[] = [],
|
|
1194
|
+
observationSteps: readonly LabeledTrajectoryStep[] = [],
|
|
1195
|
+
): number {
|
|
1196
|
+
const index = this.length;
|
|
1197
|
+
const length = super.push(text);
|
|
1198
|
+
const hasUnavailableSource =
|
|
1199
|
+
actionSteps.some((step) =>
|
|
1200
|
+
lcmArchiveRowId({ id: step.actionArchiveRowId }) === undefined
|
|
1201
|
+
) ||
|
|
1202
|
+
observationSteps.some((step) =>
|
|
1203
|
+
lcmArchiveRowId({ id: step.observationArchiveRowId }) === undefined
|
|
1204
|
+
);
|
|
1205
|
+
this.sources.set(index, {
|
|
1206
|
+
lineageStatus: hasUnavailableSource ? "unavailable" : "exact",
|
|
1207
|
+
actionArchiveRowIds: hasUnavailableSource
|
|
1208
|
+
? []
|
|
1209
|
+
: uniqueSortedArchiveRowIds(
|
|
1210
|
+
actionSteps.map((step) => step.actionArchiveRowId),
|
|
1211
|
+
),
|
|
1212
|
+
observationArchiveRowIds: hasUnavailableSource
|
|
1213
|
+
? []
|
|
1214
|
+
: uniqueSortedArchiveRowIds(
|
|
1215
|
+
observationSteps.map((step) => step.observationArchiveRowId),
|
|
1216
|
+
),
|
|
1217
|
+
});
|
|
1218
|
+
return length;
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
sourceAt(index: number): TrajectoryLineSource {
|
|
1222
|
+
const source = this.sources.get(index);
|
|
1223
|
+
return source
|
|
1224
|
+
? {
|
|
1225
|
+
lineageStatus: source.lineageStatus,
|
|
1226
|
+
actionArchiveRowIds: [...source.actionArchiveRowIds],
|
|
1227
|
+
observationArchiveRowIds: [...source.observationArchiveRowIds],
|
|
1228
|
+
}
|
|
1229
|
+
: {
|
|
1230
|
+
lineageStatus: "unavailable",
|
|
1231
|
+
actionArchiveRowIds: [],
|
|
1232
|
+
observationArchiveRowIds: [],
|
|
1233
|
+
};
|
|
1234
|
+
}
|
|
1134
1235
|
}
|
|
1135
1236
|
|
|
1136
1237
|
interface TrajectoryBounds {
|
|
@@ -1187,7 +1288,12 @@ function hasTrajectoryAnalysisIntent(query: string): boolean {
|
|
|
1187
1288
|
}
|
|
1188
1289
|
|
|
1189
1290
|
function parseLabeledTrajectory(
|
|
1190
|
-
messages: Array<{
|
|
1291
|
+
messages: Array<{
|
|
1292
|
+
id?: number;
|
|
1293
|
+
turn_index: number;
|
|
1294
|
+
role: string;
|
|
1295
|
+
content: string;
|
|
1296
|
+
}>,
|
|
1191
1297
|
): LabeledTrajectoryStep[] {
|
|
1192
1298
|
const byStep = new Map<number, LabeledTrajectoryStep>();
|
|
1193
1299
|
|
|
@@ -1197,6 +1303,8 @@ function parseLabeledTrajectory(
|
|
|
1197
1303
|
const step = getOrCreateTrajectoryStep(byStep, action.step);
|
|
1198
1304
|
step.action = action.value;
|
|
1199
1305
|
step.actionTurnIndex = message.turn_index;
|
|
1306
|
+
const archiveRowId = lcmArchiveRowId(message);
|
|
1307
|
+
if (archiveRowId !== undefined) step.actionArchiveRowId = archiveRowId;
|
|
1200
1308
|
continue;
|
|
1201
1309
|
}
|
|
1202
1310
|
|
|
@@ -1205,6 +1313,10 @@ function parseLabeledTrajectory(
|
|
|
1205
1313
|
const step = getOrCreateTrajectoryStep(byStep, observation.step);
|
|
1206
1314
|
step.observation = observation.value;
|
|
1207
1315
|
step.observationTurnIndex = message.turn_index;
|
|
1316
|
+
const archiveRowId = lcmArchiveRowId(message);
|
|
1317
|
+
if (archiveRowId !== undefined) {
|
|
1318
|
+
step.observationArchiveRowId = archiveRowId;
|
|
1319
|
+
}
|
|
1208
1320
|
}
|
|
1209
1321
|
}
|
|
1210
1322
|
|
|
@@ -1307,12 +1419,13 @@ function buildTrajectoryAnalysisLines(
|
|
|
1307
1419
|
query: string,
|
|
1308
1420
|
trajectory: readonly LabeledTrajectoryStep[],
|
|
1309
1421
|
bounds: TrajectoryBounds,
|
|
1310
|
-
):
|
|
1422
|
+
): TrajectoryAnalysisLines {
|
|
1311
1423
|
const normalized = normalizeTrajectoryQuery(query);
|
|
1312
1424
|
const explicitReferences = collectExplicitTurnReferences(query);
|
|
1313
|
-
const lines
|
|
1425
|
+
const lines = new TrajectoryAnalysisLines();
|
|
1426
|
+
lines.pushWithSources(
|
|
1314
1427
|
`Analyzed labeled action/observation transcript window: steps ${bounds.start}-${bounds.end} (${bounds.reason}).`,
|
|
1315
|
-
|
|
1428
|
+
);
|
|
1316
1429
|
const hasQuotedObservationPair = extractQuotedObservations(query).length >= 2;
|
|
1317
1430
|
const transition = findObservationTransition(query, trajectory);
|
|
1318
1431
|
const entities = extractNumberedEntities(query);
|
|
@@ -1332,8 +1445,14 @@ function buildTrajectoryAnalysisLines(
|
|
|
1332
1445
|
/\bwhat\s+will\s+be\s+the\s+resulting\b/.test(normalized);
|
|
1333
1446
|
|
|
1334
1447
|
if (transition) {
|
|
1335
|
-
|
|
1448
|
+
const fromStep = trajectory.find((step) => step.step === transition.fromStep);
|
|
1449
|
+
const toStep = trajectory.find((step) => step.step === transition.toStep);
|
|
1450
|
+
lines.pushWithSources(
|
|
1336
1451
|
`Matched quoted observations: Observation ${transition.fromStep} -> Observation ${transition.toStep}.`,
|
|
1452
|
+
[],
|
|
1453
|
+
[fromStep, toStep].filter(
|
|
1454
|
+
(step): step is LabeledTrajectoryStep => step !== undefined,
|
|
1455
|
+
),
|
|
1337
1456
|
);
|
|
1338
1457
|
appendActionSequenceSummary(
|
|
1339
1458
|
lines,
|
|
@@ -1416,11 +1535,11 @@ function buildTrajectoryAnalysisLines(
|
|
|
1416
1535
|
}
|
|
1417
1536
|
}
|
|
1418
1537
|
|
|
1419
|
-
return lines.length === 1 ?
|
|
1538
|
+
return lines.length === 1 ? new TrajectoryAnalysisLines() : lines;
|
|
1420
1539
|
}
|
|
1421
1540
|
|
|
1422
1541
|
function appendReferencedTrajectoryLines(
|
|
1423
|
-
lines:
|
|
1542
|
+
lines: TrajectoryAnalysisLines,
|
|
1424
1543
|
trajectory: readonly LabeledTrajectoryStep[],
|
|
1425
1544
|
references: readonly ExplicitTurnReference[],
|
|
1426
1545
|
options: { includeObservations: boolean; heading: string },
|
|
@@ -1434,19 +1553,23 @@ function appendReferencedTrajectoryLines(
|
|
|
1434
1553
|
return;
|
|
1435
1554
|
}
|
|
1436
1555
|
|
|
1437
|
-
lines.
|
|
1556
|
+
lines.pushWithSources(options.heading);
|
|
1438
1557
|
for (const step of window) {
|
|
1439
1558
|
if (step.action) {
|
|
1440
|
-
lines.
|
|
1559
|
+
lines.pushWithSources(`[Action ${step.step}]: ${step.action}`, [step]);
|
|
1441
1560
|
}
|
|
1442
1561
|
if (options.includeObservations && step.observation) {
|
|
1443
|
-
lines.
|
|
1562
|
+
lines.pushWithSources(
|
|
1563
|
+
`[Observation ${step.step}]: ${oneLine(step.observation)}`,
|
|
1564
|
+
[],
|
|
1565
|
+
[step],
|
|
1566
|
+
);
|
|
1444
1567
|
}
|
|
1445
1568
|
}
|
|
1446
1569
|
}
|
|
1447
1570
|
|
|
1448
1571
|
function appendActionRangeLines(
|
|
1449
|
-
lines:
|
|
1572
|
+
lines: TrajectoryAnalysisLines,
|
|
1450
1573
|
trajectory: readonly LabeledTrajectoryStep[],
|
|
1451
1574
|
start: number,
|
|
1452
1575
|
end: number,
|
|
@@ -1462,19 +1585,23 @@ function appendActionRangeLines(
|
|
|
1462
1585
|
if (window.length === 0) {
|
|
1463
1586
|
return;
|
|
1464
1587
|
}
|
|
1465
|
-
lines.
|
|
1588
|
+
lines.pushWithSources(options.heading);
|
|
1466
1589
|
for (const step of window) {
|
|
1467
1590
|
if (step.action) {
|
|
1468
|
-
lines.
|
|
1591
|
+
lines.pushWithSources(`[Action ${step.step}]: ${step.action}`, [step]);
|
|
1469
1592
|
}
|
|
1470
1593
|
if (options.includeObservations && step.observation) {
|
|
1471
|
-
lines.
|
|
1594
|
+
lines.pushWithSources(
|
|
1595
|
+
`[Observation ${step.step}]: ${oneLine(step.observation)}`,
|
|
1596
|
+
[],
|
|
1597
|
+
[step],
|
|
1598
|
+
);
|
|
1472
1599
|
}
|
|
1473
1600
|
}
|
|
1474
1601
|
}
|
|
1475
1602
|
|
|
1476
1603
|
function appendActionSequenceSummary(
|
|
1477
|
-
lines:
|
|
1604
|
+
lines: TrajectoryAnalysisLines,
|
|
1478
1605
|
trajectory: readonly LabeledTrajectoryStep[],
|
|
1479
1606
|
start: number,
|
|
1480
1607
|
end: number,
|
|
@@ -1482,17 +1609,18 @@ function appendActionSequenceSummary(
|
|
|
1482
1609
|
): void {
|
|
1483
1610
|
const low = Math.min(start, end);
|
|
1484
1611
|
const high = Math.max(start, end);
|
|
1485
|
-
const
|
|
1486
|
-
.filter((step) => step.step >= low && step.step <= high && step.action)
|
|
1612
|
+
const actionSteps = trajectory
|
|
1613
|
+
.filter((step) => step.step >= low && step.step <= high && step.action);
|
|
1614
|
+
const actions = actionSteps
|
|
1487
1615
|
.map((step) => `step ${step.step}: ${step.action}`);
|
|
1488
1616
|
if (actions.length === 0) {
|
|
1489
1617
|
return;
|
|
1490
1618
|
}
|
|
1491
|
-
lines.
|
|
1619
|
+
lines.pushWithSources(`${heading} ${actions.join("; ")}.`, actionSteps);
|
|
1492
1620
|
}
|
|
1493
1621
|
|
|
1494
1622
|
function appendResultingObservationLine(
|
|
1495
|
-
lines:
|
|
1623
|
+
lines: TrajectoryAnalysisLines,
|
|
1496
1624
|
trajectory: readonly LabeledTrajectoryStep[],
|
|
1497
1625
|
stepNumber: number,
|
|
1498
1626
|
): void {
|
|
@@ -1500,11 +1628,15 @@ function appendResultingObservationLine(
|
|
|
1500
1628
|
if (!step?.observation) {
|
|
1501
1629
|
return;
|
|
1502
1630
|
}
|
|
1503
|
-
lines.
|
|
1631
|
+
lines.pushWithSources(
|
|
1632
|
+
`Resulting observation after Action ${step.step}: ${oneLine(step.observation)}`,
|
|
1633
|
+
[],
|
|
1634
|
+
[step],
|
|
1635
|
+
);
|
|
1504
1636
|
}
|
|
1505
1637
|
|
|
1506
1638
|
function appendSpatialTrajectoryInferenceLines(
|
|
1507
|
-
lines:
|
|
1639
|
+
lines: TrajectoryAnalysisLines,
|
|
1508
1640
|
query: string,
|
|
1509
1641
|
trajectory: readonly LabeledTrajectoryStep[],
|
|
1510
1642
|
bounds: TrajectoryBounds,
|
|
@@ -1528,23 +1660,23 @@ function appendSpatialTrajectoryInferenceLines(
|
|
|
1528
1660
|
const window = spatialTrajectoryWindowForQuery(query, trajectory, bounds);
|
|
1529
1661
|
const counterfactualContactLines = collectCounterfactualContactLines(query, trajectory, normalized);
|
|
1530
1662
|
if (counterfactualContactLines.length > 0) {
|
|
1531
|
-
lines.
|
|
1663
|
+
lines.pushWithSources("Counterfactual contact cues:");
|
|
1532
1664
|
lines.push(...counterfactualContactLines);
|
|
1533
1665
|
}
|
|
1534
1666
|
|
|
1535
1667
|
const selfReversingLines = collectSelfReversingProgressLines(query, window, normalized);
|
|
1536
1668
|
if (selfReversingLines.length > 0) {
|
|
1537
|
-
lines.
|
|
1669
|
+
lines.pushWithSources("Self-reversing sequence cues:");
|
|
1538
1670
|
lines.push(...selfReversingLines);
|
|
1539
1671
|
}
|
|
1540
1672
|
const onlyEffectiveActionLines = collectOnlyEffectiveActionLines(window, normalized);
|
|
1541
1673
|
if (onlyEffectiveActionLines.length > 0) {
|
|
1542
|
-
lines.
|
|
1674
|
+
lines.pushWithSources("Only-effective action cues:");
|
|
1543
1675
|
lines.push(...onlyEffectiveActionLines);
|
|
1544
1676
|
}
|
|
1545
1677
|
const pushedPhraseGroupLines = collectPushedPhraseGroupShiftLines(query, window, normalized);
|
|
1546
1678
|
if (pushedPhraseGroupLines.length > 0) {
|
|
1547
|
-
lines.
|
|
1679
|
+
lines.pushWithSources("Pushed phrase-group shift cues:");
|
|
1548
1680
|
lines.push(...pushedPhraseGroupLines);
|
|
1549
1681
|
}
|
|
1550
1682
|
const suppressMovementProgressEvidence = onlyEffectiveActionLines.length > 0 ||
|
|
@@ -1558,7 +1690,7 @@ function appendSpatialTrajectoryInferenceLines(
|
|
|
1558
1690
|
? []
|
|
1559
1691
|
: collectActionMovementSummaryLines(query, window, bounds);
|
|
1560
1692
|
if (actionMovementLines.length > 0) {
|
|
1561
|
-
lines.
|
|
1693
|
+
lines.pushWithSources("Action movement summary cues:");
|
|
1562
1694
|
lines.push(...actionMovementLines);
|
|
1563
1695
|
}
|
|
1564
1696
|
|
|
@@ -1566,7 +1698,7 @@ function appendSpatialTrajectoryInferenceLines(
|
|
|
1566
1698
|
? []
|
|
1567
1699
|
: collectMovementDeltaLines(query, window);
|
|
1568
1700
|
if (movementLines.length > 0) {
|
|
1569
|
-
lines.
|
|
1701
|
+
lines.pushWithSources("Relative-position movement cues:");
|
|
1570
1702
|
lines.push(...movementLines);
|
|
1571
1703
|
}
|
|
1572
1704
|
|
|
@@ -1577,37 +1709,37 @@ function appendSpatialTrajectoryInferenceLines(
|
|
|
1577
1709
|
normalized,
|
|
1578
1710
|
);
|
|
1579
1711
|
if (objectAlignmentLines.length > 0) {
|
|
1580
|
-
lines.
|
|
1712
|
+
lines.pushWithSources("Object alignment cues:");
|
|
1581
1713
|
lines.push(...objectAlignmentLines);
|
|
1582
1714
|
}
|
|
1583
1715
|
|
|
1584
1716
|
const alternativeActionLines = collectAlternativeActionLines(query, trajectory);
|
|
1585
1717
|
if (alternativeActionLines.length > 0) {
|
|
1586
|
-
lines.
|
|
1718
|
+
lines.pushWithSources("Counterfactual action cues:");
|
|
1587
1719
|
lines.push(...alternativeActionLines);
|
|
1588
1720
|
}
|
|
1589
1721
|
|
|
1590
1722
|
const adjacentRuleSetupLines = collectAdjacentRuleSetupLines(window, normalized);
|
|
1591
1723
|
if (adjacentRuleSetupLines.length > 0) {
|
|
1592
|
-
lines.
|
|
1724
|
+
lines.pushWithSources("Adjacent rule-block setup cues:");
|
|
1593
1725
|
lines.push(...adjacentRuleSetupLines);
|
|
1594
1726
|
}
|
|
1595
1727
|
|
|
1596
1728
|
const blockedMoveLines = collectBlockedMoveLines(query, window, normalized);
|
|
1597
1729
|
if (blockedMoveLines.length > 0) {
|
|
1598
|
-
lines.
|
|
1730
|
+
lines.pushWithSources("Blocked-move cues:");
|
|
1599
1731
|
lines.push(...blockedMoveLines);
|
|
1600
1732
|
}
|
|
1601
1733
|
|
|
1602
1734
|
const failedEscapeLines = collectFailedEscapeLines(query, trajectory, normalized);
|
|
1603
1735
|
if (failedEscapeLines.length > 0) {
|
|
1604
|
-
lines.
|
|
1736
|
+
lines.pushWithSources("Failed-move escape cues:");
|
|
1605
1737
|
lines.push(...failedEscapeLines);
|
|
1606
1738
|
}
|
|
1607
1739
|
|
|
1608
1740
|
const sameRelativeTextPushLines = collectSameRelativeTextPushLines(window, normalized);
|
|
1609
1741
|
if (sameRelativeTextPushLines.length > 0) {
|
|
1610
|
-
lines.
|
|
1742
|
+
lines.pushWithSources("Same-relative text-push cues:");
|
|
1611
1743
|
lines.push(...sameRelativeTextPushLines);
|
|
1612
1744
|
}
|
|
1613
1745
|
|
|
@@ -1615,43 +1747,43 @@ function appendSpatialTrajectoryInferenceLines(
|
|
|
1615
1747
|
? []
|
|
1616
1748
|
: collectFailedContactBoundaryLines(window, normalized);
|
|
1617
1749
|
if (failedContactLines.length > 0) {
|
|
1618
|
-
lines.
|
|
1750
|
+
lines.pushWithSources("Failed-push boundary cues:");
|
|
1619
1751
|
lines.push(...failedContactLines);
|
|
1620
1752
|
}
|
|
1621
1753
|
|
|
1622
1754
|
const transformationLines = collectTemporaryRuleTransformationLines(window, normalized);
|
|
1623
1755
|
if (transformationLines.length > 0) {
|
|
1624
|
-
lines.
|
|
1756
|
+
lines.pushWithSources("Temporary transformation cues:");
|
|
1625
1757
|
lines.push(...transformationLines);
|
|
1626
1758
|
}
|
|
1627
1759
|
|
|
1628
1760
|
const wholeConfigurationShiftLines = collectWholeConfigurationShiftLines(window, normalized);
|
|
1629
1761
|
if (wholeConfigurationShiftLines.length > 0) {
|
|
1630
|
-
lines.
|
|
1762
|
+
lines.pushWithSources("Whole-configuration shift cues:");
|
|
1631
1763
|
lines.push(...wholeConfigurationShiftLines);
|
|
1632
1764
|
}
|
|
1633
1765
|
|
|
1634
1766
|
const ruleInterventionLines = collectRuleInterventionStrategyLines(window, normalized);
|
|
1635
1767
|
if (ruleInterventionLines.length > 0) {
|
|
1636
|
-
lines.
|
|
1768
|
+
lines.pushWithSources("Rule-intervention strategy cues:");
|
|
1637
1769
|
lines.push(...ruleInterventionLines);
|
|
1638
1770
|
}
|
|
1639
1771
|
|
|
1640
1772
|
const missingPushTargetLines = collectMissingPushTargetLines(window, normalized);
|
|
1641
1773
|
if (missingPushTargetLines.length > 0) {
|
|
1642
|
-
lines.
|
|
1774
|
+
lines.pushWithSources("Missing-interaction cues:");
|
|
1643
1775
|
lines.push(...missingPushTargetLines);
|
|
1644
1776
|
}
|
|
1645
1777
|
|
|
1646
1778
|
const rulePhraseAlignmentLines = collectRulePhraseAlignmentLines(window, normalized);
|
|
1647
1779
|
if (rulePhraseAlignmentLines.length > 0) {
|
|
1648
|
-
lines.
|
|
1780
|
+
lines.pushWithSources("Rule-phrase alignment cues:");
|
|
1649
1781
|
lines.push(...rulePhraseAlignmentLines);
|
|
1650
1782
|
}
|
|
1651
1783
|
|
|
1652
1784
|
const controlRuleInteractionLines = collectControlRuleInteractionLines(window, normalized);
|
|
1653
1785
|
if (controlRuleInteractionLines.length > 0) {
|
|
1654
|
-
lines.
|
|
1786
|
+
lines.pushWithSources("Control-rule interaction cues:");
|
|
1655
1787
|
lines.push(...controlRuleInteractionLines);
|
|
1656
1788
|
}
|
|
1657
1789
|
|
|
@@ -1659,13 +1791,13 @@ function appendSpatialTrajectoryInferenceLines(
|
|
|
1659
1791
|
? []
|
|
1660
1792
|
: collectRuleTextPositionLines(window, normalized);
|
|
1661
1793
|
if (ruleTextPositionLines.length > 0) {
|
|
1662
|
-
lines.
|
|
1794
|
+
lines.pushWithSources("Rule-text positioning cues:");
|
|
1663
1795
|
lines.push(...ruleTextPositionLines);
|
|
1664
1796
|
}
|
|
1665
1797
|
|
|
1666
1798
|
const ruleLines = collectRuleStateLines(window, normalized);
|
|
1667
1799
|
if (ruleLines.length > 0) {
|
|
1668
|
-
lines.
|
|
1800
|
+
lines.pushWithSources("Rule-state cues:");
|
|
1669
1801
|
lines.push(...ruleLines);
|
|
1670
1802
|
}
|
|
1671
1803
|
}
|
|
@@ -3458,12 +3590,15 @@ function uniqueLines(lines: readonly string[]): string[] {
|
|
|
3458
3590
|
}
|
|
3459
3591
|
|
|
3460
3592
|
function appendActionFrequencyLines(
|
|
3461
|
-
lines:
|
|
3593
|
+
lines: TrajectoryAnalysisLines,
|
|
3462
3594
|
trajectory: readonly LabeledTrajectoryStep[],
|
|
3463
3595
|
bounds: TrajectoryBounds,
|
|
3464
3596
|
): void {
|
|
3597
|
+
const actionSteps = boundedTrajectory(trajectory, bounds).filter(
|
|
3598
|
+
(step) => step.action !== undefined,
|
|
3599
|
+
);
|
|
3465
3600
|
const counts = new Map<string, number>();
|
|
3466
|
-
for (const step of
|
|
3601
|
+
for (const step of actionSteps) {
|
|
3467
3602
|
if (!step.action) continue;
|
|
3468
3603
|
const verb = normalizeActionVerb(step.action);
|
|
3469
3604
|
if (!verb) continue;
|
|
@@ -3475,15 +3610,16 @@ function appendActionFrequencyLines(
|
|
|
3475
3610
|
const frequencies = [...counts.entries()].sort((left, right) =>
|
|
3476
3611
|
right[1] - left[1] || left[0].localeCompare(right[0]),
|
|
3477
3612
|
);
|
|
3478
|
-
lines.
|
|
3613
|
+
lines.pushWithSources(
|
|
3479
3614
|
`Action frequency through requested window: ${frequencies
|
|
3480
3615
|
.map(([verb, count]) => `${verb}=${count}`)
|
|
3481
3616
|
.join(", ")}.`,
|
|
3617
|
+
actionSteps,
|
|
3482
3618
|
);
|
|
3483
3619
|
}
|
|
3484
3620
|
|
|
3485
3621
|
function appendInventoryChangeLines(
|
|
3486
|
-
lines:
|
|
3622
|
+
lines: TrajectoryAnalysisLines,
|
|
3487
3623
|
trajectory: readonly LabeledTrajectoryStep[],
|
|
3488
3624
|
bounds: TrajectoryBounds,
|
|
3489
3625
|
): void {
|
|
@@ -3499,16 +3635,24 @@ function appendInventoryChangeLines(
|
|
|
3499
3635
|
if (changes.length === 0) {
|
|
3500
3636
|
return;
|
|
3501
3637
|
}
|
|
3502
|
-
|
|
3638
|
+
const changeSteps = changes
|
|
3639
|
+
.map((change) => trajectory.find((step) => step.step === change.step))
|
|
3640
|
+
.filter((step): step is LabeledTrajectoryStep => step !== undefined);
|
|
3641
|
+
lines.pushWithSources("Inventory changes from action transcript:");
|
|
3503
3642
|
if (changes.length > 5) {
|
|
3504
|
-
lines.
|
|
3643
|
+
lines.pushWithSources(
|
|
3505
3644
|
`First five inventory changes: ${formatInventoryChangeSummary(changes.slice(0, 5))}.`,
|
|
3645
|
+
changeSteps.slice(0, 5),
|
|
3506
3646
|
);
|
|
3507
|
-
lines.
|
|
3647
|
+
lines.pushWithSources(
|
|
3508
3648
|
`Complete inventory changes: ${formatInventoryChangeSummary(changes)}.`,
|
|
3649
|
+
changeSteps,
|
|
3509
3650
|
);
|
|
3510
3651
|
}
|
|
3511
3652
|
for (const change of changes) {
|
|
3653
|
+
// The rendered change is stateful: whether a place/move removes an item
|
|
3654
|
+
// depends on earlier take actions in `held`. Until the parser returns that
|
|
3655
|
+
// full dependency chain, do not publish a misleading partial row receipt.
|
|
3512
3656
|
lines.push(`[Action ${change.step}]: ${change.action} => ${change.change}`);
|
|
3513
3657
|
}
|
|
3514
3658
|
}
|
|
@@ -3535,7 +3679,7 @@ function summarizeInventoryChange(change: string): string {
|
|
|
3535
3679
|
}
|
|
3536
3680
|
|
|
3537
3681
|
function appendContainerStateChangeLines(
|
|
3538
|
-
lines:
|
|
3682
|
+
lines: TrajectoryAnalysisLines,
|
|
3539
3683
|
trajectory: readonly LabeledTrajectoryStep[],
|
|
3540
3684
|
bounds: TrajectoryBounds,
|
|
3541
3685
|
): void {
|
|
@@ -3543,14 +3687,18 @@ function appendContainerStateChangeLines(
|
|
|
3543
3687
|
if (changes.length === 0) {
|
|
3544
3688
|
return;
|
|
3545
3689
|
}
|
|
3546
|
-
lines.
|
|
3690
|
+
lines.pushWithSources("Container open/close state changes:");
|
|
3547
3691
|
for (const change of changes) {
|
|
3548
|
-
|
|
3692
|
+
const step = trajectory.find((candidate) => candidate.step === change.step);
|
|
3693
|
+
lines.pushWithSources(
|
|
3694
|
+
`[Action ${change.step}]: ${change.action} => ${change.entity} ${change.state}`,
|
|
3695
|
+
step ? [step] : [],
|
|
3696
|
+
);
|
|
3549
3697
|
}
|
|
3550
3698
|
}
|
|
3551
3699
|
|
|
3552
3700
|
function appendEntityTimelineLines(
|
|
3553
|
-
lines:
|
|
3701
|
+
lines: TrajectoryAnalysisLines,
|
|
3554
3702
|
trajectory: readonly LabeledTrajectoryStep[],
|
|
3555
3703
|
bounds: TrajectoryBounds,
|
|
3556
3704
|
entities: readonly string[],
|
|
@@ -3586,28 +3734,37 @@ function appendEntityTimelineLines(
|
|
|
3586
3734
|
continue;
|
|
3587
3735
|
}
|
|
3588
3736
|
|
|
3589
|
-
lines.
|
|
3737
|
+
lines.pushWithSources(`Timeline for ${entity}:`);
|
|
3590
3738
|
for (const step of directActions) {
|
|
3591
|
-
lines.
|
|
3739
|
+
lines.pushWithSources(`[Action ${step.step}]: ${step.action}`, [step]);
|
|
3592
3740
|
}
|
|
3593
3741
|
if (objectTransfers.length > 0) {
|
|
3594
|
-
lines.
|
|
3742
|
+
lines.pushWithSources(`Object transfers involving ${entity}:`);
|
|
3595
3743
|
for (const transfer of objectTransfers) {
|
|
3596
|
-
|
|
3744
|
+
const step = trajectory.find((candidate) => candidate.step === transfer.step);
|
|
3745
|
+
lines.pushWithSources(
|
|
3746
|
+
`[Action ${transfer.step}]: ${transfer.action} => ${formatContainerTransfer(transfer)}`,
|
|
3747
|
+
step ? [step] : [],
|
|
3748
|
+
);
|
|
3597
3749
|
}
|
|
3598
3750
|
}
|
|
3599
3751
|
const inferredLocation = inferEntityLocation(trajectory, bounds, entity);
|
|
3600
3752
|
if (inferredLocation) {
|
|
3601
|
-
lines.
|
|
3602
|
-
`Inferred ${entity} location at step ${bounds.end}: ${inferredLocation}.`,
|
|
3753
|
+
lines.pushWithSources(
|
|
3754
|
+
`Inferred ${entity} location at step ${bounds.end}: ${inferredLocation.location}.`,
|
|
3755
|
+
[inferredLocation.sourceStep],
|
|
3603
3756
|
);
|
|
3604
3757
|
}
|
|
3605
3758
|
if (stateChanges.length > 0) {
|
|
3606
3759
|
const latest = stateChanges[stateChanges.length - 1]!;
|
|
3607
|
-
|
|
3760
|
+
const stateSteps = stateChanges
|
|
3761
|
+
.map((change) => trajectory.find((step) => step.step === change.step))
|
|
3762
|
+
.filter((step): step is LabeledTrajectoryStep => step !== undefined);
|
|
3763
|
+
lines.pushWithSources(
|
|
3608
3764
|
`Latest ${entity} state at step ${bounds.end}: ${latest.state}; state changes: ${stateChanges
|
|
3609
3765
|
.map((change) => `${change.step}:${change.state}`)
|
|
3610
3766
|
.join(", ")}.`,
|
|
3767
|
+
stateSteps,
|
|
3611
3768
|
);
|
|
3612
3769
|
}
|
|
3613
3770
|
}
|
|
@@ -3958,15 +4115,17 @@ function inferEntityLocation(
|
|
|
3958
4115
|
trajectory: readonly LabeledTrajectoryStep[],
|
|
3959
4116
|
bounds: TrajectoryBounds,
|
|
3960
4117
|
entity: string,
|
|
3961
|
-
): string | undefined {
|
|
4118
|
+
): { location: string; sourceStep: LabeledTrajectoryStep } | undefined {
|
|
3962
4119
|
const normalizedEntity = normalizeEntity(entity);
|
|
3963
4120
|
let location: string | undefined;
|
|
4121
|
+
let sourceStep: LabeledTrajectoryStep | undefined;
|
|
3964
4122
|
for (const step of boundedTrajectory(trajectory, bounds)) {
|
|
3965
4123
|
if (!step.action) continue;
|
|
3966
4124
|
const action = step.action.trim();
|
|
3967
4125
|
const take = /^take\s+(.+?)\s+from\s+(.+)$/i.exec(action);
|
|
3968
4126
|
if (take && normalizeEntity(take[1]!) === normalizedEntity) {
|
|
3969
4127
|
location = "inventory";
|
|
4128
|
+
sourceStep = step;
|
|
3970
4129
|
continue;
|
|
3971
4130
|
}
|
|
3972
4131
|
const move = /^(?:move|put|place|insert)\s+(.+?)\s+(?:to|in|into|on)\s+(.+)$/i.exec(
|
|
@@ -3974,9 +4133,10 @@ function inferEntityLocation(
|
|
|
3974
4133
|
);
|
|
3975
4134
|
if (move && normalizeEntity(move[1]!) === normalizedEntity) {
|
|
3976
4135
|
location = move[2]!.trim();
|
|
4136
|
+
sourceStep = step;
|
|
3977
4137
|
}
|
|
3978
4138
|
}
|
|
3979
|
-
return location;
|
|
4139
|
+
return location && sourceStep ? { location, sourceStep } : undefined;
|
|
3980
4140
|
}
|
|
3981
4141
|
|
|
3982
4142
|
function normalizeActionVerb(action: string): string | undefined {
|
|
@@ -4020,10 +4180,15 @@ export function normalizeTurnExpansionEnd(stats: {
|
|
|
4020
4180
|
return Math.max(messageCountEnd, Math.floor(stats.maxTurnIndex));
|
|
4021
4181
|
}
|
|
4022
4182
|
|
|
4023
|
-
function truncateTrajectoryAnalysisLines(
|
|
4024
|
-
|
|
4183
|
+
function truncateTrajectoryAnalysisLines(
|
|
4184
|
+
lines: TrajectoryAnalysisLines,
|
|
4185
|
+
maxChars: number,
|
|
4186
|
+
): SelectedTrajectoryLine[] {
|
|
4187
|
+
const result: SelectedTrajectoryLine[] = [];
|
|
4025
4188
|
let used = 0;
|
|
4026
|
-
|
|
4189
|
+
const limit = Math.min(lines.length, TRAJECTORY_ANALYSIS_MAX_LINES);
|
|
4190
|
+
for (let index = 0; index < limit; index += 1) {
|
|
4191
|
+
const line = lines[index]!;
|
|
4027
4192
|
const separator = result.length === 0 ? 0 : 1;
|
|
4028
4193
|
const remaining = maxChars - used - separator;
|
|
4029
4194
|
if (remaining <= 0) {
|
|
@@ -4037,7 +4202,7 @@ function truncateTrajectoryAnalysisLines(lines: string[], maxChars: number): str
|
|
|
4037
4202
|
if (clipped.length === 0) {
|
|
4038
4203
|
break;
|
|
4039
4204
|
}
|
|
4040
|
-
result.push(clipped);
|
|
4205
|
+
result.push({ text: clipped, ...lines.sourceAt(index) });
|
|
4041
4206
|
used += separator + clipped.length;
|
|
4042
4207
|
}
|
|
4043
4208
|
return result;
|
|
@@ -4538,21 +4703,21 @@ function normalizeTrajectoryQuery(value: string): string {
|
|
|
4538
4703
|
}
|
|
4539
4704
|
|
|
4540
4705
|
function appendExpandedEvidence(
|
|
4541
|
-
evidenceItems:
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4706
|
+
evidenceItems: ExplicitCueEvidenceItem[],
|
|
4707
|
+
seenTurns: Set<string>,
|
|
4708
|
+
sessionId: string,
|
|
4709
|
+
expanded: Array<{
|
|
4710
|
+
id?: number;
|
|
4711
|
+
session_id?: string;
|
|
4712
|
+
turn_index: number;
|
|
4545
4713
|
role: string;
|
|
4546
4714
|
content: string;
|
|
4547
4715
|
}>,
|
|
4548
|
-
seenTurns: Set<string>,
|
|
4549
|
-
sessionId: string,
|
|
4550
|
-
expanded: Array<{ turn_index: number; role: string; content: string }>,
|
|
4551
4716
|
): void {
|
|
4552
4717
|
for (const message of expanded) {
|
|
4553
4718
|
appendEvidenceItem(evidenceItems, seenTurns, {
|
|
4554
|
-
|
|
4555
|
-
sessionId,
|
|
4719
|
+
...lcmEvidenceIdentity(message, sessionId),
|
|
4720
|
+
sessionId: message.session_id ?? sessionId,
|
|
4556
4721
|
turnIndex: message.turn_index,
|
|
4557
4722
|
role: message.role,
|
|
4558
4723
|
content: message.content,
|
|
@@ -4689,14 +4854,7 @@ async function collectNamedMeetingFactEvidence(options: {
|
|
|
4689
4854
|
sessionId?: string;
|
|
4690
4855
|
query: string;
|
|
4691
4856
|
maxReferences: number;
|
|
4692
|
-
evidenceItems:
|
|
4693
|
-
id: string;
|
|
4694
|
-
sessionId: string;
|
|
4695
|
-
turnIndex: number;
|
|
4696
|
-
role: string;
|
|
4697
|
-
content: string;
|
|
4698
|
-
score?: number;
|
|
4699
|
-
}>;
|
|
4857
|
+
evidenceItems: ExplicitCueEvidenceItem[];
|
|
4700
4858
|
seenTurns: Set<string>;
|
|
4701
4859
|
}): Promise<void> {
|
|
4702
4860
|
const cues = collectMeetingFactCues(options.query)
|
|
@@ -4712,7 +4870,7 @@ async function collectNamedMeetingFactEvidence(options: {
|
|
|
4712
4870
|
for (const result of results) {
|
|
4713
4871
|
if (!isNamedMeetingFactEvidence(result.content, options.query)) continue;
|
|
4714
4872
|
appendEvidenceItem(options.evidenceItems, options.seenTurns, {
|
|
4715
|
-
|
|
4873
|
+
...lcmEvidenceIdentity(result, result.session_id),
|
|
4716
4874
|
sessionId: result.session_id,
|
|
4717
4875
|
turnIndex: result.turn_index,
|
|
4718
4876
|
role: result.role,
|