@aeye/openrouter 0.4.1 → 0.5.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 (33) hide show
  1. package/README.md +152 -65
  2. package/aeye-openrouter.md +175 -161
  3. package/dist/__integration__/openrouter.integration.test.js +6 -6
  4. package/dist/__integration__/openrouter.integration.test.js.map +1 -1
  5. package/dist/__tests__/batch.test.d.ts +5 -0
  6. package/dist/__tests__/batch.test.d.ts.map +1 -0
  7. package/dist/__tests__/batch.test.js +41 -0
  8. package/dist/__tests__/batch.test.js.map +1 -0
  9. package/dist/__tests__/features.test.d.ts +5 -0
  10. package/dist/__tests__/features.test.d.ts.map +1 -0
  11. package/dist/__tests__/features.test.js +206 -0
  12. package/dist/__tests__/features.test.js.map +1 -0
  13. package/dist/__tests__/openrouter.test.js +38 -1
  14. package/dist/__tests__/openrouter.test.js.map +1 -1
  15. package/dist/__tests__/rerank-decide.test.d.ts +5 -0
  16. package/dist/__tests__/rerank-decide.test.d.ts.map +1 -0
  17. package/dist/__tests__/rerank-decide.test.js +75 -0
  18. package/dist/__tests__/rerank-decide.test.js.map +1 -0
  19. package/dist/__tests__/schema-rejection.test.d.ts +6 -0
  20. package/dist/__tests__/schema-rejection.test.d.ts.map +1 -0
  21. package/dist/__tests__/schema-rejection.test.js +39 -0
  22. package/dist/__tests__/schema-rejection.test.js.map +1 -0
  23. package/dist/openrouter.d.ts +100 -41
  24. package/dist/openrouter.d.ts.map +1 -1
  25. package/dist/openrouter.js +390 -211
  26. package/dist/openrouter.js.map +1 -1
  27. package/dist/source.d.ts +9 -4
  28. package/dist/source.d.ts.map +1 -1
  29. package/dist/source.js +45 -28
  30. package/dist/source.js.map +1 -1
  31. package/dist/types.d.ts +244 -81
  32. package/dist/types.d.ts.map +1 -1
  33. package/package.json +71 -71
