@prestyj/voice 4.3.191

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 (39) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +79 -0
  3. package/dist/bridges/ezboss.cjs +96 -0
  4. package/dist/bridges/ezboss.cjs.map +1 -0
  5. package/dist/bridges/ezboss.d.cts +13 -0
  6. package/dist/bridges/ezboss.d.ts +13 -0
  7. package/dist/bridges/ezboss.js +70 -0
  8. package/dist/bridges/ezboss.js.map +1 -0
  9. package/dist/bridges/ezcoder-rpc.cjs +128 -0
  10. package/dist/bridges/ezcoder-rpc.cjs.map +1 -0
  11. package/dist/bridges/ezcoder-rpc.d.cts +18 -0
  12. package/dist/bridges/ezcoder-rpc.d.ts +18 -0
  13. package/dist/bridges/ezcoder-rpc.js +101 -0
  14. package/dist/bridges/ezcoder-rpc.js.map +1 -0
  15. package/dist/chunk-VJ6MPV2Z.js +225 -0
  16. package/dist/chunk-VJ6MPV2Z.js.map +1 -0
  17. package/dist/chunk-YLNKQ7CC.js +234 -0
  18. package/dist/chunk-YLNKQ7CC.js.map +1 -0
  19. package/dist/index.cjs +357 -0
  20. package/dist/index.cjs.map +1 -0
  21. package/dist/index.d.cts +90 -0
  22. package/dist/index.d.ts +90 -0
  23. package/dist/index.js +109 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/providers/openai-codex-realtime.cjs +362 -0
  26. package/dist/providers/openai-codex-realtime.cjs.map +1 -0
  27. package/dist/providers/openai-codex-realtime.d.cts +15 -0
  28. package/dist/providers/openai-codex-realtime.d.ts +15 -0
  29. package/dist/providers/openai-codex-realtime.js +31 -0
  30. package/dist/providers/openai-codex-realtime.js.map +1 -0
  31. package/dist/providers/openai-realtime.cjs +342 -0
  32. package/dist/providers/openai-realtime.cjs.map +1 -0
  33. package/dist/providers/openai-realtime.d.cts +34 -0
  34. package/dist/providers/openai-realtime.d.ts +34 -0
  35. package/dist/providers/openai-realtime.js +12 -0
  36. package/dist/providers/openai-realtime.js.map +1 -0
  37. package/dist/types-Dc4Q3Z6X.d.cts +257 -0
  38. package/dist/types-Dc4Q3Z6X.d.ts +257 -0
  39. package/package.json +63 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 KenKai
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # @prestyj/voice
2
+
3
+ Provider-agnostic realtime voice orchestration for GG tools, agents, and remote coding sessions.
4
+
5
+ ## Architecture
6
+
7
+ `gg-voice` keeps the package root mobile-safe: it exports normalized voice session types, tool conversion helpers, in-memory tests, and platform interfaces without importing Node-only `ezcoder` internals. Provider and bridge integrations live behind subpath exports so Expo, web, desktop, and Node relays can choose only the pieces they need.
8
+
9
+ Core concepts:
10
+
11
+ - `VoiceProvider`: creates a realtime `VoiceSession`.
12
+ - `VoiceTransport`: injectable WebRTC, WebSocket, or custom transport.
13
+ - `VoiceEvent`: normalized session, transcript, text, audio, tool, error, and close events.
14
+ - `VoiceTool`: realtime-safe tool contract with optional confirmation policies.
15
+ - `VoiceBridgeCommand` / `VoiceBridgeEvent`: small control surface for GG remotes.
16
+
17
+ ## Provider support
18
+
19
+ The official OpenAI adapter is exported from:
20
+
21
+ ```ts
22
+ import { createOpenAIRealtimeProvider } from "@prestyj/voice/providers/openai-realtime";
23
+ ```
24
+
25
+ It targets the documented GA Realtime WebRTC flow with `/v1/realtime/calls` and `/v1/realtime/client_secrets`, `session.type: "realtime"`, and current model examples such as `gpt-realtime-2` / `gpt-realtime`. The adapter normalizes GA event names including `response.output_text.delta`, `response.output_audio.delta`, and `response.output_audio_transcript.delta` where applicable, but requires an injected platform transport. Browser, React Native, desktop, and server runtimes wire audio/WebRTC differently, so this package does not ship a universal WebRTC implementation.
26
+
27
+ The experimental Codex/ChatGPT-backed adapter is isolated at:
28
+
29
+ ```ts
30
+ import { createExperimentalCodexRealtimeProvider } from "@prestyj/voice/providers/openai-codex-realtime";
31
+ ```
32
+
33
+ This route is intentionally marked experimental because Codex backend request shapes are internal and can change.
34
+
35
+ ## Tools
36
+
37
+ Convert existing GG tools into realtime function tools:
38
+
39
+ ```ts
40
+ import { agentToolToVoiceTool, voiceToolToRealtimeFunctionTool } from "@prestyj/voice";
41
+
42
+ const voiceTool = agentToolToVoiceTool(agentTool);
43
+ const realtimeTool = voiceToolToRealtimeFunctionTool(voiceTool);
44
+ ```
45
+
46
+ Execute model-requested tool calls with confirmation support:
47
+
48
+ ```ts
49
+ const result = await executeVoiceToolCall({
50
+ tools: [voiceTool],
51
+ call,
52
+ confirmation: async () => ({ approved: true }),
53
+ });
54
+ await session.sendToolResult(result);
55
+ ```
56
+
57
+ Use confirmation policies such as `"always"` or `"destructive"` for high-risk voice actions.
58
+
59
+ ## GG bridges
60
+
61
+ `@prestyj/voice/bridges/ezcoder-rpc` maps the voice bridge command surface to existing `ezcoder rpc` NDJSON commands such as `prompt`, `get_state`, `abort`, `new_session`, and `switch_model`.
62
+
63
+ `@prestyj/voice/bridges/ezboss` can wrap an in-process `GGBoss.enqueueUserMessage(text)` target or expose a relay-backed `send_to_ezboss` tool.
64
+
65
+ ## Expo and mobile limitations
66
+
67
+ Expo apps should consume the package root plus their own platform adapters for secure storage, URL opening, microphone capture, audio playback, and WebRTC. Direct realtime WebRTC in React Native generally requires `react-native-webrtc` and a custom dev/EAS build; Expo Go is unlikely to be enough for production speech-to-speech.
68
+
69
+ Do not import `@prestyj/cli` directly into a phone bundle. Send voice-derived commands through a relay, `ezcoder rpc`, Agent Home style bridge, or a server-side `AgentSession` wrapper.
70
+
71
+ ## Auth modes
72
+
73
+ Recommended first path:
74
+
75
+ 1. A trusted backend uses an OpenAI API key to create a Realtime client secret or call session.
76
+ 2. The mobile/web app uses the ephemeral credential or backend SDP exchange.
77
+ 3. The app sends local device tools and remote GG bridge tools through `gg-voice`.
78
+
79
+ Experimental Codex auth should remain behind explicit user opt-in and separate imports.
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/bridges/ezboss.ts
21
+ var ezboss_exports = {};
22
+ __export(ezboss_exports, {
23
+ createGGBossBridge: () => createGGBossBridge,
24
+ createRelayGGBossTool: () => createRelayGGBossTool
25
+ });
26
+ module.exports = __toCommonJS(ezboss_exports);
27
+ function createGGBossBridge(target) {
28
+ return {
29
+ async send(command, signal) {
30
+ throwIfAborted(signal);
31
+ if (command.type !== "prompt") {
32
+ return {
33
+ type: "error",
34
+ error: `Unsupported GGBoss bridge command: ${command.type}`
35
+ };
36
+ }
37
+ await target.enqueueUserMessage(command.text);
38
+ return { type: "task_dispatch", text: command.text };
39
+ },
40
+ toTool() {
41
+ return createSendToGGBossTool(this);
42
+ }
43
+ };
44
+ }
45
+ function createRelayGGBossTool(send) {
46
+ return {
47
+ name: "send_to_ezboss",
48
+ description: "Send a prompt to a EZ Boss orchestrator relay.",
49
+ parameters: {
50
+ type: "object",
51
+ properties: {
52
+ text: { type: "string", description: "Prompt text to send to EZ Boss." }
53
+ },
54
+ required: ["text"]
55
+ },
56
+ async execute(args) {
57
+ const text = typeof args.text === "string" ? args.text : "";
58
+ if (!text) {
59
+ return { error: "text is required" };
60
+ }
61
+ return send({ type: "prompt", text });
62
+ }
63
+ };
64
+ }
65
+ function createSendToGGBossTool(bridge) {
66
+ return {
67
+ name: "send_to_ezboss",
68
+ description: "Send a prompt to an in-process EZ Boss orchestrator.",
69
+ parameters: {
70
+ type: "object",
71
+ properties: {
72
+ text: { type: "string", description: "Prompt text to send to EZ Boss." }
73
+ },
74
+ required: ["text"]
75
+ },
76
+ async execute(args, context) {
77
+ const text = typeof args.text === "string" ? args.text : "";
78
+ if (!text) {
79
+ return { error: "text is required" };
80
+ }
81
+ const event = await bridge.send({ type: "prompt", text }, context.signal);
82
+ return event;
83
+ }
84
+ };
85
+ }
86
+ function throwIfAborted(signal) {
87
+ if (signal?.aborted) {
88
+ throw new Error("GGBoss bridge command aborted");
89
+ }
90
+ }
91
+ // Annotate the CommonJS export names for ESM import in node:
92
+ 0 && (module.exports = {
93
+ createGGBossBridge,
94
+ createRelayGGBossTool
95
+ });
96
+ //# sourceMappingURL=ezboss.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/bridges/ezboss.ts"],"sourcesContent":["import type { JsonObject, VoiceBridgeCommand, VoiceBridgeEvent, VoiceTool } from \"../types.js\";\n\nexport interface GGBossPromptTarget {\n enqueueUserMessage(text: string): Promise<void> | void;\n}\n\nexport interface GGBossBridge {\n send(command: VoiceBridgeCommand, signal?: AbortSignal): Promise<VoiceBridgeEvent>;\n toTool(): VoiceTool;\n}\n\nexport function createGGBossBridge(target: GGBossPromptTarget): GGBossBridge {\n return {\n async send(command, signal): Promise<VoiceBridgeEvent> {\n throwIfAborted(signal);\n if (command.type !== \"prompt\") {\n return {\n type: \"error\",\n error: `Unsupported GGBoss bridge command: ${command.type}`,\n };\n }\n await target.enqueueUserMessage(command.text);\n return { type: \"task_dispatch\", text: command.text };\n },\n toTool(): VoiceTool {\n return createSendToGGBossTool(this);\n },\n };\n}\n\nexport function createRelayGGBossTool(\n send: (command: VoiceBridgeCommand) => Promise<JsonObject>,\n): VoiceTool {\n return {\n name: \"send_to_ezboss\",\n description: \"Send a prompt to a EZ Boss orchestrator relay.\",\n parameters: {\n type: \"object\",\n properties: {\n text: { type: \"string\", description: \"Prompt text to send to EZ Boss.\" },\n },\n required: [\"text\"],\n },\n async execute(args) {\n const text = typeof args.text === \"string\" ? args.text : \"\";\n if (!text) {\n return { error: \"text is required\" };\n }\n return send({ type: \"prompt\", text });\n },\n };\n}\n\nfunction createSendToGGBossTool(bridge: GGBossBridge): VoiceTool {\n return {\n name: \"send_to_ezboss\",\n description: \"Send a prompt to an in-process EZ Boss orchestrator.\",\n parameters: {\n type: \"object\",\n properties: {\n text: { type: \"string\", description: \"Prompt text to send to EZ Boss.\" },\n },\n required: [\"text\"],\n },\n async execute(args, context) {\n const text = typeof args.text === \"string\" ? args.text : \"\";\n if (!text) {\n return { error: \"text is required\" };\n }\n const event = await bridge.send({ type: \"prompt\", text }, context.signal);\n return event;\n },\n };\n}\n\nfunction throwIfAborted(signal: AbortSignal | undefined): void {\n if (signal?.aborted) {\n throw new Error(\"GGBoss bridge command aborted\");\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWO,SAAS,mBAAmB,QAA0C;AAC3E,SAAO;AAAA,IACL,MAAM,KAAK,SAAS,QAAmC;AACrD,qBAAe,MAAM;AACrB,UAAI,QAAQ,SAAS,UAAU;AAC7B,eAAO;AAAA,UACL,MAAM;AAAA,UACN,OAAO,sCAAsC,QAAQ,IAAI;AAAA,QAC3D;AAAA,MACF;AACA,YAAM,OAAO,mBAAmB,QAAQ,IAAI;AAC5C,aAAO,EAAE,MAAM,iBAAiB,MAAM,QAAQ,KAAK;AAAA,IACrD;AAAA,IACA,SAAoB;AAClB,aAAO,uBAAuB,IAAI;AAAA,IACpC;AAAA,EACF;AACF;AAEO,SAAS,sBACd,MACW;AACX,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aAAa;AAAA,IACb,YAAY;AAAA,MACV,MAAM;AAAA,MACN,YAAY;AAAA,QACV,MAAM,EAAE,MAAM,UAAU,aAAa,kCAAkC;AAAA,MACzE;AAAA,MACA,UAAU,CAAC,MAAM;AAAA,IACnB;AAAA,IACA,MAAM,QAAQ,MAAM;AAClB,YAAM,OAAO,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO;AACzD,UAAI,CAAC,MAAM;AACT,eAAO,EAAE,OAAO,mBAAmB;AAAA,MACrC;AACA,aAAO,KAAK,EAAE,MAAM,UAAU,KAAK,CAAC;AAAA,IACtC;AAAA,EACF;AACF;AAEA,SAAS,uBAAuB,QAAiC;AAC/D,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aAAa;AAAA,IACb,YAAY;AAAA,MACV,MAAM;AAAA,MACN,YAAY;AAAA,QACV,MAAM,EAAE,MAAM,UAAU,aAAa,kCAAkC;AAAA,MACzE;AAAA,MACA,UAAU,CAAC,MAAM;AAAA,IACnB;AAAA,IACA,MAAM,QAAQ,MAAM,SAAS;AAC3B,YAAM,OAAO,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO;AACzD,UAAI,CAAC,MAAM;AACT,eAAO,EAAE,OAAO,mBAAmB;AAAA,MACrC;AACA,YAAM,QAAQ,MAAM,OAAO,KAAK,EAAE,MAAM,UAAU,KAAK,GAAG,QAAQ,MAAM;AACxE,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,SAAS,eAAe,QAAuC;AAC7D,MAAI,QAAQ,SAAS;AACnB,UAAM,IAAI,MAAM,+BAA+B;AAAA,EACjD;AACF;","names":[]}
@@ -0,0 +1,13 @@
1
+ import { p as VoiceBridgeCommand, q as VoiceBridgeEvent, e as VoiceTool, J as JsonObject } from '../types-Dc4Q3Z6X.cjs';
2
+
3
+ interface GGBossPromptTarget {
4
+ enqueueUserMessage(text: string): Promise<void> | void;
5
+ }
6
+ interface GGBossBridge {
7
+ send(command: VoiceBridgeCommand, signal?: AbortSignal): Promise<VoiceBridgeEvent>;
8
+ toTool(): VoiceTool;
9
+ }
10
+ declare function createGGBossBridge(target: GGBossPromptTarget): GGBossBridge;
11
+ declare function createRelayGGBossTool(send: (command: VoiceBridgeCommand) => Promise<JsonObject>): VoiceTool;
12
+
13
+ export { type GGBossBridge, type GGBossPromptTarget, createGGBossBridge, createRelayGGBossTool };
@@ -0,0 +1,13 @@
1
+ import { p as VoiceBridgeCommand, q as VoiceBridgeEvent, e as VoiceTool, J as JsonObject } from '../types-Dc4Q3Z6X.js';
2
+
3
+ interface GGBossPromptTarget {
4
+ enqueueUserMessage(text: string): Promise<void> | void;
5
+ }
6
+ interface GGBossBridge {
7
+ send(command: VoiceBridgeCommand, signal?: AbortSignal): Promise<VoiceBridgeEvent>;
8
+ toTool(): VoiceTool;
9
+ }
10
+ declare function createGGBossBridge(target: GGBossPromptTarget): GGBossBridge;
11
+ declare function createRelayGGBossTool(send: (command: VoiceBridgeCommand) => Promise<JsonObject>): VoiceTool;
12
+
13
+ export { type GGBossBridge, type GGBossPromptTarget, createGGBossBridge, createRelayGGBossTool };
@@ -0,0 +1,70 @@
1
+ // src/bridges/ezboss.ts
2
+ function createGGBossBridge(target) {
3
+ return {
4
+ async send(command, signal) {
5
+ throwIfAborted(signal);
6
+ if (command.type !== "prompt") {
7
+ return {
8
+ type: "error",
9
+ error: `Unsupported GGBoss bridge command: ${command.type}`
10
+ };
11
+ }
12
+ await target.enqueueUserMessage(command.text);
13
+ return { type: "task_dispatch", text: command.text };
14
+ },
15
+ toTool() {
16
+ return createSendToGGBossTool(this);
17
+ }
18
+ };
19
+ }
20
+ function createRelayGGBossTool(send) {
21
+ return {
22
+ name: "send_to_ezboss",
23
+ description: "Send a prompt to a EZ Boss orchestrator relay.",
24
+ parameters: {
25
+ type: "object",
26
+ properties: {
27
+ text: { type: "string", description: "Prompt text to send to EZ Boss." }
28
+ },
29
+ required: ["text"]
30
+ },
31
+ async execute(args) {
32
+ const text = typeof args.text === "string" ? args.text : "";
33
+ if (!text) {
34
+ return { error: "text is required" };
35
+ }
36
+ return send({ type: "prompt", text });
37
+ }
38
+ };
39
+ }
40
+ function createSendToGGBossTool(bridge) {
41
+ return {
42
+ name: "send_to_ezboss",
43
+ description: "Send a prompt to an in-process EZ Boss orchestrator.",
44
+ parameters: {
45
+ type: "object",
46
+ properties: {
47
+ text: { type: "string", description: "Prompt text to send to EZ Boss." }
48
+ },
49
+ required: ["text"]
50
+ },
51
+ async execute(args, context) {
52
+ const text = typeof args.text === "string" ? args.text : "";
53
+ if (!text) {
54
+ return { error: "text is required" };
55
+ }
56
+ const event = await bridge.send({ type: "prompt", text }, context.signal);
57
+ return event;
58
+ }
59
+ };
60
+ }
61
+ function throwIfAborted(signal) {
62
+ if (signal?.aborted) {
63
+ throw new Error("GGBoss bridge command aborted");
64
+ }
65
+ }
66
+ export {
67
+ createGGBossBridge,
68
+ createRelayGGBossTool
69
+ };
70
+ //# sourceMappingURL=ezboss.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/bridges/ezboss.ts"],"sourcesContent":["import type { JsonObject, VoiceBridgeCommand, VoiceBridgeEvent, VoiceTool } from \"../types.js\";\n\nexport interface GGBossPromptTarget {\n enqueueUserMessage(text: string): Promise<void> | void;\n}\n\nexport interface GGBossBridge {\n send(command: VoiceBridgeCommand, signal?: AbortSignal): Promise<VoiceBridgeEvent>;\n toTool(): VoiceTool;\n}\n\nexport function createGGBossBridge(target: GGBossPromptTarget): GGBossBridge {\n return {\n async send(command, signal): Promise<VoiceBridgeEvent> {\n throwIfAborted(signal);\n if (command.type !== \"prompt\") {\n return {\n type: \"error\",\n error: `Unsupported GGBoss bridge command: ${command.type}`,\n };\n }\n await target.enqueueUserMessage(command.text);\n return { type: \"task_dispatch\", text: command.text };\n },\n toTool(): VoiceTool {\n return createSendToGGBossTool(this);\n },\n };\n}\n\nexport function createRelayGGBossTool(\n send: (command: VoiceBridgeCommand) => Promise<JsonObject>,\n): VoiceTool {\n return {\n name: \"send_to_ezboss\",\n description: \"Send a prompt to a EZ Boss orchestrator relay.\",\n parameters: {\n type: \"object\",\n properties: {\n text: { type: \"string\", description: \"Prompt text to send to EZ Boss.\" },\n },\n required: [\"text\"],\n },\n async execute(args) {\n const text = typeof args.text === \"string\" ? args.text : \"\";\n if (!text) {\n return { error: \"text is required\" };\n }\n return send({ type: \"prompt\", text });\n },\n };\n}\n\nfunction createSendToGGBossTool(bridge: GGBossBridge): VoiceTool {\n return {\n name: \"send_to_ezboss\",\n description: \"Send a prompt to an in-process EZ Boss orchestrator.\",\n parameters: {\n type: \"object\",\n properties: {\n text: { type: \"string\", description: \"Prompt text to send to EZ Boss.\" },\n },\n required: [\"text\"],\n },\n async execute(args, context) {\n const text = typeof args.text === \"string\" ? args.text : \"\";\n if (!text) {\n return { error: \"text is required\" };\n }\n const event = await bridge.send({ type: \"prompt\", text }, context.signal);\n return event;\n },\n };\n}\n\nfunction throwIfAborted(signal: AbortSignal | undefined): void {\n if (signal?.aborted) {\n throw new Error(\"GGBoss bridge command aborted\");\n }\n}\n"],"mappings":";AAWO,SAAS,mBAAmB,QAA0C;AAC3E,SAAO;AAAA,IACL,MAAM,KAAK,SAAS,QAAmC;AACrD,qBAAe,MAAM;AACrB,UAAI,QAAQ,SAAS,UAAU;AAC7B,eAAO;AAAA,UACL,MAAM;AAAA,UACN,OAAO,sCAAsC,QAAQ,IAAI;AAAA,QAC3D;AAAA,MACF;AACA,YAAM,OAAO,mBAAmB,QAAQ,IAAI;AAC5C,aAAO,EAAE,MAAM,iBAAiB,MAAM,QAAQ,KAAK;AAAA,IACrD;AAAA,IACA,SAAoB;AAClB,aAAO,uBAAuB,IAAI;AAAA,IACpC;AAAA,EACF;AACF;AAEO,SAAS,sBACd,MACW;AACX,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aAAa;AAAA,IACb,YAAY;AAAA,MACV,MAAM;AAAA,MACN,YAAY;AAAA,QACV,MAAM,EAAE,MAAM,UAAU,aAAa,kCAAkC;AAAA,MACzE;AAAA,MACA,UAAU,CAAC,MAAM;AAAA,IACnB;AAAA,IACA,MAAM,QAAQ,MAAM;AAClB,YAAM,OAAO,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO;AACzD,UAAI,CAAC,MAAM;AACT,eAAO,EAAE,OAAO,mBAAmB;AAAA,MACrC;AACA,aAAO,KAAK,EAAE,MAAM,UAAU,KAAK,CAAC;AAAA,IACtC;AAAA,EACF;AACF;AAEA,SAAS,uBAAuB,QAAiC;AAC/D,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aAAa;AAAA,IACb,YAAY;AAAA,MACV,MAAM;AAAA,MACN,YAAY;AAAA,QACV,MAAM,EAAE,MAAM,UAAU,aAAa,kCAAkC;AAAA,MACzE;AAAA,MACA,UAAU,CAAC,MAAM;AAAA,IACnB;AAAA,IACA,MAAM,QAAQ,MAAM,SAAS;AAC3B,YAAM,OAAO,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO;AACzD,UAAI,CAAC,MAAM;AACT,eAAO,EAAE,OAAO,mBAAmB;AAAA,MACrC;AACA,YAAM,QAAQ,MAAM,OAAO,KAAK,EAAE,MAAM,UAAU,KAAK,GAAG,QAAQ,MAAM;AACxE,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,SAAS,eAAe,QAAuC;AAC7D,MAAI,QAAQ,SAAS;AACnB,UAAM,IAAI,MAAM,+BAA+B;AAAA,EACjD;AACF;","names":[]}
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/bridges/ezcoder-rpc.ts
21
+ var ezcoder_rpc_exports = {};
22
+ __export(ezcoder_rpc_exports, {
23
+ createGGCoderRpcBridge: () => createGGCoderRpcBridge,
24
+ normalizeGGCoderRpcEvent: () => normalizeGGCoderRpcEvent,
25
+ toGGCoderRpcCommand: () => toGGCoderRpcCommand
26
+ });
27
+ module.exports = __toCommonJS(ezcoder_rpc_exports);
28
+ function createGGCoderRpcBridge(options) {
29
+ const idFactory = options.idFactory ?? (() => `ezcoder_${Date.now()}`);
30
+ return {
31
+ async send(command, signal) {
32
+ const id = idFactory();
33
+ await options.sink.send(toGGCoderRpcCommand(id, command), signal);
34
+ return id;
35
+ },
36
+ toTool() {
37
+ return createSendToGGCoderTool(this);
38
+ }
39
+ };
40
+ }
41
+ function toGGCoderRpcCommand(id, command) {
42
+ switch (command.type) {
43
+ case "prompt":
44
+ return { id, command: "prompt", text: command.text };
45
+ case "cancel":
46
+ return { id, command: "abort" };
47
+ case "status":
48
+ return { id, command: "get_state" };
49
+ case "new_session":
50
+ return { id, command: "new_session" };
51
+ case "switch_model":
52
+ return { id, command: "switch_model", provider: command.provider, model: command.model };
53
+ case "switch_project":
54
+ return { id, command: "prompt", text: `Switch project to ${command.project}` };
55
+ case "list_projects":
56
+ return { id, command: "prompt", text: "List available GG projects." };
57
+ }
58
+ }
59
+ function normalizeGGCoderRpcEvent(message) {
60
+ if (!isJsonObject(message)) {
61
+ return null;
62
+ }
63
+ const type = typeof message.type === "string" ? message.type : "";
64
+ switch (type) {
65
+ case "text_delta":
66
+ return { type: "text_delta", text: stringValue(message.text) };
67
+ case "tool_call_start":
68
+ return {
69
+ type: "tool_start",
70
+ id: stringOrUndefined(message.toolCallId),
71
+ name: stringValue(message.name)
72
+ };
73
+ case "tool_call_end":
74
+ return {
75
+ type: "tool_end",
76
+ id: stringOrUndefined(message.toolCallId),
77
+ name: stringValue(message.name),
78
+ isError: message.isError === true
79
+ };
80
+ case "agent_done":
81
+ return { type: "completion" };
82
+ case "ready":
83
+ case "session_start":
84
+ case "model_change":
85
+ return { type: "status", status: message };
86
+ case "error":
87
+ return { type: "error", error: stringValue(message.message ?? message.error) };
88
+ default:
89
+ return null;
90
+ }
91
+ }
92
+ function createSendToGGCoderTool(bridge) {
93
+ return {
94
+ name: "send_to_ezcoder",
95
+ description: "Send a prompt or control command to a running ezcoder RPC session.",
96
+ parameters: {
97
+ type: "object",
98
+ properties: {
99
+ text: { type: "string", description: "Prompt text to send to ezcoder." }
100
+ },
101
+ required: ["text"]
102
+ },
103
+ async execute(args, context) {
104
+ const text = typeof args.text === "string" ? args.text : "";
105
+ if (!text) {
106
+ return { error: "text is required" };
107
+ }
108
+ const id = await bridge.send({ type: "prompt", text }, context.signal);
109
+ return { status: "sent", id };
110
+ }
111
+ };
112
+ }
113
+ function stringValue(value) {
114
+ return typeof value === "string" ? value : "";
115
+ }
116
+ function stringOrUndefined(value) {
117
+ return typeof value === "string" ? value : void 0;
118
+ }
119
+ function isJsonObject(value) {
120
+ return typeof value === "object" && value !== null && !Array.isArray(value);
121
+ }
122
+ // Annotate the CommonJS export names for ESM import in node:
123
+ 0 && (module.exports = {
124
+ createGGCoderRpcBridge,
125
+ normalizeGGCoderRpcEvent,
126
+ toGGCoderRpcCommand
127
+ });
128
+ //# sourceMappingURL=ezcoder-rpc.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/bridges/ezcoder-rpc.ts"],"sourcesContent":["import type { JsonObject, VoiceBridgeCommand, VoiceBridgeEvent, VoiceTool } from \"../types.js\";\n\nexport interface GGCoderRpcMessageSink {\n send(message: JsonObject, signal?: AbortSignal): Promise<void>;\n}\n\nexport interface GGCoderRpcBridgeOptions {\n readonly sink: GGCoderRpcMessageSink;\n readonly idFactory?: () => string;\n}\n\nexport interface GGCoderRpcBridge {\n send(command: VoiceBridgeCommand, signal?: AbortSignal): Promise<string>;\n toTool(): VoiceTool;\n}\n\nexport function createGGCoderRpcBridge(options: GGCoderRpcBridgeOptions): GGCoderRpcBridge {\n const idFactory = options.idFactory ?? (() => `ezcoder_${Date.now()}`);\n return {\n async send(command, signal): Promise<string> {\n const id = idFactory();\n await options.sink.send(toGGCoderRpcCommand(id, command), signal);\n return id;\n },\n toTool(): VoiceTool {\n return createSendToGGCoderTool(this);\n },\n };\n}\n\nexport function toGGCoderRpcCommand(id: string, command: VoiceBridgeCommand): JsonObject {\n switch (command.type) {\n case \"prompt\":\n return { id, command: \"prompt\", text: command.text };\n case \"cancel\":\n return { id, command: \"abort\" };\n case \"status\":\n return { id, command: \"get_state\" };\n case \"new_session\":\n return { id, command: \"new_session\" };\n case \"switch_model\":\n return { id, command: \"switch_model\", provider: command.provider, model: command.model };\n case \"switch_project\":\n return { id, command: \"prompt\", text: `Switch project to ${command.project}` };\n case \"list_projects\":\n return { id, command: \"prompt\", text: \"List available GG projects.\" };\n }\n}\n\nexport function normalizeGGCoderRpcEvent(message: unknown): VoiceBridgeEvent | null {\n if (!isJsonObject(message)) {\n return null;\n }\n const type = typeof message.type === \"string\" ? message.type : \"\";\n switch (type) {\n case \"text_delta\":\n return { type: \"text_delta\", text: stringValue(message.text) };\n case \"tool_call_start\":\n return {\n type: \"tool_start\",\n id: stringOrUndefined(message.toolCallId),\n name: stringValue(message.name),\n };\n case \"tool_call_end\":\n return {\n type: \"tool_end\",\n id: stringOrUndefined(message.toolCallId),\n name: stringValue(message.name),\n isError: message.isError === true,\n };\n case \"agent_done\":\n return { type: \"completion\" };\n case \"ready\":\n case \"session_start\":\n case \"model_change\":\n return { type: \"status\", status: message };\n case \"error\":\n return { type: \"error\", error: stringValue(message.message ?? message.error) };\n default:\n return null;\n }\n}\n\nfunction createSendToGGCoderTool(bridge: GGCoderRpcBridge): VoiceTool {\n return {\n name: \"send_to_ezcoder\",\n description: \"Send a prompt or control command to a running ezcoder RPC session.\",\n parameters: {\n type: \"object\",\n properties: {\n text: { type: \"string\", description: \"Prompt text to send to ezcoder.\" },\n },\n required: [\"text\"],\n },\n async execute(args, context) {\n const text = typeof args.text === \"string\" ? args.text : \"\";\n if (!text) {\n return { error: \"text is required\" };\n }\n const id = await bridge.send({ type: \"prompt\", text }, context.signal);\n return { status: \"sent\", id };\n },\n };\n}\n\nfunction stringValue(value: unknown): string {\n return typeof value === \"string\" ? value : \"\";\n}\n\nfunction stringOrUndefined(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction isJsonObject(value: unknown): value is JsonObject {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,18 @@
1
+ import { p as VoiceBridgeCommand, e as VoiceTool, J as JsonObject, q as VoiceBridgeEvent } from '../types-Dc4Q3Z6X.cjs';
2
+
3
+ interface GGCoderRpcMessageSink {
4
+ send(message: JsonObject, signal?: AbortSignal): Promise<void>;
5
+ }
6
+ interface GGCoderRpcBridgeOptions {
7
+ readonly sink: GGCoderRpcMessageSink;
8
+ readonly idFactory?: () => string;
9
+ }
10
+ interface GGCoderRpcBridge {
11
+ send(command: VoiceBridgeCommand, signal?: AbortSignal): Promise<string>;
12
+ toTool(): VoiceTool;
13
+ }
14
+ declare function createGGCoderRpcBridge(options: GGCoderRpcBridgeOptions): GGCoderRpcBridge;
15
+ declare function toGGCoderRpcCommand(id: string, command: VoiceBridgeCommand): JsonObject;
16
+ declare function normalizeGGCoderRpcEvent(message: unknown): VoiceBridgeEvent | null;
17
+
18
+ export { type GGCoderRpcBridge, type GGCoderRpcBridgeOptions, type GGCoderRpcMessageSink, createGGCoderRpcBridge, normalizeGGCoderRpcEvent, toGGCoderRpcCommand };
@@ -0,0 +1,18 @@
1
+ import { p as VoiceBridgeCommand, e as VoiceTool, J as JsonObject, q as VoiceBridgeEvent } from '../types-Dc4Q3Z6X.js';
2
+
3
+ interface GGCoderRpcMessageSink {
4
+ send(message: JsonObject, signal?: AbortSignal): Promise<void>;
5
+ }
6
+ interface GGCoderRpcBridgeOptions {
7
+ readonly sink: GGCoderRpcMessageSink;
8
+ readonly idFactory?: () => string;
9
+ }
10
+ interface GGCoderRpcBridge {
11
+ send(command: VoiceBridgeCommand, signal?: AbortSignal): Promise<string>;
12
+ toTool(): VoiceTool;
13
+ }
14
+ declare function createGGCoderRpcBridge(options: GGCoderRpcBridgeOptions): GGCoderRpcBridge;
15
+ declare function toGGCoderRpcCommand(id: string, command: VoiceBridgeCommand): JsonObject;
16
+ declare function normalizeGGCoderRpcEvent(message: unknown): VoiceBridgeEvent | null;
17
+
18
+ export { type GGCoderRpcBridge, type GGCoderRpcBridgeOptions, type GGCoderRpcMessageSink, createGGCoderRpcBridge, normalizeGGCoderRpcEvent, toGGCoderRpcCommand };
@@ -0,0 +1,101 @@
1
+ // src/bridges/ezcoder-rpc.ts
2
+ function createGGCoderRpcBridge(options) {
3
+ const idFactory = options.idFactory ?? (() => `ezcoder_${Date.now()}`);
4
+ return {
5
+ async send(command, signal) {
6
+ const id = idFactory();
7
+ await options.sink.send(toGGCoderRpcCommand(id, command), signal);
8
+ return id;
9
+ },
10
+ toTool() {
11
+ return createSendToGGCoderTool(this);
12
+ }
13
+ };
14
+ }
15
+ function toGGCoderRpcCommand(id, command) {
16
+ switch (command.type) {
17
+ case "prompt":
18
+ return { id, command: "prompt", text: command.text };
19
+ case "cancel":
20
+ return { id, command: "abort" };
21
+ case "status":
22
+ return { id, command: "get_state" };
23
+ case "new_session":
24
+ return { id, command: "new_session" };
25
+ case "switch_model":
26
+ return { id, command: "switch_model", provider: command.provider, model: command.model };
27
+ case "switch_project":
28
+ return { id, command: "prompt", text: `Switch project to ${command.project}` };
29
+ case "list_projects":
30
+ return { id, command: "prompt", text: "List available GG projects." };
31
+ }
32
+ }
33
+ function normalizeGGCoderRpcEvent(message) {
34
+ if (!isJsonObject(message)) {
35
+ return null;
36
+ }
37
+ const type = typeof message.type === "string" ? message.type : "";
38
+ switch (type) {
39
+ case "text_delta":
40
+ return { type: "text_delta", text: stringValue(message.text) };
41
+ case "tool_call_start":
42
+ return {
43
+ type: "tool_start",
44
+ id: stringOrUndefined(message.toolCallId),
45
+ name: stringValue(message.name)
46
+ };
47
+ case "tool_call_end":
48
+ return {
49
+ type: "tool_end",
50
+ id: stringOrUndefined(message.toolCallId),
51
+ name: stringValue(message.name),
52
+ isError: message.isError === true
53
+ };
54
+ case "agent_done":
55
+ return { type: "completion" };
56
+ case "ready":
57
+ case "session_start":
58
+ case "model_change":
59
+ return { type: "status", status: message };
60
+ case "error":
61
+ return { type: "error", error: stringValue(message.message ?? message.error) };
62
+ default:
63
+ return null;
64
+ }
65
+ }
66
+ function createSendToGGCoderTool(bridge) {
67
+ return {
68
+ name: "send_to_ezcoder",
69
+ description: "Send a prompt or control command to a running ezcoder RPC session.",
70
+ parameters: {
71
+ type: "object",
72
+ properties: {
73
+ text: { type: "string", description: "Prompt text to send to ezcoder." }
74
+ },
75
+ required: ["text"]
76
+ },
77
+ async execute(args, context) {
78
+ const text = typeof args.text === "string" ? args.text : "";
79
+ if (!text) {
80
+ return { error: "text is required" };
81
+ }
82
+ const id = await bridge.send({ type: "prompt", text }, context.signal);
83
+ return { status: "sent", id };
84
+ }
85
+ };
86
+ }
87
+ function stringValue(value) {
88
+ return typeof value === "string" ? value : "";
89
+ }
90
+ function stringOrUndefined(value) {
91
+ return typeof value === "string" ? value : void 0;
92
+ }
93
+ function isJsonObject(value) {
94
+ return typeof value === "object" && value !== null && !Array.isArray(value);
95
+ }
96
+ export {
97
+ createGGCoderRpcBridge,
98
+ normalizeGGCoderRpcEvent,
99
+ toGGCoderRpcCommand
100
+ };
101
+ //# sourceMappingURL=ezcoder-rpc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/bridges/ezcoder-rpc.ts"],"sourcesContent":["import type { JsonObject, VoiceBridgeCommand, VoiceBridgeEvent, VoiceTool } from \"../types.js\";\n\nexport interface GGCoderRpcMessageSink {\n send(message: JsonObject, signal?: AbortSignal): Promise<void>;\n}\n\nexport interface GGCoderRpcBridgeOptions {\n readonly sink: GGCoderRpcMessageSink;\n readonly idFactory?: () => string;\n}\n\nexport interface GGCoderRpcBridge {\n send(command: VoiceBridgeCommand, signal?: AbortSignal): Promise<string>;\n toTool(): VoiceTool;\n}\n\nexport function createGGCoderRpcBridge(options: GGCoderRpcBridgeOptions): GGCoderRpcBridge {\n const idFactory = options.idFactory ?? (() => `ezcoder_${Date.now()}`);\n return {\n async send(command, signal): Promise<string> {\n const id = idFactory();\n await options.sink.send(toGGCoderRpcCommand(id, command), signal);\n return id;\n },\n toTool(): VoiceTool {\n return createSendToGGCoderTool(this);\n },\n };\n}\n\nexport function toGGCoderRpcCommand(id: string, command: VoiceBridgeCommand): JsonObject {\n switch (command.type) {\n case \"prompt\":\n return { id, command: \"prompt\", text: command.text };\n case \"cancel\":\n return { id, command: \"abort\" };\n case \"status\":\n return { id, command: \"get_state\" };\n case \"new_session\":\n return { id, command: \"new_session\" };\n case \"switch_model\":\n return { id, command: \"switch_model\", provider: command.provider, model: command.model };\n case \"switch_project\":\n return { id, command: \"prompt\", text: `Switch project to ${command.project}` };\n case \"list_projects\":\n return { id, command: \"prompt\", text: \"List available GG projects.\" };\n }\n}\n\nexport function normalizeGGCoderRpcEvent(message: unknown): VoiceBridgeEvent | null {\n if (!isJsonObject(message)) {\n return null;\n }\n const type = typeof message.type === \"string\" ? message.type : \"\";\n switch (type) {\n case \"text_delta\":\n return { type: \"text_delta\", text: stringValue(message.text) };\n case \"tool_call_start\":\n return {\n type: \"tool_start\",\n id: stringOrUndefined(message.toolCallId),\n name: stringValue(message.name),\n };\n case \"tool_call_end\":\n return {\n type: \"tool_end\",\n id: stringOrUndefined(message.toolCallId),\n name: stringValue(message.name),\n isError: message.isError === true,\n };\n case \"agent_done\":\n return { type: \"completion\" };\n case \"ready\":\n case \"session_start\":\n case \"model_change\":\n return { type: \"status\", status: message };\n case \"error\":\n return { type: \"error\", error: stringValue(message.message ?? message.error) };\n default:\n return null;\n }\n}\n\nfunction createSendToGGCoderTool(bridge: GGCoderRpcBridge): VoiceTool {\n return {\n name: \"send_to_ezcoder\",\n description: \"Send a prompt or control command to a running ezcoder RPC session.\",\n parameters: {\n type: \"object\",\n properties: {\n text: { type: \"string\", description: \"Prompt text to send to ezcoder.\" },\n },\n required: [\"text\"],\n },\n async execute(args, context) {\n const text = typeof args.text === \"string\" ? args.text : \"\";\n if (!text) {\n return { error: \"text is required\" };\n }\n const id = await bridge.send({ type: \"prompt\", text }, context.signal);\n return { status: \"sent\", id };\n },\n };\n}\n\nfunction stringValue(value: unknown): string {\n return typeof value === \"string\" ? value : \"\";\n}\n\nfunction stringOrUndefined(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction isJsonObject(value: unknown): value is JsonObject {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"],"mappings":"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","names":[]}