Skip to content
Merged

V6 #33

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
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@requesty/ai-sdk",
"version": "2.1.2",
"version": "3.0.0",
"license": "Apache-2.0",
"sideEffects": false,
"main": "./dist/index.js",
Expand Down Expand Up @@ -41,15 +41,15 @@
}
},
"dependencies": {
"@ai-sdk/provider": "^2.0.0",
"@ai-sdk/provider": "^3.0.0",
"@ai-sdk/provider-utils": "^3.0.9"
},
"devDependencies": {
"@biomejs/biome": "2.2.5",
"@edge-runtime/vm": "5.0.0",
"@types/jest": "29.5.14",
"@types/node": "22.13.5",
"ai": "^5.0.52",
"ai": "^6.0.1",
"dotenv": "^17.2.3",
"msw": "^2.11.3",
"tsdown": "^0.15.7",
Expand Down
291 changes: 130 additions & 161 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions src/e2e/pizza.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Experimental_Agent as Agent, type ToolSet, tool } from 'ai'
import { ToolLoopAgent, type ToolSet, tool } from 'ai'
import { beforeAll, describe, expect, it } from 'vitest'
import { z } from 'zod'
import { createRequesty } from '..'
Expand Down Expand Up @@ -417,7 +417,7 @@ function resetInventoryAndOrders() {
const modelsToTest = getTestModels()

const testGenerateAgent = async <T extends ToolSet>(
agent: Agent<T>,
agent: ToolLoopAgent<T>,
prompt: string,
) => {
const { steps } = await agent.generate({
Expand All @@ -428,10 +428,10 @@ const testGenerateAgent = async <T extends ToolSet>(
}

const testStreamAgent = async <T extends ToolSet>(
agent: Agent<T>,
agent: ToolLoopAgent<T>,
prompt: string,
) => {
const result = agent.stream({
const result = await agent.stream({
prompt,
})

Expand All @@ -448,15 +448,15 @@ describe.concurrent.each(modelsToTest)(
'Pizza Agent Tests - $name',
{ timeout: 90_000 },
({ id }) => {
let pizzaAgent: Agent<typeof tools>
let pizzaAgent: ToolLoopAgent<typeof tools>

beforeAll(() => {
resetInventoryAndOrders()
pizzaAgent = new Agent({
pizzaAgent = new ToolLoopAgent({
model: requesty.chat(id),
system: systemPrompt,
instructions: systemPrompt,
tools,
})
}) as any
})

describe('agent.generate() tests', () => {
Expand Down
5 changes: 0 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ export type {
RequestyChatModelId,
RequestyChatSettings,
} from './requesty-chat-settings'
export type { RequestyCompletionLanguageModel } from './requesty-completion-language-model'
export type {
RequestyCompletionModelId,
RequestyCompletionSettings,
} from './requesty-completion-settings'
export * from './requesty-provider'
export type {
RequestyChatMessage,
Expand Down
16 changes: 6 additions & 10 deletions src/integration/chat.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,9 @@ describe('Requesty Integration - Chat', () => {

expect(result.text).toBe('Hello! How can I help you today?')
expect(result.finishReason).toBe('stop')
expect(result.usage).toEqual({
inputTokens: 10,
outputTokens: 9,
totalTokens: 19,
})
expect(result.usage.inputTokens).toBe(10)
expect(result.usage.outputTokens).toBe(9)
expect(result.usage.totalTokens).toBe(19)
})

it('should handle tool calls', async () => {
Expand Down Expand Up @@ -271,11 +269,9 @@ describe('Requesty Integration - Chat', () => {
const usage = await result.usage

expect(finishReason).toBe('stop')
expect(usage).toEqual({
inputTokens: 10,
outputTokens: 5,
totalTokens: 15,
})
expect(usage.inputTokens).toBe(10)
expect(usage.outputTokens).toBe(5)
expect(usage.totalTokens).toBe(15)
})

it('should handle streaming tool calls', async () => {
Expand Down
2 changes: 0 additions & 2 deletions src/internal/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
export * from '../requesty-chat-language-model'
export * from '../requesty-chat-settings'
export * from '../requesty-completion-language-model'
export * from '../requesty-completion-settings'
export * from '../types'
16 changes: 8 additions & 8 deletions src/map-requesty-finish-reason.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import type { LanguageModelV2FinishReason } from '@ai-sdk/provider'
import type { LanguageModelV3FinishReason } from '@ai-sdk/provider'

export function mapRequestyFinishReason(
finishReason: string | null | undefined,
): LanguageModelV2FinishReason {
finishReason: string | undefined,
): LanguageModelV3FinishReason {
switch (finishReason) {
case 'stop':
return 'stop'
return { unified: 'stop', raw: finishReason }
case 'length':
case 'max_tokens':
return 'length'
return { unified: 'length', raw: finishReason }
case 'tool_calls':
case 'function_call':
return 'tool-calls'
return { unified: 'tool-calls', raw: finishReason }
case 'content_filter':
return 'content-filter'
return { unified: 'content-filter', raw: finishReason }
default:
return 'unknown'
return { unified: 'other', raw: finishReason }
}
}
4 changes: 2 additions & 2 deletions src/messages/handle-assistant-message.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { LanguageModelV2Message } from '@ai-sdk/provider'
import type { LanguageModelV3Message } from '@ai-sdk/provider'
import { describe, expect, it } from 'vitest'
import type { RequestyChatMessage } from '../types'
import { handleAssistantMessage } from './handle-assistant-message'
Expand All @@ -7,7 +7,7 @@ describe('assistant messages', () => {
it.for<
[
string,
Extract<LanguageModelV2Message, { role: 'assistant' }>,
Extract<LanguageModelV3Message, { role: 'assistant' }>,
RequestyChatMessage,
]
>([
Expand Down
4 changes: 2 additions & 2 deletions src/messages/handle-assistant-message.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { LanguageModelV2Message } from '@ai-sdk/provider'
import type { LanguageModelV3Message } from '@ai-sdk/provider'
import type { RequestyChatMessage, RequestyToolCall } from '../types'
import { maybeGetReasoningContent } from '../util'

export function handleAssistantMessage(
message: Extract<LanguageModelV2Message, { role: 'assistant' }>,
message: Extract<LanguageModelV3Message, { role: 'assistant' }>,
): RequestyChatMessage {
const assistantMessage: RequestyChatMessage = {
role: 'assistant',
Expand Down
4 changes: 2 additions & 2 deletions src/messages/handle-system-message.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { LanguageModelV2Message } from '@ai-sdk/provider'
import type { LanguageModelV3Message } from '@ai-sdk/provider'
import type { RequestyChatMessage } from '../types'

export function handleSystemMessage(
message: Extract<LanguageModelV2Message, { role: 'system' }>,
message: Extract<LanguageModelV3Message, { role: 'system' }>,
): RequestyChatMessage {
return {
role: 'system',
Expand Down
8 changes: 4 additions & 4 deletions src/messages/handle-tool-message.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type {
LanguageModelV2Message,
LanguageModelV2ToolResultPart,
LanguageModelV3Message,
LanguageModelV3ToolResultPart,
} from '@ai-sdk/provider'
import { describe, expect, it } from 'vitest'
import type { RequestyChatMessage } from '../types'
import { handleToolContentPart, handleToolMessage } from './handle-tool-message'

describe('tool messages', () => {
it.for<[string, LanguageModelV2ToolResultPart, string]>([
it.for<[string, LanguageModelV3ToolResultPart, string]>([
[
'text output',
{
Expand Down Expand Up @@ -166,7 +166,7 @@ describe('tool messages', () => {
it.for<
[
string,
Extract<LanguageModelV2Message, { role: 'tool' }>,
Extract<LanguageModelV3Message, { role: 'tool' }>,
Array<RequestyChatMessage>,
]
>([
Expand Down
45 changes: 28 additions & 17 deletions src/messages/handle-tool-message.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,44 @@
import type {
LanguageModelV2Message,
LanguageModelV2ToolResultPart,
LanguageModelV3Message,
LanguageModelV3ToolApprovalResponsePart,
LanguageModelV3ToolResultPart,
} from '@ai-sdk/provider'
import type { RequestyChatMessage } from '../types'

export function handleToolContentPart(
contentPart: LanguageModelV2ToolResultPart,
contentPart:
| LanguageModelV3ToolResultPart
| LanguageModelV3ToolApprovalResponsePart,
): string {
switch (contentPart.output.type) {
case 'error-text':
case 'text':
return contentPart.output.value
case 'error-json':
case 'json':
return JSON.stringify(contentPart.output.value)
case 'content':
return contentPart.output.value
.filter((c) => c.type === 'text')
.map((c) => c.text)
.join('')
if (contentPart.type === 'tool-result') {
switch (contentPart.output.type) {
case 'error-text':
case 'text':
return contentPart.output.value
case 'error-json':
case 'json':
return JSON.stringify(contentPart.output.value)
case 'execution-denied':
return contentPart.output.reason ?? 'Execution denied'
case 'content':
return contentPart.output.value
.filter((c) => c.type === 'text')
.map((c) => c.text)
.join('')
}
} else {
return 'TODO: implement tool approval flow'
}
}

export function handleToolMessage(
message: Extract<LanguageModelV2Message, { role: 'tool' }>,
message: Extract<LanguageModelV3Message, { role: 'tool' }>,
): Array<RequestyChatMessage> {
return message.content.map((c) => ({
role: 'tool',
content: handleToolContentPart(c),
tool_call_id: c.toolCallId,

// TODO: implement tool approval flow
tool_call_id: c.type === 'tool-result' ? c.toolCallId : undefined,
}))
}
14 changes: 7 additions & 7 deletions src/messages/handle-user-message.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type {
LanguageModelV2FilePart,
LanguageModelV2Message,
LanguageModelV3FilePart,
LanguageModelV3Message,
} from '@ai-sdk/provider'
import type {
RequestUserObjectContentParts,
Expand All @@ -22,7 +22,7 @@ function toBase64DataUrl(base64Data: string, mediaType: string): string {
function transformUrl({
data,
mediaType,
}: LanguageModelV2FilePart): [string, boolean] {
}: LanguageModelV3FilePart): [string, boolean] {
if (data instanceof Uint8Array) {
const base64 = Buffer.from(data).toString('base64')
return [toBase64DataUrl(base64, mediaType), true]
Expand All @@ -46,7 +46,7 @@ function transformUrl({
}

function handleUserFileImageMessage(
part: LanguageModelV2FilePart,
part: LanguageModelV3FilePart,
): RequestyImagePart {
const [url, isDataUrl] = transformUrl(part)
return {
Expand All @@ -60,7 +60,7 @@ function handleUserFileImageMessage(
}

function handleUserFilePDFMessage(
part: LanguageModelV2FilePart,
part: LanguageModelV3FilePart,
): RequestyFilePart {
const [url] = transformUrl(part)
return {
Expand All @@ -72,7 +72,7 @@ function handleUserFilePDFMessage(
}

function handleUserFileMessage(
part: LanguageModelV2FilePart,
part: LanguageModelV3FilePart,
): RequestyDocumentPart {
if (part.mediaType.startsWith(IMAGE_MEDIA_TYPE)) {
return handleUserFileImageMessage(part)
Expand All @@ -84,7 +84,7 @@ function handleUserFileMessage(
}

export function handleUserMessage(
message: Extract<LanguageModelV2Message, { role: 'user' }>,
message: Extract<LanguageModelV3Message, { role: 'user' }>,
): RequestyChatMessage {
const includesImages = message.content.some((c) => c.type === 'file')
if (!includesImages) {
Expand Down
8 changes: 4 additions & 4 deletions src/messages/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type {
LanguageModelV2Message,
LanguageModelV2Prompt,
LanguageModelV3Message,
LanguageModelV3Prompt,
} from '@ai-sdk/provider'
import type { RequestyChatMessage, RequestyChatPrompt } from '../types'
import { handleAssistantMessage } from './handle-assistant-message'
Expand All @@ -9,7 +9,7 @@ import { handleToolMessage } from './handle-tool-message'
import { handleUserMessage } from './handle-user-message'

function handleMessage(
message: LanguageModelV2Message,
message: LanguageModelV3Message,
): Array<RequestyChatMessage> {
switch (message.role) {
case 'system':
Expand All @@ -24,7 +24,7 @@ function handleMessage(
}

export function convertToRequestyChatMessages(
prompt: LanguageModelV2Prompt,
prompt: LanguageModelV3Prompt,
): RequestyChatPrompt {
return prompt.flatMap(handleMessage)
}
Loading