refactor(session): simplify LLM event adapter
This commit is contained in:
parent
648c5cd1b6
commit
4481d46071
2 changed files with 35 additions and 22 deletions
|
|
@ -256,9 +256,15 @@ export const LLMEvent = Object.assign(llmEventTagged, {
|
|||
toolResult: (input: WithID<ToolResult, ToolCallID>) => ToolResult.make({ ...input, id: toolCallID(input.id) }),
|
||||
toolError: (input: WithID<ToolError, ToolCallID>) => ToolError.make({ ...input, id: toolCallID(input.id) }),
|
||||
stepFinish: (input: WithUsage<StepFinish>) =>
|
||||
StepFinish.make({ ...input, usage: input.usage instanceof Usage ? input.usage : new Usage(input.usage ?? {}) }),
|
||||
StepFinish.make({
|
||||
...input,
|
||||
usage: input.usage === undefined ? undefined : input.usage instanceof Usage ? input.usage : new Usage(input.usage),
|
||||
}),
|
||||
requestFinish: (input: WithUsage<RequestFinish>) =>
|
||||
RequestFinish.make({ ...input, usage: input.usage instanceof Usage ? input.usage : new Usage(input.usage ?? {}) }),
|
||||
RequestFinish.make({
|
||||
...input,
|
||||
usage: input.usage === undefined ? undefined : input.usage instanceof Usage ? input.usage : new Usage(input.usage),
|
||||
}),
|
||||
providerError: ProviderErrorEvent.make,
|
||||
is: {
|
||||
requestStart: llmEventTagged.guards["request-start"],
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { ContentBlockID, FinishReason, LLMEvent, ProviderMetadata, ToolCallID, ToolResultValue, Usage } from "@opencode-ai/llm"
|
||||
import { FinishReason, LLMEvent, ProviderMetadata, ToolResultValue } from "@opencode-ai/llm"
|
||||
import { Effect, Schema } from "effect"
|
||||
import { type streamText } from "ai"
|
||||
import { errorMessage } from "@/util/error"
|
||||
|
|
@ -11,15 +11,12 @@ export function adapterState() {
|
|||
step: 0,
|
||||
text: 0,
|
||||
reasoning: 0,
|
||||
currentTextID: undefined as ContentBlockID | undefined,
|
||||
currentReasoningID: undefined as ContentBlockID | undefined,
|
||||
currentTextID: undefined as string | undefined,
|
||||
currentReasoningID: undefined as string | undefined,
|
||||
toolNames: {} as Record<string, string>,
|
||||
}
|
||||
}
|
||||
|
||||
const contentBlockID = (value: string) => ContentBlockID.make(value)
|
||||
const toolCallID = (value: string) => ToolCallID.make(value)
|
||||
|
||||
function finishReason(value: string | undefined): FinishReason {
|
||||
return Schema.is(FinishReason)(value) ? value : "unknown"
|
||||
}
|
||||
|
|
@ -28,7 +25,7 @@ function providerMetadata(value: unknown): ProviderMetadata | undefined {
|
|||
return Schema.is(ProviderMetadata)(value) ? value : undefined
|
||||
}
|
||||
|
||||
function usage(value: unknown): Usage | undefined {
|
||||
function usage(value: unknown) {
|
||||
if (!value || typeof value !== "object") return undefined
|
||||
const item = value as {
|
||||
inputTokens?: number
|
||||
|
|
@ -49,7 +46,17 @@ function usage(value: unknown): Usage | undefined {
|
|||
cacheWriteInputTokens: item.inputTokenDetails?.cacheWriteTokens,
|
||||
}).filter((entry) => entry[1] !== undefined),
|
||||
)
|
||||
return new Usage(result)
|
||||
return result
|
||||
}
|
||||
|
||||
function currentTextID(state: ReturnType<typeof adapterState>, id: string | undefined) {
|
||||
state.currentTextID = id ?? state.currentTextID ?? `text-${state.text++}`
|
||||
return state.currentTextID
|
||||
}
|
||||
|
||||
function currentReasoningID(state: ReturnType<typeof adapterState>, id: string | undefined) {
|
||||
state.currentReasoningID = id ?? state.currentReasoningID ?? `reasoning-${state.reasoning++}`
|
||||
return state.currentReasoningID
|
||||
}
|
||||
|
||||
export function toLLMEvents(
|
||||
|
|
@ -86,7 +93,7 @@ export function toLLMEvents(
|
|||
|
||||
case "text-start":
|
||||
return Effect.sync(() => {
|
||||
state.currentTextID = contentBlockID(event.id ?? `text-${state.text++}`)
|
||||
state.currentTextID = currentTextID(state, event.id)
|
||||
return [
|
||||
LLMEvent.textStart({
|
||||
id: state.currentTextID,
|
||||
|
|
@ -98,7 +105,7 @@ export function toLLMEvents(
|
|||
case "text-delta":
|
||||
return Effect.succeed([
|
||||
LLMEvent.textDelta({
|
||||
id: event.id ? contentBlockID(event.id) : (state.currentTextID ?? contentBlockID(`text-${state.text++}`)),
|
||||
id: currentTextID(state, event.id),
|
||||
text: event.text,
|
||||
}),
|
||||
])
|
||||
|
|
@ -106,14 +113,14 @@ export function toLLMEvents(
|
|||
case "text-end":
|
||||
return Effect.succeed([
|
||||
LLMEvent.textEnd({
|
||||
id: event.id ? contentBlockID(event.id) : (state.currentTextID ?? contentBlockID(`text-${state.text++}`)),
|
||||
id: currentTextID(state, event.id),
|
||||
providerMetadata: providerMetadata(event.providerMetadata),
|
||||
}),
|
||||
])
|
||||
|
||||
case "reasoning-start":
|
||||
return Effect.sync(() => {
|
||||
state.currentReasoningID = contentBlockID(event.id)
|
||||
state.currentReasoningID = currentReasoningID(state, event.id)
|
||||
return [
|
||||
LLMEvent.reasoningStart({
|
||||
id: state.currentReasoningID,
|
||||
|
|
@ -125,14 +132,14 @@ export function toLLMEvents(
|
|||
case "reasoning-delta":
|
||||
return Effect.succeed([
|
||||
LLMEvent.reasoningDelta({
|
||||
id: event.id ? contentBlockID(event.id) : (state.currentReasoningID ?? contentBlockID(`reasoning-${state.reasoning++}`)),
|
||||
id: currentReasoningID(state, event.id),
|
||||
text: event.text,
|
||||
}),
|
||||
])
|
||||
|
||||
case "reasoning-end":
|
||||
return Effect.sync(() => {
|
||||
const id = contentBlockID(event.id)
|
||||
const id = currentReasoningID(state, event.id)
|
||||
state.currentReasoningID = undefined
|
||||
return [
|
||||
LLMEvent.reasoningEnd({
|
||||
|
|
@ -147,7 +154,7 @@ export function toLLMEvents(
|
|||
state.toolNames[event.id] = event.toolName
|
||||
return [
|
||||
LLMEvent.toolInputStart({
|
||||
id: toolCallID(event.id),
|
||||
id: event.id,
|
||||
name: event.toolName,
|
||||
providerMetadata: providerMetadata(event.providerMetadata),
|
||||
}),
|
||||
|
|
@ -157,7 +164,7 @@ export function toLLMEvents(
|
|||
case "tool-input-delta":
|
||||
return Effect.succeed([
|
||||
LLMEvent.toolInputDelta({
|
||||
id: toolCallID(event.id),
|
||||
id: event.id,
|
||||
name: state.toolNames[event.id] ?? "unknown",
|
||||
text: event.delta ?? "",
|
||||
}),
|
||||
|
|
@ -166,7 +173,7 @@ export function toLLMEvents(
|
|||
case "tool-input-end":
|
||||
return Effect.succeed([
|
||||
LLMEvent.toolInputEnd({
|
||||
id: toolCallID(event.id),
|
||||
id: event.id,
|
||||
name: state.toolNames[event.id] ?? "unknown",
|
||||
}),
|
||||
])
|
||||
|
|
@ -176,7 +183,7 @@ export function toLLMEvents(
|
|||
state.toolNames[event.toolCallId] = event.toolName
|
||||
return [
|
||||
LLMEvent.toolCall({
|
||||
id: toolCallID(event.toolCallId),
|
||||
id: event.toolCallId,
|
||||
name: event.toolName,
|
||||
input: event.input,
|
||||
providerExecuted: "providerExecuted" in event ? event.providerExecuted : undefined,
|
||||
|
|
@ -191,7 +198,7 @@ export function toLLMEvents(
|
|||
delete state.toolNames[event.toolCallId]
|
||||
return [
|
||||
LLMEvent.toolResult({
|
||||
id: toolCallID(event.toolCallId),
|
||||
id: event.toolCallId,
|
||||
name,
|
||||
result: ToolResultValue.make(event.output),
|
||||
providerExecuted: "providerExecuted" in event ? event.providerExecuted : undefined,
|
||||
|
|
@ -205,7 +212,7 @@ export function toLLMEvents(
|
|||
delete state.toolNames[event.toolCallId]
|
||||
return [
|
||||
LLMEvent.toolError({
|
||||
id: toolCallID(event.toolCallId),
|
||||
id: event.toolCallId,
|
||||
name,
|
||||
message: errorMessage(event.error),
|
||||
}),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue