llm-mock-server 1.0.6 → 1.0.7

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 (250) hide show
  1. package/dist/cli/cli.d.ts +3 -0
  2. package/dist/cli/cli.d.ts.map +1 -0
  3. package/dist/cli/cli.js +103 -0
  4. package/dist/cli/cli.js.map +1 -0
  5. package/dist/cli/validators.d.ts +7 -0
  6. package/dist/cli/validators.d.ts.map +1 -0
  7. package/dist/cli/validators.js +53 -0
  8. package/dist/cli/validators.js.map +1 -0
  9. package/dist/formats/anthropic/index.d.ts +1 -1
  10. package/dist/formats/anthropic/index.d.ts.map +1 -1
  11. package/dist/formats/anthropic/index.js +1 -1
  12. package/dist/formats/anthropic/index.js.map +1 -1
  13. package/dist/formats/anthropic/parse.d.ts +2 -2
  14. package/dist/formats/anthropic/parse.d.ts.map +1 -1
  15. package/dist/formats/anthropic/parse.js +4 -2
  16. package/dist/formats/anthropic/parse.js.map +1 -1
  17. package/dist/formats/anthropic/schema.d.ts +1 -1
  18. package/dist/formats/anthropic/schema.d.ts.map +1 -1
  19. package/dist/formats/anthropic/schema.js +9 -4
  20. package/dist/formats/anthropic/schema.js.map +1 -1
  21. package/dist/formats/anthropic/serialize.d.ts +2 -2
  22. package/dist/formats/anthropic/serialize.d.ts.map +1 -1
  23. package/dist/formats/anthropic/serialize.js +76 -19
  24. package/dist/formats/anthropic/serialize.js.map +1 -1
  25. package/dist/formats/openai/chat-completions/index.d.ts +3 -0
  26. package/dist/formats/openai/chat-completions/index.d.ts.map +1 -0
  27. package/dist/formats/openai/chat-completions/index.js +13 -0
  28. package/dist/formats/openai/chat-completions/index.js.map +1 -0
  29. package/dist/formats/openai/chat-completions/parse.d.ts +4 -0
  30. package/dist/formats/openai/chat-completions/parse.d.ts.map +1 -0
  31. package/dist/formats/openai/chat-completions/parse.js +33 -0
  32. package/dist/formats/openai/chat-completions/parse.js.map +1 -0
  33. package/dist/formats/openai/chat-completions/schema.d.ts +93 -0
  34. package/dist/formats/openai/chat-completions/schema.d.ts.map +1 -0
  35. package/dist/formats/openai/chat-completions/schema.js +74 -0
  36. package/dist/formats/openai/chat-completions/schema.js.map +1 -0
  37. package/dist/formats/openai/chat-completions/serialize.d.ts +10 -0
  38. package/dist/formats/openai/chat-completions/serialize.d.ts.map +1 -0
  39. package/dist/formats/openai/chat-completions/serialize.js +99 -0
  40. package/dist/formats/openai/chat-completions/serialize.js.map +1 -0
  41. package/dist/formats/openai/responses/index.d.ts +3 -0
  42. package/dist/formats/openai/responses/index.d.ts.map +1 -0
  43. package/dist/formats/openai/responses/index.js +13 -0
  44. package/dist/formats/openai/responses/index.js.map +1 -0
  45. package/dist/formats/openai/responses/parse.d.ts +4 -0
  46. package/dist/formats/openai/responses/parse.d.ts.map +1 -0
  47. package/dist/formats/openai/responses/parse.js +51 -0
  48. package/dist/formats/openai/responses/parse.js.map +1 -0
  49. package/dist/formats/openai/responses/schema.d.ts +103 -0
  50. package/dist/formats/openai/responses/schema.d.ts.map +1 -0
  51. package/dist/formats/openai/responses/schema.js +71 -0
  52. package/dist/formats/openai/responses/schema.js.map +1 -0
  53. package/dist/formats/openai/responses/serialize.d.ts +10 -0
  54. package/dist/formats/openai/responses/serialize.d.ts.map +1 -0
  55. package/dist/formats/openai/responses/serialize.js +273 -0
  56. package/dist/formats/openai/responses/serialize.js.map +1 -0
  57. package/dist/formats/request-helpers.d.ts +1 -1
  58. package/dist/formats/request-helpers.d.ts.map +1 -1
  59. package/dist/formats/request-helpers.js.map +1 -1
  60. package/dist/formats/serialize-helpers.d.ts +1 -1
  61. package/dist/formats/serialize-helpers.d.ts.map +1 -1
  62. package/dist/formats/serialize-helpers.js +6 -3
  63. package/dist/formats/serialize-helpers.js.map +1 -1
  64. package/dist/formats/types.d.ts +2 -1
  65. package/dist/formats/types.d.ts.map +1 -1
  66. package/dist/history.d.ts +6 -2
  67. package/dist/history.d.ts.map +1 -1
  68. package/dist/history.js +2 -0
  69. package/dist/history.js.map +1 -1
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js.map +1 -1
  72. package/dist/loader.d.ts +1 -1
  73. package/dist/loader.d.ts.map +1 -1
  74. package/dist/loader.js +26 -9
  75. package/dist/loader.js.map +1 -1
  76. package/dist/logger.d.ts.map +1 -1
  77. package/dist/logger.js +12 -4
  78. package/dist/logger.js.map +1 -1
  79. package/dist/mock-server.d.ts +44 -48
  80. package/dist/mock-server.d.ts.map +1 -1
  81. package/dist/mock-server.js +37 -85
  82. package/dist/mock-server.js.map +1 -1
  83. package/dist/route-handler.d.ts +1 -1
  84. package/dist/route-handler.d.ts.map +1 -1
  85. package/dist/route-handler.js +19 -7
  86. package/dist/route-handler.js.map +1 -1
  87. package/dist/rule-builder.d.ts +21 -0
  88. package/dist/rule-builder.d.ts.map +1 -0
  89. package/dist/rule-builder.js +58 -0
  90. package/dist/rule-builder.js.map +1 -0
  91. package/dist/rule-engine.d.ts +3 -1
  92. package/dist/rule-engine.d.ts.map +1 -1
  93. package/dist/rule-engine.js +7 -2
  94. package/dist/rule-engine.js.map +1 -1
  95. package/dist/sse-writer.d.ts +1 -1
  96. package/dist/sse-writer.d.ts.map +1 -1
  97. package/dist/types/reply.d.ts +51 -8
  98. package/dist/types/reply.d.ts.map +1 -1
  99. package/dist/types/request.d.ts +21 -6
  100. package/dist/types/request.d.ts.map +1 -1
  101. package/dist/types/rule.d.ts +65 -7
  102. package/dist/types/rule.d.ts.map +1 -1
  103. package/dist/types.d.ts +3 -3
  104. package/dist/types.d.ts.map +1 -1
  105. package/package.json +15 -9
  106. package/.claude/skills/desloppify/SKILL.md +0 -308
  107. package/.desloppify/external_review_sessions/ext_20260315_000339_a6cdc3e6/canonical_import_20260315_000801.json +0 -242
  108. package/.desloppify/external_review_sessions/ext_20260315_000339_a6cdc3e6/canonical_import_20260315_000905.json +0 -248
  109. package/.desloppify/external_review_sessions/ext_20260315_000339_a6cdc3e6/canonical_import_20260315_000917.json +0 -248
  110. package/.desloppify/external_review_sessions/ext_20260315_000339_a6cdc3e6/canonical_import_20260315_000950.json +0 -311
  111. package/.desloppify/external_review_sessions/ext_20260315_000339_a6cdc3e6/claude_launch_prompt.md +0 -17
  112. package/.desloppify/external_review_sessions/ext_20260315_000339_a6cdc3e6/review_result.json +0 -255
  113. package/.desloppify/external_review_sessions/ext_20260315_000339_a6cdc3e6/review_result.template.json +0 -22
  114. package/.desloppify/external_review_sessions/ext_20260315_000339_a6cdc3e6/reviewer_instructions.md +0 -20
  115. package/.desloppify/external_review_sessions/ext_20260315_000339_a6cdc3e6/session.json +0 -20
  116. package/.desloppify/external_review_sessions/ext_20260315_045546_0587ea3b/canonical_import_20260315_050000.json +0 -286
  117. package/.desloppify/external_review_sessions/ext_20260315_045546_0587ea3b/canonical_import_20260315_050028.json +0 -303
  118. package/.desloppify/external_review_sessions/ext_20260315_045546_0587ea3b/claude_launch_prompt.md +0 -17
  119. package/.desloppify/external_review_sessions/ext_20260315_045546_0587ea3b/review_result.json +0 -297
  120. package/.desloppify/external_review_sessions/ext_20260315_045546_0587ea3b/review_result.template.json +0 -22
  121. package/.desloppify/external_review_sessions/ext_20260315_045546_0587ea3b/reviewer_instructions.md +0 -20
  122. package/.desloppify/external_review_sessions/ext_20260315_045546_0587ea3b/session.json +0 -20
  123. package/.desloppify/query.json +0 -1312
  124. package/.desloppify/review_packet_blind.json +0 -1249
  125. package/.desloppify/review_packets/holistic_packet_20260315_000339.json +0 -1471
  126. package/.desloppify/review_packets/holistic_packet_20260315_045546.json +0 -1480
  127. package/.desloppify/review_packets/holistic_packet_20260315_185401.json +0 -1407
  128. package/.desloppify/review_packets/holistic_packet_20260315_185613.json +0 -1407
  129. package/.desloppify/state-typescript.json +0 -8438
  130. package/.desloppify/state-typescript.json.bak +0 -8432
  131. package/.desloppify/subagents/runs/20260315_185401/logs/batch-1.log +0 -384
  132. package/.desloppify/subagents/runs/20260315_185401/logs/batch-10.log +0 -484
  133. package/.desloppify/subagents/runs/20260315_185401/logs/batch-2.log +0 -408
  134. package/.desloppify/subagents/runs/20260315_185401/logs/batch-3.log +0 -416
  135. package/.desloppify/subagents/runs/20260315_185401/logs/batch-4.log +0 -360
  136. package/.desloppify/subagents/runs/20260315_185401/logs/batch-5.log +0 -360
  137. package/.desloppify/subagents/runs/20260315_185401/logs/batch-6.log +0 -364
  138. package/.desloppify/subagents/runs/20260315_185401/logs/batch-7.log +0 -428
  139. package/.desloppify/subagents/runs/20260315_185401/logs/batch-8.log +0 -388
  140. package/.desloppify/subagents/runs/20260315_185401/logs/batch-9.log +0 -500
  141. package/.desloppify/subagents/runs/20260315_185401/prompts/batch-1.md +0 -83
  142. package/.desloppify/subagents/runs/20260315_185401/prompts/batch-10.md +0 -108
  143. package/.desloppify/subagents/runs/20260315_185401/prompts/batch-2.md +0 -89
  144. package/.desloppify/subagents/runs/20260315_185401/prompts/batch-3.md +0 -91
  145. package/.desloppify/subagents/runs/20260315_185401/prompts/batch-4.md +0 -77
  146. package/.desloppify/subagents/runs/20260315_185401/prompts/batch-5.md +0 -77
  147. package/.desloppify/subagents/runs/20260315_185401/prompts/batch-6.md +0 -78
  148. package/.desloppify/subagents/runs/20260315_185401/prompts/batch-7.md +0 -94
  149. package/.desloppify/subagents/runs/20260315_185401/prompts/batch-8.md +0 -84
  150. package/.desloppify/subagents/runs/20260315_185401/prompts/batch-9.md +0 -112
  151. package/.desloppify/subagents/runs/20260315_185401/results/batch-1.raw.txt +0 -0
  152. package/.desloppify/subagents/runs/20260315_185401/results/batch-10.raw.txt +0 -0
  153. package/.desloppify/subagents/runs/20260315_185401/results/batch-2.raw.txt +0 -0
  154. package/.desloppify/subagents/runs/20260315_185401/results/batch-3.raw.txt +0 -0
  155. package/.desloppify/subagents/runs/20260315_185401/results/batch-4.raw.txt +0 -0
  156. package/.desloppify/subagents/runs/20260315_185401/results/batch-5.raw.txt +0 -0
  157. package/.desloppify/subagents/runs/20260315_185401/results/batch-6.raw.txt +0 -0
  158. package/.desloppify/subagents/runs/20260315_185401/results/batch-7.raw.txt +0 -0
  159. package/.desloppify/subagents/runs/20260315_185401/results/batch-8.raw.txt +0 -0
  160. package/.desloppify/subagents/runs/20260315_185401/results/batch-9.raw.txt +0 -0
  161. package/.desloppify/subagents/runs/20260315_185401/run.log +0 -36
  162. package/.desloppify/subagents/runs/20260315_185401/run_summary.json +0 -156
  163. package/.desloppify/subagents/runs/20260315_185613/holistic_findings_merged.json +0 -741
  164. package/.desloppify/subagents/runs/20260315_185613/logs/batch-1.log +0 -579
  165. package/.desloppify/subagents/runs/20260315_185613/logs/batch-10.log +0 -1537
  166. package/.desloppify/subagents/runs/20260315_185613/logs/batch-2.log +0 -829
  167. package/.desloppify/subagents/runs/20260315_185613/logs/batch-3.log +0 -927
  168. package/.desloppify/subagents/runs/20260315_185613/logs/batch-4.log +0 -429
  169. package/.desloppify/subagents/runs/20260315_185613/logs/batch-5.log +0 -276
  170. package/.desloppify/subagents/runs/20260315_185613/logs/batch-6.log +0 -450
  171. package/.desloppify/subagents/runs/20260315_185613/logs/batch-7.log +0 -730
  172. package/.desloppify/subagents/runs/20260315_185613/logs/batch-8.log +0 -698
  173. package/.desloppify/subagents/runs/20260315_185613/logs/batch-9.log +0 -938
  174. package/.desloppify/subagents/runs/20260315_185613/prompts/batch-1.md +0 -83
  175. package/.desloppify/subagents/runs/20260315_185613/prompts/batch-10.md +0 -108
  176. package/.desloppify/subagents/runs/20260315_185613/prompts/batch-2.md +0 -89
  177. package/.desloppify/subagents/runs/20260315_185613/prompts/batch-3.md +0 -91
  178. package/.desloppify/subagents/runs/20260315_185613/prompts/batch-4.md +0 -77
  179. package/.desloppify/subagents/runs/20260315_185613/prompts/batch-5.md +0 -77
  180. package/.desloppify/subagents/runs/20260315_185613/prompts/batch-6.md +0 -78
  181. package/.desloppify/subagents/runs/20260315_185613/prompts/batch-7.md +0 -94
  182. package/.desloppify/subagents/runs/20260315_185613/prompts/batch-8.md +0 -84
  183. package/.desloppify/subagents/runs/20260315_185613/prompts/batch-9.md +0 -112
  184. package/.desloppify/subagents/runs/20260315_185613/results/batch-1.raw.txt +0 -78
  185. package/.desloppify/subagents/runs/20260315_185613/results/batch-10.raw.txt +0 -242
  186. package/.desloppify/subagents/runs/20260315_185613/results/batch-2.raw.txt +0 -102
  187. package/.desloppify/subagents/runs/20260315_185613/results/batch-3.raw.txt +0 -94
  188. package/.desloppify/subagents/runs/20260315_185613/results/batch-4.raw.txt +0 -86
  189. package/.desloppify/subagents/runs/20260315_185613/results/batch-5.raw.txt +0 -1
  190. package/.desloppify/subagents/runs/20260315_185613/results/batch-6.raw.txt +0 -87
  191. package/.desloppify/subagents/runs/20260315_185613/results/batch-7.raw.txt +0 -1
  192. package/.desloppify/subagents/runs/20260315_185613/results/batch-8.raw.txt +0 -107
  193. package/.desloppify/subagents/runs/20260315_185613/results/batch-9.raw.txt +0 -67
  194. package/.desloppify/subagents/runs/20260315_185613/run.log +0 -96
  195. package/.desloppify/subagents/runs/20260315_185613/run_summary.json +0 -156
  196. package/.editorconfig +0 -12
  197. package/.github/dependabot.yml +0 -11
  198. package/.github/workflows/docs.yml +0 -46
  199. package/.github/workflows/test.yml +0 -40
  200. package/.markdownlint.jsonc +0 -11
  201. package/.node-version +0 -1
  202. package/.oxfmtrc.json +0 -9
  203. package/.oxlintrc.json +0 -35
  204. package/docs/ARCHITECTURE.md +0 -125
  205. package/scorecard.png +0 -0
  206. package/src/cli/cli.ts +0 -141
  207. package/src/cli/validators.ts +0 -68
  208. package/src/formats/anthropic/index.ts +0 -14
  209. package/src/formats/anthropic/parse.ts +0 -70
  210. package/src/formats/anthropic/schema.ts +0 -74
  211. package/src/formats/anthropic/serialize.ts +0 -179
  212. package/src/formats/openai/chat-completions/index.ts +0 -14
  213. package/src/formats/openai/chat-completions/parse.ts +0 -47
  214. package/src/formats/openai/chat-completions/schema.ts +0 -92
  215. package/src/formats/openai/chat-completions/serialize.ts +0 -146
  216. package/src/formats/openai/responses/index.ts +0 -14
  217. package/src/formats/openai/responses/parse.ts +0 -73
  218. package/src/formats/openai/responses/schema.ts +0 -86
  219. package/src/formats/openai/responses/serialize.ts +0 -328
  220. package/src/formats/request-helpers.ts +0 -56
  221. package/src/formats/serialize-helpers.ts +0 -43
  222. package/src/formats/types.ts +0 -26
  223. package/src/history.ts +0 -70
  224. package/src/index.ts +0 -46
  225. package/src/loader.ts +0 -246
  226. package/src/logger.ts +0 -70
  227. package/src/mock-server.ts +0 -203
  228. package/src/route-handler.ts +0 -144
  229. package/src/rule-builder.ts +0 -73
  230. package/src/rule-engine.ts +0 -165
  231. package/src/sse-writer.ts +0 -35
  232. package/src/types/reply.ts +0 -92
  233. package/src/types/request.ts +0 -56
  234. package/src/types/rule.ts +0 -125
  235. package/src/types.ts +0 -24
  236. package/test/cli-validators.test.ts +0 -151
  237. package/test/formats/anthropic.test.ts +0 -336
  238. package/test/formats/openai.test.ts +0 -316
  239. package/test/formats/parse-helpers.test.ts +0 -315
  240. package/test/formats/responses.test.ts +0 -380
  241. package/test/helpers/make-req.ts +0 -18
  242. package/test/history.test.ts +0 -361
  243. package/test/loader.test.ts +0 -333
  244. package/test/logger.test.ts +0 -344
  245. package/test/mock-server.test.ts +0 -619
  246. package/test/rule-engine.test.ts +0 -229
  247. package/tsconfig.json +0 -24
  248. package/tsconfig.test.json +0 -11
  249. package/typedoc.json +0 -9
  250. package/vitest.config.ts +0 -18
