Skip to content

Commit 6f4a28b

Browse files
authored
Prd-5653 (#1388)
1 parent c9a64e2 commit 6f4a28b

File tree

17 files changed

+3065
-1648
lines changed

17 files changed

+3065
-1648
lines changed

agents-cli/package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@
3535
"author": "Inkeep <[email protected]>",
3636
"license": "SEE LICENSE IN LICENSE.md",
3737
"dependencies": {
38-
"@ai-sdk/anthropic": "3.0.0-beta.66",
39-
"@ai-sdk/google": "3.0.0-beta.62",
40-
"@ai-sdk/openai": "3.0.0-beta.74",
38+
"@ai-sdk/anthropic": "3.0.7",
39+
"@ai-sdk/google": "3.0.4",
40+
"@ai-sdk/openai": "3.0.7",
4141
"@clack/prompts": "^0.11.0",
4242
"@inkeep/agents-core": "workspace:^",
4343
"@inkeep/agents-sdk": "workspace:^",
4444
"@vercel/otel": "^2.0.1",
45-
"ai": "6.0.0-beta.124",
45+
"ai": "6.0.14",
4646
"chalk": "^5.3.0",
4747
"cli-table3": "^0.6.3",
4848
"commander": "^14.0.0",
@@ -53,9 +53,9 @@
5353
"json-schema-to-zod": "^2.6.1",
5454
"keytar": "^7.9.0",
5555
"langfuse-vercel": "^3.38.6",
56+
"open": "^10.2.0",
5657
"ts-morph": "^26.0.0",
5758
"tsx": "^4.20.5",
58-
"open": "^10.2.0",
5959
"yaml": "^2.7.0"
6060
},
6161
"devDependencies": {

agents-docs/content/typescript-sdk/(observability)/signoz-usage.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ The traces explorer shows:
3030

3131
- **Timestamp**: When each span occurred
3232
- **Service Name**: The service that generated the span (e.g., `inkeep-agents-run-api`)
33-
- **Operation Name**: Specific operations like `ai.generateObject`, `tls.connect`, `ai.toolCall`
33+
- **Operation Name**: Specific operations like `ai.generateText`, `tls.connect`, `ai.toolCall`
3434
- **Duration**: How long each operation took (in milliseconds)
3535
- **HTTP Method**: For HTTP operations, shows the method (POST, GET, etc.)
3636
- **Response Status Code**: HTTP status codes (200, 404, etc.)

agents-manage-ui/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
"@sinclair/typebox": "^0.34.40",
7878
"@tanstack/react-query": "^5.90.12",
7979
"@xyflow/react": "^12.10.0",
80-
"ai": "6.0.0-beta.124",
80+
"ai": "6.0.14",
8181
"axios": "^1.11.0",
8282
"axios-retry": "^4.5.0",
8383
"better-auth": "^1.4.0",
@@ -136,8 +136,8 @@
136136
"vitest-canvas-mock": "^0.3.3"
137137
},
138138
"optionalDependencies": {
139-
"@sentry/nextjs": "^10.32.1",
140139
"@posthog/react": "^1.5.2",
140+
"@sentry/nextjs": "^10.32.1",
141141
"posthog-js": "^1.308.0"
142142
}
143143
}

agents-manage-ui/src/app/api/artifact-components/[artifactComponentId]/generate-render/route.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
* This route:
66
* 1. Fetches the artifact component from manage-api
77
* 2. Fetches the project to get base model configuration
8-
* 3. Uses AI SDK streamObject to generate component code and sample data
8+
* 3. Uses AI SDK structured output streamText to generate component code and sample data
99
* 4. Streams NDJSON response back to client
1010
*/
1111

1212
import { jsonSchemaToZod, ModelFactory } from '@inkeep/agents-core';
13-
import { streamObject } from 'ai';
13+
import { streamText, Output } from 'ai';
1414
import type { NextRequest } from 'next/server';
1515
import { z } from 'zod';
1616
import { fetchArtifactComponent } from '@/lib/api/artifact-components';
@@ -74,11 +74,12 @@ export async function POST(
7474
mockData: mockDataSchema.describe('Sample data matching the props schema'),
7575
});
7676

