@peac/adapter-openclaw 0.10.9 → 0.10.10

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/hooks.js DELETED
@@ -1,157 +0,0 @@
1
- "use strict";
2
- /**
3
- * @peac/adapter-openclaw - Hook Bindings
4
- *
5
- * Hook bindings for OpenClaw tool call capture.
6
- * Designed for sync capture (< 10ms target).
7
- */
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.createHookHandler = createHookHandler;
10
- exports.captureBatch = captureBatch;
11
- exports.captureParallel = captureParallel;
12
- exports.createSessionHistoryTailer = createSessionHistoryTailer;
13
- const mapper_js_1 = require("./mapper.js");
14
- // =============================================================================
15
- // Hook Handler Implementation
16
- // =============================================================================
17
- /**
18
- * Create a hook handler for OpenClaw tool call events.
19
- *
20
- * @param handlerConfig - Configuration for the handler
21
- * @returns Hook handler instance
22
- */
23
- function createHookHandler(handlerConfig) {
24
- const { session, config, onCapture, onMappingError } = handlerConfig;
25
- return {
26
- async afterToolCall(event) {
27
- // Map OpenClaw event to CapturedAction
28
- const mappingResult = (0, mapper_js_1.mapToolCallEvent)(event, config);
29
- if (!mappingResult.success || !mappingResult.action) {
30
- // Mapping failed - report and return error result
31
- if (onMappingError) {
32
- onMappingError(mappingResult, event);
33
- }
34
- return {
35
- success: false,
36
- code: mappingResult.error_code ?? 'E_OPENCLAW_MAPPING_FAILED',
37
- message: mappingResult.error_message ?? 'Failed to map OpenClaw event',
38
- };
39
- }
40
- // Capture the action
41
- const captureResult = await session.capture(mappingResult.action);
42
- // Convert to HookCaptureResult (compatible types)
43
- const hookResult = captureResult.success
44
- ? { success: true, entry: captureResult.entry }
45
- : { success: false, code: captureResult.code, message: captureResult.message };
46
- // Invoke callback
47
- if (onCapture) {
48
- onCapture(hookResult, event);
49
- }
50
- return hookResult;
51
- },
52
- getSession() {
53
- return session;
54
- },
55
- async close() {
56
- await session.close();
57
- },
58
- };
59
- }
60
- // =============================================================================
61
- // Batch Capture
62
- // =============================================================================
63
- /**
64
- * Capture multiple tool call events in sequence.
65
- *
66
- * Note: Events are captured in order. For parallel capture, use individual
67
- * afterToolCall calls with Promise.all.
68
- *
69
- * @param handler - Hook handler
70
- * @param events - Array of tool call events
71
- * @returns Array of capture results (same order as events)
72
- */
73
- async function captureBatch(handler, events) {
74
- const results = [];
75
- for (const event of events) {
76
- const result = await handler.afterToolCall(event);
77
- results.push(result);
78
- }
79
- return results;
80
- }
81
- /**
82
- * Capture multiple tool call events in parallel.
83
- *
84
- * Warning: Parallel capture may result in non-deterministic chain ordering.
85
- * Use captureBatch for deterministic ordering.
86
- *
87
- * @param handler - Hook handler
88
- * @param events - Array of tool call events
89
- * @returns Array of capture results (same order as events)
90
- */
91
- async function captureParallel(handler, events) {
92
- return Promise.all(events.map((event) => handler.afterToolCall(event)));
93
- }
94
- /**
95
- * Create a session history tailer.
96
- *
97
- * @param tailerConfig - Configuration for the tailer
98
- * @returns Session history tailer instance
99
- */
100
- function createSessionHistoryTailer(tailerConfig) {
101
- const { handler, sessionId, pollIntervalMs = 1000, fetchHistory, onError } = tailerConfig;
102
- let running = false;
103
- let inFlight = false;
104
- let lastEventId;
105
- let intervalHandle;
106
- const poll = async () => {
107
- // Prevent overlapping polls - if a poll takes longer than the
108
- // interval, skip this tick rather than double-processing
109
- if (inFlight)
110
- return;
111
- inFlight = true;
112
- try {
113
- const events = await fetchHistory(sessionId, lastEventId);
114
- for (const event of events) {
115
- // Check if tailer was stopped during processing
116
- if (!running)
117
- break;
118
- await handler.afterToolCall(event);
119
- lastEventId = event.tool_call_id;
120
- }
121
- }
122
- catch (error) {
123
- if (onError) {
124
- onError(error instanceof Error ? error : new Error(String(error)));
125
- }
126
- }
127
- finally {
128
- inFlight = false;
129
- }
130
- };
131
- return {
132
- start() {
133
- if (running)
134
- return;
135
- running = true;
136
- intervalHandle = setInterval(poll, pollIntervalMs);
137
- // Run immediately on start
138
- poll();
139
- },
140
- stop() {
141
- if (!running)
142
- return;
143
- running = false;
144
- if (intervalHandle) {
145
- clearInterval(intervalHandle);
146
- intervalHandle = undefined;
147
- }
148
- },
149
- getLastEventId() {
150
- return lastEventId;
151
- },
152
- isRunning() {
153
- return running;
154
- },
155
- };
156
- }
157
- //# sourceMappingURL=hooks.js.map
package/dist/hooks.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AA+DH,8CA6CC;AAgBD,oCAYC;AAYD,0CAKC;AAoDD,gEA2DC;AApQD,2CAA+C;AAiD/C,gFAAgF;AAChF,8BAA8B;AAC9B,gFAAgF;AAEhF;;;;;GAKG;AACH,SAAgB,iBAAiB,CAAC,aAAgC;IAChE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,GAAG,aAAa,CAAC;IAErE,OAAO;QACL,KAAK,CAAC,aAAa,CAAC,KAA4B;YAC9C,uCAAuC;YACvC,MAAM,aAAa,GAAG,IAAA,4BAAgB,EAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAEtD,IAAI,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;gBACpD,kDAAkD;gBAClD,IAAI,cAAc,EAAE,CAAC;oBACnB,cAAc,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;gBACvC,CAAC;gBAED,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,IAAI,EAAE,aAAa,CAAC,UAAU,IAAI,2BAA2B;oBAC7D,OAAO,EAAE,aAAa,CAAC,aAAa,IAAI,8BAA8B;iBACvE,CAAC;YACJ,CAAC;YAED,qBAAqB;YACrB,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAElE,kDAAkD;YAClD,MAAM,UAAU,GAAsB,aAAa,CAAC,OAAO;gBACzD,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,CAAC,KAAK,EAAE;gBAC/C,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,aAAa,CAAC,OAAO,EAAE,CAAC;YAEjF,kBAAkB;YAClB,IAAI,SAAS,EAAE,CAAC;gBACd,SAAS,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YAC/B,CAAC;YAED,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,UAAU;YACR,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,KAAK,CAAC,KAAK;YACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACxB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,gBAAgB;AAChB,gFAAgF;AAEhF;;;;;;;;;GASG;AACI,KAAK,UAAU,YAAY,CAChC,OAA4B,EAC5B,MAA+B;IAE/B,MAAM,OAAO,GAAwB,EAAE,CAAC;IAExC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAClD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;GASG;AACI,KAAK,UAAU,eAAe,CACnC,OAA4B,EAC5B,MAA+B;IAE/B,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC1E,CAAC;AA8CD;;;;;GAKG;AACH,SAAgB,0BAA0B,CAAC,YAA0B;IACnE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,GAAG,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC;IAE1F,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,WAA+B,CAAC;IACpC,IAAI,cAA0D,CAAC;IAE/D,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE;QACtB,8DAA8D;QAC9D,yDAAyD;QACzD,IAAI,QAAQ;YAAE,OAAO;QAErB,QAAQ,GAAG,IAAI,CAAC;QAChB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;YAE1D,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,gDAAgD;gBAChD,IAAI,CAAC,OAAO;oBAAE,MAAM;gBAEpB,MAAM,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;gBACnC,WAAW,GAAG,KAAK,CAAC,YAAY,CAAC;YACnC,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACrE,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,QAAQ,GAAG,KAAK,CAAC;QACnB,CAAC;IACH,CAAC,CAAC;IAEF,OAAO;QACL,KAAK;YACH,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,cAAc,GAAG,WAAW,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;YACnD,2BAA2B;YAC3B,IAAI,EAAE,CAAC;QACT,CAAC;QAED,IAAI;YACF,IAAI,CAAC,OAAO;gBAAE,OAAO;YACrB,OAAO,GAAG,KAAK,CAAC;YAChB,IAAI,cAAc,EAAE,CAAC;gBACnB,aAAa,CAAC,cAAc,CAAC,CAAC;gBAC9B,cAAc,GAAG,SAAS,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,cAAc;YACZ,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,SAAS;YACP,OAAO,OAAO,CAAC;QACjB,CAAC;KACF,CAAC;AACJ,CAAC"}
package/dist/index.js DELETED
@@ -1,53 +0,0 @@
1
- "use strict";
2
- /**
3
- * @peac/adapter-openclaw
4
- *
5
- * OpenClaw adapter for PEAC interaction evidence capture.
6
- *
7
- * This package provides:
8
- * - Mapper: OpenClaw tool call events -> PEAC CapturedAction
9
- * - Hooks: Sync capture bindings (< 10ms target)
10
- * - Emitter: Background receipt signing and persistence
11
- *
12
- * @packageDocumentation
13
- */
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.createQueryTool = exports.createVerifyTool = exports.createExportBundleTool = exports.createStatusTool = exports.createPluginInstance = exports.createFileReceiptWriter = exports.generateKeyId = exports.resolveSigner = exports.createJwkSigner = exports.createBackgroundService = exports.createReceiptEmitter = exports.createSessionHistoryTailer = exports.captureParallel = exports.captureBatch = exports.createHookHandler = exports.buildWorkflowContext = exports.extractWorkflowId = exports.mapToolCallEventBatch = exports.mapToolCallEvent = exports.OPENCLAW_WARNING_CODES = exports.OPENCLAW_ERROR_CODES = exports.OPENCLAW_EXTENSION_KEYS = void 0;
16
- var types_js_1 = require("./types.js");
17
- // Extension keys
18
- Object.defineProperty(exports, "OPENCLAW_EXTENSION_KEYS", { enumerable: true, get: function () { return types_js_1.OPENCLAW_EXTENSION_KEYS; } });
19
- // Error codes
20
- Object.defineProperty(exports, "OPENCLAW_ERROR_CODES", { enumerable: true, get: function () { return types_js_1.OPENCLAW_ERROR_CODES; } });
21
- // Warning codes
22
- Object.defineProperty(exports, "OPENCLAW_WARNING_CODES", { enumerable: true, get: function () { return types_js_1.OPENCLAW_WARNING_CODES; } });
23
- // =============================================================================
24
- // Mapper
25
- // =============================================================================
26
- var mapper_js_1 = require("./mapper.js");
27
- Object.defineProperty(exports, "mapToolCallEvent", { enumerable: true, get: function () { return mapper_js_1.mapToolCallEvent; } });
28
- Object.defineProperty(exports, "mapToolCallEventBatch", { enumerable: true, get: function () { return mapper_js_1.mapToolCallEventBatch; } });
29
- Object.defineProperty(exports, "extractWorkflowId", { enumerable: true, get: function () { return mapper_js_1.extractWorkflowId; } });
30
- Object.defineProperty(exports, "buildWorkflowContext", { enumerable: true, get: function () { return mapper_js_1.buildWorkflowContext; } });
31
- var hooks_js_1 = require("./hooks.js");
32
- Object.defineProperty(exports, "createHookHandler", { enumerable: true, get: function () { return hooks_js_1.createHookHandler; } });
33
- Object.defineProperty(exports, "captureBatch", { enumerable: true, get: function () { return hooks_js_1.captureBatch; } });
34
- Object.defineProperty(exports, "captureParallel", { enumerable: true, get: function () { return hooks_js_1.captureParallel; } });
35
- Object.defineProperty(exports, "createSessionHistoryTailer", { enumerable: true, get: function () { return hooks_js_1.createSessionHistoryTailer; } });
36
- var emitter_js_1 = require("./emitter.js");
37
- Object.defineProperty(exports, "createReceiptEmitter", { enumerable: true, get: function () { return emitter_js_1.createReceiptEmitter; } });
38
- Object.defineProperty(exports, "createBackgroundService", { enumerable: true, get: function () { return emitter_js_1.createBackgroundService; } });
39
- var plugin_js_1 = require("./plugin.js");
40
- Object.defineProperty(exports, "createJwkSigner", { enumerable: true, get: function () { return plugin_js_1.createJwkSigner; } });
41
- Object.defineProperty(exports, "resolveSigner", { enumerable: true, get: function () { return plugin_js_1.resolveSigner; } });
42
- Object.defineProperty(exports, "generateKeyId", { enumerable: true, get: function () { return plugin_js_1.generateKeyId; } });
43
- Object.defineProperty(exports, "createFileReceiptWriter", { enumerable: true, get: function () { return plugin_js_1.createFileReceiptWriter; } });
44
- Object.defineProperty(exports, "createPluginInstance", { enumerable: true, get: function () { return plugin_js_1.createPluginInstance; } });
45
- // =============================================================================
46
- // Tools
47
- // =============================================================================
48
- var tools_js_1 = require("./tools.js");
49
- Object.defineProperty(exports, "createStatusTool", { enumerable: true, get: function () { return tools_js_1.createStatusTool; } });
50
- Object.defineProperty(exports, "createExportBundleTool", { enumerable: true, get: function () { return tools_js_1.createExportBundleTool; } });
51
- Object.defineProperty(exports, "createVerifyTool", { enumerable: true, get: function () { return tools_js_1.createVerifyTool; } });
52
- Object.defineProperty(exports, "createQueryTool", { enumerable: true, get: function () { return tools_js_1.createQueryTool; } });
53
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;AA2BH,uCAWoB;AAVlB,iBAAiB;AACjB,mHAAA,uBAAuB,OAAA;AAEvB,cAAc;AACd,gHAAA,oBAAoB,OAAA;AAGpB,gBAAgB;AAChB,kHAAA,sBAAsB,OAAA;AAIxB,gFAAgF;AAChF,SAAS;AACT,gFAAgF;AAEhF,yCAKqB;AAJnB,6GAAA,gBAAgB,OAAA;AAChB,kHAAA,qBAAqB,OAAA;AACrB,8GAAA,iBAAiB,OAAA;AACjB,iHAAA,oBAAoB,OAAA;AAetB,uCAKoB;AAJlB,6GAAA,iBAAiB,OAAA;AACjB,wGAAA,YAAY,OAAA;AACZ,2GAAA,eAAe,OAAA;AACf,sHAAA,0BAA0B,OAAA;AAiB5B,2CAA6E;AAApE,kHAAA,oBAAoB,OAAA;AAAE,qHAAA,uBAAuB,OAAA;AAqBtD,yCAMqB;AALnB,4GAAA,eAAe,OAAA;AACf,0GAAA,aAAa,OAAA;AACb,0GAAA,aAAa,OAAA;AACb,oHAAA,uBAAuB,OAAA;AACvB,iHAAA,oBAAoB,OAAA;AAGtB,gFAAgF;AAChF,QAAQ;AACR,gFAAgF;AAEhF,uCAKoB;AAJlB,4GAAA,gBAAgB,OAAA;AAChB,kHAAA,sBAAsB,OAAA;AACtB,4GAAA,gBAAgB,OAAA;AAChB,2GAAA,eAAe,OAAA"}
package/dist/mapper.js DELETED
@@ -1,320 +0,0 @@
1
- "use strict";
2
- /**
3
- * @peac/adapter-openclaw - Mapper
4
- *
5
- * Maps OpenClaw tool call events to PEAC CapturedAction format.
6
- */
7
- Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.mapToolCallEvent = mapToolCallEvent;
9
- exports.mapToolCallEventBatch = mapToolCallEventBatch;
10
- exports.extractWorkflowId = extractWorkflowId;
11
- exports.buildWorkflowContext = buildWorkflowContext;
12
- const crypto_1 = require("@peac/crypto");
13
- const types_js_1 = require("./types.js");
14
- // =============================================================================
15
- // Constants
16
- // =============================================================================
17
- const DEFAULT_PLATFORM = 'openclaw';
18
- const DEFAULT_KIND = 'tool.call';
19
- // =============================================================================
20
- // Mapper Implementation
21
- // =============================================================================
22
- /**
23
- * Map an OpenClaw tool call event to a PEAC CapturedAction.
24
- *
25
- * @param event - OpenClaw tool call event
26
- * @param config - Adapter configuration
27
- * @returns Mapping result with action or error
28
- */
29
- function mapToolCallEvent(event, config) {
30
- const warnings = [];
31
- // Validate required fields
32
- const validationError = validateRequiredFields(event);
33
- if (validationError) {
34
- return {
35
- success: false,
36
- error_code: validationError.code,
37
- error_message: validationError.message,
38
- };
39
- }
40
- // Build interaction ID (deterministic, for dedupe)
41
- const interactionId = buildInteractionId(event);
42
- // Get capture policy configuration
43
- const captureMode = config?.capture?.mode ?? 'hash_only';
44
- const allowlist = config?.capture?.allowlist ?? [];
45
- const maxPayloadSize = config?.capture?.max_payload_size ?? 1024 * 1024; // 1MB default
46
- // Check if this tool is allowlisted for plaintext capture
47
- const isAllowlisted = captureMode === 'allowlist' && allowlist.includes(event.tool_name);
48
- // Serialize input/output to bytes with policy enforcement
49
- const inputResult = serializePayloadWithPolicy(event.input, maxPayloadSize, isAllowlisted, 'input');
50
- const outputResult = event.output !== undefined
51
- ? serializePayloadWithPolicy(event.output, maxPayloadSize, isAllowlisted, 'output')
52
- : undefined;
53
- // Collect warnings from serialization
54
- if (inputResult.warning) {
55
- warnings.push(inputResult.warning);
56
- }
57
- if (outputResult?.warning) {
58
- warnings.push(outputResult.warning);
59
- }
60
- const inputBytes = inputResult.bytes;
61
- const outputBytes = outputResult?.bytes;
62
- // Build platform metadata
63
- const platform = config?.platform ?? DEFAULT_PLATFORM;
64
- const platformVersion = config?.platform_version;
65
- const pluginId = config?.plugin_id;
66
- // Build OpenClaw-specific extensions
67
- const extensions = buildExtensions(event);
68
- // Build the CapturedAction
69
- const action = {
70
- id: interactionId,
71
- kind: DEFAULT_KIND,
72
- platform,
73
- started_at: event.started_at,
74
- completed_at: event.completed_at,
75
- tool_name: event.tool_name,
76
- tool_provider: event.tool_provider,
77
- input_bytes: inputBytes,
78
- output_bytes: outputBytes,
79
- status: event.status,
80
- error_code: event.error_code,
81
- retryable: event.retryable,
82
- metadata: {
83
- // Platform metadata
84
- ...(platformVersion && { platform_version: platformVersion }),
85
- ...(pluginId && { plugin_id: pluginId }),
86
- // Tool version (not a standard field, stored in metadata)
87
- ...(event.tool_version && { tool_version: event.tool_version }),
88
- // Policy context
89
- ...(event.policy && {
90
- policy_decision: event.policy.decision,
91
- sandbox_enabled: event.policy.sandbox_enabled,
92
- elevated: event.policy.elevated,
93
- policy_hash: event.policy.policy_hash,
94
- }),
95
- // OpenClaw extensions (will be mapped to interaction.extensions)
96
- ...extensions,
97
- },
98
- };
99
- return {
100
- success: true,
101
- action,
102
- warnings: warnings.length > 0 ? warnings : undefined,
103
- };
104
- }
105
- /**
106
- * Build a batch of CapturedActions from OpenClaw events.
107
- *
108
- * @param events - Array of OpenClaw tool call events
109
- * @param config - Adapter configuration
110
- * @returns Array of mapping results
111
- */
112
- function mapToolCallEventBatch(events, config) {
113
- return events.map((event) => mapToolCallEvent(event, config));
114
- }
115
- // =============================================================================
116
- // Helper Functions
117
- // =============================================================================
118
- /**
119
- * Validate required fields in OpenClaw event.
120
- */
121
- function validateRequiredFields(event) {
122
- if (!event.tool_call_id) {
123
- return {
124
- code: types_js_1.OPENCLAW_ERROR_CODES.MISSING_FIELD,
125
- message: 'Missing required field: tool_call_id',
126
- };
127
- }
128
- if (!event.run_id) {
129
- return {
130
- code: types_js_1.OPENCLAW_ERROR_CODES.MISSING_FIELD,
131
- message: 'Missing required field: run_id',
132
- };
133
- }
134
- if (!event.tool_name) {
135
- return {
136
- code: types_js_1.OPENCLAW_ERROR_CODES.MISSING_FIELD,
137
- message: 'Missing required field: tool_name',
138
- };
139
- }
140
- if (!event.started_at) {
141
- return {
142
- code: types_js_1.OPENCLAW_ERROR_CODES.MISSING_FIELD,
143
- message: 'Missing required field: started_at',
144
- };
145
- }
146
- if (!event.status) {
147
- return {
148
- code: types_js_1.OPENCLAW_ERROR_CODES.MISSING_FIELD,
149
- message: 'Missing required field: status',
150
- };
151
- }
152
- // Validate status is a known value
153
- const validStatuses = ['ok', 'error', 'timeout', 'canceled'];
154
- if (!validStatuses.includes(event.status)) {
155
- return {
156
- code: types_js_1.OPENCLAW_ERROR_CODES.INVALID_FIELD,
157
- message: `Invalid status: ${event.status}. Expected one of: ${validStatuses.join(', ')}`,
158
- };
159
- }
160
- // Validate timestamps are RFC 3339
161
- if (!isValidRfc3339(event.started_at)) {
162
- return {
163
- code: types_js_1.OPENCLAW_ERROR_CODES.INVALID_FIELD,
164
- message: `Invalid started_at timestamp: ${event.started_at}. Expected RFC 3339 format.`,
165
- };
166
- }
167
- if (event.completed_at && !isValidRfc3339(event.completed_at)) {
168
- return {
169
- code: types_js_1.OPENCLAW_ERROR_CODES.INVALID_FIELD,
170
- message: `Invalid completed_at timestamp: ${event.completed_at}. Expected RFC 3339 format.`,
171
- };
172
- }
173
- return null;
174
- }
175
- /**
176
- * Build a deterministic interaction ID from OpenClaw event.
177
- *
178
- * Uses base64url encoding to handle delimiter collisions - if run_id or
179
- * tool_call_id contains ':', the ID would be ambiguous without encoding.
180
- *
181
- * Format: openclaw/{base64url(run_id)}/{base64url(tool_call_id)}
182
- */
183
- function buildInteractionId(event) {
184
- const runIdEncoded = base64urlEncode(event.run_id);
185
- const toolCallIdEncoded = base64urlEncode(event.tool_call_id);
186
- return `openclaw/${runIdEncoded}/${toolCallIdEncoded}`;
187
- }
188
- /**
189
- * Base64url encode a string (RFC 4648 section 5).
190
- * URL-safe: replaces + with -, / with _, removes padding.
191
- */
192
- function base64urlEncode(str) {
193
- // Use TextEncoder for proper UTF-8 handling
194
- const bytes = new TextEncoder().encode(str);
195
- // Convert to base64
196
- const base64 = btoa(String.fromCharCode(...bytes));
197
- // Make URL-safe: replace + with -, / with _, remove =
198
- return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
199
- }
200
- /**
201
- * Serialize a payload to bytes with policy enforcement.
202
- *
203
- * Applies:
204
- * - Size limits (truncation if exceeds maxPayloadSize)
205
- * - Redaction policy (hash_only drops bytes for non-allowlisted tools)
206
- *
207
- * @param payload - The payload to serialize
208
- * @param maxPayloadSize - Maximum payload size in bytes
209
- * @param isAllowlisted - Whether this tool is allowlisted for plaintext capture
210
- * @param fieldName - Field name for warning messages
211
- * @returns Serialization result with bytes and/or warning
212
- */
213
- function serializePayloadWithPolicy(payload, maxPayloadSize, isAllowlisted, fieldName) {
214
- if (payload === undefined) {
215
- return {};
216
- }
217
- // Try to serialize using canonical JSON (RFC 8785)
218
- // This ensures deterministic hashes across implementations
219
- let bytes;
220
- try {
221
- const json = (0, crypto_1.canonicalize)(payload);
222
- bytes = new TextEncoder().encode(json);
223
- }
224
- catch {
225
- // Serialization failed (circular references, BigInt, functions, etc.)
226
- return {
227
- warning: {
228
- code: types_js_1.OPENCLAW_WARNING_CODES.SERIALIZATION_FAILED,
229
- message: `${fieldName} payload could not be serialized (circular ref, BigInt, etc.)`,
230
- field: fieldName,
231
- },
232
- };
233
- }
234
- // Check size limit and truncate if needed
235
- let truncated = false;
236
- if (bytes.length > maxPayloadSize) {
237
- bytes = bytes.slice(0, maxPayloadSize);
238
- truncated = true;
239
- }
240
- // Apply redaction policy - capture-core will hash these bytes
241
- // In hash_only mode for non-allowlisted tools, we still pass bytes
242
- // for hashing but could add a warning for transparency
243
- const result = { bytes, truncated };
244
- if (truncated) {
245
- result.warning = {
246
- code: types_js_1.OPENCLAW_WARNING_CODES.PAYLOAD_TRUNCATED,
247
- message: `${fieldName} payload exceeded ${maxPayloadSize} bytes and was truncated`,
248
- field: fieldName,
249
- };
250
- }
251
- return result;
252
- }
253
- /**
254
- * Build OpenClaw-specific extensions for the action metadata.
255
- */
256
- function buildExtensions(event) {
257
- const extensions = {};
258
- // OpenClaw context extension
259
- if (event.context) {
260
- const contextExt = {
261
- ...(event.context.channel && { channel: event.context.channel }),
262
- ...(event.context.workspace_digest && { workspace_digest: event.context.workspace_digest }),
263
- ...(event.context.gateway_version && { gateway_version: event.context.gateway_version }),
264
- tool_call_id: event.tool_call_id,
265
- };
266
- if (Object.keys(contextExt).length > 0) {
267
- extensions[types_js_1.OPENCLAW_EXTENSION_KEYS.CONTEXT] = contextExt;
268
- }
269
- }
270
- else {
271
- // Always include tool_call_id for correlation
272
- extensions[types_js_1.OPENCLAW_EXTENSION_KEYS.CONTEXT] = {
273
- tool_call_id: event.tool_call_id,
274
- };
275
- }
276
- // Security audit digest
277
- if (event.context?.audit_digest) {
278
- extensions[types_js_1.OPENCLAW_EXTENSION_KEYS.AUDIT_DIGEST] = event.context.audit_digest;
279
- }
280
- return extensions;
281
- }
282
- /**
283
- * Check if a string is a valid RFC 3339 timestamp.
284
- */
285
- function isValidRfc3339(timestamp) {
286
- // Basic RFC 3339 pattern (not exhaustive but catches common issues)
287
- const rfc3339Pattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/;
288
- if (!rfc3339Pattern.test(timestamp)) {
289
- return false;
290
- }
291
- // Verify it parses to a valid date
292
- const date = new Date(timestamp);
293
- return !isNaN(date.getTime());
294
- }
295
- // =============================================================================
296
- // Utility Functions
297
- // =============================================================================
298
- /**
299
- * Extract workflow ID from OpenClaw session key.
300
- *
301
- * If session_key is provided, it becomes the workflow_id for correlation.
302
- */
303
- function extractWorkflowId(event) {
304
- return event.session_key;
305
- }
306
- /**
307
- * Build a PEAC-compatible workflow context from OpenClaw event.
308
- */
309
- function buildWorkflowContext(event) {
310
- if (!event.session_key) {
311
- return undefined;
312
- }
313
- return {
314
- workflow_id: event.session_key,
315
- step_id: event.tool_call_id,
316
- tool_name: event.tool_name,
317
- framework: 'openclaw',
318
- };
319
- }
320
- //# sourceMappingURL=mapper.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mapper.js","sourceRoot":"","sources":["../src/mapper.ts"],"names":[],"mappings":"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"}