Skip to content
Open
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
27 changes: 27 additions & 0 deletions .changeset/return-invalid-tool-calls.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
"effect": patch
---

Recover tool calls which `Toolkit` never sees

A tool call naming a tool which is not in the toolkit fails the whole
operation today: the response schema has no member for it, and even if it
decoded, `Toolkit` would skip it and leave it unanswered.

`generateText` and `streamText` now accept `unknownToolCalls`. With `"return"`,
such a call comes back as a `tool-call-error` response part, and
`Prompt.fromResponseParts` adds it to history as the original tool call with a
failed tool result, so the model can correct the call on the next turn. The
default, `"error"`, is unchanged. A call which names a tool in the toolkit is
unaffected: `Toolkit` still routes a failure of its parameters through that
tool's `failureMode`.

```
const response = yield* LanguageModel.generateText({
prompt,
toolkit,
unknownToolCalls: "return"
})

response.toolCallErrors // tool-call-error parts: { name, params, error }
```
2 changes: 1 addition & 1 deletion packages/effect/src/unstable/ai/AiError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { redact } from "../../Redactable.ts"
import * as Redacted from "../../Redacted.ts"
import * as Schema from "../../Schema.ts"
import type * as HttpClientError from "../http/HttpClientError.ts"
import { HttpRequestDetails, HttpResponseDetails } from "./Response.ts"
import { HttpRequestDetails, HttpResponseDetails } from "./internal/http-details.ts"

const ReasonTypeId = "~effect/ai/AiError/Reason" as const

Expand Down
25 changes: 18 additions & 7 deletions packages/effect/src/unstable/ai/Chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ export interface Service {
<Options extends NoExcessProperties<LanguageModel.GenerateTextOptions<{}>, Options>>(
options: Options & { readonly toolkit?: undefined } & LanguageModel.GenerateTextOptions<{}>
): Effect.Effect<
LanguageModel.GenerateTextResponse<{}>,
LanguageModel.GenerateTextResponse<{}, "decoded", LanguageModel.ExtractUnknownToolCalls<Options>>,
LanguageModel.ExtractError<Options>,
LanguageModel.LanguageModel | LanguageModel.ExtractServices<Options>
>
Expand All @@ -240,7 +240,11 @@ export interface Service {
readonly toolkit: LanguageModel.ToolkitInput<Tools>
}
): Effect.Effect<
LanguageModel.GenerateTextResponse<Tools, LanguageModel.ExtractToolParametersMode<Options>>,
LanguageModel.GenerateTextResponse<
Tools,
LanguageModel.ExtractToolParametersMode<Options>,
LanguageModel.ExtractUnknownToolCalls<Options>
>,
LanguageModel.ExtractError<Options>,
LanguageModel.LanguageModel | LanguageModel.ExtractServices<Options>
>
Expand All @@ -255,7 +259,8 @@ export interface Service {
): Effect.Effect<
LanguageModel.GenerateTextResponse<
LanguageModel.ExtractTools<Options>,
LanguageModel.ExtractToolParametersMode<Options>
LanguageModel.ExtractToolParametersMode<Options>,
LanguageModel.ExtractUnknownToolCalls<Options>
>,
LanguageModel.ExtractError<Options>,
LanguageModel.LanguageModel | LanguageModel.ExtractServices<Options>
Expand Down Expand Up @@ -307,7 +312,7 @@ export interface Service {
<Options extends NoExcessProperties<LanguageModel.GenerateTextOptions<{}>, Options>>(
options: Options & { readonly toolkit?: undefined } & LanguageModel.GenerateTextOptions<{}>
): Stream.Stream<
Response.StreamPart<{}>,
Response.StreamPart<{}, "decoded", LanguageModel.ExtractUnknownToolCalls<Options>>,
LanguageModel.ExtractError<Options>,
LanguageModel.LanguageModel | LanguageModel.ExtractServices<Options>
>
Expand All @@ -322,7 +327,11 @@ export interface Service {
readonly toolkit: LanguageModel.ToolkitInput<Tools>
}
): Stream.Stream<
Response.StreamPart<Tools, LanguageModel.ExtractToolParametersMode<Options>>,
Response.StreamPart<
Tools,
LanguageModel.ExtractToolParametersMode<Options>,
LanguageModel.ExtractUnknownToolCalls<Options>
>,
LanguageModel.ExtractError<Options>,
LanguageModel.LanguageModel | LanguageModel.ExtractServices<Options>
>
Expand All @@ -337,7 +346,8 @@ export interface Service {
): Stream.Stream<
Response.StreamPart<
LanguageModel.ExtractTools<Options>,
LanguageModel.ExtractToolParametersMode<Options>
LanguageModel.ExtractToolParametersMode<Options>,
LanguageModel.ExtractUnknownToolCalls<Options>
>,
LanguageModel.ExtractError<Options>,
LanguageModel.LanguageModel | LanguageModel.ExtractServices<Options>
Expand Down Expand Up @@ -399,7 +409,8 @@ export interface Service {
LanguageModel.GenerateObjectResponse<
LanguageModel.ExtractTools<Options>,
ObjectSchema["Type"],
LanguageModel.ExtractToolParametersMode<Options>
LanguageModel.ExtractToolParametersMode<Options>,
LanguageModel.ExtractUnknownToolCalls<Options>
>,
LanguageModel.ExtractError<Options>,
LanguageModel.ExtractServices<Options> | ObjectSchema["DecodingServices"] | LanguageModel.LanguageModel
Expand Down
Loading