@gobing-ai/ts-llm-jsonl-importer 0.5.18 → 0.5.20
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/importer.d.ts.map +1 -1
- package/dist/importer.js +14 -4
- package/dist/mappers.d.ts +12 -6
- package/dist/mappers.d.ts.map +1 -1
- package/dist/mappers.js +21 -14
- package/dist/redaction.d.ts +2 -0
- package/dist/redaction.d.ts.map +1 -1
- package/dist/redaction.js +5 -1
- package/dist/schema-sql.d.ts +1 -1
- package/dist/schema-sql.js +1 -1
- package/package.json +4 -4
- package/src/importer.ts +14 -4
- package/src/mappers.ts +26 -13
- package/src/redaction.ts +6 -1
- package/src/schema-sql.ts +1 -1
package/dist/importer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"importer.d.ts","sourceRoot":"","sources":["../src/importer.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAER,aAAa,EACb,YAAY,EAGZ,gBAAgB,EAEnB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"importer.d.ts","sourceRoot":"","sources":["../src/importer.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAER,aAAa,EACb,YAAY,EAGZ,gBAAgB,EAEnB,MAAM,SAAS,CAAC;AAkKjB;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAwerH"}
|
package/dist/importer.js
CHANGED
|
@@ -95,8 +95,14 @@ async function resolveToolCallRow(db, source, sessionId, callId) {
|
|
|
95
95
|
*/
|
|
96
96
|
function attachableDuration(timing, messageTsMs) {
|
|
97
97
|
if (timing.wallTimeMs !== undefined) {
|
|
98
|
-
// The tool's own measurement — no clamping, no sanity check.
|
|
99
|
-
|
|
98
|
+
// The tool's own measurement — no clamping, no sanity check. pi carries
|
|
99
|
+
// native bounds in details.toolMetadata (task 1131 R2); persist them when
|
|
100
|
+
// present so native and fallback durations stay distinguishable.
|
|
101
|
+
return {
|
|
102
|
+
startedAt: timing.startedAtMs !== undefined ? new Date(timing.startedAtMs).toISOString() : null,
|
|
103
|
+
completedAt: timing.completedAtMs !== undefined ? new Date(timing.completedAtMs).toISOString() : null,
|
|
104
|
+
durationMs: Math.round(timing.wallTimeMs),
|
|
105
|
+
};
|
|
100
106
|
}
|
|
101
107
|
if (timing.timestampMs === undefined || messageTsMs === undefined)
|
|
102
108
|
return null;
|
|
@@ -382,10 +388,14 @@ export async function runJsonlImport(source, options) {
|
|
|
382
388
|
// an implausible fallback delta stays NULL (unmeasured). The UPDATEs ride
|
|
383
389
|
// this line's batch — idempotent, so re-imports and post-resume tail
|
|
384
390
|
// reprocessing write the same values.
|
|
385
|
-
if (definition.source === 'omp') {
|
|
391
|
+
if (definition.source === 'omp' || definition.source === 'pi') {
|
|
386
392
|
const timing = ompToolResultTiming(raw);
|
|
387
393
|
if (timing !== null) {
|
|
388
|
-
|
|
394
|
+
// pi normalizes toolResult envelopes to role `user` (piRole), so the
|
|
395
|
+
// role match must accept both shapes (task 1131 R2).
|
|
396
|
+
const resultEntry = prepared.find((entry) => entry.split.targetTable === 'history_message' &&
|
|
397
|
+
(entry.normalized.role === 'toolresult' ||
|
|
398
|
+
(definition.source === 'pi' && entry.normalized.role === 'user')));
|
|
389
399
|
const sessionId = resultEntry?.normalized.session_id;
|
|
390
400
|
if (typeof sessionId === 'string') {
|
|
391
401
|
let pending = toolCallRows.get(toolCallKey(resolvedSource, sessionId, timing.toolCallId));
|
package/dist/mappers.d.ts
CHANGED
|
@@ -54,16 +54,22 @@ export interface OmpToolResultTiming {
|
|
|
54
54
|
wallTimeMs: number | undefined;
|
|
55
55
|
/** Message timestamp as epoch millis, when parseable. */
|
|
56
56
|
timestampMs: number | undefined;
|
|
57
|
+
/** Native start bound from pi `details.toolMetadata.startedAt` (task 1131 R2). */
|
|
58
|
+
startedAtMs: number | undefined;
|
|
59
|
+
/** Native completion bound from pi `details.toolMetadata.completedAt` (task 1131 R2). */
|
|
60
|
+
completedAtMs: number | undefined;
|
|
57
61
|
}
|
|
58
62
|
/** Parse a message timestamp (epoch-millis number, numeric string, or ISO) to epoch millis. */
|
|
59
63
|
export declare function timestampToEpochMs(value: unknown): number | undefined;
|
|
60
64
|
/**
|
|
61
|
-
* Extract toolResult timing signals from a raw OMP record (task 0564 R1
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
65
|
+
* Extract toolResult timing signals from a raw OMP or pi record (task 0564 R1,
|
|
66
|
+
* generalized for pi in task 1131 R2), or null when the record is not a
|
|
67
|
+
* toolResult message or carries no toolCallId. Both sources emit
|
|
68
|
+
* `role: "toolResult"` message envelopes with `{toolCallId, toolName, content,
|
|
69
|
+
* details, isError, timestamp}`; the tool's own wall time resolves from
|
|
70
|
+
* `details.wallTimeMs`, falling back to pi's `message.durationMs` and
|
|
71
|
+
* `details.toolMetadata.durationMs`, and `toolCallId` joins the originating
|
|
72
|
+
* `toolCall.id` exactly.
|
|
67
73
|
*/
|
|
68
74
|
export declare function ompToolResultTiming(raw: Record<string, unknown>): OmpToolResultTiming | null;
|
|
69
75
|
/** Signals carried by a Claude tool_result user line (task 0624 R2). */
|
package/dist/mappers.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mappers.d.ts","sourceRoot":"","sources":["../src/mappers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"mappers.d.ts","sourceRoot":"","sources":["../src/mappers.ts"],"names":[],"mappings":"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"}
|
package/dist/mappers.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { capabilityInvocationId, extractNestedExecCommandLiterals, matchCapabilityOrigin, parseLiteralReadTargets, } from './capability.js';
|
|
3
3
|
import { sha256, sha256Text } from './hash.js';
|
|
4
|
+
import { applyRules } from './redaction.js';
|
|
4
5
|
// ---------------------------------------------------------------------------
|
|
5
6
|
// Helper: identity field map for typed columns
|
|
6
7
|
// ---------------------------------------------------------------------------
|
|
@@ -940,14 +941,15 @@ export function argsDigest(args) {
|
|
|
940
941
|
const redacted = redactArgs(args);
|
|
941
942
|
return sha256(redacted);
|
|
942
943
|
}
|
|
943
|
-
/**
|
|
944
|
+
/**
|
|
945
|
+
* Redact tool arguments for digest: every string leaf gets the same secret
|
|
946
|
+
* replacement the persistence layer applies (task 1131 R1) — no length-based
|
|
947
|
+
* collapse, so two distinct long commands keep distinct digests and a token the
|
|
948
|
+
* shape rules catch never leaks into the digest input.
|
|
949
|
+
*/
|
|
944
950
|
function redactArgs(args) {
|
|
945
951
|
if (typeof args === 'string') {
|
|
946
|
-
|
|
947
|
-
return '[REDACTED:long]';
|
|
948
|
-
if (/[A-Za-z0-9+/]{40,}=*|[A-Za-z0-9_-]{20,}/.test(args))
|
|
949
|
-
return '[REDACTED:secret]';
|
|
950
|
-
return args;
|
|
952
|
+
return applyRules(args);
|
|
951
953
|
}
|
|
952
954
|
if (Array.isArray(args))
|
|
953
955
|
return args.map(redactArgs);
|
|
@@ -1469,12 +1471,14 @@ export function timestampToEpochMs(value) {
|
|
|
1469
1471
|
return undefined;
|
|
1470
1472
|
}
|
|
1471
1473
|
/**
|
|
1472
|
-
* Extract toolResult timing signals from a raw OMP record (task 0564 R1
|
|
1473
|
-
*
|
|
1474
|
-
*
|
|
1475
|
-
*
|
|
1476
|
-
*
|
|
1477
|
-
*
|
|
1474
|
+
* Extract toolResult timing signals from a raw OMP or pi record (task 0564 R1,
|
|
1475
|
+
* generalized for pi in task 1131 R2), or null when the record is not a
|
|
1476
|
+
* toolResult message or carries no toolCallId. Both sources emit
|
|
1477
|
+
* `role: "toolResult"` message envelopes with `{toolCallId, toolName, content,
|
|
1478
|
+
* details, isError, timestamp}`; the tool's own wall time resolves from
|
|
1479
|
+
* `details.wallTimeMs`, falling back to pi's `message.durationMs` and
|
|
1480
|
+
* `details.toolMetadata.durationMs`, and `toolCallId` joins the originating
|
|
1481
|
+
* `toolCall.id` exactly.
|
|
1478
1482
|
*/
|
|
1479
1483
|
export function ompToolResultTiming(raw) {
|
|
1480
1484
|
const msg = o(raw.message);
|
|
@@ -1484,12 +1488,15 @@ export function ompToolResultTiming(raw) {
|
|
|
1484
1488
|
if (toolCallId === undefined)
|
|
1485
1489
|
return null;
|
|
1486
1490
|
const details = o(msg.details);
|
|
1487
|
-
const
|
|
1491
|
+
const toolMetadata = o(details.toolMetadata);
|
|
1492
|
+
const finite = (value) => typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
1488
1493
|
return {
|
|
1489
1494
|
toolCallId,
|
|
1490
1495
|
isError: msg.isError === true,
|
|
1491
|
-
wallTimeMs,
|
|
1496
|
+
wallTimeMs: finite(details.wallTimeMs) ?? finite(msg.durationMs) ?? finite(toolMetadata.durationMs),
|
|
1492
1497
|
timestampMs: timestampToEpochMs(raw.timestamp ?? msg.timestamp),
|
|
1498
|
+
startedAtMs: timestampToEpochMs(toolMetadata.startedAt),
|
|
1499
|
+
completedAtMs: timestampToEpochMs(toolMetadata.completedAt),
|
|
1493
1500
|
};
|
|
1494
1501
|
}
|
|
1495
1502
|
/**
|
package/dist/redaction.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { JsonObject, RedactionRule } from './types';
|
|
2
2
|
/** Default redaction rules for common token, key, and email shapes in agent logs. */
|
|
3
3
|
export declare const DEFAULT_REDACTION_RULES: readonly RedactionRule[];
|
|
4
|
+
/** Apply the rules' substring replacement to a single string leaf. */
|
|
5
|
+
export declare function applyRules(value: string, rules?: readonly RedactionRule[]): string;
|
|
4
6
|
/** Redact supported scalar and composite JSON values recursively. */
|
|
5
7
|
export declare function redactValue(value: unknown, rules?: readonly RedactionRule[]): unknown;
|
|
6
8
|
/** Redact a normalized ETL record before hashing or writing it to the database. */
|
package/dist/redaction.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redaction.d.ts","sourceRoot":"","sources":["../src/redaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAEzD,qFAAqF;AACrF,eAAO,MAAM,uBAAuB,EAAE,SAAS,aAAa,EAwC3D,CAAC;AAUF,qEAAqE;AACrE,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,GAAE,SAAS,aAAa,EAA4B,GAAG,OAAO,CAgB9G;AAED,mFAAmF;AACnF,wBAAgB,YAAY,CAAC,OAAO,SAAS,UAAU,EACnD,MAAM,EAAE,OAAO,EACf,KAAK,GAAE,SAAS,aAAa,EAA4B,GAC1D,OAAO,CAET"}
|
|
1
|
+
{"version":3,"file":"redaction.d.ts","sourceRoot":"","sources":["../src/redaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAEzD,qFAAqF;AACrF,eAAO,MAAM,uBAAuB,EAAE,SAAS,aAAa,EAwC3D,CAAC;AAUF,sEAAsE;AACtE,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,SAAS,aAAa,EAA4B,GAAG,MAAM,CAE3G;AAED,qEAAqE;AACrE,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,GAAE,SAAS,aAAa,EAA4B,GAAG,OAAO,CAgB9G;AAED,mFAAmF;AACnF,wBAAgB,YAAY,CAAC,OAAO,SAAS,UAAU,EACnD,MAAM,EAAE,OAAO,EACf,KAAK,GAAE,SAAS,aAAa,EAA4B,GAC1D,OAAO,CAET"}
|
package/dist/redaction.js
CHANGED
|
@@ -45,10 +45,14 @@ export const DEFAULT_REDACTION_RULES = [
|
|
|
45
45
|
* NOT redacted — those appear in LLM usage records.
|
|
46
46
|
*/
|
|
47
47
|
const SECRET_KEY = /^(?:api[_-]?key|apikey|api[_-]?secret|token|access[_-]?token|refresh[_-]?token|auth[_-]?token|secret|secret[_-]?key|client[_-]?secret|private[_-]?key|session[_-]?token|password|passwd|authorization)$/i;
|
|
48
|
+
/** Apply the rules' substring replacement to a single string leaf. */
|
|
49
|
+
export function applyRules(value, rules = DEFAULT_REDACTION_RULES) {
|
|
50
|
+
return rules.reduce((current, rule) => current.replace(rule.pattern, rule.replacement), value);
|
|
51
|
+
}
|
|
48
52
|
/** Redact supported scalar and composite JSON values recursively. */
|
|
49
53
|
export function redactValue(value, rules = DEFAULT_REDACTION_RULES) {
|
|
50
54
|
if (typeof value === 'string') {
|
|
51
|
-
return
|
|
55
|
+
return applyRules(value, rules);
|
|
52
56
|
}
|
|
53
57
|
if (Array.isArray(value)) {
|
|
54
58
|
return value.map((entry) => redactValue(entry, rules));
|
package/dist/schema-sql.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Guaranteed to match the package version; a bump-or-fail test enforces that
|
|
5
5
|
* any modification to HISTORY_IMPORT_SCHEMA_SQL must be accompanied by a version bump.
|
|
6
6
|
*/
|
|
7
|
-
export declare const HISTORY_IMPORT_SCHEMA_VERSION = "0.5.
|
|
7
|
+
export declare const HISTORY_IMPORT_SCHEMA_VERSION = "0.5.20";
|
|
8
8
|
/**
|
|
9
9
|
* DDL string that creates the history import checkpoint, ledger, and typed contract tables.
|
|
10
10
|
*
|
package/dist/schema-sql.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Guaranteed to match the package version; a bump-or-fail test enforces that
|
|
5
5
|
* any modification to HISTORY_IMPORT_SCHEMA_SQL must be accompanied by a version bump.
|
|
6
6
|
*/
|
|
7
|
-
export const HISTORY_IMPORT_SCHEMA_VERSION = '0.5.
|
|
7
|
+
export const HISTORY_IMPORT_SCHEMA_VERSION = '0.5.20';
|
|
8
8
|
/**
|
|
9
9
|
* DDL string that creates the history import checkpoint, ledger, and typed contract tables.
|
|
10
10
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gobing-ai/ts-llm-jsonl-importer",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.20",
|
|
4
4
|
"description": "@gobing-ai/ts-llm-jsonl-importer — Generic JSONL importer for LLM agent history files.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -47,9 +47,9 @@
|
|
|
47
47
|
"release": "echo 'Manual publish is disabled. Releases go through GitHub Actions via Trusted Publishing — push a tag: git tag @gobing-ai/ts-llm-jsonl-importer-v<version> && git push --tags' && exit 1"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@gobing-ai/ts-db": "^0.5.
|
|
51
|
-
"@gobing-ai/ts-runtime": "^0.5.
|
|
52
|
-
"@gobing-ai/ts-utils": "^0.5.
|
|
50
|
+
"@gobing-ai/ts-db": "^0.5.20",
|
|
51
|
+
"@gobing-ai/ts-runtime": "^0.5.20",
|
|
52
|
+
"@gobing-ai/ts-utils": "^0.5.20",
|
|
53
53
|
"zod": "^4.1.0"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
package/src/importer.ts
CHANGED
|
@@ -181,8 +181,14 @@ function attachableDuration(
|
|
|
181
181
|
messageTsMs: number | undefined,
|
|
182
182
|
): { startedAt: string | null; completedAt: string | null; durationMs: number } | null {
|
|
183
183
|
if (timing.wallTimeMs !== undefined) {
|
|
184
|
-
// The tool's own measurement — no clamping, no sanity check.
|
|
185
|
-
|
|
184
|
+
// The tool's own measurement — no clamping, no sanity check. pi carries
|
|
185
|
+
// native bounds in details.toolMetadata (task 1131 R2); persist them when
|
|
186
|
+
// present so native and fallback durations stay distinguishable.
|
|
187
|
+
return {
|
|
188
|
+
startedAt: timing.startedAtMs !== undefined ? new Date(timing.startedAtMs).toISOString() : null,
|
|
189
|
+
completedAt: timing.completedAtMs !== undefined ? new Date(timing.completedAtMs).toISOString() : null,
|
|
190
|
+
durationMs: Math.round(timing.wallTimeMs),
|
|
191
|
+
};
|
|
186
192
|
}
|
|
187
193
|
if (timing.timestampMs === undefined || messageTsMs === undefined) return null;
|
|
188
194
|
const delta = timing.timestampMs - messageTsMs;
|
|
@@ -526,12 +532,16 @@ export async function runJsonlImport(source: string | SourceDefinition, options:
|
|
|
526
532
|
// an implausible fallback delta stays NULL (unmeasured). The UPDATEs ride
|
|
527
533
|
// this line's batch — idempotent, so re-imports and post-resume tail
|
|
528
534
|
// reprocessing write the same values.
|
|
529
|
-
if (definition.source === 'omp') {
|
|
535
|
+
if (definition.source === 'omp' || definition.source === 'pi') {
|
|
530
536
|
const timing = ompToolResultTiming(raw);
|
|
531
537
|
if (timing !== null) {
|
|
538
|
+
// pi normalizes toolResult envelopes to role `user` (piRole), so the
|
|
539
|
+
// role match must accept both shapes (task 1131 R2).
|
|
532
540
|
const resultEntry = prepared.find(
|
|
533
541
|
(entry) =>
|
|
534
|
-
entry.split.targetTable === 'history_message' &&
|
|
542
|
+
entry.split.targetTable === 'history_message' &&
|
|
543
|
+
(entry.normalized.role === 'toolresult' ||
|
|
544
|
+
(definition.source === 'pi' && entry.normalized.role === 'user')),
|
|
535
545
|
);
|
|
536
546
|
const sessionId = resultEntry?.normalized.session_id;
|
|
537
547
|
if (typeof sessionId === 'string') {
|
package/src/mappers.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
parseLiteralReadTargets,
|
|
8
8
|
} from './capability';
|
|
9
9
|
import { sha256, sha256Text } from './hash';
|
|
10
|
+
import { applyRules } from './redaction';
|
|
10
11
|
import type { JsonObject, SkillCallSplitRecord, SplitEntry, TransformContext } from './types';
|
|
11
12
|
|
|
12
13
|
// ---------------------------------------------------------------------------
|
|
@@ -1047,12 +1048,15 @@ export function argsDigest(args: unknown): string {
|
|
|
1047
1048
|
/** Redacted tool args: JSON shape preserved, string leaves possibly elided. */
|
|
1048
1049
|
type RedactedValue = string | number | boolean | null | RedactedValue[] | { [key: string]: RedactedValue };
|
|
1049
1050
|
|
|
1050
|
-
/**
|
|
1051
|
+
/**
|
|
1052
|
+
* Redact tool arguments for digest: every string leaf gets the same secret
|
|
1053
|
+
* replacement the persistence layer applies (task 1131 R1) — no length-based
|
|
1054
|
+
* collapse, so two distinct long commands keep distinct digests and a token the
|
|
1055
|
+
* shape rules catch never leaks into the digest input.
|
|
1056
|
+
*/
|
|
1051
1057
|
function redactArgs(args: unknown): RedactedValue {
|
|
1052
1058
|
if (typeof args === 'string') {
|
|
1053
|
-
|
|
1054
|
-
if (/[A-Za-z0-9+/]{40,}=*|[A-Za-z0-9_-]{20,}/.test(args)) return '[REDACTED:secret]';
|
|
1055
|
-
return args;
|
|
1059
|
+
return applyRules(args);
|
|
1056
1060
|
}
|
|
1057
1061
|
if (Array.isArray(args)) return args.map(redactArgs);
|
|
1058
1062
|
if (args !== null && typeof args === 'object') {
|
|
@@ -1610,6 +1614,10 @@ export interface OmpToolResultTiming {
|
|
|
1610
1614
|
wallTimeMs: number | undefined;
|
|
1611
1615
|
/** Message timestamp as epoch millis, when parseable. */
|
|
1612
1616
|
timestampMs: number | undefined;
|
|
1617
|
+
/** Native start bound from pi `details.toolMetadata.startedAt` (task 1131 R2). */
|
|
1618
|
+
startedAtMs: number | undefined;
|
|
1619
|
+
/** Native completion bound from pi `details.toolMetadata.completedAt` (task 1131 R2). */
|
|
1620
|
+
completedAtMs: number | undefined;
|
|
1613
1621
|
}
|
|
1614
1622
|
|
|
1615
1623
|
/** Parse a message timestamp (epoch-millis number, numeric string, or ISO) to epoch millis. */
|
|
@@ -1625,12 +1633,14 @@ export function timestampToEpochMs(value: unknown): number | undefined {
|
|
|
1625
1633
|
}
|
|
1626
1634
|
|
|
1627
1635
|
/**
|
|
1628
|
-
* Extract toolResult timing signals from a raw OMP record (task 0564 R1
|
|
1629
|
-
*
|
|
1630
|
-
*
|
|
1631
|
-
*
|
|
1632
|
-
*
|
|
1633
|
-
*
|
|
1636
|
+
* Extract toolResult timing signals from a raw OMP or pi record (task 0564 R1,
|
|
1637
|
+
* generalized for pi in task 1131 R2), or null when the record is not a
|
|
1638
|
+
* toolResult message or carries no toolCallId. Both sources emit
|
|
1639
|
+
* `role: "toolResult"` message envelopes with `{toolCallId, toolName, content,
|
|
1640
|
+
* details, isError, timestamp}`; the tool's own wall time resolves from
|
|
1641
|
+
* `details.wallTimeMs`, falling back to pi's `message.durationMs` and
|
|
1642
|
+
* `details.toolMetadata.durationMs`, and `toolCallId` joins the originating
|
|
1643
|
+
* `toolCall.id` exactly.
|
|
1634
1644
|
*/
|
|
1635
1645
|
export function ompToolResultTiming(raw: Record<string, unknown>): OmpToolResultTiming | null {
|
|
1636
1646
|
const msg = o(raw.message);
|
|
@@ -1638,13 +1648,16 @@ export function ompToolResultTiming(raw: Record<string, unknown>): OmpToolResult
|
|
|
1638
1648
|
const toolCallId = s(msg.toolCallId);
|
|
1639
1649
|
if (toolCallId === undefined) return null;
|
|
1640
1650
|
const details = o(msg.details);
|
|
1641
|
-
const
|
|
1642
|
-
|
|
1651
|
+
const toolMetadata = o(details.toolMetadata);
|
|
1652
|
+
const finite = (value: unknown): number | undefined =>
|
|
1653
|
+
typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
1643
1654
|
return {
|
|
1644
1655
|
toolCallId,
|
|
1645
1656
|
isError: msg.isError === true,
|
|
1646
|
-
wallTimeMs,
|
|
1657
|
+
wallTimeMs: finite(details.wallTimeMs) ?? finite(msg.durationMs) ?? finite(toolMetadata.durationMs),
|
|
1647
1658
|
timestampMs: timestampToEpochMs(raw.timestamp ?? msg.timestamp),
|
|
1659
|
+
startedAtMs: timestampToEpochMs(toolMetadata.startedAt),
|
|
1660
|
+
completedAtMs: timestampToEpochMs(toolMetadata.completedAt),
|
|
1648
1661
|
};
|
|
1649
1662
|
}
|
|
1650
1663
|
|
package/src/redaction.ts
CHANGED
|
@@ -51,10 +51,15 @@ export const DEFAULT_REDACTION_RULES: readonly RedactionRule[] = [
|
|
|
51
51
|
const SECRET_KEY =
|
|
52
52
|
/^(?:api[_-]?key|apikey|api[_-]?secret|token|access[_-]?token|refresh[_-]?token|auth[_-]?token|secret|secret[_-]?key|client[_-]?secret|private[_-]?key|session[_-]?token|password|passwd|authorization)$/i;
|
|
53
53
|
|
|
54
|
+
/** Apply the rules' substring replacement to a single string leaf. */
|
|
55
|
+
export function applyRules(value: string, rules: readonly RedactionRule[] = DEFAULT_REDACTION_RULES): string {
|
|
56
|
+
return rules.reduce((current, rule) => current.replace(rule.pattern, rule.replacement), value);
|
|
57
|
+
}
|
|
58
|
+
|
|
54
59
|
/** Redact supported scalar and composite JSON values recursively. */
|
|
55
60
|
export function redactValue(value: unknown, rules: readonly RedactionRule[] = DEFAULT_REDACTION_RULES): unknown {
|
|
56
61
|
if (typeof value === 'string') {
|
|
57
|
-
return
|
|
62
|
+
return applyRules(value, rules);
|
|
58
63
|
}
|
|
59
64
|
if (Array.isArray(value)) {
|
|
60
65
|
return value.map((entry) => redactValue(entry, rules));
|
package/src/schema-sql.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Guaranteed to match the package version; a bump-or-fail test enforces that
|
|
5
5
|
* any modification to HISTORY_IMPORT_SCHEMA_SQL must be accompanied by a version bump.
|
|
6
6
|
*/
|
|
7
|
-
export const HISTORY_IMPORT_SCHEMA_VERSION = '0.5.
|
|
7
|
+
export const HISTORY_IMPORT_SCHEMA_VERSION = '0.5.20';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* DDL string that creates the history import checkpoint, ledger, and typed contract tables.
|