@effect-uai/responses 0.12.0 → 0.12.1

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.
Files changed (47) hide show
  1. package/dist/OpenAIDeepResearch.d.mts +6 -5
  2. package/dist/OpenAIDeepResearch.d.mts.map +1 -1
  3. package/dist/OpenAIDeepResearch.mjs +8 -4
  4. package/dist/OpenAIDeepResearch.mjs.map +1 -1
  5. package/dist/OpenAIEmbedding.d.mts +2 -3
  6. package/dist/OpenAIEmbedding.d.mts.map +1 -1
  7. package/dist/OpenAIEmbedding.mjs +1 -1
  8. package/dist/OpenAIEmbedding.mjs.map +1 -1
  9. package/dist/Responses.d.mts +0 -2
  10. package/dist/Responses.d.mts.map +1 -1
  11. package/dist/Responses.mjs +4 -3
  12. package/dist/Responses.mjs.map +1 -1
  13. package/dist/ResponsesTools.d.mts +0 -2
  14. package/dist/ResponsesTools.d.mts.map +1 -1
  15. package/dist/ResponsesTools.mjs +1 -1
  16. package/dist/ResponsesTools.mjs.map +1 -1
  17. package/dist/codec.d.mts +0 -2
  18. package/dist/codec.d.mts.map +1 -1
  19. package/dist/codec.mjs +1 -1
  20. package/dist/codec.mjs.map +1 -1
  21. package/dist/codec.test.d.mts +1 -1
  22. package/dist/codec.test.mjs +4 -3
  23. package/dist/codec.test.mjs.map +1 -1
  24. package/dist/{magic-string.es-CaWgF-3p.mjs → magic-string.es-CUAnjKYC.mjs} +14 -13
  25. package/dist/{magic-string.es-CaWgF-3p.mjs.map → magic-string.es-CUAnjKYC.mjs.map} +1 -1
  26. package/dist/models.d.mts.map +1 -1
  27. package/dist/region.d.mts.map +1 -1
  28. package/dist/region.mjs.map +1 -1
  29. package/dist/region.test.d.mts +1 -1
  30. package/dist/region.test.mjs +1 -1
  31. package/dist/region.test.mjs.map +1 -1
  32. package/dist/responsesTools.test.d.mts +1 -1
  33. package/dist/responsesTools.test.mjs +7 -5
  34. package/dist/responsesTools.test.mjs.map +1 -1
  35. package/dist/streamEvents.d.mts +0 -2
  36. package/dist/streamEvents.d.mts.map +1 -1
  37. package/dist/streamEvents.mjs +1 -1
  38. package/dist/streamEvents.mjs.map +1 -1
  39. package/dist/{test.DNmyFkvJ-CPKukVWS.mjs → test.DNmyFkvJ-N3QqMRwZ.mjs} +247 -222
  40. package/dist/test.DNmyFkvJ-N3QqMRwZ.mjs.map +1 -0
  41. package/package.json +5 -5
  42. package/src/OpenAIDeepResearch.ts +9 -14
  43. package/src/OpenAIEmbedding.ts +24 -29
  44. package/src/Responses.ts +4 -7
  45. package/src/ResponsesTools.ts +4 -6
  46. package/dist/test.DNmyFkvJ-CPKukVWS.mjs.map +0 -1
  47. /package/dist/{chunk-CfYAbeIz.mjs → rolldown-runtime-D7D4PA-g.mjs} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"region.mjs","names":[],"sources":["../src/region.ts"],"sourcesContent":["/**\n * OpenAI regional endpoints. `eu.api.openai.com` covers `/v1/responses`\n * and `/v1/embeddings` (along with the rest of the REST surface) for\n * projects with EU data residency enabled. Keys are project-scoped.\n *\n * Reference: https://developers.openai.com/api/docs/guides/your-data\n *\n * Defined locally in this package rather than imported from\n * `@effect-uai/openai` to keep the packages decoupled.\n */\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport type OpenAiRegion = \"default\" | \"eu\" | (string & {})\n\nconst DEFAULT_HOST = \"https://api.openai.com/v1\"\n\n/**\n * Resolve the HTTP base URL from a Config. `baseUrl` wins when set;\n * otherwise the host is computed from `region`. Unknown region strings\n * pass through as `{region}.api.openai.com/v1` for forward compat.\n */\nexport const resolveHost = (cfg: {\n readonly baseUrl?: string\n readonly region?: OpenAiRegion\n}): string => {\n if (cfg.baseUrl !== undefined) return cfg.baseUrl\n if (cfg.region === undefined || cfg.region === \"default\") return DEFAULT_HOST\n return `https://${cfg.region}.api.openai.com/v1`\n}\n"],"mappings":";AAcA,MAAM,eAAe;;;;;;AAOrB,MAAa,eAAe,QAGd;AACZ,KAAI,IAAI,YAAY,KAAA,EAAW,QAAO,IAAI;AAC1C,KAAI,IAAI,WAAW,KAAA,KAAa,IAAI,WAAW,UAAW,QAAO;AACjE,QAAO,WAAW,IAAI,OAAO"}
