Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .changeset/chatty-cobras-rhyme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
"@inkeep/create-agents": patch
"@inkeep/agents-core": patch
"@inkeep/agents-sdk": patch
"@inkeep/agents-manage-ui": patch
"@inkeep/agents-api": patch
"@inkeep/agents-cli": patch
---

Remove structuredOutput model configuration option

**Breaking Change**: The `structuredOutput` model configuration has been removed from the `Models` type. All code generation now uses the `base` model configuration.

**Migration**: Remove any `structuredOutput` configurations from your projects, agents, and sub-agents. The framework will automatically use the `base` model for all operations, including data components.

Before:
```typescript
models: {
base: { model: "anthropic/claude-sonnet-4-5" },
structuredOutput: { model: "openai/gpt-4.1-mini" },
summarizer: { model: "anthropic/claude-haiku-4-5" }
}
```

After:
```typescript
models: {
base: { model: "anthropic/claude-sonnet-4-5" },
summarizer: { model: "anthropic/claude-haiku-4-5" }
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ describe('Project Full CRUD Routes - Integration Tests', () => {
base: {
model: 'gpt-4o-mini',
},
structuredOutput: {
summarizer: {
model: 'gpt-4o',
},
},
Expand Down Expand Up @@ -519,7 +519,6 @@ describe('Project Full CRUD Routes - Integration Tests', () => {
description: 'Project with multiple interconnected agents',
models: {
base: { model: 'gpt-4o-mini' },
structuredOutput: { model: 'gpt-4o' },
},
stopWhen: {
transferCountIs: 15,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ describe('Project CRUD Routes - Integration Tests', () => {
name: 'Test name',
description: 'Test description',
models: {
structuredOutput: {
base: {
model: 'claude-sonnet-4',
providerOptions: {},
},
Expand Down
9 changes: 2 additions & 7 deletions agents-api/src/__tests__/run/agents/Agent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -507,11 +507,8 @@
base: {
model: 'anthropic/claude-sonnet-4-5',
},
structuredOutput: {
model: 'openai/gpt-4.1-mini',
},
summarizer: {
model: 'openai/gpt-4.1-nano',
model: 'openai/gpt-4.1-mini',
},
},
};
Expand Down Expand Up @@ -1512,7 +1509,7 @@
},
},
},
structuredOutput: {
summarizer: {
model: 'openai/gpt-4.1-mini',
},
},
Expand All @@ -1530,9 +1527,8 @@
await agent.generate('Test prompt');

const { ModelFactory } = await import('@inkeep/agents-core');
// Single-phase generation: uses structuredOutput model when data components are present
expect(ModelFactory.prepareGenerationConfig).toHaveBeenCalledTimes(1);
expect(ModelFactory.prepareGenerationConfig).toHaveBeenCalledWith({

Check failure on line 1531 in agents-api/src/__tests__/run/agents/Agent.test.ts

View workflow job for this annotation

GitHub Actions / ci

src/__tests__/run/agents/Agent.test.ts > Agent Model Settings > should use custom model for data component structured output when configured

AssertionError: expected "spy" to be called with arguments: [ { model: 'openai/gpt-4.1-mini' } ] Received: 1st spy call: [ { - "model": "openai/gpt-4.1-mini", + "model": "anthropic/claude-3-5-haiku-latest", + "providerOptions": { + "anthropic": { + "temperature": 0.5, + }, + }, }, ] Number of calls: 1 ❯ src/__tests__/run/agents/Agent.test.ts:1531:50
model: 'openai/gpt-4.1-mini',
});
});
Expand All @@ -1554,7 +1550,6 @@
await agent.generate('Test prompt');

const { ModelFactory } = await import('@inkeep/agents-core');
// Single-phase generation: falls back to base model when no structuredOutput model configured
expect(ModelFactory.prepareGenerationConfig).toHaveBeenCalledTimes(1);
expect(ModelFactory.prepareGenerationConfig).toHaveBeenCalledWith({
model: 'anthropic/claude-sonnet-4-5',
Expand Down
13 changes: 0 additions & 13 deletions agents-api/src/__tests__/run/agents/generateTaskHandler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,6 @@ function createMockExecutionContext(
overrides.agentModels ??
({
base: { model: 'openai/gpt-4' },
structuredOutput: { model: 'openai/gpt-4' },
summarizer: { model: 'openai/gpt-3.5-turbo' },
} as any);

Expand Down Expand Up @@ -861,7 +860,6 @@ describe('generateTaskHandler', () => {
expect(config.agentSchema.id).toBe('test-agent');
expect(config.agentSchema.models).toEqual({
base: { model: 'openai/gpt-4' },
structuredOutput: { model: 'openai/gpt-4' },
summarizer: { model: 'openai/gpt-3.5-turbo' },
});
});
Expand Down Expand Up @@ -897,10 +895,6 @@ describe('generateTaskHandler', () => {
model: 'anthropic/claude-sonnet-4-20250514',
providerOptions: { anthropic: { temperature: 0.8, maxTokens: 2048 } },
},
structuredOutput: {
model: 'anthropic/claude-sonnet-4-20250514',
providerOptions: { anthropic: { temperature: 0.8, maxTokens: 2048 } },
},
summarizer: {
model: 'anthropic/claude-sonnet-4-20250514',
providerOptions: { anthropic: { temperature: 0.8, maxTokens: 2048 } },
Expand All @@ -918,7 +912,6 @@ describe('generateTaskHandler', () => {

expect(config.agentSchema.models).toEqual({
base: { model: 'openai/gpt-4' },
structuredOutput: { model: 'openai/gpt-4' },
summarizer: { model: 'openai/gpt-3.5-turbo' },
});
});
Expand Down Expand Up @@ -947,12 +940,6 @@ describe('generateTaskHandler', () => {
openai: { temperature: 0.3, frequencyPenalty: 0.1, presencePenalty: 0.2 },
},
},
structuredOutput: {
model: 'openai/gpt-4o',
providerOptions: {
openai: { temperature: 0.3, frequencyPenalty: 0.1, presencePenalty: 0.2 },
},
},
summarizer: {
model: 'openai/gpt-4o',
providerOptions: {
Expand Down
24 changes: 0 additions & 24 deletions agents-api/src/__tests__/run/utils/model-resolver.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ describe('resolveModelConfig', () => {

expect(result).toEqual({
base: { model: 'gpt-4' },
structuredOutput: { model: 'gpt-4' },
summarizer: { model: 'gpt-4' },
});
});
Expand All @@ -105,7 +104,6 @@ describe('resolveModelConfig', () => {
...baseAgent,
models: {
base: { model: 'gpt-4' },
structuredOutput: { model: 'gpt-4-turbo' },
summarizer: undefined,
},
} as any;
Expand All @@ -117,7 +115,6 @@ describe('resolveModelConfig', () => {

expect(result).toEqual({
base: { model: 'gpt-4' },
structuredOutput: { model: 'gpt-4-turbo' },
summarizer: { model: 'gpt-4' },
});
});
Expand All @@ -127,7 +124,6 @@ describe('resolveModelConfig', () => {
...baseAgent,
models: {
base: { model: 'gpt-4' },
structuredOutput: { model: 'gpt-4-turbo' },
summarizer: { model: 'claude-3.5-haiku' },
},
} as any;
Expand All @@ -139,7 +135,6 @@ describe('resolveModelConfig', () => {

expect(result).toEqual({
base: { model: 'gpt-4' },
structuredOutput: { model: 'gpt-4-turbo' },
summarizer: { model: 'claude-3.5-haiku' },
});
});
Expand All @@ -157,7 +152,6 @@ describe('resolveModelConfig', () => {
agentId: mockAgentId,
agentModels: {
base: { model: 'claude-3-sonnet' },
structuredOutput: { model: 'claude-3.5-haiku' },
summarizer: undefined,
},
}),
Expand All @@ -166,7 +160,6 @@ describe('resolveModelConfig', () => {

expect(result).toEqual({
base: { model: 'claude-3-sonnet' },
structuredOutput: { model: 'claude-3.5-haiku' },
summarizer: { model: 'claude-3-sonnet' },
});
});
Expand All @@ -176,7 +169,6 @@ describe('resolveModelConfig', () => {
...baseAgent,
models: {
base: undefined,
structuredOutput: { model: 'gpt-4-turbo' },
summarizer: undefined,
},
} as any;
Expand All @@ -186,7 +178,6 @@ describe('resolveModelConfig', () => {
agentId: mockAgentId,
agentModels: {
base: { model: 'claude-3-sonnet' },
structuredOutput: { model: 'claude-3.5-haiku' },
summarizer: { model: 'claude-3-opus' },
},
}),
Expand All @@ -195,7 +186,6 @@ describe('resolveModelConfig', () => {

expect(result).toEqual({
base: { model: 'claude-3-sonnet' },
structuredOutput: { model: 'gpt-4-turbo' }, // Agent-specific takes precedence
summarizer: { model: 'claude-3-opus' }, // Falls back to agent
});
});
Expand All @@ -212,7 +202,6 @@ describe('resolveModelConfig', () => {
agentModels: null,
projectModels: {
base: { model: 'gpt-3.5-turbo' },
structuredOutput: undefined,
summarizer: { model: 'gpt-4' },
},
}),
Expand All @@ -221,7 +210,6 @@ describe('resolveModelConfig', () => {

expect(result).toEqual({
base: { model: 'gpt-3.5-turbo' },
structuredOutput: { model: 'gpt-3.5-turbo' }, // Falls back to base
summarizer: { model: 'gpt-4' },
});
});
Expand All @@ -231,7 +219,6 @@ describe('resolveModelConfig', () => {
...baseAgent,
models: {
base: undefined,
structuredOutput: undefined,
summarizer: { model: 'claude-3.5-haiku' },
},
} as any;
Expand All @@ -242,7 +229,6 @@ describe('resolveModelConfig', () => {
agentModels: null,
projectModels: {
base: { model: 'gpt-4' },
structuredOutput: { model: 'gpt-4-turbo' },
summarizer: { model: 'gpt-3.5-turbo' },
},
}),
Expand All @@ -251,7 +237,6 @@ describe('resolveModelConfig', () => {

expect(result).toEqual({
base: { model: 'gpt-4' },
structuredOutput: { model: 'gpt-4-turbo' }, // Falls back to project
summarizer: { model: 'claude-3.5-haiku' }, // Agent-specific takes precedence
});
});
Expand Down Expand Up @@ -291,7 +276,6 @@ describe('resolveModelConfig', () => {
agentModels: null,
projectModels: {
base: undefined,
structuredOutput: { model: 'gpt-4' },
summarizer: { model: 'claude-3.5-haiku' },
} as any,
}),
Expand All @@ -313,7 +297,6 @@ describe('resolveModelConfig', () => {
agentModels: null,
projectModels: {
base: { model: 'gpt-4' },
structuredOutput: undefined,
summarizer: undefined,
},
});
Expand All @@ -323,7 +306,6 @@ describe('resolveModelConfig', () => {

expect(result).toEqual({
base: { model: 'gpt-4' },
structuredOutput: { model: 'gpt-4' },
summarizer: { model: 'gpt-4' },
});
});
Expand Down Expand Up @@ -353,7 +335,6 @@ describe('resolveModelConfig', () => {
...baseAgent,
models: {
base: null as any,
structuredOutput: { model: 'gpt-4-turbo' },
summarizer: undefined,
},
} as any;
Expand All @@ -363,7 +344,6 @@ describe('resolveModelConfig', () => {
agentId: mockAgentId,
agentModels: {
base: { model: 'claude-3-sonnet' },
structuredOutput: undefined,
summarizer: { model: 'claude-3.5-haiku' },
} as any,
}),
Expand All @@ -372,7 +352,6 @@ describe('resolveModelConfig', () => {

expect(result).toEqual({
base: { model: 'claude-3-sonnet' },
structuredOutput: { model: 'gpt-4-turbo' }, // Agent-specific takes precedence
summarizer: { model: 'claude-3.5-haiku' }, // Falls back to agent
});
});
Expand All @@ -382,7 +361,6 @@ describe('resolveModelConfig', () => {
...baseAgent,
models: {
base: undefined,
structuredOutput: null as any,
summarizer: { model: 'custom-summarizer' },
},
} as any;
Expand All @@ -392,7 +370,6 @@ describe('resolveModelConfig', () => {
agentModels: null,
projectModels: {
base: { model: 'base-model' },
structuredOutput: { model: 'structured-model' },
summarizer: null as any,
} as any,
});
Expand All @@ -402,7 +379,6 @@ describe('resolveModelConfig', () => {

expect(result).toEqual({
base: { model: 'base-model' },
structuredOutput: { model: 'structured-model' }, // Falls back to project
summarizer: { model: 'custom-summarizer' }, // Agent-specific takes precedence
});
});
Expand Down
Loading
Loading