diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..6a1bd309 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,8 @@ +{ + "name": "opencode-dev", + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "postCreateCommand": "sudo apt-get update && sudo apt-get install -y python3 make g++ && curl -fsSL https://bun.sh/install | bash", + "remoteEnv": { + "PATH": "${containerEnv:PATH}:/home/vscode/.bun/bin" + } +} \ No newline at end of file diff --git a/packages/core/src/tool/websearch.ts b/packages/core/src/tool/websearch.ts index 6d622363..3329e7bc 100644 --- a/packages/core/src/tool/websearch.ts +++ b/packages/core/src/tool/websearch.ts @@ -149,14 +149,16 @@ const exaUrl = (apiKey: string | undefined) => { return url.toString() } -const callMcp = ( - http: HttpClient.HttpClient, - url: string, - tool: string, - args: Schema.Struct, - value: Schema.Struct.Type, - headers: Record = {}, -) => +interface McpCallOptions { + readonly http: HttpClient.HttpClient + readonly url: string + readonly tool: string + readonly args: Schema.Struct + readonly value: Schema.Struct.Type + readonly headers?: Record +} + +const callMcp = ({ http, url, tool, args, value, headers = {} }: McpCallOptions) => Effect.gen(function* () { const request = yield* HttpClientRequest.post(url).pipe( HttpClientRequest.accept("application/json, text/event-stream"), @@ -218,29 +220,35 @@ const layer = Layer.effectDiscard( const text = provider === "exa" - ? yield* callMcp(http, exaUrl(config.exaApiKey), "web_search_exa", ExaArgs, { - query: input.query, - type: input.type || "auto", - numResults: input.numResults || 8, - livecrawl: input.livecrawl || "fallback", - contextMaxCharacters: input.contextMaxCharacters, + ? yield* callMcp({ + http, + url: exaUrl(config.exaApiKey), + tool: "web_search_exa", + args: ExaArgs, + value: { + query: input.query, + type: input.type || "auto", + numResults: input.numResults || 8, + livecrawl: input.livecrawl || "fallback", + contextMaxCharacters: input.contextMaxCharacters, + }, }) - : yield* callMcp( + : yield* callMcp({ http, - PARALLEL_URL, - "web_search", - ParallelArgs, - { + url: PARALLEL_URL, + tool: "web_search", + args: ParallelArgs, + value: { objective: input.query, search_queries: [input.query], session_id: context.sessionID, // V2 invocation context does not safely expose the model yet. }, - { + headers: { "User-Agent": `opencode/${InstallationVersion}`, ...(config.parallelApiKey ? { Authorization: `Bearer ${config.parallelApiKey}` } : {}), }, - ) + }) return { provider, text: text ?? NO_RESULTS,