@effect-uai/google 0.17.0 → 0.18.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.
Files changed (63) hide show
  1. package/README.md +3 -3
  2. package/dist/Gemini.d.mts +1 -1
  3. package/dist/Gemini.mjs +1 -1
  4. package/dist/Gemini.mjs.map +1 -1
  5. package/dist/GeminiEmbedding.d.mts +1 -1
  6. package/dist/GeminiEmbedding.d.mts.map +1 -1
  7. package/dist/GeminiEmbedding.mjs +4 -3
  8. package/dist/GeminiEmbedding.mjs.map +1 -1
  9. package/dist/GeminiImageGenerator.d.mts +1 -1
  10. package/dist/GeminiImageGenerator.d.mts.map +1 -1
  11. package/dist/GeminiImageGenerator.mjs +4 -3
  12. package/dist/GeminiImageGenerator.mjs.map +1 -1
  13. package/dist/GeminiLiveSession.d.mts +1 -1
  14. package/dist/GeminiSynthesizer.d.mts +1 -1
  15. package/dist/GeminiSynthesizer.mjs +1 -1
  16. package/dist/GeminiSynthesizer.mjs.map +1 -1
  17. package/dist/GeminiSynthesizer.test.mjs +1 -1
  18. package/dist/GoogleDeepResearch.d.mts +1 -1
  19. package/dist/GoogleDeepResearch.mjs +1 -1
  20. package/dist/GoogleDeepResearch.mjs.map +1 -1
  21. package/dist/GoogleDeepResearch.test.mjs +1 -1
  22. package/dist/LyriaGenerator.d.mts +1 -1
  23. package/dist/LyriaGenerator.d.mts.map +1 -1
  24. package/dist/LyriaGenerator.mjs +4 -3
  25. package/dist/LyriaGenerator.mjs.map +1 -1
  26. package/dist/LyriaGenerator.test.mjs +4 -142
  27. package/dist/LyriaGenerator.test.mjs.map +1 -1
  28. package/dist/codec.d.mts.map +1 -1
  29. package/dist/codec.mjs +3 -2
  30. package/dist/codec.mjs.map +1 -1
  31. package/dist/dist-DHer1cql.mjs +1533 -0
  32. package/dist/dist-DHer1cql.mjs.map +1 -0
  33. package/dist/geminiSpeechCodec.d.mts.map +1 -1
  34. package/dist/geminiSpeechCodec.mjs +4 -3
  35. package/dist/geminiSpeechCodec.mjs.map +1 -1
  36. package/dist/geminiSpeechCodec.test.mjs +5 -4
  37. package/dist/geminiSpeechCodec.test.mjs.map +1 -1
  38. package/dist/geminiTools.test.mjs +1 -1
  39. package/dist/{test.DNmyFkvJ-BPz3G1HS.mjs → index.C4tKZ0yW-DjxCdpW_.mjs} +9115 -5993
  40. package/dist/index.C4tKZ0yW-DjxCdpW_.mjs.map +1 -0
  41. package/dist/{realtimeSession-7HSIjWh4.d.mts → realtimeSession-BlBgLDdp.d.mts} +2 -2
  42. package/dist/{realtimeSession-7HSIjWh4.d.mts.map → realtimeSession-BlBgLDdp.d.mts.map} +1 -1
  43. package/dist/realtimeSession.d.mts +1 -1
  44. package/dist/realtimeSession.mjs +6 -5
  45. package/dist/realtimeSession.mjs.map +1 -1
  46. package/dist/realtimeSession.test.mjs +69 -78
  47. package/dist/realtimeSession.test.mjs.map +1 -1
  48. package/package.json +4 -4
  49. package/src/Gemini.ts +1 -1
  50. package/src/GeminiEmbedding.ts +4 -3
  51. package/src/GeminiImageGenerator.ts +4 -3
  52. package/src/GeminiSynthesizer.ts +1 -1
  53. package/src/GoogleDeepResearch.ts +1 -1
  54. package/src/LyriaGenerator.test.ts +1 -1
  55. package/src/LyriaGenerator.ts +4 -14
  56. package/src/codec.ts +3 -2
  57. package/src/geminiSpeechCodec.test.ts +4 -3
  58. package/src/geminiSpeechCodec.ts +4 -3
  59. package/src/realtimeSession.test.ts +4 -3
  60. package/src/realtimeSession.ts +5 -5
  61. package/dist/magic-string.es-CUAnjKYC.mjs +0 -1014
  62. package/dist/magic-string.es-CUAnjKYC.mjs.map +0 -1
  63. package/dist/test.DNmyFkvJ-BPz3G1HS.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"realtimeSession.test.mjs","names":["Effect","Cause","Duration","V.it","pipe","Schema","Layer","Scope","V.describe","V.it"],"sources":["../../../../node_modules/.pnpm/@effect+vitest@4.0.0-rc.111_effect@4.0.0-rc.111_vitest@4.1.11_@types+node@26.2.0_vite@7_0a4161190c2476edad4e3173ad651095/node_modules/@effect/vitest/dist/internal/internal.js","../../../../node_modules/.pnpm/@effect+vitest@4.0.0-rc.111_effect@4.0.0-rc.111_vitest@4.1.11_@types+node@26.2.0_vite@7_0a4161190c2476edad4e3173ad651095/node_modules/@effect/vitest/dist/index.js","../src/realtimeSession.test.ts"],"sourcesContent":["/**\n * @since 4.0.0\n */\nimport * as Cause from \"effect/Cause\";\nimport * as Duration from \"effect/Duration\";\nimport * as Effect from \"effect/Effect\";\nimport * as Exit from \"effect/Exit\";\nimport { flow, pipe } from \"effect/Function\";\nimport * as Layer from \"effect/Layer\";\nimport { isObject } from \"effect/Predicate\";\nimport * as Rec from \"effect/Record\";\nimport * as Schedule from \"effect/Schedule\";\nimport * as Schema from \"effect/Schema\";\nimport * as Scope from \"effect/Scope\";\nimport * as fc from \"effect/testing/FastCheck\";\nimport * as TestClock from \"effect/testing/TestClock\";\nimport * as TestConsole from \"effect/testing/TestConsole\";\nimport * as V from \"vitest\";\nconst getCurrentSuite = V.TestRunner.getCurrentSuite;\nconst runPromise = /*#__PURE__*/Effect.fnUntraced(function* (effect, _ctx) {\n const exit = yield* Effect.exit(effect);\n if (Exit.isFailure(exit)) {\n const errors = Cause.prettyErrors(exit.cause);\n for (let i = 0; i < errors.length; i++) {\n yield* Effect.logError(errors[i]);\n }\n }\n return yield* exit;\n}, (effect, _, ctx) => Effect.runPromise(effect, {\n signal: ctx?.signal\n}));\n/** @internal */\nconst runTest = ctx => effect => runPromise(effect, ctx);\nconst TestEnv = /*#__PURE__*/Layer.mergeAll(TestConsole.layer, /*#__PURE__*/TestClock.layer());\n/** @internal */\nexport const addEqualityTesters = () => {\n V.expect.addEqualityTesters([]);\n};\n/** @internal */\nconst testOptions = timeout => typeof timeout === \"number\" ? {\n timeout\n} : timeout ?? {};\nconst hookTimeout = timeout => timeout === undefined ? undefined : Duration.toMillis(Duration.fromInputUnsafe(timeout));\nconst makeItProxy = (it, overrides) => new Proxy(it, {\n apply(target, thisArg, argArray) {\n return Reflect.apply(target, thisArg, argArray);\n },\n get(target, property, receiver) {\n if (Object.hasOwn(overrides, property)) {\n return Reflect.get(overrides, property);\n }\n // do not bind: binding would strip vitest's static helpers (e.g. `describe.each`)\n return Reflect.get(target, property, receiver);\n }\n});\nconst collectTasks = (tasks, acc = []) => {\n for (let i = 0; i < tasks.length; i++) {\n const task = tasks[i];\n if (task.type === \"test\" && task.mode !== \"skip\" && task.mode !== \"todo\") {\n acc.push(task);\n } else if (task.tasks !== undefined) {\n collectTasks(task.tasks, acc);\n }\n }\n return acc;\n};\n/** @internal */\nconst makeTester = (mapEffect, it = V.it) => {\n const run = (ctx, args, self) => pipe(Effect.suspend(() => self(...args)), mapEffect, runTest(ctx));\n const f = (name, self, timeout) => it(name, testOptions(timeout), ctx => run(ctx, [ctx], self));\n const skip = (name, self, timeout) => it.skip(name, testOptions(timeout), ctx => run(ctx, [ctx], self));\n const skipIf = condition => (name, self, timeout) => it.skipIf(condition)(name, testOptions(timeout), ctx => run(ctx, [ctx], self));\n const runIf = condition => (name, self, timeout) => it.runIf(condition)(name, testOptions(timeout), ctx => run(ctx, [ctx], self));\n const only = (name, self, timeout) => it.only(name, testOptions(timeout), ctx => run(ctx, [ctx], self));\n const each = cases => (name, self, timeout) => it.for(cases)(name, testOptions(timeout), (args, ctx) => run(ctx, [args], self));\n const fails = (name, self, timeout) => V.it.fails(name, testOptions(timeout), ctx => run(ctx, [ctx], self));\n const prop = (name, arbitraries, self, timeout) => {\n if (Array.isArray(arbitraries)) {\n const arbs = arbitraries.map(arbitrary => {\n if (Schema.isSchema(arbitrary)) {\n return Schema.toArbitrary(arbitrary)(fc);\n }\n return arbitrary;\n });\n return it(name, testOptions(timeout), ctx =>\n // @ts-ignore\n fc.assert(\n // @ts-ignore\n fc.asyncProperty(...arbs, (...as) => run(ctx, [as, ctx], self)),\n // @ts-ignore\n isObject(timeout) ? timeout?.fastCheck : {}));\n }\n const arbs = fc.record(Object.keys(arbitraries).reduce(function (result, key) {\n const arb = arbitraries[key];\n Rec.assignProperty(result, key, Schema.isSchema(arb) ? Schema.toArbitrary(arb)(fc) : arb);\n return result;\n }, {}));\n return it(name, testOptions(timeout), ctx =>\n // @ts-ignore\n fc.assert(fc.asyncProperty(arbs, (...as) =>\n // @ts-ignore\n run(ctx, [as[0], ctx], self)),\n // @ts-ignore\n isObject(timeout) ? timeout?.fastCheck : {}));\n };\n return Object.assign(f, {\n skip,\n skipIf,\n runIf,\n only,\n each,\n fails,\n prop\n });\n};\n/** @internal */\nexport const prop = (name, arbitraries, self, timeout) => {\n if (Array.isArray(arbitraries)) {\n const arbs = arbitraries.map(arbitrary => {\n if (Schema.isSchema(arbitrary)) {\n throw new Error(\"Schemas are not supported yet\");\n }\n return arbitrary;\n });\n return V.it(name, testOptions(timeout),\n // @ts-ignore\n ctx => fc.assert(fc.property(...arbs, (...as) => self(as, ctx)), isObject(timeout) ? timeout?.fastCheck : {}));\n }\n const arbs = fc.record(Object.keys(arbitraries).reduce(function (result, key) {\n const arb = arbitraries[key];\n if (Schema.isSchema(arb)) {\n throw new Error(\"Schemas are not supported yet\");\n }\n Rec.assignProperty(result, key, arb);\n return result;\n }, {}));\n return V.it(name, testOptions(timeout),\n // @ts-ignore\n ctx => fc.assert(fc.property(arbs, as => self(as, ctx)), isObject(timeout) ? timeout?.fastCheck : {}));\n};\n/** @internal */\nexport const layer = (layer_, options) => (...args) => {\n const excludeTestServices = options?.excludeTestServices ?? false;\n const withTestEnv = excludeTestServices ? layer_ : Layer.provideMerge(layer_, TestEnv);\n const memoMap = options?.memoMap ?? Effect.runSync(Layer.makeMemoMap);\n const scope = Effect.runSync(Scope.make());\n const contextEffect = Layer.buildWithMemoMap(withTestEnv, memoMap, scope).pipe(Effect.orDie, Effect.cached, Effect.runSync);\n let closed = false;\n const closeScope = ctx => {\n if (closed) {\n return Promise.resolve();\n }\n closed = true;\n return runPromise(Scope.close(scope, Exit.void), ctx);\n };\n const makeIt = it => makeItProxy(it, {\n effect: makeTester(effect => Effect.flatMap(contextEffect, context => effect.pipe(Effect.scoped, Effect.provide(context))), it),\n prop,\n flakyTest,\n layer(nestedLayer, options) {\n return layer(Layer.provideMerge(nestedLayer, withTestEnv), {\n ...options,\n memoMap: Layer.forkMemoMapUnsafe(memoMap),\n excludeTestServices\n });\n }\n });\n if (args.length === 1) {\n const currentSuite = getCurrentSuite();\n const previousTasks = new Set(currentSuite.tasks);\n args[0](makeIt(V.it));\n const blockTasks = collectTasks(currentSuite.tasks.filter(task => !previousTasks.has(task)));\n if (blockTasks.length === 0) {\n V.afterAll(() => closeScope(), hookTimeout(options?.timeout));\n return;\n }\n const blockTaskSet = new Set(blockTasks);\n let remaining = blockTasks.length;\n V.beforeEach(ctx => {\n if (!blockTaskSet.has(ctx.task)) {\n return;\n }\n ctx.onTestFinished(() => {\n remaining--;\n if (remaining === 0) {\n return closeScope(ctx);\n }\n });\n return runPromise(Effect.asVoid(contextEffect), ctx);\n }, hookTimeout(options?.timeout));\n V.afterAll(() => closeScope(), hookTimeout(options?.timeout));\n return;\n }\n return V.describe(args[0], () => {\n V.beforeAll(() => runPromise(Effect.asVoid(contextEffect)), hookTimeout(options?.timeout));\n V.afterAll(() => closeScope(), hookTimeout(options?.timeout));\n return args[1](makeIt(V.it));\n });\n};\n/** @internal */\nexport 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);\n/** @internal */\nexport const makeMethods = it => makeItProxy(it, {\n effect: makeTester(flow(Effect.scoped, Effect.provide(TestEnv)), it),\n live: makeTester(Effect.scoped, it),\n flakyTest,\n layer,\n prop\n});\n/** @internal */\nexport const {\n /** @internal */\n effect,\n /** @internal */\n live\n} = /*#__PURE__*/makeMethods(V.it);\n/** @internal */\nexport const describeWrapped = (name, f) => V.describe(name, it => f(makeMethods(it)));\n//# sourceMappingURL=internal.js.map","import * as V from \"vitest\";\nimport * as internal from \"./internal/internal.js\";\n/**\n * @since 4.0.0\n */\nexport * from \"vitest\";\n/**\n * @since 4.0.0\n */\nexport const addEqualityTesters = internal.addEqualityTesters;\n/**\n * @since 4.0.0\n */\nexport const effect = internal.effect;\n/**\n * @since 4.0.0\n */\nexport const live = internal.live;\n/**\n * Share a `Layer` between multiple tests, optionally wrapping\n * the tests in a `describe` block if a name is provided.\n *\n * @since 4.0.0\n *\n * ```ts\n * import { assert, layer } from \"@effect/vitest\"\n * import { Effect, Layer, Context } from \"effect\"\n *\n * class Foo extends Context.Service<Foo, \"foo\">()(\"Foo\") {\n * static layer = Layer.succeed(Foo, \"foo\")\n * }\n *\n * class Bar extends Context.Service<Bar, \"bar\">()(\"Bar\") {\n * static layer = Layer.effect(\n * Bar,\n * Effect.map(Foo, () => \"bar\" as const)\n * )\n * }\n *\n * layer(Foo.layer)(\"layer\", (it) => {\n * it.effect(\"adds context\", () =>\n * Effect.gen(function*() {\n * const foo = yield* Foo\n * assert.strictEqual(foo, \"foo\")\n * }))\n *\n * it.layer(Bar.layer)(\"nested\", (it) => {\n * it.effect(\"adds context\", () =>\n * Effect.gen(function*() {\n * const foo = yield* Foo\n * const bar = yield* Bar\n * assert.strictEqual(foo, \"foo\")\n * assert.strictEqual(bar, \"bar\")\n * }))\n * })\n * })\n * ```\n */\nexport const layer = internal.layer;\n/**\n * @since 4.0.0\n */\nexport const flakyTest = internal.flakyTest;\n/**\n * @since 4.0.0\n */\nexport const prop = internal.prop;\n/**\n * @since 4.0.0\n */\n/**\n * @since 4.0.0\n */\nexport const it = /*#__PURE__*/internal.makeMethods(V.it);\n/**\n * @since 4.0.0\n */\nexport const makeMethods = internal.makeMethods;\n/**\n * @since 4.0.0\n */\nexport const describeWrapped = internal.describeWrapped;\n//# sourceMappingURL=index.js.map","import { describe, it } from \"@effect/vitest\"\nimport { Duration, Effect, Encoding, Fiber, Logger, Redacted, Ref, Stream } from \"effect\"\nimport { expect } from \"vitest\"\nimport type { RealtimeEvent } from \"@effect-uai/core/Realtime\"\nimport { RealtimeInput } from \"@effect-uai/core/Realtime\"\nimport type { RealtimeSessionHandle } from \"@effect-uai/core/RealtimeSession\"\nimport * as FakeWebSocket from \"@effect-uai/core/testing/FakeWebSocket\"\nimport { type GeminiLiveRequest, openSession } from \"./realtimeSession.js\"\n\nconst request: GeminiLiveRequest = {\n model: \"gemini-3.1-flash-live-preview\",\n instructions: \"be terse\",\n voiceId: \"Kore\",\n inputFormat: { container: \"raw\", encoding: \"pcm_s16le\", sampleRate: 16000, channels: 1 },\n outputFormat: { container: \"raw\", encoding: \"pcm_s16le\", sampleRate: 24000, channels: 1 },\n}\n\nconst cfg = { apiKey: Redacted.make(\"test-key\") }\n\n/** The client speaks first here, so the handshake answers `setup`. */\nconst gemini = FakeWebSocket.make({\n reply: (frame) =>\n Effect.succeed(Object.hasOwn(frame as object, \"setup\") ? [{ setupComplete: {} }] : []),\n})\n\n/** Let the socket's own turn and the adapter's fibers run. */\nconst tick = Effect.sleep(\"5 millis\")\n\n/**\n * Events are recorded as they arrive rather than collected at the end, so a\n * run that ends in a failure still says what the caller saw before it.\n */\nconst transcript = (\n server: FakeWebSocket.FakeWebSocketServer,\n script: (handle: RealtimeSessionHandle) => Effect.Effect<void, unknown>,\n options?: { readonly closeCode?: number; readonly request?: GeminiLiveRequest },\n) =>\n Effect.gen(function* () {\n const handle = yield* openSession({ ...cfg, webSocket: server.connect })(\n options?.request ?? request,\n )\n const seen = yield* Ref.make<ReadonlyArray<RealtimeEvent>>([])\n const collector = yield* Effect.forkChild(\n Effect.exit(Stream.runForEach(handle.events, (e) => Ref.update(seen, (xs) => [...xs, e]))),\n )\n yield* script(handle)\n yield* tick\n yield* server.close(options?.closeCode ?? 1000)\n const exit = yield* Fiber.join(collector)\n return { exit, events: yield* Ref.get(seen) }\n })\n\nconst tags = (events: ReadonlyArray<RealtimeEvent>) => events.map((e) => e._tag)\n\nconst audioPart = (bytes: ReadonlyArray<number>) => ({\n inlineData: {\n mimeType: \"audio/pcm;rate=24000\",\n data: Encoding.encodeBase64(new Uint8Array(bytes)),\n },\n})\n\ndescribe(\"Gemini live session turns\", () => {\n it.live(\"mints one turn id for a whole answer, and reports its usage at the end\", () =>\n Effect.gen(function* () {\n const server = yield* gemini\n const { events } = yield* transcript(server, () =>\n Effect.gen(function* () {\n // 3.1 packs several parts, and their transcription, into one message.\n yield* server.push({\n serverContent: {\n modelTurn: { parts: [audioPart([1, 2, 3]), { thought: true, text: \"planning\" }] },\n outputTranscription: { text: \"hi\" },\n },\n })\n yield* server.push({\n serverContent: { modelTurn: { parts: [audioPart([4, 5])] } },\n usageMetadata: { promptTokenCount: 10, responseTokenCount: 20, totalTokenCount: 30 },\n })\n yield* server.push({ serverContent: { turnComplete: true } })\n }),\n )\n\n // The thought part is the model reasoning, not something to speak.\n expect(tags(events)).toEqual([\n \"ResponseStarted\",\n \"AudioDelta\",\n \"OutputTranscriptDelta\",\n \"AudioDelta\",\n \"ResponseDone\",\n ])\n // The wire carries no response id, so every event of the turn shares one.\n expect(new Set(events.map((e) => (\"responseId\" in e ? e.responseId : \"\")))).toEqual(\n new Set([\"turn_1\"]),\n )\n const done = events[4]\n expect(done?._tag === \"ResponseDone\" && done.reason).toBe(\"complete\")\n expect(done?._tag === \"ResponseDone\" && done.usage?.total_tokens).toBe(30)\n }).pipe(Effect.scoped),\n )\n\n it.live(\"ends an interrupted turn once, and numbers the next one after it\", () =>\n Effect.gen(function* () {\n const server = yield* gemini\n const { events } = yield* transcript(server, () =>\n Effect.gen(function* () {\n yield* server.push({ serverContent: { modelTurn: { parts: [audioPart([1])] } } })\n yield* server.push({ serverContent: { interrupted: true } })\n // The server follows an interruption with `turnComplete`, which\n // would otherwise end the same turn a second time.\n yield* server.push({ serverContent: { turnComplete: true } })\n yield* server.push({ serverContent: { modelTurn: { parts: [audioPart([2])] } } })\n yield* server.push({ serverContent: { turnComplete: true } })\n }),\n )\n\n expect(tags(events)).toEqual([\n \"ResponseStarted\",\n \"AudioDelta\",\n \"Interrupted\",\n \"ResponseDone\",\n \"ResponseStarted\",\n \"AudioDelta\",\n \"ResponseDone\",\n ])\n const interrupted = events[3]\n expect(interrupted?._tag === \"ResponseDone\" && interrupted.reason).toBe(\"interrupted\")\n const next = events[4]\n expect(next?._tag === \"ResponseStarted\" && next.responseId).toBe(\"turn_2\")\n }).pipe(Effect.scoped),\n )\n\n it.live(\"marks the user's words interim until the utterance is transcribed\", () =>\n Effect.gen(function* () {\n const server = yield* gemini\n const { events } = yield* transcript(server, () =>\n Effect.gen(function* () {\n yield* server.push({ serverContent: { interimInputTranscription: { text: \"weather\" } } })\n yield* server.push({\n serverContent: { inputTranscription: { text: \"weather in Lisbon\" } },\n })\n }),\n )\n\n // A transcript belongs to no turn, so none is started for it.\n expect(events).toEqual([\n { _tag: \"InputTranscript\", text: \"weather\", final: false },\n { _tag: \"InputTranscript\", text: \"weather in Lisbon\", final: true },\n ])\n }).pipe(Effect.scoped),\n )\n\n it.live(\"ends the stream as an incomplete turn when a turn is still running\", () =>\n Effect.gen(function* () {\n const server = yield* gemini\n const { exit } = yield* transcript(server, () =>\n server.push({ serverContent: { modelTurn: { parts: [audioPart([1])] } } }),\n )\n\n // A close must never look like a finished turn.\n expect(exit._tag).toBe(\"Failure\")\n expect(JSON.stringify(exit)).toContain(\"IncompleteTurn\")\n }).pipe(Effect.scoped),\n )\n\n it.live(\"fails when the socket closes before the configuration is accepted\", () =>\n Effect.gen(function* () {\n const mute = yield* FakeWebSocket.make()\n const opened = yield* Effect.forkChild(\n Effect.exit(openSession({ ...cfg, webSocket: mute.connect })(request)),\n )\n yield* tick\n yield* mute.close(1000)\n\n const exit = yield* Fiber.join(opened)\n expect(exit._tag).toBe(\"Failure\")\n expect(JSON.stringify(exit)).toContain(\"Unavailable\")\n }).pipe(Effect.scoped),\n )\n})\n\ndescribe(\"Gemini live session tools\", () => {\n it.live(\"answers a call with the name the server gave it\", () =>\n Effect.gen(function* () {\n const server = yield* gemini\n const { events } = yield* transcript(server, (handle) =>\n Effect.gen(function* () {\n yield* server.push({\n toolCall: {\n functionCalls: [{ id: \"fc_1\", name: \"get_weather\", args: { city: \"Lisbon\" } }],\n },\n })\n yield* tick\n yield* handle.send(\n RealtimeInput.ToolResult({\n output: {\n type: \"function_call_output\",\n call_id: \"fc_1\",\n output: '{\"celsius\":32}',\n providerData: undefined,\n },\n }),\n )\n yield* server.push({ serverContent: { turnComplete: true } })\n }),\n )\n\n const call = events.find((e) => e._tag === \"ToolCall\")\n expect(call?._tag === \"ToolCall\" && call.call.arguments).toBe('{\"city\":\"Lisbon\"}')\n // A call arrives with no turn open, so it gets one of its own.\n expect(call?._tag === \"ToolCall\" && call.responseId).toBe(\"turn_1\")\n\n const sent = yield* server.sent\n const response = sent.find((f: any) => f.toolResponse !== undefined) as any\n // The name comes from the call, and the payload has to be an object.\n // `WHEN_IDLE` by default: a model that kept talking while the tool ran\n // finishes the sentence rather than cutting itself off to report.\n expect(response.toolResponse.functionResponses).toEqual([\n {\n id: \"fc_1\",\n name: \"get_weather\",\n response: { celsius: 32 },\n scheduling: \"WHEN_IDLE\",\n },\n ])\n }).pipe(Effect.scoped),\n )\n\n it.live(\"reports a result at once when the caller asks it to interrupt\", () =>\n Effect.gen(function* () {\n const server = yield* gemini\n yield* transcript(\n server,\n (handle) =>\n Effect.gen(function* () {\n yield* server.push({\n toolCall: { functionCalls: [{ id: \"fc_1\", name: \"get_weather\", args: {} }] },\n })\n yield* tick\n yield* handle.send(\n RealtimeInput.ToolResult({\n output: {\n type: \"function_call_output\",\n call_id: \"fc_1\",\n output: \"{}\",\n providerData: undefined,\n },\n }),\n )\n }),\n { request: { ...request, toolScheduling: \"interrupt\" } },\n )\n\n const sent = yield* server.sent\n const response = sent.find((f: any) => f.toolResponse !== undefined) as any\n expect(response.toolResponse.functionResponses[0].scheduling).toBe(\"INTERRUPT\")\n }).pipe(Effect.scoped),\n )\n\n it.live(\"rejects a result for a call this session never made\", () =>\n Effect.gen(function* () {\n const server = yield* gemini\n const handle = yield* openSession({ ...cfg, webSocket: server.connect })(request)\n const failure = yield* Effect.exit(\n handle.send(\n RealtimeInput.ToolResult({\n output: {\n type: \"function_call_output\",\n call_id: \"fc_unknown\",\n output: \"{}\",\n providerData: undefined,\n },\n }),\n ),\n )\n\n expect(failure._tag).toBe(\"Failure\")\n expect(JSON.stringify(failure)).toContain(\"InvalidRequest\")\n expect((yield* server.sent).some((f: any) => f.toolResponse !== undefined)).toBe(false)\n }).pipe(Effect.scoped),\n )\n})\n\ndescribe(\"Gemini live session lifetime\", () => {\n it.live(\"keeps only a resumable handle, and reads the closing warning as a duration\", () =>\n Effect.gen(function* () {\n const server = yield* gemini\n const { events, exit } = yield* transcript(server, () =>\n Effect.gen(function* () {\n // Sent while a tool runs: no handle, and the stored one must stand.\n yield* server.push({ sessionResumptionUpdate: { newHandle: \"\", resumable: false } })\n yield* server.push({ sessionResumptionUpdate: { newHandle: \"h1\", resumable: true } })\n yield* server.push({ goAway: { timeLeft: \"60s\" } })\n }),\n )\n\n expect(tags(events)).toEqual([\"ResumptionHandle\", \"SessionEnding\"])\n const handle = events[0]\n expect(handle?._tag === \"ResumptionHandle\" && handle.handle).toBe(\"h1\")\n const ending = events[1]\n // A proto duration string, not a number.\n expect(ending?._tag === \"SessionEnding\" && ending.timeLeft).toEqual(Duration.seconds(60))\n // The close `goAway` announced is the lifetime cap, not a clean end, so\n // a caller can tell \"reconnect\" from \"we are done here\".\n expect(JSON.stringify(exit)).toContain(\"SessionExpired\")\n }).pipe(Effect.scoped),\n )\n\n it.live(\"ends cleanly when the close was not announced\", () =>\n Effect.gen(function* () {\n const server = yield* gemini\n const { exit } = yield* transcript(server, () =>\n server.push({ serverContent: { turnComplete: true } }),\n )\n\n expect(exit._tag).toBe(\"Success\")\n }).pipe(Effect.scoped),\n )\n})\n\n/** The `CapabilityWarning` payloads a run produced, in order. */\nconst warningCollector = () => {\n const seen: Array<{ readonly field: string; readonly value?: unknown }> = []\n const logger = Logger.make((options) => {\n const [label, warning] = options.message as ReadonlyArray<any>\n if (label === \"Capability dropped\") seen.push(warning)\n })\n return { seen, layer: Logger.layer([logger]) }\n}\n\nconst userText = (text: string) =>\n ({\n type: \"message\",\n role: \"user\",\n content: [{ type: \"input_text\", text, providerData: undefined }],\n providerData: undefined,\n }) as const\n\nconst call = (id: string) =>\n ({\n type: \"function_call\",\n call_id: id,\n name: \"get_time\",\n arguments: \"{}\",\n providerData: undefined,\n }) as const\n\ndescribe(\"Gemini live session history\", () => {\n it.live(\"names each kind of item the text-only seed cannot carry, once\", () =>\n Effect.gen(function* () {\n const server = yield* gemini\n const warnings = warningCollector()\n\n yield* openSession({ ...cfg, webSocket: server.connect })({\n ...request,\n history: [\n userText(\"what time is it\"),\n call(\"fc_1\"),\n call(\"fc_2\"),\n {\n type: \"function_call_output\",\n call_id: \"fc_1\",\n output: '{\"now\":\"12:00\"}',\n providerData: undefined,\n },\n ],\n }).pipe(Effect.provide(warnings.layer))\n yield* tick\n\n // Two calls, one kind: a long tool history is not a wall of warnings.\n expect(warnings.seen.map((w) => w.value)).toEqual([\"function_call\", \"function_call_output\"])\n expect(warnings.seen.every((w) => w.field === \"history\")).toBe(true)\n\n const sent = yield* server.sent\n const seed = sent.find((f: any) => f.clientContent !== undefined) as any\n expect(seed.clientContent.turns).toEqual([\n { role: \"user\", parts: [{ text: \"what time is it\" }] },\n ])\n }).pipe(Effect.scoped),\n )\n})\n\ndescribe(\"Gemini live session video\", () => {\n it.live(\"sends frame bytes inline, and refuses a frame it would have to fetch\", () =>\n Effect.gen(function* () {\n const server = yield* gemini\n yield* transcript(server, (handle) =>\n Effect.gen(function* () {\n yield* handle.send(\n RealtimeInput.VideoFrame({\n frame: { _tag: \"bytes\", bytes: new Uint8Array([1, 2]), mimeType: \"image/jpeg\" },\n }),\n )\n // A URL would need an upload through the Files API first.\n const exit = yield* Effect.exit(\n handle.send(\n RealtimeInput.VideoFrame({\n frame: { _tag: \"url\", url: \"https://example.com/frame.jpg\" },\n }),\n ),\n )\n expect(JSON.stringify(exit)).toContain(\"Unsupported\")\n }),\n )\n\n const sent = yield* server.sent\n expect(sent.filter((f: any) => f.realtimeInput?.video !== undefined)).toEqual([\n {\n realtimeInput: {\n video: { data: Encoding.encodeBase64(new Uint8Array([1, 2])), mimeType: \"image/jpeg\" },\n },\n },\n ])\n }).pipe(Effect.scoped),\n )\n})\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
1
+ {"version":3,"file":"realtimeSession.test.mjs","names":["Effect","Cause","Duration","pipe","Layer","Scope","V.describe","it","V.it","internal.it"],"sources":["../../../../node_modules/.pnpm/@effect+vitest@4.0.1_effect@4.0.1_vitest@5.0.3_@types+node@26.2.0_vite@7.3.2_@types+nod_65816e3353e20bfeb9b2e1494bdddeef/node_modules/@effect/vitest/dist/internal/internal.js","../../../../node_modules/.pnpm/@effect+vitest@4.0.1_effect@4.0.1_vitest@5.0.3_@types+node@26.2.0_vite@7.3.2_@types+nod_65816e3353e20bfeb9b2e1494bdddeef/node_modules/@effect/vitest/dist/index.js","../src/realtimeSession.test.ts"],"sourcesContent":["/**\n * @since 4.0.0\n */\nimport * as Arbitrary from \"effect/Arbitrary\";\nimport * as Cause from \"effect/Cause\";\nimport * as Duration from \"effect/Duration\";\nimport * as Effect from \"effect/Effect\";\nimport * as Exit from \"effect/Exit\";\nimport { constVoid, flow, pipe } from \"effect/Function\";\nimport * as Layer from \"effect/Layer\";\nimport * as Schedule from \"effect/Schedule\";\nimport * as Scope from \"effect/Scope\";\nimport * as TestClock from \"effect/testing/TestClock\";\nimport * as TestConsole from \"effect/testing/TestConsole\";\nimport * as V from \"vitest\";\nconst getCurrentSuite = V.TestRunner.getCurrentSuite;\nconst runPromise = /*#__PURE__*/Effect.fnUntraced(function* (effect, _ctx) {\n const exit = yield* Effect.exit(effect);\n if (Exit.isFailure(exit)) {\n const errors = Cause.prettyErrors(exit.cause);\n for (let i = 0; i < errors.length; i++) {\n yield* Effect.logError(errors[i]);\n }\n }\n return yield* exit;\n}, (effect, _, ctx) => Effect.runPromise(effect, {\n signal: ctx?.signal\n}));\n/** @internal */\nconst runTest = ctx => effect => {\n const promise = runPromise(effect, ctx);\n if (ctx) {\n // Vitest stops awaiting the test promise once the signal aborts (timeout or\n // cancellation), so only then add a hook that waits for the finalizers.\n // Registering it unconditionally would change the teardown of every test.\n const onAbort = () => ctx.onTestFinished(() => promise.then(constVoid, constVoid));\n ctx.signal.addEventListener(\"abort\", onAbort, {\n once: true\n });\n const cleanup = () => ctx.signal.removeEventListener(\"abort\", onAbort);\n promise.then(cleanup, cleanup);\n // A retry after a timed-out attempt reuses the aborted signal, so no event fires.\n if (ctx.signal.aborted) onAbort();\n }\n return promise;\n};\nconst TestEnv = /*#__PURE__*/Layer.mergeAll(TestConsole.layer, /*#__PURE__*/TestClock.layer());\n/** @internal */\nexport const addEqualityTesters = () => {\n V.expect.addEqualityTesters([]);\n};\n/** @internal */\nconst testOptions = timeout => typeof timeout === \"number\" ? {\n timeout\n} : timeout ?? {};\nconst hookTimeout = timeout => timeout === undefined ? undefined : Duration.toMillis(Duration.fromInputUnsafe(timeout));\nconst propertyTestOptions = timeout => typeof timeout === \"number\" ? undefined : timeout;\nconst checkOptions = timeout => propertyTestOptions(timeout)?.arbitrary;\nconst compileArbitraryInput = input => Arbitrary.isArbitrary(input) ? input : Arbitrary.schema(input);\nconst makeArbitrary = arbitraries => Arbitrary.all(Array.isArray(arbitraries) ? arbitraries.map(compileArbitraryInput) : Object.fromEntries(Object.entries(arbitraries).map(([key, input]) => [key, compileArbitraryInput(input)])));\nconst normalizeProperty = (property, value) => Effect.catchCause(Effect.suspend(() => {\n const output = property(value);\n return Effect.isEffect(output) ? output : Effect.succeed(output);\n}), cause => Cause.hasInterrupts(cause) ? Effect.failCause(cause) : Effect.fail(cause));\nconst runCheck = (ctx, arbitrary, property, options) => runTest(ctx)(Effect.flatMapEager(Arbitrary.checkEffect(arbitrary, value => normalizeProperty(property, value), options), result => {\n const failure = Arbitrary.formatCheckFailure(result);\n return failure === undefined ? Effect.void : Effect.die(new Error(failure));\n}));\n// Vitest decides which fixtures to set up by parsing the source of a test\n// function's context parameter, and there is no public API to supply the names\n// for a wrapper, so wrappers expose the source of the function they call.\nconst withFixturesOf = (source, f) => Object.defineProperty(f, \"toString\", {\n value: () => source.toString()\n});\nconst makeItProxy = (it, overrides) => new Proxy(it, {\n apply(target, thisArg, argArray) {\n return Reflect.apply(target, thisArg, argArray);\n },\n get(target, property, receiver) {\n if (Object.hasOwn(overrides, property)) {\n return Reflect.get(overrides, property);\n }\n // do not bind: binding would strip vitest's static helpers (e.g. `describe.each`)\n return Reflect.get(target, property, receiver);\n }\n});\nconst collectTasks = (tasks, acc = []) => {\n for (let i = 0; i < tasks.length; i++) {\n const task = tasks[i];\n if (task.type === \"test\" && task.mode !== \"skip\" && task.mode !== \"todo\") {\n acc.push(task);\n } else if (task.tasks !== undefined) {\n collectTasks(task.tasks, acc);\n }\n }\n return acc;\n};\nconst registerProp = (it, name, arbitraries, property, timeout) => {\n const arbitrary = makeArbitrary(arbitraries);\n // Property callbacks receive only the base context; the empty source requests no fixtures.\n it(name, testOptions(timeout), withFixturesOf(() => {}, ctx => runCheck(ctx, arbitrary, values => property(values, ctx), checkOptions(timeout))));\n};\nconst makeTester = (mapEffect, it) => {\n const run = (ctx, args, self) => pipe(Effect.suspend(() => self(...args)), mapEffect, runTest(ctx));\n const register = test => (name, self, timeout) => test(name, testOptions(timeout), withFixturesOf(self, ctx => run(ctx, [ctx], self)));\n const each = cases => (name, self, timeout) => it.for(cases)(name, testOptions(timeout), withFixturesOf(self, (args, ctx) => run(ctx, [args, ctx], self).then(constVoid)));\n const prop = (name, arbitraries, self, timeout) => registerProp(it, name, arbitraries, (values, ctx) => Effect.mapEager(mapEffect(Effect.suspend(() => self(values, ctx))), value => value !== false), timeout);\n return Object.assign(register(it), {\n skip: register(it.skip),\n skipIf: condition => register(it.skipIf(condition)),\n runIf: condition => register(it.runIf(condition)),\n only: register(it.only),\n each,\n fails: register(it.fails),\n prop\n });\n};\nconst makeProp = it => (name, arbitraries, self, timeout) => registerProp(it, name, arbitraries, (values, ctx) => self(values, ctx) !== false, timeout);\nconst makeLayer = it => (layer_, options) => (...args) => {\n const excludeTestServices = options?.excludeTestServices ?? false;\n const withTestEnv = excludeTestServices ? layer_ : Layer.provideMerge(layer_, TestEnv);\n const memoMap = options?.memoMap ?? Effect.runSync(Layer.makeMemoMap);\n const scope = Effect.runSync(Scope.make());\n const contextEffect = Layer.buildWithMemoMap(withTestEnv, memoMap, scope).pipe(Effect.orDie, Effect.cached, Effect.runSync);\n let closed = false;\n const closeScope = () => {\n if (closed) {\n return Promise.resolve();\n }\n closed = true;\n // Layer cleanup must outlive the last test's already-aborted signal.\n return runPromise(Scope.close(scope, Exit.void));\n };\n const methods = makeItProxy(it, {\n effect: makeTester(effect => Effect.flatMap(contextEffect, context => effect.pipe(Effect.scoped, Effect.provide(context))), it),\n prop: makeProp(it),\n flakyTest,\n layer(nestedLayer, options) {\n return makeLayer(it)(Layer.provideMerge(nestedLayer, withTestEnv), {\n ...options,\n memoMap: Layer.forkMemoMapUnsafe(memoMap),\n excludeTestServices\n });\n }\n });\n if (args.length === 1) {\n const currentSuite = getCurrentSuite();\n const previousTasks = new Set(currentSuite.tasks);\n args[0](methods);\n const blockTasks = collectTasks(currentSuite.tasks.filter(task => !previousTasks.has(task)));\n if (blockTasks.length === 0) {\n V.afterAll(() => closeScope(), hookTimeout(options?.timeout));\n return;\n }\n const blockTaskSet = new Set(blockTasks);\n let remaining = blockTasks.length;\n V.beforeEach(\n // Destructured so Vitest can parse the hook once the suite defines fixtures.\n ({\n onTestFinished,\n signal,\n task\n }) => {\n if (!blockTaskSet.has(task)) {\n return;\n }\n onTestFinished(() => {\n remaining--;\n if (remaining === 0) {\n return closeScope();\n }\n });\n return runPromise(Effect.asVoid(contextEffect), {\n signal\n });\n }, hookTimeout(options?.timeout));\n V.afterAll(() => closeScope(), hookTimeout(options?.timeout));\n return;\n }\n const suiteOptions = options?.concurrent === undefined ? {} : {\n concurrent: options.concurrent\n };\n return V.describe(args[0], suiteOptions, () => {\n V.beforeAll(() => runPromise(Effect.asVoid(contextEffect)), hookTimeout(options?.timeout));\n V.afterAll(() => closeScope(), hookTimeout(options?.timeout));\n return args[1](methods);\n });\n};\n/** @internal */\nexport 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);\n/** @internal */\nexport const makeMethods = it => makeItProxy(it, {\n effect: makeTester(flow(Effect.scoped, Effect.provide(TestEnv)), it),\n live: makeTester(Effect.scoped, it),\n flakyTest,\n layer: makeLayer(it),\n prop: makeProp(it)\n});\n/** @internal */\nexport const it = /*#__PURE__*/makeMethods(V.it);\n/** @internal */\nexport const {\n /** @internal */\n effect,\n /** @internal */\n layer,\n /** @internal */\n live,\n /** @internal */\n prop\n} = it;\n/** @internal */\nexport const describeWrapped = (name, f) => V.describe(name, () => f(it));\n//# sourceMappingURL=internal.js.map","import * as internal from \"./internal/internal.js\";\n/**\n * Re-exports the `vitest` API unchanged.\n *\n * @stability unstable\n * @since 4.0.0\n */\nexport * from \"vitest\";\n/**\n * @since 4.0.0\n */\nexport const addEqualityTesters = internal.addEqualityTesters;\n/**\n * @since 4.0.0\n */\nexport const effect = internal.effect;\n/**\n * @since 4.0.0\n */\nexport const live = internal.live;\n/**\n * Share a `Layer` between multiple tests, optionally wrapping\n * the tests in a `describe` block if a name is provided.\n *\n * Named layers accept `concurrent` to override inherited suite concurrency.\n * Anonymous layers always inherit the enclosing suite's concurrency.\n * Use `ctx.expect` in concurrent tests for test-local snapshots and assertion counts.\n *\n * @since 4.0.0\n *\n * ```ts\n * import { assert, layer } from \"@effect/vitest\"\n * import { Effect, Layer, Context } from \"effect\"\n *\n * class Foo extends Context.Service<Foo, \"foo\">()(\"Foo\") {\n * static layer = Layer.succeed(Foo, \"foo\")\n * }\n *\n * class Bar extends Context.Service<Bar, \"bar\">()(\"Bar\") {\n * static layer = Layer.effect(\n * Bar,\n * Effect.map(Foo, () => \"bar\" as const)\n * )\n * }\n *\n * layer(Foo.layer)(\"layer\", (it) => {\n * it.effect(\"adds context\", () =>\n * Effect.gen(function*() {\n * const foo = yield* Foo\n * assert.strictEqual(foo, \"foo\")\n * }))\n *\n * it.layer(Bar.layer)(\"nested\", (it) => {\n * it.effect(\"adds context\", () =>\n * Effect.gen(function*() {\n * const foo = yield* Foo\n * const bar = yield* Bar\n * assert.strictEqual(foo, \"foo\")\n * assert.strictEqual(bar, \"bar\")\n * }))\n * })\n * })\n * ```\n */\nexport const layer = internal.layer;\n/**\n * @since 4.0.0\n */\nexport const flakyTest = internal.flakyTest;\n/**\n * @since 4.0.0\n */\nexport const prop = internal.prop;\n/**\n * @since 4.0.0\n */\n/**\n * @since 4.0.0\n */\nexport const it = internal.it;\n/**\n * Creates the Effect test helpers for a Vitest test API, such as one extended with fixtures.\n *\n * **Details**\n *\n * Tests receive the fixtures they destructure from their context. Vitest sets them up before the test and tears\n * them down after the test's scope closes, as it does for its own tests. `it.effect.each` passes the context\n * after the test case, and named and anonymous `it.layer` blocks keep the fixtures.\n *\n * **Gotchas**\n *\n * Vitest reads the destructured names to decide which fixtures to set up. Once any fixture is defined, a test that\n * takes the whole context as a plain parameter, such as `(ctx) =>`, fails with a `FixtureParseError`. Property\n * tests receive only the base test context and cannot request fixtures; auto fixtures still run.\n *\n * **Example** (Using a Vitest fixture in an Effect test)\n *\n * ```ts\n * import { assert, makeMethods, test } from \"@effect/vitest\"\n * import { Effect } from \"effect\"\n *\n * const it = makeMethods(\n * test.extend(\"config\", { scope: \"file\" }, () => ({ port: 3000 }))\n * )\n *\n * it.effect(\"reads the config fixture\", ({ config }) =>\n * Effect.sync(() => {\n * assert.strictEqual(config.port, 3000)\n * }))\n * ```\n *\n * @since 4.0.0\n */\nexport const makeMethods = internal.makeMethods;\n/**\n * @since 4.0.0\n */\nexport const describeWrapped = internal.describeWrapped;\n//# sourceMappingURL=index.js.map","import { describe, it } from \"@effect/vitest\"\nimport { Duration, Effect, Fiber, Logger, Redacted, Ref, Stream } from \"effect\"\nimport { Base64 } from \"effect/encoding\"\nimport { expect } from \"vitest\"\nimport type { RealtimeEvent } from \"@effect-uai/core/Realtime\"\nimport { RealtimeInput } from \"@effect-uai/core/Realtime\"\nimport type { RealtimeSessionHandle } from \"@effect-uai/core/RealtimeSession\"\nimport * as FakeWebSocket from \"@effect-uai/core/testing/FakeWebSocket\"\nimport { type GeminiLiveRequest, openSession } from \"./realtimeSession.js\"\n\nconst request: GeminiLiveRequest = {\n model: \"gemini-3.1-flash-live-preview\",\n instructions: \"be terse\",\n voiceId: \"Kore\",\n inputFormat: { container: \"raw\", encoding: \"pcm_s16le\", sampleRate: 16000, channels: 1 },\n outputFormat: { container: \"raw\", encoding: \"pcm_s16le\", sampleRate: 24000, channels: 1 },\n}\n\nconst cfg = { apiKey: Redacted.make(\"test-key\") }\n\n/** The client speaks first here, so the handshake answers `setup`. */\nconst gemini = FakeWebSocket.make({\n reply: (frame) =>\n Effect.succeed(Object.hasOwn(frame as object, \"setup\") ? [{ setupComplete: {} }] : []),\n})\n\n/** Let the socket's own turn and the adapter's fibers run. */\nconst tick = Effect.sleep(\"5 millis\")\n\n/**\n * Events are recorded as they arrive rather than collected at the end, so a\n * run that ends in a failure still says what the caller saw before it.\n */\nconst transcript = (\n server: FakeWebSocket.FakeWebSocketServer,\n script: (handle: RealtimeSessionHandle) => Effect.Effect<void, unknown>,\n options?: { readonly closeCode?: number; readonly request?: GeminiLiveRequest },\n) =>\n Effect.gen(function* () {\n const handle = yield* openSession({ ...cfg, webSocket: server.connect })(\n options?.request ?? request,\n )\n const seen = yield* Ref.make<ReadonlyArray<RealtimeEvent>>([])\n const collector = yield* Effect.forkChild(\n Effect.exit(Stream.runForEach(handle.events, (e) => Ref.update(seen, (xs) => [...xs, e]))),\n )\n yield* script(handle)\n yield* tick\n yield* server.close(options?.closeCode ?? 1000)\n const exit = yield* Fiber.join(collector)\n return { exit, events: yield* Ref.get(seen) }\n })\n\nconst tags = (events: ReadonlyArray<RealtimeEvent>) => events.map((e) => e._tag)\n\nconst audioPart = (bytes: ReadonlyArray<number>) => ({\n inlineData: {\n mimeType: \"audio/pcm;rate=24000\",\n data: Base64.encode(new Uint8Array(bytes)),\n },\n})\n\ndescribe(\"Gemini live session turns\", () => {\n it.live(\"mints one turn id for a whole answer, and reports its usage at the end\", () =>\n Effect.gen(function* () {\n const server = yield* gemini\n const { events } = yield* transcript(server, () =>\n Effect.gen(function* () {\n // 3.1 packs several parts, and their transcription, into one message.\n yield* server.push({\n serverContent: {\n modelTurn: { parts: [audioPart([1, 2, 3]), { thought: true, text: \"planning\" }] },\n outputTranscription: { text: \"hi\" },\n },\n })\n yield* server.push({\n serverContent: { modelTurn: { parts: [audioPart([4, 5])] } },\n usageMetadata: { promptTokenCount: 10, responseTokenCount: 20, totalTokenCount: 30 },\n })\n yield* server.push({ serverContent: { turnComplete: true } })\n }),\n )\n\n // The thought part is the model reasoning, not something to speak.\n expect(tags(events)).toEqual([\n \"ResponseStarted\",\n \"AudioDelta\",\n \"OutputTranscriptDelta\",\n \"AudioDelta\",\n \"ResponseDone\",\n ])\n // The wire carries no response id, so every event of the turn shares one.\n expect(new Set(events.map((e) => (\"responseId\" in e ? e.responseId : \"\")))).toEqual(\n new Set([\"turn_1\"]),\n )\n const done = events[4]\n expect(done?._tag === \"ResponseDone\" && done.reason).toBe(\"complete\")\n expect(done?._tag === \"ResponseDone\" && done.usage?.total_tokens).toBe(30)\n }).pipe(Effect.scoped),\n )\n\n it.live(\"ends an interrupted turn once, and numbers the next one after it\", () =>\n Effect.gen(function* () {\n const server = yield* gemini\n const { events } = yield* transcript(server, () =>\n Effect.gen(function* () {\n yield* server.push({ serverContent: { modelTurn: { parts: [audioPart([1])] } } })\n yield* server.push({ serverContent: { interrupted: true } })\n // The server follows an interruption with `turnComplete`, which\n // would otherwise end the same turn a second time.\n yield* server.push({ serverContent: { turnComplete: true } })\n yield* server.push({ serverContent: { modelTurn: { parts: [audioPart([2])] } } })\n yield* server.push({ serverContent: { turnComplete: true } })\n }),\n )\n\n expect(tags(events)).toEqual([\n \"ResponseStarted\",\n \"AudioDelta\",\n \"Interrupted\",\n \"ResponseDone\",\n \"ResponseStarted\",\n \"AudioDelta\",\n \"ResponseDone\",\n ])\n const interrupted = events[3]\n expect(interrupted?._tag === \"ResponseDone\" && interrupted.reason).toBe(\"interrupted\")\n const next = events[4]\n expect(next?._tag === \"ResponseStarted\" && next.responseId).toBe(\"turn_2\")\n }).pipe(Effect.scoped),\n )\n\n it.live(\"marks the user's words interim until the utterance is transcribed\", () =>\n Effect.gen(function* () {\n const server = yield* gemini\n const { events } = yield* transcript(server, () =>\n Effect.gen(function* () {\n yield* server.push({ serverContent: { interimInputTranscription: { text: \"weather\" } } })\n yield* server.push({\n serverContent: { inputTranscription: { text: \"weather in Lisbon\" } },\n })\n }),\n )\n\n // A transcript belongs to no turn, so none is started for it.\n expect(events).toEqual([\n { _tag: \"InputTranscript\", text: \"weather\", final: false },\n { _tag: \"InputTranscript\", text: \"weather in Lisbon\", final: true },\n ])\n }).pipe(Effect.scoped),\n )\n\n it.live(\"ends the stream as an incomplete turn when a turn is still running\", () =>\n Effect.gen(function* () {\n const server = yield* gemini\n const { exit } = yield* transcript(server, () =>\n server.push({ serverContent: { modelTurn: { parts: [audioPart([1])] } } }),\n )\n\n // A close must never look like a finished turn.\n expect(exit._tag).toBe(\"Failure\")\n expect(JSON.stringify(exit)).toContain(\"IncompleteTurn\")\n }).pipe(Effect.scoped),\n )\n\n it.live(\"fails when the socket closes before the configuration is accepted\", () =>\n Effect.gen(function* () {\n const mute = yield* FakeWebSocket.make()\n const opened = yield* Effect.forkChild(\n Effect.exit(openSession({ ...cfg, webSocket: mute.connect })(request)),\n )\n yield* tick\n yield* mute.close(1000)\n\n const exit = yield* Fiber.join(opened)\n expect(exit._tag).toBe(\"Failure\")\n expect(JSON.stringify(exit)).toContain(\"Unavailable\")\n }).pipe(Effect.scoped),\n )\n})\n\ndescribe(\"Gemini live session tools\", () => {\n it.live(\"answers a call with the name the server gave it\", () =>\n Effect.gen(function* () {\n const server = yield* gemini\n const { events } = yield* transcript(server, (handle) =>\n Effect.gen(function* () {\n yield* server.push({\n toolCall: {\n functionCalls: [{ id: \"fc_1\", name: \"get_weather\", args: { city: \"Lisbon\" } }],\n },\n })\n yield* tick\n yield* handle.send(\n RealtimeInput.ToolResult({\n output: {\n type: \"function_call_output\",\n call_id: \"fc_1\",\n output: '{\"celsius\":32}',\n providerData: undefined,\n },\n }),\n )\n yield* server.push({ serverContent: { turnComplete: true } })\n }),\n )\n\n const call = events.find((e) => e._tag === \"ToolCall\")\n expect(call?._tag === \"ToolCall\" && call.call.arguments).toBe('{\"city\":\"Lisbon\"}')\n // A call arrives with no turn open, so it gets one of its own.\n expect(call?._tag === \"ToolCall\" && call.responseId).toBe(\"turn_1\")\n\n const sent = yield* server.sent\n const response = sent.find((f: any) => f.toolResponse !== undefined) as any\n // The name comes from the call, and the payload has to be an object.\n // `WHEN_IDLE` by default: a model that kept talking while the tool ran\n // finishes the sentence rather than cutting itself off to report.\n expect(response.toolResponse.functionResponses).toEqual([\n {\n id: \"fc_1\",\n name: \"get_weather\",\n response: { celsius: 32 },\n scheduling: \"WHEN_IDLE\",\n },\n ])\n }).pipe(Effect.scoped),\n )\n\n it.live(\"reports a result at once when the caller asks it to interrupt\", () =>\n Effect.gen(function* () {\n const server = yield* gemini\n yield* transcript(\n server,\n (handle) =>\n Effect.gen(function* () {\n yield* server.push({\n toolCall: { functionCalls: [{ id: \"fc_1\", name: \"get_weather\", args: {} }] },\n })\n yield* tick\n yield* handle.send(\n RealtimeInput.ToolResult({\n output: {\n type: \"function_call_output\",\n call_id: \"fc_1\",\n output: \"{}\",\n providerData: undefined,\n },\n }),\n )\n }),\n { request: { ...request, toolScheduling: \"interrupt\" } },\n )\n\n const sent = yield* server.sent\n const response = sent.find((f: any) => f.toolResponse !== undefined) as any\n expect(response.toolResponse.functionResponses[0].scheduling).toBe(\"INTERRUPT\")\n }).pipe(Effect.scoped),\n )\n\n it.live(\"rejects a result for a call this session never made\", () =>\n Effect.gen(function* () {\n const server = yield* gemini\n const handle = yield* openSession({ ...cfg, webSocket: server.connect })(request)\n const failure = yield* Effect.exit(\n handle.send(\n RealtimeInput.ToolResult({\n output: {\n type: \"function_call_output\",\n call_id: \"fc_unknown\",\n output: \"{}\",\n providerData: undefined,\n },\n }),\n ),\n )\n\n expect(failure._tag).toBe(\"Failure\")\n expect(JSON.stringify(failure)).toContain(\"InvalidRequest\")\n expect((yield* server.sent).some((f: any) => f.toolResponse !== undefined)).toBe(false)\n }).pipe(Effect.scoped),\n )\n})\n\ndescribe(\"Gemini live session lifetime\", () => {\n it.live(\"keeps only a resumable handle, and reads the closing warning as a duration\", () =>\n Effect.gen(function* () {\n const server = yield* gemini\n const { events, exit } = yield* transcript(server, () =>\n Effect.gen(function* () {\n // Sent while a tool runs: no handle, and the stored one must stand.\n yield* server.push({ sessionResumptionUpdate: { newHandle: \"\", resumable: false } })\n yield* server.push({ sessionResumptionUpdate: { newHandle: \"h1\", resumable: true } })\n yield* server.push({ goAway: { timeLeft: \"60s\" } })\n }),\n )\n\n expect(tags(events)).toEqual([\"ResumptionHandle\", \"SessionEnding\"])\n const handle = events[0]\n expect(handle?._tag === \"ResumptionHandle\" && handle.handle).toBe(\"h1\")\n const ending = events[1]\n // A proto duration string, not a number.\n expect(ending?._tag === \"SessionEnding\" && ending.timeLeft).toEqual(Duration.seconds(60))\n // The close `goAway` announced is the lifetime cap, not a clean end, so\n // a caller can tell \"reconnect\" from \"we are done here\".\n expect(JSON.stringify(exit)).toContain(\"SessionExpired\")\n }).pipe(Effect.scoped),\n )\n\n it.live(\"ends cleanly when the close was not announced\", () =>\n Effect.gen(function* () {\n const server = yield* gemini\n const { exit } = yield* transcript(server, () =>\n server.push({ serverContent: { turnComplete: true } }),\n )\n\n expect(exit._tag).toBe(\"Success\")\n }).pipe(Effect.scoped),\n )\n})\n\n/** The `CapabilityWarning` payloads a run produced, in order. */\nconst warningCollector = () => {\n const seen: Array<{ readonly field: string; readonly value?: unknown }> = []\n const logger = Logger.make((options) => {\n const [label, warning] = options.message as ReadonlyArray<any>\n if (label === \"Capability dropped\") seen.push(warning)\n })\n return { seen, layer: Logger.layer([logger]) }\n}\n\nconst userText = (text: string) =>\n ({\n type: \"message\",\n role: \"user\",\n content: [{ type: \"input_text\", text, providerData: undefined }],\n providerData: undefined,\n }) as const\n\nconst call = (id: string) =>\n ({\n type: \"function_call\",\n call_id: id,\n name: \"get_time\",\n arguments: \"{}\",\n providerData: undefined,\n }) as const\n\ndescribe(\"Gemini live session history\", () => {\n it.live(\"names each kind of item the text-only seed cannot carry, once\", () =>\n Effect.gen(function* () {\n const server = yield* gemini\n const warnings = warningCollector()\n\n yield* openSession({ ...cfg, webSocket: server.connect })({\n ...request,\n history: [\n userText(\"what time is it\"),\n call(\"fc_1\"),\n call(\"fc_2\"),\n {\n type: \"function_call_output\",\n call_id: \"fc_1\",\n output: '{\"now\":\"12:00\"}',\n providerData: undefined,\n },\n ],\n }).pipe(Effect.provide(warnings.layer))\n yield* tick\n\n // Two calls, one kind: a long tool history is not a wall of warnings.\n expect(warnings.seen.map((w) => w.value)).toEqual([\"function_call\", \"function_call_output\"])\n expect(warnings.seen.every((w) => w.field === \"history\")).toBe(true)\n\n const sent = yield* server.sent\n const seed = sent.find((f: any) => f.clientContent !== undefined) as any\n expect(seed.clientContent.turns).toEqual([\n { role: \"user\", parts: [{ text: \"what time is it\" }] },\n ])\n }).pipe(Effect.scoped),\n )\n})\n\ndescribe(\"Gemini live session video\", () => {\n it.live(\"sends frame bytes inline, and refuses a frame it would have to fetch\", () =>\n Effect.gen(function* () {\n const server = yield* gemini\n yield* transcript(server, (handle) =>\n Effect.gen(function* () {\n yield* handle.send(\n RealtimeInput.VideoFrame({\n frame: { _tag: \"bytes\", bytes: new Uint8Array([1, 2]), mimeType: \"image/jpeg\" },\n }),\n )\n // A URL would need an upload through the Files API first.\n const exit = yield* Effect.exit(\n handle.send(\n RealtimeInput.VideoFrame({\n frame: { _tag: \"url\", url: \"https://example.com/frame.jpg\" },\n }),\n ),\n )\n expect(JSON.stringify(exit)).toContain(\"Unsupported\")\n }),\n )\n\n const sent = yield* server.sent\n expect(sent.filter((f: any) => f.realtimeInput?.video !== undefined)).toEqual([\n {\n realtimeInput: {\n video: { data: Base64.encode(new Uint8Array([1, 2])), mimeType: \"image/jpeg\" },\n },\n },\n ])\n }).pipe(Effect.scoped),\n )\n})\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect-uai/google",
3
- "version": "0.17.0",
3
+ "version": "0.18.0",
4
4
  "description": "Google Gemini provider for @effect-uai/core.",
5
5
  "keywords": [
6
6
  "ai",
@@ -67,13 +67,13 @@
67
67
  "access": "public"
68
68
  },
69
69
  "devDependencies": {
70
- "effect": "4.0.0-rc.111",
70
+ "effect": "4.0.1",
71
71
  "typescript": "^7.0.2",
72
- "@effect-uai/core": "0.17.0"
72
+ "@effect-uai/core": "0.18.0"
73
73
  },
74
74
  "peerDependencies": {
75
75
  "@effect-uai/core": ">=0.2.0 <1",
76
- "effect": ">=4.0.0-rc.111 <5.0.0"
76
+ "effect": ">=4.0.1 <5.0.0"
77
77
  },
78
78
  "scripts": {
79
79
  "build": "tsdown",
package/src/Gemini.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Context, Effect, Layer, Option, Redacted, Result, Schema, Stream } from "effect"
2
- import { HttpClient, HttpClientRequest } from "effect/unstable/http"
2
+ import { HttpClient, HttpClientRequest } from "effect/http"
3
3
  import * as AiError from "@effect-uai/core/AiError"
4
4
  import {
5
5
  type CommonRequest,
@@ -1,5 +1,6 @@
1
- import { Context, Effect, Encoding, Layer, Match, Redacted, Schema } from "effect"
2
- import { HttpClient, HttpClientRequest } from "effect/unstable/http"
1
+ import { Context, Effect, Layer, Match, Redacted, Schema } from "effect"
2
+ import { Base64 } from "effect/encoding"
3
+ import { HttpClient, HttpClientRequest } from "effect/http"
3
4
  import * as AiError from "@effect-uai/core/AiError"
4
5
  import type {
5
6
  EmbedContentPart,
@@ -126,7 +127,7 @@ const imageSourceToPart = (param: string) =>
126
127
  ),
127
128
  Match.tag("bytes", (s): Effect.Effect<WirePart, AiError.AiError> =>
128
129
  Effect.succeed({
129
- inlineData: { mimeType: s.mimeType, data: Encoding.encodeBase64(s.bytes) },
130
+ inlineData: { mimeType: s.mimeType, data: Base64.encode(s.bytes) },
130
131
  }),
131
132
  ),
132
133
  Match.tag("url", (): Effect.Effect<WirePart, AiError.AiError> =>
@@ -1,5 +1,6 @@
1
- import { Context, Effect, Encoding, Layer, Match, Redacted, Schema, Stream } from "effect"
2
- import { HttpClient, HttpClientRequest } from "effect/unstable/http"
1
+ import { Context, Effect, Layer, Match, Redacted, Schema, Stream } from "effect"
2
+ import { Base64 } from "effect/encoding"
3
+ import { HttpClient, HttpClientRequest } from "effect/http"
3
4
  import * as AiError from "@effect-uai/core/AiError"
4
5
  import * as Capabilities from "@effect-uai/core/Capabilities"
5
6
  import type {
@@ -129,7 +130,7 @@ const referencePart: (image: ImageSource) => Effect.Effect<RequestPart, AiError.
129
130
  ),
130
131
  Match.tag("bytes", (i) =>
131
132
  Effect.succeed<RequestPart>({
132
- inlineData: { mimeType: i.mimeType, data: Encoding.encodeBase64(i.bytes) },
133
+ inlineData: { mimeType: i.mimeType, data: Base64.encode(i.bytes) },
133
134
  }),
134
135
  ),
135
136
  Match.tag("url", () => Effect.fail(urlRefNotSupported)),
@@ -1,5 +1,5 @@
1
1
  import { Context, Effect, Layer, Match, Redacted, Result, Schema, Stream } from "effect"
2
- import { HttpClient, HttpClientRequest } from "effect/unstable/http"
2
+ import { HttpClient, HttpClientRequest } from "effect/http"
3
3
  import * as AiError from "@effect-uai/core/AiError"
4
4
  import type { AudioBlob, AudioChunk, AudioFormat } from "@effect-uai/core/Audio"
5
5
  import * as Capabilities from "@effect-uai/core/Capabilities"
@@ -12,7 +12,7 @@ import {
12
12
  Stream,
13
13
  pipe,
14
14
  } from "effect"
15
- import { HttpClient, HttpClientRequest } from "effect/unstable/http"
15
+ import { HttpClient, HttpClientRequest } from "effect/http"
16
16
  import * as AiError from "@effect-uai/core/AiError"
17
17
  import type { Source } from "@effect-uai/core/Citation"
18
18
  import {
@@ -1,5 +1,5 @@
1
1
  import { Duration, Effect, Layer, Redacted, Stream } from "effect"
2
- import { FetchHttpClient } from "effect/unstable/http"
2
+ import { FetchHttpClient } from "effect/http"
3
3
  import { describe, expect, expectTypeOf, it } from "vitest"
4
4
  import type * as AiError from "@effect-uai/core/AiError"
5
5
  import type { GenerateResult } from "@effect-uai/core/Music"
@@ -1,16 +1,6 @@
1
- import {
2
- Context,
3
- Duration,
4
- Effect,
5
- Encoding,
6
- Layer,
7
- Match,
8
- Redacted,
9
- Result,
10
- Schema,
11
- Stream,
12
- } from "effect"
13
- import { HttpClient, HttpClientRequest } from "effect/unstable/http"
1
+ import { Context, Duration, Effect, Layer, Match, Redacted, Result, Schema, Stream } from "effect"
2
+ import { Base64 } from "effect/encoding"
3
+ import { HttpClient, HttpClientRequest } from "effect/http"
14
4
  import * as AiError from "@effect-uai/core/AiError"
15
5
  import type { AudioChunk, AudioFormat } from "@effect-uai/core/Audio"
16
6
  import { warnDroppedWhen } from "@effect-uai/core/Capabilities"
@@ -207,7 +197,7 @@ const transportFailure = sharedTransportFailure("lyria")
207
197
  const httpStatusError = sharedHttpStatusError("lyria")
208
198
 
209
199
  const decodeBase64ToBytes = (b64: string): Effect.Effect<Uint8Array, AiError.AiError> =>
210
- Result.match(Encoding.decodeBase64(b64), {
200
+ Result.match(Base64.decode(b64), {
211
201
  onSuccess: Effect.succeed,
212
202
  onFailure: (cause) =>
213
203
  Effect.fail(new AiError.InvalidRequest({ provider: "lyria", param: "audio", raw: cause })),
package/src/codec.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { Array as Arr, Encoding, Match, Option, Result, Schema, pipe } from "effect"
1
+ import { Array as Arr, Match, Option, Result, Schema, pipe } from "effect"
2
+ import { Base64 } from "effect/encoding"
2
3
  import * as AiError from "@effect-uai/core/AiError"
3
4
  import type { ImageSource } from "@effect-uai/core/Image"
4
5
  import { imageBase64 } from "@effect-uai/core/Image"
@@ -249,7 +250,7 @@ const imageSourceToParts = Match.type<InputImage["source"]>().pipe(
249
250
  { inlineData: { mimeType: s.mimeType, data: s.base64 } },
250
251
  ]),
251
252
  Match.tag("bytes", (s): ReadonlyArray<RequestPart> => [
252
- { inlineData: { mimeType: s.mimeType, data: Encoding.encodeBase64(s.bytes) } },
253
+ { inlineData: { mimeType: s.mimeType, data: Base64.encode(s.bytes) } },
253
254
  ]),
254
255
  Match.exhaustive,
255
256
  )
@@ -1,4 +1,5 @@
1
- import { Effect, Encoding } from "effect"
1
+ import { Effect } from "effect"
2
+ import { Base64 } from "effect/encoding"
2
3
  import { describe, expect, it } from "vitest"
3
4
  import type { AudioSource } from "@effect-uai/core/Audio"
4
5
  import { audioSourceToInlineData, wrapPcmAsWav } from "./geminiSpeechCodec.js"
@@ -9,11 +10,11 @@ describe("audioSourceToInlineData", () => {
9
10
  const source: AudioSource = { _tag: "bytes", bytes: original, mimeType: "audio/wav" }
10
11
  const inline = await Effect.runPromise(audioSourceToInlineData(source))
11
12
  expect(inline.mimeType).toBe("audio/wav")
12
- expect(inline.data).toBe(Encoding.encodeBase64(original))
13
+ expect(inline.data).toBe(Base64.encode(original))
13
14
  })
14
15
 
15
16
  it("passes a `base64` source through unchanged", async () => {
16
- const b64 = Encoding.encodeBase64(new Uint8Array([1, 2, 3]))
17
+ const b64 = Base64.encode(new Uint8Array([1, 2, 3]))
17
18
  const source: AudioSource = { _tag: "base64", base64: b64, mimeType: "audio/mp3" }
18
19
  const inline = await Effect.runPromise(audioSourceToInlineData(source))
19
20
  expect(inline.mimeType).toBe("audio/mp3")
@@ -1,4 +1,5 @@
1
- import { Effect, Encoding, Match, Result } from "effect"
1
+ import { Effect, Match, Result } from "effect"
2
+ import { Base64 } from "effect/encoding"
2
3
  import * as AiError from "@effect-uai/core/AiError"
3
4
  import type { AudioSource } from "@effect-uai/core/Audio"
4
5
 
@@ -34,7 +35,7 @@ export const audioSourceToInlineData: (
34
35
  Match.tag("bytes", (a) =>
35
36
  Effect.succeed<InlineAudioData>({
36
37
  mimeType: a.mimeType,
37
- data: Encoding.encodeBase64(a.bytes),
38
+ data: Base64.encode(a.bytes),
38
39
  }),
39
40
  ),
40
41
  Match.tag("base64", (a) =>
@@ -46,7 +47,7 @@ export const audioSourceToInlineData: (
46
47
 
47
48
  /** Decode a base64-encoded audio payload into bytes. */
48
49
  export const decodeBase64Audio = (b64: string): Effect.Effect<Uint8Array, AiError.AiError> =>
49
- Result.match(Encoding.decodeBase64(b64), {
50
+ Result.match(Base64.decode(b64), {
50
51
  onSuccess: Effect.succeed,
51
52
  onFailure: (cause) =>
52
53
  Effect.fail(new AiError.InvalidRequest({ provider: "gemini", param: "audio", raw: cause })),
@@ -1,5 +1,6 @@
1
1
  import { describe, it } from "@effect/vitest"
2
- import { Duration, Effect, Encoding, Fiber, Logger, Redacted, Ref, Stream } from "effect"
2
+ import { Duration, Effect, Fiber, Logger, Redacted, Ref, Stream } from "effect"
3
+ import { Base64 } from "effect/encoding"
3
4
  import { expect } from "vitest"
4
5
  import type { RealtimeEvent } from "@effect-uai/core/Realtime"
5
6
  import { RealtimeInput } from "@effect-uai/core/Realtime"
@@ -55,7 +56,7 @@ const tags = (events: ReadonlyArray<RealtimeEvent>) => events.map((e) => e._tag)
55
56
  const audioPart = (bytes: ReadonlyArray<number>) => ({
56
57
  inlineData: {
57
58
  mimeType: "audio/pcm;rate=24000",
58
- data: Encoding.encodeBase64(new Uint8Array(bytes)),
59
+ data: Base64.encode(new Uint8Array(bytes)),
59
60
  },
60
61
  })
61
62
 
@@ -406,7 +407,7 @@ describe("Gemini live session video", () => {
406
407
  expect(sent.filter((f: any) => f.realtimeInput?.video !== undefined)).toEqual([
407
408
  {
408
409
  realtimeInput: {
409
- video: { data: Encoding.encodeBase64(new Uint8Array([1, 2])), mimeType: "image/jpeg" },
410
+ video: { data: Base64.encode(new Uint8Array([1, 2])), mimeType: "image/jpeg" },
410
411
  },
411
412
  },
412
413
  ])
@@ -13,7 +13,6 @@ import {
13
13
  Cause,
14
14
  Duration,
15
15
  Effect,
16
- Encoding,
17
16
  Match,
18
17
  Pull,
19
18
  Queue,
@@ -24,7 +23,8 @@ import {
24
23
  type Scope,
25
24
  Stream,
26
25
  } from "effect"
27
- import * as Socket from "effect/unstable/socket/Socket"
26
+ import { Base64 } from "effect/encoding"
27
+ import * as Socket from "effect/socket/Socket"
28
28
  import * as AiError from "@effect-uai/core/AiError"
29
29
  import type { AudioFormat } from "@effect-uai/core/Audio"
30
30
  import * as Capabilities from "@effect-uai/core/Capabilities"
@@ -383,7 +383,7 @@ const usageOf = (metadata: typeof UsageMetadata.Type): Usage => ({
383
383
  })
384
384
 
385
385
  const decodeAudio = (b64: string): Effect.Effect<Uint8Array, AiError.AiError> =>
386
- Result.match(Encoding.decodeBase64(b64), {
386
+ Result.match(Base64.decode(b64), {
387
387
  onSuccess: Effect.succeed,
388
388
  onFailure: (cause) =>
389
389
  Effect.fail(
@@ -555,7 +555,7 @@ const videoPart = (
555
555
  Match.value(frame).pipe(
556
556
  Match.tag("base64", (s) => Effect.succeed({ data: s.base64, mimeType: s.mimeType })),
557
557
  Match.tag("bytes", (s) =>
558
- Effect.succeed({ data: Encoding.encodeBase64(s.bytes), mimeType: s.mimeType }),
558
+ Effect.succeed({ data: Base64.encode(s.bytes), mimeType: s.mimeType }),
559
559
  ),
560
560
  Match.tag("url", () =>
561
561
  Effect.fail(
@@ -596,7 +596,7 @@ const handleInput = (
596
596
  JSON.stringify({
597
597
  realtimeInput: {
598
598
  audio: {
599
- data: Encoding.encodeBase64(i.bytes),
599
+ data: Base64.encode(i.bytes),
600
600
  mimeType: `audio/pcm;rate=${options.rate}`,
601
601
  },
602
602
  },