@effect-uai/ai-sdk 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/UIMessageStream.d.mts.map +1 -1
- package/dist/UIMessageStream.mjs +2 -0
- package/dist/UIMessageStream.mjs.map +1 -1
- package/dist/UIMessageStream.test.mjs +1 -1
- package/dist/conformance.test.mjs +1 -1
- package/dist/{dist-DaKrk-s5.mjs → dist-DDciKZ0w.mjs} +74 -33
- package/dist/dist-DDciKZ0w.mjs.map +1 -0
- package/package.json +4 -4
- package/src/UIMessageStream.ts +4 -0
- package/dist/dist-DaKrk-s5.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UIMessageStream.d.mts","names":[],"sources":["../src/UIMessageStream.ts"],"mappings":";;;;;;;;;;;;KAyBY,IAAA;EAAA,SACG,IAAA;EAAA,SAAwB,SAAA;AAAA;EAAA,SACxB,IAAA;EAAA,SAA6B,EAAA;AAAA;EAAA,SAC7B,IAAA;EAAA,SAA6B,EAAA;EAAA,SAAqB,KAAA;AAAA;EAAA,SAClD,IAAA;EAAA,SAA2B,EAAA;AAAA;EAAA,SAC3B,IAAA;EAAA,SAAkC,EAAA;AAAA;EAAA,SAClC,IAAA;EAAA,SAAkC,EAAA;EAAA,SAAqB,KAAA;AAAA;EAAA,SACvD,IAAA;EAAA,SAAgC,EAAA;AAAA;EAAA,SAChC,IAAA;EAAA,SAAmC,UAAA;EAAA,SAA6B,QAAA;AAAA;EAAA,SAEhE,IAAA;EAAA,SACA,UAAA;EAAA,SACA,cAAA;AAAA;EAAA,SAGA,IAAA;EAAA,SACA,UAAA;EAAA,SACA,QAAA;EAAA,SACA,KAAA;AAAA;EAAA,SAGA,IAAA;EAAA,SACA,UAAA;EAAA,SACA,MAAA;AAAA;EAAA,SAGA,IAAA;EAAA,SACA,EAAA;EAAA,SACA,IAAA;EAAA,SACA,SAAA;AAAA;EAAA,SAEA,IAAA;EAAA,SAAmC,eAAA;AAAA;EAAA,SACnC,IAAA;EAAA,SAAwB,SAAA;AAAA;EAAA,SACxB,IAAA;AAAA;;;;;;KAOH,YAAA;EAAA,SACD,IAAA;EAAA,SACA,IAAA;EAAA,SACA,IAAA;EAAA,SACA,EAAA;EAAA,SACA,SAAA;AAAA;AAgBX;AAAA,KAZY,gBAAA;EAAA,SACD,IAAA;EAAA,SACA,QAAA;AAAA;;;;;KAOC,QAAA,GAAW,IAAA,CAAK,gBAAA,GAAmB,YAAA,GAAe,gBAAA;;cAGjD,QAAA,GACX,IAAA,UACA,IAAA,WACA,OAAA;EAAA,SAAqB,EAAA;EAAA,SAAsB,SAAA;AAAA,MAC1C,YAAA;;cAGU,eAAA,GAAmB,QAAA,cAAoB,gBAAA;AAYpD;;;;;
|
|
1
|
+
{"version":3,"file":"UIMessageStream.d.mts","names":[],"sources":["../src/UIMessageStream.ts"],"mappings":";;;;;;;;;;;;KAyBY,IAAA;EAAA,SACG,IAAA;EAAA,SAAwB,SAAA;AAAA;EAAA,SACxB,IAAA;EAAA,SAA6B,EAAA;AAAA;EAAA,SAC7B,IAAA;EAAA,SAA6B,EAAA;EAAA,SAAqB,KAAA;AAAA;EAAA,SAClD,IAAA;EAAA,SAA2B,EAAA;AAAA;EAAA,SAC3B,IAAA;EAAA,SAAkC,EAAA;AAAA;EAAA,SAClC,IAAA;EAAA,SAAkC,EAAA;EAAA,SAAqB,KAAA;AAAA;EAAA,SACvD,IAAA;EAAA,SAAgC,EAAA;AAAA;EAAA,SAChC,IAAA;EAAA,SAAmC,UAAA;EAAA,SAA6B,QAAA;AAAA;EAAA,SAEhE,IAAA;EAAA,SACA,UAAA;EAAA,SACA,cAAA;AAAA;EAAA,SAGA,IAAA;EAAA,SACA,UAAA;EAAA,SACA,QAAA;EAAA,SACA,KAAA;AAAA;EAAA,SAGA,IAAA;EAAA,SACA,UAAA;EAAA,SACA,MAAA;AAAA;EAAA,SAGA,IAAA;EAAA,SACA,EAAA;EAAA,SACA,IAAA;EAAA,SACA,SAAA;AAAA;EAAA,SAEA,IAAA;EAAA,SAAmC,eAAA;AAAA;EAAA,SACnC,IAAA;EAAA,SAAwB,SAAA;AAAA;EAAA,SACxB,IAAA;AAAA;;;;;;KAOH,YAAA;EAAA,SACD,IAAA;EAAA,SACA,IAAA;EAAA,SACA,IAAA;EAAA,SACA,EAAA;EAAA,SACA,SAAA;AAAA;AAgBX;AAAA,KAZY,gBAAA;EAAA,SACD,IAAA;EAAA,SACA,QAAA;AAAA;;;;;KAOC,QAAA,GAAW,IAAA,CAAK,gBAAA,GAAmB,YAAA,GAAe,gBAAA;;cAGjD,QAAA,GACX,IAAA,UACA,IAAA,WACA,OAAA;EAAA,SAAqB,EAAA;EAAA,SAAsB,SAAA;AAAA,MAC1C,YAAA;;cAGU,eAAA,GAAmB,QAAA,cAAoB,gBAAA;AAYpD;;;;;AAoHA;;AApHA,cAAa,eAAA,EAAiB,MAAA;;;;;;cAoHjB,iBAAA,GACV,SAAA,oBACM,IAAA,EAAM,MAAA,CAAO,MAAA,CAAO,QAAA,EAAU,CAAA,EAAG,CAAA,MAAK,MAAA,CAAO,MAAA,CAAO,GAAA,CAAI,KAAA,EAAO,CAAA,EAAG,CAAA"}
|
package/dist/UIMessageStream.mjs
CHANGED
|
@@ -106,6 +106,8 @@ const step = (s, ev) => Match.value(ev).pipe(Match.tags({
|
|
|
106
106
|
errorText: e.text
|
|
107
107
|
}]],
|
|
108
108
|
UsageUpdate: () => [s, []],
|
|
109
|
+
WebSearchCall: () => [s, []],
|
|
110
|
+
CitationAdded: () => [s, []],
|
|
109
111
|
TurnComplete: (e) => {
|
|
110
112
|
const closing = [
|
|
111
113
|
...s.textId !== null ? [{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UIMessageStream.mjs","names":[],"sources":["../src/UIMessageStream.ts"],"sourcesContent":["/**\n * Project an effect-uai loop onto the Vercel AI SDK \"UI Message Stream\"\n * protocol (the `v1` wire format, stable across AI SDK v5–v7). The output is a\n * `Stream<SSE.Event>` ready for `SSE.toBytes`; a `useChat` client on the other\n * end consumes it with no frontend changes.\n *\n * The encoder input is an `Emission`: every `InteractionEvent` the loop\n * produces, plus optional `dataPart` and `messageMetadata` emissions a caller\n * interleaves to stream custom typed data (e.g. live metrics) and settled\n * per-message metadata (e.g. usage). A plain `Stream<InteractionEvent>` is a\n * valid `Stream<Emission>`, so existing callers are unaffected.\n *\n * The protocol wants a stable id and explicit start/end lifecycle around each\n * text and reasoning block, which effect-uai's delta events don't carry. This\n * module synthesizes them: one block id per turn, opened on the first delta\n * and closed on `TurnComplete`.\n */\nimport type * as SSE from \"@effect-uai/core/SSE\"\nimport * as Turn from \"@effect-uai/core/Turn\"\nimport { Match, Option, Stream } from \"effect\"\n\n/**\n * The stream parts `useChat` consumes. Names and shapes are the wire\n * contract with the AI SDK client; keep them literal.\n */\nexport type Part =\n | { readonly type: \"start\"; readonly messageId: string }\n | { readonly type: \"text-start\"; readonly id: string }\n | { readonly type: \"text-delta\"; readonly id: string; readonly delta: string }\n | { readonly type: \"text-end\"; readonly id: string }\n | { readonly type: \"reasoning-start\"; readonly id: string }\n | { readonly type: \"reasoning-delta\"; readonly id: string; readonly delta: string }\n | { readonly type: \"reasoning-end\"; readonly id: string }\n | { readonly type: \"tool-input-start\"; readonly toolCallId: string; readonly toolName: string }\n | {\n readonly type: \"tool-input-delta\"\n readonly toolCallId: string\n readonly inputTextDelta: string\n }\n | {\n readonly type: \"tool-input-available\"\n readonly toolCallId: string\n readonly toolName: string\n readonly input: unknown\n }\n | {\n readonly type: \"tool-output-available\"\n readonly toolCallId: string\n readonly output: unknown\n }\n | {\n readonly type: `data-${string}`\n readonly id?: string\n readonly data: unknown\n readonly transient?: boolean\n }\n | { readonly type: \"message-metadata\"; readonly messageMetadata: unknown }\n | { readonly type: \"error\"; readonly errorText: string }\n | { readonly type: \"finish\" }\n\n/**\n * A custom typed data part (`data-<name>`). `transient: true` delivers it to\n * the client's `onData` callback only (not persisted into `message.parts`);\n * reuse an `id` across emissions to reconcile/update one part in place.\n */\nexport type DataEmission = {\n readonly kind: \"data\"\n readonly name: string\n readonly data: unknown\n readonly id?: string\n readonly transient?: boolean\n}\n\n/** Settled per-message metadata, surfaced as `message.metadata` on the client. */\nexport type MetadataEmission = {\n readonly kind: \"metadata\"\n readonly metadata: unknown\n}\n\n/**\n * What `toUIMessageStream` encodes: loop `InteractionEvent`s plus optional\n * data / metadata emissions a caller interleaves into the stream.\n */\nexport type Emission = Turn.InteractionEvent | DataEmission | MetadataEmission\n\n/** Construct a `data-<name>` emission. See {@link DataEmission}. */\nexport const dataPart = (\n name: string,\n data: unknown,\n options?: { readonly id?: string; readonly transient?: boolean },\n): DataEmission => ({ kind: \"data\", name, data, ...options })\n\n/** Construct a message-metadata emission. See {@link MetadataEmission}. */\nexport const messageMetadata = (metadata: unknown): MetadataEmission => ({\n kind: \"metadata\",\n metadata,\n})\n\n/**\n * Headers the UI Message Stream protocol requires on the HTTP response.\n * `x-vercel-ai-ui-message-stream: v1` is mandatory; without it the client\n * falls back to the plain text-stream protocol and ignores non-text parts.\n * Pure data, so it composes with any server (web `Response`, `@effect/platform`\n * `HttpServerResponse`, raw Node) - the package deliberately owns no HTTP layer.\n */\nexport const responseHeaders: Record<string, string> = {\n \"content-type\": \"text/event-stream\",\n \"cache-control\": \"no-cache\",\n connection: \"keep-alive\",\n \"x-vercel-ai-ui-message-stream\": \"v1\",\n}\n\nconst parseJson = Option.liftThrowable(JSON.parse)\n\n// Tool arguments/output cross effect-uai as JSON strings; hand the client the\n// decoded value, falling back to the raw string when it isn't JSON.\nconst decode = (raw: string): unknown => Option.getOrElse(parseJson(raw), () => raw)\n\nconst event = (part: Part | \"[DONE]\"): SSE.Event => ({\n data: part === \"[DONE]\" ? \"[DONE]\" : JSON.stringify(part),\n})\n\ntype State = {\n readonly messageId: string\n readonly textId: string | null\n readonly reasoningId: string | null\n readonly seq: number\n}\n\ntype Step = readonly [State, ReadonlyArray<Part>]\n\nconst toDataPart = (d: DataEmission): Part => {\n const base: Part = { type: `data-${d.name}`, data: d.data }\n const withId = d.id !== undefined ? { ...base, id: d.id } : base\n return d.transient !== undefined ? { ...withId, transient: d.transient } : withId\n}\n\n// One emission fans out to zero or more parts (a first TextDelta opens a block\n// *and* emits its delta), so each step yields an array.\nconst step = (s: State, ev: Emission): Step =>\n Match.value(ev).pipe(\n Match.tags({\n TextDelta: (e): Step => {\n if (s.textId !== null) return [s, [{ type: \"text-delta\", id: s.textId, delta: e.text }]]\n const id = `${s.messageId}:t${s.seq}`\n return [\n { ...s, textId: id, seq: s.seq + 1 },\n [\n { type: \"text-start\", id },\n { type: \"text-delta\", id, delta: e.text },\n ],\n ]\n },\n ReasoningDelta: (e): Step => {\n if (s.reasoningId !== null)\n return [s, [{ type: \"reasoning-delta\", id: s.reasoningId, delta: e.text }]]\n const id = `${s.messageId}:r${s.seq}`\n return [\n { ...s, reasoningId: id, seq: s.seq + 1 },\n [\n { type: \"reasoning-start\", id },\n { type: \"reasoning-delta\", id, delta: e.text },\n ],\n ]\n },\n ToolCallStart: (e): Step => [\n s,\n [{ type: \"tool-input-start\", toolCallId: e.call_id, toolName: e.name }],\n ],\n ToolCallArgsDelta: (e): Step => [\n s,\n [{ type: \"tool-input-delta\", toolCallId: e.call_id, inputTextDelta: e.delta }],\n ],\n RefusalDelta: (e): Step => [s, [{ type: \"error\", errorText: e.text }]],\n UsageUpdate: (): Step => [s, []],\n TurnComplete: (e): Step => {\n const closing: ReadonlyArray<Part> = [\n ...(s.textId !== null ? [{ type: \"text-end\", id: s.textId } as const] : []),\n ...(s.reasoningId !== null\n ? [{ type: \"reasoning-end\", id: s.reasoningId } as const]\n : []),\n ...Turn.getToolCalls(e.turn).map(\n (call): Part => ({\n type: \"tool-input-available\",\n toolCallId: call.call_id,\n toolName: call.name,\n input: decode(call.arguments),\n }),\n ),\n ]\n // Reset block ids; the loop may run further turns after tools resolve.\n return [{ ...s, textId: null, reasoningId: null }, closing]\n },\n }),\n // The non-`_tag` arm of InteractionEvent: a resolved tool result the loop\n // appended after running the tool.\n Match.when(\n { type: \"function_call_output\" },\n (o): Step => [\n s,\n [{ type: \"tool-output-available\", toolCallId: o.call_id, output: decode(o.output) }],\n ],\n ),\n // Caller-interleaved emissions.\n Match.when({ kind: \"data\" }, (d): Step => [s, [toDataPart(d)]]),\n Match.when(\n { kind: \"metadata\" },\n (m): Step => [s, [{ type: \"message-metadata\", messageMetadata: m.metadata }]],\n ),\n Match.exhaustive,\n )\n\n/**\n * Encode an `InteractionEvent` stream as UI Message Stream `SSE.Event`s,\n * bracketed by the protocol's `start` and terminal `finish` / `[DONE]`\n * markers. `messageId` identifies the assistant message on the client.\n */\nexport const toUIMessageStream =\n (messageId: string) =>\n <E, R>(self: Stream.Stream<Emission, E, R>): Stream.Stream<SSE.Event, E, R> =>\n Stream.make(event({ type: \"start\", messageId })).pipe(\n Stream.concat(\n Stream.mapAccum(\n self,\n (): State => ({ messageId, textId: null, reasoningId: null, seq: 0 }),\n (s, ev: Emission): readonly [State, ReadonlyArray<SSE.Event>] => {\n const [next, parts] = step(s, ev)\n return [next, parts.map(event)]\n },\n ),\n ),\n Stream.concat(Stream.make(event({ type: \"finish\" }), event(\"[DONE]\"))),\n )\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"UIMessageStream.mjs","names":[],"sources":["../src/UIMessageStream.ts"],"sourcesContent":["/**\n * Project an effect-uai loop onto the Vercel AI SDK \"UI Message Stream\"\n * protocol (the `v1` wire format, stable across AI SDK v5–v7). The output is a\n * `Stream<SSE.Event>` ready for `SSE.toBytes`; a `useChat` client on the other\n * end consumes it with no frontend changes.\n *\n * The encoder input is an `Emission`: every `InteractionEvent` the loop\n * produces, plus optional `dataPart` and `messageMetadata` emissions a caller\n * interleaves to stream custom typed data (e.g. live metrics) and settled\n * per-message metadata (e.g. usage). A plain `Stream<InteractionEvent>` is a\n * valid `Stream<Emission>`, so existing callers are unaffected.\n *\n * The protocol wants a stable id and explicit start/end lifecycle around each\n * text and reasoning block, which effect-uai's delta events don't carry. This\n * module synthesizes them: one block id per turn, opened on the first delta\n * and closed on `TurnComplete`.\n */\nimport type * as SSE from \"@effect-uai/core/SSE\"\nimport * as Turn from \"@effect-uai/core/Turn\"\nimport { Match, Option, Stream } from \"effect\"\n\n/**\n * The stream parts `useChat` consumes. Names and shapes are the wire\n * contract with the AI SDK client; keep them literal.\n */\nexport type Part =\n | { readonly type: \"start\"; readonly messageId: string }\n | { readonly type: \"text-start\"; readonly id: string }\n | { readonly type: \"text-delta\"; readonly id: string; readonly delta: string }\n | { readonly type: \"text-end\"; readonly id: string }\n | { readonly type: \"reasoning-start\"; readonly id: string }\n | { readonly type: \"reasoning-delta\"; readonly id: string; readonly delta: string }\n | { readonly type: \"reasoning-end\"; readonly id: string }\n | { readonly type: \"tool-input-start\"; readonly toolCallId: string; readonly toolName: string }\n | {\n readonly type: \"tool-input-delta\"\n readonly toolCallId: string\n readonly inputTextDelta: string\n }\n | {\n readonly type: \"tool-input-available\"\n readonly toolCallId: string\n readonly toolName: string\n readonly input: unknown\n }\n | {\n readonly type: \"tool-output-available\"\n readonly toolCallId: string\n readonly output: unknown\n }\n | {\n readonly type: `data-${string}`\n readonly id?: string\n readonly data: unknown\n readonly transient?: boolean\n }\n | { readonly type: \"message-metadata\"; readonly messageMetadata: unknown }\n | { readonly type: \"error\"; readonly errorText: string }\n | { readonly type: \"finish\" }\n\n/**\n * A custom typed data part (`data-<name>`). `transient: true` delivers it to\n * the client's `onData` callback only (not persisted into `message.parts`);\n * reuse an `id` across emissions to reconcile/update one part in place.\n */\nexport type DataEmission = {\n readonly kind: \"data\"\n readonly name: string\n readonly data: unknown\n readonly id?: string\n readonly transient?: boolean\n}\n\n/** Settled per-message metadata, surfaced as `message.metadata` on the client. */\nexport type MetadataEmission = {\n readonly kind: \"metadata\"\n readonly metadata: unknown\n}\n\n/**\n * What `toUIMessageStream` encodes: loop `InteractionEvent`s plus optional\n * data / metadata emissions a caller interleaves into the stream.\n */\nexport type Emission = Turn.InteractionEvent | DataEmission | MetadataEmission\n\n/** Construct a `data-<name>` emission. See {@link DataEmission}. */\nexport const dataPart = (\n name: string,\n data: unknown,\n options?: { readonly id?: string; readonly transient?: boolean },\n): DataEmission => ({ kind: \"data\", name, data, ...options })\n\n/** Construct a message-metadata emission. See {@link MetadataEmission}. */\nexport const messageMetadata = (metadata: unknown): MetadataEmission => ({\n kind: \"metadata\",\n metadata,\n})\n\n/**\n * Headers the UI Message Stream protocol requires on the HTTP response.\n * `x-vercel-ai-ui-message-stream: v1` is mandatory; without it the client\n * falls back to the plain text-stream protocol and ignores non-text parts.\n * Pure data, so it composes with any server (web `Response`, `@effect/platform`\n * `HttpServerResponse`, raw Node) - the package deliberately owns no HTTP layer.\n */\nexport const responseHeaders: Record<string, string> = {\n \"content-type\": \"text/event-stream\",\n \"cache-control\": \"no-cache\",\n connection: \"keep-alive\",\n \"x-vercel-ai-ui-message-stream\": \"v1\",\n}\n\nconst parseJson = Option.liftThrowable(JSON.parse)\n\n// Tool arguments/output cross effect-uai as JSON strings; hand the client the\n// decoded value, falling back to the raw string when it isn't JSON.\nconst decode = (raw: string): unknown => Option.getOrElse(parseJson(raw), () => raw)\n\nconst event = (part: Part | \"[DONE]\"): SSE.Event => ({\n data: part === \"[DONE]\" ? \"[DONE]\" : JSON.stringify(part),\n})\n\ntype State = {\n readonly messageId: string\n readonly textId: string | null\n readonly reasoningId: string | null\n readonly seq: number\n}\n\ntype Step = readonly [State, ReadonlyArray<Part>]\n\nconst toDataPart = (d: DataEmission): Part => {\n const base: Part = { type: `data-${d.name}`, data: d.data }\n const withId = d.id !== undefined ? { ...base, id: d.id } : base\n return d.transient !== undefined ? { ...withId, transient: d.transient } : withId\n}\n\n// One emission fans out to zero or more parts (a first TextDelta opens a block\n// *and* emits its delta), so each step yields an array.\nconst step = (s: State, ev: Emission): Step =>\n Match.value(ev).pipe(\n Match.tags({\n TextDelta: (e): Step => {\n if (s.textId !== null) return [s, [{ type: \"text-delta\", id: s.textId, delta: e.text }]]\n const id = `${s.messageId}:t${s.seq}`\n return [\n { ...s, textId: id, seq: s.seq + 1 },\n [\n { type: \"text-start\", id },\n { type: \"text-delta\", id, delta: e.text },\n ],\n ]\n },\n ReasoningDelta: (e): Step => {\n if (s.reasoningId !== null)\n return [s, [{ type: \"reasoning-delta\", id: s.reasoningId, delta: e.text }]]\n const id = `${s.messageId}:r${s.seq}`\n return [\n { ...s, reasoningId: id, seq: s.seq + 1 },\n [\n { type: \"reasoning-start\", id },\n { type: \"reasoning-delta\", id, delta: e.text },\n ],\n ]\n },\n ToolCallStart: (e): Step => [\n s,\n [{ type: \"tool-input-start\", toolCallId: e.call_id, toolName: e.name }],\n ],\n ToolCallArgsDelta: (e): Step => [\n s,\n [{ type: \"tool-input-delta\", toolCallId: e.call_id, inputTextDelta: e.delta }],\n ],\n RefusalDelta: (e): Step => [s, [{ type: \"error\", errorText: e.text }]],\n UsageUpdate: (): Step => [s, []],\n // Grounding progress and streamed citations have no UI Message Stream\n // part; the citations still arrive on `TurnComplete.turn`.\n WebSearchCall: (): Step => [s, []],\n CitationAdded: (): Step => [s, []],\n TurnComplete: (e): Step => {\n const closing: ReadonlyArray<Part> = [\n ...(s.textId !== null ? [{ type: \"text-end\", id: s.textId } as const] : []),\n ...(s.reasoningId !== null\n ? [{ type: \"reasoning-end\", id: s.reasoningId } as const]\n : []),\n ...Turn.getToolCalls(e.turn).map(\n (call): Part => ({\n type: \"tool-input-available\",\n toolCallId: call.call_id,\n toolName: call.name,\n input: decode(call.arguments),\n }),\n ),\n ]\n // Reset block ids; the loop may run further turns after tools resolve.\n return [{ ...s, textId: null, reasoningId: null }, closing]\n },\n }),\n // The non-`_tag` arm of InteractionEvent: a resolved tool result the loop\n // appended after running the tool.\n Match.when(\n { type: \"function_call_output\" },\n (o): Step => [\n s,\n [{ type: \"tool-output-available\", toolCallId: o.call_id, output: decode(o.output) }],\n ],\n ),\n // Caller-interleaved emissions.\n Match.when({ kind: \"data\" }, (d): Step => [s, [toDataPart(d)]]),\n Match.when(\n { kind: \"metadata\" },\n (m): Step => [s, [{ type: \"message-metadata\", messageMetadata: m.metadata }]],\n ),\n Match.exhaustive,\n )\n\n/**\n * Encode an `InteractionEvent` stream as UI Message Stream `SSE.Event`s,\n * bracketed by the protocol's `start` and terminal `finish` / `[DONE]`\n * markers. `messageId` identifies the assistant message on the client.\n */\nexport const toUIMessageStream =\n (messageId: string) =>\n <E, R>(self: Stream.Stream<Emission, E, R>): Stream.Stream<SSE.Event, E, R> =>\n Stream.make(event({ type: \"start\", messageId })).pipe(\n Stream.concat(\n Stream.mapAccum(\n self,\n (): State => ({ messageId, textId: null, reasoningId: null, seq: 0 }),\n (s, ev: Emission): readonly [State, ReadonlyArray<SSE.Event>] => {\n const [next, parts] = step(s, ev)\n return [next, parts.map(event)]\n },\n ),\n ),\n Stream.concat(Stream.make(event({ type: \"finish\" }), event(\"[DONE]\"))),\n )\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { decodeMessages } from "./Messages.mjs";
|
|
2
|
-
import { n as globalExpect, r as describe, t as it } from "./dist-
|
|
2
|
+
import { n as globalExpect, r as describe, t as it } from "./dist-DDciKZ0w.mjs";
|
|
3
3
|
import { dataPart, messageMetadata, toUIMessageStream } from "./UIMessageStream.mjs";
|
|
4
4
|
import * as Image from "@effect-uai/core/Image";
|
|
5
5
|
import * as Items from "@effect-uai/core/Items";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as globalExpect, r as describe, t as it } from "./dist-
|
|
1
|
+
import { n as globalExpect, r as describe, t as it } from "./dist-DDciKZ0w.mjs";
|
|
2
2
|
import { toUIMessageStream } from "./UIMessageStream.mjs";
|
|
3
3
|
import * as Items from "@effect-uai/core/Items";
|
|
4
4
|
import { Array as Array$1, Effect, Option, Stream } from "effect";
|
|
@@ -5119,7 +5119,7 @@ function manageArtifactAttachment(attachment) {
|
|
|
5119
5119
|
if (attachment.body != null) attachment.bodyEncoding ??= "base64";
|
|
5120
5120
|
}
|
|
5121
5121
|
//#endregion
|
|
5122
|
-
//#region ../../../node_modules/.pnpm/vitest@4.1.5_@types+node@25.6.0_vite@7.3.2_@types+node@25.6.0_jiti@2.6.1_lightningcss@1.32.0_tsx@4.21.0_yaml@2.
|
|
5122
|
+
//#region ../../../node_modules/.pnpm/vitest@4.1.5_@types+node@25.6.0_vite@7.3.2_@types+node@25.6.0_jiti@2.6.1_lightningcss@1.32.0_tsx@4.21.0_yaml@2.9.0_/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.js
|
|
5123
5123
|
const NAME_WORKER_STATE = "__vitest_worker__";
|
|
5124
5124
|
function getWorkerState() {
|
|
5125
5125
|
const workerState = globalThis[NAME_WORKER_STATE];
|
|
@@ -9998,10 +9998,10 @@ function offsetToLineNumber(source, offset) {
|
|
|
9998
9998
|
return line + 1;
|
|
9999
9999
|
}
|
|
10000
10000
|
//#endregion
|
|
10001
|
-
//#region ../../../node_modules/.pnpm/vitest@4.1.5_@types+node@25.6.0_vite@7.3.2_@types+node@25.6.0_jiti@2.6.1_lightningcss@1.32.0_tsx@4.21.0_yaml@2.
|
|
10001
|
+
//#region ../../../node_modules/.pnpm/vitest@4.1.5_@types+node@25.6.0_vite@7.3.2_@types+node@25.6.0_jiti@2.6.1_lightningcss@1.32.0_tsx@4.21.0_yaml@2.9.0_/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.js
|
|
10002
10002
|
var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
|
|
10003
10003
|
//#endregion
|
|
10004
|
-
//#region ../../../node_modules/.pnpm/vitest@4.1.5_@types+node@25.6.0_vite@7.3.2_@types+node@25.6.0_jiti@2.6.1_lightningcss@1.32.0_tsx@4.21.0_yaml@2.
|
|
10004
|
+
//#region ../../../node_modules/.pnpm/vitest@4.1.5_@types+node@25.6.0_vite@7.3.2_@types+node@25.6.0_jiti@2.6.1_lightningcss@1.32.0_tsx@4.21.0_yaml@2.9.0_/node_modules/vitest/dist/chunks/rpc.MzXet3jl.js
|
|
10005
10005
|
const RealDate = Date;
|
|
10006
10006
|
let now = null;
|
|
10007
10007
|
var MockDate = class MockDate extends RealDate {
|
|
@@ -10964,7 +10964,7 @@ function raceWith(promise, other) {
|
|
|
10964
10964
|
}))]);
|
|
10965
10965
|
}
|
|
10966
10966
|
//#endregion
|
|
10967
|
-
//#region ../../../node_modules/.pnpm/vitest@4.1.5_@types+node@25.6.0_vite@7.3.2_@types+node@25.6.0_jiti@2.6.1_lightningcss@1.32.0_tsx@4.21.0_yaml@2.
|
|
10967
|
+
//#region ../../../node_modules/.pnpm/vitest@4.1.5_@types+node@25.6.0_vite@7.3.2_@types+node@25.6.0_jiti@2.6.1_lightningcss@1.32.0_tsx@4.21.0_yaml@2.9.0_/node_modules/vitest/dist/chunks/test.DNmyFkvJ.js
|
|
10968
10968
|
var fakeTimersSrc = {};
|
|
10969
10969
|
var global$1;
|
|
10970
10970
|
var hasRequiredGlobal;
|
|
@@ -13641,9 +13641,9 @@ Object.defineProperty(globalThis, GLOBAL_EXPECT, {
|
|
|
13641
13641
|
configurable: true
|
|
13642
13642
|
});
|
|
13643
13643
|
//#endregion
|
|
13644
|
-
//#region ../../../node_modules/.pnpm/@effect+vitest@4.0.0-beta.
|
|
13644
|
+
//#region ../../../node_modules/.pnpm/@effect+vitest@4.0.0-beta.94_effect@4.0.0-beta.94_vitest@4.1.5_@types+node@25.6.0_vite@_d376dad414e93cb5624154e275002f20/node_modules/@effect/vitest/dist/internal/internal.js
|
|
13645
13645
|
/**
|
|
13646
|
-
* @since
|
|
13646
|
+
* @since 4.0.0
|
|
13647
13647
|
*/
|
|
13648
13648
|
const runPromise = /* @__PURE__ */ Effect.fnUntraced(function* (effect, _ctx) {
|
|
13649
13649
|
const exit = yield* Effect.exit(effect);
|
|
@@ -13658,6 +13658,25 @@ const runTest = (ctx) => (effect) => runPromise(effect, ctx);
|
|
|
13658
13658
|
const TestEnv = /* @__PURE__ */ Layer.mergeAll(TestConsole.layer, /* @__PURE__ */ TestClock.layer());
|
|
13659
13659
|
/** @internal */
|
|
13660
13660
|
const testOptions = (timeout) => typeof timeout === "number" ? { timeout } : timeout ?? {};
|
|
13661
|
+
const hookTimeout = (timeout) => timeout === void 0 ? void 0 : Duration.toMillis(Duration.fromInputUnsafe(timeout));
|
|
13662
|
+
const makeItProxy = (it, overrides) => new Proxy(it, {
|
|
13663
|
+
apply(target, thisArg, argArray) {
|
|
13664
|
+
return Reflect.apply(target, thisArg, argArray);
|
|
13665
|
+
},
|
|
13666
|
+
get(target, property, receiver) {
|
|
13667
|
+
if (property in overrides) return Reflect.get(overrides, property);
|
|
13668
|
+
const value = Reflect.get(target, property, receiver);
|
|
13669
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
13670
|
+
}
|
|
13671
|
+
});
|
|
13672
|
+
const collectTasks = (tasks, acc = []) => {
|
|
13673
|
+
for (let i = 0; i < tasks.length; i++) {
|
|
13674
|
+
const task = tasks[i];
|
|
13675
|
+
if (task.type === "test" && task.mode !== "skip" && task.mode !== "todo") acc.push(task);
|
|
13676
|
+
else if (task.tasks !== void 0) collectTasks(task.tasks, acc);
|
|
13677
|
+
}
|
|
13678
|
+
return acc;
|
|
13679
|
+
};
|
|
13661
13680
|
/** @internal */
|
|
13662
13681
|
const makeTester = (mapEffect, it = it$1) => {
|
|
13663
13682
|
const run = (ctx, args, self) => pipe(Effect.suspend(() => self(...args)), mapEffect, runTest(ctx));
|
|
@@ -13695,7 +13714,7 @@ const makeTester = (mapEffect, it = it$1) => {
|
|
|
13695
13714
|
});
|
|
13696
13715
|
};
|
|
13697
13716
|
/** @internal */
|
|
13698
|
-
const prop
|
|
13717
|
+
const prop = (name, arbitraries, self, timeout) => {
|
|
13699
13718
|
if (Array.isArray(arbitraries)) {
|
|
13700
13719
|
const arbs = arbitraries.map((arbitrary) => {
|
|
13701
13720
|
if (Schema.isSchema(arbitrary)) throw new Error("Schemas are not supported yet");
|
|
@@ -13712,58 +13731,80 @@ const prop$1 = (name, arbitraries, self, timeout) => {
|
|
|
13712
13731
|
return it$1(name, testOptions(timeout), (ctx) => fc.assert(fc.property(arbs, (as) => self(as, ctx)), isObject(timeout) ? timeout?.fastCheck : {}));
|
|
13713
13732
|
};
|
|
13714
13733
|
/** @internal */
|
|
13715
|
-
const layer
|
|
13734
|
+
const layer = (layer_, options) => (...args) => {
|
|
13716
13735
|
const excludeTestServices = options?.excludeTestServices ?? false;
|
|
13717
13736
|
const withTestEnv = excludeTestServices ? layer_ : Layer.provideMerge(layer_, TestEnv);
|
|
13718
13737
|
const memoMap = options?.memoMap ?? Effect.runSync(Layer.makeMemoMap);
|
|
13719
13738
|
const scope = Effect.runSync(Scope.make());
|
|
13720
13739
|
const contextEffect = Layer.buildWithMemoMap(withTestEnv, memoMap, scope).pipe(Effect.orDie, Effect.cached, Effect.runSync);
|
|
13721
|
-
|
|
13740
|
+
let closed = false;
|
|
13741
|
+
const closeScope = (ctx) => {
|
|
13742
|
+
if (closed) return Promise.resolve();
|
|
13743
|
+
closed = true;
|
|
13744
|
+
return runPromise(Scope.close(scope, Exit.void), ctx);
|
|
13745
|
+
};
|
|
13746
|
+
const makeIt = (it) => makeItProxy(it, {
|
|
13722
13747
|
effect: makeTester((effect) => Effect.flatMap(contextEffect, (context) => effect.pipe(Effect.scoped, Effect.provide(context))), it),
|
|
13723
|
-
prop
|
|
13724
|
-
flakyTest
|
|
13748
|
+
prop,
|
|
13749
|
+
flakyTest,
|
|
13725
13750
|
layer(nestedLayer, options) {
|
|
13726
|
-
return layer
|
|
13751
|
+
return layer(Layer.provideMerge(nestedLayer, withTestEnv), {
|
|
13727
13752
|
...options,
|
|
13728
|
-
memoMap,
|
|
13753
|
+
memoMap: Layer.forkMemoMapUnsafe(memoMap),
|
|
13729
13754
|
excludeTestServices
|
|
13730
13755
|
});
|
|
13731
13756
|
}
|
|
13732
13757
|
});
|
|
13733
13758
|
if (args.length === 1) {
|
|
13734
|
-
|
|
13735
|
-
|
|
13736
|
-
|
|
13759
|
+
const currentSuite = getCurrentSuite();
|
|
13760
|
+
const previousTasks = new Set(currentSuite.tasks);
|
|
13761
|
+
args[0](makeIt(it$1));
|
|
13762
|
+
const blockTasks = collectTasks(currentSuite.tasks.filter((task) => !previousTasks.has(task)));
|
|
13763
|
+
if (blockTasks.length === 0) {
|
|
13764
|
+
afterAll(() => closeScope(), hookTimeout(options?.timeout));
|
|
13765
|
+
return;
|
|
13766
|
+
}
|
|
13767
|
+
const blockTaskSet = new Set(blockTasks);
|
|
13768
|
+
let remaining = blockTasks.length;
|
|
13769
|
+
beforeEach((ctx) => {
|
|
13770
|
+
if (!blockTaskSet.has(ctx.task)) return;
|
|
13771
|
+
ctx.onTestFinished(() => {
|
|
13772
|
+
remaining--;
|
|
13773
|
+
if (remaining === 0) return closeScope(ctx);
|
|
13774
|
+
});
|
|
13775
|
+
return runPromise(Effect.asVoid(contextEffect), ctx);
|
|
13776
|
+
}, hookTimeout(options?.timeout));
|
|
13777
|
+
afterAll(() => closeScope(), hookTimeout(options?.timeout));
|
|
13778
|
+
return;
|
|
13737
13779
|
}
|
|
13738
13780
|
return describe(args[0], () => {
|
|
13739
|
-
beforeAll(() => runPromise(Effect.asVoid(contextEffect)), options?.timeout
|
|
13740
|
-
afterAll(() =>
|
|
13781
|
+
beforeAll(() => runPromise(Effect.asVoid(contextEffect)), hookTimeout(options?.timeout));
|
|
13782
|
+
afterAll(() => closeScope(), hookTimeout(options?.timeout));
|
|
13741
13783
|
return args[1](makeIt(it$1));
|
|
13742
13784
|
});
|
|
13743
13785
|
};
|
|
13744
13786
|
/** @internal */
|
|
13745
|
-
const flakyTest
|
|
13787
|
+
const flakyTest = (self, timeout = Duration.seconds(30)) => pipe(self, Effect.scoped, Effect.sandbox, Effect.retry(pipe(Schedule.recurs(10), Schedule.while((_) => Effect.succeed(Duration.isLessThanOrEqualTo(Duration.fromInputUnsafe(_.elapsed), Duration.fromInputUnsafe(timeout)))))), Effect.orDie);
|
|
13746
13788
|
/** @internal */
|
|
13747
|
-
const makeMethods = (it) =>
|
|
13789
|
+
const makeMethods = (it) => makeItProxy(it, {
|
|
13748
13790
|
effect: makeTester(flow(Effect.scoped, Effect.provide(TestEnv)), it),
|
|
13749
13791
|
live: makeTester(Effect.scoped, it),
|
|
13750
|
-
flakyTest
|
|
13751
|
-
layer
|
|
13752
|
-
prop
|
|
13792
|
+
flakyTest,
|
|
13793
|
+
layer,
|
|
13794
|
+
prop
|
|
13753
13795
|
});
|
|
13754
13796
|
/** @internal */
|
|
13755
|
-
const { effect
|
|
13797
|
+
const { effect, live } = /* @__PURE__ */ makeMethods(it$1);
|
|
13798
|
+
//#endregion
|
|
13799
|
+
//#region ../../../node_modules/.pnpm/@effect+vitest@4.0.0-beta.94_effect@4.0.0-beta.94_vitest@4.1.5_@types+node@25.6.0_vite@_d376dad414e93cb5624154e275002f20/node_modules/@effect/vitest/dist/index.js
|
|
13756
13800
|
/**
|
|
13757
|
-
* @since
|
|
13801
|
+
* @since 4.0.0
|
|
13758
13802
|
*/
|
|
13759
|
-
|
|
13760
|
-
|
|
13761
|
-
|
|
13762
|
-
|
|
13763
|
-
layer: layer$1,
|
|
13764
|
-
prop: prop$1
|
|
13765
|
-
});
|
|
13803
|
+
/**
|
|
13804
|
+
* @since 4.0.0
|
|
13805
|
+
*/
|
|
13806
|
+
const it = /* @__PURE__ */ makeMethods(it$1);
|
|
13766
13807
|
//#endregion
|
|
13767
13808
|
export { globalExpect as n, describe as r, it as t };
|
|
13768
13809
|
|
|
13769
|
-
//# sourceMappingURL=dist-
|
|
13810
|
+
//# sourceMappingURL=dist-DDciKZ0w.mjs.map
|