Skip to content

Commit 761f373

Browse files
committed
fix(plugin): restore package publishing
1 parent b452368 commit 761f373

20 files changed

Lines changed: 67 additions & 204 deletions

File tree

‎packages/core/src/plugin/hooks.ts‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
export * as PluginHooks from "./hooks"
22

33
import type { AISDKHooks } from "@opencode-ai/plugin/v2/effect/aisdk"
4-
import type { SessionHooks } from "@opencode-ai/plugin/v2/effect/session"
54
import type { ToolHooks } from "@opencode-ai/plugin/v2/effect/tool"
65
import { Context, Effect, Layer, Scope } from "effect"
76
import { makeLocationNode } from "../effect/app-node"
87
import { State } from "../state"
98

109
export interface Domains {
1110
readonly aisdk: AISDKHooks
12-
readonly session: SessionHooks
1311
readonly tool: ToolHooks
1412
}
1513

‎packages/core/src/plugin/host.ts‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,6 @@ export const make = Effect.fn("PluginHost.make")(function* (plugin: PluginV2.Int
367367
},
368368
},
369369
session: {
370-
hook: (name, callback) => hooks.register("session", name, callback),
371370
create: (input) =>
372371
runtime.session.create({
373372
id: input?.id,

‎packages/core/src/plugin/promise.ts‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,6 @@ export function fromPromise(plugin: PromisePlugin) {
118118
prompt: (input) => run(host.session.prompt(input)),
119119
command: (input) => run(host.session.command(input)),
120120
interrupt: (input) => run(host.session.interrupt(input)),
121-
hook: (name, callback) =>
122-
register(host.session.hook(name, (event) => Effect.promise(() => Promise.resolve(callback(event))))),
123121
},
124122
}
125123

‎packages/core/src/session/runner/llm.ts‎

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ import { llmClient } from "../../effect/app-node-platform"
5151
import { AgentNotFoundError, StepFailedError } from "../error"
5252
import { toSessionError } from "../to-session-error"
5353
import { SessionRunnerRetry } from "./retry"
54-
import type { SessionHooks } from "@opencode-ai/plugin/v2/effect/session"
55-
import { PluginHooks } from "../../plugin/hooks"
5654
import { PluginSupervisor } from "../../plugin/supervisor"
5755

5856
type StepTokens = {
@@ -91,7 +89,6 @@ const layer = Layer.effect(
9189
const llm = yield* LLMClient.Service
9290
const agents = yield* AgentV2.Service
9391
const tools = yield* ToolRegistry.Service
94-
const hooks = yield* PluginHooks.Service
9592
const models = yield* SessionRunnerModel.Service
9693
const store = yield* SessionStore.Service
9794
const location = yield* Location.Service
@@ -212,30 +209,7 @@ const layer = Layer.effect(
212209
const toolFibers = yield* FiberSet.make<void, ToolOutputStore.Error>()
213210
const ownedToolFibers: Array<Fiber.Fiber<void, ToolOutputStore.Error>> = []
214211
let needsContinuation = false
215-
const availableTools = new Map(request.tools.map((tool) => [tool.name, tool]))
216-
const requestEvent: SessionHooks["request"] = {
217-
sessionID: session.id,
218-
agent: agent.id,
219-
model: resolved.ref,
220-
system: [...request.system],
221-
messages: [...request.messages],
222-
tools: Object.fromEntries(
223-
request.tools.map((tool) => [tool.name, { description: tool.description, input: { ...tool.inputSchema } }]),
224-
),
225-
}
226-
// Plugins may reshape the draft, but cannot advertise tools excluded earlier
227-
// by permissions or registration state.
228-
yield* hooks.trigger("session", "request", requestEvent)
229-
const hookedRequest = LLM.updateRequest(request, {
230-
system: requestEvent.system,
231-
messages: requestEvent.messages,
232-
tools: Object.entries(requestEvent.tools).flatMap(([name, tool]) => {
233-
const registered = availableTools.get(name)
234-
if (!registered) return []
235-
return [{ ...registered, description: tool.description, inputSchema: tool.input }]
236-
}),
237-
})
238-
const advertisedTools = new Set(hookedRequest.tools.map((tool) => tool.name))
212+
const hookedRequest = request
239213
// Automatic compaction completed; rebuild the request from compacted history.
240214
if (
241215
!(yield* SessionPending.compaction(db, session.id)) &&
@@ -280,21 +254,6 @@ const layer = Layer.effect(
280254
)
281255
return
282256
}
283-
// A request hook hid this registered tool from the current request. Fail only
284-
// this call durably and continue so the model can react, instead of executing
285-
// a tool that was not advertised. Unregistered tools flow through settle, which
286-
// durably fails them as unknown.
287-
if (!advertisedTools.has(event.name) && availableTools.has(event.name)) {
288-
needsContinuation = true
289-
yield* publish(
290-
LLMEvent.toolError({
291-
id: event.id,
292-
name: event.name,
293-
message: `Tool is not available for this request: ${event.name}`,
294-
}),
295-
)
296-
return
297-
}
298257
needsContinuation = true
299258
const assistantMessageID = yield* publisher.assistantMessageID(event.id)
300259
ownedToolFibers.push(
@@ -624,7 +583,6 @@ export const node = makeLocationNode({
624583
llmClient,
625584
AgentV2.node,
626585
ToolRegistry.node,
627-
PluginHooks.node,
628586
SessionRunnerModel.node,
629587
SessionStore.node,
630588
Location.node,

‎packages/core/src/session/to-session-error.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { LLMError, ToolFailure } from "@opencode-ai/llm"
2+
import { Tool } from "@opencode-ai/plugin/v2/effect/tool"
23
import { SessionError } from "@opencode-ai/schema/session-error"
34
import { PermissionV2 } from "../permission"
45
import { QuestionV2 } from "../question"
@@ -38,7 +39,7 @@ export function toSessionError(cause: unknown): SessionError.Error {
3839
}
3940
if (cause instanceof PermissionV2.BlockedError) return { type: "permission.rejected", message: cause.message }
4041
if (cause instanceof QuestionV2.RejectedError) return { type: "aborted", message: cause.message }
41-
if (cause instanceof ToolFailure)
42+
if (cause instanceof ToolFailure || cause instanceof Tool.Failure)
4243
return cause.error === undefined ? { type: "tool.execution", message: cause.message } : toSessionError(cause.error)
4344
if (cause instanceof StepFailedError) return cause.error
4445
if (cause instanceof AgentNotFoundError) return { type: "unknown", message: cause.message }

‎packages/core/src/tool/patch.ts‎

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -194,19 +194,6 @@ export const Plugin = {
194194
),
195195
)
196196
.pipe(Effect.orDie)
197-
198-
yield* ctx.session.hook("request", (event) =>
199-
Effect.sync(() => {
200-
const usePatch =
201-
event.model.providerID.toLowerCase() === "openai" || event.model.id.toLowerCase().includes("gpt")
202-
if (usePatch) {
203-
delete event.tools.edit
204-
delete event.tools.write
205-
return
206-
}
207-
delete event.tools.patch
208-
}),
209-
)
210197
}),
211198
}
212199

‎packages/core/src/tool/subagent.ts‎

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -192,32 +192,5 @@ export const Plugin = {
192192
),
193193
)
194194
.pipe(Effect.orDie)
195-
196-
yield* ctx.session.hook("request", (event) =>
197-
Effect.gen(function* () {
198-
const tool = event.tools[name]
199-
if (!tool) return
200-
const selected = yield* agents.resolve(event.agent)
201-
if (!selected) return
202-
const available = (yield* agents.list())
203-
.filter(
204-
(agent) =>
205-
agent.mode !== "primary" &&
206-
!agent.hidden &&
207-
PermissionV2.evaluate(name, agent.id, selected.permissions).effect !== "deny",
208-
)
209-
.toSorted((a, b) => a.id.localeCompare(b.id))
210-
if (available.length === 0) return
211-
tool.description = [
212-
tool.description,
213-
"",
214-
"Available subagents:",
215-
...available.map(
216-
(agent) =>
217-
`- ${agent.id}: ${agent.description ?? "This subagent should only be called when explicitly requested."}`,
218-
),
219-
].join("\n")
220-
}),
221-
)
222195
}),
223196
}

