@renxqoo/renx-code 0.0.4 → 0.0.6

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 (210) hide show
  1. package/README.md +82 -51
  2. package/bin/renx.cjs +16 -0
  3. package/package.json +2 -45
  4. package/src/agent/runtime/runtime.context-usage.test.ts +4 -5
  5. package/src/agent/runtime/runtime.error-handling.test.ts +4 -5
  6. package/src/agent/runtime/runtime.test.ts +7 -4
  7. package/src/agent/runtime/runtime.ts +3 -9
  8. package/src/agent/runtime/runtime.usage-forwarding.test.ts +4 -5
  9. package/src/agent/runtime/source-modules.test.ts +16 -35
  10. package/src/agent/runtime/source-modules.ts +17 -0
  11. package/vendor/agent-root/src/agent/ENTERPRISE_ACCEPTANCE_CHECKLIST.md +95 -0
  12. package/vendor/agent-root/src/agent/ENTERPRISE_REALTIME.html +1345 -0
  13. package/vendor/agent-root/src/agent/ENTERPRISE_REALTIME.md +1353 -0
  14. package/vendor/agent-root/src/agent/ERROR_CONTRACT.md +60 -0
  15. package/vendor/agent-root/src/agent/TEST_COVERAGE_ANALYSIS.md +278 -0
  16. package/vendor/agent-root/src/agent/__test__/error-contract.test.ts +72 -0
  17. package/vendor/agent-root/src/agent/__test__/types.test.ts +137 -0
  18. package/vendor/agent-root/src/agent/agent/__test__/abort-runtime.test.ts +83 -0
  19. package/vendor/agent-root/src/agent/agent/__test__/callback-safety.test.ts +34 -0
  20. package/vendor/agent-root/src/agent/agent/__test__/compaction.test.ts +323 -0
  21. package/vendor/agent-root/src/agent/agent/__test__/concurrency.test.ts +290 -0
  22. package/vendor/agent-root/src/agent/agent/__test__/error-normalizer.test.ts +377 -0
  23. package/vendor/agent-root/src/agent/agent/__test__/error.test.ts +212 -0
  24. package/vendor/agent-root/src/agent/agent/__test__/fault-injection.test.ts +295 -0
  25. package/vendor/agent-root/src/agent/agent/__test__/index.test.ts +3607 -0
  26. package/vendor/agent-root/src/agent/agent/__test__/logger.test.ts +35 -0
  27. package/vendor/agent-root/src/agent/agent/__test__/message-utils.test.ts +517 -0
  28. package/vendor/agent-root/src/agent/agent/__test__/telemetry.test.ts +97 -0
  29. package/vendor/agent-root/src/agent/agent/__test__/timeout-budget.test.ts +479 -0
  30. package/vendor/agent-root/src/agent/agent/__test__/tool-call-merge.test.ts +80 -0
  31. package/vendor/agent-root/src/agent/agent/__test__/tool-execution-ledger.test.ts +76 -0
  32. package/vendor/agent-root/src/agent/agent/__test__/write-buffer.test.ts +173 -0
  33. package/vendor/agent-root/src/agent/agent/__test__/write-file-session.test.ts +109 -0
  34. package/vendor/agent-root/src/agent/agent/abort-runtime.ts +71 -0
  35. package/vendor/agent-root/src/agent/agent/callback-safety.ts +33 -0
  36. package/vendor/agent-root/src/agent/agent/compaction.ts +291 -0
  37. package/vendor/agent-root/src/agent/agent/concurrency.ts +103 -0
  38. package/vendor/agent-root/src/agent/agent/error-normalizer.ts +190 -0
  39. package/vendor/agent-root/src/agent/agent/error.ts +198 -0
  40. package/vendor/agent-root/src/agent/agent/index.ts +1772 -0
  41. package/vendor/agent-root/src/agent/agent/logger.ts +65 -0
  42. package/vendor/agent-root/src/agent/agent/message-utils.ts +101 -0
  43. package/vendor/agent-root/src/agent/agent/stream-events.ts +61 -0
  44. package/vendor/agent-root/src/agent/agent/telemetry.ts +123 -0
  45. package/vendor/agent-root/src/agent/agent/timeout-budget.ts +227 -0
  46. package/vendor/agent-root/src/agent/agent/tool-call-merge.ts +111 -0
  47. package/vendor/agent-root/src/agent/agent/tool-execution-ledger.ts +164 -0
  48. package/vendor/agent-root/src/agent/agent/write-buffer.ts +188 -0
  49. package/vendor/agent-root/src/agent/agent/write-file-session.ts +238 -0
  50. package/vendor/agent-root/src/agent/app/__test__/agent-app-service.test.ts +1053 -0
  51. package/vendor/agent-root/src/agent/app/__test__/minimal-agent-application.test.ts +158 -0
  52. package/vendor/agent-root/src/agent/app/__test__/sqlite-agent-app-store.test.ts +437 -0
  53. package/vendor/agent-root/src/agent/app/agent-app-service.ts +748 -0
  54. package/vendor/agent-root/src/agent/app/contracts.ts +109 -0
  55. package/vendor/agent-root/src/agent/app/index.ts +5 -0
  56. package/vendor/agent-root/src/agent/app/minimal-agent-application.ts +151 -0
  57. package/vendor/agent-root/src/agent/app/ports.ts +72 -0
  58. package/vendor/agent-root/src/agent/app/sqlite-agent-app-store.ts +1182 -0
  59. package/vendor/agent-root/src/agent/app/sqlite-client.ts +177 -0
  60. package/vendor/agent-root/src/agent/docs/cli-app-layer/00-README.md +36 -0
  61. package/vendor/agent-root/src/agent/docs/cli-app-layer/01-scope-and-goals.md +33 -0
  62. package/vendor/agent-root/src/agent/docs/cli-app-layer/02-architecture-overview.md +40 -0
  63. package/vendor/agent-root/src/agent/docs/cli-app-layer/03-domain-model-and-contracts.md +91 -0
  64. package/vendor/agent-root/src/agent/docs/cli-app-layer/04-ports-and-interfaces.md +116 -0
  65. package/vendor/agent-root/src/agent/docs/cli-app-layer/05-run-orchestration-and-state-machine.md +52 -0
  66. package/vendor/agent-root/src/agent/docs/cli-app-layer/06-cli-commands-and-ux.md +53 -0
  67. package/vendor/agent-root/src/agent/docs/cli-app-layer/07-storage-design-local.md +52 -0
  68. package/vendor/agent-root/src/agent/docs/cli-app-layer/08-error-and-observability.md +40 -0
  69. package/vendor/agent-root/src/agent/docs/cli-app-layer/09-security-and-policy-boundary.md +19 -0
  70. package/vendor/agent-root/src/agent/docs/cli-app-layer/10-test-plan-and-acceptance.md +28 -0
  71. package/vendor/agent-root/src/agent/docs/cli-app-layer/11-implementation-phases.md +26 -0
  72. package/vendor/agent-root/src/agent/docs/cli-app-layer/12-open-questions-and-risks.md +30 -0
  73. package/vendor/agent-root/src/agent/docs/cli-app-layer/13-sqlite-schema-fields-and-rationale.md +567 -0
  74. package/vendor/agent-root/src/agent/docs/cli-app-layer/14-project-flow-mermaid.md +583 -0
  75. package/vendor/agent-root/src/agent/docs/cli-app-layer/15-openclaw-style-project-blueprint.md +972 -0
  76. package/vendor/agent-root/src/agent/error-contract.ts +154 -0
  77. package/vendor/agent-root/src/agent/prompts/system.ts +246 -0
  78. package/vendor/agent-root/src/agent/prompts/system1.ts +208 -0
  79. package/vendor/agent-root/src/agent/storage/__test__/file-history-store.test.ts +98 -0
  80. package/vendor/agent-root/src/agent/storage/file-history-store.ts +313 -0
  81. package/vendor/agent-root/src/agent/storage/file-storage-config.ts +94 -0
  82. package/vendor/agent-root/src/agent/storage/file-system.ts +31 -0
  83. package/vendor/agent-root/src/agent/storage/file-write-service.ts +21 -0
  84. package/vendor/agent-root/src/agent/tool/__test__/base-tool.test.ts +413 -0
  85. package/vendor/agent-root/src/agent/tool/__test__/bash-policy.test.ts +356 -0
  86. package/vendor/agent-root/src/agent/tool/__test__/bash.mocked-coverage.test.ts +375 -0
  87. package/vendor/agent-root/src/agent/tool/__test__/bash.test.ts +372 -0
  88. package/vendor/agent-root/src/agent/tool/__test__/error.test.ts +108 -0
  89. package/vendor/agent-root/src/agent/tool/__test__/file-edit-tool.test.ts +258 -0
  90. package/vendor/agent-root/src/agent/tool/__test__/file-history-tools.test.ts +121 -0
  91. package/vendor/agent-root/src/agent/tool/__test__/file-read-tool.test.ts +210 -0
  92. package/vendor/agent-root/src/agent/tool/__test__/glob.test.ts +139 -0
  93. package/vendor/agent-root/src/agent/tool/__test__/grep.mocked-coverage.test.ts +456 -0
  94. package/vendor/agent-root/src/agent/tool/__test__/grep.test.ts +192 -0
  95. package/vendor/agent-root/src/agent/tool/__test__/lsp.test.ts +300 -0
  96. package/vendor/agent-root/src/agent/tool/__test__/outside-workspace-confirmation.test.ts +214 -0
  97. package/vendor/agent-root/src/agent/tool/__test__/path-security.test.ts +336 -0
  98. package/vendor/agent-root/src/agent/tool/__test__/skill-loader.test.ts +494 -0
  99. package/vendor/agent-root/src/agent/tool/__test__/skill-parser.test.ts +543 -0
  100. package/vendor/agent-root/src/agent/tool/__test__/skill-tool.test.ts +172 -0
  101. package/vendor/agent-root/src/agent/tool/__test__/task-concurrency-and-version.test.ts +116 -0
  102. package/vendor/agent-root/src/agent/tool/__test__/task-create-get-list-update.test.ts +267 -0
  103. package/vendor/agent-root/src/agent/tool/__test__/task-create.test.ts +519 -0
  104. package/vendor/agent-root/src/agent/tool/__test__/task-errors.test.ts +225 -0
  105. package/vendor/agent-root/src/agent/tool/__test__/task-output-blocking.test.ts +223 -0
  106. package/vendor/agent-root/src/agent/tool/__test__/task-output.test.ts +184 -0
  107. package/vendor/agent-root/src/agent/tool/__test__/task-parent-abort.test.ts +287 -0
  108. package/vendor/agent-root/src/agent/tool/__test__/task-real-runner-adapter.test.ts +190 -0
  109. package/vendor/agent-root/src/agent/tool/__test__/task-run-lifecycle.test.ts +352 -0
  110. package/vendor/agent-root/src/agent/tool/__test__/task-store-runner-branches.test.ts +395 -0
  111. package/vendor/agent-root/src/agent/tool/__test__/task-store.test.ts +391 -0
  112. package/vendor/agent-root/src/agent/tool/__test__/task-subagent-config-integration.test.ts +176 -0
  113. package/vendor/agent-root/src/agent/tool/__test__/task-subagent-config.test.ts +68 -0
  114. package/vendor/agent-root/src/agent/tool/__test__/task-tools-core-edges.test.ts +630 -0
  115. package/vendor/agent-root/src/agent/tool/__test__/task-tools-runtime-edges.test.ts +732 -0
  116. package/vendor/agent-root/src/agent/tool/__test__/task-types.test.ts +494 -0
  117. package/vendor/agent-root/src/agent/tool/__test__/task-utils-branches.test.ts +175 -0
  118. package/vendor/agent-root/src/agent/tool/__test__/tool-manager.test.ts +505 -0
  119. package/vendor/agent-root/src/agent/tool/__test__/types.test.ts +55 -0
  120. package/vendor/agent-root/src/agent/tool/__test__/web-fetch.test.ts +244 -0
  121. package/vendor/agent-root/src/agent/tool/__test__/web-search.test.ts +290 -0
  122. package/vendor/agent-root/src/agent/tool/__test__/write-file.test.ts +368 -0
  123. package/vendor/agent-root/src/agent/tool/base-tool.ts +345 -0
  124. package/vendor/agent-root/src/agent/tool/bash-policy.ts +636 -0
  125. package/vendor/agent-root/src/agent/tool/bash.ts +688 -0
  126. package/vendor/agent-root/src/agent/tool/error.ts +131 -0
  127. package/vendor/agent-root/src/agent/tool/file-edit-tool.ts +264 -0
  128. package/vendor/agent-root/src/agent/tool/file-history-list.ts +103 -0
  129. package/vendor/agent-root/src/agent/tool/file-history-restore.ts +149 -0
  130. package/vendor/agent-root/src/agent/tool/file-read-tool.ts +211 -0
  131. package/vendor/agent-root/src/agent/tool/glob.ts +171 -0
  132. package/vendor/agent-root/src/agent/tool/grep.ts +496 -0
  133. package/vendor/agent-root/src/agent/tool/lsp.ts +481 -0
  134. package/vendor/agent-root/src/agent/tool/path-security.ts +117 -0
  135. package/vendor/agent-root/src/agent/tool/search/common.ts +153 -0
  136. package/vendor/agent-root/src/agent/tool/skill/index.ts +13 -0
  137. package/vendor/agent-root/src/agent/tool/skill/loader.ts +229 -0
  138. package/vendor/agent-root/src/agent/tool/skill/parser.ts +124 -0
  139. package/vendor/agent-root/src/agent/tool/skill/types.ts +27 -0
  140. package/vendor/agent-root/src/agent/tool/skill-tool.ts +143 -0
  141. package/vendor/agent-root/src/agent/tool/task-create.ts +186 -0
  142. package/vendor/agent-root/src/agent/tool/task-errors.ts +42 -0
  143. package/vendor/agent-root/src/agent/tool/task-get.ts +116 -0
  144. package/vendor/agent-root/src/agent/tool/task-graph.ts +78 -0
  145. package/vendor/agent-root/src/agent/tool/task-list.ts +141 -0
  146. package/vendor/agent-root/src/agent/tool/task-mock-runner-adapter.ts +232 -0
  147. package/vendor/agent-root/src/agent/tool/task-output.ts +223 -0
  148. package/vendor/agent-root/src/agent/tool/task-parent-abort.ts +115 -0
  149. package/vendor/agent-root/src/agent/tool/task-real-runner-adapter.ts +336 -0
  150. package/vendor/agent-root/src/agent/tool/task-runner-adapter.ts +55 -0
  151. package/vendor/agent-root/src/agent/tool/task-stop.ts +187 -0
  152. package/vendor/agent-root/src/agent/tool/task-store.ts +217 -0
  153. package/vendor/agent-root/src/agent/tool/task-subagent-config.ts +149 -0
  154. package/vendor/agent-root/src/agent/tool/task-types.ts +264 -0
  155. package/vendor/agent-root/src/agent/tool/task-update.ts +315 -0
  156. package/vendor/agent-root/src/agent/tool/task.ts +209 -0
  157. package/vendor/agent-root/src/agent/tool/tool-manager.ts +362 -0
  158. package/vendor/agent-root/src/agent/tool/tool-prompts.ts +242 -0
  159. package/vendor/agent-root/src/agent/tool/types.ts +116 -0
  160. package/vendor/agent-root/src/agent/tool/web-fetch.ts +227 -0
  161. package/vendor/agent-root/src/agent/tool/web-search.ts +208 -0
  162. package/vendor/agent-root/src/agent/tool/write-file.ts +497 -0
  163. package/vendor/agent-root/src/agent/types.ts +232 -0
  164. package/vendor/agent-root/src/agent/utils/__tests__/index.test.ts +18 -0
  165. package/vendor/agent-root/src/agent/utils/__tests__/message-utils.test.ts +610 -0
  166. package/vendor/agent-root/src/agent/utils/__tests__/message.test.ts +223 -0
  167. package/vendor/agent-root/src/agent/utils/__tests__/token.test.ts +42 -0
  168. package/vendor/agent-root/src/agent/utils/index.ts +16 -0
  169. package/vendor/agent-root/src/agent/utils/message.ts +171 -0
  170. package/vendor/agent-root/src/agent/utils/token.ts +28 -0
  171. package/vendor/agent-root/src/config/__tests__/load-config-to-env.test.ts +129 -0
  172. package/vendor/agent-root/src/config/__tests__/loader.test.ts +247 -0
  173. package/vendor/agent-root/src/config/__tests__/runtime.test.ts +88 -0
  174. package/vendor/agent-root/src/config/index.ts +54 -0
  175. package/vendor/agent-root/src/config/loader.ts +431 -0
  176. package/vendor/agent-root/src/config/paths.ts +30 -0
  177. package/vendor/agent-root/src/config/runtime.ts +163 -0
  178. package/vendor/agent-root/src/config/types.ts +70 -0
  179. package/vendor/agent-root/src/logger/index.ts +57 -0
  180. package/vendor/agent-root/src/logger/logger.ts +819 -0
  181. package/vendor/agent-root/src/logger/types.ts +150 -0
  182. package/vendor/agent-root/src/providers/__tests__/errors.test.ts +441 -0
  183. package/vendor/agent-root/src/providers/__tests__/index.test.ts +16 -0
  184. package/vendor/agent-root/src/providers/__tests__/openai-compatible.options.test.ts +318 -0
  185. package/vendor/agent-root/src/providers/__tests__/openai-compatible.test.ts +600 -0
  186. package/vendor/agent-root/src/providers/__tests__/registry.test.ts +449 -0
  187. package/vendor/agent-root/src/providers/__tests__/responses-adapter.test.ts +298 -0
  188. package/vendor/agent-root/src/providers/adapters/__tests__/anthropic.test.ts +354 -0
  189. package/vendor/agent-root/src/providers/adapters/__tests__/kimi.test.ts +58 -0
  190. package/vendor/agent-root/src/providers/adapters/__tests__/standard.test.ts +261 -0
  191. package/vendor/agent-root/src/providers/adapters/anthropic.ts +572 -0
  192. package/vendor/agent-root/src/providers/adapters/base.ts +131 -0
  193. package/vendor/agent-root/src/providers/adapters/kimi.ts +48 -0
  194. package/vendor/agent-root/src/providers/adapters/responses.ts +732 -0
  195. package/vendor/agent-root/src/providers/adapters/standard.ts +120 -0
  196. package/vendor/agent-root/src/providers/http/__tests__/client.timeout.test.ts +313 -0
  197. package/vendor/agent-root/src/providers/http/client.ts +289 -0
  198. package/vendor/agent-root/src/providers/http/stream-parser.ts +109 -0
  199. package/vendor/agent-root/src/providers/index.ts +76 -0
  200. package/vendor/agent-root/src/providers/kimi-headers.ts +177 -0
  201. package/vendor/agent-root/src/providers/openai-compatible.ts +387 -0
  202. package/vendor/agent-root/src/providers/registry/model-config.ts +230 -0
  203. package/vendor/agent-root/src/providers/registry/provider-factory.ts +123 -0
  204. package/vendor/agent-root/src/providers/registry.ts +135 -0
  205. package/vendor/agent-root/src/providers/types/api.ts +284 -0
  206. package/vendor/agent-root/src/providers/types/config.ts +58 -0
  207. package/vendor/agent-root/src/providers/types/errors.ts +323 -0
  208. package/vendor/agent-root/src/providers/types/index.ts +72 -0
  209. package/vendor/agent-root/src/providers/types/provider.ts +45 -0
  210. package/vendor/agent-root/src/providers/types/registry.ts +88 -0
