@opencode-ai/ai
Advanced tools
@@ -434,2 +434,3 @@ import { Schema } from "effect"; | ||
| tools: Partial<Record<number, ToolStream.PendingTool>>; | ||
| reasoningSignatures: {}; | ||
| lifecycle: Lifecycle.State; | ||
@@ -436,0 +437,0 @@ }>; |
@@ -635,2 +635,5 @@ import { Effect, Schema } from "effect"; | ||
| name: block.name ?? "", | ||
| input: block.input !== undefined && (!ProviderShared.isRecord(block.input) || Object.keys(block.input).length > 0) | ||
| ? ProviderShared.encodeJson(block.input) | ||
| : undefined, | ||
| providerExecuted: block.type === "server_tool_use", | ||
@@ -649,15 +652,25 @@ }), | ||
| } | ||
| if (block.type === "text" && block.text) { | ||
| if (block.type === "text" && block.text !== undefined) { | ||
| const events = []; | ||
| const id = `text-${event.index ?? 0}`; | ||
| const lifecycle = Lifecycle.textStart(state.lifecycle, events, id); | ||
| return [ | ||
| { ...state, lifecycle: Lifecycle.textDelta(state.lifecycle, events, `text-${event.index ?? 0}`, block.text) }, | ||
| { ...state, lifecycle: block.text ? Lifecycle.textDelta(lifecycle, events, id, block.text) : lifecycle }, | ||
| events, | ||
| ]; | ||
| } | ||
| if (block.type === "thinking" && block.thinking) { | ||
| if (block.type === "thinking" && block.thinking !== undefined) { | ||
| const events = []; | ||
| const id = `reasoning-${event.index ?? 0}`; | ||
| const providerMetadata = block.signature === undefined ? undefined : anthropicMetadata({ signature: block.signature }); | ||
| const lifecycle = Lifecycle.reasoningStart(state.lifecycle, events, id, providerMetadata); | ||
| return [ | ||
| { | ||
| ...state, | ||
| lifecycle: Lifecycle.reasoningDelta(state.lifecycle, events, `reasoning-${event.index ?? 0}`, block.thinking), | ||
| lifecycle: block.thinking | ||
| ? Lifecycle.reasoningDelta(lifecycle, events, id, block.thinking, providerMetadata) | ||
| : lifecycle, | ||
| reasoningSignatures: event.index === undefined || block.signature === undefined | ||
| ? state.reasoningSignatures | ||
| : { ...state.reasoningSignatures, [event.index]: block.signature }, | ||
| }, | ||
@@ -670,3 +683,3 @@ events, | ||
| // @ai-sdk/anthropic). The existing content_block_stop closes the part. | ||
| if (block.type === "redacted_thinking" && block.data) { | ||
| if (block.type === "redacted_thinking" && block.data !== undefined) { | ||
| const events = []; | ||
@@ -707,9 +720,9 @@ return [ | ||
| if (delta?.type === "signature_delta" && delta.signature) { | ||
| const events = []; | ||
| const index = event.index ?? 0; | ||
| return [ | ||
| { | ||
| ...state, | ||
| lifecycle: Lifecycle.reasoningEnd(state.lifecycle, events, `reasoning-${event.index ?? 0}`, anthropicMetadata({ signature: delta.signature })), | ||
| reasoningSignatures: { ...state.reasoningSignatures, [index]: delta.signature }, | ||
| }, | ||
| events, | ||
| NO_EVENTS, | ||
| ]; | ||
@@ -736,22 +749,41 @@ } | ||
| const resultEvents = result.events ?? []; | ||
| const signature = state.reasoningSignatures[event.index]; | ||
| const lifecycle = resultEvents.length | ||
| ? Lifecycle.stepStart(state.lifecycle, events) | ||
| : Lifecycle.reasoningEnd(Lifecycle.textEnd(state.lifecycle, events, `text-${event.index}`), events, `reasoning-${event.index}`); | ||
| : Lifecycle.reasoningEnd(Lifecycle.textEnd(state.lifecycle, events, `text-${event.index}`), events, `reasoning-${event.index}`, signature === undefined ? undefined : anthropicMetadata({ signature })); | ||
| events.push(...resultEvents); | ||
| return [{ ...state, lifecycle, tools: result.tools }, events]; | ||
| const reasoningSignatures = { ...state.reasoningSignatures }; | ||
| delete reasoningSignatures[event.index]; | ||
| return [{ ...state, lifecycle, tools: result.tools, reasoningSignatures }, events]; | ||
| }); | ||
| const onMessageDelta = (state, event) => { | ||
| const usage = mergeUsage(state.usage, mapUsage(event.usage)); | ||
| return [ | ||
| { | ||
| ...state, | ||
| usage, | ||
| pendingFinish: { | ||
| reason: { | ||
| normalized: mapFinishReason(event.delta?.stop_reason), | ||
| raw: event.delta?.stop_reason ?? undefined, | ||
| }, | ||
| providerMetadata: event.delta?.stop_sequence === null || event.delta?.stop_sequence === undefined | ||
| ? undefined | ||
| : anthropicMetadata({ stopSequence: event.delta.stop_sequence }), | ||
| }, | ||
| }, | ||
| NO_EVENTS, | ||
| ]; | ||
| }; | ||
| const onMessageStop = (state) => { | ||
| const events = []; | ||
| const lifecycle = Lifecycle.finish(state.lifecycle, events, { | ||
| reason: { | ||
| normalized: mapFinishReason(event.delta?.stop_reason), | ||
| raw: event.delta?.stop_reason ?? undefined, | ||
| reason: state.pendingFinish?.reason ?? { | ||
| normalized: "unknown", | ||
| raw: undefined, | ||
| }, | ||
| usage, | ||
| providerMetadata: event.delta?.stop_sequence | ||
| ? anthropicMetadata({ stopSequence: event.delta.stop_sequence }) | ||
| : undefined, | ||
| usage: state.usage, | ||
| providerMetadata: state.pendingFinish?.providerMetadata, | ||
| }); | ||
| return [{ ...state, lifecycle, usage }, events]; | ||
| return [{ ...state, lifecycle }, events]; | ||
| }; | ||
@@ -783,2 +815,4 @@ // Prefix `error.type` so overloads, rate limits, and quota errors are visible | ||
| return Effect.succeed(onMessageDelta(state, event)); | ||
| if (event.type === "message_stop") | ||
| return Effect.succeed(onMessageStop(state)); | ||
| if (event.type === "error") | ||
@@ -804,3 +838,7 @@ return onError(event); | ||
| event: Protocol.jsonEvent(AnthropicEvent), | ||
| initial: () => ({ tools: ToolStream.empty(), lifecycle: Lifecycle.initial() }), | ||
| initial: () => ({ | ||
| tools: ToolStream.empty(), | ||
| reasoningSignatures: {}, | ||
| lifecycle: Lifecycle.initial(), | ||
| }), | ||
| step, | ||
@@ -807,0 +845,0 @@ }, |
@@ -9,2 +9,3 @@ import { LLMEvent, type FinishReasonDetails, type ProviderMetadata, type Usage } from "../../schema"; | ||
| export declare const stepStart: (state: State, events: LLMEvent[]) => State; | ||
| export declare const textStart: (state: State, events: LLMEvent[], id: string, providerMetadata?: ProviderMetadata) => State; | ||
| export declare const textDelta: (state: State, events: LLMEvent[], id: string, text: string) => State; | ||
@@ -11,0 +12,0 @@ export declare const reasoningStart: (state: State, events: LLMEvent[], id: string, providerMetadata?: ProviderMetadata) => State; |
@@ -9,11 +9,14 @@ import { LLMEvent } from "../../schema"; | ||
| }; | ||
| export const textDelta = (state, events, id, text) => { | ||
| export const textStart = (state, events, id, providerMetadata) => { | ||
| if (state.text.has(id)) | ||
| return state; | ||
| const stepped = stepStart(state, events); | ||
| if (stepped.text.has(id)) { | ||
| events.push(LLMEvent.textDelta({ id, text })); | ||
| return stepped; | ||
| } | ||
| events.push(LLMEvent.textStart({ id }), LLMEvent.textDelta({ id, text })); | ||
| events.push(LLMEvent.textStart({ id, providerMetadata })); | ||
| return { ...stepped, text: new Set([...stepped.text, id]) }; | ||
| }; | ||
| export const textDelta = (state, events, id, text) => { | ||
| const started = textStart(state, events, id); | ||
| events.push(LLMEvent.textDelta({ id, text })); | ||
| return started; | ||
| }; | ||
| export const reasoningStart = (state, events, id, providerMetadata) => { | ||
@@ -20,0 +23,0 @@ if (state.reasoning.has(id)) |
+3
-3
| { | ||
| "$schema": "https://json.schemastore.org/package.json", | ||
| "version": "0.0.0-next-16176", | ||
| "version": "0.0.0-next-16179", | ||
| "name": "@opencode-ai/ai", | ||
@@ -29,3 +29,3 @@ "type": "module", | ||
| "@effect/platform-node": "4.0.0-beta.98", | ||
| "@opencode-ai/http-recorder": "0.0.0-next-16176", | ||
| "@opencode-ai/http-recorder": "0.0.0-next-16179", | ||
| "@tsconfig/bun": "1.0.9", | ||
@@ -39,3 +39,3 @@ "@types/bun": "1.3.13", | ||
| "@smithy/util-utf8": "4.2.2", | ||
| "@opencode-ai/schema": "0.0.0-next-16176", | ||
| "@opencode-ai/schema": "0.0.0-next-16179", | ||
| "aws4fetch": "1.0.20", | ||
@@ -42,0 +42,0 @@ "effect": "4.0.0-beta.98", |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
1092911
0.19%22948
0.19%+ Added
- Removed