@a1hvdy/cc-openclaw 0.9.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.
Files changed (227) hide show
  1. package/dist/scripts/bench/ab-harness.d.ts +58 -0
  2. package/dist/scripts/bench/ab-harness.d.ts.map +1 -0
  3. package/dist/scripts/bench/ab-harness.js +78 -0
  4. package/dist/scripts/bench/ab-harness.js.map +1 -0
  5. package/dist/src/channels/adapter.d.ts.map +1 -0
  6. package/dist/src/channels/telegram/completion-summary.d.ts.map +1 -0
  7. package/dist/src/channels/telegram/error-renderer.d.ts.map +1 -0
  8. package/dist/src/channels/telegram/event-reducer.d.ts.map +1 -0
  9. package/dist/src/channels/telegram/index.d.ts.map +1 -0
  10. package/dist/src/channels/telegram/injector.d.ts.map +1 -0
  11. package/dist/src/channels/telegram/live-card.d.ts.map +1 -0
  12. package/dist/src/channels/telegram/state-machine.d.ts.map +1 -0
  13. package/dist/src/channels/telegram/tool-tracker.d.ts.map +1 -0
  14. package/dist/src/command-router/cc-handler.d.ts.map +1 -0
  15. package/dist/src/command-router/index.d.ts.map +1 -0
  16. package/dist/src/constants.d.ts.map +1 -0
  17. package/dist/src/council/consensus.d.ts.map +1 -0
  18. package/dist/src/council/council.d.ts.map +1 -0
  19. package/dist/src/council/index.d.ts.map +1 -0
  20. package/dist/src/engines/base-oneshot-session.d.ts.map +1 -0
  21. package/dist/src/engines/index.d.ts.map +1 -0
  22. package/dist/src/engines/persistent-codex-session.d.ts.map +1 -0
  23. package/dist/src/engines/persistent-cursor-session.d.ts.map +1 -0
  24. package/dist/src/engines/persistent-custom-session.d.ts.map +1 -0
  25. package/dist/src/engines/persistent-gemini-session.d.ts.map +1 -0
  26. package/dist/src/engines/persistent-session.d.ts.map +1 -0
  27. package/dist/src/health/handler.d.ts.map +1 -0
  28. package/dist/src/health/index.d.ts.map +1 -0
  29. package/dist/src/index.d.ts.map +1 -0
  30. package/dist/src/lib/auto-recovery.d.ts.map +1 -0
  31. package/dist/src/lib/cache-parity.d.ts.map +1 -0
  32. package/dist/src/lib/circuit-breaker.d.ts.map +1 -0
  33. package/dist/src/lib/config.d.ts.map +1 -0
  34. package/dist/src/lib/debug-tap.d.ts.map +1 -0
  35. package/dist/src/lib/drift-detector.d.ts.map +1 -0
  36. package/dist/src/lib/error-formatter.d.ts.map +1 -0
  37. package/dist/src/lib/heartbeat-workaround.d.ts.map +1 -0
  38. package/dist/src/lib/index.d.ts.map +1 -0
  39. package/dist/src/lib/register-guard.d.ts.map +1 -0
  40. package/dist/src/lib/req-shape-log.d.ts +31 -0
  41. package/dist/src/lib/req-shape-log.js +106 -0
  42. package/dist/src/lib/req-shape-log.js.map +1 -0
  43. package/dist/src/lib/route-flag.d.ts +49 -0
  44. package/dist/src/lib/route-flag.d.ts.map +1 -0
  45. package/dist/src/lib/route-flag.js +52 -0
  46. package/dist/src/lib/route-flag.js.map +1 -0
  47. package/dist/src/lib/sysprompt-strip.d.ts.map +1 -0
  48. package/dist/src/lib/telemetry.d.ts.map +1 -0
  49. package/dist/src/lib/test-mode.d.ts.map +1 -0
  50. package/dist/src/lib/vendor-paths.d.ts.map +1 -0
  51. package/dist/src/logger.d.ts.map +1 -0
  52. package/dist/src/mcp/bridge.d.ts.map +1 -0
  53. package/dist/src/mcp/index.d.ts.map +1 -0
  54. package/dist/src/models.d.ts.map +1 -0
  55. package/dist/src/openai-compat/cli-stream-parser.d.ts.map +1 -0
  56. package/dist/src/openai-compat/index.d.ts.map +1 -0
  57. package/dist/src/openai-compat/message-extractor.js +31 -3
  58. package/dist/src/openai-compat/message-extractor.js.map +1 -1
  59. package/dist/src/openai-compat/openai-compat.d.ts.map +1 -0
  60. package/dist/src/openai-compat/openai-compat.js +6 -0
  61. package/dist/src/openai-compat/openai-compat.js.map +1 -1
  62. package/dist/src/openai-compat/skill-resolver.d.ts.map +1 -0
  63. package/dist/src/openai-compat/sse-translator.d.ts.map +1 -0
  64. package/dist/src/proxy/anthropic-adapter.d.ts.map +1 -0
  65. package/dist/src/proxy/handler.d.ts.map +1 -0
  66. package/dist/src/proxy/index.d.ts.map +1 -0
  67. package/dist/src/proxy/schema-cleaner.d.ts.map +1 -0
  68. package/dist/src/proxy/thought-cache.d.ts.map +1 -0
  69. package/dist/src/session/embedded-server.d.ts.map +1 -0
  70. package/dist/src/session/inbox-manager.d.ts.map +1 -0
  71. package/dist/src/session/index.d.ts.map +1 -0
  72. package/dist/src/session/session-manager.d.ts.map +1 -0
  73. package/dist/src/session-bootstrap/cwd-patch.d.ts.map +1 -0
  74. package/dist/src/session-bootstrap/index.d.ts.map +1 -0
  75. package/dist/src/session-bootstrap/sysprompt-strip.d.ts.map +1 -0
  76. package/dist/src/session-bootstrap/think-conflict-resolver.d.ts.map +1 -0
  77. package/dist/src/types.d.ts.map +1 -0
  78. package/dist/src/validation.d.ts.map +1 -0
  79. package/dist/tests/_helpers/subprocess-mock.d.ts +35 -0
  80. package/dist/tests/_helpers/subprocess-mock.d.ts.map +1 -0
  81. package/dist/tests/_helpers/subprocess-mock.js +136 -0
  82. package/dist/tests/_helpers/subprocess-mock.js.map +1 -0
  83. package/dist/tests/auto-recovery.test.d.ts +2 -0
  84. package/dist/tests/auto-recovery.test.d.ts.map +1 -0
  85. package/dist/tests/auto-recovery.test.js +189 -0
  86. package/dist/tests/auto-recovery.test.js.map +1 -0
  87. package/dist/tests/bench-harness.test.d.ts +2 -0
  88. package/dist/tests/bench-harness.test.d.ts.map +1 -0
  89. package/dist/tests/bench-harness.test.js +21 -0
  90. package/dist/tests/bench-harness.test.js.map +1 -0
  91. package/dist/tests/cache-parity.test.d.ts +2 -0
  92. package/dist/tests/cache-parity.test.d.ts.map +1 -0
  93. package/dist/tests/cache-parity.test.js +401 -0
  94. package/dist/tests/cache-parity.test.js.map +1 -0
  95. package/dist/tests/command-router.test.d.ts +2 -0
  96. package/dist/tests/command-router.test.d.ts.map +1 -0
  97. package/dist/tests/command-router.test.js +60 -0
  98. package/dist/tests/command-router.test.js.map +1 -0
  99. package/dist/tests/council.test.d.ts +2 -0
  100. package/dist/tests/council.test.d.ts.map +1 -0
  101. package/dist/tests/council.test.js +20 -0
  102. package/dist/tests/council.test.js.map +1 -0
  103. package/dist/tests/drift-detector.test.d.ts +2 -0
  104. package/dist/tests/drift-detector.test.d.ts.map +1 -0
  105. package/dist/tests/drift-detector.test.js +268 -0
  106. package/dist/tests/drift-detector.test.js.map +1 -0
  107. package/dist/tests/eager-bootstrap-gating.test.d.ts +9 -0
  108. package/dist/tests/eager-bootstrap-gating.test.d.ts.map +1 -0
  109. package/dist/tests/eager-bootstrap-gating.test.js +97 -0
  110. package/dist/tests/eager-bootstrap-gating.test.js.map +1 -0
  111. package/dist/tests/engines.test.d.ts +2 -0
  112. package/dist/tests/engines.test.d.ts.map +1 -0
  113. package/dist/tests/engines.test.js +8 -0
  114. package/dist/tests/engines.test.js.map +1 -0
  115. package/dist/tests/error-formatter.test.d.ts +2 -0
  116. package/dist/tests/error-formatter.test.d.ts.map +1 -0
  117. package/dist/tests/error-formatter.test.js +220 -0
  118. package/dist/tests/error-formatter.test.js.map +1 -0
  119. package/dist/tests/health.test.d.ts +2 -0
  120. package/dist/tests/health.test.d.ts.map +1 -0
  121. package/dist/tests/health.test.js +110 -0
  122. package/dist/tests/health.test.js.map +1 -0
  123. package/dist/tests/heartbeat-workaround.test.d.ts +2 -0
  124. package/dist/tests/heartbeat-workaround.test.d.ts.map +1 -0
  125. package/dist/tests/heartbeat-workaround.test.js +90 -0
  126. package/dist/tests/heartbeat-workaround.test.js.map +1 -0
  127. package/dist/tests/index.test.d.ts +2 -0
  128. package/dist/tests/index.test.d.ts.map +1 -0
  129. package/dist/tests/index.test.js +7 -0
  130. package/dist/tests/index.test.js.map +1 -0
  131. package/dist/tests/lib-sysprompt-strip.test.d.ts +2 -0
  132. package/dist/tests/lib-sysprompt-strip.test.d.ts.map +1 -0
  133. package/dist/tests/lib-sysprompt-strip.test.js +145 -0
  134. package/dist/tests/lib-sysprompt-strip.test.js.map +1 -0
  135. package/dist/tests/listener-activation.test.d.ts +2 -0
  136. package/dist/tests/listener-activation.test.d.ts.map +1 -0
  137. package/dist/tests/listener-activation.test.js +87 -0
  138. package/dist/tests/listener-activation.test.js.map +1 -0
  139. package/dist/tests/mcp-bridge.test.d.ts +2 -0
  140. package/dist/tests/mcp-bridge.test.d.ts.map +1 -0
  141. package/dist/tests/mcp-bridge.test.js +137 -0
  142. package/dist/tests/mcp-bridge.test.js.map +1 -0
  143. package/dist/tests/openai-compat.test.d.ts +2 -0
  144. package/dist/tests/openai-compat.test.d.ts.map +1 -0
  145. package/dist/tests/openai-compat.test.js +8 -0
  146. package/dist/tests/openai-compat.test.js.map +1 -0
  147. package/dist/tests/proxy-heartbeat-integration.test.d.ts +15 -0
  148. package/dist/tests/proxy-heartbeat-integration.test.d.ts.map +1 -0
  149. package/dist/tests/proxy-heartbeat-integration.test.js +122 -0
  150. package/dist/tests/proxy-heartbeat-integration.test.js.map +1 -0
  151. package/dist/tests/proxy.test.d.ts +2 -0
  152. package/dist/tests/proxy.test.d.ts.map +1 -0
  153. package/dist/tests/proxy.test.js +8 -0
  154. package/dist/tests/proxy.test.js.map +1 -0
  155. package/dist/tests/register-guard-stacking.test.d.ts +2 -0
  156. package/dist/tests/register-guard-stacking.test.d.ts.map +1 -0
  157. package/dist/tests/register-guard-stacking.test.js +61 -0
  158. package/dist/tests/register-guard-stacking.test.js.map +1 -0
  159. package/dist/tests/register-guard.test.d.ts +2 -0
  160. package/dist/tests/register-guard.test.d.ts.map +1 -0
  161. package/dist/tests/register-guard.test.js +129 -0
  162. package/dist/tests/register-guard.test.js.map +1 -0
  163. package/dist/tests/route-flag-rollback.test.d.ts +2 -0
  164. package/dist/tests/route-flag-rollback.test.d.ts.map +1 -0
  165. package/dist/tests/route-flag-rollback.test.js +70 -0
  166. package/dist/tests/route-flag-rollback.test.js.map +1 -0
  167. package/dist/tests/route-flag.test.d.ts +2 -0
  168. package/dist/tests/route-flag.test.d.ts.map +1 -0
  169. package/dist/tests/route-flag.test.js +101 -0
  170. package/dist/tests/route-flag.test.js.map +1 -0
  171. package/dist/tests/session-bootstrap.test.d.ts +2 -0
  172. package/dist/tests/session-bootstrap.test.d.ts.map +1 -0
  173. package/dist/tests/session-bootstrap.test.js +183 -0
  174. package/dist/tests/session-bootstrap.test.js.map +1 -0
  175. package/dist/tests/session.test.d.ts +2 -0
  176. package/dist/tests/session.test.d.ts.map +1 -0
  177. package/dist/tests/session.test.js +17 -0
  178. package/dist/tests/session.test.js.map +1 -0
  179. package/dist/tests/state-machine.test.d.ts +2 -0
  180. package/dist/tests/state-machine.test.d.ts.map +1 -0
  181. package/dist/tests/state-machine.test.js +133 -0
  182. package/dist/tests/state-machine.test.js.map +1 -0
  183. package/dist/tests/streaming/cli-stream-parser.test.d.ts +2 -0
  184. package/dist/tests/streaming/cli-stream-parser.test.d.ts.map +1 -0
  185. package/dist/tests/streaming/cli-stream-parser.test.js +233 -0
  186. package/dist/tests/streaming/cli-stream-parser.test.js.map +1 -0
  187. package/dist/tests/streaming/feature-flag.test.d.ts +14 -0
  188. package/dist/tests/streaming/feature-flag.test.d.ts.map +1 -0
  189. package/dist/tests/streaming/feature-flag.test.js +163 -0
  190. package/dist/tests/streaming/feature-flag.test.js.map +1 -0
  191. package/dist/tests/streaming/no-tools-prompt.test.d.ts +17 -0
  192. package/dist/tests/streaming/no-tools-prompt.test.d.ts.map +1 -0
  193. package/dist/tests/streaming/no-tools-prompt.test.js +229 -0
  194. package/dist/tests/streaming/no-tools-prompt.test.js.map +1 -0
  195. package/dist/tests/streaming/skill-plus-tools.test.d.ts +14 -0
  196. package/dist/tests/streaming/skill-plus-tools.test.d.ts.map +1 -0
  197. package/dist/tests/streaming/skill-plus-tools.test.js +234 -0
  198. package/dist/tests/streaming/skill-plus-tools.test.js.map +1 -0
  199. package/dist/tests/streaming/sse-translator.test.d.ts +2 -0
  200. package/dist/tests/streaming/sse-translator.test.d.ts.map +1 -0
  201. package/dist/tests/streaming/sse-translator.test.js +227 -0
  202. package/dist/tests/streaming/sse-translator.test.js.map +1 -0
  203. package/dist/tests/streaming/tool-result-roundtrip.test.d.ts +11 -0
  204. package/dist/tests/streaming/tool-result-roundtrip.test.d.ts.map +1 -0
  205. package/dist/tests/streaming/tool-result-roundtrip.test.js +215 -0
  206. package/dist/tests/streaming/tool-result-roundtrip.test.js.map +1 -0
  207. package/dist/tests/streaming/tool-use-translation.test.d.ts +10 -0
  208. package/dist/tests/streaming/tool-use-translation.test.d.ts.map +1 -0
  209. package/dist/tests/streaming/tool-use-translation.test.js +251 -0
  210. package/dist/tests/streaming/tool-use-translation.test.js.map +1 -0
  211. package/dist/tests/telegram-bridge.test.d.ts +2 -0
  212. package/dist/tests/telegram-bridge.test.d.ts.map +1 -0
  213. package/dist/tests/telegram-bridge.test.js +17 -0
  214. package/dist/tests/telegram-bridge.test.js.map +1 -0
  215. package/dist/tests/telegram-injector.test.d.ts +2 -0
  216. package/dist/tests/telegram-injector.test.d.ts.map +1 -0
  217. package/dist/tests/telegram-injector.test.js +74 -0
  218. package/dist/tests/telegram-injector.test.js.map +1 -0
  219. package/dist/tests/telemetry.test.d.ts +2 -0
  220. package/dist/tests/telemetry.test.d.ts.map +1 -0
  221. package/dist/tests/telemetry.test.js +405 -0
  222. package/dist/tests/telemetry.test.js.map +1 -0
  223. package/dist/tests/test-mode.test.d.ts +2 -0
  224. package/dist/tests/test-mode.test.d.ts.map +1 -0
  225. package/dist/tests/test-mode.test.js +39 -0
  226. package/dist/tests/test-mode.test.js.map +1 -0
  227. package/package.json +1 -1
@@ -0,0 +1,163 @@
1
+ // phase: 4 | pillar: 0.5 | agent: P05.B
2
+ /**
3
+ * R5+R13 feature flag test: verifies that CC_OPENCLAW_TOOL_STREAM cleanly
4
+ * switches between legacy (=0) and new (=1) behaviour with no leakage
5
+ * between tests.
6
+ *
7
+ * Covers:
8
+ * - CC_OPENCLAW_TOOL_STREAM=0: legacy XML tool_result wrapping; "no tools"
9
+ * prompt included when tools present
10
+ * - CC_OPENCLAW_TOOL_STREAM=1: new pipeline active; "no tools" prompt
11
+ * suppressed when tools are provided
12
+ * - Env var isolation: no leakage between tests
13
+ */
14
+ import { describe, expect, it, beforeEach, afterEach } from 'vitest';
15
+ import { serializeToolResults, noToolsSystemPrompt, buildSessionSystemPrompt, } from '../../src/openai-compat/openai-compat.js';
16
+ // ─── env management ────────────────────────────────────────────────────────
17
+ let savedEnv = {};
18
+ const FLAG_KEYS = [
19
+ 'CC_OPENCLAW_TOOL_STREAM',
20
+ 'CC_OPENCLAW_ALLOW_BUILTINS',
21
+ 'OPENAI_COMPAT_TOOLS_PER_MESSAGE',
22
+ ];
23
+ beforeEach(() => {
24
+ savedEnv = {};
25
+ for (const k of FLAG_KEYS)
26
+ savedEnv[k] = process.env[k];
27
+ for (const k of FLAG_KEYS)
28
+ delete process.env[k];
29
+ });
30
+ afterEach(() => {
31
+ for (const k of FLAG_KEYS) {
32
+ if (savedEnv[k] === undefined)
33
+ delete process.env[k];
34
+ else
35
+ process.env[k] = savedEnv[k];
36
+ }
37
+ });
38
+ // ─── CC_OPENCLAW_TOOL_STREAM=0 (legacy path) ──────────────────────────────
39
+ describe('feature-flag — CC_OPENCLAW_TOOL_STREAM=0 (legacy)', () => {
40
+ beforeEach(() => {
41
+ process.env.CC_OPENCLAW_TOOL_STREAM = '0';
42
+ });
43
+ it('serializeToolResults still produces XML <tool_result> wrapping', () => {
44
+ const msgs = [
45
+ { role: 'tool', content: 'hello output', tool_call_id: 'toolu_leg' },
46
+ ];
47
+ const result = serializeToolResults(msgs);
48
+ expect(result).toContain('<tool_result tool_call_id="toolu_leg">');
49
+ expect(result).toContain('hello output');
50
+ expect(result).toContain('</tool_result>');
51
+ });
52
+ it('noToolsSystemPrompt still includes "no tools" language', () => {
53
+ const prompt = noToolsSystemPrompt('system');
54
+ // Must contain the proxy/tools guidance text
55
+ expect(prompt.toLowerCase()).toMatch(/tool/);
56
+ expect(prompt.length).toBeGreaterThan(50);
57
+ });
58
+ it('buildSessionSystemPrompt includes tool definitions block when tools provided', () => {
59
+ const tools = [
60
+ {
61
+ type: 'function',
62
+ function: {
63
+ name: 'Bash',
64
+ description: 'Run shell commands',
65
+ parameters: { type: 'object', properties: {} },
66
+ },
67
+ },
68
+ ];
69
+ const prompt = buildSessionSystemPrompt(tools, undefined);
70
+ expect(prompt).toContain('Bash');
71
+ expect(prompt).toContain('available_tools');
72
+ });
73
+ it('CC_OPENCLAW_TOOL_STREAM=0 is not the "new pipeline" path', () => {
74
+ const useToolStream = process.env.CC_OPENCLAW_TOOL_STREAM === '1';
75
+ expect(useToolStream).toBe(false);
76
+ });
77
+ });
78
+ // ─── CC_OPENCLAW_TOOL_STREAM=1 (new pipeline path) ────────────────────────
79
+ describe('feature-flag — CC_OPENCLAW_TOOL_STREAM=1 (new)', () => {
80
+ beforeEach(() => {
81
+ process.env.CC_OPENCLAW_TOOL_STREAM = '1';
82
+ });
83
+ it('CC_OPENCLAW_TOOL_STREAM=1 is detected as the new pipeline path', () => {
84
+ const useToolStream = process.env.CC_OPENCLAW_TOOL_STREAM === '1';
85
+ expect(useToolStream).toBe(true);
86
+ });
87
+ it('serializeToolResults (legacy function) still works unchanged on =1', () => {
88
+ // The serializer function itself is not gated — gating is in the caller.
89
+ // This verifies no side-effect of the flag on the function output.
90
+ const msgs = [
91
+ { role: 'tool', content: 'output', tool_call_id: 'toolu_new' },
92
+ ];
93
+ const result = serializeToolResults(msgs);
94
+ expect(result).toContain('<tool_result');
95
+ expect(result).toContain('toolu_new');
96
+ });
97
+ });
98
+ // ─── Clean switching between flag values ──────────────────────────────────
99
+ describe('feature-flag — clean switching', () => {
100
+ it('flag=0 then flag=1 produces correct detection each time', () => {
101
+ process.env.CC_OPENCLAW_TOOL_STREAM = '0';
102
+ expect(process.env.CC_OPENCLAW_TOOL_STREAM === '1').toBe(false);
103
+ process.env.CC_OPENCLAW_TOOL_STREAM = '1';
104
+ expect(process.env.CC_OPENCLAW_TOOL_STREAM === '1').toBe(true);
105
+ process.env.CC_OPENCLAW_TOOL_STREAM = '0';
106
+ expect(process.env.CC_OPENCLAW_TOOL_STREAM === '1').toBe(false);
107
+ });
108
+ it('flag unset (undefined) defaults to legacy path (not new pipeline)', () => {
109
+ delete process.env.CC_OPENCLAW_TOOL_STREAM;
110
+ const useToolStream = process.env.CC_OPENCLAW_TOOL_STREAM === '1';
111
+ expect(useToolStream).toBe(false);
112
+ });
113
+ it('noToolsSystemPrompt output is stable across flag changes', () => {
114
+ process.env.CC_OPENCLAW_TOOL_STREAM = '0';
115
+ const p0 = noToolsSystemPrompt('system');
116
+ process.env.CC_OPENCLAW_TOOL_STREAM = '1';
117
+ const p1 = noToolsSystemPrompt('system');
118
+ // noToolsSystemPrompt is not directly gated on CC_OPENCLAW_TOOL_STREAM
119
+ expect(p0).toBe(p1);
120
+ });
121
+ });
122
+ // ─── No env-var leakage between tests ─────────────────────────────────────
123
+ describe('feature-flag — env isolation proof', () => {
124
+ it('env is clean at start of test (no CC_OPENCLAW_TOOL_STREAM set)', () => {
125
+ // beforeEach deletes the key; this proves it
126
+ expect(process.env.CC_OPENCLAW_TOOL_STREAM).toBeUndefined();
127
+ });
128
+ it('setting env in one test does not affect next (isolation A)', () => {
129
+ process.env.CC_OPENCLAW_TOOL_STREAM = '1';
130
+ expect(process.env.CC_OPENCLAW_TOOL_STREAM).toBe('1');
131
+ // afterEach will restore it
132
+ });
133
+ it('isolation B — CC_OPENCLAW_TOOL_STREAM is clean again', () => {
134
+ // afterEach from previous test should have cleaned up
135
+ expect(process.env.CC_OPENCLAW_TOOL_STREAM).toBeUndefined();
136
+ });
137
+ it('CC_OPENCLAW_ALLOW_BUILTINS isolation works too', () => {
138
+ process.env.CC_OPENCLAW_ALLOW_BUILTINS = '1';
139
+ expect(process.env.CC_OPENCLAW_ALLOW_BUILTINS).toBe('1');
140
+ });
141
+ it('CC_OPENCLAW_ALLOW_BUILTINS is clean after previous test', () => {
142
+ expect(process.env.CC_OPENCLAW_ALLOW_BUILTINS).toBeUndefined();
143
+ });
144
+ });
145
+ // ─── noToolsSystemPrompt flag interaction ─────────────────────────────────
146
+ describe('feature-flag — noToolsSystemPrompt with CC_OPENCLAW_ALLOW_BUILTINS', () => {
147
+ it('allow-builtins=0: prompt includes "do NOT have direct access" language', () => {
148
+ process.env.CC_OPENCLAW_ALLOW_BUILTINS = '0';
149
+ const prompt = noToolsSystemPrompt('system');
150
+ expect(prompt).toContain('do NOT have direct access');
151
+ });
152
+ it('allow-builtins=1: prompt includes dual tool-source language', () => {
153
+ process.env.CC_OPENCLAW_ALLOW_BUILTINS = '1';
154
+ const prompt = noToolsSystemPrompt('system');
155
+ expect(prompt).toContain('TWO complementary tool sources');
156
+ });
157
+ it('allow-builtins unset defaults to single-source language', () => {
158
+ delete process.env.CC_OPENCLAW_ALLOW_BUILTINS;
159
+ const prompt = noToolsSystemPrompt('system');
160
+ expect(prompt).not.toContain('TWO complementary tool sources');
161
+ });
162
+ });
163
+ //# sourceMappingURL=feature-flag.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature-flag.test.js","sourceRoot":"","sources":["../../../tests/streaming/feature-flag.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * R5 verification: snapshots the system prompt sent to Claude CLI for three
3
+ * cases and asserts that "you have no tools" / restrictive no-tools language
4
+ * is absent when tools are provided.
5
+ *
6
+ * Cases:
7
+ * a) No tools (tools=undefined or tools=[]) → prompt CONTAINS no-tools preamble
8
+ * b) Plain tools provided (tools=[Bash]) → "you have no tools" absent; tool block present
9
+ * c) Skill + tools (/search foo + tools=[Bash]) → skill body AND tool block present;
10
+ * "you have no tools" absent
11
+ *
12
+ * Also tests the conditional gating logic that P05.A implements:
13
+ * - CC_OPENCLAW_TOOL_STREAM=1 + tools.length>0 → no-tools preamble suppressed
14
+ * - CC_OPENCLAW_TOOL_STREAM=0 → legacy path (no-tools preamble always emitted)
15
+ */
16
+ export {};
17
+ //# sourceMappingURL=no-tools-prompt.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-tools-prompt.test.d.ts","sourceRoot":"","sources":["../../../tests/streaming/no-tools-prompt.test.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;GAcG"}
@@ -0,0 +1,229 @@
1
+ // phase: 4 | pillar: 0.5 | agent: P05.B
2
+ /**
3
+ * R5 verification: snapshots the system prompt sent to Claude CLI for three
4
+ * cases and asserts that "you have no tools" / restrictive no-tools language
5
+ * is absent when tools are provided.
6
+ *
7
+ * Cases:
8
+ * a) No tools (tools=undefined or tools=[]) → prompt CONTAINS no-tools preamble
9
+ * b) Plain tools provided (tools=[Bash]) → "you have no tools" absent; tool block present
10
+ * c) Skill + tools (/search foo + tools=[Bash]) → skill body AND tool block present;
11
+ * "you have no tools" absent
12
+ *
13
+ * Also tests the conditional gating logic that P05.A implements:
14
+ * - CC_OPENCLAW_TOOL_STREAM=1 + tools.length>0 → no-tools preamble suppressed
15
+ * - CC_OPENCLAW_TOOL_STREAM=0 → legacy path (no-tools preamble always emitted)
16
+ */
17
+ import { describe, expect, it, beforeEach, afterEach } from 'vitest';
18
+ import * as path from 'node:path';
19
+ import * as os from 'node:os';
20
+ import * as fs from 'node:fs';
21
+ import { buildSessionSystemPrompt, noToolsSystemPrompt, } from '../../src/openai-compat/openai-compat.js';
22
+ import { maybeInlineSkill } from '../../src/openai-compat/skill-resolver.js';
23
+ // ─── env management ────────────────────────────────────────────────────────
24
+ const FLAG_KEYS = ['CC_OPENCLAW_TOOL_STREAM', 'CC_OPENCLAW_ALLOW_BUILTINS', 'OPENCLAW_WORKSPACE_SKILLS_DIR'];
25
+ let savedEnv = {};
26
+ beforeEach(() => {
27
+ savedEnv = {};
28
+ for (const k of FLAG_KEYS)
29
+ savedEnv[k] = process.env[k];
30
+ delete process.env.CC_OPENCLAW_TOOL_STREAM;
31
+ delete process.env.CC_OPENCLAW_ALLOW_BUILTINS;
32
+ });
33
+ afterEach(() => {
34
+ for (const k of FLAG_KEYS) {
35
+ if (savedEnv[k] === undefined)
36
+ delete process.env[k];
37
+ else
38
+ process.env[k] = savedEnv[k];
39
+ }
40
+ });
41
+ // ─── Tool definitions used in tests ───────────────────────────────────────
42
+ const BASH_TOOL = {
43
+ type: 'function',
44
+ function: {
45
+ name: 'Bash',
46
+ description: 'Execute shell commands',
47
+ parameters: { type: 'object', properties: { command: { type: 'string' } }, required: ['command'] },
48
+ },
49
+ };
50
+ const READ_TOOL = {
51
+ type: 'function',
52
+ function: {
53
+ name: 'Read',
54
+ description: 'Read a file',
55
+ parameters: { type: 'object', properties: { file_path: { type: 'string' } }, required: ['file_path'] },
56
+ },
57
+ };
58
+ // The "no tools" sentinel phrase to search for in prompts.
59
+ // R5 requires this to be absent when tools.length > 0.
60
+ const NO_TOOLS_SENTINEL = 'you have no tools';
61
+ // ─── Case A: no tools ──────────────────────────────────────────────────────
62
+ describe('no-tools-prompt — case A: no tools provided', () => {
63
+ it('buildSessionSystemPrompt with no tools includes proxy/tool guidance', () => {
64
+ const prompt = buildSessionSystemPrompt(undefined, undefined);
65
+ // Should contain the no-tools preamble language
66
+ expect(prompt.toLowerCase()).toContain('tool');
67
+ expect(prompt.length).toBeGreaterThan(100);
68
+ });
69
+ it('buildSessionSystemPrompt with empty tools array produces no-tools style prompt', () => {
70
+ const prompt = buildSessionSystemPrompt([], undefined);
71
+ // Empty tools: no rendered <available_tools> block. Note: the preamble
72
+ // text itself mentions "<available_tools>" as prose, so a substring
73
+ // match would false-positive — assert on the closing tag, which only
74
+ // appears when buildToolPromptBlock actually renders content.
75
+ expect(prompt).not.toContain('</available_tools>');
76
+ });
77
+ it('noToolsSystemPrompt includes "not available" or similar restriction language', () => {
78
+ const prompt = noToolsSystemPrompt('system');
79
+ // Must have some statement about tools being limited/unavailable
80
+ const lower = prompt.toLowerCase();
81
+ expect(lower.includes('do not') || lower.includes("don't") || lower.includes('not in')).toBe(true);
82
+ });
83
+ it('system prompt with caller system prompt appended correctly', () => {
84
+ const prompt = buildSessionSystemPrompt(undefined, 'You are a helpful assistant.');
85
+ expect(prompt).toContain('You are a helpful assistant.');
86
+ });
87
+ });
88
+ // ─── Case B: plain tools provided ─────────────────────────────────────────
89
+ describe('no-tools-prompt — case B: plain tools provided', () => {
90
+ it('buildSessionSystemPrompt includes tool name in the prompt block', () => {
91
+ const prompt = buildSessionSystemPrompt([BASH_TOOL], undefined);
92
+ expect(prompt).toContain('Bash');
93
+ });
94
+ it('buildSessionSystemPrompt includes <available_tools> block', () => {
95
+ const prompt = buildSessionSystemPrompt([BASH_TOOL], undefined);
96
+ expect(prompt).toContain('<available_tools>');
97
+ });
98
+ it('does NOT contain "you have no tools" phrase when tools are provided', () => {
99
+ const prompt = buildSessionSystemPrompt([BASH_TOOL], undefined);
100
+ expect(prompt.toLowerCase()).not.toContain(NO_TOOLS_SENTINEL);
101
+ });
102
+ it('includes description and parameters for each tool', () => {
103
+ const prompt = buildSessionSystemPrompt([BASH_TOOL, READ_TOOL], undefined);
104
+ expect(prompt).toContain('Bash');
105
+ expect(prompt).toContain('Execute shell commands');
106
+ expect(prompt).toContain('Read');
107
+ expect(prompt).toContain('Read a file');
108
+ });
109
+ it('multiple tools all appear in the prompt', () => {
110
+ const prompt = buildSessionSystemPrompt([BASH_TOOL, READ_TOOL], undefined);
111
+ expect(prompt).toContain('Bash');
112
+ expect(prompt).toContain('Read');
113
+ });
114
+ it('caller system prompt is appended after the tool block', () => {
115
+ const callerSys = 'You are a specialized assistant.';
116
+ const prompt = buildSessionSystemPrompt([BASH_TOOL], callerSys);
117
+ expect(prompt).toContain(callerSys);
118
+ const toolBlockPos = prompt.indexOf('<available_tools>');
119
+ const callerPos = prompt.indexOf(callerSys);
120
+ expect(toolBlockPos).toBeGreaterThanOrEqual(0);
121
+ expect(callerPos).toBeGreaterThan(toolBlockPos);
122
+ });
123
+ });
124
+ // ─── Case C: tools + skill inline coexist ─────────────────────────────────
125
+ describe('no-tools-prompt — case C: tools + skill inline', () => {
126
+ let tmpSkillsDir;
127
+ beforeEach(() => {
128
+ // Create a temporary skills directory with a mock /search skill
129
+ tmpSkillsDir = fs.mkdtempSync(path.join(os.tmpdir(), 'cc-openclaw-test-skills-'));
130
+ const searchDir = path.join(tmpSkillsDir, 'deep-research');
131
+ fs.mkdirSync(searchDir, { recursive: true });
132
+ fs.writeFileSync(path.join(searchDir, 'SKILL.md'), [
133
+ '---',
134
+ 'name: search',
135
+ '---',
136
+ '# Deep Research Skill',
137
+ '',
138
+ 'This skill performs web research and returns scored results.',
139
+ 'Use WebFetch and WebSearch tools to gather data.',
140
+ ].join('\n'));
141
+ process.env.OPENCLAW_WORKSPACE_SKILLS_DIR = tmpSkillsDir;
142
+ });
143
+ afterEach(() => {
144
+ delete process.env.OPENCLAW_WORKSPACE_SKILLS_DIR;
145
+ fs.rmSync(tmpSkillsDir, { recursive: true, force: true });
146
+ });
147
+ it('maybeInlineSkill returns skill body for /search command', () => {
148
+ const result = maybeInlineSkill('/search latest openclaw release');
149
+ expect(result).not.toBeNull();
150
+ expect(result).toContain('Deep Research Skill');
151
+ expect(result).toContain('latest openclaw release');
152
+ });
153
+ it('inlined skill body does NOT contain "you have no tools"', () => {
154
+ const inlined = maybeInlineSkill('/search foo');
155
+ expect(inlined).not.toBeNull();
156
+ expect(inlined.toLowerCase()).not.toContain(NO_TOOLS_SENTINEL);
157
+ });
158
+ it('session system prompt with tools does NOT contain "you have no tools"', () => {
159
+ // When skill is inlined AND tools are forwarded, the session system prompt
160
+ // (built at session creation) should not have the no-tools restriction.
161
+ const prompt = buildSessionSystemPrompt([BASH_TOOL, READ_TOOL], undefined);
162
+ expect(prompt.toLowerCase()).not.toContain(NO_TOOLS_SENTINEL);
163
+ });
164
+ it('inlined skill body includes both skill content AND user args', () => {
165
+ const result = maybeInlineSkill('/search openclaw streaming pipeline');
166
+ expect(result).toContain('Deep Research Skill');
167
+ expect(result).toContain('openclaw streaming pipeline');
168
+ });
169
+ });
170
+ // ─── R5: conditional no-tools prompt gating logic ─────────────────────────
171
+ describe('no-tools-prompt — R5 conditional gating logic', () => {
172
+ it('tools present → system prompt contains <available_tools>, not no-tools wall', () => {
173
+ const prompt = buildSessionSystemPrompt([BASH_TOOL], undefined);
174
+ // New behaviour: available_tools block present, no restrictive "no tools" wall
175
+ expect(prompt).toContain('<available_tools>');
176
+ expect(prompt.toLowerCase()).not.toContain(NO_TOOLS_SENTINEL);
177
+ });
178
+ it('no tools → system prompt has preamble but no <available_tools> block', () => {
179
+ const prompt = buildSessionSystemPrompt([], undefined);
180
+ // Preamble text mentions "<available_tools>" as prose; assert on the
181
+ // closing tag, which only appears when an actual block is rendered.
182
+ expect(prompt).not.toContain('</available_tools>');
183
+ });
184
+ it('noToolsSystemPrompt("user") includes user-message location hint', () => {
185
+ const prompt = noToolsSystemPrompt('user');
186
+ expect(prompt).toContain('user message');
187
+ });
188
+ it('noToolsSystemPrompt("system") includes system-block location hint', () => {
189
+ const prompt = noToolsSystemPrompt('system');
190
+ expect(prompt).toContain('below');
191
+ });
192
+ it('CC_OPENCLAW_TOOL_STREAM=1 detected as new pipeline — gate logic in caller', () => {
193
+ process.env.CC_OPENCLAW_TOOL_STREAM = '1';
194
+ const useToolStream = process.env.CC_OPENCLAW_TOOL_STREAM === '1';
195
+ // With tools + new pipeline, the caller should NOT call noToolsSystemPrompt
196
+ // This test documents the expected gating condition
197
+ expect(useToolStream).toBe(true);
198
+ });
199
+ it('CC_OPENCLAW_TOOL_STREAM=0 → legacy path uses no-tools preamble unconditionally', () => {
200
+ process.env.CC_OPENCLAW_TOOL_STREAM = '0';
201
+ const useToolStream = process.env.CC_OPENCLAW_TOOL_STREAM === '1';
202
+ expect(useToolStream).toBe(false);
203
+ // Legacy path always calls buildSessionSystemPrompt which includes noToolsSystemPrompt
204
+ const prompt = buildSessionSystemPrompt([BASH_TOOL], undefined);
205
+ // Even in legacy mode, buildSessionSystemPrompt still puts tools in prompt
206
+ expect(prompt).toContain('Bash');
207
+ });
208
+ });
209
+ // ─── Snapshot: three cases side by side ───────────────────────────────────
210
+ describe('no-tools-prompt — three-case comparison snapshot', () => {
211
+ it('case A (no tools) prompt is shorter than case B (with tools) prompt', () => {
212
+ const promptA = buildSessionSystemPrompt([], undefined);
213
+ const promptB = buildSessionSystemPrompt([BASH_TOOL], undefined);
214
+ // Case B has the full tool block, so it must be longer
215
+ expect(promptB.length).toBeGreaterThan(promptA.length);
216
+ });
217
+ it('case B and case C prompts both contain tool name (no "no tools" wall)', () => {
218
+ const promptB = buildSessionSystemPrompt([BASH_TOOL], undefined);
219
+ const promptC = buildSessionSystemPrompt([BASH_TOOL, READ_TOOL], 'research skill context');
220
+ expect(promptB.toLowerCase()).not.toContain(NO_TOOLS_SENTINEL);
221
+ expect(promptC.toLowerCase()).not.toContain(NO_TOOLS_SENTINEL);
222
+ });
223
+ it('case C prompt contains both tool names', () => {
224
+ const promptC = buildSessionSystemPrompt([BASH_TOOL, READ_TOOL], undefined);
225
+ expect(promptC).toContain('Bash');
226
+ expect(promptC).toContain('Read');
227
+ });
228
+ });
229
+ //# sourceMappingURL=no-tools-prompt.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-tools-prompt.test.js","sourceRoot":"","sources":["../../../tests/streaming/no-tools-prompt.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * R6 coexist test: verifies that skill auto-inline AND tools[] forwarding
3
+ * work simultaneously on the same request.
4
+ *
5
+ * Asserts:
6
+ * a) SKILL.md body is present in the user message sent to subprocess
7
+ * b) tools[] array is forwarded to the session (present in sessionConfig)
8
+ *
9
+ * Uses a temporary skills directory so the test is hermetic.
10
+ * Does NOT spawn a real subprocess — verifies the message extraction and
11
+ * session config construction layer (extractUserMessage + buildSessionSystemPrompt).
12
+ */
13
+ export {};
14
+ //# sourceMappingURL=skill-plus-tools.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-plus-tools.test.d.ts","sourceRoot":"","sources":["../../../tests/streaming/skill-plus-tools.test.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;GAWG"}