1
+ {"version":3,"file":"region.mjs","names":[],"sources":["../src/region.ts"],"sourcesContent":["/**\n * OpenAI regional endpoints. `eu.api.openai.com` covers `/v1/responses`\n * and `/v1/embeddings` (along with the rest of the REST surface) for\n * projects with EU data residency enabled. Keys are project-scoped.\n *\n * Reference: https://developers.openai.com/api/docs/guides/your-data\n *\n * Defined locally in this package rather than imported from\n * `@effect-uai/openai` to keep the packages decoupled.\n */\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport type OpenAiRegion = \"default\" | \"eu\" | (string & {})\n\nconst DEFAULT_HOST = \"https://api.openai.com/v1\"\n\n/**\n * Resolve the HTTP base URL from a Config. `baseUrl` wins when set;\n * otherwise the host is computed from `region`. Unknown region strings\n * pass through as `{region}.api.openai.com/v1` for forward compat.\n */\nexport const resolveHost = (cfg: {\n readonly baseUrl?: string\n readonly region?: OpenAiRegion\n}): string => {\n if (cfg.baseUrl !== undefined) return cfg.baseUrl\n if (cfg.region === undefined || cfg.region === \"default\") return DEFAULT_HOST\n return `https://${cfg.region}.api.openai.com/v1`\n}\n"],"mappings":";AAcA,MAAM,eAAe;;;;;;AAOrB,MAAa,eAAe,QAGd;CACZ,IAAI,IAAI,YAAY,KAAA,GAAW,OAAO,IAAI;CAC1C,IAAI,IAAI,WAAW,KAAA,KAAa,IAAI,WAAW,WAAW,OAAO;CACjE,OAAO,WAAW,IAAI,OAAO;AAC/B"}
@@ -1 +1 @@
1
- export { };
1
+ export {}
@@ -1,5 +1,5 @@
1
1
  import { resolveHost } from "./region.mjs";
2
- import { n as describe, r as it, t as globalExpect } from "./test.DNmyFkvJ-CPKukVWS.mjs";
2
+ import { n as describe, r as it, t as globalExpect } from "./test.DNmyFkvJ-N3QqMRwZ.mjs";
3
3
  //#region src/region.test.ts
