feat(core): add pluggable web search (#35558)

Co-authored-by: Dax Raad <d@ironbay.co>
This commit is contained in:
Shoubhit Dash 2026-07-26 09:25:05 +05:30 committed by GitHub
commit efb629a33a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
57 changed files with 1700 additions and 587 deletions

View file

@ -9,3 +9,4 @@ export { Model } from "@opencode-ai/schema/model"
export { Provider } from "@opencode-ai/schema/provider"
export { Reference } from "@opencode-ai/schema/reference"
export { Skill } from "@opencode-ai/schema/skill"
export { WebSearch } from "@opencode-ai/schema/websearch"

View file

@ -12,6 +12,7 @@ import type { ReferenceDomain } from "./reference.js"
import type { SessionDomain } from "./session.js"
import type { SkillDomain } from "./skill.js"
import type { ToolDomain } from "./tool.js"
import type { WebSearchDomain } from "./websearch.js"
export interface Context {
readonly app: App
@ -27,6 +28,7 @@ export interface Context {
readonly session: SessionDomain
readonly skill: SkillDomain
readonly tool: ToolDomain
readonly websearch: WebSearchDomain
}
export interface Plugin<R = Scope.Scope> {

View file

@ -0,0 +1,23 @@
import type { WebSearch } from "@opencode-ai/schema/websearch"
import type { WebsearchApi } from "@opencode-ai/client/effect/api"
import type { Effect } from "effect"
import type { Transform } from "./registration.js"
export interface WebSearchDefinition {
readonly id: string
readonly name: string
readonly execute: (input: WebSearch.ProviderInput) => Effect.Effect<readonly WebSearch.Result[], unknown>
}
export interface WebSearchDomain extends WebsearchApi<unknown> {
readonly transform: Transform<WebSearchDraft>
readonly reload: () => Effect.Effect<void>
}
export interface WebSearchDraft {
add(definition: WebSearchDefinition): void
readonly default: {
get(): string | undefined
set(providerID: string): void
}
}

View file

@ -10,3 +10,4 @@ export { Model } from "@opencode-ai/schema/model"
export { Provider } from "@opencode-ai/schema/provider"
export { Reference } from "@opencode-ai/schema/reference"
export { Skill } from "@opencode-ai/schema/skill"
export { WebSearch } from "@opencode-ai/schema/websearch"

View file

@ -1,10 +1,32 @@
import type { IntegrationApi } from "@opencode-ai/client/promise/api"
import type { IntegrationDraft, IntegrationMethodRegistration } from "../effect/integration.js"
import type { CredentialValue } from "@opencode-ai/sdk/v2/types"
import type {
CredentialOAuth,
CredentialValue,
IntegrationEnvMethod,
IntegrationInputs,
IntegrationKeyMethod,
IntegrationOAuthMethod,
} from "@opencode-ai/sdk/v2/types"
import type { Transform } from "./registration.js"
export type { IntegrationDraft, IntegrationMethodRegistration }
export type IntegrationOAuthAuthorization = {
readonly url: string
readonly instructions: string
readonly expiresAt?: number
} & (
| {
readonly mode: "auto"
readonly callback: Promise<CredentialOAuth>
}
| {
readonly mode: "code"
readonly callback: (code: string) => Promise<CredentialOAuth>
}
)
export interface IntegrationDomain extends Omit<IntegrationApi, "wellknown"> {
readonly transform: Transform<IntegrationDraft>
readonly reload: () => Promise<void>

View file

@ -11,6 +11,7 @@ import type { ReferenceDomain } from "./reference.js"
import type { SessionDomain } from "./session.js"
import type { SkillDomain } from "./skill.js"
import type { ToolDomain } from "./tool.js"
import type { WebSearchDomain } from "./websearch.js"
export interface Context {
readonly app: App
@ -26,6 +27,7 @@ export interface Context {
readonly session: SessionDomain
readonly skill: SkillDomain
readonly tool: ToolDomain
readonly websearch: WebSearchDomain
}
export type Cleanup = () => Promise<void> | void

View file

@ -0,0 +1,25 @@
import type { WebSearch } from "@opencode-ai/schema/websearch"
import type { WebSearchApi } from "@opencode-ai/client/promise/api"
import type { Transform } from "./registration.js"
export interface WebSearchDefinition {
readonly id: string
readonly name: string
readonly execute: (
input: WebSearch.ProviderInput,
context: { readonly signal: AbortSignal },
) => Promise<readonly WebSearch.Result[]>
}
export interface WebSearchDomain extends WebSearchApi {
readonly transform: Transform<WebSearchDraft>
readonly reload: () => Promise<void>
}
export interface WebSearchDraft {
add(definition: WebSearchDefinition): void
readonly default: {
get(): string | undefined
set(providerID: string): void
}
}