genaicode 2.0.0 → 2.3.0

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 (48) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/README.md +194 -26
  3. package/dist/core/client.d.ts +15 -3
  4. package/dist/core/client.js +87 -3
  5. package/dist/core/client.js.map +1 -1
  6. package/dist/core/errors.d.ts +38 -0
  7. package/dist/core/errors.js +118 -0
  8. package/dist/core/errors.js.map +1 -0
  9. package/dist/core/middleware.d.ts +43 -0
  10. package/dist/core/middleware.js +175 -0
  11. package/dist/core/middleware.js.map +1 -0
  12. package/dist/core/plugins.d.ts +8 -1
  13. package/dist/core/plugins.js +25 -1
  14. package/dist/core/plugins.js.map +1 -1
  15. package/dist/core/result.d.ts +2 -2
  16. package/dist/core/result.js +5 -1
  17. package/dist/core/result.js.map +1 -1
  18. package/dist/core/stream.d.ts +11 -0
  19. package/dist/core/stream.js +93 -0
  20. package/dist/core/stream.js.map +1 -0
  21. package/dist/core/types.d.ts +101 -0
  22. package/dist/index.d.ts +6 -1
  23. package/dist/index.js +3 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/providers/anthropic-converter.js +32 -6
  26. package/dist/providers/anthropic-converter.js.map +1 -1
  27. package/dist/providers/anthropic.js +64 -0
  28. package/dist/providers/anthropic.js.map +1 -1
  29. package/dist/providers/fixtures/multimodal-tool-roundtrip.d.ts +4 -0
  30. package/dist/providers/fixtures/multimodal-tool-roundtrip.js +32 -0
  31. package/dist/providers/fixtures/multimodal-tool-roundtrip.js.map +1 -0
  32. package/dist/providers/google-converter.js +53 -2
  33. package/dist/providers/google-converter.js.map +1 -1
  34. package/dist/providers/google.js +65 -0
  35. package/dist/providers/google.js.map +1 -1
  36. package/dist/providers/openai-converter.d.ts +20 -1
  37. package/dist/providers/openai-converter.js +98 -0
  38. package/dist/providers/openai-converter.js.map +1 -1
  39. package/dist/providers/openai.js +18 -1
  40. package/dist/providers/openai.js.map +1 -1
  41. package/dist/providers.d.ts +1 -1
  42. package/dist/providers.js +1 -1
  43. package/dist/providers.js.map +1 -1
  44. package/docs/pivot.md +33 -14
  45. package/docs/provider-packages.md +60 -0
  46. package/docs/retry.md +62 -0
  47. package/docs/semver.md +56 -0
  48. package/package.json +5 -2
@@ -1,5 +1,5 @@
1
1
  import type OpenAI from 'openai';
2
- import type { GenerationRequest, GenerationResult, PromptItem, ToolChoice, ToolDefinition } from '../core/types.js';
2
+ import type { GenerationRequest, GenerationResult, PromptItem, StreamEvent, ToolChoice, ToolDefinition } from '../core/types.js';
3
3
  type OpenAIMessage = OpenAI.Chat.Completions.ChatCompletionMessageParam;
4
4
  export declare function toOpenAIMessages(prompt: PromptItem[]): OpenAIMessage[];
5
5
  export declare function toOpenAITools(tools: ToolDefinition[] | undefined): OpenAI.Chat.Completions.ChatCompletionTool[] | undefined;
@@ -12,5 +12,24 @@ export declare function toOpenAIRequest(request: GenerationRequest, defaultModel
12
12
  max_completion_tokens: number | undefined;
13
13
  tools: OpenAI.Chat.Completions.ChatCompletionTool[] | undefined;
14
14
  tool_choice: OpenAI.Chat.Completions.ChatCompletionToolChoiceOption | undefined;
15
+ response_format: import("openai/resources/shared.mjs").ResponseFormatText | import("openai/resources/shared.mjs").ResponseFormatJSONSchema | import("openai/resources/shared.mjs").ResponseFormatJSONObject | undefined;
15
16
  };