4
4
  describe("responses/region.resolveHost", () => {
5
5
  it("returns default host when no region or baseUrl", () => {
@@ -1 +1 @@
1
- {"version":3,"file":"region.test.mjs","names":[],"sources":["../src/region.test.ts"],"sourcesContent":["import { describe, expect, it } from \"vitest\"\nimport { resolveHost } from \"./region.js\"\n\ndescribe(\"responses/region.resolveHost\", () => {\n it(\"returns default host when no region or baseUrl\", () => {\n expect(resolveHost({})).toBe(\"https://api.openai.com/v1\")\n })\n\n it(\"returns default host for region 'default'\", () => {\n expect(resolveHost({ region: \"default\" })).toBe(\"https://api.openai.com/v1\")\n })\n\n it(\"computes EU host for region 'eu'\", () => {\n expect(resolveHost({ region: \"eu\" })).toBe(\"https://eu.api.openai.com/v1\")\n })\n\n it(\"passes unknown region through as host prefix\", () => {\n expect(resolveHost({ region: \"apac\" })).toBe(\"https://apac.api.openai.com/v1\")\n })\n\n it(\"baseUrl wins over region\", () => {\n expect(resolveHost({ baseUrl: \"http://localhost:8080/v1\", region: \"eu\" })).toBe(\n \"http://localhost:8080/v1\",\n )\n })\n})\n"],"mappings":";;;AAGA,SAAS,sCAAsC;AAC7C,IAAG,wDAAwD;AACzD,eAAO,YAAY,EAAE,CAAC,CAAC,CAAC,KAAK,4BAA4B;GACzD;AAEF,IAAG,mDAAmD;AACpD,eAAO,YAAY,EAAE,QAAQ,WAAW,CAAC,CAAC,CAAC,KAAK,4BAA4B;GAC5E;AAEF,IAAG,0CAA0C;AAC3C,eAAO,YAAY,EAAE,QAAQ,MAAM,CAAC,CAAC,CAAC,KAAK,+BAA+B;GAC1E;AAEF,IAAG,sDAAsD;AACvD,eAAO,YAAY,EAAE,QAAQ,QAAQ,CAAC,CAAC,CAAC,KAAK,iCAAiC;GAC9E;AAEF,IAAG,kCAAkC;AACnC,eAAO,YAAY;GAAE,SAAS;GAA4B,QAAQ;GAAM,CAAC,CAAC,CAAC,KACzE,2BACD;GACD;EACF"}
1
+ {"version":3,"file":"region.test.mjs","names":[],"sources":["../src/region.test.ts"],"sourcesContent":["import { describe, expect, it } from \"vitest\"\nimport { resolveHost } from \"./region.js\"\n\ndescribe(\"responses/region.resolveHost\", () => {\n it(\"returns default host when no region or baseUrl\", () => {\n expect(resolveHost({})).toBe(\"https://api.openai.com/v1\")\n })\n\n it(\"returns default host for region 'default'\", () => {\n expect(resolveHost({ region: \"default\" })).toBe(\"https://api.openai.com/v1\")\n })\n\n it(\"computes EU host for region 'eu'\", () => {\n expect(resolveHost({ region: \"eu\" })).toBe(\"https://eu.api.openai.com/v1\")\n })\n\n it(\"passes unknown region through as host prefix\", () => {\n expect(resolveHost({ region: \"apac\" })).toBe(\"https://apac.api.openai.com/v1\")\n })\n\n it(\"baseUrl wins over region\", () => {\n expect(resolveHost({ baseUrl: \"http://localhost:8080/v1\", region: \"eu\" })).toBe(\n \"http://localhost:8080/v1\",\n )\n })\n})\n"],"mappings":";;;AAGA,SAAS,sCAAsC;CAC7C,GAAG,wDAAwD;EACzD,aAAO,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,2BAA2B;CAC1D,CAAC;CAED,GAAG,mDAAmD;EACpD,aAAO,YAAY,EAAE,QAAQ,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,2BAA2B;CAC7E,CAAC;CAED,GAAG,0CAA0C;EAC3C,aAAO,YAAY,EAAE,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,8BAA8B;CAC3E,CAAC;CAED,GAAG,sDAAsD;EACvD,aAAO,YAAY,EAAE,QAAQ,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,gCAAgC;CAC/E,CAAC;CAED,GAAG,kCAAkC;EACnC,aAAO,YAAY;GAAE,SAAS;GAA4B,QAAQ;EAAK,CAAC,CAAC,CAAC,CAAC,KACzE,0BACF;CACF,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- export { };
1
+ export {}
@@ -1,6 +1,6 @@
1
1
  import { codeInterpreterTool, fileSearchTool, renderProviderTools, webSearchTool } from "./ResponsesTools.mjs";
2
2
  import { KnownProviderEvent, eventToDeltas, makeCallIdLookup } from "./streamEvents.mjs";
3
- import { n as describe, r as it, t as globalExpect } from "./test.DNmyFkvJ-CPKukVWS.mjs";
3
+ import { n as describe, r as it, t as globalExpect } from "./test.DNmyFkvJ-N3QqMRwZ.mjs";
4
4
  import { Result, Schema } from "effect";
5
5
  import * as Tool from "@effect-uai/core/Tool";
6
6
  import { providerToolsOf } from "@effect-uai/core/Tool";
@@ -75,7 +75,7 @@ describe("Responses provider tool rendering", () => {
75
75
  describe("Responses hosted-tool response tolerance", () => {
76
76
  const decodeEvent = Schema.decodeUnknownSync(KnownProviderEvent);
77
77
  it("emits TurnComplete with just the text answer for a grounded completion", () => {
78
- const complete = eventToDeltas(decodeEvent({
78
+ const event = decodeEvent({
79
79
  type: "response.completed",
80
80
  response: {
81
81
  status: "completed",
@@ -92,7 +92,8 @@ describe("Responses hosted-tool response tolerance", () => {
92
92
  }]
93
93
  }]
94
94
  }
95
- }), makeCallIdLookup()).find((d) => d._tag === "TurnComplete");
95
+ });
96
+ const complete = eventToDeltas(event, makeCallIdLookup()).find((d) => d._tag === "TurnComplete");
96
97
  globalExpect(complete).toBeDefined();
97
98
  const turn = complete?._tag === "TurnComplete" ? complete.turn : void 0;
98
99
  globalExpect(turn?.stop_reason).toBe("stop");
@@ -107,7 +108,7 @@ describe("Responses hosted-tool response tolerance", () => {
107
108
  }]);
108
109
  });
109
110
  it("projects a streamed url_citation to CitationAdded", () => {
110
- globalExpect(eventToDeltas(decodeEvent({
111
+ const deltas = eventToDeltas(decodeEvent({
111
112
  type: "response.output_text.annotation.added",
112
113
  item_id: "msg_1",
113
114
  output_index: 0,
@@ -120,7 +121,8 @@ describe("Responses hosted-tool response tolerance", () => {
120
121
  start_index: 10,
121
122
  end_index: 20
122
123
  }
123
- }), makeCallIdLookup())).toEqual([{
124
+ }), makeCallIdLookup());
125
+ globalExpect(deltas).toEqual([{
124
126
  _tag: "CitationAdded",
125
127
  annotation: {
126
128
  type: "url_citation",
@@ -1 +1 @@
1
- {"version":3,"file":"responsesTools.test.mjs","names":["expect"],"sources":["../src/responsesTools.test.ts"],"sourcesContent":["import { Result, Schema } from \"effect\"\nimport * as Tool from \"@effect-uai/core/Tool\"\nimport { providerToolsOf } from \"@effect-uai/core/Tool\"\nimport { describe, expect, it } from \"vitest\"\nimport { KnownProviderEvent, eventToDeltas, makeCallIdLookup } from \"./streamEvents.js\"\nimport {\n codeInterpreterTool,\n fileSearchTool,\n renderProviderTools,\n webSearchTool,\n} from \"./ResponsesTools.js\"\n\nconst wireFor = (toolkit: Record<string, Tool.AnyTool>) =>\n Result.getOrThrow(renderProviderTools(providerToolsOf(toolkit)))\n\ndescribe(\"Responses provider tool rendering\", () => {\n it(\"maps web_search options onto the native wire fields\", () => {\n expect(\n wireFor({\n web_search: webSearchTool({\n searchContextSize: \"high\",\n filters: { allowedDomains: [\"example.com\"], blockedDomains: [\"spam.com\"] },\n userLocation: { city: \"Berlin\", country: \"DE\" },\n }),\n }),\n ).toEqual([\n {\n type: \"web_search\",\n filters: { allowed_domains: [\"example.com\"], blocked_domains: [\"spam.com\"] },\n user_location: { type: \"approximate\", city: \"Berlin\", country: \"DE\" },\n search_context_size: \"high\",\n },\n ])\n })\n\n it(\"maps code_interpreter to an auto container (with file ids when given)\", () => {\n expect(wireFor({ ci: codeInterpreterTool() })).toEqual([\n { type: \"code_interpreter\", container: { type: \"auto\" } },\n ])\n expect(wireFor({ ci: codeInterpreterTool({ fileIds: [\"file_1\"] }) })).toEqual([\n { type: \"code_interpreter\", container: { type: \"auto\", file_ids: [\"file_1\"] } },\n ])\n })\n\n it(\"maps file_search to its vector store ids\", () => {\n expect(wireFor({ fs: fileSearchTool({ vectorStoreIds: [\"vs_1\", \"vs_2\"] }) })).toEqual([\n { type: \"file_search\", vector_store_ids: [\"vs_1\", \"vs_2\"] },\n ])\n })\n\n it(\"fails on a tool hosted by a different provider\", () => {\n const foreign = Tool.provider({\n name: \"google_search\",\n description: \"Gemini grounding.\",\n inputSchema: Tool.noInput,\n provider: \"gemini\",\n config: { kind: \"google_search\" },\n })\n expect(Result.isFailure(renderProviderTools(providerToolsOf({ foreign })))).toBe(true)\n })\n\n it(\"fails on an unrecognized config\", () => {\n const bogus = Tool.provider({\n name: \"mystery\",\n description: \"Unknown Responses tool.\",\n inputSchema: Tool.noInput,\n provider: \"openai\",\n config: { kind: \"telepathy\" },\n })\n expect(Result.isFailure(renderProviderTools(providerToolsOf({ bogus })))).toBe(true)\n })\n})\n\ndescribe(\"Responses hosted-tool response tolerance\", () => {\n // The real regression: a hosted-tool output item in `response.completed` must\n // not break the event decode, or `TurnComplete` would never fire. Decoding\n // through the actual event schema (throws on failure) and projecting to\n // TurnEvents proves the grounded text still assembles into a turn.\n const decodeEvent = Schema.decodeUnknownSync(KnownProviderEvent)\n\n it(\"emits TurnComplete with just the text answer for a grounded completion\", () => {\n const event = decodeEvent({\n type: \"response.completed\",\n response: {\n status: \"completed\",\n output: [\n { type: \"web_search_call\", id: \"ws_1\", status: \"completed\" },\n {\n type: \"message\",\n role: \"assistant\",\n content: [{ type: \"output_text\", text: \"Grounded answer.\" }],\n },\n ],\n },\n })\n const deltas = eventToDeltas(event, makeCallIdLookup())\n const complete = deltas.find((d) => d._tag === \"TurnComplete\")\n expect(complete).toBeDefined()\n const turn = complete?._tag === \"TurnComplete\" ? complete.turn : undefined\n expect(turn?.stop_reason).toBe(\"stop\")\n expect(turn?.items).toEqual([\n {\n type: \"message\",\n role: \"assistant\",\n content: [{ type: \"output_text\", text: \"Grounded answer.\" }],\n providerData: expect.anything(),\n },\n ])\n })\n\n // The new streamed-citation path: a real `annotation.added` payload (with the\n // wire's positional fields) must decode and project to a `CitationAdded`\n // carrying a domain `Annotation`. This is what makes native-grounding\n // citations stream instead of only landing on the final turn.\n it(\"projects a streamed url_citation to CitationAdded\", () => {\n const deltas = eventToDeltas(\n decodeEvent({\n type: \"response.output_text.annotation.added\",\n item_id: \"msg_1\",\n output_index: 0,\n content_index: 0,\n annotation_index: 0,\n annotation: {\n type: \"url_citation\",\n url: \"https://example.com/a\",\n title: \"A\",\n start_index: 10,\n end_index: 20,\n },\n }),\n makeCallIdLookup(),\n )\n expect(deltas).toEqual([\n {\n _tag: \"CitationAdded\",\n annotation: {\n type: \"url_citation\",\n url: \"https://example.com/a\",\n title: \"A\",\n start_index: 10,\n end_index: 20,\n },\n },\n ])\n })\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"responsesTools.test.mjs","names":["expect"],"sources":["../src/responsesTools.test.ts"],"sourcesContent":["import { Result, Schema } from \"effect\"\nimport * as Tool from \"@effect-uai/core/Tool\"\nimport { providerToolsOf } from \"@effect-uai/core/Tool\"\nimport { describe, expect, it } from \"vitest\"\nimport { KnownProviderEvent, eventToDeltas, makeCallIdLookup } from \"./streamEvents.js\"\nimport {\n codeInterpreterTool,\n fileSearchTool,\n renderProviderTools,\n webSearchTool,\n} from \"./ResponsesTools.js\"\n\nconst wireFor = (toolkit: Record<string, Tool.AnyTool>) =>\n Result.getOrThrow(renderProviderTools(providerToolsOf(toolkit)))\n\ndescribe(\"Responses provider tool rendering\", () => {\n it(\"maps web_search options onto the native wire fields\", () => {\n expect(\n wireFor({\n web_search: webSearchTool({\n searchContextSize: \"high\",\n filters: { allowedDomains: [\"example.com\"], blockedDomains: [\"spam.com\"] },\n userLocation: { city: \"Berlin\", country: \"DE\" },\n }),\n }),\n ).toEqual([\n {\n type: \"web_search\",\n filters: { allowed_domains: [\"example.com\"], blocked_domains: [\"spam.com\"] },\n user_location: { type: \"approximate\", city: \"Berlin\", country: \"DE\" },\n search_context_size: \"high\",\n },\n ])\n })\n\n it(\"maps code_interpreter to an auto container (with file ids when given)\", () => {\n expect(wireFor({ ci: codeInterpreterTool() })).toEqual([\n { type: \"code_interpreter\", container: { type: \"auto\" } },\n ])\n expect(wireFor({ ci: codeInterpreterTool({ fileIds: [\"file_1\"] }) })).toEqual([\n { type: \"code_interpreter\", container: { type: \"auto\", file_ids: [\"file_1\"] } },\n ])\n })\n\n it(\"maps file_search to its vector store ids\", () => {\n expect(wireFor({ fs: fileSearchTool({ vectorStoreIds: [\"vs_1\", \"vs_2\"] }) })).toEqual([\n { type: \"file_search\", vector_store_ids: [\"vs_1\", \"vs_2\"] },\n ])\n })\n\n it(\"fails on a tool hosted by a different provider\", () => {\n const foreign = Tool.provider({\n name: \"google_search\",\n description: \"Gemini grounding.\",\n inputSchema: Tool.noInput,\n provider: \"gemini\",\n config: { kind: \"google_search\" },\n })\n expect(Result.isFailure(renderProviderTools(providerToolsOf({ foreign })))).toBe(true)\n })\n\n it(\"fails on an unrecognized config\", () => {\n const bogus = Tool.provider({\n name: \"mystery\",\n description: \"Unknown Responses tool.\",\n inputSchema: Tool.noInput,\n provider: \"openai\",\n config: { kind: \"telepathy\" },\n })\n expect(Result.isFailure(renderProviderTools(providerToolsOf({ bogus })))).toBe(true)\n })\n})\n\ndescribe(\"Responses hosted-tool response tolerance\", () => {\n // The real regression: a hosted-tool output item in `response.completed` must\n // not break the event decode, or `TurnComplete` would never fire. Decoding\n // through the actual event schema (throws on failure) and projecting to\n // TurnEvents proves the grounded text still assembles into a turn.\n const decodeEvent = Schema.decodeUnknownSync(KnownProviderEvent)\n\n it(\"emits TurnComplete with just the text answer for a grounded completion\", () => {\n const event = decodeEvent({\n type: \"response.completed\",\n response: {\n status: \"completed\",\n output: [\n { type: \"web_search_call\", id: \"ws_1\", status: \"completed\" },\n {\n type: \"message\",\n role: \"assistant\",\n content: [{ type: \"output_text\", text: \"Grounded answer.\" }],\n },\n ],\n },\n })\n const deltas = eventToDeltas(event, makeCallIdLookup())\n const complete = deltas.find((d) => d._tag === \"TurnComplete\")\n expect(complete).toBeDefined()\n const turn = complete?._tag === \"TurnComplete\" ? complete.turn : undefined\n expect(turn?.stop_reason).toBe(\"stop\")\n expect(turn?.items).toEqual([\n {\n type: \"message\",\n role: \"assistant\",\n content: [{ type: \"output_text\", text: \"Grounded answer.\" }],\n providerData: expect.anything(),\n },\n ])\n })\n\n // The new streamed-citation path: a real `annotation.added` payload (with the\n // wire's positional fields) must decode and project to a `CitationAdded`\n // carrying a domain `Annotation`. This is what makes native-grounding\n // citations stream instead of only landing on the final turn.\n it(\"projects a streamed url_citation to CitationAdded\", () => {\n const deltas = eventToDeltas(\n decodeEvent({\n type: \"response.output_text.annotation.added\",\n item_id: \"msg_1\",\n output_index: 0,\n content_index: 0,\n annotation_index: 0,\n annotation: {\n type: \"url_citation\",\n url: \"https://example.com/a\",\n title: \"A\",\n start_index: 10,\n end_index: 20,\n },\n }),\n makeCallIdLookup(),\n )\n expect(deltas).toEqual([\n {\n _tag: \"CitationAdded\",\n annotation: {\n type: \"url_citation\",\n url: \"https://example.com/a\",\n title: \"A\",\n start_index: 10,\n end_index: 20,\n },\n },\n ])\n })\n})\n"],"mappings":"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"}
@@ -1,7 +1,5 @@
1
1
  import { Schema } from "effect";
2
2
  import { TurnEvent } from "@effect-uai/core/Turn";
3
-
4
- //#region src/streamEvents.d.ts
5
3
  declare namespace streamEvents_d_exports {
6
4
  export { CallIdLookup, KnownProviderEvent, ProviderEvent, eventToDeltas, makeCallIdLookup };
7
5
  }
@@ -1 +1 @@
1
- {"version":3,"file":"streamEvents.d.mts","names":[],"sources":["../src/streamEvents.ts"],"mappings":";;;;;;;;;;;cAuHa,kBAAA,EAAkB,MAAA,CAAA,KAAA,WAAA,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAuBlB,aAAA,EAAa,MAAA,CAAA,KAAA,WAAA,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAkBd,aAAA,UAAuB,aAAA,CAAc,IAAA;AAAA,KAKrC,YAAA;EAAA,SACD,OAAA,GAAU,MAAA;EAAA,SACV,QAAA,GAAW,MAAA,UAAgB,MAAA;AAAA;AAAA,cAGzB,gBAAA,QAAuB,YAAA;;;;;;;cAgBvB,aAAA,GACX,KAAA,EAAO,aAAA,EACP,MAAA,EAAQ,YAAA,KACP,aAAA,CAAc,SAAA"}
1
+ {"version":3,"file":"streamEvents.d.mts","names":[],"sources":["../src/streamEvents.ts"],"mappings":";;;;;;;;;cAuHa,oBAAkB,OAAA,gBAAA,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAuBlB,eAAa,OAAA,gBAAA,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAkBd,uBAAuB,cAAc;KAKrC;WACD,UAAU;WACV,WAAW,gBAAgB;;cAGzB,wBAAuB;;;;;;;cAgBvB,gBAAa,OACjB,eAAa,QACZ,iBACP,cAAc"}
@@ -1,4 +1,4 @@
1
- import { t as __exportAll } from "./chunk-CfYAbeIz.mjs";
1
+ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
2
  import { WireAnnotation, WireOutputItem, WireResponseCompleted, turnFromCompleted } from "./codec.mjs";
3
3
  import { Match, Schema } from "effect";
4
4
  import { TurnEvent } from "@effect-uai/core/Turn";
@@ -1 +1 @@
1
- {"version":3,"file":"streamEvents.mjs","names":[],"sources":["../src/streamEvents.ts"],"sourcesContent":["import { Match, Schema } from \"effect\"\nimport { TurnEvent } from \"@effect-uai/core/Turn\"\nimport {\n WireAnnotation,\n WireOutputItem,\n WireResponseCompleted,\n turnFromCompleted,\n} from \"./codec.js\"\n\n// ---------------------------------------------------------------------------\n// Schemas for the SSE event payloads we care about. The Responses API ships\n// many event types; we model only the ones that map to a `TurnEvent`. All\n// others are silently ignored at the dispatch site.\n// ---------------------------------------------------------------------------\n\nconst OutputItemAdded = Schema.Struct({\n type: Schema.Literal(\"response.output_item.added\"),\n item: WireOutputItem,\n})\n\nconst OutputTextDelta = Schema.Struct({\n type: Schema.Literal(\"response.output_text.delta\"),\n delta: Schema.String,\n})\n\nconst FunctionArgsDelta = Schema.Struct({\n type: Schema.Literal(\"response.function_call_arguments.delta\"),\n item_id: Schema.String,\n delta: Schema.String,\n})\n\nconst ReasoningTextDelta = Schema.Struct({\n type: Schema.Literal(\"response.reasoning_text.delta\"),\n delta: Schema.String,\n})\n\nconst ReasoningSummaryDelta = Schema.Struct({\n type: Schema.Literal(\"response.reasoning_summary_text.delta\"),\n delta: Schema.String,\n})\n\nconst RefusalDelta = Schema.Struct({\n type: Schema.Literal(\"response.refusal.delta\"),\n delta: Schema.String,\n})\n\nconst RefusalDone = Schema.Struct({\n type: Schema.Literal(\"response.refusal.done\"),\n refusal: Schema.optional(Schema.String),\n})\n\n// Web-search lifecycle. The three phases carry `item_id` / `output_index` /\n// `sequence_number`; we map each to a `WebSearchCall` status. `query` / `action`\n// ride on the `web_search_call` output item, not these lifecycle events.\nconst WebSearchInProgress = Schema.Struct({\n type: Schema.Literal(\"response.web_search_call.in_progress\"),\n})\n\nconst WebSearchSearching = Schema.Struct({\n type: Schema.Literal(\"response.web_search_call.searching\"),\n})\n\nconst WebSearchCompleted = Schema.Struct({\n type: Schema.Literal(\"response.web_search_call.completed\"),\n})\n\n// A citation attached to the answer as it is written. `annotation` is the\n// same shape as the ones bundled on the final `output_text` block.\nconst AnnotationAdded = Schema.Struct({\n type: Schema.Literal(\"response.output_text.annotation.added\"),\n annotation: WireAnnotation,\n})\n\nconst Completed = Schema.Struct({\n type: Schema.Literal(\"response.completed\"),\n response: WireResponseCompleted,\n})\n\nconst Incomplete = Schema.Struct({\n type: Schema.Literal(\"response.incomplete\"),\n response: WireResponseCompleted,\n})\n\nconst Failed = Schema.Struct({\n type: Schema.Literal(\"response.failed\"),\n response: WireResponseCompleted,\n})\n\nconst ErrorEvent = Schema.Struct({\n type: Schema.Literal(\"error\"),\n // Flat form (top-level `message`/`code`) and the nested form the Responses API\n // uses for request rejections: `error: { message, code, type, param }`.\n message: Schema.optional(Schema.String),\n code: Schema.optional(Schema.String),\n error: Schema.optional(\n Schema.Struct({\n message: Schema.optional(Schema.NullOr(Schema.String)),\n code: Schema.optional(Schema.NullOr(Schema.String)),\n type: Schema.optional(Schema.NullOr(Schema.String)),\n param: Schema.optional(Schema.NullOr(Schema.String)),\n }),\n ),\n})\n\n/**\n * Catch-all variant for wire events that fail to decode against any known\n * schema, plus events that fail to JSON-parse. The decoder never produces\n * this directly - it's synthesized by `sseEventToProviderEvent` when\n * `decodeKnown` fails.\n */\nconst Unknown = Schema.Struct({\n type: Schema.Literal(\"_unknown\"),\n raw: Schema.Unknown,\n})\n\n/**\n * Internal: union of variants we actually know how to decode from the wire.\n * Used as the decode target; failures are caught and re-emitted as `Unknown`.\n */\nexport const KnownProviderEvent = Schema.Union([\n OutputItemAdded,\n OutputTextDelta,\n FunctionArgsDelta,\n ReasoningTextDelta,\n ReasoningSummaryDelta,\n RefusalDelta,\n RefusalDone,\n WebSearchInProgress,\n WebSearchSearching,\n WebSearchCompleted,\n AnnotationAdded,\n Completed,\n Incomplete,\n Failed,\n ErrorEvent,\n])\n\n/**\n * Public: every event the native stream can emit. Discriminated on `type`.\n * The `_unknown` branch closes the cardinality so downstream `Match.exhaustive`\n * cannot silently miss a wire event we didn't model.\n */\nexport const ProviderEvent = Schema.Union([\n OutputItemAdded,\n OutputTextDelta,\n FunctionArgsDelta,\n ReasoningTextDelta,\n ReasoningSummaryDelta,\n RefusalDelta,\n RefusalDone,\n WebSearchInProgress,\n WebSearchSearching,\n WebSearchCompleted,\n AnnotationAdded,\n Completed,\n Incomplete,\n Failed,\n ErrorEvent,\n Unknown,\n])\nexport type ProviderEvent = typeof ProviderEvent.Type\n\n// `call_id` lookup for `function_call_arguments.delta`. The SSE event\n// references the *item id*, not the call id; we keep a small map populated\n// from the `output_item.added` events.\nexport type CallIdLookup = {\n readonly resolve: (itemId: string) => string | undefined\n readonly remember: (itemId: string, callId: string) => void\n}\n\nexport const makeCallIdLookup = (): CallIdLookup => {\n const map = new Map<string, string>()\n return {\n resolve: (id) => map.get(id),\n remember: (id, callId) => {\n map.set(id, callId)\n },\n }\n}\n\n/**\n * Translate a decoded provider event into zero-or-more `TurnEvent`s.\n * Mutates `lookup` to record `(item_id → call_id)` from `output_item.added`\n * so subsequent `function_call_arguments.delta` events can be tagged with\n * the right call id.\n */\nexport const eventToDeltas = (\n event: ProviderEvent,\n lookup: CallIdLookup,\n): ReadonlyArray<TurnEvent> =>\n Match.value(event).pipe(\n Match.discriminatorsExhaustive(\"type\")({\n \"response.output_item.added\": ({ item }) => {\n if (item.type !== \"function_call\") return []\n if (item.id !== undefined) lookup.remember(item.id, item.call_id)\n return [TurnEvent.ToolCallStart({ call_id: item.call_id, name: item.name })]\n },\n \"response.output_text.delta\": ({ delta }) => [TurnEvent.TextDelta({ text: delta })],\n \"response.function_call_arguments.delta\": ({ item_id, delta }) => {\n const call_id = lookup.resolve(item_id)\n return call_id === undefined ? [] : [TurnEvent.ToolCallArgsDelta({ call_id, delta })]\n },\n \"response.reasoning_text.delta\": ({ delta }) => [\n TurnEvent.ReasoningDelta({ text: delta, kind: \"trace\" }),\n ],\n \"response.reasoning_summary_text.delta\": ({ delta }) => [\n TurnEvent.ReasoningDelta({ text: delta, kind: \"summary\" }),\n ],\n \"response.refusal.delta\": ({ delta }) => [TurnEvent.RefusalDelta({ text: delta })],\n // Terminal marker for the refusal stream; the deltas already covered\n // the text, so no canonical event is emitted here.\n \"response.refusal.done\": () => [],\n \"response.web_search_call.in_progress\": () => [\n TurnEvent.WebSearchCall({ status: \"started\" }),\n ],\n \"response.web_search_call.searching\": () => [\n TurnEvent.WebSearchCall({ status: \"searching\" }),\n ],\n \"response.web_search_call.completed\": () => [\n TurnEvent.WebSearchCall({ status: \"completed\" }),\n ],\n \"response.output_text.annotation.added\": ({ annotation }) => [\n TurnEvent.CitationAdded({ annotation }),\n ],\n \"response.completed\": ({ response }) => [\n TurnEvent.TurnComplete({ turn: turnFromCompleted(response) }),\n ],\n // Incomplete = the model stopped early but produced a usable partial\n // turn (max_tokens, content_filter, max_tool_calls, refusal). Same\n // payload shape as `response.completed`; the stop_reason carries the\n // reason.\n \"response.incomplete\": ({ response }) => [\n TurnEvent.TurnComplete({ turn: turnFromCompleted(response) }),\n ],\n // Failed and error are surfaced separately as `AiError` by the stream\n // pipeline, not as canonical events.\n \"response.failed\": () => [],\n error: () => [],\n // No silent drops: unknown wire events flow through `streamNative` but\n // produce no canonical delta. Step 3 (canonical `other` event) replaces\n // this with a forwarded `other` delta on `TurnEvent`.\n _unknown: () => [],\n }),\n )\n"],"mappings":"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"}
1
+ {"version":3,"file":"streamEvents.mjs","names":[],"sources":["../src/streamEvents.ts"],"sourcesContent":["import { Match, Schema } from \"effect\"\nimport { TurnEvent } from \"@effect-uai/core/Turn\"\nimport {\n WireAnnotation,\n WireOutputItem,\n WireResponseCompleted,\n turnFromCompleted,\n} from \"./codec.js\"\n\n// ---------------------------------------------------------------------------\n// Schemas for the SSE event payloads we care about. The Responses API ships\n// many event types; we model only the ones that map to a `TurnEvent`. All\n// others are silently ignored at the dispatch site.\n// ---------------------------------------------------------------------------\n\nconst OutputItemAdded = Schema.Struct({\n type: Schema.Literal(\"response.output_item.added\"),\n item: WireOutputItem,\n})\n\nconst OutputTextDelta = Schema.Struct({\n type: Schema.Literal(\"response.output_text.delta\"),\n delta: Schema.String,\n})\n\nconst FunctionArgsDelta = Schema.Struct({\n type: Schema.Literal(\"response.function_call_arguments.delta\"),\n item_id: Schema.String,\n delta: Schema.String,\n})\n\nconst ReasoningTextDelta = Schema.Struct({\n type: Schema.Literal(\"response.reasoning_text.delta\"),\n delta: Schema.String,\n})\n\nconst ReasoningSummaryDelta = Schema.Struct({\n type: Schema.Literal(\"response.reasoning_summary_text.delta\"),\n delta: Schema.String,\n})\n\nconst RefusalDelta = Schema.Struct({\n type: Schema.Literal(\"response.refusal.delta\"),\n delta: Schema.String,\n})\n\nconst RefusalDone = Schema.Struct({\n type: Schema.Literal(\"response.refusal.done\"),\n refusal: Schema.optional(Schema.String),\n})\n\n// Web-search lifecycle. The three phases carry `item_id` / `output_index` /\n// `sequence_number`; we map each to a `WebSearchCall` status. `query` / `action`\n// ride on the `web_search_call` output item, not these lifecycle events.\nconst WebSearchInProgress = Schema.Struct({\n type: Schema.Literal(\"response.web_search_call.in_progress\"),\n})\n\nconst WebSearchSearching = Schema.Struct({\n type: Schema.Literal(\"response.web_search_call.searching\"),\n})\n\nconst WebSearchCompleted = Schema.Struct({\n type: Schema.Literal(\"response.web_search_call.completed\"),\n})\n\n// A citation attached to the answer as it is written. `annotation` is the\n// same shape as the ones bundled on the final `output_text` block.\nconst AnnotationAdded = Schema.Struct({\n type: Schema.Literal(\"response.output_text.annotation.added\"),\n annotation: WireAnnotation,\n})\n\nconst Completed = Schema.Struct({\n type: Schema.Literal(\"response.completed\"),\n response: WireResponseCompleted,\n})\n\nconst Incomplete = Schema.Struct({\n type: Schema.Literal(\"response.incomplete\"),\n response: WireResponseCompleted,\n})\n\nconst Failed = Schema.Struct({\n type: Schema.Literal(\"response.failed\"),\n response: WireResponseCompleted,\n})\n\nconst ErrorEvent = Schema.Struct({\n type: Schema.Literal(\"error\"),\n // Flat form (top-level `message`/`code`) and the nested form the Responses API\n // uses for request rejections: `error: { message, code, type, param }`.\n message: Schema.optional(Schema.String),\n code: Schema.optional(Schema.String),\n error: Schema.optional(\n Schema.Struct({\n message: Schema.optional(Schema.NullOr(Schema.String)),\n code: Schema.optional(Schema.NullOr(Schema.String)),\n type: Schema.optional(Schema.NullOr(Schema.String)),\n param: Schema.optional(Schema.NullOr(Schema.String)),\n }),\n ),\n})\n\n/**\n * Catch-all variant for wire events that fail to decode against any known\n * schema, plus events that fail to JSON-parse. The decoder never produces\n * this directly - it's synthesized by `sseEventToProviderEvent` when\n * `decodeKnown` fails.\n */\nconst Unknown = Schema.Struct({\n type: Schema.Literal(\"_unknown\"),\n raw: Schema.Unknown,\n})\n\n/**\n * Internal: union of variants we actually know how to decode from the wire.\n * Used as the decode target; failures are caught and re-emitted as `Unknown`.\n */\nexport const KnownProviderEvent = Schema.Union([\n OutputItemAdded,\n OutputTextDelta,\n FunctionArgsDelta,\n ReasoningTextDelta,\n ReasoningSummaryDelta,\n RefusalDelta,\n RefusalDone,\n WebSearchInProgress,\n WebSearchSearching,\n WebSearchCompleted,\n AnnotationAdded,\n Completed,\n Incomplete,\n Failed,\n ErrorEvent,\n])\n\n/**\n * Public: every event the native stream can emit. Discriminated on `type`.\n * The `_unknown` branch closes the cardinality so downstream `Match.exhaustive`\n * cannot silently miss a wire event we didn't model.\n */\nexport const ProviderEvent = Schema.Union([\n OutputItemAdded,\n OutputTextDelta,\n FunctionArgsDelta,\n ReasoningTextDelta,\n ReasoningSummaryDelta,\n RefusalDelta,\n RefusalDone,\n WebSearchInProgress,\n WebSearchSearching,\n WebSearchCompleted,\n AnnotationAdded,\n Completed,\n Incomplete,\n Failed,\n ErrorEvent,\n Unknown,\n])\nexport type ProviderEvent = typeof ProviderEvent.Type\n\n// `call_id` lookup for `function_call_arguments.delta`. The SSE event\n// references the *item id*, not the call id; we keep a small map populated\n// from the `output_item.added` events.\nexport type CallIdLookup = {\n readonly resolve: (itemId: string) => string | undefined\n readonly remember: (itemId: string, callId: string) => void\n}\n\nexport const makeCallIdLookup = (): CallIdLookup => {\n const map = new Map<string, string>()\n return {\n resolve: (id) => map.get(id),\n remember: (id, callId) => {\n map.set(id, callId)\n },\n }\n}\n\n/**\n * Translate a decoded provider event into zero-or-more `TurnEvent`s.\n * Mutates `lookup` to record `(item_id → call_id)` from `output_item.added`\n * so subsequent `function_call_arguments.delta` events can be tagged with\n * the right call id.\n */\nexport const eventToDeltas = (\n event: ProviderEvent,\n lookup: CallIdLookup,\n): ReadonlyArray<TurnEvent> =>\n Match.value(event).pipe(\n Match.discriminatorsExhaustive(\"type\")({\n \"response.output_item.added\": ({ item }) => {\n if (item.type !== \"function_call\") return []\n if (item.id !== undefined) lookup.remember(item.id, item.call_id)\n return [TurnEvent.ToolCallStart({ call_id: item.call_id, name: item.name })]\n },\n \"response.output_text.delta\": ({ delta }) => [TurnEvent.TextDelta({ text: delta })],\n \"response.function_call_arguments.delta\": ({ item_id, delta }) => {\n const call_id = lookup.resolve(item_id)\n return call_id === undefined ? [] : [TurnEvent.ToolCallArgsDelta({ call_id, delta })]\n },\n \"response.reasoning_text.delta\": ({ delta }) => [\n TurnEvent.ReasoningDelta({ text: delta, kind: \"trace\" }),\n ],\n \"response.reasoning_summary_text.delta\": ({ delta }) => [\n TurnEvent.ReasoningDelta({ text: delta, kind: \"summary\" }),\n ],\n \"response.refusal.delta\": ({ delta }) => [TurnEvent.RefusalDelta({ text: delta })],\n // Terminal marker for the refusal stream; the deltas already covered\n // the text, so no canonical event is emitted here.\n \"response.refusal.done\": () => [],\n \"response.web_search_call.in_progress\": () => [\n TurnEvent.WebSearchCall({ status: \"started\" }),\n ],\n \"response.web_search_call.searching\": () => [\n TurnEvent.WebSearchCall({ status: \"searching\" }),\n ],\n \"response.web_search_call.completed\": () => [\n TurnEvent.WebSearchCall({ status: \"completed\" }),\n ],\n \"response.output_text.annotation.added\": ({ annotation }) => [\n TurnEvent.CitationAdded({ annotation }),\n ],\n \"response.completed\": ({ response }) => [\n TurnEvent.TurnComplete({ turn: turnFromCompleted(response) }),\n ],\n // Incomplete = the model stopped early but produced a usable partial\n // turn (max_tokens, content_filter, max_tool_calls, refusal). Same\n // payload shape as `response.completed`; the stop_reason carries the\n // reason.\n \"response.incomplete\": ({ response }) => [\n TurnEvent.TurnComplete({ turn: turnFromCompleted(response) }),\n ],\n // Failed and error are surfaced separately as `AiError` by the stream\n // pipeline, not as canonical events.\n \"response.failed\": () => [],\n error: () => [],\n // No silent drops: unknown wire events flow through `streamNative` but\n // produce no canonical delta. Step 3 (canonical `other` event) replaces\n // this with a forwarded `other` delta on `TurnEvent`.\n _unknown: () => [],\n }),\n )\n"],"mappings":"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"}