footprintjs 6.1.0 → 6.1.2
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/AGENTS.md +60 -49
- package/CLAUDE.md +33 -26
- package/README.md +20 -1
- package/dist/esm/lib/detach/types.js +1 -1
- package/dist/esm/lib/engine/narrative/recorders/SeparateNarrativeFlowRecorder.js +3 -3
- package/dist/esm/lib/recorder/BoundaryStateTracker.js +3 -6
- package/dist/esm/lib/recorder/QualityRecorder.js +5 -5
- package/dist/esm/lib/recorder/SequenceStore.js +2 -2
- package/dist/esm/lib/runner/FlowChartExecutor.js +5 -5
- package/dist/esm/lib/runner/RunContext.js +14 -30
- package/dist/esm/package.json +1 -0
- package/dist/esm/trace.js +16 -7
- package/dist/lib/detach/types.js +1 -1
- package/dist/lib/engine/narrative/recorders/SeparateNarrativeFlowRecorder.js +3 -3
- package/dist/lib/recorder/BoundaryStateTracker.js +3 -6
- package/dist/lib/recorder/QualityRecorder.js +5 -5
- package/dist/lib/recorder/SequenceStore.js +2 -2
- package/dist/lib/runner/FlowChartExecutor.js +5 -5
- package/dist/lib/runner/RunContext.js +14 -30
- package/dist/trace.js +16 -7
- package/dist/types/lib/detach/types.d.ts +1 -1
- package/dist/types/lib/engine/narrative/recorders/SeparateNarrativeFlowRecorder.d.ts +2 -2
- package/dist/types/lib/recorder/BoundaryStateTracker.d.ts +2 -5
- package/dist/types/lib/recorder/QualityRecorder.d.ts +4 -4
- package/dist/types/lib/recorder/SequenceStore.d.ts +1 -1
- package/dist/types/lib/runner/FlowChartExecutor.d.ts +4 -4
- package/dist/types/lib/runner/RunContext.d.ts +9 -4
- package/dist/types/trace.d.ts +15 -6
- package/package.json +3 -2
package/dist/trace.js
CHANGED
|
@@ -6,19 +6,28 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @example
|
|
8
8
|
* ```typescript
|
|
9
|
-
* import { parseRuntimeStageId, findLastWriter,
|
|
9
|
+
* import { parseRuntimeStageId, findLastWriter, KeyedStore, SequenceStore } from 'footprintjs/trace';
|
|
10
10
|
*
|
|
11
11
|
* // Parse a runtimeStageId
|
|
12
12
|
* const { stageId, executionIndex } = parseRuntimeStageId('call-llm#5');
|
|
13
13
|
*
|
|
14
|
-
* // Backtrack: who wrote 'systemPrompt' before
|
|
14
|
+
* // Backtrack: who wrote 'systemPrompt' before commit at idx 8?
|
|
15
15
|
* const writer = findLastWriter(commitLog, 'systemPrompt', 8);
|
|
16
16
|
*
|
|
17
|
-
* //
|
|
18
|
-
*
|
|
17
|
+
* // v5 primary API: compose a Store as a field (one purpose per recorder).
|
|
18
|
+
* // KeyedStore<T> — 1:1 (one entry per step)
|
|
19
|
+
* class MyRecorder {
|
|
20
|
+
* readonly id = 'my-recorder';
|
|
21
|
+
* private store = new KeyedStore<MyEntry>();
|
|
22
|
+
* onWrite(e) { this.store.set(e.runtimeStageId, { ... }); }
|
|
23
|
+
* }
|
|
19
24
|
*
|
|
20
|
-
* //
|
|
21
|
-
* class AuditRecorder
|
|
25
|
+
* // SequenceStore<T> — 1:N (multiple entries per step, ordering matters)
|
|
26
|
+
* class AuditRecorder {
|
|
27
|
+
* readonly id = 'audit';
|
|
28
|
+
* private store = new SequenceStore<AuditEntry>();
|
|
29
|
+
* onRead(e) { this.store.push({ runtimeStageId: e.runtimeStageId, ... }); }
|
|
30
|
+
* }
|
|
22
31
|
* ```
|
|
23
32
|
*/
|
|
24
33
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -78,4 +87,4 @@ Object.defineProperty(exports, "QualityRecorder", { enumerable: true, get: funct
|
|
|
78
87
|
var qualityTrace_js_1 = require("./lib/recorder/qualityTrace.js");
|
|
79
88
|
Object.defineProperty(exports, "formatQualityTrace", { enumerable: true, get: function () { return qualityTrace_js_1.formatQualityTrace; } });
|
|
80
89
|
Object.defineProperty(exports, "qualityTrace", { enumerable: true, get: function () { return qualityTrace_js_1.qualityTrace; } });
|
|
81
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
90
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdHJhY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E4Qkc7OztBQUlILG9FQUt3QztBQUp0Qyx3SEFBQSxtQkFBbUIsT0FBQTtBQUNuQiwySEFBQSxzQkFBc0IsT0FBQTtBQUN0Qix3SEFBQSxtQkFBbUIsT0FBQTtBQUNuQixpSEFBQSxZQUFZLE9BQUE7QUFNZCxzRUFBa0U7QUFBekQscUhBQUEsZUFBZSxPQUFBO0FBRXhCLHdEQUF3RDtBQUN4RCxvRUFBeUY7QUFBaEYsK0dBQUEsVUFBVSxPQUFBO0FBQUUsZ0hBQUEsV0FBVyxPQUFBO0FBQUUsbUhBQUEsY0FBYyxPQUFBO0FBSWhELDBEQUE2RjtBQUFwRiwyR0FBQSxXQUFXLE9BQUE7QUFBRSxnSEFBQSxnQkFBZ0IsT0FBQTtBQUFFLGlIQUFBLGlCQUFpQixPQUFBO0FBRXpELG1FQUFtRTtBQUNuRSxpRUFBaUU7QUFDakUsaUVBQWlFO0FBQ2pFLDRDQUE0QztBQUM1Qyw4RUFBMEU7QUFBakUsMkhBQUEsa0JBQWtCLE9BQUE7QUFDM0IsOERBQTBEO0FBQWpELDJHQUFBLFVBQVUsT0FBQTtBQUNuQixvRUFBZ0U7QUFBdkQsaUhBQUEsYUFBYSxPQUFBO0FBU3RCLDBFQUFzRTtBQUE3RCx1SEFBQSxnQkFBZ0IsT0FBQTtBQUV6QixvRUFBb0U7QUFDcEUsK0RBQStEO0FBQy9ELGdFQUFnRTtBQUNoRSx3REFBd0Q7QUFDeEQseURBQXlEO0FBQ3pELG9FQUFnRTtBQUF2RCxpSEFBQSxhQUFhLE9BQUE7QUFFdEIsb0ZBQW9GO0FBQ3BGLDBFQUFzRTtBQUE3RCx1SEFBQSxnQkFBZ0IsT0FBQTtBQUV6Qix1RUFBdUU7QUFDdkUsNkVBQTZFO0FBQzdFLGtGQUE4RTtBQUFyRSwrSEFBQSxvQkFBb0IsT0FBQTtBQVU3QiwwRUFBd0Y7QUFBL0UsdUhBQUEsZ0JBQWdCLE9BQUE7QUFBRSx1SEFBQSxnQkFBZ0IsT0FBQTtBQUszQyxvRUFBdUg7QUFBOUcsaUhBQUEsYUFBYSxPQUFBO0FBQUUsaUhBQUEsYUFBYSxPQUFBO0FBQUUseUhBQUEscUJBQXFCLE9BQUE7QUFBRSxtSEFBQSxlQUFlLE9BQUE7QUFJN0Usd0VBQW9FO0FBQTNELHFIQUFBLGVBQWUsT0FBQTtBQUl4QixrRUFBa0Y7QUFBekUscUhBQUEsa0JBQWtCLE9BQUE7QUFBRSwrR0FBQSxZQUFZLE9BQUEiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIGZvb3RwcmludGpzL3RyYWNlIOKAlCBFeGVjdXRpb24gdHJhY2luZywgZGVidWdnaW5nLCBhbmQgYmFja3RyYWNraW5nIHV0aWxpdGllcy5cbiAqXG4gKiBSdW50aW1lIHN0YWdlIElEcywgY29tbWl0IGxvZyBxdWVyaWVzLCBhbmQgcmVjb3JkZXIgYmFzZSBjbGFzc2VzLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQgeyBwYXJzZVJ1bnRpbWVTdGFnZUlkLCBmaW5kTGFzdFdyaXRlciwgS2V5ZWRTdG9yZSwgU2VxdWVuY2VTdG9yZSB9IGZyb20gJ2Zvb3RwcmludGpzL3RyYWNlJztcbiAqXG4gKiAvLyBQYXJzZSBhIHJ1bnRpbWVTdGFnZUlkXG4gKiBjb25zdCB7IHN0YWdlSWQsIGV4ZWN1dGlvbkluZGV4IH0gPSBwYXJzZVJ1bnRpbWVTdGFnZUlkKCdjYWxsLWxsbSM1Jyk7XG4gKlxuICogLy8gQmFja3RyYWNrOiB3aG8gd3JvdGUgJ3N5c3RlbVByb21wdCcgYmVmb3JlIGNvbW1pdCBhdCBpZHggOD9cbiAqIGNvbnN0IHdyaXRlciA9IGZpbmRMYXN0V3JpdGVyKGNvbW1pdExvZywgJ3N5c3RlbVByb21wdCcsIDgpO1xuICpcbiAqIC8vIHY1IHByaW1hcnkgQVBJOiBjb21wb3NlIGEgU3RvcmUgYXMgYSBmaWVsZCAob25lIHB1cnBvc2UgcGVyIHJlY29yZGVyKS5cbiAqIC8vIEtleWVkU3RvcmU8VD4g4oCUIDE6MSAob25lIGVudHJ5IHBlciBzdGVwKVxuICogY2xhc3MgTXlSZWNvcmRlciB7XG4gKiAgIHJlYWRvbmx5IGlkID0gJ215LXJlY29yZGVyJztcbiAqICAgcHJpdmF0ZSBzdG9yZSA9IG5ldyBLZXllZFN0b3JlPE15RW50cnk+KCk7XG4gKiAgIG9uV3JpdGUoZSkgeyB0aGlzLnN0b3JlLnNldChlLnJ1bnRpbWVTdGFnZUlkLCB7IC4uLiB9KTsgfVxuICogfVxuICpcbiAqIC8vIFNlcXVlbmNlU3RvcmU8VD4g4oCUIDE6TiAobXVsdGlwbGUgZW50cmllcyBwZXIgc3RlcCwgb3JkZXJpbmcgbWF0dGVycylcbiAqIGNsYXNzIEF1ZGl0UmVjb3JkZXIge1xuICogICByZWFkb25seSBpZCA9ICdhdWRpdCc7XG4gKiAgIHByaXZhdGUgc3RvcmUgPSBuZXcgU2VxdWVuY2VTdG9yZTxBdWRpdEVudHJ5PigpO1xuICogICBvblJlYWQoZSkgeyB0aGlzLnN0b3JlLnB1c2goeyBydW50aW1lU3RhZ2VJZDogZS5ydW50aW1lU3RhZ2VJZCwgLi4uIH0pOyB9XG4gKiB9XG4gKiBgYGBcbiAqL1xuXG4vLyBSdW50aW1lIHN0YWdlIElEIOKAlCB1bmlxdWUgZXhlY3V0aW9uIHN0ZXAgaWRlbnRpZmllcnNcbmV4cG9ydCB0eXBlIHsgRXhlY3V0aW9uQ291bnRlciB9IGZyb20gJy4vbGliL2VuZ2luZS9ydW50aW1lU3RhZ2VJZC5qcyc7XG5leHBvcnQge1xuICBidWlsZFJ1bnRpbWVTdGFnZUlkLFxuICBjcmVhdGVFeGVjdXRpb25Db3VudGVyLFxuICBwYXJzZVJ1bnRpbWVTdGFnZUlkLFxuICBzcGxpdFN0YWdlSWQsXG59IGZyb20gJy4vbGliL2VuZ2luZS9ydW50aW1lU3RhZ2VJZC5qcyc7XG5cbi8vIHdhbGtTdWJmbG93U3BlYyDigJQgZmxhdCBvcmRlcmVkIHRyYXZlcnNhbCBvZiBhIHN1YmZsb3cncyBzdHJ1Y3R1cmVcbi8vIChjb25zdW1lIHZpYSBTdHJ1Y3R1cmVSZWNvcmRlci5vblN1YmZsb3dNb3VudGVkJ3Mgc3ViZmxvd1NwZWMgcGF5bG9hZClcbmV4cG9ydCB0eXBlIHsgV2Fsa2VySXRlbSwgV2Fsa2VyT3B0aW9ucyB9IGZyb20gJy4vbGliL2VuZ2luZS93YWxrU3ViZmxvd1NwZWMuanMnO1xuZXhwb3J0IHsgd2Fsa1N1YmZsb3dTcGVjIH0gZnJvbSAnLi9saWIvZW5naW5lL3dhbGtTdWJmbG93U3BlYy5qcyc7XG5cbi8vIENvbW1pdCBsb2cgcXVlcmllcyDigJQgdHlwZWQgdXRpbGl0aWVzIGZvciBiYWNrdHJhY2tpbmdcbmV4cG9ydCB7IGZpbmRDb21taXQsIGZpbmRDb21taXRzLCBmaW5kTGFzdFdyaXRlciB9IGZyb20gJy4vbGliL21lbW9yeS9jb21taXRMb2dVdGlscy5qcyc7XG5cbi8vIENhdXNhbCBjaGFpbiDigJQgYmFja3dhcmQgcHJvZ3JhbSBzbGljaW5nIG9uIGNvbW1pdCBsb2cgKERBRylcbmV4cG9ydCB0eXBlIHsgQ2F1c2FsQ2hhaW5PcHRpb25zLCBDYXVzYWxOb2RlLCBLZXlzUmVhZExvb2t1cCB9IGZyb20gJy4vbGliL21lbW9yeS9iYWNrdHJhY2suanMnO1xuZXhwb3J0IHsgY2F1c2FsQ2hhaW4sIGZsYXR0ZW5DYXVzYWxEQUcsIGZvcm1hdENhdXNhbENoYWluIH0gZnJvbSAnLi9saWIvbWVtb3J5L2JhY2t0cmFjay5qcyc7XG5cbi8vIOKUgOKUgCB2NSBTdG9yZXMgKGNvbmNyZXRlLCBjb21wb3NhYmxlIOKAlCBwcmltYXJ5IHJlY29yZGVyIEFQSSkg4pSA4pSA4pSA4pSA4pSAXG4vLyBDb21wb3NlIHRoZXNlIHZpYSBgbmV3IFN0b3JlPFQ+KClgIGFzIGEgZmllbGQgb24geW91ciByZWNvcmRlclxuLy8gY2xhc3MuIE9uZSBwdXJwb3NlIHBlciByZWNvcmRlcjogc3RvcmVzIGFyZSBzdG9yYWdlOyByZWNvcmRlcnNcbi8vIGFyZSBldmVudC1ob29rIGludGVyZmFjZSBpbXBsZW1lbnRhdGlvbnMuXG5leHBvcnQgeyBCb3VuZGFyeVN0YXRlU3RvcmUgfSBmcm9tICcuL2xpYi9yZWNvcmRlci9Cb3VuZGFyeVN0YXRlU3RvcmUuanMnO1xuZXhwb3J0IHsgS2V5ZWRTdG9yZSB9IGZyb20gJy4vbGliL3JlY29yZGVyL0tleWVkU3RvcmUuanMnO1xuZXhwb3J0IHsgU2VxdWVuY2VTdG9yZSB9IGZyb20gJy4vbGliL3JlY29yZGVyL1NlcXVlbmNlU3RvcmUuanMnO1xuXG4vLyDilIDilIAgdjUuMSBDb21taXQgZ3JvdXBpbmcgcHJpbWl0aXZlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuLy8gSW50ZXJ2YWwgaW5kZXggb3ZlciBjb21taXQgaW5kaWNlcy4gQnVpbHQgaW5jcmVtZW50YWxseSBkdXJpbmdcbi8vIHRyYXZlcnNhbDogb3BlbigpIG9uIGJvdW5kYXJ5IGVudHJ5LCBjbG9zZSgpIG9uIGV4aXQuIFF1ZXJ5IGF0IGFueVxuLy8gY29tbWl0IHBvc2l0aW9uIHdpdGggZW5jbG9zaW5nKCkvb3ZlcmxhcHBpbmcoKS4gR2VuZXJpYyBvdmVyIFRMYWJlbFxuLy8g4oCUIGZvb3RwcmludGpzIG93bnMgWkVSTyBrbm93bGVkZ2Ugb2Ygd2hhdCBjb25zdW1lcnMgdXNlIGFzIGxhYmVscy5cbi8vIFNlZSBkb2NzL2Rlc2lnbi9jb21taXQtcmFuZ2UtaW5kZXgubWQgZm9yIHRoZSBmdWxsIGNvbnRyYWN0LlxuZXhwb3J0IHR5cGUgeyBSYW5nZUVudHJ5LCBSYW5nZVRva2VuIH0gZnJvbSAnLi9saWIvcmVjb3JkZXIvQ29tbWl0UmFuZ2VJbmRleC5qcyc7XG5leHBvcnQgeyBDb21taXRSYW5nZUluZGV4IH0gZnJvbSAnLi9saWIvcmVjb3JkZXIvQ29tbWl0UmFuZ2VJbmRleC5qcyc7XG5cbi8vIOKUgOKUgCBBYnN0cmFjdCBiYXNlcyAoREVQUkVDQVRFRCBpbiB2NSDigJQgc2xhdGVkIGZvciByZW1vdmFsKSDilIDilIDilIDilIDilIDilIDilIBcbi8vIEtlcHQgZHVyaW5nIHRoZSB2NSBtaWdyYXRpb24gd2luZG93IGZvciBkb3duc3RyZWFtIGNvbnN1bWVyc1xuLy8gKGFnZW50Zm9vdHByaW50LCBhZ2VudGZvb3RwcmludC1sZW5zLCBldGMuKSB0aGF0IHN0aWxsIGV4dGVuZFxuLy8gdGhlbS4gTWlncmF0ZSB0byB0aGUgY29ycmVzcG9uZGluZyBTdG9yZSBjbGFzcyBhYm92ZS5cbi8vIEtleWVkUmVjb3JkZXIg4oCUIGJhc2UgY2xhc3MgZm9yIDE6MSBNYXAtYmFzZWQgcmVjb3JkZXJzXG5leHBvcnQgeyBLZXllZFJlY29yZGVyIH0gZnJvbSAnLi9saWIvcmVjb3JkZXIvS2V5ZWRSZWNvcmRlci5qcyc7XG5cbi8vIFNlcXVlbmNlUmVjb3JkZXIg4oCUIGJhc2UgY2xhc3MgZm9yIDE6TiBvcmRlcmVkIHNlcXVlbmNlIHJlY29yZGVycyB3aXRoIGtleWVkIGluZGV4XG5leHBvcnQgeyBTZXF1ZW5jZVJlY29yZGVyIH0gZnJvbSAnLi9saWIvcmVjb3JkZXIvU2VxdWVuY2VSZWNvcmRlci5qcyc7XG5cbi8vIEJvdW5kYXJ5U3RhdGVUcmFja2VyIOKAlCBiYXNlIGNsYXNzIGZvciB0cmFuc2llbnQgYnJhY2tldC1zY29wZWQgc3RhdGVcbi8vIChsaXZlIHN0YXRlIERVUklORyBhIG1hdGNoZWQgW3N0YXJ0LCBzdG9wXSBldmVudCBpbnRlcnZhbDsgY2xlYXJzIG9uIHN0b3ApXG5leHBvcnQgeyBCb3VuZGFyeVN0YXRlVHJhY2tlciB9IGZyb20gJy4vbGliL3JlY29yZGVyL0JvdW5kYXJ5U3RhdGVUcmFja2VyLmpzJztcblxuLy8gVG9wb2xvZ3lSZWNvcmRlciDigJQgY29tcG9zaXRpb24gZ3JhcGggYWNjdW11bGF0b3IgKHN1YmZsb3dzICsgY29udHJvbC1mbG93IGVkZ2VzKVxuZXhwb3J0IHR5cGUge1xuICBUb3BvbG9neSxcbiAgVG9wb2xvZ3lFZGdlLFxuICBUb3BvbG9neUluY29taW5nS2luZCxcbiAgVG9wb2xvZ3lOb2RlLFxuICBUb3BvbG9neVJlY29yZGVyT3B0aW9ucyxcbn0gZnJvbSAnLi9saWIvcmVjb3JkZXIvVG9wb2xvZ3lSZWNvcmRlci5qcyc7XG5leHBvcnQgeyBUb3BvbG9neVJlY29yZGVyLCB0b3BvbG9neVJlY29yZGVyIH0gZnJvbSAnLi9saWIvcmVjb3JkZXIvVG9wb2xvZ3lSZWNvcmRlci5qcyc7XG5cbi8vIEluT3V0UmVjb3JkZXIg4oCUIGNoYXJ0IGluL291dCBzdHJlYW0gKGVudHJ5L2V4aXQgcGFpcnMgYXQgZXZlcnkgY2hhcnQgYm91bmRhcnksXG4vLyBpbmNsdWRpbmcgdGhlIHRvcC1sZXZlbCBydW4gYW5kIGV2ZXJ5IHN1YmZsb3cpXG5leHBvcnQgdHlwZSB7IEluT3V0RW50cnksIEluT3V0UGhhc2UsIEluT3V0UmVjb3JkZXJPcHRpb25zIH0gZnJvbSAnLi9saWIvcmVjb3JkZXIvSW5PdXRSZWNvcmRlci5qcyc7XG5leHBvcnQgeyBJbk91dFJlY29yZGVyLCBpbk91dFJlY29yZGVyLCBST09UX1JVTlRJTUVfU1RBR0VfSUQsIFJPT1RfU1VCRkxPV19JRCB9IGZyb20gJy4vbGliL3JlY29yZGVyL0luT3V0UmVjb3JkZXIuanMnO1xuXG4vLyBRdWFsaXR5UmVjb3JkZXIg4oCUIHBlci1zdGVwIHF1YWxpdHkgc2NvcmluZyB3aXRoIGJhY2t0cmFja2luZ1xuZXhwb3J0IHR5cGUgeyBRdWFsaXR5RW50cnksIFF1YWxpdHlSZWNvcmRlck9wdGlvbnMsIFF1YWxpdHlTY29yaW5nRm4gfSBmcm9tICcuL2xpYi9yZWNvcmRlci9RdWFsaXR5UmVjb3JkZXIuanMnO1xuZXhwb3J0IHsgUXVhbGl0eVJlY29yZGVyIH0gZnJvbSAnLi9saWIvcmVjb3JkZXIvUXVhbGl0eVJlY29yZGVyLmpzJztcblxuLy8gcXVhbGl0eVRyYWNlIOKAlCBRdWFsaXR5IFN0YWNrIFRyYWNlIChiYWNrdHJhY2sgZnJvbSBsb3ctc2NvcmluZyBzdGVwcylcbmV4cG9ydCB0eXBlIHsgUXVhbGl0eUZyYW1lLCBRdWFsaXR5U3RhY2tUcmFjZSB9IGZyb20gJy4vbGliL3JlY29yZGVyL3F1YWxpdHlUcmFjZS5qcyc7XG5leHBvcnQgeyBmb3JtYXRRdWFsaXR5VHJhY2UsIHF1YWxpdHlUcmFjZSB9IGZyb20gJy4vbGliL3JlY29yZGVyL3F1YWxpdHlUcmFjZS5qcyc7XG4iXX0=
|
|
@@ -165,7 +165,7 @@ export interface DriverCapabilities {
|
|
|
165
165
|
* capabilities: { nodeSafe: true, survivesUnload: true },
|
|
166
166
|
* schedule(child, input, refId) {
|
|
167
167
|
* sharedBuffer.push({ refId, child, input });
|
|
168
|
-
* return createHandle(refId
|
|
168
|
+
* return createHandle(refId);
|
|
169
169
|
* },
|
|
170
170
|
* };
|
|
171
171
|
*/
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
* executor.attachFlowRecorder(recorder);
|
|
14
14
|
* await executor.run();
|
|
15
15
|
*
|
|
16
|
-
* const
|
|
17
|
-
* const loopDetail = recorder.getLoopSentences();
|
|
16
|
+
* const mainEntries = executor.getNarrativeEntries(); // No loop sentences
|
|
17
|
+
* const loopDetail = recorder.getLoopSentences(); // All loop detail
|
|
18
18
|
* ```
|
|
19
19
|
*/
|
|
20
20
|
import { NarrativeFlowRecorder } from '../NarrativeFlowRecorder.js';
|
|
@@ -95,11 +95,8 @@
|
|
|
95
95
|
* @example Build a live LLM tracker (combining storage + observer):
|
|
96
96
|
*
|
|
97
97
|
* ```typescript
|
|
98
|
-
* import {
|
|
99
|
-
*
|
|
100
|
-
* type CombinedRecorder,
|
|
101
|
-
* type EmitEvent,
|
|
102
|
-
* } from 'footprintjs';
|
|
98
|
+
* import { BoundaryStateTracker } from 'footprintjs/trace';
|
|
99
|
+
* import { type CombinedRecorder, type EmitEvent } from 'footprintjs';
|
|
103
100
|
*
|
|
104
101
|
* interface LLMLiveState {
|
|
105
102
|
* readonly partial: string;
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
*
|
|
12
12
|
* @example
|
|
13
13
|
* ```typescript
|
|
14
|
-
* const quality = new QualityRecorder((runtimeStageId,
|
|
15
|
-
* // Custom scoring function — return 0.0–1.0
|
|
16
|
-
* if (
|
|
17
|
-
* return 1.0;
|
|
14
|
+
* const quality = new QualityRecorder((runtimeStageId, context) => {
|
|
15
|
+
* // Custom scoring function — return { score: 0.0–1.0, factors? }
|
|
16
|
+
* if (context.stageName.includes('llm')) return { score: 0.7, factors: ['llm stage'] };
|
|
17
|
+
* return { score: 1.0 };
|
|
18
18
|
* });
|
|
19
19
|
* executor.attachScopeRecorder(quality);
|
|
20
20
|
* await executor.run();
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* @example
|
|
16
16
|
* ```typescript
|
|
17
17
|
* import { SequenceStore } from 'footprintjs/trace';
|
|
18
|
-
* import type { ScopeRecorder } from 'footprintjs';
|
|
18
|
+
* import type { ScopeRecorder, ReadEvent, WriteEvent } from 'footprintjs';
|
|
19
19
|
*
|
|
20
20
|
* interface AuditEntry {
|
|
21
21
|
* runtimeStageId?: string;
|
|
@@ -187,14 +187,14 @@ export declare class FlowChartExecutor<TOut = any, TScope = any> {
|
|
|
187
187
|
*
|
|
188
188
|
* @example
|
|
189
189
|
* ```typescript
|
|
190
|
-
* //
|
|
190
|
+
* // Process A — after a pause, persist the checkpoint:
|
|
191
191
|
* const checkpoint = executor.getCheckpoint()!;
|
|
192
192
|
* await redis.set(`session:${id}`, JSON.stringify(checkpoint));
|
|
193
193
|
*
|
|
194
|
-
* //
|
|
195
|
-
* const
|
|
194
|
+
* // Process B (possibly different server, same chart) — restore and resume:
|
|
195
|
+
* const restored = JSON.parse(await redis.get(`session:${id}`));
|
|
196
196
|
* const executor = new FlowChartExecutor(chart);
|
|
197
|
-
* const result = await executor.resume(
|
|
197
|
+
* const result = await executor.resume(restored, { approved: true });
|
|
198
198
|
* ```
|
|
199
199
|
*/
|
|
200
200
|
resume(checkpoint: FlowchartCheckpoint, resumeInput?: unknown, options?: Pick<RunOptions, 'signal' | 'env' | 'maxDepth'>): Promise<ExecutorResult>;
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import type { FlowChart } from '../builder/types.js';
|
|
11
11
|
import type { FlowRecorder } from '../engine/narrative/types.js';
|
|
12
12
|
import type { RunOptions } from '../engine/types.js';
|
|
13
|
+
import type { CombinedRecorder } from '../recorder/CombinedRecorder.js';
|
|
13
14
|
import type { RedactionPolicy, ScopeRecorder } from '../scope/types.js';
|
|
14
15
|
/** Result from RunContext.run() — owns state and output. */
|
|
15
16
|
export interface RunResult {
|
|
@@ -24,12 +25,16 @@ export interface RunResult {
|
|
|
24
25
|
}
|
|
25
26
|
export declare class RunContext<TOut = any, TScope = any> {
|
|
26
27
|
private readonly chart;
|
|
27
|
-
private readonly
|
|
28
|
-
private readonly flowRecorders;
|
|
28
|
+
private readonly recorders;
|
|
29
29
|
private redactionPolicy?;
|
|
30
30
|
constructor(chart: FlowChart<TOut, TScope>);
|
|
31
|
-
/**
|
|
32
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Attach a recorder. Routed through the executor's combined-attach logic at
|
|
33
|
+
* run time, so scope, flow, AND emit channels are all detected uniformly — a
|
|
34
|
+
* recorder that implements only `onEmit` (or any mix) lands on the right
|
|
35
|
+
* channel(s) exactly once. Chainable.
|
|
36
|
+
*/
|
|
37
|
+
recorder(r: ScopeRecorder | FlowRecorder | CombinedRecorder): RunContext<TOut, TScope>;
|
|
33
38
|
/** Set redaction policy for this run. Chainable. */
|
|
34
39
|
redact(policy: RedactionPolicy): RunContext<TOut, TScope>;
|
|
35
40
|
/** Execute the chart with accumulated config. Returns RunResult. */
|
package/dist/types/trace.d.ts
CHANGED
|
@@ -5,19 +5,28 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @example
|
|
7
7
|
* ```typescript
|
|
8
|
-
* import { parseRuntimeStageId, findLastWriter,
|
|
8
|
+
* import { parseRuntimeStageId, findLastWriter, KeyedStore, SequenceStore } from 'footprintjs/trace';
|
|
9
9
|
*
|
|
10
10
|
* // Parse a runtimeStageId
|
|
11
11
|
* const { stageId, executionIndex } = parseRuntimeStageId('call-llm#5');
|
|
12
12
|
*
|
|
13
|
-
* // Backtrack: who wrote 'systemPrompt' before
|
|
13
|
+
* // Backtrack: who wrote 'systemPrompt' before commit at idx 8?
|
|
14
14
|
* const writer = findLastWriter(commitLog, 'systemPrompt', 8);
|
|
15
15
|
*
|
|
16
|
-
* //
|
|
17
|
-
*
|
|
16
|
+
* // v5 primary API: compose a Store as a field (one purpose per recorder).
|
|
17
|
+
* // KeyedStore<T> — 1:1 (one entry per step)
|
|
18
|
+
* class MyRecorder {
|
|
19
|
+
* readonly id = 'my-recorder';
|
|
20
|
+
* private store = new KeyedStore<MyEntry>();
|
|
21
|
+
* onWrite(e) { this.store.set(e.runtimeStageId, { ... }); }
|
|
22
|
+
* }
|
|
18
23
|
*
|
|
19
|
-
* //
|
|
20
|
-
* class AuditRecorder
|
|
24
|
+
* // SequenceStore<T> — 1:N (multiple entries per step, ordering matters)
|
|
25
|
+
* class AuditRecorder {
|
|
26
|
+
* readonly id = 'audit';
|
|
27
|
+
* private store = new SequenceStore<AuditEntry>();
|
|
28
|
+
* onRead(e) { this.store.push({ runtimeStageId: e.runtimeStageId, ... }); }
|
|
29
|
+
* }
|
|
21
30
|
* ```
|
|
22
31
|
*/
|
|
23
32
|
export type { ExecutionCounter } from './lib/engine/runtimeStageId.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "footprintjs",
|
|
3
|
-
"version": "6.1.
|
|
3
|
+
"version": "6.1.2",
|
|
4
4
|
"description": "Explainable backend flows — automatic causal traces, decision evidence, and MCP tool generation for AI agents",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Sanjay Krishna Anbalagan",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"clean": "rm -rf build/* coverage dist node_modules package-lock.json",
|
|
42
|
-
"build": "tsc && tsc -p tsconfig.esm.json",
|
|
42
|
+
"build": "tsc && tsc -p tsconfig.esm.json && node scripts/postbuild-esm.mjs",
|
|
43
43
|
"prepare": "husky",
|
|
44
44
|
"watch": "tsc -w",
|
|
45
45
|
"test": "vitest run",
|
|
@@ -117,6 +117,7 @@
|
|
|
117
117
|
"@typescript-eslint/parser": "^5.61.0",
|
|
118
118
|
"@vitest/coverage-v8": "^4.1.8",
|
|
119
119
|
"concurrently": "^8.0.1",
|
|
120
|
+
"esbuild": "^0.28.0",
|
|
120
121
|
"eslint": "^8.44.0",
|
|
121
122
|
"eslint-config-prettier": "^6.15.0",
|
|
122
123
|
"eslint-config-standard": "^17.0.0",
|