‎packages/core/test/plugin-hooks.test.ts‎

Lines changed: 0 additions & 47 deletions
This file was deleted.

‎packages/core/test/plugin/host.ts‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,6 @@ export function host(overrides: Overrides = {}): PluginContext {
8383
prompt: () => Effect.die("unused session.prompt"),
8484
command: () => Effect.die("unused session.command"),
8585
interrupt: () => Effect.die("unused session.interrupt"),
86-
// Plugins register session hooks during setup, so a bare host accepts the
87-
// registration; the callback only runs when a test triggers the request pipeline.
88-
hook: () => Effect.succeed({ dispose: Effect.void }),
8986
},
9087
}
9188
}

‎packages/core/test/session-error.test.ts‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
ToolFailure,
1717
} from "@opencode-ai/llm"
1818
import { PermissionV2 } from "@opencode-ai/core/permission"
19+
import { Tool } from "@opencode-ai/plugin/v2/effect/tool"
1920
import { toSessionError } from "@opencode-ai/core/session/to-session-error"
2021
import { SessionRunnerRetry } from "@opencode-ai/core/session/runner/retry"
2122

@@ -64,6 +65,10 @@ describe("toSessionError", () => {
6465
type: "permission.rejected",
6566
message: "Permission denied: external_directory",
6667
})
68+
expect(toSessionError(new Tool.Failure({ message: "failed" }))).toEqual({
69+
type: "tool.execution",
70+
message: "failed",
71+
})
6772
})
6873

6974
test("retries only rate limits, provider-internal failures, and transport failures", () => {

0 commit comments

Comments
 (0)