(tools: Record<string, Tool>, input: Pick<StreamInput, "messages" | "abort">)
| 167 | } |
| 168 | |
| 169 | export function nativeTools(tools: Record<string, Tool>, input: Pick<StreamInput, "messages" | "abort">) { |
| 170 | return Object.fromEntries( |
| 171 | Object.entries(tools).map(([name, item]) => [ |
| 172 | name, |
| 173 | // Tool execution remains opencode-owned. The native runtime only adapts |
| 174 | // the @opencode-ai/llm tool call back into the AI SDK Tool.execute shape. |
| 175 | NativeTool.make({ |
| 176 | description: item.description ?? "", |
| 177 | jsonSchema: nativeSchema(item.inputSchema), |
| 178 | execute: (args: unknown, ctx) => |
| 179 | Effect.tryPromise({ |
| 180 | try: () => { |
| 181 | if (!item.execute) throw new Error(`Tool has no execute handler: ${name}`) |
| 182 | return item.execute(args, { |
| 183 | toolCallId: ctx?.id ?? name, |
| 184 | messages: input.messages, |
| 185 | abortSignal: input.abort, |
| 186 | }) |
| 187 | }, |
| 188 | catch: (error) => new ToolFailure({ message: errorMessage(error), error }), |
| 189 | }), |
| 190 | }), |
| 191 | ]), |
| 192 | ) |
| 193 | } |
| 194 | |
| 195 | export * as LLMNativeRuntime from "./native-runtime" |
no test coverage detected