@@ -0,0 +1,206 @@
1
+ /**
2
+ * OpenRouter request features, response extras, and model conversion.
3
+ */
4
+ import { AI } from '@aeye/ai';
5
+ import { accumulateReasoning, TEXT_TOOL_SCHEMA } from '@aeye/core';
6
+ import { convertOpenRouterModel, OpenRouterProvider } from '../openrouter';
7
+ const mockCreate = jest.fn();
8
+ jest.mock('openai', () => jest.fn().mockImplementation(() => ({
9
+ chat: { completions: { create: mockCreate } },
10
+ })));
11
+ const ctx = { ai: AI.with().providers({}).create({}), metadata: {} };
12
+ const hi = { messages: [{ role: 'user', content: 'Hi' }] };
13
+ const completion = (message, usage) => ({
14
+ id: 'gen-1',
15
+ choices: [{ message: { role: 'assistant', content: 'ok', ...message }, finish_reason: 'stop' }],
16
+ usage,
17
+ });
18
+ const sentParams = () => mockCreate.mock.calls[mockCreate.mock.calls.length - 1][0];
19
+ beforeEach(() => mockCreate.mockReset().mockResolvedValue(completion({})));
20
+ describe('request', () => {
21
+ it('sends reasoning as one object with a budget or an effort, never both', async () => {
22
+ await new OpenRouterProvider({ apiKey: 'k' }).createExecutor()({ ...hi, reason: { effort: 'high', exclude: true, maxTokens: 2000 } }, ctx, { model: 'openai/gpt-5.4' });
23
+ expect(sentParams().reasoning).toEqual({ enabled: true, max_tokens: 2000, exclude: true });
24
+ expect(sentParams()).not.toHaveProperty('reasoning_effort');
25
+ await new OpenRouterProvider({ apiKey: 'k' }).createExecutor()({ ...hi, reason: { effort: 'high' } }, ctx, { model: 'openai/gpt-5.4' });
26
+ expect(sentParams().reasoning).toEqual({ enabled: true, effort: 'high' });
27
+ });
28
+ it('maps routing, fallbacks, plugins, and the deprecated middle-out transform', async () => {
29
+ const provider = new OpenRouterProvider({
30
+ apiKey: 'k',
31
+ defaultParams: {
32
+ providers: { sort: { by: 'throughput', partition: 'none' }, preferredMaxLatency: 2, enforceDistillableText: true },
33
+ fallbackModels: ['anthropic/claude-sonnet-5'],
34
+ plugins: [{ id: 'response-healing' }],
35
+ transforms: ['middle-out'],
36
+ },
37
+ });
38
+ await provider.createExecutor()({ ...hi, userKey: 'user-1' }, ctx, { model: 'openai/gpt-5.4' });
39
+ expect(sentParams()).toMatchObject({
40
+ provider: { sort: { by: 'throughput', partition: 'none' }, preferred_max_latency: 2, enforce_distillable_text: true },
41
+ models: ['anthropic/claude-sonnet-5'],
42
+ plugins: [{ id: 'response-healing' }, { id: 'context-compression', engine: 'middle-out' }],
43
+ user: 'user-1',
44
+ });
45
+ expect(sentParams()).not.toHaveProperty('transforms');
46
+ });
47
+ it('runs hosted tools as OpenRouter server tools through chat', async () => {
48
+ await new OpenRouterProvider({ apiKey: 'k' }).createExecutor()({
49
+ ...hi,
50
+ hostedTools: [{ type: 'web_search', maxResults: 3, allowedDomains: ['github.com'] }, { type: 'web_fetch' }],
51
+ }, ctx, { model: 'openai/gpt-5.4' });
52
+ expect(sentParams().tools).toEqual([
53
+ { type: 'openrouter:web_search', parameters: { max_results: 3, allowed_domains: ['github.com'], excluded_domains: undefined } },
54
+ { type: 'openrouter:web_fetch' },
55
+ ]);
56
+ });
57
+ it('sends only the allowed tools, since OpenRouter ignores allowed_tools', async () => {
58
+ const tool = (name) => ({ name, parameters: TEXT_TOOL_SCHEMA });
59
+ await new OpenRouterProvider({ apiKey: 'k' }).createExecutor()({
60
+ ...hi,
61
+ tools: [tool('weather'), tool('news')],
62
+ toolChoice: { allowed: ['news'], required: true },
63
+ }, ctx, { model: 'anthropic/claude-haiku-4.5' });
64
+ expect(sentParams().tools.map((t) => t.function.name)).toEqual(['news']);
65
+ expect(sentParams().tool_choice).toBe('required');
66
+ });
67
+ it('marks cache breakpoints with cache_control', async () => {
68
+ await new OpenRouterProvider({ apiKey: 'k' }).createExecutor()({
69
+ messages: [{ role: 'user', content: [{ type: 'text', content: 'Shared prefix', cacheBreakpoint: true }] }],
70
+ }, ctx, { model: 'anthropic/claude-sonnet-5' });
71
+ expect(sentParams().messages[0].content[0]).toEqual({ type: 'text', text: 'Shared prefix', cache_control: { type: 'ephemeral' } });
72
+ });
73
+ it('replays reasoning on its own turn, with no empty text beside tool calls', async () => {
74
+ // As captured from anthropic/claude-haiku-4.5: Anthropic checks the signature, and
75
+ // upstreams such as Qwen's reject an empty text part
76
+ const details = [{ type: 'reasoning.text', text: 'Roll first.', signature: 'sig', format: 'anthropic-claude-v1', index: 0 }];
77
+ const call = { id: 'toolu_1', name: 'roll_dice', arguments: '{"count":4}' };
78
+ await new OpenRouterProvider({ apiKey: 'k' }).createExecutor()({
79
+ messages: [
80
+ { role: 'user', content: 'Q' },
81
+ { role: 'assistant', content: 'A', reasoning: { content: 'Thinking', details, provider: 'openrouter' } },
82
+ { role: 'user', content: 'Q2' },
83
+ { role: 'assistant', content: '', toolCalls: [call], reasoning: { content: 'Roll first.', details } },
84
+ { role: 'tool', toolCallId: 'toolu_1', content: '7' },
85
+ ],
86
+ }, ctx, { model: 'anthropic/claude-sonnet-5' });
87
+ const [, answer, , roll] = sentParams().messages;
88
+ expect(answer).toMatchObject({ role: 'assistant', content: [{ type: 'text', text: 'A' }], reasoning: 'Thinking', reasoning_details: details });
89
+ expect(roll).toEqual({
90
+ role: 'assistant',
91
+ content: null,
92
+ tool_calls: [{ id: 'toolu_1', type: 'function', function: { name: 'roll_dice', arguments: '{"count":4}' } }],
93
+ reasoning: 'Roll first.',
94
+ reasoning_details: details,
95
+ });
96
+ expect(sentParams().messages).toHaveLength(5);
97
+ });
98
+ it('replays only reasoning OpenRouter produced', async () => {
99
+ // As captured from OpenAI gpt-5.4-nano directly: encrypted for another account
100
+ const details = [{ id: 'rs_1', type: 'reasoning.encrypted', format: 'openai-responses-v1', data: 'ENC' }];
101
+ await new OpenRouterProvider({ apiKey: 'k' }).createExecutor()({
102
+ messages: [
103
+ { role: 'user', content: 'Q' },
104
+ { role: 'assistant', content: 'A', reasoning: { details, provider: 'openai' } },
105
+ { role: 'user', content: 'Q2' },
106
+ ],
107
+ }, ctx, { model: 'openai/gpt-5.4-mini' });
108
+ expect(sentParams().messages[1]).not.toHaveProperty('reasoning_details');
109
+ });
110
+ });
111
+ describe('response', () => {
112
+ it('counts tokens once, adds the BYOK upstream bill, and counts server tools', async () => {
113
+ mockCreate.mockResolvedValue(completion({}, {
114
+ prompt_tokens: 100,
115
+ completion_tokens: 40,
116
+ total_tokens: 140,
117
+ prompt_tokens_details: { cached_tokens: 30 },
118
+ completion_tokens_details: { reasoning_tokens: 25 },
119
+ cost: 0.001,
120
+ is_byok: true,
121
+ cost_details: { upstream_inference_cost: 0.02 },
122
+ server_tool_use_details: { web_search_requests: 2 },
123
+ }));
124
+ const response = await new OpenRouterProvider({ apiKey: 'k' }).createExecutor()(hi, ctx, { model: 'openai/gpt-5.4' });
125
+ expect(response.usage).toEqual({
126
+ text: { input: 70, output: 15, cached: 30 },
127
+ reasoning: { output: 25 },
128
+ tools: { web_search: 2 },
129
+ cost: 0.021,
130
+ });
131
+ });
132
+ it('streams reasoning deltas from both reasoning and reasoning_details', async () => {
133
+ // As measured from anthropic/claude-haiku-4.5 and google/gemini-3.5-flash:
134
+ // each delta once in both fields, the signature or encrypted payload last
135
+ const format = 'anthropic-claude-v1';
136
+ const deltas = ['Is 391', ' prime', '?', ' Try', ' the', ' primes', '.', '\n', '\n', ' 17', ' times', ' the', ' 23', '.'];
137
+ const chunk = (delta, finish_reason = null) => ({ id: 'gen-1', choices: [{ index: 0, delta, finish_reason }] });
138
+ mockCreate.mockResolvedValue((async function* () {
139
+ for (const text of deltas) {
140
+ yield chunk({ reasoning: text, reasoning_details: [{ type: 'reasoning.text', text, format, index: 0 }] });
141
+ }
142
+ yield chunk({ reasoning_details: [{ type: 'reasoning.text', signature: 'sig', format, index: 0 }] });
143
+ yield chunk({ reasoning: null, reasoning_details: [{ type: 'reasoning.encrypted', data: 'ENC', format, index: 0 }] });
144
+ yield chunk({ content: 'No.' }, 'stop');
145
+ })());
146
+ const stream = new OpenRouterProvider({ apiKey: 'k' }).createStreamer()(hi, ctx, { model: 'anthropic/claude-haiku-4.5' });
147
+ let partial;
148
+ let next = await stream.next();
149
+ for (; !next.done; next = await stream.next()) {
150
+ partial = accumulateReasoning(partial, next.value.reasoning);
151
+ }
152
+ const text = deltas.join('');
153
+ const reasoning = {
154
+ content: text,
155
+ details: [{ type: 'reasoning.text', text, signature: 'sig', format, index: 0 }, { type: 'reasoning.encrypted', data: 'ENC', format, index: 0 }],
156
+ provider: 'openrouter',
157
+ };
158
+ expect(partial).toEqual(reasoning);
159
+ expect(next.value.reasoning).toEqual(reasoning);
160
+ });
161
+ it('generates images through chat', async () => {
162
+ mockCreate.mockResolvedValue(completion({ images: [{ type: 'image_url', image_url: { url: 'data:image/png;base64,AAA' } }] }));
163
+ const response = await new OpenRouterProvider({ apiKey: 'k' }).generateImage({ prompt: 'A dot', size: '1600x900' }, ctx);
164
+ expect(sentParams()).toMatchObject({
165
+ model: 'google/gemini-2.5-flash-image',
166
+ modalities: ['image', 'text'],
167
+ image_config: { aspect_ratio: '16:9' },
168
+ });
169
+ expect(response.images).toEqual([{ url: 'data:image/png;base64,AAA' }]);
170
+ });
171
+ });
172
+ describe('convertOpenRouterModel', () => {
173
+ const model = {
174
+ id: 'openai/gpt-5.4-mini',
175
+ canonical_slug: 'openai/gpt-5.4-mini-20260317',
176
+ hugging_face_id: null,
177
+ name: 'OpenAI: GPT-5.4 Mini',
178
+ created: 1,
179
+ context_length: 400000,
180
+ architecture: { modality: 'text+image+file->text', input_modalities: ['text', 'image', 'file'], output_modalities: ['text'], tokenizer: 'GPT', instruct_type: null },
181
+ pricing: { prompt: '0.00000075', completion: '0.0000045', input_cache_read: '0.000000075', web_search: '0.01', internal_reasoning: '0' },
182
+ top_provider: { context_length: 400000, max_completion_tokens: 128000, is_moderated: true },
183
+ supported_parameters: ['tools', 'reasoning', 'response_format', 'structured_outputs', 'verbosity', 'seed'],
184
+ default_parameters: null,
185
+ reasoning: { supported_efforts: ['xhigh', 'high', 'medium', 'low', 'none'], default_effort: 'medium' },
186
+ expiration_date: '2027-03-01T00:00:00Z',
187
+ knowledge_cutoff: '2025-08-31',
188
+ };
189
+ it('maps capabilities, prices, efforts, and retirement', () => {
190
+ const info = convertOpenRouterModel(model, new Set([model.id]));
191
+ expect([...info.capabilities].sort()).toEqual(['chat', 'files', 'json', 'reasoning', 'streaming', 'structured', 'tools', 'vision', 'zdr']);
192
+ expect(info.pricing.text).toEqual({ input: 0.75, output: 4.5, cached: 0.075, cacheWrite: undefined });
193
+ expect(info.pricing.tools).toEqual({ web_search: 0.01 });
194
+ expect(info.pricing.reasoning).toBeUndefined();
195
+ expect(info.reasoningEfforts).toEqual(['none', 'low', 'medium', 'high', 'xhigh']);
196
+ expect(info.retiresAt).toBe('2027-03-01');
197
+ expect([...info.supportedParameters ?? []]).toEqual(expect.arrayContaining(['verbosity', 'seed']));
198
+ });
199
+ it('recognizes speech, transcription, and embedding models', () => {
200
+ const as = (modality) => convertOpenRouterModel({ ...model, architecture: modality, supported_parameters: [] }, new Set()).capabilities;
201
+ expect([...as({ ...model.architecture, input_modalities: ['text'], output_modalities: ['speech'] })]).toEqual(['audio']);
202
+ expect([...as({ ...model.architecture, input_modalities: ['audio'], output_modalities: ['transcription'] })]).toEqual(['hearing']);
203
+ expect([...as({ ...model.architecture, input_modalities: ['text'], output_modalities: ['embeddings'] })]).toEqual(['embedding']);
204
+ });
205
+ });
206
+ //# sourceMappingURL=features.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features.test.js","sourceRoot":"","sources":["../../src/__tests__/features.test.ts"],"names":[],"mappings":"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"}
@@ -109,6 +109,27 @@ describe('OpenRouterProvider strict structured output enforcement', () => {
109
109
  expect(body.provider?.allow_fallbacks).toBe(false);
110
110
  expect(body.provider?.order).toEqual(['openai']);
111
111
  });
