@strands-agents/sdk 0.7.0 → 1.0.0-rc.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.
- package/README.md +7 -7
- package/dist/src/__fixtures__/agent-helpers.d.ts +44 -0
- package/dist/src/__fixtures__/agent-helpers.d.ts.map +1 -1
- package/dist/src/__fixtures__/agent-helpers.js +45 -0
- package/dist/src/__fixtures__/agent-helpers.js.map +1 -1
- package/dist/src/__fixtures__/mock-plugin.d.ts.map +1 -1
- package/dist/src/__fixtures__/mock-plugin.js +3 -1
- package/dist/src/__fixtures__/mock-plugin.js.map +1 -1
- package/dist/src/__fixtures__/tool-helpers.d.ts.map +1 -1
- package/dist/src/__fixtures__/tool-helpers.js +1 -0
- package/dist/src/__fixtures__/tool-helpers.js.map +1 -1
- package/dist/src/a2a/__tests__/events.test.d.ts +2 -0
- package/dist/src/a2a/__tests__/events.test.d.ts.map +1 -0
- package/dist/src/a2a/__tests__/events.test.js +66 -0
- package/dist/src/a2a/__tests__/events.test.js.map +1 -0
- package/dist/src/a2a/a2a-agent.d.ts.map +1 -1
- package/dist/src/a2a/a2a-agent.js +1 -1
- package/dist/src/a2a/a2a-agent.js.map +1 -1
- package/dist/src/a2a/events.d.ts +2 -0
- package/dist/src/a2a/events.d.ts.map +1 -1
- package/dist/src/a2a/events.js +6 -0
- package/dist/src/a2a/events.js.map +1 -1
- package/dist/src/a2a/index.d.ts +0 -1
- package/dist/src/a2a/index.d.ts.map +1 -1
- package/dist/src/a2a/index.js +0 -1
- package/dist/src/a2a/index.js.map +1 -1
- package/dist/src/a2a/server.d.ts +1 -1
- package/dist/src/a2a/server.js +1 -1
- package/dist/src/agent/__tests__/agent.hook.test.js +229 -1
- package/dist/src/agent/__tests__/agent.hook.test.js.map +1 -1
- package/dist/src/agent/__tests__/agent.test.js +215 -42
- package/dist/src/agent/__tests__/agent.test.js.map +1 -1
- package/dist/src/agent/__tests__/agent.tracer.test.node.d.ts +2 -0
- package/dist/src/agent/__tests__/agent.tracer.test.node.d.ts.map +1 -0
- package/dist/src/agent/__tests__/{agent.tracer.test.js → agent.tracer.test.node.js} +52 -40
- package/dist/src/agent/__tests__/agent.tracer.test.node.js.map +1 -0
- package/dist/src/agent/__tests__/printer.test.js +7 -7
- package/dist/src/agent/__tests__/printer.test.js.map +1 -1
- package/dist/src/agent/__tests__/snapshot.test.js +39 -2
- package/dist/src/agent/__tests__/snapshot.test.js.map +1 -1
- package/dist/src/agent/agent.d.ts +16 -1
- package/dist/src/agent/agent.d.ts.map +1 -1
- package/dist/src/agent/agent.js +170 -94
- package/dist/src/agent/agent.js.map +1 -1
- package/dist/src/agent/printer.d.ts.map +1 -1
- package/dist/src/agent/printer.js +3 -0
- package/dist/src/agent/printer.js.map +1 -1
- package/dist/src/agent/snapshot.d.ts +3 -3
- package/dist/src/agent/snapshot.d.ts.map +1 -1
- package/dist/src/agent/snapshot.js +14 -7
- package/dist/src/agent/snapshot.js.map +1 -1
- package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.js +72 -46
- package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.js.map +1 -1
- package/dist/src/conversation-manager/sliding-window-conversation-manager.d.ts.map +1 -1
- package/dist/src/conversation-manager/sliding-window-conversation-manager.js +14 -7
- package/dist/src/conversation-manager/sliding-window-conversation-manager.js.map +1 -1
- package/dist/src/errors.d.ts +8 -0
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/errors.js +11 -0
- package/dist/src/errors.js.map +1 -1
- package/dist/src/hooks/__tests__/events.test.js +387 -0
- package/dist/src/hooks/__tests__/events.test.js.map +1 -1
- package/dist/src/hooks/events.d.ts +104 -0
- package/dist/src/hooks/events.d.ts.map +1 -1
- package/dist/src/hooks/events.js +137 -0
- package/dist/src/hooks/events.js.map +1 -1
- package/dist/src/index.d.ts +3 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +5 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/models/__tests__/anthropic.test.js +1 -2
- package/dist/src/models/__tests__/anthropic.test.js.map +1 -1
- package/dist/src/models/__tests__/bedrock.test.js +18 -18
- package/dist/src/models/__tests__/bedrock.test.js.map +1 -1
- package/dist/src/models/__tests__/google.test.d.ts +2 -0
- package/dist/src/models/__tests__/google.test.d.ts.map +1 -0
- package/dist/src/models/__tests__/{gemini.test.js → google.test.js} +55 -21
- package/dist/src/models/__tests__/google.test.js.map +1 -0
- package/dist/src/models/__tests__/openai.test.js +78 -71
- package/dist/src/models/__tests__/openai.test.js.map +1 -1
- package/dist/src/models/anthropic.d.ts.map +1 -1
- package/dist/src/models/anthropic.js +8 -7
- package/dist/src/models/anthropic.js.map +1 -1
- package/dist/src/models/bedrock.d.ts +3 -3
- package/dist/src/models/bedrock.d.ts.map +1 -1
- package/dist/src/models/bedrock.js +7 -7
- package/dist/src/models/bedrock.js.map +1 -1
- package/dist/src/models/{gemini → google}/adapters.d.ts +3 -3
- package/dist/src/models/{gemini → google}/adapters.d.ts.map +1 -1
- package/dist/src/models/{gemini → google}/adapters.js +1 -1
- package/dist/src/models/{gemini → google}/adapters.js.map +1 -1
- package/dist/src/models/{gemini → google}/errors.d.ts +7 -7
- package/dist/src/models/google/errors.d.ts.map +1 -0
- package/dist/src/models/{gemini → google}/errors.js +11 -5
- package/dist/src/models/google/errors.js.map +1 -0
- package/dist/src/models/google/index.d.ts +15 -0
- package/dist/src/models/google/index.d.ts.map +1 -0
- package/dist/src/models/google/index.js +15 -0
- package/dist/src/models/google/index.js.map +1 -0
- package/dist/src/models/{gemini → google}/model.d.ts +18 -18
- package/dist/src/models/{gemini → google}/model.d.ts.map +1 -1
- package/dist/src/models/{gemini → google}/model.js +22 -19
- package/dist/src/models/google/model.js.map +1 -0
- package/dist/src/models/{gemini → google}/types.d.ts +9 -9
- package/dist/src/models/{gemini → google}/types.d.ts.map +1 -1
- package/dist/src/models/google/types.js +5 -0
- package/dist/src/models/google/types.js.map +1 -0
- package/dist/src/models/model.js +2 -2
- package/dist/src/models/model.js.map +1 -1
- package/dist/src/models/openai.d.ts +29 -11
- package/dist/src/models/openai.d.ts.map +1 -1
- package/dist/src/models/openai.js +25 -15
- package/dist/src/models/openai.js.map +1 -1
- package/dist/src/models/streaming.d.ts +13 -0
- package/dist/src/models/streaming.d.ts.map +1 -1
- package/dist/src/models/streaming.js +29 -0
- package/dist/src/models/streaming.js.map +1 -1
- package/dist/src/multiagent/__tests__/events.test.js +177 -0
- package/dist/src/multiagent/__tests__/events.test.js.map +1 -1
- package/dist/src/multiagent/__tests__/graph.tracer.test.d.ts +2 -0
- package/dist/src/multiagent/__tests__/graph.tracer.test.d.ts.map +1 -0
- package/dist/src/multiagent/__tests__/graph.tracer.test.js +204 -0
- package/dist/src/multiagent/__tests__/graph.tracer.test.js.map +1 -0
- package/dist/src/multiagent/__tests__/nodes.test.js +48 -5
- package/dist/src/multiagent/__tests__/nodes.test.js.map +1 -1
- package/dist/src/multiagent/__tests__/swarm.test.js +34 -6
- package/dist/src/multiagent/__tests__/swarm.test.js.map +1 -1
- package/dist/src/multiagent/__tests__/swarm.tracer.test.d.ts +2 -0
- package/dist/src/multiagent/__tests__/swarm.tracer.test.d.ts.map +1 -0
- package/dist/src/multiagent/__tests__/swarm.tracer.test.js +235 -0
- package/dist/src/multiagent/__tests__/swarm.tracer.test.js.map +1 -0
- package/dist/src/multiagent/events.d.ts +14 -0
- package/dist/src/multiagent/events.d.ts.map +1 -1
- package/dist/src/multiagent/events.js +34 -0
- package/dist/src/multiagent/events.js.map +1 -1
- package/dist/src/multiagent/graph.d.ts +4 -0
- package/dist/src/multiagent/graph.d.ts.map +1 -1
- package/dist/src/multiagent/graph.js +42 -16
- package/dist/src/multiagent/graph.js.map +1 -1
- package/dist/src/multiagent/index.d.ts +1 -1
- package/dist/src/multiagent/index.d.ts.map +1 -1
- package/dist/src/multiagent/index.js.map +1 -1
- package/dist/src/multiagent/nodes.d.ts +23 -9
- package/dist/src/multiagent/nodes.d.ts.map +1 -1
- package/dist/src/multiagent/nodes.js +25 -14
- package/dist/src/multiagent/nodes.js.map +1 -1
- package/dist/src/multiagent/state.d.ts +8 -3
- package/dist/src/multiagent/state.d.ts.map +1 -1
- package/dist/src/multiagent/state.js +18 -4
- package/dist/src/multiagent/state.js.map +1 -1
- package/dist/src/multiagent/swarm.d.ts +15 -1
- package/dist/src/multiagent/swarm.d.ts.map +1 -1
- package/dist/src/multiagent/swarm.js +71 -30
- package/dist/src/multiagent/swarm.js.map +1 -1
- package/dist/src/session/__tests__/session-manager.test.js +36 -0
- package/dist/src/session/__tests__/session-manager.test.js.map +1 -1
- package/dist/src/session/session-manager.d.ts +2 -3
- package/dist/src/session/session-manager.d.ts.map +1 -1
- package/dist/src/session/session-manager.js +11 -9
- package/dist/src/session/session-manager.js.map +1 -1
- package/dist/src/telemetry/__tests__/local-trace.test.d.ts +2 -0
- package/dist/src/telemetry/__tests__/local-trace.test.d.ts.map +1 -0
- package/dist/src/telemetry/__tests__/local-trace.test.js +158 -0
- package/dist/src/telemetry/__tests__/local-trace.test.js.map +1 -0
- package/dist/src/telemetry/__tests__/tracer.test.node.js +28 -0
- package/dist/src/telemetry/__tests__/tracer.test.node.js.map +1 -1
- package/dist/src/telemetry/config.js +1 -1
- package/dist/src/telemetry/config.js.map +1 -1
- package/dist/src/telemetry/meter.d.ts +0 -13
- package/dist/src/telemetry/meter.d.ts.map +1 -1
- package/dist/src/telemetry/meter.js +8 -36
- package/dist/src/telemetry/meter.js.map +1 -1
- package/dist/src/telemetry/tracer.d.ts +107 -18
- package/dist/src/telemetry/tracer.d.ts.map +1 -1
- package/dist/src/telemetry/tracer.js +245 -33
- package/dist/src/telemetry/tracer.js.map +1 -1
- package/dist/src/telemetry/types.d.ts +49 -0
- package/dist/src/telemetry/types.d.ts.map +1 -1
- package/dist/src/tools/__tests__/structured-output-tool.test.d.ts +2 -0
- package/dist/src/tools/__tests__/structured-output-tool.test.d.ts.map +1 -0
- package/dist/src/tools/__tests__/structured-output-tool.test.js +84 -0
- package/dist/src/tools/__tests__/structured-output-tool.test.js.map +1 -0
- package/dist/src/tools/structured-output-tool.d.ts +41 -0
- package/dist/src/tools/structured-output-tool.d.ts.map +1 -0
- package/dist/src/tools/structured-output-tool.js +82 -0
- package/dist/src/tools/structured-output-tool.js.map +1 -0
- package/dist/src/tools/zod-tool.js +1 -1
- package/dist/src/tools/zod-tool.js.map +1 -1
- package/dist/src/{utils/zod.d.ts → tools/zod-utils.d.ts} +1 -1
- package/dist/src/tools/zod-utils.d.ts.map +1 -0
- package/dist/src/{utils/zod.js → tools/zod-utils.js} +1 -1
- package/dist/src/tools/zod-utils.js.map +1 -0
- package/dist/src/tsconfig.tsbuildinfo +1 -1
- package/dist/src/types/__tests__/agent.test.js +127 -0
- package/dist/src/types/__tests__/agent.test.js.map +1 -1
- package/dist/src/types/agent.d.ts +27 -1
- package/dist/src/types/agent.d.ts.map +1 -1
- package/dist/src/types/agent.js +26 -0
- package/dist/src/types/agent.js.map +1 -1
- package/dist/src/vended-tools/bash/__tests__/bash.test.node.js +12 -0
- package/dist/src/vended-tools/bash/__tests__/bash.test.node.js.map +1 -1
- package/dist/src/vended-tools/bash/bash.d.ts.map +1 -1
- package/dist/src/vended-tools/bash/bash.js +16 -14
- package/dist/src/vended-tools/bash/bash.js.map +1 -1
- package/package.json +12 -8
- package/dist/src/agent/__tests__/agent.tracer.test.d.ts +0 -2
- package/dist/src/agent/__tests__/agent.tracer.test.d.ts.map +0 -1
- package/dist/src/agent/__tests__/agent.tracer.test.js.map +0 -1
- package/dist/src/models/__tests__/gemini.test.d.ts +0 -2
- package/dist/src/models/__tests__/gemini.test.d.ts.map +0 -1
- package/dist/src/models/__tests__/gemini.test.js.map +0 -1
- package/dist/src/models/gemini/errors.d.ts.map +0 -1
- package/dist/src/models/gemini/errors.js.map +0 -1
- package/dist/src/models/gemini/model.js.map +0 -1
- package/dist/src/models/gemini/types.js +0 -5
- package/dist/src/models/gemini/types.js.map +0 -1
- package/dist/src/structured-output/__tests__/context.test.d.ts +0 -2
- package/dist/src/structured-output/__tests__/context.test.d.ts.map +0 -1
- package/dist/src/structured-output/__tests__/context.test.js +0 -201
- package/dist/src/structured-output/__tests__/context.test.js.map +0 -1
- package/dist/src/structured-output/__tests__/exceptions.test.d.ts +0 -2
- package/dist/src/structured-output/__tests__/exceptions.test.d.ts.map +0 -1
- package/dist/src/structured-output/__tests__/exceptions.test.js +0 -103
- package/dist/src/structured-output/__tests__/exceptions.test.js.map +0 -1
- package/dist/src/structured-output/__tests__/tool.test.d.ts +0 -2
- package/dist/src/structured-output/__tests__/tool.test.d.ts.map +0 -1
- package/dist/src/structured-output/__tests__/tool.test.js +0 -256
- package/dist/src/structured-output/__tests__/tool.test.js.map +0 -1
- package/dist/src/structured-output/__tests__/utils.test.d.ts +0 -2
- package/dist/src/structured-output/__tests__/utils.test.d.ts.map +0 -1
- package/dist/src/structured-output/__tests__/utils.test.js +0 -183
- package/dist/src/structured-output/__tests__/utils.test.js.map +0 -1
- package/dist/src/structured-output/context.d.ts +0 -91
- package/dist/src/structured-output/context.d.ts.map +0 -1
- package/dist/src/structured-output/context.js +0 -112
- package/dist/src/structured-output/context.js.map +0 -1
- package/dist/src/structured-output/exceptions.d.ts +0 -18
- package/dist/src/structured-output/exceptions.d.ts.map +0 -1
- package/dist/src/structured-output/exceptions.js +0 -28
- package/dist/src/structured-output/exceptions.js.map +0 -1
- package/dist/src/structured-output/tool.d.ts +0 -33
- package/dist/src/structured-output/tool.d.ts.map +0 -1
- package/dist/src/structured-output/tool.js +0 -73
- package/dist/src/structured-output/tool.js.map +0 -1
- package/dist/src/structured-output/utils.d.ts +0 -23
- package/dist/src/structured-output/utils.d.ts.map +0 -1
- package/dist/src/structured-output/utils.js +0 -104
- package/dist/src/structured-output/utils.js.map +0 -1
- package/dist/src/utils/zod.d.ts.map +0 -1
- package/dist/src/utils/zod.js.map +0 -1
|
@@ -61,20 +61,20 @@ describe('OpenAIModel', () => {
|
|
|
61
61
|
};
|
|
62
62
|
describe('constructor', () => {
|
|
63
63
|
it('creates an instance with required modelId', () => {
|
|
64
|
-
const provider = new OpenAIModel({ modelId: 'gpt-
|
|
64
|
+
const provider = new OpenAIModel({ api: 'chat', modelId: 'gpt-5.4', apiKey: 'sk-test' });
|
|
65
65
|
const config = provider.getConfig();
|
|
66
|
-
expect(config.modelId).toBe('gpt-
|
|
66
|
+
expect(config.modelId).toBe('gpt-5.4');
|
|
67
67
|
});
|
|
68
68
|
it('uses custom model ID', () => {
|
|
69
69
|
const customModelId = 'gpt-3.5-turbo';
|
|
70
|
-
const provider = new OpenAIModel({ modelId: customModelId, apiKey: 'sk-test' });
|
|
70
|
+
const provider = new OpenAIModel({ api: 'chat', modelId: customModelId, apiKey: 'sk-test' });
|
|
71
71
|
expect(provider.getConfig()).toStrictEqual({
|
|
72
72
|
modelId: customModelId,
|
|
73
73
|
});
|
|
74
74
|
});
|
|
75
75
|
it('uses API key from constructor parameter', () => {
|
|
76
76
|
const apiKey = 'sk-explicit';
|
|
77
|
-
new OpenAIModel({ modelId: 'gpt-
|
|
77
|
+
new OpenAIModel({ api: 'chat', modelId: 'gpt-5.4', apiKey });
|
|
78
78
|
expect(OpenAI).toHaveBeenCalledWith(expect.objectContaining({
|
|
79
79
|
apiKey: apiKey,
|
|
80
80
|
}));
|
|
@@ -83,7 +83,7 @@ describe('OpenAIModel', () => {
|
|
|
83
83
|
if (isNode) {
|
|
84
84
|
it('uses API key from environment variable', () => {
|
|
85
85
|
vi.stubEnv('OPENAI_API_KEY', 'sk-from-env');
|
|
86
|
-
new OpenAIModel({ modelId: 'gpt-
|
|
86
|
+
new OpenAIModel({ api: 'chat', modelId: 'gpt-5.4' });
|
|
87
87
|
// OpenAI client should be called without explicit apiKey (uses env var internally)
|
|
88
88
|
expect(OpenAI).toHaveBeenCalled();
|
|
89
89
|
});
|
|
@@ -93,7 +93,7 @@ describe('OpenAIModel', () => {
|
|
|
93
93
|
vi.stubEnv('OPENAI_API_KEY', 'sk-from-env');
|
|
94
94
|
}
|
|
95
95
|
const explicitKey = 'sk-explicit';
|
|
96
|
-
new OpenAIModel({ modelId: 'gpt-
|
|
96
|
+
new OpenAIModel({ api: 'chat', modelId: 'gpt-5.4', apiKey: explicitKey });
|
|
97
97
|
expect(OpenAI).toHaveBeenCalledWith(expect.objectContaining({
|
|
98
98
|
apiKey: explicitKey,
|
|
99
99
|
}));
|
|
@@ -102,11 +102,11 @@ describe('OpenAIModel', () => {
|
|
|
102
102
|
if (isNode) {
|
|
103
103
|
vi.stubEnv('OPENAI_API_KEY', '');
|
|
104
104
|
}
|
|
105
|
-
expect(() => new OpenAIModel({ modelId: 'gpt-
|
|
105
|
+
expect(() => new OpenAIModel({ api: 'chat', modelId: 'gpt-5.4' })).toThrow("OpenAI API key is required. Provide it via the 'apiKey' option (string or function) or set the OPENAI_API_KEY environment variable.");
|
|
106
106
|
});
|
|
107
107
|
it('uses custom client configuration', () => {
|
|
108
108
|
const timeout = 30000;
|
|
109
|
-
new OpenAIModel({ modelId: 'gpt-
|
|
109
|
+
new OpenAIModel({ api: 'chat', modelId: 'gpt-5.4', apiKey: 'sk-test', clientConfig: { timeout } });
|
|
110
110
|
expect(OpenAI).toHaveBeenCalledWith(expect.objectContaining({
|
|
111
111
|
timeout: timeout,
|
|
112
112
|
}));
|
|
@@ -114,7 +114,7 @@ describe('OpenAIModel', () => {
|
|
|
114
114
|
it('uses provided client instance', () => {
|
|
115
115
|
vi.clearAllMocks();
|
|
116
116
|
const mockClient = {};
|
|
117
|
-
const provider = new OpenAIModel({
|
|
117
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
118
118
|
// Should not create a new OpenAI client
|
|
119
119
|
expect(OpenAI).not.toHaveBeenCalled();
|
|
120
120
|
expect(provider).toBeDefined();
|
|
@@ -123,7 +123,8 @@ describe('OpenAIModel', () => {
|
|
|
123
123
|
vi.clearAllMocks();
|
|
124
124
|
const mockClient = {};
|
|
125
125
|
new OpenAIModel({
|
|
126
|
-
|
|
126
|
+
api: 'chat',
|
|
127
|
+
modelId: 'gpt-5.4',
|
|
127
128
|
apiKey: 'sk-test',
|
|
128
129
|
client: mockClient,
|
|
129
130
|
clientConfig: { timeout: 30000 },
|
|
@@ -137,12 +138,13 @@ describe('OpenAIModel', () => {
|
|
|
137
138
|
vi.stubEnv('OPENAI_API_KEY', '');
|
|
138
139
|
}
|
|
139
140
|
const mockClient = {};
|
|
140
|
-
expect(() => new OpenAIModel({
|
|
141
|
+
expect(() => new OpenAIModel({ api: 'chat', client: mockClient })).not.toThrow();
|
|
141
142
|
});
|
|
142
143
|
it('accepts function-based API key', () => {
|
|
143
144
|
const apiKeyFn = vi.fn(async () => 'sk-dynamic');
|
|
144
145
|
new OpenAIModel({
|
|
145
|
-
|
|
146
|
+
api: 'chat',
|
|
147
|
+
modelId: 'gpt-5.4',
|
|
146
148
|
apiKey: apiKeyFn,
|
|
147
149
|
});
|
|
148
150
|
expect(OpenAI).toHaveBeenCalledWith(expect.objectContaining({
|
|
@@ -155,7 +157,8 @@ describe('OpenAIModel', () => {
|
|
|
155
157
|
return 'sk-async-key';
|
|
156
158
|
};
|
|
157
159
|
new OpenAIModel({
|
|
158
|
-
|
|
160
|
+
api: 'chat',
|
|
161
|
+
modelId: 'gpt-5.4',
|
|
159
162
|
apiKey: apiKeyFn,
|
|
160
163
|
});
|
|
161
164
|
expect(OpenAI).toHaveBeenCalledWith(expect.objectContaining({
|
|
@@ -165,16 +168,17 @@ describe('OpenAIModel', () => {
|
|
|
165
168
|
});
|
|
166
169
|
describe('updateConfig', () => {
|
|
167
170
|
it('merges new config with existing config', () => {
|
|
168
|
-
const provider = new OpenAIModel({ modelId: 'gpt-
|
|
169
|
-
provider.updateConfig({ modelId: 'gpt-
|
|
171
|
+
const provider = new OpenAIModel({ api: 'chat', modelId: 'gpt-5.4', apiKey: 'sk-test', temperature: 0.5 });
|
|
172
|
+
provider.updateConfig({ modelId: 'gpt-5.4', temperature: 0.8, maxTokens: 2048 });
|
|
170
173
|
expect(provider.getConfig()).toStrictEqual({
|
|
171
|
-
modelId: 'gpt-
|
|
174
|
+
modelId: 'gpt-5.4',
|
|
172
175
|
temperature: 0.8,
|
|
173
176
|
maxTokens: 2048,
|
|
174
177
|
});
|
|
175
178
|
});
|
|
176
179
|
it('preserves fields not included in the update', () => {
|
|
177
180
|
const provider = new OpenAIModel({
|
|
181
|
+
api: 'chat',
|
|
178
182
|
apiKey: 'sk-test',
|
|
179
183
|
modelId: 'gpt-3.5-turbo',
|
|
180
184
|
temperature: 0.5,
|
|
@@ -191,13 +195,14 @@ describe('OpenAIModel', () => {
|
|
|
191
195
|
describe('getConfig', () => {
|
|
192
196
|
it('returns the current configuration', () => {
|
|
193
197
|
const provider = new OpenAIModel({
|
|
194
|
-
|
|
198
|
+
api: 'chat',
|
|
199
|
+
modelId: 'gpt-5.4',
|
|
195
200
|
apiKey: 'sk-test',
|
|
196
201
|
maxTokens: 1024,
|
|
197
202
|
temperature: 0.7,
|
|
198
203
|
});
|
|
199
204
|
expect(provider.getConfig()).toStrictEqual({
|
|
200
|
-
modelId: 'gpt-
|
|
205
|
+
modelId: 'gpt-5.4',
|
|
201
206
|
maxTokens: 1024,
|
|
202
207
|
temperature: 0.7,
|
|
203
208
|
});
|
|
@@ -207,7 +212,7 @@ describe('OpenAIModel', () => {
|
|
|
207
212
|
describe('validation', () => {
|
|
208
213
|
it('throws error when messages array is empty', async () => {
|
|
209
214
|
const mockClient = createMockClient(async function* () { });
|
|
210
|
-
const provider = new OpenAIModel({
|
|
215
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
211
216
|
await expect(async () => {
|
|
212
217
|
await collectIterator(provider.stream([]));
|
|
213
218
|
}).rejects.toThrow('At least one message is required');
|
|
@@ -221,7 +226,7 @@ describe('OpenAIModel', () => {
|
|
|
221
226
|
choices: [{ finish_reason: 'stop', delta: {}, index: 0 }],
|
|
222
227
|
};
|
|
223
228
|
});
|
|
224
|
-
const provider = new OpenAIModel({
|
|
229
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
225
230
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
|
|
226
231
|
// System prompt that's only whitespace should not be sent
|
|
227
232
|
const events = await collectIterator(provider.stream(messages, { systemPrompt: ' ' }));
|
|
@@ -232,7 +237,8 @@ describe('OpenAIModel', () => {
|
|
|
232
237
|
it('throws error for streaming with n > 1', async () => {
|
|
233
238
|
const mockClient = createMockClient(async function* () { });
|
|
234
239
|
const provider = new OpenAIModel({
|
|
235
|
-
|
|
240
|
+
api: 'chat',
|
|
241
|
+
modelId: 'gpt-5.4',
|
|
236
242
|
client: mockClient,
|
|
237
243
|
params: { n: 2 },
|
|
238
244
|
});
|
|
@@ -245,7 +251,7 @@ describe('OpenAIModel', () => {
|
|
|
245
251
|
});
|
|
246
252
|
it('throws error for tool spec without name or description', async () => {
|
|
247
253
|
const mockClient = createMockClient(async function* () { });
|
|
248
|
-
const provider = new OpenAIModel({
|
|
254
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
249
255
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
|
|
250
256
|
await expect(async () => {
|
|
251
257
|
for await (const _ of provider.stream(messages, {
|
|
@@ -257,7 +263,7 @@ describe('OpenAIModel', () => {
|
|
|
257
263
|
});
|
|
258
264
|
it('throws error for empty tool result content', async () => {
|
|
259
265
|
const mockClient = createMockClient(async function* () { });
|
|
260
|
-
const provider = new OpenAIModel({
|
|
266
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
261
267
|
const messages = [
|
|
262
268
|
new Message({
|
|
263
269
|
role: 'user',
|
|
@@ -285,7 +291,7 @@ describe('OpenAIModel', () => {
|
|
|
285
291
|
choices: [{ finish_reason: 'stop', delta: {}, index: 0 }],
|
|
286
292
|
};
|
|
287
293
|
});
|
|
288
|
-
const provider = new OpenAIModel({
|
|
294
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
289
295
|
const messages = [
|
|
290
296
|
new Message({ role: 'user', content: [new TextBlock('Run tool')] }),
|
|
291
297
|
new Message({
|
|
@@ -317,7 +323,7 @@ describe('OpenAIModel', () => {
|
|
|
317
323
|
});
|
|
318
324
|
it('throws error for circular reference in tool input', async () => {
|
|
319
325
|
const mockClient = createMockClient(async function* () { });
|
|
320
|
-
const provider = new OpenAIModel({
|
|
326
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
321
327
|
const circular = { a: 1 };
|
|
322
328
|
circular.self = circular;
|
|
323
329
|
const messages = [
|
|
@@ -356,7 +362,7 @@ describe('OpenAIModel', () => {
|
|
|
356
362
|
choices: [{ finish_reason: 'stop', delta: {}, index: 0 }],
|
|
357
363
|
};
|
|
358
364
|
});
|
|
359
|
-
const provider = new OpenAIModel({
|
|
365
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
360
366
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
|
|
361
367
|
const events = await collectIterator(provider.stream(messages));
|
|
362
368
|
// Now includes complete content block lifecycle: start, deltas, stop
|
|
@@ -392,7 +398,7 @@ describe('OpenAIModel', () => {
|
|
|
392
398
|
usage: { prompt_tokens: 10, completion_tokens: 5, total_tokens: 15 },
|
|
393
399
|
};
|
|
394
400
|
});
|
|
395
|
-
const provider = new OpenAIModel({
|
|
401
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
396
402
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
|
|
397
403
|
const events = await collectIterator(provider.stream(messages));
|
|
398
404
|
const metadataEvent = events.find((e) => e.type === 'modelMetadataEvent');
|
|
@@ -419,7 +425,7 @@ describe('OpenAIModel', () => {
|
|
|
419
425
|
usage: {}, // Empty usage object
|
|
420
426
|
};
|
|
421
427
|
});
|
|
422
|
-
const provider = new OpenAIModel({
|
|
428
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
423
429
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
|
|
424
430
|
const events = await collectIterator(provider.stream(messages));
|
|
425
431
|
const metadataEvent = events.find((e) => e.type === 'modelMetadataEvent');
|
|
@@ -448,7 +454,7 @@ describe('OpenAIModel', () => {
|
|
|
448
454
|
choices: [{ finish_reason: 'stop', delta: {}, index: 0 }],
|
|
449
455
|
};
|
|
450
456
|
});
|
|
451
|
-
const provider = new OpenAIModel({
|
|
457
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
452
458
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
|
|
453
459
|
const events = await collectIterator(provider.stream(messages));
|
|
454
460
|
// Should not emit event for empty content
|
|
@@ -468,7 +474,7 @@ describe('OpenAIModel', () => {
|
|
|
468
474
|
choices: [{ finish_reason: 'stop', delta: {}, index: 0 }],
|
|
469
475
|
};
|
|
470
476
|
});
|
|
471
|
-
const provider = new OpenAIModel({
|
|
477
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
472
478
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
|
|
473
479
|
// Suppress console.warn for this test
|
|
474
480
|
vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
@@ -525,7 +531,7 @@ describe('OpenAIModel', () => {
|
|
|
525
531
|
choices: [{ finish_reason: 'tool_calls', delta: {}, index: 0 }],
|
|
526
532
|
};
|
|
527
533
|
});
|
|
528
|
-
const provider = new OpenAIModel({
|
|
534
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
529
535
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Calculate 2+2')] })];
|
|
530
536
|
const events = await collectIterator(provider.stream(messages));
|
|
531
537
|
// Verify key events in sequence
|
|
@@ -600,7 +606,7 @@ describe('OpenAIModel', () => {
|
|
|
600
606
|
choices: [{ finish_reason: 'tool_calls', delta: {}, index: 0 }],
|
|
601
607
|
};
|
|
602
608
|
});
|
|
603
|
-
const provider = new OpenAIModel({
|
|
609
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
604
610
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
|
|
605
611
|
const events = await collectIterator(provider.stream(messages));
|
|
606
612
|
// Should emit stop events for both tool calls
|
|
@@ -635,7 +641,7 @@ describe('OpenAIModel', () => {
|
|
|
635
641
|
choices: [{ finish_reason: 'stop', delta: {}, index: 0 }],
|
|
636
642
|
};
|
|
637
643
|
});
|
|
638
|
-
const provider = new OpenAIModel({
|
|
644
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
639
645
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
|
|
640
646
|
// Suppress console.warn for this test
|
|
641
647
|
vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
@@ -675,7 +681,7 @@ describe('OpenAIModel', () => {
|
|
|
675
681
|
yield { choices: [{ delta: { tool_calls: [{ index: 0, function: { arguments: '20}' } }] }, index: 0 }] };
|
|
676
682
|
yield { choices: [{ finish_reason: 'tool_calls', delta: {}, index: 0 }] };
|
|
677
683
|
});
|
|
678
|
-
const provider = new OpenAIModel({
|
|
684
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
679
685
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
|
|
680
686
|
const events = await collectIterator(provider.stream(messages));
|
|
681
687
|
// Extract and concatenate all tool input deltas
|
|
@@ -713,7 +719,7 @@ describe('OpenAIModel', () => {
|
|
|
713
719
|
};
|
|
714
720
|
yield { choices: [{ finish_reason: 'tool_calls', delta: {}, index: 0 }] };
|
|
715
721
|
});
|
|
716
|
-
const provider = new OpenAIModel({
|
|
722
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
717
723
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Calculate 2+2')] })];
|
|
718
724
|
const events = await collectIterator(provider.stream(messages));
|
|
719
725
|
// Should have text deltas followed by tool events
|
|
@@ -749,7 +755,7 @@ describe('OpenAIModel', () => {
|
|
|
749
755
|
choices: [{ finish_reason: openai, delta: {}, index: 0 }],
|
|
750
756
|
};
|
|
751
757
|
});
|
|
752
|
-
const provider = new OpenAIModel({
|
|
758
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
753
759
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
|
|
754
760
|
const events = await collectIterator(provider.stream(messages));
|
|
755
761
|
const stopEvent = events.find((e) => e.type === 'modelMessageStopEvent');
|
|
@@ -766,7 +772,7 @@ describe('OpenAIModel', () => {
|
|
|
766
772
|
choices: [{ finish_reason: 'new_unknown_reason', delta: {}, index: 0 }],
|
|
767
773
|
};
|
|
768
774
|
});
|
|
769
|
-
const provider = new OpenAIModel({
|
|
775
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
770
776
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
|
|
771
777
|
const events = await collectIterator(provider.stream(messages));
|
|
772
778
|
// Should convert unknown stop reason to camelCase
|
|
@@ -797,7 +803,8 @@ describe('OpenAIModel', () => {
|
|
|
797
803
|
},
|
|
798
804
|
};
|
|
799
805
|
const provider = new OpenAIModel({
|
|
800
|
-
|
|
806
|
+
api: 'chat',
|
|
807
|
+
modelId: 'gpt-5.4',
|
|
801
808
|
client: mockClient,
|
|
802
809
|
temperature: 0.7,
|
|
803
810
|
maxTokens: 1000,
|
|
@@ -819,7 +826,7 @@ describe('OpenAIModel', () => {
|
|
|
819
826
|
expect(callCount).toBe(1);
|
|
820
827
|
expect(capturedRequest).toBeDefined();
|
|
821
828
|
expect(capturedRequest).toEqual({
|
|
822
|
-
model: 'gpt-
|
|
829
|
+
model: 'gpt-5.4',
|
|
823
830
|
stream: true,
|
|
824
831
|
stream_options: { include_usage: true },
|
|
825
832
|
temperature: 0.7,
|
|
@@ -846,7 +853,7 @@ describe('OpenAIModel', () => {
|
|
|
846
853
|
it('formats array system prompt with text blocks only', async () => {
|
|
847
854
|
const captured = { request: null };
|
|
848
855
|
const mockClient = createMockClientWithCapture(captured);
|
|
849
|
-
const provider = new OpenAIModel({
|
|
856
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
850
857
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hello')] })];
|
|
851
858
|
await collectIterator(provider.stream(messages, {
|
|
852
859
|
systemPrompt: [
|
|
@@ -864,7 +871,7 @@ describe('OpenAIModel', () => {
|
|
|
864
871
|
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
865
872
|
const captured = { request: null };
|
|
866
873
|
const mockClient = createMockClientWithCapture(captured);
|
|
867
|
-
const provider = new OpenAIModel({
|
|
874
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
868
875
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hello')] })];
|
|
869
876
|
collectIterator(provider.stream(messages, {
|
|
870
877
|
systemPrompt: [
|
|
@@ -886,7 +893,7 @@ describe('OpenAIModel', () => {
|
|
|
886
893
|
it('handles empty array system prompt', async () => {
|
|
887
894
|
const captured = { request: null };
|
|
888
895
|
const mockClient = createMockClientWithCapture(captured);
|
|
889
|
-
const provider = new OpenAIModel({
|
|
896
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
890
897
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hello')] })];
|
|
891
898
|
await collectIterator(provider.stream(messages, {
|
|
892
899
|
systemPrompt: [],
|
|
@@ -898,7 +905,7 @@ describe('OpenAIModel', () => {
|
|
|
898
905
|
it('formats array system prompt with single text block', async () => {
|
|
899
906
|
const captured = { request: null };
|
|
900
907
|
const mockClient = createMockClientWithCapture(captured);
|
|
901
|
-
const provider = new OpenAIModel({
|
|
908
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
902
909
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hello')] })];
|
|
903
910
|
await collectIterator(provider.stream(messages, {
|
|
904
911
|
systemPrompt: [{ type: 'textBlock', text: 'You are a helpful assistant' }],
|
|
@@ -913,7 +920,7 @@ describe('OpenAIModel', () => {
|
|
|
913
920
|
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
914
921
|
const captured = { request: null };
|
|
915
922
|
const mockClient = createMockClientWithCapture(captured);
|
|
916
|
-
const provider = new OpenAIModel({
|
|
923
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
917
924
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hello')] })];
|
|
918
925
|
await collectIterator(provider.stream(messages, {
|
|
919
926
|
systemPrompt: [
|
|
@@ -941,7 +948,7 @@ describe('OpenAIModel', () => {
|
|
|
941
948
|
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
942
949
|
const captured = { request: null };
|
|
943
950
|
const mockClient = createMockClientWithCapture(captured);
|
|
944
|
-
const provider = new OpenAIModel({
|
|
951
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
945
952
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hello')] })];
|
|
946
953
|
await collectIterator(provider.stream(messages, {
|
|
947
954
|
systemPrompt: [
|
|
@@ -970,7 +977,7 @@ describe('OpenAIModel', () => {
|
|
|
970
977
|
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
971
978
|
const captured = { request: null };
|
|
972
979
|
const mockClient = createMockClientWithCapture(captured);
|
|
973
|
-
const provider = new OpenAIModel({
|
|
980
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
974
981
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hello')] })];
|
|
975
982
|
await collectIterator(provider.stream(messages, {
|
|
976
983
|
systemPrompt: [
|
|
@@ -996,7 +1003,7 @@ describe('OpenAIModel', () => {
|
|
|
996
1003
|
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
997
1004
|
const captured = { request: null };
|
|
998
1005
|
const mockClient = createMockClientWithCapture(captured);
|
|
999
|
-
const provider = new OpenAIModel({
|
|
1006
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
1000
1007
|
const messages = [
|
|
1001
1008
|
new Message({
|
|
1002
1009
|
role: 'user',
|
|
@@ -1014,7 +1021,7 @@ describe('OpenAIModel', () => {
|
|
|
1014
1021
|
];
|
|
1015
1022
|
await collectIterator(provider.stream(messages));
|
|
1016
1023
|
// Verify warning was logged
|
|
1017
|
-
expect(warnSpy).toHaveBeenCalledWith('
|
|
1024
|
+
expect(warnSpy).toHaveBeenCalledWith('block_type=<guardContentBlock> | unsupported content type in openai user message | skipping');
|
|
1018
1025
|
// Verify guard content filtered out
|
|
1019
1026
|
expect(captured.request).toBeDefined();
|
|
1020
1027
|
expect(captured.request.messages).toEqual([
|
|
@@ -1032,7 +1039,7 @@ describe('OpenAIModel', () => {
|
|
|
1032
1039
|
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
1033
1040
|
const captured = { request: null };
|
|
1034
1041
|
const mockClient = createMockClientWithCapture(captured);
|
|
1035
|
-
const provider = new OpenAIModel({
|
|
1042
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
1036
1043
|
const imageBytes = new Uint8Array([1, 2, 3, 4]);
|
|
1037
1044
|
const messages = [
|
|
1038
1045
|
new Message({
|
|
@@ -1050,7 +1057,7 @@ describe('OpenAIModel', () => {
|
|
|
1050
1057
|
];
|
|
1051
1058
|
await collectIterator(provider.stream(messages));
|
|
1052
1059
|
// Verify warning was logged
|
|
1053
|
-
expect(warnSpy).toHaveBeenCalledWith('
|
|
1060
|
+
expect(warnSpy).toHaveBeenCalledWith('block_type=<guardContentBlock> | unsupported content type in openai user message | skipping');
|
|
1054
1061
|
// Verify guard content filtered out
|
|
1055
1062
|
expect(captured.request).toBeDefined();
|
|
1056
1063
|
expect(captured.request.messages).toEqual([
|
|
@@ -1062,7 +1069,7 @@ describe('OpenAIModel', () => {
|
|
|
1062
1069
|
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
1063
1070
|
const captured = { request: null };
|
|
1064
1071
|
const mockClient = createMockClientWithCapture(captured);
|
|
1065
|
-
const provider = new OpenAIModel({
|
|
1072
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
1066
1073
|
const messages = [
|
|
1067
1074
|
new Message({
|
|
1068
1075
|
role: 'user',
|
|
@@ -1078,7 +1085,7 @@ describe('OpenAIModel', () => {
|
|
|
1078
1085
|
];
|
|
1079
1086
|
await collectIterator(provider.stream(messages));
|
|
1080
1087
|
// Verify warning was logged
|
|
1081
|
-
expect(warnSpy).toHaveBeenCalledWith('
|
|
1088
|
+
expect(warnSpy).toHaveBeenCalledWith('block_type=<guardContentBlock> | unsupported content type in openai user message | skipping');
|
|
1082
1089
|
// Verify no user message added (only guard content)
|
|
1083
1090
|
expect(captured.request).toBeDefined();
|
|
1084
1091
|
expect(captured.request.messages).toEqual([]);
|
|
@@ -1089,7 +1096,7 @@ describe('OpenAIModel', () => {
|
|
|
1089
1096
|
it('formats image block in user message as image_url with base64', async () => {
|
|
1090
1097
|
const captured = { request: null };
|
|
1091
1098
|
const mockClient = createMockClientWithCapture(captured);
|
|
1092
|
-
const provider = new OpenAIModel({
|
|
1099
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
1093
1100
|
const imageBytes = new Uint8Array([72, 101, 108, 108, 111]);
|
|
1094
1101
|
const messages = [
|
|
1095
1102
|
new Message({
|
|
@@ -1113,7 +1120,7 @@ describe('OpenAIModel', () => {
|
|
|
1113
1120
|
it('formats image block in user message with URL source', async () => {
|
|
1114
1121
|
const captured = { request: null };
|
|
1115
1122
|
const mockClient = createMockClientWithCapture(captured);
|
|
1116
|
-
const provider = new OpenAIModel({
|
|
1123
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
1117
1124
|
const messages = [
|
|
1118
1125
|
new Message({
|
|
1119
1126
|
role: 'user',
|
|
@@ -1130,7 +1137,7 @@ describe('OpenAIModel', () => {
|
|
|
1130
1137
|
it('formats document block with bytes source as file in user message', async () => {
|
|
1131
1138
|
const captured = { request: null };
|
|
1132
1139
|
const mockClient = createMockClientWithCapture(captured);
|
|
1133
|
-
const provider = new OpenAIModel({
|
|
1140
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
1134
1141
|
const docBytes = new Uint8Array([1, 2, 3]);
|
|
1135
1142
|
const messages = [
|
|
1136
1143
|
new Message({
|
|
@@ -1148,7 +1155,7 @@ describe('OpenAIModel', () => {
|
|
|
1148
1155
|
it('splits image from tool result into separate user message', async () => {
|
|
1149
1156
|
const captured = { request: null };
|
|
1150
1157
|
const mockClient = createMockClientWithCapture(captured);
|
|
1151
|
-
const provider = new OpenAIModel({
|
|
1158
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
1152
1159
|
const imageBytes = new Uint8Array([72, 101, 108, 108, 111]);
|
|
1153
1160
|
const messages = [
|
|
1154
1161
|
new Message({
|
|
@@ -1182,7 +1189,7 @@ describe('OpenAIModel', () => {
|
|
|
1182
1189
|
it('injects placeholder text when tool result contains only images', async () => {
|
|
1183
1190
|
const captured = { request: null };
|
|
1184
1191
|
const mockClient = createMockClientWithCapture(captured);
|
|
1185
|
-
const provider = new OpenAIModel({
|
|
1192
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
1186
1193
|
const messages = [
|
|
1187
1194
|
new Message({
|
|
1188
1195
|
role: 'user',
|
|
@@ -1203,7 +1210,7 @@ describe('OpenAIModel', () => {
|
|
|
1203
1210
|
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
1204
1211
|
const captured = { request: null };
|
|
1205
1212
|
const mockClient = createMockClientWithCapture(captured);
|
|
1206
|
-
const provider = new OpenAIModel({
|
|
1213
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
1207
1214
|
const messages = [
|
|
1208
1215
|
new Message({
|
|
1209
1216
|
role: 'user',
|
|
@@ -1229,7 +1236,7 @@ describe('OpenAIModel', () => {
|
|
|
1229
1236
|
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
1230
1237
|
const captured = { request: null };
|
|
1231
1238
|
const mockClient = createMockClientWithCapture(captured);
|
|
1232
|
-
const provider = new OpenAIModel({
|
|
1239
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
1233
1240
|
const messages = [
|
|
1234
1241
|
new Message({
|
|
1235
1242
|
role: 'user',
|
|
@@ -1265,7 +1272,7 @@ describe('OpenAIModel', () => {
|
|
|
1265
1272
|
},
|
|
1266
1273
|
},
|
|
1267
1274
|
};
|
|
1268
|
-
const provider = new OpenAIModel({
|
|
1275
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
1269
1276
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
|
|
1270
1277
|
await expect(async () => {
|
|
1271
1278
|
for await (const _ of provider.stream(messages)) {
|
|
@@ -1283,7 +1290,7 @@ describe('OpenAIModel', () => {
|
|
|
1283
1290
|
},
|
|
1284
1291
|
},
|
|
1285
1292
|
};
|
|
1286
|
-
const provider = new OpenAIModel({
|
|
1293
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
1287
1294
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
|
|
1288
1295
|
await expect(async () => {
|
|
1289
1296
|
for await (const _ of provider.stream(messages)) {
|
|
@@ -1308,7 +1315,7 @@ describe('OpenAIModel', () => {
|
|
|
1308
1315
|
},
|
|
1309
1316
|
},
|
|
1310
1317
|
};
|
|
1311
|
-
const provider = new OpenAIModel({
|
|
1318
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
1312
1319
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
|
|
1313
1320
|
await expect(async () => {
|
|
1314
1321
|
for await (const _ of provider.stream(messages)) {
|
|
@@ -1326,7 +1333,7 @@ describe('OpenAIModel', () => {
|
|
|
1326
1333
|
},
|
|
1327
1334
|
},
|
|
1328
1335
|
};
|
|
1329
|
-
const provider = new OpenAIModel({
|
|
1336
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
1330
1337
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
|
|
1331
1338
|
await expect(async () => {
|
|
1332
1339
|
for await (const _ of provider.stream(messages)) {
|
|
@@ -1341,7 +1348,7 @@ describe('OpenAIModel', () => {
|
|
|
1341
1348
|
// Stream interruption
|
|
1342
1349
|
throw new Error('Network connection lost');
|
|
1343
1350
|
});
|
|
1344
|
-
const provider = new OpenAIModel({
|
|
1351
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
1345
1352
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
|
|
1346
1353
|
await expect(async () => {
|
|
1347
1354
|
for await (const _ of provider.stream(messages)) {
|
|
@@ -1361,7 +1368,7 @@ describe('OpenAIModel', () => {
|
|
|
1361
1368
|
},
|
|
1362
1369
|
},
|
|
1363
1370
|
};
|
|
1364
|
-
const provider = new OpenAIModel({
|
|
1371
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
1365
1372
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
|
|
1366
1373
|
await expect(async () => {
|
|
1367
1374
|
for await (const _ of provider.stream(messages)) {
|
|
@@ -1381,7 +1388,7 @@ describe('OpenAIModel', () => {
|
|
|
1381
1388
|
},
|
|
1382
1389
|
},
|
|
1383
1390
|
};
|
|
1384
|
-
const provider = new OpenAIModel({
|
|
1391
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
1385
1392
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
|
|
1386
1393
|
await expect(async () => {
|
|
1387
1394
|
for await (const _ of provider.stream(messages)) {
|
|
@@ -1399,7 +1406,7 @@ describe('OpenAIModel', () => {
|
|
|
1399
1406
|
},
|
|
1400
1407
|
},
|
|
1401
1408
|
};
|
|
1402
|
-
const provider = new OpenAIModel({
|
|
1409
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
1403
1410
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
|
|
1404
1411
|
await expect(async () => {
|
|
1405
1412
|
for await (const _ of provider.stream(messages)) {
|
|
@@ -1417,7 +1424,7 @@ describe('OpenAIModel', () => {
|
|
|
1417
1424
|
},
|
|
1418
1425
|
},
|
|
1419
1426
|
};
|
|
1420
|
-
const provider = new OpenAIModel({
|
|
1427
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
1421
1428
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
|
|
1422
1429
|
await expect(async () => {
|
|
1423
1430
|
for await (const _ of provider.stream(messages)) {
|
|
@@ -1426,7 +1433,7 @@ describe('OpenAIModel', () => {
|
|
|
1426
1433
|
}).rejects.toThrow(ModelThrottledError);
|
|
1427
1434
|
});
|
|
1428
1435
|
it('preserves original error as cause in ModelThrottledError', async () => {
|
|
1429
|
-
const originalError = new Error('Request too large for gpt-
|
|
1436
|
+
const originalError = new Error('Request too large for gpt-5.4 on tokens per min');
|
|
1430
1437
|
originalError.status = 429;
|
|
1431
1438
|
const mockClient = {
|
|
1432
1439
|
chat: {
|
|
@@ -1437,7 +1444,7 @@ describe('OpenAIModel', () => {
|
|
|
1437
1444
|
},
|
|
1438
1445
|
},
|
|
1439
1446
|
};
|
|
1440
|
-
const provider = new OpenAIModel({
|
|
1447
|
+
const provider = new OpenAIModel({ api: 'chat', client: mockClient });
|
|
1441
1448
|
const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
|
|
1442
1449
|
try {
|
|
1443
1450
|
for await (const _ of provider.stream(messages)) {
|
|
@@ -1449,7 +1456,7 @@ describe('OpenAIModel', () => {
|
|
|
1449
1456
|
expect(error).toBeInstanceOf(ModelThrottledError);
|
|
1450
1457
|
const throttleError = error;
|
|
1451
1458
|
expect(throttleError.cause).toBe(originalError);
|
|
1452
|
-
expect(throttleError.message).toBe('Request too large for gpt-
|
|
1459
|
+
expect(throttleError.message).toBe('Request too large for gpt-5.4 on tokens per min');
|
|
1453
1460
|
}
|
|
1454
1461
|
});
|
|
1455
1462
|
});
|