17
+ export declare function toOpenAIStreamRequest(request: GenerationRequest, defaultModel: string): {
18
+ stream: true;
19
+ stream_options: {
20
+ include_usage: true;
21
+ };
22
+ model: string;
23
+ messages: OpenAI.Chat.Completions.ChatCompletionMessageParam[];
24
+ temperature: number | undefined;
25
+ max_completion_tokens: number | undefined;
26
+ tools: OpenAI.Chat.Completions.ChatCompletionTool[] | undefined;
27
+ tool_choice: OpenAI.Chat.Completions.ChatCompletionToolChoiceOption | undefined;
28
+ response_format: import("openai/resources/shared.mjs").ResponseFormatText | import("openai/resources/shared.mjs").ResponseFormatJSONSchema | import("openai/resources/shared.mjs").ResponseFormatJSONObject | undefined;
29
+ };
30
+ /**
31
+ * Accumulate OpenAI chat completion chunks into StreamEvents.
32
+ * Tool-call argument fragments are emitted as `tool-call-delta` and finalized on `done`.
33
+ */
34
+ export declare function fromOpenAIStream(chunks: AsyncIterable<OpenAI.Chat.Completions.ChatCompletionChunk>): AsyncGenerator<StreamEvent>;
16
35
  export {};
@@ -97,6 +97,21 @@ export function fromOpenAICompletion(completion) {
97
97
  raw: completion,
98
98
  };
99
99
  }