112
+ it('mentions JSON once when a response format is set and the messages never do', async () => {
113
+ const provider = new OpenRouterProvider({ apiKey: 'test-key' });
114
+ const silent = await buildBody(provider, strictRequest);
115
+ expect(silent.messages[0]).toEqual({ role: 'system', content: 'Respond in JSON.' });
116
+ const said = await buildBody(provider, { ...strictRequest, messages: [{ role: 'user', content: 'Return the query as JSON' }] });
117
+ expect(said.messages).toHaveLength(1);
118
+ });
119
+ it('sends the Anthropic structured-outputs flag only with a strict tool', async () => {
120
+ const haiku = { ...gpt4o, id: 'anthropic/claude-haiku-4.5', capabilities: new Set(['chat', 'tools', 'toolsStrict']) };
121
+ const executor = new OpenRouterProvider({ apiKey: 'test-key' }).createExecutor();
122
+ const tool = (strict) => ({
123
+ messages: [{ role: 'user', content: 'Call it' }],
124
+ tools: [{ name: 'record', parameters: z.object({ query: z.string() }), strict }],
125
+ });
126
+ await executor(tool(true), { ...ctxDefault, metadata: { model: haiku } }, { model: haiku.id });
127
+ await executor(tool(false), { ...ctxDefault, metadata: { model: haiku } }, { model: haiku.id });
128
+ const [[strictBody, strictOptions], [, looseOptions]] = mockOpenAI.chat.completions.create.mock.calls;
129
+ expect(strictBody.tools[0].function.strict).toBe(true);
130
+ expect(strictOptions.headers).toEqual({ 'x-anthropic-beta': 'structured-outputs-2025-11-13' });
131
+ expect(looseOptions.headers).toBeUndefined();
132
+ });
112
133
  it('leaves require_parameters undefined for a non-strict request with unrelated provider config', async () => {
113
134
  const config = {
114
135
  apiKey: 'test-key',
@@ -220,7 +241,7 @@ describe('OpenRouterProvider tool schema dialects', () => {
220
241
  // observable proof of which dialect was chosen.
221
242
  expect(request.tools[0].descriptor).toBe('google-strict');
222
243
  });
223
- it('REGRESSION: the emitted google tool schema carries no anyOf / oneOf / allOf / $defs / $ref', async () => {
244
+ it('REGRESSION: an any-typed google tool argument is an empty schema, not a recursive $defs/Any', async () => {
224
245
  const request = {
225
246
  messages: [{ role: 'user', content: 'Declare it' }],
226
247
  tools: [{ ...signatureTool }],
@@ -239,6 +260,22 @@ describe('OpenRouterProvider tool schema dialects', () => {
239
260
  expect(parameters.properties.signature.additionalProperties).toEqual({});
240
261
  expect(parameters.properties.signature.properties.name.type).toBe('string');
241
262
  });
263
+ it('REGRESSION: a bare google/* model id still gets the google dialect', async () => {
264
+ // Without a full ModelInfo there is no strict capability to go on, but the
265
+ // dialect still applies: LENIENT's recursive $defs/Any is a ref loop
266
+ // through required values, which Gemini rejects with a 400.
267
+ const request = {
268
+ messages: [{ role: 'user', content: 'Declare it' }],
269
+ tools: [{ ...signatureTool }],
270
+ toolChoice: 'required',
271
+ };
272
+ const provider = new OpenRouterProvider({ apiKey: 'test-key' });
273
+ await provider.createExecutor()(request, { ai: AI.with().providers({}).create({}), metadata: {} }, { model: gemini3.id });
274
+ const calls = mockOpenAI.chat.completions.create.mock.calls;
275
+ const parameters = calls[calls.length - 1][0].tools[0].function.parameters;
276
+ expect(request.tools[0].descriptor).toBe('google-non-strict');
277
+ expect(keywordsIn(parameters).has('$defs')).toBe(false);
278
+ });
242
279
  it('still resolves the OpenAI dialect for an openai/* model', async () => {
243
280
  const request = {
244
281
  messages: [{ role: 'user', content: 'Declare it' }],
@@ -1 +1 @@
1
- {"version":3,"file":"openrouter.test.js","sourceRoot":"","sources":["../../src/__tests__/openrouter.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"openrouter.test.js","sourceRoot":"","sources":["../../src/__tests__/openrouter.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * OpenRouter rerank and System One decisions.
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=rerank-decide.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rerank-decide.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/rerank-decide.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * OpenRouter rerank and System One decisions.
3
+ */
4
+ import { AI } from '@aeye/ai';
5
+ import { OpenRouterProvider } from '../openrouter';
6
+ const mockPost = jest.fn();
7
+ jest.mock('openai', () => jest.fn().mockImplementation(() => ({ post: mockPost, baseURL: 'https://openrouter.ai/api/v1' })));
8
+ const ctx = { ai: AI.with().providers({}).create({}), metadata: {} };
9
+ const provider = new OpenRouterProvider({ apiKey: 'k' });
10
+ beforeEach(() => jest.clearAllMocks());
11
+ describe('rerank', () => {
12
+ it('orders documents by relevance score', async () => {
13
+ mockPost.mockResolvedValue({ model: 'rerank-v3.5', results: [{ index: 1, relevance_score: 0.9 }, { index: 0, relevance_score: 0.1 }], usage: { search_units: 1, cost: 0.001 } });
14
+ const response = await provider.rerank({ query: 'capital', documents: ['Berlin', 'Paris'], topN: 2 }, ctx);
15
+ expect(mockPost).toHaveBeenCalledWith('/rerank', expect.objectContaining({ body: { model: 'cohere/rerank-v3.5', query: 'capital', documents: ['Berlin', 'Paris'], top_n: 2 } }));
16
+ expect(response.results).toEqual([{ index: 1, score: 0.9 }, { index: 0, score: 0.1 }]);
17
+ expect(response.usage).toEqual({ cost: 0.001 });
18
+ });
19
+ });
20
+ describe('decide', () => {
21
+ it('asks System One questions at the alpha endpoint', async () => {
22
+ mockPost.mockResolvedValue({
23
+ model: 'typesafe/jev-1.14-20261014',
24
+ answers: {
25
+ billing: { type: 'noul', noul: 0.95 },
26
+ team: { type: 'choice', choice: 'payments', probabilities: { payments: 0.9, web: 0.1 }, confidence: 0.85 },
27
+ urgency: { type: 'score', score: 1.9, legend: { 0: 'Later', 1: 'Soon', 2: 'Now' }, probabilities: { 2: 0.9, 0: 0, 1: 0.1 }, confidence: 0.8 },
28
+ },
29
+ usage: { input_tokens: 421, output_tokens: 70, cost: 0.00002 },
30
+ });
31
+ const response = await provider.decide({
32
+ input: 'Charged twice.',
33
+ questions: {
34
+ billing: { type: 'predicate', instructions: 'Billing problem?' },
35
+ team: { type: 'choice', instructions: 'Which team?', choices: { payments: 'Charges', web: 'Bugs' } },
36
+ urgency: { type: 'score', instructions: 'How urgent?', levels: ['Later', 'Soon', 'Now'] },
37
+ },
38
+ }, ctx);
39
+ const [url, { body }] = mockPost.mock.calls[0];
40
+ expect(url).toBe('https://openrouter.ai/api/alpha/decisions');
41
+ expect(body).toEqual({
42
+ model: 'typesafe/jev-1.14',
43
+ state: 'Charged twice.',
44
+ questions: {
45
+ billing: { type: 'noul', instructions: 'Billing problem?' },
46
+ team: { type: 'choice', instructions: 'Which team?', criteria: { payments: 'Charges', web: 'Bugs' } },
47
+ urgency: { type: 'score', instructions: 'How urgent?', criteria: ['Later', 'Soon', 'Now'] },
48
+ },
49
+ });
50
+ expect(response.answers).toEqual({
51
+ billing: { type: 'predicate', probability: 0.95 },
52
+ team: { type: 'choice', choice: 'payments', probabilities: { payments: 0.9, web: 0.1 }, confidence: 0.85 },
53
+ urgency: { type: 'score', score: 1.9, probabilities: [0, 0.1, 0.9], confidence: 0.8 },
54
+ });
55
+ expect(response.usage).toEqual({ text: { input: 421, output: 70 }, cost: 0.00002 });
56
+ });
57
+ });
58
+ describe('hooks', () => {
59
+ it('runs the rerank and decide hooks around the calls', async () => {
60
+ const calls = [];
61
+ const hooked = new OpenRouterProvider({
62
+ apiKey: 'k',
63
+ hooks: {
64
+ rerank: { beforeRequest: (request, params) => { calls.push(`rerank ${params.model}`); }, afterRequest: (request, params, response) => { calls.push(`reranked ${response.results.length}`); } },
65
+ decide: { beforeRequest: (request, params) => { calls.push(`decide ${'state' in params ? 'system-one' : 'openai'}`); } },
66
+ },
67
+ });
68
+ mockPost.mockResolvedValueOnce({ model: 'rerank-v3.5', results: [{ index: 0, relevance_score: 0.5 }] });
69
+ mockPost.mockResolvedValueOnce({ model: 'jev', answers: {}, usage: { input_tokens: 1, output_tokens: 0 } });
70
+ await hooked.rerank({ query: 'q', documents: ['d'] }, ctx);
71
+ await hooked.decide({ input: 'x', questions: {} }, ctx);
72
+ expect(calls).toEqual(['rerank cohere/rerank-v3.5', 'reranked 1', 'decide system-one']);
73
+ });
74
+ });
75
+ //# sourceMappingURL=rerank-decide.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rerank-decide.test.js","sourceRoot":"","sources":["../../src/__tests__/rerank-decide.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * OpenRouter reports an upstream schema rejection as "Provider returned
3
+ * error", with the upstream's message in `metadata.raw`.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=schema-rejection.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-rejection.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/schema-rejection.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * OpenRouter reports an upstream schema rejection as "Provider returned
3
+ * error", with the upstream's message in `metadata.raw`.
4
+ */
5
+ import { z } from 'zod';
6
+ import { AI } from '@aeye/ai';
7
+ import { SchemaRejectedError } from '@aeye/core';
8
+ import { OpenRouterProvider } from '../openrouter';
9
+ const mockCreate = jest.fn();
10
+ jest.mock('openai', () => jest.fn().mockImplementation(() => ({ chat: { completions: { create: mockCreate } } })));
11
+ const ctx = { ai: AI.with().providers({}).create({}), metadata: {} };
12
+ /** An error shaped like the SDK's APIError for an upstream failure. */
13
+ function upstreamError(raw) {
14
+ return Object.assign(new Error('400 Provider returned error'), {
15
+ status: 400,
16
+ error: { message: 'Provider returned error', code: 400, metadata: { raw, provider_name: 'Google' } },
17
+ });
18
+ }
19
+ async function rejection(error) {
20
+ mockCreate.mockRejectedValue(error);
21
+ const request = {
22
+ messages: [{ role: 'user', content: 'Answer' }],
23
+ responseFormat: { type: z.object({ value: z.number() }), strict: 1 },
24
+ };
25
+ return new OpenRouterProvider({ apiKey: 'test' }).createExecutor()(request, ctx, { model: 'google/gemini-2.5-flash' })
26
+ .then(() => undefined, (e) => e);
27
+ }
28
+ describe('OpenRouter schema rejections', () => {
29
+ it('reads the upstream message', async () => {
30
+ const error = await rejection(upstreamError('{"error":{"message":"Invalid JSON payload received. Unknown name \\"additionalProperties\\" at \'generation_config.response_schema\'"}}'));
31
+ expect(error).toBeInstanceOf(SchemaRejectedError);
32
+ expect(error).toMatchObject({ target: { kind: 'output' } });
33
+ });
34
+ it('leaves other upstream errors alone', async () => {
35
+ const original = upstreamError('{"error":{"message":"Model is overloaded"}}');
36
+ expect(await rejection(original)).toBe(original);
37
+ });
38
+ });
39
+ //# sourceMappingURL=schema-rejection.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-rejection.test.js","sourceRoot":"","sources":["../../src/__tests__/schema-rejection.test.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,EAAE,EAAqB,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAgB,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,MAAM,UAAU,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;AAC7B,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;AAEnH,MAAM,GAAG,GAAiB,EAAE,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;AAEnF,uEAAuE;AACvE,SAAS,aAAa,CAAC,GAAW;IAChC,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,CAAC,EAAE;QAC7D,MAAM,EAAE,GAAG;QACX,KAAK,EAAE,EAAE,OAAO,EAAE,yBAAyB,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,EAAE;KACrG,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,KAAY;IACnC,UAAU,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,OAAO,GAAY;QACvB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;QAC/C,cAAc,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;KACrE,CAAC;IACF,OAAO,IAAI,kBAAkB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,cAAc,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC;SACnH,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC5C,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,aAAa,CAAC,yIAAyI,CAAC,CAAC,CAAC;QACxL,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC;QAClD,MAAM,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,QAAQ,GAAG,aAAa,CAAC,6CAA6C,CAAC,CAAC;QAC9E,MAAM,CAAC,MAAM,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}