From f1a95735b81c2fef95e2c41e4163120939089e05 Mon Sep 17 00:00:00 2001 From: Aiden Cline Date: Tue, 21 Jul 2026 19:15:26 +0000 Subject: [PATCH] fix(plugin): resolve request hook rebase --- packages/core/src/session/model-stream.ts | 2 +- packages/core/src/session/runner/llm.ts | 120 +++++++++--------- .../core/test/session-model-stream.test.ts | 2 +- 3 files changed, 65 insertions(+), 59 deletions(-) diff --git a/packages/core/src/session/model-stream.ts b/packages/core/src/session/model-stream.ts index eb5833e002..4c6a7b07c0 100644 --- a/packages/core/src/session/model-stream.ts +++ b/packages/core/src/session/model-stream.ts @@ -4,8 +4,8 @@ import { LLMClient, type LLMError, type LLMEvent, type LLMRequest } from "@openc import type { Agent } from "@opencode-ai/schema/agent" import type { Model } from "@opencode-ai/schema/model" import type { Session } from "@opencode-ai/schema/session" +import { makeLocationNode } from "@opencode-ai/util/effect/app-node" import { Context, Effect, Layer, Stream } from "effect" -import { makeLocationNode } from "../effect/app-node" import { llmClient } from "../effect/app-node-platform" import { PluginHooks } from "../plugin/hooks" diff --git a/packages/core/src/session/runner/llm.ts b/packages/core/src/session/runner/llm.ts index 2f9baa0be8..3aabbf8a35 100644 --- a/packages/core/src/session/runner/llm.ts +++ b/packages/core/src/session/runner/llm.ts @@ -104,7 +104,14 @@ const layer = Layer.effect( const agent = loaded.agent const resolved = loaded.model const model = resolved.model - const compactionInput = { session, messages: loaded.messages, model, cost: resolved.cost } + const compactionInput = { + session, + messages: loaded.messages, + model, + agent: agent.id, + modelRef: resolved.ref, + cost: resolved.cost, + } if (compaction.required(compactionInput) && !(yield* SessionPending.compaction(db, session.id))) { const compacted = yield* compaction.compact(compactionInput) if (compacted.status === "completed") return { _tag: "RestartAfterCompaction", step: currentStep } as const @@ -137,66 +144,66 @@ const layer = Layer.effect( const providerStream = llm .stream({ sessionID: session.id, agent: agent.id, model: resolved.ref, request: prepared.request }) .pipe( - Stream.runForEach((event) => - Effect.gen(function* () { - if (overflowFailure || publisher.hasProviderError()) return - if (LLMEvent.is.providerError(event)) { - if (isContextOverflowFailure(event) && !publisher.hasRetryEvidence()) { - overflowFailure = event + Stream.runForEach((event) => + Effect.gen(function* () { + if (overflowFailure || publisher.hasProviderError()) return + if (LLMEvent.is.providerError(event)) { + if (isContextOverflowFailure(event) && !publisher.hasRetryEvidence()) { + overflowFailure = event + return + } + } + yield* publish(event) + if (LLMEvent.is.toolInputError(event)) { + if (prepared.resolveToolCall(event.name).type === "settle") needsContinuation = true return } - } - yield* publish(event) - if (LLMEvent.is.toolInputError(event)) { - if (prepared.resolveToolCall(event.name).type === "settle") needsContinuation = true - return - } - if (event.type !== "tool-call" || event.providerExecuted) return - const tool = prepared.resolveToolCall(event.name) - if (tool.type === "reject") { - yield* serialized(publisher.failUnsettledTools(tool.error)) - return - } - needsContinuation = true - const assistantMessageID = yield* publisher.assistantMessageID(event.id) - ownedToolFibers.push( - yield* Effect.uninterruptibleMask((restore) => - restore( - tool.settle({ - sessionID: session.id, - agent: agent.id, - messageID: assistantMessageID, - call: event, - progress: (update) => - serialized( - events.publish(SessionEvent.Tool.Progress, { - sessionID: session.id, - assistantMessageID, - callID: event.id, - structured: { ...update.structured }, - content: [...update.content], + if (event.type !== "tool-call" || event.providerExecuted) return + const tool = prepared.resolveToolCall(event.name) + if (tool.type === "reject") { + yield* serialized(publisher.failUnsettledTools(tool.error)) + return + } + needsContinuation = true + const assistantMessageID = yield* publisher.assistantMessageID(event.id) + ownedToolFibers.push( + yield* Effect.uninterruptibleMask((restore) => + restore( + tool.settle({ + sessionID: session.id, + agent: agent.id, + messageID: assistantMessageID, + call: event, + progress: (update) => + serialized( + events.publish(SessionEvent.Tool.Progress, { + sessionID: session.id, + assistantMessageID, + callID: event.id, + structured: { ...update.structured }, + content: [...update.content], + }), + ), + }), + ).pipe( + Effect.flatMap((settlement) => + publish( + LLMEvent.toolResult({ + id: event.id, + name: event.name, + result: settlement.result, + output: settlement.output, }), + settlement.error, ), - }), - ).pipe( - Effect.flatMap((settlement) => - publish( - LLMEvent.toolResult({ - id: event.id, - name: event.name, - result: settlement.result, - output: settlement.output, - }), - settlement.error, ), ), - ), - ).pipe(FiberSet.run(toolFibers)), - ) - }), - ), - Effect.ensuring(serialized(publisher.flush())), - ) + ).pipe(FiberSet.run(toolFibers)), + ) + }), + ), + Effect.ensuring(serialized(publisher.flush())), + ) const stepUsage = (settlement: NonNullable>) => ({ cost: SessionUsage.calculateCost(resolved.cost, settlement.tokens), @@ -243,8 +250,7 @@ const layer = Layer.effect( recoverOverflow && !publisher.hasRetryEvidence() && isContextOverflowFailure(overflowFailure ?? streamFailure) && - (yield* restore(recoverOverflow({ session, messages: loaded.messages, model, cost: resolved.cost }))) - .status === "completed" + (yield* restore(recoverOverflow(compactionInput))).status === "completed" ) return { _tag: "RestartAfterOverflowCompaction", step: currentStep } as const diff --git a/packages/core/test/session-model-stream.test.ts b/packages/core/test/session-model-stream.test.ts index 7ae22e7400..d8e3fee73a 100644 --- a/packages/core/test/session-model-stream.test.ts +++ b/packages/core/test/session-model-stream.test.ts @@ -9,7 +9,7 @@ import { Session } from "@opencode-ai/schema/session" import { Effect, Layer, Stream } from "effect" import { AppNodeBuilder } from "@opencode-ai/core/effect/app-node-builder" import { llmClient } from "@opencode-ai/core/effect/app-node-platform" -import { LayerNode } from "@opencode-ai/core/effect/layer-node" +import { LayerNode } from "@opencode-ai/util/effect/layer-node" import { PluginHooks } from "@opencode-ai/core/plugin/hooks" import { SessionModelStream } from "@opencode-ai/core/session/model-stream" import { testEffect } from "./lib/effect"