100
+ function toOpenAIResponseFormat(format) {
101
+ if (!format || format.type === 'text')
102
+ return undefined;
103
+ if (format.type === 'json') {
104
+ return { type: 'json_object' };
105
+ }
106
+ return {
107
+ type: 'json_schema',
108
+ json_schema: {
109
+ name: format.name,
110
+ schema: format.schema,
111
+ strict: format.strict,
112
+ },
113
+ };
114
+ }
100
115
  export function toOpenAIRequest(request, defaultModel) {
101
116
  return {
102
117
  model: request.model ?? defaultModel,
@@ -105,6 +120,89 @@ export function toOpenAIRequest(request, defaultModel) {
105
120
  max_completion_tokens: request.maxOutputTokens,
106
121
  tools: toOpenAITools(request.tools),
107
122
  tool_choice: toOpenAIToolChoice(request.toolChoice),
123
+ response_format: toOpenAIResponseFormat(request.responseFormat),
124
+ };
125
+ }
126
+ export function toOpenAIStreamRequest(request, defaultModel) {
127
+ return {
128
+ ...toOpenAIRequest(request, defaultModel),
129
+ stream: true,
130
+ stream_options: { include_usage: true },
131
+ };
132
+ }
133
+ /**
134
+ * Accumulate OpenAI chat completion chunks into StreamEvents.
135
+ * Tool-call argument fragments are emitted as `tool-call-delta` and finalized on `done`.
136
+ */
137
+ export async function* fromOpenAIStream(chunks) {
138
+ let text = '';
139
+ const toolCalls = new Map();
140
+ let model;
141
+ let finishReason;
142
+ let usage;
143
+ let raw;
144
+ for await (const chunk of chunks) {
145
+ raw = chunk;
146
+ model = chunk.model ?? model;
147
+ if (chunk.usage) {
148
+ usage = {
149
+ inputTokens: chunk.usage.prompt_tokens,
150
+ outputTokens: chunk.usage.completion_tokens,
151
+ totalTokens: chunk.usage.total_tokens,
152
+ cachedInputTokens: chunk.usage.prompt_tokens_details?.cached_tokens,
153
+ };
154
+ yield { type: 'usage', usage };
155
+ }
156
+ const choice = chunk.choices[0];
157
+ if (!choice)
158
+ continue;
159
+ finishReason = choice.finish_reason ?? finishReason;
160
+ const delta = choice.delta;
161
+ if (delta.content) {
162
+ text += delta.content;
163
+ yield { type: 'text-delta', text: delta.content };
164
+ }
165
+ for (const call of delta.tool_calls ?? []) {
166
+ const current = toolCalls.get(call.index) ?? { arguments: '' };
167
+ if (call.id)
168
+ current.id = call.id;
169
+ if (call.function?.name)
170
+ current.name = call.function.name;
171
+ if (call.function?.arguments) {
172
+ current.arguments += call.function.arguments;
173
+ yield {
174
+ type: 'tool-call-delta',
175
+ id: current.id,
176
+ name: current.name,
177
+ argumentsDelta: call.function.arguments,
178
+ };
179
+ }
180
+ toolCalls.set(call.index, current);
181
+ }
182
+ }
183
+ const parts = [];
184
+ if (text)
185
+ parts.push({ type: 'text', text });
186
+ for (const call of toolCalls.values()) {
187
+ if (!call.name)
188
+ continue;
189
+ const toolCall = {
190
+ id: call.id,
191
+ name: call.name,
192
+ arguments: parseArguments(call.arguments),
193
+ };
194
+ parts.push({ type: 'toolCall', toolCall });
195
+ yield { type: 'tool-call', toolCall };
196
+ }
197
+ yield {
198
+ type: 'done',
199
+ result: {
200
+ parts,
201
+ model,
202
+ finishReason: finishReason ?? undefined,
203
+ usage,
204
+ raw,
205
+ },
108
206
  };
109
207
  }
110
208
  //# sourceMappingURL=openai-converter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"openai-converter.js","sourceRoot":"","sources":["../../src/providers/openai-converter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"openai-converter.js","sourceRoot":"","sources":["../../src/providers/openai-converter.ts"],"names":[],"mappings":"AAcA,SAAS,cAAc,CAAC,KAAa;IACnC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAY,CAAC;QAC5C,OAAO,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YAC5E,CAAC,CAAE,MAAkC;YACrC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACzB,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAChB,KAAgD;IAEhD,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,QAAQ,KAAK,CAAC,SAAS,WAAW,KAAK,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;IAC9E,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAoB;IACnD,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAmB,EAAE;QAC9C,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YACjC,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;QAC7E,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC9B,OAAO;gBACL;oBACE,IAAI,EAAE,WAAW;oBACjB,OAAO,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI;oBAC1B,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM;wBACxB,CAAC,CAAC;4BACE,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gCACxC,IAAI,EAAE,UAAmB;gCACzB,EAAE,EAAE,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,IAAI;gCACxB,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE;6BACzE,CAAC,CAAC;yBACJ;wBACH,CAAC,CAAC,EAAE,CAAC;iBACR;aACF,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GAAoB,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAC1E,IAAI,EAAE,MAAM;YACZ,YAAY,EAAE,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI;YAC1C,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,CAAC,CAAC,CAAC;QACJ,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,MAAM,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9D,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM;gBACjC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;gBACrG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;YACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;QAC3C,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,KAAmC;IAEnC,OAAO,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC3B,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE;YACR,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,UAAU,EAAE,IAAI,CAAC,UAAU;SAC5B;KACF,CAAC,CAAC,CAAC;AACN,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,MAA8B;IAE9B,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC;IACzD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,UAAkD;IACrF,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACrC,MAAM,KAAK,GAAiB,EAAE,CAAC;IAC/B,IAAI,MAAM,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,OAAO,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC;QACpD,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU;YAAE,SAAS;QACvC,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE;gBACR,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;gBACxB,SAAS,EAAE,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;aACnD;SACF,CAAC,CAAC;IACL,CAAC;IACD,OAAO;QACL,KAAK;QACL,KAAK,EAAE,UAAU,CAAC,KAAK;QACvB,YAAY,EAAE,MAAM,EAAE,aAAa,IAAI,SAAS;QAChD,KAAK,EAAE,UAAU,CAAC,KAAK;YACrB,CAAC,CAAC;gBACE,WAAW,EAAE,UAAU,CAAC,KAAK,CAAC,aAAa;gBAC3C,YAAY,EAAE,UAAU,CAAC,KAAK,CAAC,iBAAiB;gBAChD,WAAW,EAAE,UAAU,CAAC,KAAK,CAAC,YAAY;gBAC1C,iBAAiB,EAAE,UAAU,CAAC,KAAK,CAAC,qBAAqB,EAAE,aAAa;aACzE;YACH,CAAC,CAAC,SAAS;QACb,GAAG,EAAE,UAAU;KAChB,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAC7B,MAA2C;IAE3C,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,SAAS,CAAC;IACxD,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC3B,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;IACjC,CAAC;IACD,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE;YACX,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAA0B,EAAE,YAAoB;IAC9E,OAAO;QACL,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,YAAY;QACpC,QAAQ,EAAE,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC;QAC1C,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,qBAAqB,EAAE,OAAO,CAAC,eAAe;QAC9C,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC;QACnC,WAAW,EAAE,kBAAkB,CAAC,OAAO,CAAC,UAAU,CAAC;QACnD,eAAe,EAAE,sBAAsB,CAAC,OAAO,CAAC,cAAc,CAAC;KACS,CAAC;AAC7E,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,OAA0B,EAAE,YAAoB;IACpF,OAAO;QACL,GAAG,eAAe,CAAC,OAAO,EAAE,YAAY,CAAC;QACzC,MAAM,EAAE,IAAa;QACrB,cAAc,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE;KAC8B,CAAC;AAC1E,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,gBAAgB,CACrC,MAAkE;IAElE,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,MAAM,SAAS,GAAG,IAAI,GAAG,EAA6D,CAAC;IACvF,IAAI,KAAyB,CAAC;IAC9B,IAAI,YAAgC,CAAC;IACrC,IAAI,KAA6B,CAAC;IAClC,IAAI,GAA4D,CAAC;IAEjE,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QACjC,GAAG,GAAG,KAAK,CAAC;QACZ,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC;QAC7B,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,KAAK,GAAG;gBACN,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,aAAa;gBACtC,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC,iBAAiB;gBAC3C,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,YAAY;gBACrC,iBAAiB,EAAE,KAAK,CAAC,KAAK,CAAC,qBAAqB,EAAE,aAAa;aACpE,CAAC;YACF,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QACjC,CAAC;QAED,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAChC,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,YAAY,GAAG,MAAM,CAAC,aAAa,IAAI,YAAY,CAAC;QAEpD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC3B,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAClB,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC;YACtB,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;QACpD,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC;YAC1C,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;YAC/D,IAAI,IAAI,CAAC,EAAE;gBAAE,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;YAClC,IAAI,IAAI,CAAC,QAAQ,EAAE,IAAI;gBAAE,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YAC3D,IAAI,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,CAAC;gBAC7B,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;gBAC7C,MAAM;oBACJ,IAAI,EAAE,iBAAiB;oBACvB,EAAE,EAAE,OAAO,CAAC,EAAE;oBACd,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,cAAc,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS;iBACxC,CAAC;YACJ,CAAC;YACD,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAiB,EAAE,CAAC;IAC/B,IAAI,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAE7C,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;QACtC,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,SAAS;QACzB,MAAM,QAAQ,GAAG;YACf,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,SAAS,EAAE,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC;SAC1C,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC3C,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC;IACxC,CAAC;IAED,MAAM;QACJ,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE;YACN,KAAK;YACL,KAAK;YACL,YAAY,EAAE,YAAY,IAAI,SAAS;YACvC,KAAK;YACL,GAAG;SACJ;KACF,CAAC;AACJ,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import OpenAI from 'openai';
2
- import { fromOpenAICompletion, toOpenAIRequest } from './openai-converter.js';
2
+ import { fromOpenAICompletion, fromOpenAIStream, toOpenAIRequest, toOpenAIStreamRequest } from './openai-converter.js';
3
3
  export function openai(options = {}) {
4
4
  const client = new OpenAI({
5
5
  apiKey: options.apiKey ?? process.env.OPENAI_API_KEY,
@@ -10,6 +10,13 @@ export function openai(options = {}) {
10
10
  const defaultModel = options.model ?? process.env.OPENAI_MODEL;
11
11
  return {
12
12
  name: 'openai',
13
+ capabilities: {
14
+ streaming: true,
15
+ tools: true,
16
+ images: 'input',
17
+ systemPrompt: true,
18
+ jsonResponse: true,
19
+ },
13
20
  async generate(request) {
14
21
  const model = request.model ?? defaultModel;
15
22
  if (!model) {
@@ -20,6 +27,16 @@ export function openai(options = {}) {
20
27
  });
21
28
  return fromOpenAICompletion(completion);
22
29
  },
30
+ async *stream(request) {
31
+ const model = request.model ?? defaultModel;
32
+ if (!model) {
33
+ throw new Error('No OpenAI model configured. Pass `model` to openai() or the request builder.');
34
+ }
35
+ const chunks = await client.chat.completions.create(toOpenAIStreamRequest(request, model), {
36
+ signal: request.signal,
37
+ });
38
+ yield* fromOpenAIStream(chunks);
39
+ },
23
40
  };
24
41
  }
25
42
  export function openaiCompatible(options) {
@@ -1 +1 @@
1
- {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAU9E,MAAM,UAAU,MAAM,CAAC,UAAiC,EAAE;IACxD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;QACxB,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc;QACpD,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC,CAAC;IACH,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IAE/D,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,KAAK,CAAC,QAAQ,CAAC,OAAO;YACpB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC;YAC5C,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAC;YAClG,CAAC;YACD,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE;gBACvF,MAAM,EAAE,OAAO,CAAC,MAAM;aACvB,CAAC,CAAC;YACH,OAAO,oBAAoB,CAAC,UAAU,CAAC,CAAC;QAC1C,CAAC;KACF,CAAC;AACJ,CAAC;AAMD,MAAM,UAAU,gBAAgB,CAAC,OAAwC;IACvE,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IACjC,OAAO,EAAE,GAAG,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,mBAAmB,EAAE,CAAC;AACpE,CAAC"}
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAUvH,MAAM,UAAU,MAAM,CAAC,UAAiC,EAAE;IACxD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;QACxB,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc;QACpD,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC,CAAC;IACH,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IAE/D,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,YAAY,EAAE;YACZ,SAAS,EAAE,IAAI;YACf,KAAK,EAAE,IAAI;YACX,MAAM,EAAE,OAAO;YACf,YAAY,EAAE,IAAI;YAClB,YAAY,EAAE,IAAI;SACnB;QACD,KAAK,CAAC,QAAQ,CAAC,OAAO;YACpB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC;YAC5C,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAC;YAClG,CAAC;YACD,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE;gBACvF,MAAM,EAAE,OAAO,CAAC,MAAM;aACvB,CAAC,CAAC;YACH,OAAO,oBAAoB,CAAC,UAAU,CAAC,CAAC;QAC1C,CAAC;QACD,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO;YACnB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC;YAC5C,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAC;YAClG,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,qBAAqB,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE;gBACzF,MAAM,EAAE,OAAO,CAAC,MAAM;aACvB,CAAC,CAAC;YACH,KAAK,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC;KACF,CAAC;AACJ,CAAC;AAMD,MAAM,UAAU,gBAAgB,CAAC,OAAwC;IACvE,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IACjC,OAAO,EAAE,GAAG,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,mBAAmB,EAAE,CAAC;AACpE,CAAC"}
@@ -8,4 +8,4 @@ export { fromGoogleResponse, toGoogleContents, toGoogleRequest, toGoogleSystemIn
8
8
  export type { GoogleRequestDefaults } from './providers/google-converter.js';
9
9
  export { openai, openaiCompatible } from './providers/openai.js';
10
10
  export type { OpenAICompatibleProviderOptions, OpenAIProviderOptions } from './providers/openai.js';
11
- export { fromOpenAICompletion, toOpenAIMessages, toOpenAIRequest, toOpenAIToolChoice, toOpenAITools, } from './providers/openai-converter.js';
11
+ export { fromOpenAICompletion, fromOpenAIStream, toOpenAIMessages, toOpenAIRequest, toOpenAIStreamRequest, toOpenAIToolChoice, toOpenAITools, } from './providers/openai-converter.js';
package/dist/providers.js CHANGED
@@ -3,5 +3,5 @@ export { fromAnthropicMessage, toAnthropicMessages, toAnthropicRequest, toAnthro
3
3
  export { gemini, vertexAI } from './providers/google.js';
4
4
  export { fromGoogleResponse, toGoogleContents, toGoogleRequest, toGoogleSystemInstruction, } from './providers/google-converter.js';
5
5
  export { openai, openaiCompatible } from './providers/openai.js';
6
- export { fromOpenAICompletion, toOpenAIMessages, toOpenAIRequest, toOpenAIToolChoice, toOpenAITools, } from './providers/openai-converter.js';
6
+ export { fromOpenAICompletion, fromOpenAIStream, toOpenAIMessages, toOpenAIRequest, toOpenAIStreamRequest, toOpenAIToolChoice, toOpenAITools, } from './providers/openai-converter.js';
7
7
  //# sourceMappingURL=providers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"providers.js","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,yBAAyB,GAC1B,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEjE,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,aAAa,GACd,MAAM,iCAAiC,CAAC"}
1
+ {"version":3,"file":"providers.js","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,yBAAyB,GAC1B,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEjE,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,kBAAkB,EAClB,aAAa,GACd,MAAM,iCAAiC,CAAC"}
package/docs/pivot.md CHANGED
@@ -71,20 +71,39 @@ and in the 1.x npm line.
71
71
  - Add converter contract tests with multimodal and tool-call fixtures.
72
72
  - Keep provider SDKs isolated behind the `genaicode/providers` export.
73
73
 
74
- ### Phase 3: backend ergonomics
75
-
76
- - Streaming with a provider-neutral event IR.
77
- - Middleware for observability, rate limiting, caching, and fallback.
78
- - First-class schema adapters without requiring a specific validation library.
79
- - Small framework examples for HTTP handlers, queues, and cron jobs.
80
- - Re-evaluate separate provider packages if dependency size becomes material.
81
-
82
- ### Phase 4: hardening
83
-
84
- - Provider capability metadata.
85
- - Retry classification and idempotency guidance.
86
- - Compatibility fixtures for multimodal and tool-call round trips.
87
- - Stable extension contracts and a written semver policy.
74
+ ### Phase 3: backend ergonomics — implemented
75
+
76
+ - Streaming with a provider-neutral event IR — implemented (`StreamEvent`,
77
+ `RequestBuilder.stream` / `streamText`, native provider streams with generate
78
+ fallback).
79
+ - Middleware for observability, rate limiting, caching, and fallback —
80
+ implemented (`timingPlugin`, `rateLimitPlugin`, `cachePlugin`, `fallbackPlugin`,
81
+ `fallbackProvider`).
82
+ - First-class schema adapters without requiring a specific validation library — implemented.
83
+ - Small framework examples for HTTP handlers, queues, and cron jobs — implemented
84
+ under `examples/`.
85
+ - Re-evaluate separate provider packages if dependency size becomes material —
86
+ evaluated; keep bundled for 2.x (see [provider-packages.md](./provider-packages.md)).
87
+
88
+ ### Phase 4: hardening — implemented
89
+
90
+ - Provider capability metadata — implemented (`ProviderCapabilities` on
91
+ `ModelProvider`).
92
+ - Retry classification and idempotency guidance — implemented
93
+ (`classifyError` / `withRetry` + [retry.md](./retry.md)).
94
+ - Compatibility fixtures for multimodal and tool-call round trips — implemented
95
+ under `src/providers/fixtures/`.
96
+ - Stable extension contracts and a written semver policy — implemented
97
+ ([semver.md](./semver.md)).
98
+
99
+ ### Release status
100
+
101
+ - `2.0.0` on npm shipped the Phase 1–2 kernel and provider adapters.
102
+ - `2.1.0` publishes Phases 3–4 (streaming, middleware, capabilities, retry
103
+ helpers, fixtures, examples, and related docs).
104
+ - `2.2.0` adds portable `responseFormat` and `thinking` request fields (so apps
105
+ need fewer provider-specific `generationConfig` casts). See
106
+ [CHANGELOG.md](../CHANGELOG.md).
88
107
 
89
108
  ## Success measures
90
109
 
@@ -0,0 +1,60 @@
1
+ # Provider package split evaluation
2
+
3
+ Phase 3 asked whether OpenAI, Anthropic, and Google adapters should move into
4
+ separate packages to shrink the default install.
5
+
6
+ ## Current shape
7
+
8
+ | Package surface | Role |
9
+ | ---------------------- | ----------------------------------------- |
10
+ | `genaicode` | Core client, IR, plugins, middleware |
11
+ | `genaicode/providers` | Adapters + public converters |
12
+
13
+ Hard dependencies today (approximate installed sizes in this repo's lockfile):
14
+
15
+ - `openai` ~12MB
16
+ - `@anthropic-ai/sdk` ~5MB
17
+ - `@google/genai` (+ tree) ~14MB
18
+
19
+ Together the provider SDKs dominate runtime dependency weight versus the small
20
+ core TypeScript sources.
21
+
22
+ ## Options considered
23
+
24
+ 1. **Keep bundled (status quo)**
25
+ One install, one version matrix, simplest DX. Cost: every consumer downloads
26
+ all three SDKs even if they only use one.
27
+
28
+ 2. **Separate packages** (`genaicode-openai`, `genaicode-anthropic`, …)
29
+ Smallest installs. Cost: version skew between core and adapters, more release
30
+ surface, harder getting-started docs.
31
+
32
+ 3. **Peer dependencies + optional installs**
33
+ Core stays free of SDKs; `genaicode/providers` re-exports adapters that import
34
+ peers. Cost: peer warnings and slightly worse first-run DX.
35
+
36
+ ## Decision for 2.0
37
+
38
+ **Keep provider adapters bundled behind `genaicode/providers` for 2.x.**
39
+
40
+ Reasons:
41
+
42
+ - The product pitch is a tiny portable layer with batteries-included adapters.
43
+ - Converter functions are part of the public compatibility story and are tested
44
+ together against shared fixtures.
45
+ - Absolute weight (~30MB of SDKs) is material but still far smaller than GenAIcode
46
+ 1.x; success measures emphasize “substantially smaller than 1.x,” not absolute
47
+ minimalism.
48
+ - Splitting before streaming, middleware, and capability metadata settled would
49
+ freeze the wrong package boundaries.
50
+
51
+ ## Revisit triggers
52
+
53
+ Split (or move to optional peers) when any of these become true:
54
+
55
+ - Published install size or cold `npm install` time becomes a documented user pain.
56
+ - A provider SDK forces frequent breaking upgrades independent of core.
57
+ - Tree-shaking cannot eliminate unused SDKs for bundlers targeting edge runtimes.
58
+
59
+ Until then, application authors who need a zero-SDK core can implement
60
+ `ModelProvider` directly and ignore `genaicode/providers`.
package/docs/retry.md ADDED
@@ -0,0 +1,62 @@
1
+ # Retry classification and idempotency
2
+
3
+ GenAIcode does **not** retry provider calls automatically. Retries, backoff, and
4
+ failure budgets belong to application code so side effects stay explicit.
5
+
6
+ ## Classify, then decide
7
+
8
+ ```ts
9
+ import { classifyError, isRetryable, withRetry } from 'genaicode';
10
+
11
+ const classified = classifyError(error);
12
+ if (classified.retryable) {
13
+ // transient: 408/425/429/5xx, network resets, overload heuristics
14
+ }
15
+
16
+ await withRetry(() => ai('summarize this').text(), {
17
+ attempts: 3,
18
+ delayMs: 250,
19
+ shouldRetry: (error) => isRetryable(error),
20
+ });
21
+ ```
22
+
23
+ `classifyError` returns `{ class, retryable, reason, status?, code?, cause }`:
24
+
25
+ | Class | Typical causes | Retry? |
26
+ | ----------- | -------------------------------------- | ------ |
27
+ | `transient` | 429, 5xx, timeouts, connection resets | yes |
28
+ | `permanent` | 4xx (except above), auth, abort | no |
29
+ | `unknown` | Unrecognized shapes | no* |
30
+
31
+ \*Treat unknown as non-retryable by default; override with `shouldRetry` when you
32
+ know more about your gateway.
33
+
34
+ ## Idempotency guidance
35
+
36
+ Safe to retry without extra coordination:
37
+
38
+ - Pure generation (`text`, `json`, `toolCalls` that only *propose* tool calls)
39
+ - Read-only prompts against immutable inputs
40
+
41
+ Not safe to retry blindly:
42
+
43
+ - Application code that executes tool calls with side effects (writes, charges, emails)
44
+ - Chains where a partial turn already mutated external state
45
+
46
+ Patterns that keep retries safe:
47
+
48
+ 1. **Propose, then commit.** Let the model return a plan; apply side effects once
49
+ after validation.
50
+ 2. **Idempotency keys.** If a tool must run inside a retry loop, key the effect
51
+ (e.g. `Idempotency-Key` on a payment API) so duplicates collapse.
52
+ 3. **Outbox / queue.** Persist the intended effect before calling the provider, or
53
+ after a successful model response but before side effects, depending on your
54
+ failure mode.
55
+ 4. **Do not put retries inside plugins by default.** A retry plugin hides policy
56
+ from callers; prefer `withRetry` at the call site or a named, intentional plugin.
57
+
58
+ ## Streaming
59
+
60
+ If a stream fails mid-flight, do not assume the partial text was committed anywhere.
61
+ Re-run the full request (or resume with your own checkpointing). Conversation
62
+ chains only append history after a successful completed turn.
package/docs/semver.md ADDED
@@ -0,0 +1,56 @@
1
+ # Semver and extension contracts
2
+
3
+ GenAIcode 2.x follows semantic versioning for the published TypeScript API.
4
+
5
+ ## Public contracts (semver-stable)
6
+
7
+ These are covered by minor/patch compatibility within 2.x:
8
+
9
+ - `genaicode()` client, immutable request builders, and conversation chains
10
+ - `PromptItem`, `GenerationRequest`, `GenerationResult`, `StreamEvent`
11
+ - `ResponseFormat`, `ThinkingConfig`, and related capability flags
12
+ - `ModelProvider` and `GenAIPlugin` interfaces
13
+ - Prompt helpers (`prompt`, `system`, `user`, `assistant`, `asPrompt`, …)
14
+ - Result helpers (`resultText`, `parseJsonResult`, …)
15
+ - Built-in middleware factories (`timingPlugin`, `rateLimitPlugin`, `cachePlugin`,
16
+ `fallbackPlugin`, `fallbackProvider`)
17
+ - Error helpers (`classifyError`, `isRetryable`, `withRetry`)
18
+ - Provider factories and converter functions exported from `genaicode/providers`
19
+
20
+ ## Additive changes (minor)
21
+
22
+ Safe in a minor release:
23
+
24
+ - New optional fields on request/result/stream types
25
+ - New optional methods on `ModelProvider` / `GenAIPlugin` (callers must feature-detect)
26
+ - New exports and middleware helpers
27
+ - New provider adapters behind `genaicode/providers`
28
+ - New capability flags on `ProviderCapabilities`
29
+
30
+ ## Breaking changes (major)
31
+
32
+ Require a new major version:
33
+
34
+ - Removing or renaming exports
35
+ - Changing the meaning of existing `PromptItem` fields
36
+ - Making previously optional callback/plugin behavior mandatory
37
+ - Changing default retry/side-effect policy (there is none today; introducing
38
+ hidden retries would be a major behavioral break)
39
+ - Moving provider SDKs in a way that removes the current `genaicode/providers`
40
+ entry without a compatibility window
41
+
42
+ ## Non-guarantees
43
+
44
+ - Exact shapes of `raw` provider payloads
45
+ - Timing of stream events beyond the `StreamEvent` discriminant
46
+ - Dependency versions of underlying provider SDKs within a major (may bump in
47
+ minors when needed for security or API drift)
48
+ - Example apps under `examples/` (illustrative only)
49
+
50
+ ## Plugin and provider authors
51
+
52
+ - Depend on TypeScript types from `genaicode`, not on private `dist/` paths.
53
+ - Prefer ordinary package exports over runtime loaders.
54
+ - Feature-detect `provider.stream` and `provider.capabilities`.
55
+ - Treat `metadata` on `GenerationRequest` as an open bag for your middleware;
56
+ do not require core to understand your keys.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genaicode",
3
- "version": "2.0.0",
3
+ "version": "2.3.0",
4
4
  "description": "A small, provider-neutral TypeScript toolkit for calling LLMs from backend code.",
5
5
  "author": "Grzegorz Tańczyk",
6
6
  "repository": {
@@ -27,6 +27,7 @@
27
27
  "files": [
28
28
  "dist",
29
29
  "docs",
30
+ "CHANGELOG.md",
30
31
  "README.md",
31
32
  "LICENSE"
32
33
  ],
@@ -45,10 +46,12 @@
45
46
  "build": "npm run clean && tsc -p tsconfig.build.json",
46
47
  "lint": "eslint . --ext js,ts --report-unused-disable-directives --max-warnings 0",
47
48
  "test": "vitest --config vitest.unit.config.ts --run",
49
+ "test:e2e": "vitest --config vitest.e2e.config.ts --run",
48
50
  "test:watch": "vitest --config vitest.unit.config.ts",
49
51
  "type-check": "tsc --noEmit",
50
52
  "check": "npm run type-check && npm run lint && npm test && npm run build",
51
- "prepublishOnly": "npm run check"
53
+ "prepublishOnly": "npm run check",
54
+ "prepare": "npm run build"
52
55
  },
53
56
  "dependencies": {
54
57
  "@anthropic-ai/sdk": "^0.74.0",