diff --git a/packages/ai/src/providers/groq.ts b/packages/ai/src/providers/groq.ts index 4ece7cf6eeb..e9048262b74 100644 --- a/packages/ai/src/providers/groq.ts +++ b/packages/ai/src/providers/groq.ts @@ -34,8 +34,6 @@ export type Settings = ProviderPackage.Settings & const Options = Schema.Struct({ includeReasoning: Schema.optional(Schema.Boolean), - parallelToolCalls: Schema.optional(Schema.Boolean), - serviceTier: Schema.optional(Schema.String), user: Schema.optional(Schema.String), }) @@ -46,8 +44,6 @@ export const protocol = Protocol.make({ ...OpenAIChat.bodyFields, reasoning_format: Schema.optional(Schema.Literal("parsed")), include_reasoning: Schema.optional(Schema.Boolean), - parallel_tool_calls: Schema.optional(Schema.Boolean), - service_tier: Schema.optional(Schema.String), user: Schema.optional(Schema.String), }), from: Effect.fn("Groq.fromRequest")(function* (request: LLMRequest) { @@ -59,8 +55,6 @@ export const protocol = Protocol.make({ ...(yield* OpenAIChat.fromRequest(request)), reasoning_format: gptOSS ? undefined : ("parsed" as const), include_reasoning: gptOSS ? options.includeReasoning : undefined, - parallel_tool_calls: options.parallelToolCalls, - service_tier: options.serviceTier, user: options.user, } }), diff --git a/packages/ai/test/provider/groq.test.ts b/packages/ai/test/provider/groq.test.ts index aca18d2180c..eac3b09d903 100644 --- a/packages/ai/test/provider/groq.test.ts +++ b/packages/ai/test/provider/groq.test.ts @@ -42,7 +42,12 @@ it.effect("Groq lowers its own options for custom catalog identities and endpoin { provider: "custom-groq" }, ) const compiled = yield* compileRequest( - LLM.request({ model, prompt: "Hello", providerOptions: { parallelToolCalls: false, includeReasoning: false } }), + LLM.request({ + model, + prompt: "Hello", + tools: [weatherTool], + providerOptions: { parallelToolCalls: false, includeReasoning: false }, + }), ) expect(model.route.endpoint.baseURL).toBe("https://gateway.example/v1") expect(model.route.defaults.headers).toEqual({ "x-client": "test" }) @@ -60,6 +65,25 @@ it.effect("Groq lowers its own options for custom catalog identities and endpoin }), ) +it.effect("Groq honors disableParallelToolUse and sends parallel_tool_calls only with tools", () => + Effect.gen(function* () { + const model = Groq.configure({ apiKey: "fixture" }).model("openai/gpt-oss-20b") + const withTools = yield* compileRequest( + LLM.request({ + model, + prompt: "Hello", + tools: [weatherTool], + toolChoice: { type: "auto", disableParallelToolUse: true }, + }), + ) + expect(withTools.body.parallel_tool_calls).toBe(false) + const withoutTools = yield* compileRequest( + LLM.request({ model, prompt: "Hello", providerOptions: { parallelToolCalls: true } }), + ) + expect(withoutTools.body).not.toHaveProperty("parallel_tool_calls") + }), +) + it.effect("Groq replays reasoning only when present and preserves explicit reasoning exclusion", () => Effect.gen(function* () { const compiled = yield* compileRequest( @@ -100,11 +124,13 @@ it.effect("Groq omits reasoning_format for the GPT-OSS family by default", () => it.effect("Groq validates option types", () => Effect.gen(function* () { - for (const providerOptions of [{ includeReasoning: "false" }, { parallelToolCalls: "false" }]) { - const error = yield* compileRequest( - LLM.request({ model: Groq.configure({ apiKey: "fixture" }).model("qwen"), prompt: "Hello", providerOptions }), - ).pipe(Effect.flip) - expect(error.reason._tag).toBe("InvalidRequest") - } + const error = yield* compileRequest( + LLM.request({ + model: Groq.configure({ apiKey: "fixture" }).model("qwen"), + prompt: "Hello", + providerOptions: { includeReasoning: "false" }, + }), + ).pipe(Effect.flip) + expect(error.reason._tag).toBe("InvalidRequest") }), )