@@ -0,0 +1,732 @@
1
+ import { BaseAPIAdapter } from './base';
2
+ import type {
3
+ Chunk,
4
+ InputContentPart,
5
+ LLMRequest,
6
+ LLMRequestMessage,
7
+ LLMResponse,
8
+ LLMResponseMessage,
9
+ Tool,
10
+ ToolCall,
11
+ Usage,
12
+ } from '../types';
13
+
14
+ interface ResponsesInputTextPart {
15
+ type: 'input_text';
16
+ text: string;
17
+ }
18
+
19
+ interface ResponsesOutputTextPart {
20
+ type: 'output_text';
21
+ text: string;
22
+ }
23
+
24
+ interface ResponsesInputImagePart {
25
+ type: 'input_image';
26
+ image_url: string;
27
+ detail?: 'auto' | 'low' | 'high';
28
+ }
29
+
30
+ interface ResponsesInputAudioPart {
31
+ type: 'input_audio';
32
+ input_audio: {
33
+ data: string;
34
+ format: 'wav' | 'mp3';
35
+ };
36
+ }
37
+
38
+ interface ResponsesInputFilePart {
39
+ type: 'input_file';
40
+ file_id?: string;
41
+ file_data?: string;
42
+ filename?: string;
43
+ }
44
+
45
+ type ResponsesInputContentPart =
46
+ | ResponsesInputTextPart
47
+ | ResponsesOutputTextPart
48
+ | ResponsesInputImagePart
49
+ | ResponsesInputAudioPart
50
+ | ResponsesInputFilePart;
51
+
52
+ interface ResponsesMessageItem {
53
+ role: 'system' | 'user' | 'assistant';
54
+ content: string | ResponsesInputContentPart[];
55
+ }
56
+
57
+ interface ResponsesFunctionCallItem {
58
+ type: 'function_call';
59
+ call_id: string;
60
+ name: string;
61
+ arguments: string;
62
+ }
63
+
64
+ interface ResponsesFunctionCallOutputItem {
65
+ type: 'function_call_output';
66
+ call_id: string;
67
+ output: string;
68
+ }
69
+
70
+ type ResponsesInputItem =
71
+ | ResponsesMessageItem
72
+ | ResponsesFunctionCallItem
73
+ | ResponsesFunctionCallOutputItem;
74
+
75
+ interface ResponsesTool {
76
+ type: 'function';
77
+ name: string;
78
+ description?: string;
79
+ parameters?: Record<string, unknown>;
80
+ }
81
+
82
+ interface ResponsesOutputTextContent {
83
+ type: 'output_text';
84
+ text?: string;
85
+ }
86
+
87
+ interface ResponsesOutputMessageItem {
88
+ id?: string;
89
+ type: 'message';
90
+ role?: 'assistant';
91
+ content?: ResponsesOutputTextContent[];
92
+ }
93
+
94
+ interface ResponsesOutputFunctionCallItem {
95
+ id?: string;
96
+ type: 'function_call';
97
+ call_id?: string;
98
+ name?: string;
99
+ arguments?: string;
100
+ }
101
+
102
+ const isResponsesOutputMessageItem = (
103
+ item: ResponsesOutputMessageItem | ResponsesOutputFunctionCallItem | { type?: string }
104
+ ): item is ResponsesOutputMessageItem => item.type === 'message';
105
+
106
+ const isResponsesOutputFunctionCallItem = (
107
+ item: ResponsesOutputMessageItem | ResponsesOutputFunctionCallItem | { type?: string }
108
+ ): item is ResponsesOutputFunctionCallItem => item.type === 'function_call';
109
+
110
+ interface ResponsesUsage {
111
+ input_tokens?: number;
112
+ output_tokens?: number;
113
+ total_tokens?: number;
114
+ [key: string]: unknown;
115
+ }
116
+
117
+ interface ResponsesCompletedResponse {
118
+ id?: string;
119
+ created_at?: number;
120
+ model?: string;
121
+ output?: Array<ResponsesOutputMessageItem | ResponsesOutputFunctionCallItem | { type?: string }>;
122
+ usage?: ResponsesUsage;
123
+ response?: {
124
+ id?: string;
125
+ created_at?: number;
126
+ model?: string;
127
+ output?: Array<
128
+ ResponsesOutputMessageItem | ResponsesOutputFunctionCallItem | { type?: string }
129
+ >;
130
+ usage?: ResponsesUsage;
131
+ };
132
+ }
133
+
134
+ interface ResponsesStreamState {
135
+ responseId?: string;
136
+ model?: string;
137
+ created: number;
138
+ toolCalls: Map<number, { id?: string; name?: string }>;
139
+ }
140
+
141
+ interface ParsedSseEvent {
142
+ type: string;
143
+ data: Record<string, unknown>;
144
+ }
145
+
146
+ export class ResponsesAdapter extends BaseAPIAdapter {
147
+ readonly endpointPath: string;
148
+ readonly defaultModel: string;
149
+
150
+ constructor(options: { endpointPath?: string; defaultModel?: string } = {}) {
151
+ super();
152
+ this.endpointPath = options.endpointPath ?? '/responses';
153
+ this.defaultModel = options.defaultModel ?? 'gpt-5';
154
+ }
155
+
156
+ transformRequest(options?: LLMRequest): Record<string, unknown> {
157
+ if (!options) {
158
+ return {
159
+ model: this.defaultModel,
160
+ input: [],
161
+ store: false,
162
+ };
163
+ }
164
+
165
+ const {
166
+ messages,
167
+ max_tokens,
168
+ model_reasoning_effort,
169
+ stream_options,
170
+ tool_stream,
171
+ thinking,
172
+ abortSignal,
173
+ tools,
174
+ ...rest
175
+ } = options;
176
+ void stream_options;
177
+ void tool_stream;
178
+ void thinking;
179
+ void abortSignal;
180
+
181
+ const extras = Object.fromEntries(
182
+ Object.entries(rest).filter(([, value]) => value !== undefined)
183
+ );
184
+
185
+ const body: Record<string, unknown> = {
186
+ ...extras,
187
+ model: options.model || this.defaultModel,
188
+ input: this.convertMessages(messages || []),
189
+ store: false,
190
+ stream: options.stream ?? false,
191
+ };
192
+
193
+ if (max_tokens !== undefined) {
194
+ body.max_output_tokens = max_tokens;
195
+ }
196
+
197
+ if (model_reasoning_effort) {
198
+ body.reasoning = {
199
+ effort: model_reasoning_effort,
200
+ };
201
+ }
202
+
203
+ if (tools && tools.length > 0) {
204
+ body.tools = tools.map((tool) => this.convertTool(tool));
205
+ }
206
+
207
+ return body;
208
+ }
209
+
210
+ transformResponse(response: unknown): LLMResponse {
211
+ const payload = this.unwrapResponse(response);
212
+ const extracted = this.extractOutput(payload.output || []);
213
+ const message: LLMResponseMessage = {
214
+ role: 'assistant',
215
+ content: extracted.text,
216
+ };
217
+
218
+ if (extracted.toolCalls.length > 0) {
219
+ message.tool_calls = extracted.toolCalls;
220
+ }
221
+
222
+ return {
223
+ id: payload.id || 'response',
224
+ object: 'chat.completion',
225
+ created: payload.created_at || Math.floor(Date.now() / 1000),
226
+ model: payload.model || this.defaultModel,
227
+ choices: [
228
+ {
229
+ index: 0,
230
+ message,
231
+ finish_reason: extracted.toolCalls.length > 0 ? 'tool_calls' : 'stop',
232
+ },
233
+ ],
234
+ usage: this.mapUsage(payload.usage),
235
+ };
236
+ }
237
+
238
+ getHeaders(apiKey: string): Headers {
239
+ return new Headers({
240
+ 'Content-Type': 'application/json',
241
+ Authorization: `Bearer ${apiKey}`,
242
+ });
243
+ }
244
+
245
+ getEndpointPath(): string {
246
+ return this.endpointPath;
247
+ }
248
+
249
+ async *parseStreamAsync(reader: ReadableStreamDefaultReader<Uint8Array>): AsyncGenerator<Chunk> {
250
+ const decoder = new TextDecoder();
251
+ let buffer = '';
252
+ const state: ResponsesStreamState = {
253
+ created: Math.floor(Date.now() / 1000),
254
+ toolCalls: new Map(),
255
+ };
256
+
257
+ try {
258
+ while (true) {
259
+ const { done, value } = await reader.read();
260
+ if (done) {
261
+ if (buffer.trim()) {
262
+ const event = this.parseSseBlock(buffer);
263
+ const parsed = this.parseStreamEvent(event, state);
264
+ if (parsed === 'done') {
265
+ return;
266
+ }
267
+ if (parsed) {
268
+ yield parsed;
269
+ }
270
+ }
271
+ return;
272
+ }
273
+
274
+ buffer += decoder.decode(value, { stream: true });
275
+ const blocks = buffer.split(/\r?\n\r?\n/);
276
+ buffer = blocks.pop() ?? '';
277
+
278
+ for (const block of blocks) {
279
+ const event = this.parseSseBlock(block);
280
+ const parsed = this.parseStreamEvent(event, state);
281
+ if (parsed === 'done') {
282
+ return;
283
+ }
284
+ if (parsed) {
285
+ yield parsed;
286
+ }
287
+ }
288
+ }
289
+ } finally {
290
+ try {
291
+ reader.releaseLock();
292
+ } catch {
293
+ // ignore lock release errors
294
+ }
295
+ }
296
+ }
297
+
298
+ private convertMessages(messages: LLMRequestMessage[]): ResponsesInputItem[] {
299
+ const cleaned = this.cleanMessage(messages as Array<Record<string, unknown>>);
300
+ const items: ResponsesInputItem[] = [];
301
+
302
+ for (const message of cleaned) {
303
+ if (message.role === 'tool') {
304
+ if (!message.tool_call_id) {
305
+ continue;
306
+ }
307
+ items.push({
308
+ type: 'function_call_output',
309
+ call_id: message.tool_call_id,
310
+ output: this.contentToText(message.content),
311
+ });
312
+ continue;
313
+ }
314
+
315
+ const content = this.convertContentParts(message.role, message.content);
316
+ if (content.length > 0 && this.isResponsesMessageRole(message.role)) {
317
+ items.push({
318
+ role: message.role,
319
+ content:
320
+ message.role === 'assistant'
321
+ ? this.normalizeAssistantContent(message.content, content)
322
+ : content,
323
+ });
324
+ }
325
+
326
+ if (message.role === 'assistant' && Array.isArray(message.tool_calls)) {
327
+ // Assistant tool-call turns may legitimately have empty text content.
328
+ // The actual semantic payload is carried by function_call items below.
329
+ for (const toolCall of message.tool_calls) {
330
+ items.push({
331
+ type: 'function_call',
332
+ call_id: toolCall.id,
333
+ name: toolCall.function.name,
334
+ arguments: toolCall.function.arguments,
335
+ });
336
+ }
337
+ }
338
+ }
339
+
340
+ return items;
341
+ }
342
+
343
+ private convertContentParts(
344
+ role: LLMRequestMessage['role'],
345
+ content: LLMRequestMessage['content']
346
+ ): ResponsesInputContentPart[] {
347
+ if (typeof content === 'string') {
348
+ if (content === '') {
349
+ return [];
350
+ }
351
+ return [
352
+ {
353
+ type: role === 'assistant' ? 'output_text' : 'input_text',
354
+ text: content,
355
+ },
356
+ ];
357
+ }
358
+
359
+ if (!Array.isArray(content)) {
360
+ return [];
361
+ }
362
+
363
+ const parts: ResponsesInputContentPart[] = [];
364
+ for (const part of content) {
365
+ const converted = this.convertContentPart(role, part);
366
+ if (converted) {
367
+ parts.push(converted);
368
+ }
369
+ }
370
+ return parts;
371
+ }
372
+
373
+ private convertContentPart(
374
+ role: LLMRequestMessage['role'],
375
+ part: InputContentPart
376
+ ): ResponsesInputContentPart | null {
377
+ switch (part.type) {
378
+ case 'text':
379
+ return {
380
+ type: role === 'assistant' ? 'output_text' : 'input_text',
381
+ text: part.text,
382
+ };
383
+ case 'image_url':
384
+ return {
385
+ type: 'input_image',
386
+ image_url: part.image_url.url,
387
+ detail: part.image_url.detail,
388
+ };
389
+ case 'input_audio':
390
+ return {
391
+ type: 'input_audio',
392
+ input_audio: part.input_audio,
393
+ };
394
+ case 'file':
395
+ return {
396
+ type: 'input_file',
397
+ file_id: part.file.file_id,
398
+ file_data: part.file.file_data,
399
+ filename: part.file.filename,
400
+ };
401
+ case 'input_video':
402
+ return {
403
+ type: 'input_file',
404
+ file_id: part.input_video.file_id,
405
+ file_data: part.input_video.data,
406
+ filename: undefined,
407
+ };
408
+ default:
409
+ return null;
410
+ }
411
+ }
412
+
413
+ private normalizeAssistantContent(
414
+ originalContent: LLMRequestMessage['content'],
415
+ converted: ResponsesInputContentPart[]
416
+ ): string | ResponsesInputContentPart[] {
417
+ if (typeof originalContent === 'string') {
418
+ return originalContent;
419
+ }
420
+
421
+ if (
422
+ converted.length > 0 &&
423
+ converted.every(
424
+ (part) =>
425
+ part.type === 'output_text' ||
426
+ part.type === 'input_audio' ||
427
+ part.type === 'input_file' ||
428
+ part.type === 'input_image'
429
+ )
430
+ ) {
431
+ return converted;
432
+ }
433
+
434
+ return this.contentToText(originalContent);
435
+ }
436
+
437
+ private convertTool(tool: Tool): ResponsesTool {
438
+ return {
439
+ type: 'function',
440
+ name: tool.function.name,
441
+ description: tool.function.description,
442
+ parameters: tool.function.parameters,
443
+ };
444
+ }
445
+
446
+ private unwrapResponse(response: unknown) {
447
+ const payload = response as ResponsesCompletedResponse;
448
+ return payload.response ?? payload;
449
+ }
450
+
451
+ private extractOutput(
452
+ output: Array<ResponsesOutputMessageItem | ResponsesOutputFunctionCallItem | { type?: string }>
453
+ ): {
454
+ text: string;
455
+ toolCalls: ToolCall[];
456
+ } {
457
+ const texts: string[] = [];
458
+ const toolCalls: ToolCall[] = [];
459
+
460
+ for (const item of output) {
461
+ if (isResponsesOutputMessageItem(item)) {
462
+ for (const part of item.content ?? []) {
463
+ if (part.type === 'output_text' && typeof part.text === 'string') {
464
+ texts.push(part.text);
465
+ }
466
+ }
467
+ }
468
+
469
+ if (isResponsesOutputFunctionCallItem(item)) {
470
+ toolCalls.push({
471
+ id: item.call_id || item.id || `call_${toolCalls.length}`,
472
+ type: 'function',
473
+ index: toolCalls.length,
474
+ function: {
475
+ name: item.name || '',
476
+ arguments: item.arguments || '',
477
+ },
478
+ });
479
+ }
480
+ }
481
+
482
+ return {
483
+ text: texts.join(''),
484
+ toolCalls,
485
+ };
486
+ }
487
+
488
+ private mapUsage(usage?: ResponsesUsage): Usage | undefined {
489
+ if (!usage) {
490
+ return undefined;
491
+ }
492
+
493
+ const promptTokens = usage.input_tokens ?? 0;
494
+ const completionTokens = usage.output_tokens ?? 0;
495
+
496
+ return {
497
+ ...usage,
498
+ prompt_tokens: promptTokens,
499
+ completion_tokens: completionTokens,
500
+ total_tokens: usage.total_tokens ?? promptTokens + completionTokens,
501
+ };
502
+ }
503
+
504
+ private parseSseBlock(block: string): ParsedSseEvent | null {
505
+ const lines = block
506
+ .split(/\r?\n/)
507
+ .map((line) => line.trim())
508
+ .filter(Boolean);
509
+ if (lines.length === 0) {
510
+ return null;
511
+ }
512
+
513
+ let type = '';
514
+ const dataLines: string[] = [];
515
+
516
+ for (const line of lines) {
517
+ if (line.startsWith('event:')) {
518
+ type = line.slice('event:'.length).trim();
519
+ } else if (line.startsWith('data:')) {
520
+ dataLines.push(line.slice('data:'.length).trim());
521
+ } else if (line.startsWith('{')) {
522
+ dataLines.push(line);
523
+ }
524
+ }
525
+
526
+ const rawData = dataLines.join('\n');
527
+ if (!rawData || rawData === '[DONE]') {
528
+ return null;
529
+ }
530
+
531
+ let data: Record<string, unknown>;
532
+ try {
533
+ data = JSON.parse(rawData) as Record<string, unknown>;
534
+ } catch {
535
+ return null;
536
+ }
537
+
538
+ return {
539
+ type: type || String(data.type || ''),
540
+ data,
541
+ };
542
+ }
543
+
544
+ private parseStreamEvent(
545
+ event: ParsedSseEvent | null,
546
+ state: ResponsesStreamState
547
+ ): Chunk | 'done' | null {
548
+ if (!event) {
549
+ return null;
550
+ }
551
+
552
+ const { type, data } = event;
553
+
554
+ if (type === 'response.created') {
555
+ const response = (data.response as Record<string, unknown> | undefined) ?? data;
556
+ state.responseId = this.readString(response.id) || state.responseId;
557
+ state.model = this.readString(response.model) || state.model;
558
+ state.created = this.readNumber(response.created_at) || state.created;
559
+ return null;
560
+ }
561
+
562
+ if (type === 'response.output_item.added') {
563
+ const item = data.item as Record<string, unknown> | undefined;
564
+ if (item?.type !== 'function_call') {
565
+ return null;
566
+ }
567
+
568
+ const outputIndex = this.readNumber(data.output_index) ?? 0;
569
+ const toolCallId =
570
+ this.readString(item.call_id) || this.readString(item.id) || `call_${outputIndex}`;
571
+ const name = this.readString(item.name) || '';
572
+ state.toolCalls.set(outputIndex, { id: toolCallId, name });
573
+
574
+ return this.createChunk(state, {
575
+ tool_calls: [
576
+ {
577
+ index: outputIndex,
578
+ id: toolCallId,
579
+ type: 'function',
580
+ function: {
581
+ name,
582
+ arguments: '',
583
+ },
584
+ },
585
+ ],
586
+ });
587
+ }
588
+
589
+ if (type === 'response.function_call_arguments.delta') {
590
+ const outputIndex = this.readNumber(data.output_index) ?? 0;
591
+ const toolState = state.toolCalls.get(outputIndex) || {};
592
+ const delta = this.readString(data.delta) || '';
593
+ const name = this.readString(data.name) || toolState.name || '';
594
+ const id = toolState.id || this.readString(data.call_id) || this.readString(data.item_id);
595
+
596
+ state.toolCalls.set(outputIndex, { id, name });
597
+
598
+ return this.createChunk(state, {
599
+ tool_calls: [
600
+ {
601
+ index: outputIndex,
602
+ id: id || `call_${outputIndex}`,
603
+ type: 'function',
604
+ function: {
605
+ name,
606
+ arguments: delta,
607
+ },
608
+ },
609
+ ],
610
+ });
611
+ }
612
+
613
+ if (type === 'response.output_text.delta') {
614
+ const delta = this.readString(data.delta);
615
+ if (!delta) {
616
+ return null;
617
+ }
618
+
619
+ return this.createChunk(state, {
620
+ content: delta,
621
+ });
622
+ }
623
+
624
+ if (type === 'response.completed') {
625
+ const payload = this.unwrapResponse(data);
626
+ state.responseId = payload.id || state.responseId;
627
+ state.model = payload.model || state.model;
628
+ state.created = payload.created_at || state.created;
629
+
630
+ return {
631
+ id: state.responseId,
632
+ index: 0,
633
+ object: 'chat.completion.chunk',
634
+ created: state.created,
635
+ model: state.model,
636
+ choices: [
637
+ {
638
+ index: 0,
639
+ delta: {
640
+ role: 'assistant',
641
+ content: '',
642
+ },
643
+ finish_reason: 'stop',
644
+ },
645
+ ],
646
+ usage: this.mapUsage(payload.usage),
647
+ };
648
+ }
649
+
650
+ if (type === 'response.failed') {
651
+ const error = data.error as Record<string, unknown> | undefined;
652
+ const message = this.readString(error?.message) || 'Responses stream failed';
653
+ const errorCode = this.readString(error?.code);
654
+ const errorType = this.readString(error?.type) || 'response.failed';
655
+ return {
656
+ id: state.responseId,
657
+ index: 0,
658
+ error: {
659
+ code: errorCode,
660
+ type: errorType,
661
+ message,
662
+ },
663
+ };
664
+ }
665
+
666
+ return null;
667
+ }
668
+
669
+ private createChunk(
670
+ state: ResponsesStreamState,
671
+ delta: Partial<Pick<LLMResponseMessage, 'content' | 'tool_calls'>>
672
+ ): Chunk {
673
+ return {
674
+ id: state.responseId,
675
+ index: 0,
676
+ object: 'chat.completion.chunk',
677
+ created: state.created,
678
+ model: state.model,
679
+ choices: [
680
+ {
681
+ index: 0,
682
+ delta: {
683
+ role: 'assistant',
684
+ content: delta.content ?? '',
685
+ tool_calls: delta.tool_calls,
686
+ },
687
+ },
688
+ ],
689
+ };
690
+ }
691
+
692
+ private isResponsesMessageRole(role: string): role is ResponsesMessageItem['role'] {
693
+ return role === 'system' || role === 'user' || role === 'assistant';
694
+ }
695
+
696
+ private contentToText(content: LLMRequestMessage['content']): string {
697
+ if (typeof content === 'string') {
698
+ return content;
699
+ }
700
+
701
+ if (!Array.isArray(content)) {
702
+ return '';
703
+ }
704
+
705
+ return content
706
+ .map((part) => {
707
+ switch (part.type) {
708
+ case 'text':
709
+ return part.text;
710
+ case 'image_url':
711
+ return part.image_url.url;
712
+ case 'input_audio':
713
+ return part.input_audio.data;
714
+ case 'input_video':
715
+ return part.input_video.url || part.input_video.file_id || part.input_video.data || '';
716
+ case 'file':
717
+ return part.file.file_id || part.file.filename || part.file.file_data || '';
718
+ default:
719
+ return '';
720
+ }
721
+ })
722
+ .join('\n');
723
+ }
724
+
725
+ private readNumber(value: unknown): number | undefined {
726
+ return typeof value === 'number' ? value : undefined;
727
+ }
728
+
729
+ private readString(value: unknown): string | undefined {
730
+ return typeof value === 'string' ? value : undefined;
731
+ }
732
+ }