@ouro.bot/cli 0.1.0-alpha.560 → 0.1.0-alpha.562

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.
@@ -0,0 +1,216 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ function readRequiredAgentName() {
37
+ const agentArgIndex = process.argv.indexOf("--agent");
38
+ const value = agentArgIndex >= 0 ? process.argv[agentArgIndex + 1] : undefined;
39
+ if (value)
40
+ return value;
41
+ process.stderr.write("Missing required --agent <name> argument.\nUsage: node dist/senses/voice-twilio-entry.js --agent ouroboros --public-url https://<tunnel>\n");
42
+ process.exit(1);
43
+ }
44
+ const agentName = readRequiredAgentName();
45
+ const path = __importStar(require("path"));
46
+ const identity_1 = require("../heart/identity");
47
+ const machine_identity_1 = require("../heart/machine-identity");
48
+ const runtime_logging_1 = require("../heart/daemon/runtime-logging");
49
+ const provider_credentials_1 = require("../heart/provider-credentials");
50
+ const runtime_credentials_1 = require("../heart/runtime-credentials");
51
+ const runtime_1 = require("../nerves/runtime");
52
+ const elevenlabs_1 = require("./voice/elevenlabs");
53
+ const whisper_1 = require("./voice/whisper");
54
+ const twilio_phone_1 = require("./voice/twilio-phone");
55
+ function argValue(name) {
56
+ const index = process.argv.indexOf(name);
57
+ if (index < 0)
58
+ return undefined;
59
+ const value = process.argv[index + 1];
60
+ return value && !value.startsWith("--") ? value : undefined;
61
+ }
62
+ function asRecord(value) {
63
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
64
+ }
65
+ function configString(config, dottedPath) {
66
+ let cursor = config;
67
+ for (const segment of dottedPath.split(".")) {
68
+ const record = asRecord(cursor);
69
+ if (!record)
70
+ return undefined;
71
+ cursor = record[segment];
72
+ }
73
+ return typeof cursor === "string" && cursor.trim() ? cursor.trim() : undefined;
74
+ }
75
+ function configNumber(config, dottedPath) {
76
+ let cursor = config;
77
+ for (const segment of dottedPath.split(".")) {
78
+ const record = asRecord(cursor);
79
+ if (!record)
80
+ return undefined;
81
+ cursor = record[segment];
82
+ }
83
+ if (typeof cursor === "number" && Number.isFinite(cursor))
84
+ return cursor;
85
+ if (typeof cursor === "string" && cursor.trim()) {
86
+ const parsed = Number(cursor);
87
+ return Number.isFinite(parsed) ? parsed : undefined;
88
+ }
89
+ return undefined;
90
+ }
91
+ function requireConfig(result, label) {
92
+ if (result.ok)
93
+ return result.config;
94
+ throw new Error(`${label} unavailable: ${result.error}`);
95
+ }
96
+ function required(value, guidance) {
97
+ if (value)
98
+ return value;
99
+ throw new Error(guidance);
100
+ }
101
+ function numberArg(name) {
102
+ const raw = argValue(name);
103
+ if (!raw)
104
+ return undefined;
105
+ const parsed = Number(raw);
106
+ if (!Number.isFinite(parsed))
107
+ throw new Error(`${name} must be a number`);
108
+ return parsed;
109
+ }
110
+ function selectedAgentProviders(config) {
111
+ const providers = new Set();
112
+ providers.add(config.humanFacing.provider);
113
+ providers.add(config.agentFacing.provider);
114
+ if (config.provider)
115
+ providers.add(config.provider);
116
+ return [...providers];
117
+ }
118
+ async function cacheSelectedProviderCredentials(agentName) {
119
+ const providers = selectedAgentProviders((0, identity_1.loadAgentConfig)());
120
+ const pool = await (0, provider_credentials_1.refreshProviderCredentialPool)(agentName, { providers });
121
+ if (!pool.ok) {
122
+ throw new Error(`provider credentials unavailable for phone voice: ${pool.error}`);
123
+ }
124
+ const missing = providers.filter((provider) => !pool.pool.providers[provider]);
125
+ if (missing.length > 0) {
126
+ throw new Error(`missing provider credentials for phone voice: ${missing.join(", ")}`);
127
+ }
128
+ }
129
+ function writeReadyInstructions(localUrl, publicBaseUrl) {
130
+ process.stdout.write([
131
+ "Twilio phone voice bridge ready.",
132
+ `local: ${localUrl}`,
133
+ `public: ${publicBaseUrl}`,
134
+ `Twilio Voice webhook: POST ${new URL(`${twilio_phone_1.TWILIO_PHONE_WEBHOOK_BASE_PATH}/incoming`, publicBaseUrl).toString()}`,
135
+ "",
136
+ ].join("\n"));
137
+ }
138
+ (0, runtime_logging_1.configureDaemonRuntimeLogger)("voice");
139
+ (0, runtime_1.emitNervesEvent)({
140
+ component: "senses",
141
+ event: "senses.entry_boot",
142
+ message: "booting Twilio Voice entrypoint",
143
+ meta: { entry: "voice-twilio", agentName },
144
+ });
145
+ async function main() {
146
+ await (0, runtime_credentials_1.waitForRuntimeCredentialBootstrap)(agentName);
147
+ const machine = (0, machine_identity_1.loadOrCreateMachineIdentity)();
148
+ await Promise.all([
149
+ (0, runtime_credentials_1.refreshRuntimeCredentialConfig)(agentName, { preserveCachedOnFailure: true }).catch(() => undefined),
150
+ (0, runtime_credentials_1.refreshMachineRuntimeCredentialConfig)(agentName, machine.machineId, { preserveCachedOnFailure: true }).catch(() => undefined),
151
+ ]);
152
+ await cacheSelectedProviderCredentials(agentName);
153
+ const runtimeConfig = requireConfig((0, runtime_credentials_1.readRuntimeCredentialConfig)(agentName), "portable runtime/config");
154
+ const machineConfig = requireConfig((0, runtime_credentials_1.readMachineRuntimeCredentialConfig)(agentName), "machine runtime config");
155
+ const port = numberArg("--port")
156
+ ?? configNumber(machineConfig, "voice.twilioPort")
157
+ ?? twilio_phone_1.DEFAULT_TWILIO_PHONE_PORT;
158
+ const host = argValue("--host")
159
+ ?? configString(machineConfig, "voice.twilioHost")
160
+ ?? "127.0.0.1";
161
+ const publicBaseUrl = required(argValue("--public-url") ?? configString(machineConfig, "voice.twilioPublicUrl"), `missing public URL; run 'cloudflared tunnel --url http://127.0.0.1:${port}' and restart with --public-url https://<tunnel>`);
162
+ const elevenLabsApiKey = required(configString(runtimeConfig, "integrations.elevenLabsApiKey"), "missing integrations.elevenLabsApiKey; run 'ouro connect voice --agent <agent>' for setup guidance");
163
+ const elevenLabsVoiceId = required(argValue("--elevenlabs-voice-id")
164
+ ?? configString(runtimeConfig, "integrations.elevenLabsVoiceId")
165
+ ?? configString(runtimeConfig, "voice.elevenLabsVoiceId"), "missing integrations.elevenLabsVoiceId; save the ElevenLabs voice ID before starting phone voice");
166
+ const whisperCliPath = required(configString(machineConfig, "voice.whisperCliPath"), "missing voice.whisperCliPath in this machine's runtime config");
167
+ const whisperModelPath = required(configString(machineConfig, "voice.whisperModelPath"), "missing voice.whisperModelPath in this machine's runtime config");
168
+ const outputDir = argValue("--output-dir")
169
+ ?? configString(machineConfig, "voice.twilioOutputDir")
170
+ ?? path.join((0, identity_1.getAgentRoot)(agentName), "state", "voice", "twilio-phone");
171
+ const defaultFriendId = argValue("--friend")
172
+ ?? configString(machineConfig, "voice.twilioDefaultFriendId");
173
+ const twilioAccountSid = configString(runtimeConfig, "voice.twilioAccountSid");
174
+ const twilioAuthToken = configString(runtimeConfig, "voice.twilioAuthToken");
175
+ const recordTimeoutSeconds = numberArg("--record-timeout")
176
+ ?? configNumber(machineConfig, "voice.twilioRecordTimeoutSeconds")
177
+ ?? twilio_phone_1.DEFAULT_TWILIO_RECORD_TIMEOUT_SECONDS;
178
+ const recordMaxLengthSeconds = numberArg("--record-max-length")
179
+ ?? configNumber(machineConfig, "voice.twilioRecordMaxLengthSeconds")
180
+ ?? twilio_phone_1.DEFAULT_TWILIO_RECORD_MAX_LENGTH_SECONDS;
181
+ const transcriber = (0, whisper_1.createWhisperCppTranscriber)({
182
+ whisperCliPath,
183
+ modelPath: whisperModelPath,
184
+ });
185
+ const tts = (0, elevenlabs_1.createElevenLabsTtsClient)({
186
+ apiKey: elevenLabsApiKey,
187
+ voiceId: elevenLabsVoiceId,
188
+ outputFormat: "mp3_44100_128",
189
+ });
190
+ const bridge = await (0, twilio_phone_1.startTwilioPhoneBridgeServer)({
191
+ agentName,
192
+ publicBaseUrl,
193
+ outputDir,
194
+ transcriber,
195
+ tts,
196
+ port,
197
+ host,
198
+ twilioAccountSid,
199
+ twilioAuthToken,
200
+ defaultFriendId,
201
+ recordTimeoutSeconds,
202
+ recordMaxLengthSeconds,
203
+ });
204
+ writeReadyInstructions(bridge.localUrl, publicBaseUrl);
205
+ }
206
+ main().catch((error) => {
207
+ (0, runtime_1.emitNervesEvent)({
208
+ level: "error",
209
+ component: "senses",
210
+ event: "senses.entry_error",
211
+ message: "Twilio Voice entrypoint failed",
212
+ meta: { entry: "voice-twilio", agentName, error: error instanceof Error ? error.message : String(error) },
213
+ });
214
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
215
+ process.exit(1);
216
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.560",
3
+ "version": "0.1.0-alpha.562",
4
4
  "main": "dist/heart/daemon/ouro-entry.js",
5
5
  "bin": {
6
6
  "cli": "dist/heart/daemon/ouro-bot-entry.js",