New:Socket for Asana Is Now Available.Learn more
Get Started

@opencode-ai/ai

Package Overview
Dependencies
Maintainers
2
Versions
1085
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@opencode-ai/ai - npm Package Compare versions

Comparing version
0.0.0-dev-18548
to
0.0.0-dev-18549
+5
-2
dist/protocols/open-responses.d.ts

@@ -572,4 +572,6 @@ import { Effect, Schema } from "effect";

readonly outputItems: Readonly<Record<number, string>>;
readonly messageItems: ReadonlySet<string>;
readonly messagePhases: Readonly<Record<string, MessagePhase | null>>;
readonly message: {
readonly id: string;
readonly phase: MessagePhase | null | undefined;
} | undefined;
readonly reasoningItems: Readonly<Record<string, ReasoningStreamItem>>;

@@ -579,2 +581,3 @@ }

interface ReasoningStreamItem {
readonly open: boolean;
readonly encryptedContent: string | null | undefined;

@@ -581,0 +584,0 @@ readonly summaryParts: Readonly<Record<number, ReasoningSummaryStatus>>;

@@ -610,6 +610,6 @@ import { Effect, Schema } from "effect";

const onOutputTextDelta = (state, event, id) => {
if (!event.delta || !state.messageItems.has(id))
if (!event.delta || state.message?.id !== id)
return [state, NO_EVENTS];
const events = [];
const phase = state.messagePhases[id];
const phase = state.message.phase;
const metadata = providerMetadata(state, { itemId: id, ...(phase === undefined ? {} : { phase }) });

@@ -620,3 +620,3 @@ const lifecycle = Lifecycle.textStart(state.lifecycle, events, id, metadata);

const onOutputTextDone = (state, event, id) => {
if (state.messageItems.has(id)) {
if (state.message?.id === id) {
if (state.lifecycle.text.has(id) || event.text === undefined)

@@ -632,6 +632,4 @@ return [state, NO_EVENTS];

const item = state.reasoningItems[itemID];
if (!item || index === 0 || item.summaryParts[index] !== undefined)
if (!item?.open || index === 0 || item.summaryParts[index] !== undefined)
return [state, NO_EVENTS];
if (Object.values(item.summaryParts).every((status) => status === "concluded"))
return [state, NO_EVENTS];
const events = [];

@@ -661,3 +659,3 @@ const lifecycle = Object.entries(item.summaryParts)

const item = state.reasoningItems[itemID];
if (!event.delta || !item)
if (!event.delta || !item?.open)
return [state, NO_EVENTS];

@@ -667,17 +665,13 @@ const index = event.summary_index ?? 0;

return [state, NO_EVENTS];
// An unseen index cannot reopen an item whose parts have all concluded.
if (item.summaryParts[index] === undefined &&
Object.values(item.summaryParts).every((status) => status === "concluded"))
return [state, NO_EVENTS];
const started = item.summaryParts[index] === undefined ? startReasoningSummaryPart(state, itemID, index) : [state, NO_EVENTS];
const current = started[0].reasoningItems[itemID];
const [started, emitted] = startReasoningSummaryPart(state, itemID, index);
const current = started.reasoningItems[itemID];
if (!current)
return started;
const events = [...started[1]];
return [started, emitted];
const events = [...emitted];
return [
{
...started[0],
lifecycle: Lifecycle.reasoningDelta(started[0].lifecycle, events, `${itemID}:${index}`, event.delta),
...started,
lifecycle: Lifecycle.reasoningDelta(started.lifecycle, events, `${itemID}:${index}`, event.delta),
reasoningItems: {
...started[0].reasoningItems,
...started.reasoningItems,
[itemID]: { ...current, deltaIndexes: new Set([...current.deltaIndexes, index]) },

@@ -694,3 +688,3 @@ },

const item = state.reasoningItems[itemID];
if (!item || typeof event.text !== "string")
if (!item?.open || typeof event.text !== "string")
return [state, NO_EVENTS];

@@ -718,5 +712,3 @@ const index = event.summary_index ?? 0;

const phase = messagePhase(item.phase);
// A new message item is an implicit boundary for every earlier message
// item: text still streaming is ended, and all older items leave the
// tracked set so their late deltas stay no-ops instead of overlapping.
// A new message closes earlier messages, including ones that never streamed.
const events = [];

@@ -726,6 +718,5 @@ const lifecycle = [...state.lifecycle.text]

.reduce((lifecycle, id) => {
const openPhase = state.messagePhases[id];
const openPhase = state.message?.id === id ? state.message.phase : undefined;
return Lifecycle.textEnd(lifecycle, events, id, providerMetadata(state, { itemId: id, ...(openPhase === undefined ? {} : { phase: openPhase }) }));
}, state.lifecycle);
const nextPhase = phase === undefined ? state.messagePhases[itemID] : phase;
return [

@@ -735,4 +726,6 @@ {

lifecycle,
messageItems: new Set([itemID]),
messagePhases: nextPhase === undefined ? {} : { [itemID]: nextPhase },
message: {
id: itemID,
phase: phase === undefined && state.message?.id === itemID ? state.message.phase : phase,
},
},

@@ -753,2 +746,3 @@ events,

[item.id]: {
open: true,
encryptedContent: item.encrypted_content,

@@ -766,4 +760,2 @@ summaryParts: { 0: "active" },

const id = item.id ?? item.call_id;
// Pending tools always store the call id, so this also catches duplicates
// that disagree on whether `item.id` is present.
if (Object.values(state.tools).some((tool) => tool?.id === item.call_id) || state.completedTools.has(item.call_id))

@@ -797,3 +789,3 @@ return [state, NO_EVENTS];

const item = state.reasoningItems[event.item_id];
if (!item)
if (!item?.open)
return [state, NO_EVENTS];

@@ -850,7 +842,4 @@ if (item.summaryParts[event.summary_index] !== "active")

const itemPhase = messagePhase(item.phase);
const phase = itemPhase === undefined ? state.messagePhases[item.id] : itemPhase;
const phase = itemPhase === undefined && state.message?.id === item.id ? state.message.phase : itemPhase;
const events = [];
const messageItems = new Set(state.messageItems);
messageItems.delete(item.id);
const { [item.id]: _phase, ...messagePhases } = state.messagePhases;
return [

@@ -860,4 +849,3 @@ {

lifecycle: Lifecycle.textEnd(state.lifecycle, events, item.id, providerMetadata(state, { itemId: item.id, ...(phase === undefined ? {} : { phase }) })),
messageItems,
messagePhases,
message: state.message?.id === item.id ? undefined : state.message,
},

@@ -916,7 +904,7 @@ events,

if (reasoningItem) {
if (!reasoningItem.open)
return [state, NO_EVENTS];
const lifecycle = Object.entries(reasoningItem.summaryParts)
.filter((entry) => entry[1] === "active" || entry[1] === "can-conclude")
.reduce((lifecycle, entry) => Lifecycle.reasoningEnd(lifecycle, events, `${item.id}:${entry[0]}`, metadata), state.lifecycle);
// Keep the fully-concluded entry so duplicate or late events for this
// item remain no-ops instead of reopening lifecycle state.
return [

@@ -930,4 +918,4 @@ {

...reasoningItem,
open: false,
encryptedContent: item.encrypted_content ?? reasoningItem.encryptedContent,
summaryParts: Object.fromEntries(Object.keys(reasoningItem.summaryParts).map((index) => [index, "concluded"])),
},

@@ -950,2 +938,3 @@ },

[item.id]: {
open: false,
encryptedContent: item.encrypted_content,

@@ -973,3 +962,3 @@ summaryParts: { 0: "concluded" },

((item.type !== "function_call" || !current.tools[id]) &&
(item.type !== "reasoning" || !current.reasoningItems[id])))
(item.type !== "reasoning" || !current.reasoningItems[id]?.open)))
return Effect.succeed([current, events]);

@@ -1119,4 +1108,3 @@ return onOutputItemDone(current, { type: "response.output_item.done", item }).pipe(Effect.map(([next, emitted]) => [next, [...events, ...emitted]]));

outputItems: {},
messageItems: new Set(),
messagePhases: {},
message: undefined,
reasoningItems: {},

@@ -1123,0 +1111,0 @@ });

{
"$schema": "https://json.schemastore.org/package.json",
"version": "0.0.0-dev-18548",
"version": "0.0.0-dev-18549",
"name": "@opencode-ai/ai",

@@ -33,3 +33,3 @@ "type": "module",

"@effect/platform-node": "4.0.0-rc.112",
"@opencode-ai/http-recorder": "0.0.0-dev-18548",
"@opencode-ai/http-recorder": "0.0.0-dev-18549",
"@tsconfig/bun": "1.0.9",

@@ -43,3 +43,3 @@ "@types/bun": "1.3.13",

"@smithy/util-utf8": "4.2.2",
"@opencode-ai/schema": "0.0.0-dev-18548",
"@opencode-ai/schema": "0.0.0-dev-18549",
"aws4fetch": "1.0.20",

@@ -46,0 +46,0 @@ "effect": "4.0.0-rc.112",