@a1hvdy/cc-openclaw 0.8.0 → 0.9.1
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/scripts/bench/ab-harness.d.ts +58 -0
- package/dist/scripts/bench/ab-harness.d.ts.map +1 -0
- package/dist/scripts/bench/ab-harness.js +78 -0
- package/dist/scripts/bench/ab-harness.js.map +1 -0
- package/dist/src/channels/adapter.d.ts.map +1 -0
- package/dist/src/channels/telegram/completion-summary.d.ts.map +1 -0
- package/dist/src/channels/telegram/error-renderer.d.ts.map +1 -0
- package/dist/src/channels/telegram/event-reducer.d.ts.map +1 -0
- package/dist/src/channels/telegram/index.d.ts.map +1 -0
- package/dist/src/channels/telegram/injector.d.ts.map +1 -0
- package/dist/src/channels/telegram/live-card.d.ts.map +1 -0
- package/dist/src/channels/telegram/state-machine.d.ts.map +1 -0
- package/dist/src/channels/telegram/tool-tracker.d.ts.map +1 -0
- package/dist/src/command-router/cc-handler.d.ts.map +1 -0
- package/dist/src/command-router/index.d.ts.map +1 -0
- package/dist/src/constants.d.ts.map +1 -0
- package/dist/src/council/consensus.d.ts.map +1 -0
- package/dist/src/council/council.d.ts.map +1 -0
- package/dist/src/council/index.d.ts.map +1 -0
- package/dist/src/engines/base-oneshot-session.d.ts.map +1 -0
- package/dist/src/engines/index.d.ts.map +1 -0
- package/dist/src/engines/persistent-codex-session.d.ts.map +1 -0
- package/dist/src/engines/persistent-cursor-session.d.ts.map +1 -0
- package/dist/src/engines/persistent-custom-session.d.ts.map +1 -0
- package/dist/src/engines/persistent-gemini-session.d.ts.map +1 -0
- package/dist/src/engines/persistent-session.d.ts.map +1 -0
- package/dist/src/health/handler.d.ts.map +1 -0
- package/dist/src/health/index.d.ts.map +1 -0
- package/dist/src/index.d.ts +10 -1
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +47 -7
- package/dist/src/index.js.map +1 -1
- package/dist/src/lib/auto-recovery.d.ts.map +1 -0
- package/dist/src/lib/cache-parity.d.ts.map +1 -0
- package/dist/src/lib/circuit-breaker.d.ts.map +1 -0
- package/dist/src/lib/config-service.d.ts +106 -0
- package/dist/src/lib/config-service.js +217 -0
- package/dist/src/lib/config-service.js.map +1 -0
- package/dist/src/lib/config.d.ts +33 -14
- package/dist/src/lib/config.d.ts.map +1 -0
- package/dist/src/lib/config.js +147 -34
- package/dist/src/lib/config.js.map +1 -1
- package/dist/src/lib/debug-tap.d.ts.map +1 -0
- package/dist/src/lib/drift-detector.d.ts.map +1 -0
- package/dist/src/lib/error-formatter.d.ts.map +1 -0
- package/dist/src/lib/heartbeat-workaround.d.ts.map +1 -0
- package/dist/src/lib/index.d.ts +1 -1
- package/dist/src/lib/index.d.ts.map +1 -0
- package/dist/src/lib/index.js +4 -1
- package/dist/src/lib/index.js.map +1 -1
- package/dist/src/lib/register-guard.d.ts.map +1 -0
- package/dist/src/lib/req-shape-log.d.ts +31 -0
- package/dist/src/lib/req-shape-log.js +106 -0
- package/dist/src/lib/req-shape-log.js.map +1 -0
- package/dist/src/lib/route-flag.d.ts.map +1 -0
- package/dist/src/lib/sysprompt-strip.d.ts.map +1 -0
- package/dist/src/lib/telemetry.d.ts.map +1 -0
- package/dist/src/lib/test-mode.d.ts.map +1 -0
- package/dist/src/lib/vendor-paths.d.ts.map +1 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/src/mcp/bridge.d.ts.map +1 -0
- package/dist/src/mcp/index.d.ts.map +1 -0
- package/dist/src/models.d.ts.map +1 -0
- package/dist/src/openai-compat/cli-stream-parser.d.ts.map +1 -0
- package/dist/src/openai-compat/index.d.ts.map +1 -0
- package/dist/src/openai-compat/message-extractor.d.ts +79 -0
- package/dist/src/openai-compat/message-extractor.js +162 -0
- package/dist/src/openai-compat/message-extractor.js.map +1 -0
- package/dist/src/openai-compat/mode-flags.d.ts +34 -0
- package/dist/src/openai-compat/mode-flags.js +44 -0
- package/dist/src/openai-compat/mode-flags.js.map +1 -0
- package/dist/src/openai-compat/non-streaming-handler.d.ts +26 -0
- package/dist/src/openai-compat/non-streaming-handler.js +108 -0
- package/dist/src/openai-compat/non-streaming-handler.js.map +1 -0
- package/dist/src/openai-compat/openai-compat.d.ts +15 -166
- package/dist/src/openai-compat/openai-compat.d.ts.map +1 -0
- package/dist/src/openai-compat/openai-compat.js +65 -849
- package/dist/src/openai-compat/openai-compat.js.map +1 -1
- package/dist/src/openai-compat/prompts.d.ts +47 -0
- package/dist/src/openai-compat/prompts.js +119 -0
- package/dist/src/openai-compat/prompts.js.map +1 -0
- package/dist/src/openai-compat/response-formatter.d.ts +33 -0
- package/dist/src/openai-compat/response-formatter.js +74 -0
- package/dist/src/openai-compat/response-formatter.js.map +1 -0
- package/dist/src/openai-compat/session-key-resolver.d.ts +41 -0
- package/dist/src/openai-compat/session-key-resolver.js +78 -0
- package/dist/src/openai-compat/session-key-resolver.js.map +1 -0
- package/dist/src/openai-compat/skill-resolver.d.ts.map +1 -0
- package/dist/src/openai-compat/sse-translator.d.ts.map +1 -0
- package/dist/src/openai-compat/status-reporter.d.ts +30 -0
- package/dist/src/openai-compat/status-reporter.js +81 -0
- package/dist/src/openai-compat/status-reporter.js.map +1 -0
- package/dist/src/openai-compat/streaming-handler.d.ts +41 -0
- package/dist/src/openai-compat/streaming-handler.js +294 -0
- package/dist/src/openai-compat/streaming-handler.js.map +1 -0
- package/dist/src/openai-compat/tool-calls-parser.d.ts +34 -0
- package/dist/src/openai-compat/tool-calls-parser.js +93 -0
- package/dist/src/openai-compat/tool-calls-parser.js.map +1 -0
- package/dist/src/openai-compat/tool-results-serializer.d.ts +60 -0
- package/dist/src/openai-compat/tool-results-serializer.js +56 -0
- package/dist/src/openai-compat/tool-results-serializer.js.map +1 -0
- package/dist/src/proxy/anthropic-adapter.d.ts.map +1 -0
- package/dist/src/proxy/handler.d.ts.map +1 -0
- package/dist/src/proxy/index.d.ts.map +1 -0
- package/dist/src/proxy/schema-cleaner.d.ts.map +1 -0
- package/dist/src/proxy/thought-cache.d.ts.map +1 -0
- package/dist/src/session/embedded-server.d.ts.map +1 -0
- package/dist/src/session/inbox-manager.d.ts.map +1 -0
- package/dist/src/session/index.d.ts.map +1 -0
- package/dist/src/session/session-manager.d.ts.map +1 -0
- package/dist/src/session-bootstrap/cwd-patch.d.ts.map +1 -0
- package/dist/src/session-bootstrap/cwd-patch.js +20 -13
- package/dist/src/session-bootstrap/cwd-patch.js.map +1 -1
- package/dist/src/session-bootstrap/index.d.ts.map +1 -0
- package/dist/src/session-bootstrap/sysprompt-strip.d.ts.map +1 -0
- package/dist/src/session-bootstrap/think-conflict-resolver.d.ts.map +1 -0
- package/dist/src/types/index.d.ts +15 -0
- package/dist/src/types/index.js +16 -0
- package/dist/src/types/index.js.map +1 -0
- package/dist/src/types/route.d.ts +41 -0
- package/dist/src/types/route.js +12 -0
- package/dist/src/types/route.js.map +1 -0
- package/dist/src/types/runtime-config.d.ts +161 -0
- package/dist/src/types/runtime-config.js +118 -0
- package/dist/src/types/runtime-config.js.map +1 -0
- package/dist/src/types/session.d.ts +48 -0
- package/dist/src/types/session.js +20 -0
- package/dist/src/types/session.js.map +1 -0
- package/dist/src/types/sse.d.ts +38 -0
- package/dist/src/types/sse.js +12 -0
- package/dist/src/types/sse.js.map +1 -0
- package/dist/src/types/tool-bridge.d.ts +81 -0
- package/dist/src/types/tool-bridge.js +34 -0
- package/dist/src/types/tool-bridge.js.map +1 -0
- package/dist/src/types/upstream.d.ts +652 -0
- package/dist/src/types/upstream.js +145 -0
- package/dist/src/types/upstream.js.map +1 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/validation.d.ts.map +1 -0
- package/dist/tests/_helpers/subprocess-mock.d.ts +35 -0
- package/dist/tests/_helpers/subprocess-mock.d.ts.map +1 -0
- package/dist/tests/_helpers/subprocess-mock.js +136 -0
- package/dist/tests/_helpers/subprocess-mock.js.map +1 -0
- package/dist/tests/auto-recovery.test.d.ts +2 -0
- package/dist/tests/auto-recovery.test.d.ts.map +1 -0
- package/dist/tests/auto-recovery.test.js +189 -0
- package/dist/tests/auto-recovery.test.js.map +1 -0
- package/dist/tests/bench-harness.test.d.ts +2 -0
- package/dist/tests/bench-harness.test.d.ts.map +1 -0
- package/dist/tests/bench-harness.test.js +21 -0
- package/dist/tests/bench-harness.test.js.map +1 -0
- package/dist/tests/cache-parity.test.d.ts +2 -0
- package/dist/tests/cache-parity.test.d.ts.map +1 -0
- package/dist/tests/cache-parity.test.js +401 -0
- package/dist/tests/cache-parity.test.js.map +1 -0
- package/dist/tests/command-router.test.d.ts +2 -0
- package/dist/tests/command-router.test.d.ts.map +1 -0
- package/dist/tests/command-router.test.js +60 -0
- package/dist/tests/command-router.test.js.map +1 -0
- package/dist/tests/council.test.d.ts +2 -0
- package/dist/tests/council.test.d.ts.map +1 -0
- package/dist/tests/council.test.js +20 -0
- package/dist/tests/council.test.js.map +1 -0
- package/dist/tests/drift-detector.test.d.ts +2 -0
- package/dist/tests/drift-detector.test.d.ts.map +1 -0
- package/dist/tests/drift-detector.test.js +268 -0
- package/dist/tests/drift-detector.test.js.map +1 -0
- package/dist/tests/eager-bootstrap-gating.test.d.ts +9 -0
- package/dist/tests/eager-bootstrap-gating.test.d.ts.map +1 -0
- package/dist/tests/eager-bootstrap-gating.test.js +97 -0
- package/dist/tests/eager-bootstrap-gating.test.js.map +1 -0
- package/dist/tests/engines.test.d.ts +2 -0
- package/dist/tests/engines.test.d.ts.map +1 -0
- package/dist/tests/engines.test.js +8 -0
- package/dist/tests/engines.test.js.map +1 -0
- package/dist/tests/error-formatter.test.d.ts +2 -0
- package/dist/tests/error-formatter.test.d.ts.map +1 -0
- package/dist/tests/error-formatter.test.js +220 -0
- package/dist/tests/error-formatter.test.js.map +1 -0
- package/dist/tests/health.test.d.ts +2 -0
- package/dist/tests/health.test.d.ts.map +1 -0
- package/dist/tests/health.test.js +110 -0
- package/dist/tests/health.test.js.map +1 -0
- package/dist/tests/heartbeat-workaround.test.d.ts +2 -0
- package/dist/tests/heartbeat-workaround.test.d.ts.map +1 -0
- package/dist/tests/heartbeat-workaround.test.js +90 -0
- package/dist/tests/heartbeat-workaround.test.js.map +1 -0
- package/dist/tests/index.test.d.ts +2 -0
- package/dist/tests/index.test.d.ts.map +1 -0
- package/dist/tests/index.test.js +7 -0
- package/dist/tests/index.test.js.map +1 -0
- package/dist/tests/lib-sysprompt-strip.test.d.ts +2 -0
- package/dist/tests/lib-sysprompt-strip.test.d.ts.map +1 -0
- package/dist/tests/lib-sysprompt-strip.test.js +145 -0
- package/dist/tests/lib-sysprompt-strip.test.js.map +1 -0
- package/dist/tests/listener-activation.test.d.ts +2 -0
- package/dist/tests/listener-activation.test.d.ts.map +1 -0
- package/dist/tests/listener-activation.test.js +87 -0
- package/dist/tests/listener-activation.test.js.map +1 -0
- package/dist/tests/mcp-bridge.test.d.ts +2 -0
- package/dist/tests/mcp-bridge.test.d.ts.map +1 -0
- package/dist/tests/mcp-bridge.test.js +137 -0
- package/dist/tests/mcp-bridge.test.js.map +1 -0
- package/dist/tests/openai-compat.test.d.ts +2 -0
- package/dist/tests/openai-compat.test.d.ts.map +1 -0
- package/dist/tests/openai-compat.test.js +8 -0
- package/dist/tests/openai-compat.test.js.map +1 -0
- package/dist/tests/proxy-heartbeat-integration.test.d.ts +15 -0
- package/dist/tests/proxy-heartbeat-integration.test.d.ts.map +1 -0
- package/dist/tests/proxy-heartbeat-integration.test.js +122 -0
- package/dist/tests/proxy-heartbeat-integration.test.js.map +1 -0
- package/dist/tests/proxy.test.d.ts +2 -0
- package/dist/tests/proxy.test.d.ts.map +1 -0
- package/dist/tests/proxy.test.js +8 -0
- package/dist/tests/proxy.test.js.map +1 -0
- package/dist/tests/register-guard-stacking.test.d.ts +2 -0
- package/dist/tests/register-guard-stacking.test.d.ts.map +1 -0
- package/dist/tests/register-guard-stacking.test.js +61 -0
- package/dist/tests/register-guard-stacking.test.js.map +1 -0
- package/dist/tests/register-guard.test.d.ts +2 -0
- package/dist/tests/register-guard.test.d.ts.map +1 -0
- package/dist/tests/register-guard.test.js +129 -0
- package/dist/tests/register-guard.test.js.map +1 -0
- package/dist/tests/route-flag-rollback.test.d.ts +2 -0
- package/dist/tests/route-flag-rollback.test.d.ts.map +1 -0
- package/dist/tests/route-flag-rollback.test.js +70 -0
- package/dist/tests/route-flag-rollback.test.js.map +1 -0
- package/dist/tests/route-flag.test.d.ts +2 -0
- package/dist/tests/route-flag.test.d.ts.map +1 -0
- package/dist/tests/route-flag.test.js +101 -0
- package/dist/tests/route-flag.test.js.map +1 -0
- package/dist/tests/session-bootstrap.test.d.ts +2 -0
- package/dist/tests/session-bootstrap.test.d.ts.map +1 -0
- package/dist/tests/session-bootstrap.test.js +183 -0
- package/dist/tests/session-bootstrap.test.js.map +1 -0
- package/dist/tests/session.test.d.ts +2 -0
- package/dist/tests/session.test.d.ts.map +1 -0
- package/dist/tests/session.test.js +17 -0
- package/dist/tests/session.test.js.map +1 -0
- package/dist/tests/state-machine.test.d.ts +2 -0
- package/dist/tests/state-machine.test.d.ts.map +1 -0
- package/dist/tests/state-machine.test.js +133 -0
- package/dist/tests/state-machine.test.js.map +1 -0
- package/dist/tests/streaming/cli-stream-parser.test.d.ts +2 -0
- package/dist/tests/streaming/cli-stream-parser.test.d.ts.map +1 -0
- package/dist/tests/streaming/cli-stream-parser.test.js +233 -0
- package/dist/tests/streaming/cli-stream-parser.test.js.map +1 -0
- package/dist/tests/streaming/feature-flag.test.d.ts +14 -0
- package/dist/tests/streaming/feature-flag.test.d.ts.map +1 -0
- package/dist/tests/streaming/feature-flag.test.js +163 -0
- package/dist/tests/streaming/feature-flag.test.js.map +1 -0
- package/dist/tests/streaming/no-tools-prompt.test.d.ts +17 -0
- package/dist/tests/streaming/no-tools-prompt.test.d.ts.map +1 -0
- package/dist/tests/streaming/no-tools-prompt.test.js +229 -0
- package/dist/tests/streaming/no-tools-prompt.test.js.map +1 -0
- package/dist/tests/streaming/skill-plus-tools.test.d.ts +14 -0
- package/dist/tests/streaming/skill-plus-tools.test.d.ts.map +1 -0
- package/dist/tests/streaming/skill-plus-tools.test.js +234 -0
- package/dist/tests/streaming/skill-plus-tools.test.js.map +1 -0
- package/dist/tests/streaming/sse-translator.test.d.ts +2 -0
- package/dist/tests/streaming/sse-translator.test.d.ts.map +1 -0
- package/dist/tests/streaming/sse-translator.test.js +227 -0
- package/dist/tests/streaming/sse-translator.test.js.map +1 -0
- package/dist/tests/streaming/tool-result-roundtrip.test.d.ts +11 -0
- package/dist/tests/streaming/tool-result-roundtrip.test.d.ts.map +1 -0
- package/dist/tests/streaming/tool-result-roundtrip.test.js +215 -0
- package/dist/tests/streaming/tool-result-roundtrip.test.js.map +1 -0
- package/dist/tests/streaming/tool-use-translation.test.d.ts +10 -0
- package/dist/tests/streaming/tool-use-translation.test.d.ts.map +1 -0
- package/dist/tests/streaming/tool-use-translation.test.js +251 -0
- package/dist/tests/streaming/tool-use-translation.test.js.map +1 -0
- package/dist/tests/telegram-bridge.test.d.ts +2 -0
- package/dist/tests/telegram-bridge.test.d.ts.map +1 -0
- package/dist/tests/telegram-bridge.test.js +17 -0
- package/dist/tests/telegram-bridge.test.js.map +1 -0
- package/dist/tests/telegram-injector.test.d.ts +2 -0
- package/dist/tests/telegram-injector.test.d.ts.map +1 -0
- package/dist/tests/telegram-injector.test.js +74 -0
- package/dist/tests/telegram-injector.test.js.map +1 -0
- package/dist/tests/telemetry.test.d.ts +2 -0
- package/dist/tests/telemetry.test.d.ts.map +1 -0
- package/dist/tests/telemetry.test.js +405 -0
- package/dist/tests/telemetry.test.js.map +1 -0
- package/dist/tests/test-mode.test.d.ts +2 -0
- package/dist/tests/test-mode.test.d.ts.map +1 -0
- package/dist/tests/test-mode.test.js +39 -0
- package/dist/tests/test-mode.test.js.map +1 -0
- package/package.json +3 -2
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
// phase: 4 | pillar: 0.5 | agent: P05.B
|
|
2
|
+
/**
|
|
3
|
+
* R4 integration test: verifies that tool_result messages are serialized into
|
|
4
|
+
* Claude-native tool_result blocks (NOT XML wrapping) when
|
|
5
|
+
* CC_OPENCLAW_TOOL_STREAM=1 is set.
|
|
6
|
+
*
|
|
7
|
+
* Tests the serializeToolResults function exported from openai-compat.ts and
|
|
8
|
+
* the extractUserMessage behaviour when the last message is role:tool.
|
|
9
|
+
* Also asserts that CC_OPENCLAW_TOOL_STREAM=0 preserves the legacy XML path.
|
|
10
|
+
*/
|
|
11
|
+
import { describe, expect, it, beforeEach, afterEach } from 'vitest';
|
|
12
|
+
import { serializeToolResults, extractUserMessage, } from '../../src/openai-compat/openai-compat.js';
|
|
13
|
+
// ─── helpers ──────────────────────────────────────────────────────────────
|
|
14
|
+
function toolMsg(toolCallId, content) {
|
|
15
|
+
return { role: 'tool', content, tool_call_id: toolCallId };
|
|
16
|
+
}
|
|
17
|
+
function userMsg(content) {
|
|
18
|
+
return { role: 'user', content };
|
|
19
|
+
}
|
|
20
|
+
function assistantMsg(toolCallId, toolName, args) {
|
|
21
|
+
return {
|
|
22
|
+
role: 'assistant',
|
|
23
|
+
content: null,
|
|
24
|
+
tool_calls: [{ id: toolCallId, type: 'function', function: { name: toolName, arguments: args } }],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
// ─── Current legacy behaviour: serializeToolResults emits XML ─────────────
|
|
28
|
+
// These tests document CURRENT behaviour (XML). They should remain green
|
|
29
|
+
// regardless of the feature flag because serializeToolResults is still
|
|
30
|
+
// used on the legacy path.
|
|
31
|
+
describe('tool-result-roundtrip — serializeToolResults (current XML path)', () => {
|
|
32
|
+
it('wraps a single tool result in <tool_result> XML', () => {
|
|
33
|
+
const msgs = [toolMsg('toolu_abc', 'file1.txt\nfile2.txt')];
|
|
34
|
+
const result = serializeToolResults(msgs);
|
|
35
|
+
expect(result).toContain('<tool_result tool_call_id="toolu_abc">');
|
|
36
|
+
expect(result).toContain('file1.txt\nfile2.txt');
|
|
37
|
+
expect(result).toContain('</tool_result>');
|
|
38
|
+
expect(result).toContain('<tool_results>');
|
|
39
|
+
expect(result).toContain('</tool_results>');
|
|
40
|
+
});
|
|
41
|
+
it('wraps multiple tool results in separate <tool_result> blocks', () => {
|
|
42
|
+
const msgs = [
|
|
43
|
+
toolMsg('toolu_1', 'result one'),
|
|
44
|
+
toolMsg('toolu_2', 'result two'),
|
|
45
|
+
];
|
|
46
|
+
const result = serializeToolResults(msgs);
|
|
47
|
+
expect(result).toContain('tool_call_id="toolu_1"');
|
|
48
|
+
expect(result).toContain('result one');
|
|
49
|
+
expect(result).toContain('tool_call_id="toolu_2"');
|
|
50
|
+
expect(result).toContain('result two');
|
|
51
|
+
});
|
|
52
|
+
it('returns empty string when no tool messages present', () => {
|
|
53
|
+
const msgs = [userMsg('hello'), { role: 'assistant', content: 'hi' }];
|
|
54
|
+
expect(serializeToolResults(msgs)).toBe('');
|
|
55
|
+
});
|
|
56
|
+
it('handles missing tool_call_id gracefully (uses "unknown")', () => {
|
|
57
|
+
const msg = { role: 'tool', content: 'output', tool_call_id: undefined };
|
|
58
|
+
const result = serializeToolResults([msg]);
|
|
59
|
+
expect(result).toContain('tool_call_id="unknown"');
|
|
60
|
+
});
|
|
61
|
+
it('serializes object content via JSON.stringify', () => {
|
|
62
|
+
const msg = {
|
|
63
|
+
role: 'tool',
|
|
64
|
+
content: [{ type: 'text', text: 'structured' }],
|
|
65
|
+
tool_call_id: 'toolu_x',
|
|
66
|
+
};
|
|
67
|
+
const result = serializeToolResults([msg]);
|
|
68
|
+
expect(result).toContain('structured');
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
// ─── extractUserMessage with tool results ──────────────────────────────────
|
|
72
|
+
describe('tool-result-roundtrip — extractUserMessage with role:tool tail', () => {
|
|
73
|
+
it('detects last message is tool and returns tool result block in userMessage', () => {
|
|
74
|
+
const messages = [
|
|
75
|
+
userMsg('run ls'),
|
|
76
|
+
assistantMsg('toolu_abc', 'Bash', '{"command":"ls"}'),
|
|
77
|
+
toolMsg('toolu_abc', 'file1.txt\nfile2.txt'),
|
|
78
|
+
];
|
|
79
|
+
const extracted = extractUserMessage(messages);
|
|
80
|
+
expect(extracted.userMessage).toContain('toolu_abc');
|
|
81
|
+
expect(extracted.userMessage).toContain('file1.txt');
|
|
82
|
+
expect(extracted.isNewConversation).toBe(false);
|
|
83
|
+
});
|
|
84
|
+
it('appends the last user message text after the tool result block', () => {
|
|
85
|
+
const messages = [
|
|
86
|
+
userMsg('please run ls'),
|
|
87
|
+
assistantMsg('toolu_abc', 'Bash', '{"command":"ls"}'),
|
|
88
|
+
toolMsg('toolu_abc', 'result output'),
|
|
89
|
+
];
|
|
90
|
+
const extracted = extractUserMessage(messages);
|
|
91
|
+
// Tool result block comes first, then the user message text
|
|
92
|
+
const toolResultPos = extracted.userMessage.indexOf('result output');
|
|
93
|
+
const userTextPos = extracted.userMessage.indexOf('please run ls');
|
|
94
|
+
expect(toolResultPos).toBeGreaterThanOrEqual(0);
|
|
95
|
+
expect(userTextPos).toBeGreaterThan(toolResultPos);
|
|
96
|
+
});
|
|
97
|
+
it('handles multiple parallel tool results (all included in block)', () => {
|
|
98
|
+
const messages = [
|
|
99
|
+
userMsg('run both'),
|
|
100
|
+
assistantMsg('toolu_1', 'Bash', '{"command":"ls"}'),
|
|
101
|
+
toolMsg('toolu_1', 'ls output'),
|
|
102
|
+
toolMsg('toolu_2', 'read output'),
|
|
103
|
+
];
|
|
104
|
+
const extracted = extractUserMessage(messages);
|
|
105
|
+
expect(extracted.userMessage).toContain('ls output');
|
|
106
|
+
expect(extracted.userMessage).toContain('read output');
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
// ─── Native tool_result block shape (R4 target) ────────────────────────────
|
|
110
|
+
// These tests verify the NATIVE Claude block format that P05.A will implement.
|
|
111
|
+
// They test the expected output shape directly, asserting the contract that
|
|
112
|
+
// serializeNativeToolResults (to be added by P05.A) must satisfy.
|
|
113
|
+
// Until P05.A lands, these document the target interface.
|
|
114
|
+
describe('tool-result-roundtrip — native Claude block format (R4 contract)', () => {
|
|
115
|
+
/**
|
|
116
|
+
* Inline implementation of the target native serializer as described in
|
|
117
|
+
* the PRP §3.C task 3 and PRP_v1_part2 P05.A task 3.
|
|
118
|
+
*
|
|
119
|
+
* This mirrors what P05.A will implement. Tests here verify the CONTRACT,
|
|
120
|
+
* not a hypothetical future function — we implement it inline to make
|
|
121
|
+
* the test self-contained and runnable before P05.A lands.
|
|
122
|
+
*/
|
|
123
|
+
function serializeNativeToolResults(messages) {
|
|
124
|
+
return messages
|
|
125
|
+
.filter((m) => m.role === 'tool')
|
|
126
|
+
.map((m) => ({
|
|
127
|
+
type: 'tool_result',
|
|
128
|
+
tool_use_id: m.tool_call_id ?? 'unknown',
|
|
129
|
+
content: typeof m.content === 'string' ? m.content : JSON.stringify(m.content),
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
it('produces an array of tool_result blocks (not XML strings)', () => {
|
|
133
|
+
const msgs = [toolMsg('toolu_abc', 'file1.txt')];
|
|
134
|
+
const blocks = serializeNativeToolResults(msgs);
|
|
135
|
+
expect(Array.isArray(blocks)).toBe(true);
|
|
136
|
+
expect(blocks).toHaveLength(1);
|
|
137
|
+
expect(blocks[0].type).toBe('tool_result');
|
|
138
|
+
expect(blocks[0].tool_use_id).toBe('toolu_abc');
|
|
139
|
+
expect(blocks[0].content).toBe('file1.txt');
|
|
140
|
+
});
|
|
141
|
+
it('does NOT contain any XML tags in native block content', () => {
|
|
142
|
+
const msgs = [toolMsg('toolu_abc', 'clean output')];
|
|
143
|
+
const blocks = serializeNativeToolResults(msgs);
|
|
144
|
+
const serialized = JSON.stringify(blocks);
|
|
145
|
+
expect(serialized).not.toContain('<tool_result');
|
|
146
|
+
expect(serialized).not.toContain('</tool_result>');
|
|
147
|
+
expect(serialized).not.toContain('<tool_results>');
|
|
148
|
+
});
|
|
149
|
+
it('handles parallel tool results — one block per tool call', () => {
|
|
150
|
+
const msgs = [
|
|
151
|
+
toolMsg('toolu_1', 'result A'),
|
|
152
|
+
toolMsg('toolu_2', 'result B'),
|
|
153
|
+
];
|
|
154
|
+
const blocks = serializeNativeToolResults(msgs);
|
|
155
|
+
expect(blocks).toHaveLength(2);
|
|
156
|
+
expect(blocks[0].tool_use_id).toBe('toolu_1');
|
|
157
|
+
expect(blocks[1].tool_use_id).toBe('toolu_2');
|
|
158
|
+
});
|
|
159
|
+
it('serializes the block as a user message with content array (Anthropic wire format)', () => {
|
|
160
|
+
const msgs = [toolMsg('toolu_abc', 'output here')];
|
|
161
|
+
const blocks = serializeNativeToolResults(msgs);
|
|
162
|
+
// The wire message to Claude CLI subprocess must be:
|
|
163
|
+
// { role: 'user', content: [{ type: 'tool_result', tool_use_id, content }] }
|
|
164
|
+
const wireMessage = { role: 'user', content: blocks };
|
|
165
|
+
expect(wireMessage.role).toBe('user');
|
|
166
|
+
expect(Array.isArray(wireMessage.content)).toBe(true);
|
|
167
|
+
expect(wireMessage.content[0].type).toBe('tool_result');
|
|
168
|
+
});
|
|
169
|
+
it('object content is JSON-stringified in the content field', () => {
|
|
170
|
+
const msg = {
|
|
171
|
+
role: 'tool',
|
|
172
|
+
content: [{ type: 'text', text: 'structured output' }],
|
|
173
|
+
tool_call_id: 'toolu_obj',
|
|
174
|
+
};
|
|
175
|
+
const blocks = serializeNativeToolResults([msg]);
|
|
176
|
+
expect(blocks[0].content).toBe(JSON.stringify([{ type: 'text', text: 'structured output' }]));
|
|
177
|
+
});
|
|
178
|
+
it('is_error:true round-trip: content is preserved verbatim', () => {
|
|
179
|
+
const msg = {
|
|
180
|
+
role: 'tool',
|
|
181
|
+
content: 'Error: command not found',
|
|
182
|
+
tool_call_id: 'toolu_err',
|
|
183
|
+
};
|
|
184
|
+
const blocks = serializeNativeToolResults([msg]);
|
|
185
|
+
expect(blocks[0].content).toBe('Error: command not found');
|
|
186
|
+
expect(blocks[0].tool_use_id).toBe('toolu_err');
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
// ─── env-var isolation ─────────────────────────────────────────────────────
|
|
190
|
+
describe('tool-result-roundtrip — env isolation', () => {
|
|
191
|
+
const originalEnv = { ...process.env };
|
|
192
|
+
beforeEach(() => {
|
|
193
|
+
// Ensure clean env for each test
|
|
194
|
+
delete process.env.CC_OPENCLAW_TOOL_STREAM;
|
|
195
|
+
});
|
|
196
|
+
afterEach(() => {
|
|
197
|
+
// Restore original env
|
|
198
|
+
for (const key of Object.keys(process.env)) {
|
|
199
|
+
if (!(key in originalEnv))
|
|
200
|
+
delete process.env[key];
|
|
201
|
+
}
|
|
202
|
+
Object.assign(process.env, originalEnv);
|
|
203
|
+
});
|
|
204
|
+
it('serializeToolResults is deterministic regardless of CC_OPENCLAW_TOOL_STREAM', () => {
|
|
205
|
+
const msgs = [toolMsg('toolu_z', 'some output')];
|
|
206
|
+
process.env.CC_OPENCLAW_TOOL_STREAM = '0';
|
|
207
|
+
const result0 = serializeToolResults(msgs);
|
|
208
|
+
process.env.CC_OPENCLAW_TOOL_STREAM = '1';
|
|
209
|
+
const result1 = serializeToolResults(msgs);
|
|
210
|
+
// serializeToolResults itself is not flag-gated — gating happens in the caller
|
|
211
|
+
expect(result0).toBe(result1);
|
|
212
|
+
expect(result0).toContain('<tool_result');
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
//# sourceMappingURL=tool-result-roundtrip.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-result-roundtrip.test.js","sourceRoot":"","sources":["../../../tests/streaming/tool-result-roundtrip.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* R1+R2 integration test: feeds all 6 fixture files through the
|
|
3
|
+
* createCliStreamParser + createSseTranslator pipeline and asserts the
|
|
4
|
+
* OpenAI SSE output is well-formed and semantically correct.
|
|
5
|
+
*
|
|
6
|
+
* This tests the pipeline in isolation (no HTTP, no subprocess) —
|
|
7
|
+
* the same pipeline that P05.A wires into the live path in openai-compat.ts.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=tool-use-translation.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-use-translation.test.d.ts","sourceRoot":"","sources":["../../../tests/streaming/tool-use-translation.test.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG"}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
// phase: 4 | pillar: 0.5 | agent: P05.B
|
|
2
|
+
/**
|
|
3
|
+
* R1+R2 integration test: feeds all 6 fixture files through the
|
|
4
|
+
* createCliStreamParser + createSseTranslator pipeline and asserts the
|
|
5
|
+
* OpenAI SSE output is well-formed and semantically correct.
|
|
6
|
+
*
|
|
7
|
+
* This tests the pipeline in isolation (no HTTP, no subprocess) —
|
|
8
|
+
* the same pipeline that P05.A wires into the live path in openai-compat.ts.
|
|
9
|
+
*/
|
|
10
|
+
import { describe, expect, it } from 'vitest';
|
|
11
|
+
import * as fs from 'node:fs';
|
|
12
|
+
import * as path from 'node:path';
|
|
13
|
+
import { fileURLToPath } from 'node:url';
|
|
14
|
+
import { createCliStreamParser } from '../../src/openai-compat/cli-stream-parser.js';
|
|
15
|
+
import { createSseTranslator } from '../../src/openai-compat/sse-translator.js';
|
|
16
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
17
|
+
const FIXTURES_DIR = path.join(__dirname, 'fixtures');
|
|
18
|
+
function loadFixture(name) {
|
|
19
|
+
return fs.readFileSync(path.join(FIXTURES_DIR, name), 'utf8');
|
|
20
|
+
}
|
|
21
|
+
/** Run fixture through parser+translator pipeline, return all SSE strings. */
|
|
22
|
+
function pipelineFixture(ndjson, completionId = 'chatcmpl-test', model = 'claude-opus-4-7') {
|
|
23
|
+
const parser = createCliStreamParser();
|
|
24
|
+
const translator = createSseTranslator({ completionId, model });
|
|
25
|
+
const events = [];
|
|
26
|
+
// Push in 256-byte chunks to exercise the buffer boundary logic
|
|
27
|
+
for (let i = 0; i < ndjson.length; i += 256) {
|
|
28
|
+
events.push(...parser.push(ndjson.slice(i, i + 256)));
|
|
29
|
+
}
|
|
30
|
+
events.push(...parser.flush());
|
|
31
|
+
const sseChunks = [];
|
|
32
|
+
for (const event of events) {
|
|
33
|
+
sseChunks.push(...translator.translate(event));
|
|
34
|
+
}
|
|
35
|
+
sseChunks.push(...translator.done());
|
|
36
|
+
return sseChunks;
|
|
37
|
+
}
|
|
38
|
+
function parseSseChunk(sse) {
|
|
39
|
+
if (sse === 'data: [DONE]\n\n')
|
|
40
|
+
return { done: true };
|
|
41
|
+
expect(sse.startsWith('data: ')).toBe(true);
|
|
42
|
+
expect(sse.endsWith('\n\n')).toBe(true);
|
|
43
|
+
return JSON.parse(sse.slice('data: '.length, -2));
|
|
44
|
+
}
|
|
45
|
+
// ─── SSE format invariants ─────────────────────────────────────────────────
|
|
46
|
+
describe('tool-use-translation — SSE format invariants (all fixtures)', () => {
|
|
47
|
+
const fixtures = [
|
|
48
|
+
'text-only.ndjson',
|
|
49
|
+
'single-tool-use.ndjson',
|
|
50
|
+
'parallel-tool-use.ndjson',
|
|
51
|
+
'partial-json-deltas.ndjson',
|
|
52
|
+
'message-stop-no-tool.ndjson',
|
|
53
|
+
'tool-use-error.ndjson',
|
|
54
|
+
];
|
|
55
|
+
it.each(fixtures)('%s: every chunk has data: prefix and \\n\\n suffix', (fixture) => {
|
|
56
|
+
const chunks = pipelineFixture(loadFixture(fixture));
|
|
57
|
+
expect(chunks.length).toBeGreaterThan(0);
|
|
58
|
+
for (const chunk of chunks) {
|
|
59
|
+
expect(chunk.startsWith('data: ')).toBe(true);
|
|
60
|
+
expect(chunk.endsWith('\n\n')).toBe(true);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
it.each(fixtures)('%s: last chunk is [DONE]', (fixture) => {
|
|
64
|
+
const chunks = pipelineFixture(loadFixture(fixture));
|
|
65
|
+
expect(chunks[chunks.length - 1]).toBe('data: [DONE]\n\n');
|
|
66
|
+
});
|
|
67
|
+
it.each(fixtures)('%s: non-DONE chunks have id, object, model, choices', (fixture) => {
|
|
68
|
+
const chunks = pipelineFixture(loadFixture(fixture));
|
|
69
|
+
const dataChunks = chunks.slice(0, -1); // all except [DONE]
|
|
70
|
+
for (const chunk of dataChunks) {
|
|
71
|
+
const parsed = parseSseChunk(chunk);
|
|
72
|
+
expect(typeof parsed.id).toBe('string');
|
|
73
|
+
expect(parsed.object).toBe('chat.completion.chunk');
|
|
74
|
+
expect(typeof parsed.model).toBe('string');
|
|
75
|
+
expect(Array.isArray(parsed.choices)).toBe(true);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
// ─── text-only fixture ─────────────────────────────────────────────────────
|
|
80
|
+
describe('tool-use-translation — text-only fixture', () => {
|
|
81
|
+
it('emits content deltas with text and finish_reason=stop', () => {
|
|
82
|
+
const chunks = pipelineFixture(loadFixture('text-only.ndjson'));
|
|
83
|
+
const parsed = chunks.slice(0, -1).map(parseSseChunk);
|
|
84
|
+
const contentChunks = parsed.filter((p) => {
|
|
85
|
+
const choices = p.choices;
|
|
86
|
+
return typeof choices?.[0]?.delta?.content === 'string';
|
|
87
|
+
});
|
|
88
|
+
expect(contentChunks.length).toBeGreaterThan(0);
|
|
89
|
+
const finishChunk = parsed.find((p) => {
|
|
90
|
+
const choices = p.choices;
|
|
91
|
+
return choices?.[0]?.finish_reason !== null;
|
|
92
|
+
});
|
|
93
|
+
expect(finishChunk).toBeDefined();
|
|
94
|
+
const choices = finishChunk.choices;
|
|
95
|
+
expect(choices[0].finish_reason).toBe('stop');
|
|
96
|
+
});
|
|
97
|
+
it('produces no tool_calls deltas for text-only fixture', () => {
|
|
98
|
+
const chunks = pipelineFixture(loadFixture('text-only.ndjson'));
|
|
99
|
+
const parsed = chunks.slice(0, -1).map(parseSseChunk);
|
|
100
|
+
const toolCallChunks = parsed.filter((p) => {
|
|
101
|
+
const choices = p.choices;
|
|
102
|
+
return choices?.[0]?.delta?.tool_calls !== undefined;
|
|
103
|
+
});
|
|
104
|
+
expect(toolCallChunks).toHaveLength(0);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
// ─── single-tool-use fixture ───────────────────────────────────────────────
|
|
108
|
+
describe('tool-use-translation — single-tool-use fixture', () => {
|
|
109
|
+
it('emits a tool_calls start chunk with id, type=function, name, arguments=""', () => {
|
|
110
|
+
const chunks = pipelineFixture(loadFixture('single-tool-use.ndjson'));
|
|
111
|
+
const parsed = chunks.slice(0, -1).map(parseSseChunk);
|
|
112
|
+
const startChunk = parsed.find((p) => {
|
|
113
|
+
const choices = p.choices;
|
|
114
|
+
const tc = choices?.[0]?.delta?.tool_calls;
|
|
115
|
+
return tc?.[0]?.id !== undefined;
|
|
116
|
+
});
|
|
117
|
+
expect(startChunk).toBeDefined();
|
|
118
|
+
const tc = startChunk.choices[0].delta.tool_calls;
|
|
119
|
+
expect(typeof tc[0].id).toBe('string');
|
|
120
|
+
expect(tc[0].type).toBe('function');
|
|
121
|
+
const fn = tc[0].function;
|
|
122
|
+
expect(typeof fn.name).toBe('string');
|
|
123
|
+
expect(fn.arguments).toBe('');
|
|
124
|
+
});
|
|
125
|
+
it('emits argument delta chunks for partial JSON', () => {
|
|
126
|
+
const chunks = pipelineFixture(loadFixture('single-tool-use.ndjson'));
|
|
127
|
+
const parsed = chunks.slice(0, -1).map(parseSseChunk);
|
|
128
|
+
const argChunks = parsed.filter((p) => {
|
|
129
|
+
const choices = p.choices;
|
|
130
|
+
const tc = choices?.[0]?.delta?.tool_calls;
|
|
131
|
+
const fn = tc?.[0]?.function;
|
|
132
|
+
return fn?.arguments !== undefined && fn.arguments !== '';
|
|
133
|
+
});
|
|
134
|
+
expect(argChunks.length).toBeGreaterThan(0);
|
|
135
|
+
});
|
|
136
|
+
it('emits finish_reason=tool_calls for single-tool-use fixture', () => {
|
|
137
|
+
const chunks = pipelineFixture(loadFixture('single-tool-use.ndjson'));
|
|
138
|
+
const parsed = chunks.slice(0, -1).map(parseSseChunk);
|
|
139
|
+
const finishChunk = parsed.find((p) => {
|
|
140
|
+
const choices = p.choices;
|
|
141
|
+
return choices?.[0]?.finish_reason !== null;
|
|
142
|
+
});
|
|
143
|
+
expect(finishChunk).toBeDefined();
|
|
144
|
+
const choices = finishChunk.choices;
|
|
145
|
+
expect(choices[0].finish_reason).toBe('tool_calls');
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
// ─── parallel-tool-use fixture ─────────────────────────────────────────────
|
|
149
|
+
describe('tool-use-translation — parallel-tool-use fixture', () => {
|
|
150
|
+
it('emits tool_calls start chunks with separate tool_call indices (0, 1)', () => {
|
|
151
|
+
const chunks = pipelineFixture(loadFixture('parallel-tool-use.ndjson'));
|
|
152
|
+
const parsed = chunks.slice(0, -1).map(parseSseChunk);
|
|
153
|
+
const startChunks = parsed.filter((p) => {
|
|
154
|
+
const choices = p.choices;
|
|
155
|
+
const tc = choices?.[0]?.delta?.tool_calls;
|
|
156
|
+
return tc?.[0]?.id !== undefined;
|
|
157
|
+
});
|
|
158
|
+
expect(startChunks.length).toBeGreaterThanOrEqual(2);
|
|
159
|
+
const indices = startChunks.map((p) => {
|
|
160
|
+
const choices = p.choices;
|
|
161
|
+
const tc = choices[0].delta.tool_calls;
|
|
162
|
+
return tc[0].index;
|
|
163
|
+
});
|
|
164
|
+
expect(indices).toContain(0);
|
|
165
|
+
expect(indices).toContain(1);
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
// ─── partial-json-deltas fixture ──────────────────────────────────────────
|
|
169
|
+
describe('tool-use-translation — partial-json-deltas fixture', () => {
|
|
170
|
+
it('emits multiple argument delta chunks that concatenate to valid JSON', () => {
|
|
171
|
+
const chunks = pipelineFixture(loadFixture('partial-json-deltas.ndjson'));
|
|
172
|
+
const parsed = chunks.slice(0, -1).map(parseSseChunk);
|
|
173
|
+
const argChunks = parsed.filter((p) => {
|
|
174
|
+
const choices = p.choices;
|
|
175
|
+
const tc = choices?.[0]?.delta?.tool_calls;
|
|
176
|
+
const fn = tc?.[0]?.function;
|
|
177
|
+
return typeof fn?.arguments === 'string' && fn.arguments !== '';
|
|
178
|
+
});
|
|
179
|
+
expect(argChunks.length).toBeGreaterThanOrEqual(2);
|
|
180
|
+
// Concatenated args should form valid JSON
|
|
181
|
+
const accumulated = argChunks
|
|
182
|
+
.map((p) => {
|
|
183
|
+
const choices = p.choices;
|
|
184
|
+
const tc = choices[0].delta.tool_calls;
|
|
185
|
+
const fn = tc[0].function;
|
|
186
|
+
return fn.arguments;
|
|
187
|
+
})
|
|
188
|
+
.join('');
|
|
189
|
+
expect(() => JSON.parse(accumulated)).not.toThrow();
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
// ─── message-stop-no-tool fixture ─────────────────────────────────────────
|
|
193
|
+
describe('tool-use-translation — message-stop-no-tool fixture', () => {
|
|
194
|
+
it('emits finish_reason=stop (not tool_calls)', () => {
|
|
195
|
+
const chunks = pipelineFixture(loadFixture('message-stop-no-tool.ndjson'));
|
|
196
|
+
const parsed = chunks.slice(0, -1).map(parseSseChunk);
|
|
197
|
+
const finishChunk = parsed.find((p) => {
|
|
198
|
+
const choices = p.choices;
|
|
199
|
+
return choices?.[0]?.finish_reason !== null;
|
|
200
|
+
});
|
|
201
|
+
expect(finishChunk).toBeDefined();
|
|
202
|
+
const choices = finishChunk.choices;
|
|
203
|
+
expect(choices[0].finish_reason).toBe('stop');
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
// ─── tool-use-error fixture ────────────────────────────────────────────────
|
|
207
|
+
describe('tool-use-translation — tool-use-error fixture', () => {
|
|
208
|
+
it('produces at least one SSE chunk and terminates with [DONE]', () => {
|
|
209
|
+
const chunks = pipelineFixture(loadFixture('tool-use-error.ndjson'));
|
|
210
|
+
expect(chunks.length).toBeGreaterThan(0);
|
|
211
|
+
expect(chunks[chunks.length - 1]).toBe('data: [DONE]\n\n');
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
// ─── completionId propagation ──────────────────────────────────────────────
|
|
215
|
+
describe('tool-use-translation — completionId propagation', () => {
|
|
216
|
+
it('every non-DONE chunk carries the provided completionId', () => {
|
|
217
|
+
const id = 'chatcmpl-my-specific-id';
|
|
218
|
+
const chunks = pipelineFixture(loadFixture('text-only.ndjson'), id);
|
|
219
|
+
const dataChunks = chunks.slice(0, -1);
|
|
220
|
+
for (const chunk of dataChunks) {
|
|
221
|
+
const parsed = parseSseChunk(chunk);
|
|
222
|
+
expect(parsed.id).toBe(id);
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
// ─── pipeline idempotency across chunk sizes ──────────────────────────────
|
|
227
|
+
describe('tool-use-translation — chunk-size independence', () => {
|
|
228
|
+
function pipelineAtChunkSize(ndjson, chunkSize) {
|
|
229
|
+
const parser = createCliStreamParser();
|
|
230
|
+
const translator = createSseTranslator({ completionId: 'chatcmpl-x', model: 'm' });
|
|
231
|
+
const events = [];
|
|
232
|
+
for (let i = 0; i < ndjson.length; i += chunkSize) {
|
|
233
|
+
events.push(...parser.push(ndjson.slice(i, i + chunkSize)));
|
|
234
|
+
}
|
|
235
|
+
events.push(...parser.flush());
|
|
236
|
+
const out = [];
|
|
237
|
+
for (const e of events)
|
|
238
|
+
out.push(...translator.translate(e));
|
|
239
|
+
out.push(...translator.done());
|
|
240
|
+
return out;
|
|
241
|
+
}
|
|
242
|
+
it('produces identical SSE output at 1, 17, 256 byte chunks (single-tool-use)', () => {
|
|
243
|
+
const ndjson = loadFixture('single-tool-use.ndjson');
|
|
244
|
+
const a = pipelineAtChunkSize(ndjson, 1);
|
|
245
|
+
const b = pipelineAtChunkSize(ndjson, 17);
|
|
246
|
+
const c = pipelineAtChunkSize(ndjson, 256);
|
|
247
|
+
expect(a).toEqual(b);
|
|
248
|
+
expect(b).toEqual(c);
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
//# sourceMappingURL=tool-use-translation.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-use-translation.test.js","sourceRoot":"","sources":["../../../tests/streaming/tool-use-translation.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telegram-bridge.test.d.ts","sourceRoot":"","sources":["../../tests/telegram-bridge.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
+
import { registerLiveCard, registerToolTracker, registerCompletionSummary, registerStateMachine, registerEventReducer, } from '../src/channels/telegram/index.js';
|
|
3
|
+
describe('telegram bridge registers', () => {
|
|
4
|
+
for (const [name, fn] of [
|
|
5
|
+
['live-card', registerLiveCard],
|
|
6
|
+
['tool-tracker', registerToolTracker],
|
|
7
|
+
['completion-summary', registerCompletionSummary],
|
|
8
|
+
['state-machine', registerStateMachine],
|
|
9
|
+
['event-reducer', registerEventReducer],
|
|
10
|
+
]) {
|
|
11
|
+
it(`${name} register() does not throw`, () => {
|
|
12
|
+
const on = vi.fn();
|
|
13
|
+
expect(() => fn({ on })).not.toThrow();
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
//# sourceMappingURL=telegram-bridge.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telegram-bridge.test.js","sourceRoot":"","sources":["../../tests/telegram-bridge.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,yBAAyB,EACzB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,mCAAmC,CAAC;AAE3C,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI;QACvB,CAAC,WAAW,EAAE,gBAAgB,CAAC;QAC/B,CAAC,cAAc,EAAE,mBAAmB,CAAC;QACrC,CAAC,oBAAoB,EAAE,yBAAyB,CAAC;QACjD,CAAC,eAAe,EAAE,oBAAoB,CAAC;QACvC,CAAC,eAAe,EAAE,oBAAoB,CAAC;KAC/B,EAAE,CAAC;QACX,EAAE,CAAC,GAAG,IAAI,4BAA4B,EAAE,GAAG,EAAE;YAC3C,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;YACnB,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACzC,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telegram-injector.test.d.ts","sourceRoot":"","sources":["../../tests/telegram-injector.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
2
|
+
import { register, parseConversationId, cleanStaleEntries, METADATA_TTL_MS, MAX_STORE_SIZE, } from '../src/channels/telegram/injector.js';
|
|
3
|
+
import { defaultRegisterGuard } from '../src/lib/register-guard.js';
|
|
4
|
+
describe('telegram injector register()', () => {
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
defaultRegisterGuard._resetForTests();
|
|
7
|
+
});
|
|
8
|
+
it('wires handlers without crashing', () => {
|
|
9
|
+
const on = vi.fn();
|
|
10
|
+
const api = { on };
|
|
11
|
+
expect(() => register(api)).not.toThrow();
|
|
12
|
+
expect(on).toHaveBeenCalled();
|
|
13
|
+
});
|
|
14
|
+
it('is idempotent for the same api object (centralized register-guard)', () => {
|
|
15
|
+
const on = vi.fn();
|
|
16
|
+
const api = { on };
|
|
17
|
+
register(api);
|
|
18
|
+
const callsAfterFirst = on.mock.calls.length;
|
|
19
|
+
register(api); // same api → guard returns early
|
|
20
|
+
expect(on.mock.calls.length).toBe(callsAfterFirst);
|
|
21
|
+
});
|
|
22
|
+
it('skips when a new api object is provided (id-only tracking — production-correct)', () => {
|
|
23
|
+
// Production reality: openclaw gateway calls register() with different
|
|
24
|
+
// api instances per plugin context, but every api wraps the same shared
|
|
25
|
+
// event bus. Re-firing on new api would stack listeners → doubled
|
|
26
|
+
// greetings. Guard is id-only.
|
|
27
|
+
const onA = vi.fn();
|
|
28
|
+
const onB = vi.fn();
|
|
29
|
+
register({ on: onA });
|
|
30
|
+
register({ on: onB });
|
|
31
|
+
expect(onB).not.toHaveBeenCalled();
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
describe('parseConversationId()', () => {
|
|
35
|
+
it('parses telegram: prefix with topic', () => {
|
|
36
|
+
const result = parseConversationId('telegram:-1001234567:topic:42');
|
|
37
|
+
expect(result).toEqual({ chatId: '-1001234567', threadId: '42' });
|
|
38
|
+
});
|
|
39
|
+
it('parses bare chatId:topic format', () => {
|
|
40
|
+
const result = parseConversationId('-100999:topic:7');
|
|
41
|
+
expect(result).toEqual({ chatId: '-100999', threadId: '7' });
|
|
42
|
+
});
|
|
43
|
+
it('parses telegram: prefix without topic', () => {
|
|
44
|
+
const result = parseConversationId('telegram:-1001234567');
|
|
45
|
+
expect(result).toEqual({ chatId: '-1001234567', threadId: undefined });
|
|
46
|
+
});
|
|
47
|
+
it('parses bare numeric chatId', () => {
|
|
48
|
+
const result = parseConversationId('-1001234567');
|
|
49
|
+
expect(result).toEqual({ chatId: '-1001234567', threadId: undefined });
|
|
50
|
+
});
|
|
51
|
+
it('returns empty chatId for unrecognised format', () => {
|
|
52
|
+
const result = parseConversationId('not-a-chat-id');
|
|
53
|
+
expect(result).toEqual({ chatId: '', threadId: undefined });
|
|
54
|
+
});
|
|
55
|
+
it('handles empty string', () => {
|
|
56
|
+
const result = parseConversationId('');
|
|
57
|
+
expect(result).toEqual({ chatId: '', threadId: undefined });
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
describe('cleanStaleEntries()', () => {
|
|
61
|
+
it('is a callable function', () => {
|
|
62
|
+
expect(typeof cleanStaleEntries).toBe('function');
|
|
63
|
+
expect(() => cleanStaleEntries()).not.toThrow();
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
describe('exported constants', () => {
|
|
67
|
+
it('METADATA_TTL_MS is 5 minutes in ms', () => {
|
|
68
|
+
expect(METADATA_TTL_MS).toBe(5 * 60 * 1000);
|
|
69
|
+
});
|
|
70
|
+
it('MAX_STORE_SIZE is 100', () => {
|
|
71
|
+
expect(MAX_STORE_SIZE).toBe(100);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
//# sourceMappingURL=telegram-injector.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telegram-injector.test.js","sourceRoot":"","sources":["../../tests/telegram-injector.test.ts"],"names":[],"mappings":"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"}
|