@@ -1,146 +0,0 @@
1
- import type { ReplyObject, ReplyOptions } from "#/types/reply.js";
2
- import type { SSEChunk } from "#/formats/types.js";
3
- import {
4
- splitText,
5
- genId,
6
- toolId,
7
- finishReason,
8
- MS_PER_SECOND,
9
- DEFAULT_USAGE,
10
- } from "#/formats/serialize-helpers.js";
11
-
12
- function buildUsage(usage: { input: number; output: number }) {
13
- return {
14
- prompt_tokens: usage.input,
15
- completion_tokens: usage.output,
16
- total_tokens: usage.input + usage.output,
17
- prompt_tokens_details: { cached_tokens: 0, audio_tokens: 0 },
18
- completion_tokens_details: {
19
- reasoning_tokens: 0,
20
- audio_tokens: 0,
21
- accepted_prediction_tokens: 0,
22
- rejected_prediction_tokens: 0,
23
- },
24
- };
25
- }
26
-
27
- function chunkEnvelope(
28
- id: string,
29
- created: number,
30
- model: string,
31
- delta: Record<string, unknown>,
32
- finish_reason: string | null = null,
33
- usage: Record<string, unknown> | null = null,
34
- ): SSEChunk {
35
- return {
36
- data: JSON.stringify({
37
- id,
38
- object: "chat.completion.chunk",
39
- created,
40
- model,
41
- system_fingerprint: null,
42
- service_tier: "default",
43
- choices: [{ index: 0, delta, logprobs: null, finish_reason }],
44
- usage,
45
- }),
46
- };
47
- }
48
-
49
- export function serialize(
50
- reply: ReplyObject,
51
- model: string,
52
- options: ReplyOptions = {},
53
- ): readonly SSEChunk[] {
54
- const id = genId("chatcmpl");
55
- const created = Math.floor(Date.now() / MS_PER_SECOND);
56
- const usage = reply.usage ?? DEFAULT_USAGE;
57
-
58
- const textChunks = reply.text
59
- ? splitText(reply.text, options.chunkSize ?? 0).map((piece) =>
60
- chunkEnvelope(id, created, model, { content: piece }),
61
- )
62
- : [];
63
-
64
- const toolChunks = (reply.tools ?? []).map((tool, i) =>
65
- chunkEnvelope(id, created, model, {
66
- tool_calls: [
67
- {
68
- index: i,
69
- id: toolId(tool, "call", i),
70
- type: "function",
71
- function: { name: tool.name, arguments: JSON.stringify(tool.args) },
72
- },
73
- ],
74
- }),
75
- );
76
-
77
- const usageChunk = buildUsage(usage);
78
-
79
- return [
80
- chunkEnvelope(id, created, model, { role: "assistant" }),
81
- ...textChunks,
82
- ...toolChunks,
83
- chunkEnvelope(
84
- id,
85
- created,
86
- model,
87
- {},
88
- finishReason(reply, "tool_calls", "stop"),
89
- ),
90
- chunkEnvelope(id, created, model, {}, null, usageChunk),
91
- { data: "[DONE]" },
92
- ];
93
- }
94
-
95
- export function serializeComplete(
96
- reply: ReplyObject,
97
- model: string,
98
- ): Record<string, unknown> {
99
- const id = genId("chatcmpl");
100
- const created = Math.floor(Date.now() / MS_PER_SECOND);
101
- const usage = reply.usage ?? DEFAULT_USAGE;
102
-
103
- const message: Record<string, unknown> = {
104
- role: "assistant",
105
- content: reply.text ?? null,
106
- ...(reply.tools?.length && {
107
- tool_calls: reply.tools.map((tool, i) => ({
108
- id: toolId(tool, "call", i),
109
- type: "function",
110
- function: { name: tool.name, arguments: JSON.stringify(tool.args) },
111
- })),
112
- }),
113
- };
114
-
115
- return {
116
- id,
117
- object: "chat.completion",
118
- created,
119
- model,
120
- system_fingerprint: null,
121
- service_tier: "default",
122
- choices: [
123
- {
124
- index: 0,
125
- message,
126
- logprobs: null,
127
- finish_reason: finishReason(reply, "tool_calls", "stop"),
128
- },
129
- ],
130
- usage: buildUsage(usage),
131
- };
132
- }
133
-
134
- export function serializeError(error: {
135
- status: number;
136
- message: string;
137
- type?: string;
138
- }): Record<string, unknown> {
139
- return {
140
- error: {
141
- message: error.message,
142
- type: error.type ?? "server_error",
143
- code: null,
144
- },
145
- };
146
- }
@@ -1,14 +0,0 @@
1
- import type { Format } from "#/formats/types.js";
2
- import { isStreaming } from "#/formats/request-helpers.js";
3
- import { parseRequest } from "./parse.js";
4
- import { serialize, serializeComplete, serializeError } from "./serialize.js";
5
-
6
- export const responsesFormat: Format = {
7
- name: "responses",
8
- route: "/v1/responses",
9
- parseRequest,
10
- isStreaming,
11
- serialize,
12
- serializeComplete,
13
- serializeError,
14
- };
@@ -1,73 +0,0 @@
1
- import type { MockRequest, Message, ToolDef } from "#/types/request.js";
2
- import {
3
- buildMockRequest,
4
- type RequestMeta,
5
- } from "#/formats/request-helpers.js";
6
- import {
7
- ResponsesRequestSchema,
8
- FunctionToolSchema,
9
- type ResponsesRequest,
10
- } from "./schema.js";
11
-
12
- function extractInputContent(
13
- content: string | Record<string, unknown>[],
14
- ): string {
15
- if (typeof content === "string") return content;
16
- return content
17
- .filter((b) => b["type"] === "input_text" || b["type"] === "text")
18
- .map((b) => String(b["text"] ?? ""))
19
- .join("\n");
20
- }
21
-
22
- function parseInput(req: ResponsesRequest): readonly Message[] {
23
- const instructions: Message[] = req.instructions
24
- ? [{ role: "system", content: req.instructions }]
25
- : [];
26
-
27
- if (req.input === undefined) return instructions;
28
-
29
- if (typeof req.input === "string") {
30
- return [...instructions, { role: "user", content: req.input }];
31
- }
32
-
33
- const messages = req.input.map((item): Message => {
34
- if ("call_id" in item) {
35
- return {
36
- role: "tool",
37
- content: "output" in item ? item.output : item.arguments,
38
- toolCallId: item.call_id,
39
- };
40
- }
41
- return {
42
- role: item.role === "developer" ? "system" : item.role,
43
- content: extractInputContent(item.content),
44
- };
45
- });
46
-
47
- return [...instructions, ...messages];
48
- }
49
-
50
- function parseTools(req: ResponsesRequest): readonly ToolDef[] | undefined {
51
- if (!req.tools) return undefined;
52
- return req.tools
53
- .map((t) => FunctionToolSchema.safeParse(t))
54
- .filter((r) => r.success)
55
- .map((r) => ({
56
- name: r.data.name,
57
- description: r.data.description,
58
- parameters: r.data.parameters,
59
- }));
60
- }
61
-
62
- export function parseRequest(body: unknown, meta?: RequestMeta): MockRequest {
63
- const req = ResponsesRequestSchema.parse(body);
64
- return buildMockRequest(
65
- "responses",
66
- req,
67
- parseInput(req),
68
- parseTools(req),
69
- "codex-mini",
70
- body,
71
- meta,
72
- );
73
- }
@@ -1,86 +0,0 @@
1
- import { z } from "zod";
2
-
3
- export {
4
- ResponsesRequestSchema,
5
- FunctionToolSchema,
6
- type ResponsesRequest,
7
- } from "llm-schemas/openai/responses";
8
-
9
- const OutputContentSchema = z.object({
10
- type: z.string(),
11
- text: z.string(),
12
- annotations: z.array(z.unknown()).optional(),
13
- });
14
-
15
- const OutputItemSchema = z.object({
16
- type: z.string(),
17
- id: z.string().optional(),
18
- status: z.string().optional(),
19
- role: z.string().optional(),
20
- content: z.array(OutputContentSchema).optional(),
21
- call_id: z.string().optional(),
22
- name: z.string().optional(),
23
- arguments: z.string().optional(),
24
- summary: z.array(z.object({ type: z.string(), text: z.string() })).optional(),
25
- });
26
-
27
- export const ResponsesEventSchema = z.object({
28
- type: z.string(),
29
- sequence_number: z.number().optional(),
30
- response: z
31
- .object({
32
- id: z.string(),
33
- object: z.string(),
34
- created_at: z.number(),
35
- model: z.string(),
36
- status: z.string(),
37
- output: z.array(OutputItemSchema),
38
- usage: z
39
- .object({
40
- input_tokens: z.number(),
41
- output_tokens: z.number(),
42
- total_tokens: z.number(),
43
- })
44
- .optional(),
45
- })
46
- .optional(),
47
- item: OutputItemSchema.optional(),
48
- part: z
49
- .object({
50
- type: z.string(),
51
- text: z.string().optional(),
52
- annotations: z.array(z.unknown()).optional(),
53
- })
54
- .optional(),
55
- delta: z.string().optional(),
56
- item_id: z.string().optional(),
57
- });
58
-
59
- export type ResponsesEvent = z.infer<typeof ResponsesEventSchema>;
60
-
61
- export const ResponsesCompleteSchema = z.object({
62
- id: z.string(),
63
- object: z.literal("response"),
64
- created_at: z.number(),
65
- status: z.literal("completed"),
66
- model: z.string(),
67
- output: z.array(OutputItemSchema),
68
- usage: z.object({
69
- input_tokens: z.number(),
70
- output_tokens: z.number(),
71
- total_tokens: z.number(),
72
- }),
73
- });
74
-
75
- export type ResponsesComplete = z.infer<typeof ResponsesCompleteSchema>;
76
-
77
- export const ResponsesErrorSchema = z.object({
78
- type: z.literal("error"),
79
- error: z.object({
80
- message: z.string(),
81
- type: z.string().optional(),
82
- code: z.string().optional(),
83
- }),
84
- });
85
-
86
- export type ResponsesError = z.infer<typeof ResponsesErrorSchema>;
@@ -1,328 +0,0 @@
1
- import type { ReplyObject, ReplyOptions, ToolCall } from "#/types/reply.js";
2
- import type { SSEChunk } from "#/formats/types.js";
3
- import {
4
- splitText,
5
- genId,
6
- toolId,
7
- shouldEmitText,
8
- MS_PER_SECOND,
9
- DEFAULT_USAGE,
10
- } from "#/formats/serialize-helpers.js";
11
-
12
- function buildUsage(usage: { input: number; output: number }) {
13
- return {
14
- input_tokens: usage.input,
15
- output_tokens: usage.output,
16
- total_tokens: usage.input + usage.output,
17
- };
18
- }
19
-
20
- interface StreamBlock {
21
- chunks: SSEChunk[];
22
- outputItem: unknown;
23
- }
24
-
25
- const NO_ANNOTATIONS: readonly unknown[] = [];
26
-
27
- type Chunk = (payload: Record<string, unknown>) => SSEChunk;
28
-
29
- function createChunk(): Chunk {
30
- let seq = 0;
31
- return (payload) => ({
32
- data: JSON.stringify({ ...payload, sequence_number: seq++ }),
33
- });
34
- }
35
-
36
- function reasoningStreamBlock(
37
- c: Chunk,
38
- i: number,
39
- reasoning: string,
40
- ): StreamBlock {
41
- const itemId = `rs_${genId("rs")}`;
42
- const summaryPart = { type: "summary_text" as const, text: reasoning };
43
- const item = {
44
- type: "reasoning",
45
- id: itemId,
46
- status: "completed",
47
- summary: [summaryPart],
48
- };
49
-
50
- return {
51
- outputItem: item,
52
- chunks: [
53
- c({
54
- type: "response.output_item.added",
55
- output_index: i,
56
- item: {
57
- type: "reasoning",
58
- id: itemId,
59
- status: "in_progress",
60
- summary: [],
61
- },
62
- }),
63
- c({
64
- type: "response.reasoning_summary_part.added",
65
- item_id: itemId,
66
- output_index: i,
67
- summary_index: 0,
68
- part: { type: "summary_text", text: "" },
69
- }),
70
- c({
71
- type: "response.reasoning_summary_text.delta",
72
- item_id: itemId,
73
- output_index: i,
74
- summary_index: 0,
75
- delta: reasoning,
76
- }),
77
- c({
78
- type: "response.reasoning_summary_text.done",
79
- item_id: itemId,
80
- output_index: i,
81
- summary_index: 0,
82
- text: reasoning,
83
- }),
84
- c({
85
- type: "response.reasoning_summary_part.done",
86
- item_id: itemId,
87
- output_index: i,
88
- summary_index: 0,
89
- part: summaryPart,
90
- }),
91
- c({ type: "response.output_item.done", output_index: i, item }),
92
- ],
93
- };
94
- }
95
-
96
- function textStreamBlock(
97
- c: Chunk,
98
- i: number,
99
- text: string,
100
- chunkSize: number,
101
- ): StreamBlock {
102
- const itemId = `msg_${genId("msg")}`;
103
- const outputText = {
104
- type: "output_text" as const,
105
- text,
106
- annotations: NO_ANNOTATIONS,
107
- };
108
- const outputItem = {
109
- type: "message",
110
- id: itemId,
111
- status: "completed",
112
- role: "assistant",
113
- content: [outputText],
114
- };
115
-
116
- return {
117
- outputItem,
118
- chunks: [
119
- c({
120
- type: "response.output_item.added",
121
- output_index: i,
122
- item: {
123
- type: "message",
124
- id: itemId,
125
- status: "in_progress",
126
- role: "assistant",
127
- content: [],
128
- },
129
- }),
130
- c({
131
- type: "response.content_part.added",
132
- item_id: itemId,
133
- output_index: i,
134
- content_index: 0,
135
- part: { type: "output_text", text: "", annotations: [] },
136
- }),
137
- ...splitText(text, chunkSize).map((piece) =>
138
- c({
139
- type: "response.output_text.delta",
140
- item_id: itemId,
141
- output_index: i,
142
- content_index: 0,
143
- delta: piece,
144
- }),
145
- ),
146
- c({
147
- type: "response.output_text.done",
148
- item_id: itemId,
149
- output_index: i,
150
- content_index: 0,
151
- text,
152
- }),
153
- c({
154
- type: "response.content_part.done",
155
- item_id: itemId,
156
- output_index: i,
157
- content_index: 0,
158
- part: outputText,
159
- }),
160
- c({
161
- type: "response.output_item.done",
162
- output_index: i,
163
- item: outputItem,
164
- }),
165
- ],
166
- };
167
- }
168
-
169
- function toolStreamBlock(c: Chunk, i: number, tool: ToolCall): StreamBlock {
170
- const callId = toolId(tool, "call", i);
171
- const argsJson = JSON.stringify(tool.args);
172
- const outputItem = {
173
- type: "function_call",
174
- id: callId,
175
- status: "completed",
176
- name: tool.name,
177
- call_id: callId,
178
- arguments: argsJson,
179
- };
180
-
181
- return {
182
- outputItem,
183
- chunks: [
184
- c({
185
- type: "response.output_item.added",
186
- output_index: i,
187
- item: { ...outputItem, status: "in_progress", arguments: "" },
188
- }),
189
- c({
190
- type: "response.function_call_arguments.delta",
191
- item_id: callId,
192
- output_index: i,
193
- delta: argsJson,
194
- }),
195
- c({
196
- type: "response.function_call_arguments.done",
197
- item_id: callId,
198
- output_index: i,
199
- arguments: argsJson,
200
- }),
201
- c({
202
- type: "response.output_item.done",
203
- output_index: i,
204
- item: outputItem,
205
- }),
206
- ],
207
- };
208
- }
209
-
210
- export function serialize(
211
- reply: ReplyObject,
212
- model: string,
213
- options: ReplyOptions = {},
214
- ): readonly SSEChunk[] {
215
- const id = genId("resp");
216
- const createdAt = Math.floor(Date.now() / MS_PER_SECOND);
217
- const usage = reply.usage ?? DEFAULT_USAGE;
218
- const c = createChunk();
219
- let i = 0;
220
-
221
- const baseResponse = { id, object: "response", created_at: createdAt, model };
222
- const header = [
223
- c({
224
- type: "response.created",
225
- response: { ...baseResponse, status: "in_progress", output: [] },
226
- }),
227
- c({
228
- type: "response.in_progress",
229
- response: { ...baseResponse, status: "in_progress", output: [] },
230
- }),
231
- ];
232
-
233
- const blocks: StreamBlock[] = [
234
- ...(reply.reasoning ? [reasoningStreamBlock(c, i++, reply.reasoning)] : []),
235
- ...(shouldEmitText(reply)
236
- ? [textStreamBlock(c, i++, reply.text ?? "", options.chunkSize ?? 0)]
237
- : []),
238
- ...(reply.tools ?? []).map((tool) => toolStreamBlock(c, i++, tool)),
239
- ];
240
-
241
- const allChunks = blocks.flatMap((b) => b.chunks);
242
- const output = blocks.map((b) => b.outputItem);
243
-
244
- return [
245
- ...header,
246
- ...allChunks,
247
- c({
248
- type: "response.completed",
249
- response: {
250
- ...baseResponse,
251
- status: "completed",
252
- output,
253
- usage: buildUsage(usage),
254
- },
255
- }),
256
- ];
257
- }
258
-
259
- export function serializeComplete(
260
- reply: ReplyObject,
261
- model: string,
262
- ): Record<string, unknown> {
263
- const id = genId("resp");
264
- const createdAt = Math.floor(Date.now() / MS_PER_SECOND);
265
- const usage = reply.usage ?? DEFAULT_USAGE;
266
-
267
- const output: unknown[] = [
268
- ...(reply.reasoning
269
- ? [
270
- {
271
- type: "reasoning",
272
- id: `rs_${genId("rs")}`,
273
- status: "completed",
274
- summary: [{ type: "summary_text", text: reply.reasoning }],
275
- },
276
- ]
277
- : []),
278
- ...(shouldEmitText(reply)
279
- ? [
280
- {
281
- type: "message",
282
- id: `msg_${genId("msg")}`,
283
- status: "completed",
284
- role: "assistant",
285
- content: [
286
- { type: "output_text", text: reply.text ?? "", annotations: [] },
287
- ],
288
- },
289
- ]
290
- : []),
291
- ...(reply.tools ?? []).map((tool, i) => {
292
- const callId = toolId(tool, "call", i);
293
- return {
294
- type: "function_call",
295
- id: callId,
296
- status: "completed",
297
- name: tool.name,
298
- call_id: callId,
299
- arguments: JSON.stringify(tool.args),
300
- };
301
- }),
302
- ];
303
-
304
- return {
305
- id,
306
- object: "response",
307
- created_at: createdAt,
308
- status: "completed",
309
- model,
310
- output,
311
- usage: buildUsage(usage),
312
- };
313
- }
314
-
315
- export function serializeError(error: {
316
- status: number;
317
- message: string;
318
- type?: string;
319
- }): Record<string, unknown> {
320
- return {
321
- type: "error",
322
- error: {
323
- message: error.message,
324
- type: error.type ?? "server_error",
325
- code: error.type ?? "server_error",
326
- },
327
- };
328
- }
@@ -1,56 +0,0 @@
1
- import type {
2
- FormatName,
3
- Message,
4
- MockRequest,
5
- ToolDef,
6
- } from "#/types/request.js";
7
-
8
- function asRecord(body: unknown): Record<string, unknown> {
9
- if (typeof body === "object" && body !== null)
10
- return body as Record<string, unknown>;
11
- return {};
12
- }
13
-
14
- export function isStreaming(body: unknown): boolean {
15
- return asRecord(body)["stream"] !== false;
16
- }
17
-
18
- export interface RequestMeta {
19
- readonly headers: Readonly<Record<string, string | undefined>>;
20
- readonly path: string;
21
- }
22
-
23
- const EMPTY_META: RequestMeta = { headers: {}, path: "" };
24
-
25
- interface ParsedBody {
26
- readonly model?: string | undefined;
27
- readonly stream?: boolean | undefined;
28
- }
29
-
30
- export function buildMockRequest(
31
- format: FormatName,
32
- body: ParsedBody,
33
- messages: readonly Message[],
34
- tools: readonly ToolDef[] | undefined,
35
- defaultModel: string,
36
- raw: unknown,
37
- meta: RequestMeta = EMPTY_META,
38
- ): MockRequest {
39
- const userMessages = messages.filter((m) => m.role === "user");
40
- const toolCallMsgs = messages.filter((m) => m.toolCallId !== undefined);
41
-
42
- return {
43
- format,
44
- model: body.model || defaultModel,
45
- streaming: body.stream !== false,
46
- messages,
47
- lastMessage: userMessages.at(-1)?.content ?? "",
48
- systemMessage: messages.find((m) => m.role === "system")?.content ?? "",
49
- tools,
50
- toolNames: tools?.map((t) => t.name) ?? [],
51
- lastToolCallId: toolCallMsgs.at(-1)?.toolCallId,
52
- raw,
53
- headers: meta.headers,
54
- path: meta.path,
55
- };
56
- }