77-
// Generate using AI SDK streamObject
78-
const result = streamObject({
77+
const result = streamText({
7978
...modelConfig,
8079
prompt,
81-
schema: renderSchema,
80+
output: Output.object({
81+
schema: renderSchema,
82+
}),
8283
temperature: 0.7,
8384
});
8485

@@ -95,7 +96,7 @@ export async function POST(
9596
const stream = new ReadableStream({
9697
async start(controller) {
9798
try {
98-
for await (const partialObject of result.partialObjectStream) {
99+
for await (const partialObject of result.partialOutputStream) {
99100
// If modifying with instructions, preserve existing data
100101
const outputObject =
101102
instructions && existingData

agents-manage-ui/src/app/api/data-components/[dataComponentId]/generate-render/route.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
* This route:
66
* 1. Fetches the data component from manage-api
77
* 2. Fetches the project to get base model configuration
8-
* 3. Uses AI SDK streamObject to generate component code and sample data
8+
* 3. Uses AI SDK structured output streamText to generate component code and sample data
99
* 4. Streams NDJSON response back to client
1010
*/
1111

1212
import { jsonSchemaToZod, ModelFactory } from '@inkeep/agents-core';
13-
import { streamObject } from 'ai';
13+
import { streamText, Output } from 'ai';
1414
import type { NextRequest } from 'next/server';
1515
import { z } from 'zod';
1616
import { fetchDataComponent } from '@/lib/api/data-components';
@@ -72,11 +72,13 @@ export async function POST(
7272
mockData: mockDataSchema.describe('Sample data matching the props schema'),
7373
});
7474

75-
// Generate using AI SDK streamObject
76-
const result = streamObject({
75+
// Generate using AI SDK structured output streamText
76+
const result = streamText({
7777
...modelConfig,
7878
prompt,
79-
schema: renderSchema,
79+
output: Output.object({
80+
schema: renderSchema,
81+
}),
8082
temperature: 0.7,
8183
});
8284

@@ -93,7 +95,7 @@ export async function POST(
9395
const stream = new ReadableStream({
9496
async start(controller) {
9597
try {
96-
for await (const partialObject of result.partialObjectStream) {
98+
for await (const partialObject of result.partialOutputStream) {
9799
// If modifying with instructions, preserve existing data
98100
const outputObject =
99101
instructions && existingData

agents-run-api/package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@
2727
"typecheck:watch": "tsc --noEmit --watch"
2828
},
2929
"dependencies": {
30-
"@electric-sql/pglite": "^0.3.13",
31-
"@ai-sdk/anthropic": "3.0.0-beta.66",
32-
"@ai-sdk/gateway": "2.0.0-beta.68",
33-
"@ai-sdk/google": "3.0.0-beta.62",
34-
"@ai-sdk/openai": "3.0.0-beta.74",
35-
"@ai-sdk/openai-compatible": "2.0.0-beta.41",
30+
"@ai-sdk/anthropic": "3.0.7",
31+
"@ai-sdk/gateway": "3.0.9",
32+
"@ai-sdk/google": "3.0.4",
33+
"@ai-sdk/openai": "3.0.7",
34+
"@ai-sdk/openai-compatible": "2.0.4",
3635
"@alcyone-labs/modelcontextprotocol-sdk": "^1.16.0",
36+
"@electric-sql/pglite": "^0.3.13",
3737
"@hono/otel": "^0.4.0",
3838
"@hono/swagger-ui": "^0.5.1",
3939
"@inkeep/agents-core": "workspace:^",
@@ -49,7 +49,7 @@
4949
"@opentelemetry/sdk-trace-base": "^2.1.0",
5050
"@opentelemetry/semantic-conventions": "^1.37.0",
5151
"@vercel/sandbox": "^0.0.24",
52-
"ai": "6.0.0-beta.124",
52+
"ai": "6.0.14",
5353
"ajv": "^8.17.1",
5454
"drizzle-orm": "^0.44.4",
5555
"fetch-to-node": "^2.1.0",

agents-run-api/src/__tests__/agents/Agent.test.ts

Lines changed: 96 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -11,46 +11,109 @@ import { Phase1Config } from '../../agents/versions/v1/Phase1Config';
1111

1212
// Mock the AI SDK functions
1313
vi.mock('ai', () => ({
14-
generateText: vi.fn().mockResolvedValue({
15-
text: 'Mocked response',
16-
toolCalls: [],
17-
finishReason: 'stop',
18-
steps: [
19-
{
20-
content: [
21-
{
22-
type: 'text',
23-
text: 'Mocked response',
24-
},
25-
],
26-
toolCalls: [
27-
{
28-
toolName: 'thinking_complete',
29-
args: {},
30-
},
31-
],
32-
toolResults: [
14+
generateText: vi.fn().mockImplementation(async (options: any) => {
15+
// When Output.object is present in options, return "output" with the correct shape
16+
if (options?.output && typeof options.output === 'object') {
17+
// Try to determine the expected output structure from the schema
18+
const schema = options.output.schema;
19+
let outputData: any = {};
20+
21+
// Check if schema expects dataComponents
22+
if (schema?._def?.shape?.dataComponents) {
23+
outputData = {
24+
dataComponents: [
25+
{
26+
id: 'test-component',
27+
name: 'TestComponent',
28+
props: { message: 'Hello, World!' },
29+
},
30+
],
31+
};
32+
} else if (schema?._def?.shape?.statusComponents) {
33+
outputData = {
34+
statusComponents: [
35+
{
36+
id: 'status-1',
37+
type: 'text',
38+
props: { text: 'Status update generated' },
39+
},
40+
],
41+
};
42+
}
43+
44+
return {
45+
text: 'Mocked response',
46+
toolCalls: [],
47+
finishReason: 'stop',
48+
output: outputData,
49+
steps: [
3350
{
34-
toolCallId: 'call_1',
35-
result: 'Thinking complete',
51+
content: [
52+
{
53+
type: 'text',
54+
text: 'Mocked response',
55+
},
56+
],
57+
toolCalls: [
58+
{
59+
toolName: 'thinking_complete',
60+
args: {},
61+
},
62+
],
63+
toolResults: [
64+
{
65+
toolCallId: 'call_1',
66+
result: 'Thinking complete',
67+
},
68+
],
3669
},
3770
],
38-
},
39-
],
40-
}),
41-
generateObject: vi.fn().mockResolvedValue({
42-
object: {
43-
dataComponents: [
71+
};
72+
}
73+
// Otherwise, return just text as fallback
74+
return {
75+
text: 'Mocked response',
76+
toolCalls: [],
77+
finishReason: 'stop',
78+
steps: [
4479
{
45-
id: 'test-component-id',
46-
name: 'TestComponent',
47-
description: 'A test component',
48-
props: { message: 'Hello, World!' },
80+
content: [
81+
{
82+
type: 'text',
83+
text: 'Mocked response',
84+
},
85+
],
86+
toolCalls: [
87+
{
88+
toolName: 'thinking_complete',
89+
args: {},
90+
},
91+
],
92+
toolResults: [
93+
{
94+
toolCallId: 'call_1',
95+
result: 'Thinking complete',
96+
},
97+
],
4998
},
5099
],
51-
},
52-
finishReason: 'stop',
100+
};
101+
}),
102+
streamText: vi.fn().mockReturnValue({
103+
textStream: (async function* () {
104+
yield 'Mocked';
105+
yield ' response';
106+
})(),
107+
fullStream: (async function* () {
108+
yield { type: 'text-delta', textDelta: 'Mocked response' };
109+
})(),
53110
}),
111+
Output: {
112+
object: vi.fn().mockImplementation((config: any) => ({
113+
type: 'object',
114+
...config,
115+
})),
116+
},
54117
tool: vi.fn().mockImplementation((config) => config),
55118
}));
56119

@@ -295,8 +358,6 @@ vi.mock('../../data/conversations.js', () => ({
295358
.mockResolvedValue('Mock conversation history as string'),
296359
}));
297360

298-
// Import the mocked functions so we can reference them in tests
299-
import { generateObject, generateText } from 'ai';
300361
// Import the mocked module - these will automatically be mocked
301362
import {
302363
getConversationHistoryWithCompression,
@@ -1216,46 +1277,6 @@ describe('Two-Pass Generation System', () => {
12161277
};
12171278
});
12181279

1219-
test('should only call generateText when no data components configured', async () => {
1220-
const agent = new Agent({ ...mockAgentConfig, dataComponents: [] });
1221-
await agent.generate('Test prompt');
1222-
1223-
expect(vi.mocked(generateText)).toHaveBeenCalledTimes(1);
1224-
expect(vi.mocked(generateObject)).not.toHaveBeenCalled();
1225-
});
1226-
1227-
test('should call both generateText and generateObject when data components configured', async () => {
1228-
const agent = new Agent(mockAgentConfig);
1229-
await agent.generate('Test prompt');
1230-
1231-
expect(vi.mocked(generateText)).toHaveBeenCalledTimes(1);
1232-
expect(vi.mocked(generateObject)).toHaveBeenCalledTimes(1);
1233-
});
1234-
1235-
test('should skip generateObject when transfer detected', async () => {
1236-
vi.mocked(generateText).mockResolvedValueOnce({
1237-
text: 'Transfer needed',
1238-
finishReason: 'stop',
1239-
steps: [
1240-
{
1241-
content: [
1242-
{
1243-
type: 'text',
1244-
text: 'Transfer needed',
1245-
},
1246-
],
1247-
toolCalls: [{ toolName: 'transfer_to_agent', args: {} }],
1248-
},
1249-
],
1250-
} as any);
1251-
1252-
const agent = new Agent(mockAgentConfig);
1253-
await agent.generate('Test prompt');
1254-
1255-
expect(vi.mocked(generateText)).toHaveBeenCalledTimes(1);
1256-
expect(vi.mocked(generateObject)).not.toHaveBeenCalled();
1257-
});
1258-
12591280
test('should return text response when no data components', async () => {
12601281
const agent = new Agent({ ...mockAgentConfig, dataComponents: [] });
12611282
const result = await agent.generate('Test prompt');

0 commit comments

Comments
 (0)