@ai-ecoverse/pi-audio 1.22.0 → 1.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/custom-llm.js +32 -0
- package/dist/custom-llm.js.map +7 -0
- package/dist/elevenlabs-agents/index.js +2 -0
- package/dist/elevenlabs-agents/index.js.map +2 -2
- package/dist/elevenlabs-agents/provision.js +2 -8
- package/dist/elevenlabs-agents/provision.js.map +2 -2
- package/dist/fish-agents/index.js +2 -0
- package/dist/fish-agents/index.js.map +2 -2
- package/dist/fish-agents/provision.js +2 -14
- package/dist/fish-agents/provision.js.map +2 -2
- package/dist/types/custom-llm.d.ts +4 -0
- package/dist/types/elevenlabs-agents/index.d.ts +1 -0
- package/dist/types/fish-agents/index.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -56,9 +56,9 @@ pi-audio does not apply that patch. Hosts such as slicc-agent record monkeypatch
|
|
|
56
56
|
|
|
57
57
|
`mintRealtimeToken(model, constraints, options)` returns `{ value, expiresAt, model, url? }` and calls `options.fetch` (or `globalThis.fetch`). OpenAI `POST /v1/realtime/client_secrets` sends a realtime session with instructions, voice, and tools. xAI `POST /v1/realtime/client_secrets` sends only `expires_after.seconds` of 300. Gemini `POST /v1beta/auth_tokens` locks `models/<id>`, instructions, voice, and tools in `liveConnectConstraints` and returns `name`, which the live adapter sends as `access_token`. ElevenLabs `GET /v1/convai/conversation/get-signed-url` takes `agent_id` (or `GET /conversation/token` when the only transport is WebRTC) and expires in 15 minutes. Fish `POST /v1/agent/sessions` sends `agent_id` plus `overrides.system_prompt` and `overrides.voice_id`. `value` is the LiveKit participant token and `url` is `livekit_url`. `expiresAt` is milliseconds. A numeric `expires_at` below `1e12` is unix seconds.
|
|
58
58
|
|
|
59
|
-
`@ai-ecoverse/pi-audio/elevenlabs-agents` registers `elevenlabs-agent`, a hosted cascade (`provisioning: "agent"`, `truncation: "server"`, `liveToolUpdate: false`). `provisionAgent` creates or updates the agent and reuses it when the spec hash matches. pi tools become client tools. A string `llm` is a vendor model name.
|
|
59
|
+
`@ai-ecoverse/pi-audio/elevenlabs-agents` registers `elevenlabs-agent`, a hosted cascade (`provisioning: "agent"`, `truncation: "server"`, `liveToolUpdate: false`). `provisionAgent` creates or updates the agent and reuses it when the spec hash matches. pi tools become client tools. A string `llm` is a vendor model name. `elevenLabsCustomLlm` sets `llm` to `custom-llm` and sends `custom_llm.url`, `model_id`, `api_type`, and `request_headers` (ElevenLabs `api_key` is a workspace secret reference, not a raw token). `connectRealtime` uses a `RealtimeToken` from `mintRealtimeToken` (`get-signed-url`) when one is passed. Otherwise an API key provisions the agent and mints the signed URL. Silent `inject` sends `contextual_update` with `context_id` `pi-audio`. `close()` prices `audio.inputSeconds` from the wall-clock session at $0.08 per minute.
|
|
60
60
|
|
|
61
|
-
`@ai-ecoverse/pi-audio/fish-agents` registers `fish-agent` (`transports: ["webrtc"]`, `delivery.silent: "approximate"`, `delivery.interrupt: "native"`). `provisionAgent` creates client tools, writes the draft, and publishes it. A `RealtimeToken` with `url` is the LiveKit room from `mintRealtimeToken`; connect does not open a second session. Without a token, connect creates the session and fails on an unknown `transport`. Silent `inject` sends `user.message` with `audio: false` and drops that reply's transcript. The microphone is published after `openEchoMic`. The catalog `audioCost` is zero because Fish has not published a per-minute session rate. The example voice id is the one in Fish's quickstart.
|
|
61
|
+
`@ai-ecoverse/pi-audio/fish-agents` registers `fish-agent` (`transports: ["webrtc"]`, `delivery.silent: "approximate"`, `delivery.interrupt: "native"`). `provisionAgent` creates client tools, writes the draft, and publishes it. `fishCustomLlm` sends `llm.custom.base_url`, `model`, and a raw `api_key`, and rejects `openai-responses`. A `RealtimeToken` with `url` is the LiveKit room from `mintRealtimeToken`; connect does not open a second session. Without a token, connect creates the session and fails on an unknown `transport`. Silent `inject` sends `user.message` with `audio: false` and drops that reply's transcript. The microphone is published after `openEchoMic`. The catalog `audioCost` is zero because Fish has not published a per-minute session rate. The example voice id is the one in Fish's quickstart.
|
|
62
62
|
|
|
63
63
|
`talkerTools` is `ask_agent` and `read`. pi-audio defines `askAgent` (a pi `Tool` whose parameters are `request` and optional `context`) and the `Thinker` interface. The host implements `Thinker` and supplies `read`. `bindThinker` runs direct tools with `directTimeoutMs` and truncates their text to `directMaxChars`. On a blocking `ask_agent` it answers with `ack` immediately and injects the result later. On an async call it `respond`s with the result and `options.result`. Progress is injected with `options.progress`. `tool_call_cancelled` aborts the thinker and any direct tool. A blocking failure is injected after the acknowledgement, with a `thinker_result` caption. `Thinker.ask` receives the optional `context` string. Closing the session aborts work that is still running. The binding also yields `thinker_progress` / `thinker_result` captions and `thinking` / `tool` / `idle` phases.
|
|
64
64
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { VoiceRequestError } from "./errors.js";
|
|
2
|
+
function bearer(headers) {
|
|
3
|
+
if (headers === void 0) return void 0;
|
|
4
|
+
const value = headers.Authorization ?? headers.authorization;
|
|
5
|
+
if (typeof value !== "string" || value.length === 0) return void 0;
|
|
6
|
+
if (value.startsWith("Bearer ")) return value.slice("Bearer ".length);
|
|
7
|
+
return value;
|
|
8
|
+
}
|
|
9
|
+
function elevenLabsCustomLlm(llm) {
|
|
10
|
+
const custom = {
|
|
11
|
+
url: llm.baseUrl,
|
|
12
|
+
model_id: llm.id,
|
|
13
|
+
api_type: llm.api === "openai-responses" ? "responses" : "chat_completions"
|
|
14
|
+
};
|
|
15
|
+
const headers = llm.headers;
|
|
16
|
+
if (headers !== void 0 && Object.keys(headers).length > 0) custom.request_headers = headers;
|
|
17
|
+
return { llm: "custom-llm", custom_llm: custom };
|
|
18
|
+
}
|
|
19
|
+
function fishCustomLlm(llm) {
|
|
20
|
+
if (llm.api === "openai-responses") {
|
|
21
|
+
throw new VoiceRequestError("error", "fish custom llm accepts openai-completions only");
|
|
22
|
+
}
|
|
23
|
+
const custom = { base_url: llm.baseUrl, model: llm.id };
|
|
24
|
+
const key = bearer(llm.headers);
|
|
25
|
+
if (key !== void 0) custom.api_key = key;
|
|
26
|
+
return { custom };
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
elevenLabsCustomLlm,
|
|
30
|
+
fishCustomLlm
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=custom-llm.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/custom-llm.ts"],
|
|
4
|
+
"sourcesContent": ["import type { JsonObject } from '@earendil-works/pi-ai';\nimport { VoiceRequestError } from './errors.ts';\nimport type { CustomLlm } from './hosted-agent.ts';\n\nfunction bearer(headers: CustomLlm['headers']): string | undefined {\n if (headers === undefined) return undefined;\n const value = headers.Authorization ?? headers.authorization;\n if (typeof value !== 'string' || value.length === 0) return undefined;\n if (value.startsWith('Bearer ')) return value.slice('Bearer '.length);\n return value;\n}\n\nexport function elevenLabsCustomLlm(llm: CustomLlm): JsonObject {\n const custom: JsonObject = {\n url: llm.baseUrl,\n model_id: llm.id,\n api_type: llm.api === 'openai-responses' ? 'responses' : 'chat_completions',\n };\n const headers = llm.headers;\n if (headers !== undefined && Object.keys(headers).length > 0) custom.request_headers = headers;\n return { llm: 'custom-llm', custom_llm: custom };\n}\n\nexport function fishCustomLlm(llm: CustomLlm): JsonObject {\n if (llm.api === 'openai-responses') {\n throw new VoiceRequestError('error', 'fish custom llm accepts openai-completions only');\n }\n const custom: JsonObject = { base_url: llm.baseUrl, model: llm.id };\n const key = bearer(llm.headers);\n if (key !== undefined) custom.api_key = key;\n return { custom };\n}\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,yBAAyB;AAGlC,SAAS,OAAO,SAAmD;AACjE,MAAI,YAAY,OAAW,QAAO;AAClC,QAAM,QAAQ,QAAQ,iBAAiB,QAAQ;AAC/C,MAAI,OAAO,UAAU,YAAY,MAAM,WAAW,EAAG,QAAO;AAC5D,MAAI,MAAM,WAAW,SAAS,EAAG,QAAO,MAAM,MAAM,UAAU,MAAM;AACpE,SAAO;AACT;AAEO,SAAS,oBAAoB,KAA4B;AAC9D,QAAM,SAAqB;AAAA,IACzB,KAAK,IAAI;AAAA,IACT,UAAU,IAAI;AAAA,IACd,UAAU,IAAI,QAAQ,qBAAqB,cAAc;AAAA,EAC3D;AACA,QAAM,UAAU,IAAI;AACpB,MAAI,YAAY,UAAa,OAAO,KAAK,OAAO,EAAE,SAAS,EAAG,QAAO,kBAAkB;AACvF,SAAO,EAAE,KAAK,cAAc,YAAY,OAAO;AACjD;AAEO,SAAS,cAAc,KAA4B;AACxD,MAAI,IAAI,QAAQ,oBAAoB;AAClC,UAAM,IAAI,kBAAkB,SAAS,iDAAiD;AAAA,EACxF;AACA,QAAM,SAAqB,EAAE,UAAU,IAAI,SAAS,OAAO,IAAI,GAAG;AAClE,QAAM,MAAM,OAAO,IAAI,OAAO;AAC9B,MAAI,QAAQ,OAAW,QAAO,UAAU;AACxC,SAAO,EAAE,OAAO;AAClB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -44,11 +44,13 @@ function registerElevenLabsAgents(options = {}) {
|
|
|
44
44
|
unregisterApi();
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
|
+
import { elevenLabsCustomLlm } from "../custom-llm.js";
|
|
47
48
|
import { hashHostedSpec, memoryHostedCache } from "../hosted-agent.js";
|
|
48
49
|
import { agentBody, httpsOrigin, provisionAgent } from "./provision.js";
|
|
49
50
|
export {
|
|
50
51
|
agentBody,
|
|
51
52
|
elevenLabsAgent,
|
|
53
|
+
elevenLabsCustomLlm,
|
|
52
54
|
hashHostedSpec,
|
|
53
55
|
httpsOrigin,
|
|
54
56
|
memoryHostedCache,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/elevenlabs-agents/index.ts"],
|
|
4
|
-
"sourcesContent": ["import type { RealtimeModel } from '../models.ts';\nimport { registerVoiceModel } from '../models.ts';\nimport { registerRealtimeApiProvider } from '../registry.ts';\nimport type { ElevenLabsOptions } from './session.ts';\nimport { connectElevenLabs } from './session.ts';\n\nconst voices = [\n { id: '21m00Tcm4TlvDq8ikWAM', name: 'Rachel' },\n { id: 'EXAVITQu4vr4xnSDxMaL', name: 'Sarah' },\n { id: 'pNInz6obpgDQGcFmaJgB', name: 'Adam' },\n];\n\nfunction pcm16(sampleRate: number) {\n return { encoding: 'pcm16' as const, sampleRate, channels: 1 as const };\n}\n\nexport const elevenLabsAgent: RealtimeModel<'elevenlabs-agents'> = {\n id: 'elevenlabs-agent',\n name: 'ElevenLabs Agent',\n api: 'elevenlabs-agents',\n provider: 'elevenlabs',\n baseUrl: 'wss://api.elevenlabs.io/v1/convai/conversation',\n type: 'realtime',\n transports: ['websocket'],\n toolCalls: 'blocking',\n inputFormat: pcm16(16000),\n outputFormat: pcm16(16000),\n maxSessionMs: 600_000,\n resumable: false,\n ephemeralAuth: true,\n voices,\n cascade: { stt: 'scribe_realtime', llm: 'gemini-2.5-flash', tts: 'eleven_flash_v2_5' },\n provisioning: 'agent',\n delivery: { interrupt: 'approximate', when_idle: 'approximate', silent: 'native' },\n truncation: 'server',\n liveToolUpdate: false,\n toolTimeoutMs: { min: 1000, max: 120_000 },\n cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n audioCost: { perInputMinute: 0.08 },\n};\n\nexport function registerElevenLabsAgents(options: ElevenLabsOptions = {}): () => void {\n const unregisterModel = registerVoiceModel(elevenLabsAgent);\n const unregisterApi = registerRealtimeApiProvider({\n api: 'elevenlabs-agents',\n connect: (model, context, connectOptions) =>\n connectElevenLabs(model, context, connectOptions, options),\n });\n return () => {\n unregisterModel();\n unregisterApi();\n };\n}\n\nexport type { CustomLlm, HostedAgent, HostedAgentSpec, HostedCache } from '../hosted-agent.ts';\nexport { hashHostedSpec, memoryHostedCache } from '../hosted-agent.ts';\nexport type { ProvisionOptions } from './provision.ts';\nexport { agentBody, httpsOrigin, provisionAgent } from './provision.ts';\nexport type { ElevenLabsOptions, VoiceWireFactory } from './session.ts';\n"],
|
|
5
|
-
"mappings": "AACA,SAAS,0BAA0B;AACnC,SAAS,mCAAmC;AAE5C,SAAS,yBAAyB;AAElC,MAAM,SAAS;AAAA,EACb,EAAE,IAAI,wBAAwB,MAAM,SAAS;AAAA,EAC7C,EAAE,IAAI,wBAAwB,MAAM,QAAQ;AAAA,EAC5C,EAAE,IAAI,wBAAwB,MAAM,OAAO;AAC7C;AAEA,SAAS,MAAM,YAAoB;AACjC,SAAO,EAAE,UAAU,SAAkB,YAAY,UAAU,EAAW;AACxE;AAEO,MAAM,kBAAsD;AAAA,EACjE,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,KAAK;AAAA,EACL,UAAU;AAAA,EACV,SAAS;AAAA,EACT,MAAM;AAAA,EACN,YAAY,CAAC,WAAW;AAAA,EACxB,WAAW;AAAA,EACX,aAAa,MAAM,IAAK;AAAA,EACxB,cAAc,MAAM,IAAK;AAAA,EACzB,cAAc;AAAA,EACd,WAAW;AAAA,EACX,eAAe;AAAA,EACf;AAAA,EACA,SAAS,EAAE,KAAK,mBAAmB,KAAK,oBAAoB,KAAK,oBAAoB;AAAA,EACrF,cAAc;AAAA,EACd,UAAU,EAAE,WAAW,eAAe,WAAW,eAAe,QAAQ,SAAS;AAAA,EACjF,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,eAAe,EAAE,KAAK,KAAM,KAAK,KAAQ;AAAA,EACzC,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,WAAW,GAAG,YAAY,EAAE;AAAA,EACzD,WAAW,EAAE,gBAAgB,KAAK;AACpC;AAEO,SAAS,yBAAyB,UAA6B,CAAC,GAAe;AACpF,QAAM,kBAAkB,mBAAmB,eAAe;AAC1D,QAAM,gBAAgB,4BAA4B;AAAA,IAChD,KAAK;AAAA,IACL,SAAS,CAAC,OAAO,SAAS,mBACxB,kBAAkB,OAAO,SAAS,gBAAgB,OAAO;AAAA,EAC7D,CAAC;AACD,SAAO,MAAM;AACX,oBAAgB;AAChB,kBAAc;AAAA,EAChB;AACF;
|
|
4
|
+
"sourcesContent": ["import type { RealtimeModel } from '../models.ts';\nimport { registerVoiceModel } from '../models.ts';\nimport { registerRealtimeApiProvider } from '../registry.ts';\nimport type { ElevenLabsOptions } from './session.ts';\nimport { connectElevenLabs } from './session.ts';\n\nconst voices = [\n { id: '21m00Tcm4TlvDq8ikWAM', name: 'Rachel' },\n { id: 'EXAVITQu4vr4xnSDxMaL', name: 'Sarah' },\n { id: 'pNInz6obpgDQGcFmaJgB', name: 'Adam' },\n];\n\nfunction pcm16(sampleRate: number) {\n return { encoding: 'pcm16' as const, sampleRate, channels: 1 as const };\n}\n\nexport const elevenLabsAgent: RealtimeModel<'elevenlabs-agents'> = {\n id: 'elevenlabs-agent',\n name: 'ElevenLabs Agent',\n api: 'elevenlabs-agents',\n provider: 'elevenlabs',\n baseUrl: 'wss://api.elevenlabs.io/v1/convai/conversation',\n type: 'realtime',\n transports: ['websocket'],\n toolCalls: 'blocking',\n inputFormat: pcm16(16000),\n outputFormat: pcm16(16000),\n maxSessionMs: 600_000,\n resumable: false,\n ephemeralAuth: true,\n voices,\n cascade: { stt: 'scribe_realtime', llm: 'gemini-2.5-flash', tts: 'eleven_flash_v2_5' },\n provisioning: 'agent',\n delivery: { interrupt: 'approximate', when_idle: 'approximate', silent: 'native' },\n truncation: 'server',\n liveToolUpdate: false,\n toolTimeoutMs: { min: 1000, max: 120_000 },\n cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n audioCost: { perInputMinute: 0.08 },\n};\n\nexport function registerElevenLabsAgents(options: ElevenLabsOptions = {}): () => void {\n const unregisterModel = registerVoiceModel(elevenLabsAgent);\n const unregisterApi = registerRealtimeApiProvider({\n api: 'elevenlabs-agents',\n connect: (model, context, connectOptions) =>\n connectElevenLabs(model, context, connectOptions, options),\n });\n return () => {\n unregisterModel();\n unregisterApi();\n };\n}\n\nexport { elevenLabsCustomLlm } from '../custom-llm.ts';\nexport type { CustomLlm, HostedAgent, HostedAgentSpec, HostedCache } from '../hosted-agent.ts';\nexport { hashHostedSpec, memoryHostedCache } from '../hosted-agent.ts';\nexport type { ProvisionOptions } from './provision.ts';\nexport { agentBody, httpsOrigin, provisionAgent } from './provision.ts';\nexport type { ElevenLabsOptions, VoiceWireFactory } from './session.ts';\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,0BAA0B;AACnC,SAAS,mCAAmC;AAE5C,SAAS,yBAAyB;AAElC,MAAM,SAAS;AAAA,EACb,EAAE,IAAI,wBAAwB,MAAM,SAAS;AAAA,EAC7C,EAAE,IAAI,wBAAwB,MAAM,QAAQ;AAAA,EAC5C,EAAE,IAAI,wBAAwB,MAAM,OAAO;AAC7C;AAEA,SAAS,MAAM,YAAoB;AACjC,SAAO,EAAE,UAAU,SAAkB,YAAY,UAAU,EAAW;AACxE;AAEO,MAAM,kBAAsD;AAAA,EACjE,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,KAAK;AAAA,EACL,UAAU;AAAA,EACV,SAAS;AAAA,EACT,MAAM;AAAA,EACN,YAAY,CAAC,WAAW;AAAA,EACxB,WAAW;AAAA,EACX,aAAa,MAAM,IAAK;AAAA,EACxB,cAAc,MAAM,IAAK;AAAA,EACzB,cAAc;AAAA,EACd,WAAW;AAAA,EACX,eAAe;AAAA,EACf;AAAA,EACA,SAAS,EAAE,KAAK,mBAAmB,KAAK,oBAAoB,KAAK,oBAAoB;AAAA,EACrF,cAAc;AAAA,EACd,UAAU,EAAE,WAAW,eAAe,WAAW,eAAe,QAAQ,SAAS;AAAA,EACjF,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,eAAe,EAAE,KAAK,KAAM,KAAK,KAAQ;AAAA,EACzC,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,WAAW,GAAG,YAAY,EAAE;AAAA,EACzD,WAAW,EAAE,gBAAgB,KAAK;AACpC;AAEO,SAAS,yBAAyB,UAA6B,CAAC,GAAe;AACpF,QAAM,kBAAkB,mBAAmB,eAAe;AAC1D,QAAM,gBAAgB,4BAA4B;AAAA,IAChD,KAAK;AAAA,IACL,SAAS,CAAC,OAAO,SAAS,mBACxB,kBAAkB,OAAO,SAAS,gBAAgB,OAAO;AAAA,EAC7D,CAAC;AACD,SAAO,MAAM;AACX,oBAAgB;AAChB,kBAAc;AAAA,EAChB;AACF;AAEA,SAAS,2BAA2B;AAEpC,SAAS,gBAAgB,yBAAyB;AAElD,SAAS,WAAW,aAAa,sBAAsB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { elevenLabsCustomLlm } from "../custom-llm.js";
|
|
1
2
|
import { VoiceRequestError } from "../errors.js";
|
|
2
3
|
import {
|
|
3
4
|
hashHostedSpec,
|
|
@@ -66,14 +67,7 @@ function clientTool(tool, timeoutMs) {
|
|
|
66
67
|
};
|
|
67
68
|
}
|
|
68
69
|
function customLlmFields(llm) {
|
|
69
|
-
|
|
70
|
-
url: llm.baseUrl,
|
|
71
|
-
model_id: llm.id,
|
|
72
|
-
api_type: llm.api === "openai-responses" ? "responses" : "chat_completions"
|
|
73
|
-
};
|
|
74
|
-
const headers = llm.headers;
|
|
75
|
-
if (headers !== void 0 && Object.keys(headers).length > 0) custom.request_headers = headers;
|
|
76
|
-
return { llm: "custom-llm", custom_llm: custom };
|
|
70
|
+
return elevenLabsCustomLlm(llm);
|
|
77
71
|
}
|
|
78
72
|
function promptFields(spec) {
|
|
79
73
|
const llm = typeof spec.llm === "string" ? { llm: spec.llm } : customLlmFields(spec.llm);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/elevenlabs-agents/provision.ts"],
|
|
4
|
-
"sourcesContent": ["import type { JsonObject, ProviderRequestOptions, Tool } from '@earendil-works/pi-ai';\nimport { VoiceRequestError } from '../errors.ts';\nimport {\n type CustomLlm,\n type HostedAgent,\n type HostedAgentSpec,\n type HostedCache,\n hashHostedSpec,\n hostedCacheKey,\n memoryHostedCache,\n} from '../hosted-agent.ts';\nimport type { RealtimeModel } from '../models.ts';\n\nexport interface ProvisionOptions extends ProviderRequestOptions {\n agentId?: string;\n now?: () => number;\n cache?: HostedCache;\n}\n\nconst defaultCache = memoryHostedCache();\n\nconst clientEvents = [\n 'conversation_initiation_metadata',\n 'ping',\n 'audio',\n 'interruption',\n 'user_transcript',\n 'agent_response',\n 'agent_response_correction',\n 'client_tool_call',\n 'vad_score',\n 'agent_chat_response_part',\n 'agent_response_complete',\n];\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction asVoice(error: unknown): VoiceRequestError {\n if (error instanceof VoiceRequestError) return error;\n if (error instanceof Error && error.name === 'AbortError') {\n return new VoiceRequestError('aborted', 'session aborted');\n }\n if (error instanceof Error) return new VoiceRequestError('error', error.message);\n return new VoiceRequestError('error', String(error));\n}\n\nexport function httpsOrigin(baseUrl: string): string {\n const url = new URL(baseUrl);\n let protocol = url.protocol;\n if (protocol === 'wss:') protocol = 'https:';\n if (protocol === 'ws:') protocol = 'http:';\n return `${protocol}//${url.host}`;\n}\n\nfunction mergedHeaders(\n options: ProvisionOptions,\n defaults: Record<string, string>\n): Record<string, string> {\n const headers = { ...defaults };\n const extra = options.headers;\n if (extra === undefined) return headers;\n for (const [key, value] of Object.entries(extra)) {\n if (value === null) delete headers[key];\n else headers[key] = value;\n }\n return headers;\n}\n\nfunction apiKey(options: ProvisionOptions): string {\n const key = options.apiKey;\n if (typeof key === 'string' && key.length > 0) return key;\n throw new VoiceRequestError('error', 'missing realtime credential');\n}\n\nfunction timeoutSeconds(timeoutMs: number | undefined): number {\n if (timeoutMs === undefined) return 20;\n return Math.min(120, Math.max(1, Math.round(timeoutMs / 1000)));\n}\n\nfunction clientTool(tool: Tool, timeoutMs: number | undefined): JsonObject {\n return {\n type: 'client',\n name: tool.name,\n description: tool.description,\n expects_response: true,\n response_timeout_secs: timeoutSeconds(timeoutMs),\n parameters: tool.parameters as unknown as JsonObject,\n };\n}\n\nfunction customLlmFields(llm: CustomLlm): JsonObject {\n
|
|
5
|
-
"mappings": "AACA,SAAS,yBAAyB;AAClC;AAAA,EAKE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AASP,MAAM,eAAe,kBAAkB;AAEvC,MAAM,eAAe;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,QAAQ,OAAmC;AAClD,MAAI,iBAAiB,kBAAmB,QAAO;AAC/C,MAAI,iBAAiB,SAAS,MAAM,SAAS,cAAc;AACzD,WAAO,IAAI,kBAAkB,WAAW,iBAAiB;AAAA,EAC3D;AACA,MAAI,iBAAiB,MAAO,QAAO,IAAI,kBAAkB,SAAS,MAAM,OAAO;AAC/E,SAAO,IAAI,kBAAkB,SAAS,OAAO,KAAK,CAAC;AACrD;AAEO,SAAS,YAAY,SAAyB;AACnD,QAAM,MAAM,IAAI,IAAI,OAAO;AAC3B,MAAI,WAAW,IAAI;AACnB,MAAI,aAAa,OAAQ,YAAW;AACpC,MAAI,aAAa,MAAO,YAAW;AACnC,SAAO,GAAG,QAAQ,KAAK,IAAI,IAAI;AACjC;AAEA,SAAS,cACP,SACA,UACwB;AACxB,QAAM,UAAU,EAAE,GAAG,SAAS;AAC9B,QAAM,QAAQ,QAAQ;AACtB,MAAI,UAAU,OAAW,QAAO;AAChC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,UAAU,KAAM,QAAO,QAAQ,GAAG;AAAA,QACjC,SAAQ,GAAG,IAAI;AAAA,EACtB;AACA,SAAO;AACT;AAEA,SAAS,OAAO,SAAmC;AACjD,QAAM,MAAM,QAAQ;AACpB,MAAI,OAAO,QAAQ,YAAY,IAAI,SAAS,EAAG,QAAO;AACtD,QAAM,IAAI,kBAAkB,SAAS,6BAA6B;AACpE;AAEA,SAAS,eAAe,WAAuC;AAC7D,MAAI,cAAc,OAAW,QAAO;AACpC,SAAO,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,YAAY,GAAI,CAAC,CAAC;AAChE;AAEA,SAAS,WAAW,MAAY,WAA2C;AACzE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM,KAAK;AAAA,IACX,aAAa,KAAK;AAAA,IAClB,kBAAkB;AAAA,IAClB,uBAAuB,eAAe,SAAS;AAAA,IAC/C,YAAY,KAAK;AAAA,EACnB;AACF;AAEA,SAAS,gBAAgB,KAA4B;AACnD,
|
|
4
|
+
"sourcesContent": ["import type { JsonObject, ProviderRequestOptions, Tool } from '@earendil-works/pi-ai';\nimport { elevenLabsCustomLlm } from '../custom-llm.ts';\nimport { VoiceRequestError } from '../errors.ts';\nimport {\n type CustomLlm,\n type HostedAgent,\n type HostedAgentSpec,\n type HostedCache,\n hashHostedSpec,\n hostedCacheKey,\n memoryHostedCache,\n} from '../hosted-agent.ts';\nimport type { RealtimeModel } from '../models.ts';\n\nexport interface ProvisionOptions extends ProviderRequestOptions {\n agentId?: string;\n now?: () => number;\n cache?: HostedCache;\n}\n\nconst defaultCache = memoryHostedCache();\n\nconst clientEvents = [\n 'conversation_initiation_metadata',\n 'ping',\n 'audio',\n 'interruption',\n 'user_transcript',\n 'agent_response',\n 'agent_response_correction',\n 'client_tool_call',\n 'vad_score',\n 'agent_chat_response_part',\n 'agent_response_complete',\n];\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction asVoice(error: unknown): VoiceRequestError {\n if (error instanceof VoiceRequestError) return error;\n if (error instanceof Error && error.name === 'AbortError') {\n return new VoiceRequestError('aborted', 'session aborted');\n }\n if (error instanceof Error) return new VoiceRequestError('error', error.message);\n return new VoiceRequestError('error', String(error));\n}\n\nexport function httpsOrigin(baseUrl: string): string {\n const url = new URL(baseUrl);\n let protocol = url.protocol;\n if (protocol === 'wss:') protocol = 'https:';\n if (protocol === 'ws:') protocol = 'http:';\n return `${protocol}//${url.host}`;\n}\n\nfunction mergedHeaders(\n options: ProvisionOptions,\n defaults: Record<string, string>\n): Record<string, string> {\n const headers = { ...defaults };\n const extra = options.headers;\n if (extra === undefined) return headers;\n for (const [key, value] of Object.entries(extra)) {\n if (value === null) delete headers[key];\n else headers[key] = value;\n }\n return headers;\n}\n\nfunction apiKey(options: ProvisionOptions): string {\n const key = options.apiKey;\n if (typeof key === 'string' && key.length > 0) return key;\n throw new VoiceRequestError('error', 'missing realtime credential');\n}\n\nfunction timeoutSeconds(timeoutMs: number | undefined): number {\n if (timeoutMs === undefined) return 20;\n return Math.min(120, Math.max(1, Math.round(timeoutMs / 1000)));\n}\n\nfunction clientTool(tool: Tool, timeoutMs: number | undefined): JsonObject {\n return {\n type: 'client',\n name: tool.name,\n description: tool.description,\n expects_response: true,\n response_timeout_secs: timeoutSeconds(timeoutMs),\n parameters: tool.parameters as unknown as JsonObject,\n };\n}\n\nfunction customLlmFields(llm: CustomLlm): JsonObject {\n return elevenLabsCustomLlm(llm);\n}\n\nfunction promptFields(spec: HostedAgentSpec): JsonObject {\n const llm = typeof spec.llm === 'string' ? { llm: spec.llm } : customLlmFields(spec.llm);\n return {\n prompt: spec.instructions,\n tools: spec.tools.map((tool) => clientTool(tool, spec.clientToolTimeoutMs)),\n ...llm,\n };\n}\n\nexport function agentBody(spec: HostedAgentSpec): JsonObject {\n const agent: JsonObject = { prompt: promptFields(spec) };\n if (spec.firstMessage !== undefined) agent.first_message = spec.firstMessage;\n return {\n name: spec.name,\n conversation_config: {\n agent,\n tts: { voice_id: spec.voice },\n conversation: { client_events: clientEvents },\n },\n platform_settings: {\n overrides: {\n conversation_config_override: {\n agent: { prompt: { prompt: true }, first_message: true },\n tts: { voice_id: true },\n },\n custom_llm_extra_body: true,\n },\n },\n };\n}\n\nasync function requestJson(\n fetchImpl: typeof fetch,\n url: string,\n init: RequestInit\n): Promise<Record<string, unknown>> {\n let response: Response;\n try {\n response = await fetchImpl(url, init);\n } catch (error) {\n throw asVoice(error);\n }\n if (!response.ok) {\n throw new VoiceRequestError('error', `agent request failed (${response.status})`);\n }\n let json: unknown;\n try {\n json = await response.json();\n } catch (error) {\n throw asVoice(error);\n }\n if (!isRecord(json)) throw new VoiceRequestError('error', 'agent response was not an object');\n return json;\n}\n\nfunction agentIdFrom(json: Record<string, unknown>, fallback: string | undefined): string {\n const id = json.agent_id;\n if (typeof id === 'string' && id.length > 0) return id;\n if (fallback !== undefined) return fallback;\n throw new VoiceRequestError('error', 'agent response had no agent_id');\n}\n\nexport async function provisionAgent(\n model: RealtimeModel<string>,\n spec: HostedAgentSpec,\n options: ProvisionOptions = {}\n): Promise<HostedAgent> {\n if (options.signal?.aborted === true) throw new VoiceRequestError('aborted', 'session aborted');\n const cache = options.cache ?? defaultCache;\n const now = options.now ?? Date.now;\n const key = hostedCacheKey(model.provider, spec.name);\n const hash = hashHostedSpec(spec);\n const cached = cache.get(key);\n if (cached !== undefined && cached.specHash === hash) return cached;\n const existing = cached?.agentId ?? options.agentId;\n const origin = httpsOrigin(model.baseUrl);\n const url =\n existing === undefined\n ? `${origin}/v1/convai/agents/create`\n : `${origin}/v1/convai/agents/${encodeURIComponent(existing)}`;\n const headers = mergedHeaders(options, {\n 'Content-Type': 'application/json',\n 'xi-api-key': apiKey(options),\n });\n const fetchImpl = options.fetch ?? globalThis.fetch;\n const json = await requestJson(fetchImpl, url, {\n method: existing === undefined ? 'POST' : 'PATCH',\n headers,\n body: JSON.stringify(agentBody(spec)),\n signal: options.signal,\n });\n const agent: HostedAgent = {\n agentId: agentIdFrom(json, existing),\n specHash: hash,\n publishedAt: now(),\n };\n cache.set(key, agent);\n return agent;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -40,12 +40,14 @@ function registerFishAgents(options = {}) {
|
|
|
40
40
|
unregisterApi();
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
|
+
import { fishCustomLlm } from "../custom-llm.js";
|
|
43
44
|
import { hashHostedSpec, memoryHostedCache } from "../hosted-agent.js";
|
|
44
45
|
import { agentConfig, httpsOrigin, provisionAgent } from "./provision.js";
|
|
45
46
|
import { importFishSdk, openFishRoom } from "./room.js";
|
|
46
47
|
export {
|
|
47
48
|
agentConfig,
|
|
48
49
|
fishAgent,
|
|
50
|
+
fishCustomLlm,
|
|
49
51
|
hashHostedSpec,
|
|
50
52
|
httpsOrigin,
|
|
51
53
|
importFishSdk,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/fish-agents/index.ts"],
|
|
4
|
-
"sourcesContent": ["import type { RealtimeModel } from '../models.ts';\nimport { registerVoiceModel } from '../models.ts';\nimport { registerRealtimeApiProvider } from '../registry.ts';\nimport type { FishOptions } from './session.ts';\nimport { connectFish } from './session.ts';\n\nconst voices = [{ id: '802e3bc2b27e49c2995d23ef70e6ac89', name: 'Example' }];\n\nfunction pcm16(sampleRate: number) {\n return { encoding: 'pcm16' as const, sampleRate, channels: 1 as const };\n}\n\nexport const fishAgent: RealtimeModel<'fish-agents'> = {\n id: 'fish-agent',\n name: 'Fish Agent',\n api: 'fish-agents',\n provider: 'fish',\n baseUrl: 'https://api.fish.audio',\n type: 'realtime',\n transports: ['webrtc'],\n toolCalls: 'blocking',\n inputFormat: pcm16(24000),\n outputFormat: pcm16(24000),\n maxSessionMs: 1_800_000,\n resumable: false,\n ephemeralAuth: true,\n voices,\n cascade: { stt: 'deepgram:nova-3', llm: 'fish', tts: 's2.1-pro' },\n provisioning: 'agent',\n delivery: { interrupt: 'native', when_idle: 'approximate', silent: 'approximate' },\n truncation: 'server',\n liveToolUpdate: false,\n toolTimeoutMs: { min: 1000, max: 120_000 },\n cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n audioCost: { perInputMinute: 0 },\n};\n\nexport function registerFishAgents(options: FishOptions = {}): () => void {\n const unregisterModel = registerVoiceModel(fishAgent);\n const unregisterApi = registerRealtimeApiProvider({\n api: 'fish-agents',\n connect: (model, context, connectOptions) =>\n connectFish(model, context, connectOptions, options),\n });\n return () => {\n unregisterModel();\n unregisterApi();\n };\n}\n\nexport type { CustomLlm, HostedAgent, HostedAgentSpec, HostedCache } from '../hosted-agent.ts';\nexport { hashHostedSpec, memoryHostedCache } from '../hosted-agent.ts';\nexport type { ProvisionOptions } from './provision.ts';\nexport { agentConfig, httpsOrigin, provisionAgent } from './provision.ts';\nexport type { FishRoom, FishRoomFactory, FishSdk } from './room.ts';\nexport { importFishSdk, openFishRoom } from './room.ts';\nexport type { FishOptions } from './session.ts';\n"],
|
|
5
|
-
"mappings": "AACA,SAAS,0BAA0B;AACnC,SAAS,mCAAmC;AAE5C,SAAS,mBAAmB;AAE5B,MAAM,SAAS,CAAC,EAAE,IAAI,oCAAoC,MAAM,UAAU,CAAC;AAE3E,SAAS,MAAM,YAAoB;AACjC,SAAO,EAAE,UAAU,SAAkB,YAAY,UAAU,EAAW;AACxE;AAEO,MAAM,YAA0C;AAAA,EACrD,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,KAAK;AAAA,EACL,UAAU;AAAA,EACV,SAAS;AAAA,EACT,MAAM;AAAA,EACN,YAAY,CAAC,QAAQ;AAAA,EACrB,WAAW;AAAA,EACX,aAAa,MAAM,IAAK;AAAA,EACxB,cAAc,MAAM,IAAK;AAAA,EACzB,cAAc;AAAA,EACd,WAAW;AAAA,EACX,eAAe;AAAA,EACf;AAAA,EACA,SAAS,EAAE,KAAK,mBAAmB,KAAK,QAAQ,KAAK,WAAW;AAAA,EAChE,cAAc;AAAA,EACd,UAAU,EAAE,WAAW,UAAU,WAAW,eAAe,QAAQ,cAAc;AAAA,EACjF,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,eAAe,EAAE,KAAK,KAAM,KAAK,KAAQ;AAAA,EACzC,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,WAAW,GAAG,YAAY,EAAE;AAAA,EACzD,WAAW,EAAE,gBAAgB,EAAE;AACjC;AAEO,SAAS,mBAAmB,UAAuB,CAAC,GAAe;AACxE,QAAM,kBAAkB,mBAAmB,SAAS;AACpD,QAAM,gBAAgB,4BAA4B;AAAA,IAChD,KAAK;AAAA,IACL,SAAS,CAAC,OAAO,SAAS,mBACxB,YAAY,OAAO,SAAS,gBAAgB,OAAO;AAAA,EACvD,CAAC;AACD,SAAO,MAAM;AACX,oBAAgB;AAChB,kBAAc;AAAA,EAChB;AACF;
|
|
4
|
+
"sourcesContent": ["import type { RealtimeModel } from '../models.ts';\nimport { registerVoiceModel } from '../models.ts';\nimport { registerRealtimeApiProvider } from '../registry.ts';\nimport type { FishOptions } from './session.ts';\nimport { connectFish } from './session.ts';\n\nconst voices = [{ id: '802e3bc2b27e49c2995d23ef70e6ac89', name: 'Example' }];\n\nfunction pcm16(sampleRate: number) {\n return { encoding: 'pcm16' as const, sampleRate, channels: 1 as const };\n}\n\nexport const fishAgent: RealtimeModel<'fish-agents'> = {\n id: 'fish-agent',\n name: 'Fish Agent',\n api: 'fish-agents',\n provider: 'fish',\n baseUrl: 'https://api.fish.audio',\n type: 'realtime',\n transports: ['webrtc'],\n toolCalls: 'blocking',\n inputFormat: pcm16(24000),\n outputFormat: pcm16(24000),\n maxSessionMs: 1_800_000,\n resumable: false,\n ephemeralAuth: true,\n voices,\n cascade: { stt: 'deepgram:nova-3', llm: 'fish', tts: 's2.1-pro' },\n provisioning: 'agent',\n delivery: { interrupt: 'native', when_idle: 'approximate', silent: 'approximate' },\n truncation: 'server',\n liveToolUpdate: false,\n toolTimeoutMs: { min: 1000, max: 120_000 },\n cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n audioCost: { perInputMinute: 0 },\n};\n\nexport function registerFishAgents(options: FishOptions = {}): () => void {\n const unregisterModel = registerVoiceModel(fishAgent);\n const unregisterApi = registerRealtimeApiProvider({\n api: 'fish-agents',\n connect: (model, context, connectOptions) =>\n connectFish(model, context, connectOptions, options),\n });\n return () => {\n unregisterModel();\n unregisterApi();\n };\n}\n\nexport { fishCustomLlm } from '../custom-llm.ts';\nexport type { CustomLlm, HostedAgent, HostedAgentSpec, HostedCache } from '../hosted-agent.ts';\nexport { hashHostedSpec, memoryHostedCache } from '../hosted-agent.ts';\nexport type { ProvisionOptions } from './provision.ts';\nexport { agentConfig, httpsOrigin, provisionAgent } from './provision.ts';\nexport type { FishRoom, FishRoomFactory, FishSdk } from './room.ts';\nexport { importFishSdk, openFishRoom } from './room.ts';\nexport type { FishOptions } from './session.ts';\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,0BAA0B;AACnC,SAAS,mCAAmC;AAE5C,SAAS,mBAAmB;AAE5B,MAAM,SAAS,CAAC,EAAE,IAAI,oCAAoC,MAAM,UAAU,CAAC;AAE3E,SAAS,MAAM,YAAoB;AACjC,SAAO,EAAE,UAAU,SAAkB,YAAY,UAAU,EAAW;AACxE;AAEO,MAAM,YAA0C;AAAA,EACrD,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,KAAK;AAAA,EACL,UAAU;AAAA,EACV,SAAS;AAAA,EACT,MAAM;AAAA,EACN,YAAY,CAAC,QAAQ;AAAA,EACrB,WAAW;AAAA,EACX,aAAa,MAAM,IAAK;AAAA,EACxB,cAAc,MAAM,IAAK;AAAA,EACzB,cAAc;AAAA,EACd,WAAW;AAAA,EACX,eAAe;AAAA,EACf;AAAA,EACA,SAAS,EAAE,KAAK,mBAAmB,KAAK,QAAQ,KAAK,WAAW;AAAA,EAChE,cAAc;AAAA,EACd,UAAU,EAAE,WAAW,UAAU,WAAW,eAAe,QAAQ,cAAc;AAAA,EACjF,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,eAAe,EAAE,KAAK,KAAM,KAAK,KAAQ;AAAA,EACzC,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,WAAW,GAAG,YAAY,EAAE;AAAA,EACzD,WAAW,EAAE,gBAAgB,EAAE;AACjC;AAEO,SAAS,mBAAmB,UAAuB,CAAC,GAAe;AACxE,QAAM,kBAAkB,mBAAmB,SAAS;AACpD,QAAM,gBAAgB,4BAA4B;AAAA,IAChD,KAAK;AAAA,IACL,SAAS,CAAC,OAAO,SAAS,mBACxB,YAAY,OAAO,SAAS,gBAAgB,OAAO;AAAA,EACvD,CAAC;AACD,SAAO,MAAM;AACX,oBAAgB;AAChB,kBAAc;AAAA,EAChB;AACF;AAEA,SAAS,qBAAqB;AAE9B,SAAS,gBAAgB,yBAAyB;AAElD,SAAS,aAAa,aAAa,sBAAsB;AAEzD,SAAS,eAAe,oBAAoB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { fishCustomLlm } from "../custom-llm.js";
|
|
1
2
|
import { VoiceRequestError } from "../errors.js";
|
|
2
3
|
import {
|
|
3
4
|
hashHostedSpec,
|
|
@@ -66,22 +67,9 @@ function clientTool(tool, timeoutMs) {
|
|
|
66
67
|
timeout_seconds: timeoutSeconds(timeoutMs)
|
|
67
68
|
};
|
|
68
69
|
}
|
|
69
|
-
function bearer(headers) {
|
|
70
|
-
if (headers === void 0) return void 0;
|
|
71
|
-
const value = headers.Authorization ?? headers.authorization;
|
|
72
|
-
if (typeof value !== "string" || value.length === 0) return void 0;
|
|
73
|
-
if (value.startsWith("Bearer ")) return value.slice("Bearer ".length);
|
|
74
|
-
return value;
|
|
75
|
-
}
|
|
76
70
|
function llmFields(llm) {
|
|
77
71
|
if (typeof llm === "string") return { model: llm };
|
|
78
|
-
|
|
79
|
-
throw new VoiceRequestError("error", "fish custom llm accepts openai-completions only");
|
|
80
|
-
}
|
|
81
|
-
const custom = { base_url: llm.baseUrl, model: llm.id };
|
|
82
|
-
const key = bearer(llm.headers);
|
|
83
|
-
if (key !== void 0) custom.api_key = key;
|
|
84
|
-
return { custom };
|
|
72
|
+
return fishCustomLlm(llm);
|
|
85
73
|
}
|
|
86
74
|
function agentConfig(spec, toolIds) {
|
|
87
75
|
const prompt = { system_prompt: spec.instructions };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/fish-agents/provision.ts"],
|
|
4
|
-
"sourcesContent": ["import type { JsonObject, ProviderRequestOptions, Tool } from '@earendil-works/pi-ai';\nimport { VoiceRequestError } from '../errors.ts';\nimport {\n type CustomLlm,\n type HostedAgent,\n type HostedAgentSpec,\n type HostedCache,\n hashHostedSpec,\n hostedCacheKey,\n memoryHostedCache,\n} from '../hosted-agent.ts';\nimport type { RealtimeModel } from '../models.ts';\n\nexport interface ProvisionOptions extends ProviderRequestOptions {\n agentId?: string;\n now?: () => number;\n cache?: HostedCache;\n}\n\nconst defaultCache = memoryHostedCache();\nconst toolName = /^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction asVoice(error: unknown): VoiceRequestError {\n if (error instanceof VoiceRequestError) return error;\n if (error instanceof Error && error.name === 'AbortError') {\n return new VoiceRequestError('aborted', 'session aborted');\n }\n if (error instanceof Error) return new VoiceRequestError('error', error.message);\n return new VoiceRequestError('error', String(error));\n}\n\nexport function httpsOrigin(baseUrl: string): string {\n const url = new URL(baseUrl);\n let protocol = url.protocol;\n if (protocol === 'wss:') protocol = 'https:';\n if (protocol === 'ws:') protocol = 'http:';\n return `${protocol}//${url.host}`;\n}\n\nfunction mergedHeaders(\n options: ProvisionOptions,\n defaults: Record<string, string>\n): Record<string, string> {\n const headers = { ...defaults };\n const extra = options.headers;\n if (extra === undefined) return headers;\n for (const [key, value] of Object.entries(extra)) {\n if (value === null) delete headers[key];\n else headers[key] = value;\n }\n return headers;\n}\n\nfunction apiKey(options: ProvisionOptions): string {\n const key = options.apiKey;\n if (typeof key === 'string' && key.length > 0) return key;\n throw new VoiceRequestError('error', 'missing realtime credential');\n}\n\nfunction timeoutSeconds(timeoutMs: number | undefined): number {\n if (timeoutMs === undefined) return 30;\n return Math.min(120, Math.max(1, Math.round(timeoutMs / 1000)));\n}\n\nfunction argumentsOf(tool: Tool): JsonObject[] {\n const parameters = tool.parameters as unknown;\n if (!isRecord(parameters) || !isRecord(parameters.properties)) return [];\n const args: JsonObject[] = [];\n for (const [name, schema] of Object.entries(parameters.properties)) {\n const description =\n isRecord(schema) && typeof schema.description === 'string' ? schema.description : '';\n args.push({ name, description });\n }\n return args;\n}\n\nfunction clientTool(tool: Tool, timeoutMs: number | undefined): JsonObject {\n if (!toolName.test(tool.name)) {\n throw new VoiceRequestError('error', `invalid client tool name: ${tool.name}`);\n }\n return {\n tool_type: 'client',\n name: tool.name,\n description: tool.description,\n arguments: argumentsOf(tool),\n expects_response: true,\n timeout_seconds: timeoutSeconds(timeoutMs),\n };\n}\n\nfunction
|
|
5
|
-
"mappings": "AACA,SAAS,yBAAyB;AAClC;AAAA,EAKE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AASP,MAAM,eAAe,kBAAkB;AACvC,MAAM,WAAW;AAEjB,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,QAAQ,OAAmC;AAClD,MAAI,iBAAiB,kBAAmB,QAAO;AAC/C,MAAI,iBAAiB,SAAS,MAAM,SAAS,cAAc;AACzD,WAAO,IAAI,kBAAkB,WAAW,iBAAiB;AAAA,EAC3D;AACA,MAAI,iBAAiB,MAAO,QAAO,IAAI,kBAAkB,SAAS,MAAM,OAAO;AAC/E,SAAO,IAAI,kBAAkB,SAAS,OAAO,KAAK,CAAC;AACrD;AAEO,SAAS,YAAY,SAAyB;AACnD,QAAM,MAAM,IAAI,IAAI,OAAO;AAC3B,MAAI,WAAW,IAAI;AACnB,MAAI,aAAa,OAAQ,YAAW;AACpC,MAAI,aAAa,MAAO,YAAW;AACnC,SAAO,GAAG,QAAQ,KAAK,IAAI,IAAI;AACjC;AAEA,SAAS,cACP,SACA,UACwB;AACxB,QAAM,UAAU,EAAE,GAAG,SAAS;AAC9B,QAAM,QAAQ,QAAQ;AACtB,MAAI,UAAU,OAAW,QAAO;AAChC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,UAAU,KAAM,QAAO,QAAQ,GAAG;AAAA,QACjC,SAAQ,GAAG,IAAI;AAAA,EACtB;AACA,SAAO;AACT;AAEA,SAAS,OAAO,SAAmC;AACjD,QAAM,MAAM,QAAQ;AACpB,MAAI,OAAO,QAAQ,YAAY,IAAI,SAAS,EAAG,QAAO;AACtD,QAAM,IAAI,kBAAkB,SAAS,6BAA6B;AACpE;AAEA,SAAS,eAAe,WAAuC;AAC7D,MAAI,cAAc,OAAW,QAAO;AACpC,SAAO,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,YAAY,GAAI,CAAC,CAAC;AAChE;AAEA,SAAS,YAAY,MAA0B;AAC7C,QAAM,aAAa,KAAK;AACxB,MAAI,CAAC,SAAS,UAAU,KAAK,CAAC,SAAS,WAAW,UAAU,EAAG,QAAO,CAAC;AACvE,QAAM,OAAqB,CAAC;AAC5B,aAAW,CAAC,MAAM,MAAM,KAAK,OAAO,QAAQ,WAAW,UAAU,GAAG;AAClE,UAAM,cACJ,SAAS,MAAM,KAAK,OAAO,OAAO,gBAAgB,WAAW,OAAO,cAAc;AACpF,SAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAAA,EACjC;AACA,SAAO;AACT;AAEA,SAAS,WAAW,MAAY,WAA2C;AACzE,MAAI,CAAC,SAAS,KAAK,KAAK,IAAI,GAAG;AAC7B,UAAM,IAAI,kBAAkB,SAAS,6BAA6B,KAAK,IAAI,EAAE;AAAA,EAC/E;AACA,SAAO;AAAA,IACL,WAAW;AAAA,IACX,MAAM,KAAK;AAAA,IACX,aAAa,KAAK;AAAA,IAClB,WAAW,YAAY,IAAI;AAAA,IAC3B,kBAAkB;AAAA,IAClB,iBAAiB,eAAe,SAAS;AAAA,EAC3C;AACF;AAEA,SAAS,
|
|
4
|
+
"sourcesContent": ["import type { JsonObject, ProviderRequestOptions, Tool } from '@earendil-works/pi-ai';\nimport { fishCustomLlm } from '../custom-llm.ts';\nimport { VoiceRequestError } from '../errors.ts';\nimport {\n type CustomLlm,\n type HostedAgent,\n type HostedAgentSpec,\n type HostedCache,\n hashHostedSpec,\n hostedCacheKey,\n memoryHostedCache,\n} from '../hosted-agent.ts';\nimport type { RealtimeModel } from '../models.ts';\n\nexport interface ProvisionOptions extends ProviderRequestOptions {\n agentId?: string;\n now?: () => number;\n cache?: HostedCache;\n}\n\nconst defaultCache = memoryHostedCache();\nconst toolName = /^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction asVoice(error: unknown): VoiceRequestError {\n if (error instanceof VoiceRequestError) return error;\n if (error instanceof Error && error.name === 'AbortError') {\n return new VoiceRequestError('aborted', 'session aborted');\n }\n if (error instanceof Error) return new VoiceRequestError('error', error.message);\n return new VoiceRequestError('error', String(error));\n}\n\nexport function httpsOrigin(baseUrl: string): string {\n const url = new URL(baseUrl);\n let protocol = url.protocol;\n if (protocol === 'wss:') protocol = 'https:';\n if (protocol === 'ws:') protocol = 'http:';\n return `${protocol}//${url.host}`;\n}\n\nfunction mergedHeaders(\n options: ProvisionOptions,\n defaults: Record<string, string>\n): Record<string, string> {\n const headers = { ...defaults };\n const extra = options.headers;\n if (extra === undefined) return headers;\n for (const [key, value] of Object.entries(extra)) {\n if (value === null) delete headers[key];\n else headers[key] = value;\n }\n return headers;\n}\n\nfunction apiKey(options: ProvisionOptions): string {\n const key = options.apiKey;\n if (typeof key === 'string' && key.length > 0) return key;\n throw new VoiceRequestError('error', 'missing realtime credential');\n}\n\nfunction timeoutSeconds(timeoutMs: number | undefined): number {\n if (timeoutMs === undefined) return 30;\n return Math.min(120, Math.max(1, Math.round(timeoutMs / 1000)));\n}\n\nfunction argumentsOf(tool: Tool): JsonObject[] {\n const parameters = tool.parameters as unknown;\n if (!isRecord(parameters) || !isRecord(parameters.properties)) return [];\n const args: JsonObject[] = [];\n for (const [name, schema] of Object.entries(parameters.properties)) {\n const description =\n isRecord(schema) && typeof schema.description === 'string' ? schema.description : '';\n args.push({ name, description });\n }\n return args;\n}\n\nfunction clientTool(tool: Tool, timeoutMs: number | undefined): JsonObject {\n if (!toolName.test(tool.name)) {\n throw new VoiceRequestError('error', `invalid client tool name: ${tool.name}`);\n }\n return {\n tool_type: 'client',\n name: tool.name,\n description: tool.description,\n arguments: argumentsOf(tool),\n expects_response: true,\n timeout_seconds: timeoutSeconds(timeoutMs),\n };\n}\n\nfunction llmFields(llm: string | CustomLlm): JsonObject {\n if (typeof llm === 'string') return { model: llm };\n return fishCustomLlm(llm);\n}\n\nexport function agentConfig(spec: HostedAgentSpec, toolIds: string[]): JsonObject {\n const prompt: JsonObject = { system_prompt: spec.instructions };\n if (spec.firstMessage !== undefined) prompt.first_message = spec.firstMessage;\n const config: JsonObject = {\n prompt,\n voice: { voice_id: spec.voice },\n llm: llmFields(spec.llm),\n };\n if (toolIds.length > 0) config.tools = { enabled: true, tool_ids: toolIds };\n return config;\n}\n\nasync function requestJson(\n fetchImpl: typeof fetch,\n url: string,\n init: RequestInit\n): Promise<Record<string, unknown>> {\n let response: Response;\n try {\n response = await fetchImpl(url, init);\n } catch (error) {\n throw asVoice(error);\n }\n if (!response.ok) {\n throw new VoiceRequestError('error', `agent request failed (${response.status})`);\n }\n if (response.status === 204) return {};\n let json: unknown;\n try {\n json = await response.json();\n } catch (error) {\n throw asVoice(error);\n }\n if (!isRecord(json)) throw new VoiceRequestError('error', 'agent response was not an object');\n return json;\n}\n\nfunction textId(\n json: Record<string, unknown>,\n field: string,\n fallback: string | undefined\n): string {\n const id = json[field];\n if (typeof id === 'string' && id.length > 0) return id;\n if (fallback !== undefined) return fallback;\n throw new VoiceRequestError('error', `agent response had no ${field}`);\n}\n\nasync function createTools(\n origin: string,\n spec: HostedAgentSpec,\n options: ProvisionOptions,\n fetchImpl: typeof fetch\n): Promise<string[]> {\n const ids: string[] = [];\n for (const tool of spec.tools) {\n const json = await requestJson(fetchImpl, `${origin}/v1/agent/tools`, {\n method: 'POST',\n headers: mergedHeaders(options, {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey(options)}`,\n }),\n body: JSON.stringify(clientTool(tool, spec.clientToolTimeoutMs)),\n signal: options.signal,\n });\n ids.push(textId(json, 'tool_id', undefined));\n }\n return ids;\n}\n\nexport async function provisionAgent(\n model: RealtimeModel<string>,\n spec: HostedAgentSpec,\n options: ProvisionOptions = {}\n): Promise<HostedAgent> {\n if (options.signal?.aborted === true) throw new VoiceRequestError('aborted', 'session aborted');\n const cache = options.cache ?? defaultCache;\n const now = options.now ?? Date.now;\n const key = hostedCacheKey(model.provider, spec.name);\n const hash = hashHostedSpec(spec);\n const cached = cache.get(key);\n if (cached !== undefined && cached.specHash === hash) return cached;\n const origin = httpsOrigin(model.baseUrl);\n const fetchImpl = options.fetch ?? globalThis.fetch;\n const toolIds = await createTools(origin, spec, options, fetchImpl);\n const config = agentConfig(spec, toolIds);\n const existing = cached?.agentId ?? options.agentId;\n const headers = mergedHeaders(options, {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey(options)}`,\n });\n const url =\n existing === undefined\n ? `${origin}/v1/agent/agents`\n : `${origin}/v1/agent/agents/${encodeURIComponent(existing)}/config`;\n const json = await requestJson(fetchImpl, url, {\n method: existing === undefined ? 'POST' : 'PATCH',\n headers,\n body: JSON.stringify(existing === undefined ? { name: spec.name, config } : config),\n signal: options.signal,\n });\n const agentId = textId(json, 'agent_id', existing);\n await requestJson(fetchImpl, `${origin}/v1/agent/agents/${encodeURIComponent(agentId)}/publish`, {\n method: 'POST',\n headers: mergedHeaders(options, { Authorization: `Bearer ${apiKey(options)}` }),\n signal: options.signal,\n });\n const agent: HostedAgent = { agentId, specHash: hash, publishedAt: now() };\n cache.set(key, agent);\n return agent;\n}\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB;AAClC;AAAA,EAKE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AASP,MAAM,eAAe,kBAAkB;AACvC,MAAM,WAAW;AAEjB,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,QAAQ,OAAmC;AAClD,MAAI,iBAAiB,kBAAmB,QAAO;AAC/C,MAAI,iBAAiB,SAAS,MAAM,SAAS,cAAc;AACzD,WAAO,IAAI,kBAAkB,WAAW,iBAAiB;AAAA,EAC3D;AACA,MAAI,iBAAiB,MAAO,QAAO,IAAI,kBAAkB,SAAS,MAAM,OAAO;AAC/E,SAAO,IAAI,kBAAkB,SAAS,OAAO,KAAK,CAAC;AACrD;AAEO,SAAS,YAAY,SAAyB;AACnD,QAAM,MAAM,IAAI,IAAI,OAAO;AAC3B,MAAI,WAAW,IAAI;AACnB,MAAI,aAAa,OAAQ,YAAW;AACpC,MAAI,aAAa,MAAO,YAAW;AACnC,SAAO,GAAG,QAAQ,KAAK,IAAI,IAAI;AACjC;AAEA,SAAS,cACP,SACA,UACwB;AACxB,QAAM,UAAU,EAAE,GAAG,SAAS;AAC9B,QAAM,QAAQ,QAAQ;AACtB,MAAI,UAAU,OAAW,QAAO;AAChC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,UAAU,KAAM,QAAO,QAAQ,GAAG;AAAA,QACjC,SAAQ,GAAG,IAAI;AAAA,EACtB;AACA,SAAO;AACT;AAEA,SAAS,OAAO,SAAmC;AACjD,QAAM,MAAM,QAAQ;AACpB,MAAI,OAAO,QAAQ,YAAY,IAAI,SAAS,EAAG,QAAO;AACtD,QAAM,IAAI,kBAAkB,SAAS,6BAA6B;AACpE;AAEA,SAAS,eAAe,WAAuC;AAC7D,MAAI,cAAc,OAAW,QAAO;AACpC,SAAO,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,YAAY,GAAI,CAAC,CAAC;AAChE;AAEA,SAAS,YAAY,MAA0B;AAC7C,QAAM,aAAa,KAAK;AACxB,MAAI,CAAC,SAAS,UAAU,KAAK,CAAC,SAAS,WAAW,UAAU,EAAG,QAAO,CAAC;AACvE,QAAM,OAAqB,CAAC;AAC5B,aAAW,CAAC,MAAM,MAAM,KAAK,OAAO,QAAQ,WAAW,UAAU,GAAG;AAClE,UAAM,cACJ,SAAS,MAAM,KAAK,OAAO,OAAO,gBAAgB,WAAW,OAAO,cAAc;AACpF,SAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAAA,EACjC;AACA,SAAO;AACT;AAEA,SAAS,WAAW,MAAY,WAA2C;AACzE,MAAI,CAAC,SAAS,KAAK,KAAK,IAAI,GAAG;AAC7B,UAAM,IAAI,kBAAkB,SAAS,6BAA6B,KAAK,IAAI,EAAE;AAAA,EAC/E;AACA,SAAO;AAAA,IACL,WAAW;AAAA,IACX,MAAM,KAAK;AAAA,IACX,aAAa,KAAK;AAAA,IAClB,WAAW,YAAY,IAAI;AAAA,IAC3B,kBAAkB;AAAA,IAClB,iBAAiB,eAAe,SAAS;AAAA,EAC3C;AACF;AAEA,SAAS,UAAU,KAAqC;AACtD,MAAI,OAAO,QAAQ,SAAU,QAAO,EAAE,OAAO,IAAI;AACjD,SAAO,cAAc,GAAG;AAC1B;AAEO,SAAS,YAAY,MAAuB,SAA+B;AAChF,QAAM,SAAqB,EAAE,eAAe,KAAK,aAAa;AAC9D,MAAI,KAAK,iBAAiB,OAAW,QAAO,gBAAgB,KAAK;AACjE,QAAM,SAAqB;AAAA,IACzB;AAAA,IACA,OAAO,EAAE,UAAU,KAAK,MAAM;AAAA,IAC9B,KAAK,UAAU,KAAK,GAAG;AAAA,EACzB;AACA,MAAI,QAAQ,SAAS,EAAG,QAAO,QAAQ,EAAE,SAAS,MAAM,UAAU,QAAQ;AAC1E,SAAO;AACT;AAEA,eAAe,YACb,WACA,KACA,MACkC;AAClC,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,UAAU,KAAK,IAAI;AAAA,EACtC,SAAS,OAAO;AACd,UAAM,QAAQ,KAAK;AAAA,EACrB;AACA,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,kBAAkB,SAAS,yBAAyB,SAAS,MAAM,GAAG;AAAA,EAClF;AACA,MAAI,SAAS,WAAW,IAAK,QAAO,CAAC;AACrC,MAAI;AACJ,MAAI;AACF,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B,SAAS,OAAO;AACd,UAAM,QAAQ,KAAK;AAAA,EACrB;AACA,MAAI,CAAC,SAAS,IAAI,EAAG,OAAM,IAAI,kBAAkB,SAAS,kCAAkC;AAC5F,SAAO;AACT;AAEA,SAAS,OACP,MACA,OACA,UACQ;AACR,QAAM,KAAK,KAAK,KAAK;AACrB,MAAI,OAAO,OAAO,YAAY,GAAG,SAAS,EAAG,QAAO;AACpD,MAAI,aAAa,OAAW,QAAO;AACnC,QAAM,IAAI,kBAAkB,SAAS,yBAAyB,KAAK,EAAE;AACvE;AAEA,eAAe,YACb,QACA,MACA,SACA,WACmB;AACnB,QAAM,MAAgB,CAAC;AACvB,aAAW,QAAQ,KAAK,OAAO;AAC7B,UAAM,OAAO,MAAM,YAAY,WAAW,GAAG,MAAM,mBAAmB;AAAA,MACpE,QAAQ;AAAA,MACR,SAAS,cAAc,SAAS;AAAA,QAC9B,gBAAgB;AAAA,QAChB,eAAe,UAAU,OAAO,OAAO,CAAC;AAAA,MAC1C,CAAC;AAAA,MACD,MAAM,KAAK,UAAU,WAAW,MAAM,KAAK,mBAAmB,CAAC;AAAA,MAC/D,QAAQ,QAAQ;AAAA,IAClB,CAAC;AACD,QAAI,KAAK,OAAO,MAAM,WAAW,MAAS,CAAC;AAAA,EAC7C;AACA,SAAO;AACT;AAEA,eAAsB,eACpB,OACA,MACA,UAA4B,CAAC,GACP;AACtB,MAAI,QAAQ,QAAQ,YAAY,KAAM,OAAM,IAAI,kBAAkB,WAAW,iBAAiB;AAC9F,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,MAAM,QAAQ,OAAO,KAAK;AAChC,QAAM,MAAM,eAAe,MAAM,UAAU,KAAK,IAAI;AACpD,QAAM,OAAO,eAAe,IAAI;AAChC,QAAM,SAAS,MAAM,IAAI,GAAG;AAC5B,MAAI,WAAW,UAAa,OAAO,aAAa,KAAM,QAAO;AAC7D,QAAM,SAAS,YAAY,MAAM,OAAO;AACxC,QAAM,YAAY,QAAQ,SAAS,WAAW;AAC9C,QAAM,UAAU,MAAM,YAAY,QAAQ,MAAM,SAAS,SAAS;AAClE,QAAM,SAAS,YAAY,MAAM,OAAO;AACxC,QAAM,WAAW,QAAQ,WAAW,QAAQ;AAC5C,QAAM,UAAU,cAAc,SAAS;AAAA,IACrC,gBAAgB;AAAA,IAChB,eAAe,UAAU,OAAO,OAAO,CAAC;AAAA,EAC1C,CAAC;AACD,QAAM,MACJ,aAAa,SACT,GAAG,MAAM,qBACT,GAAG,MAAM,oBAAoB,mBAAmB,QAAQ,CAAC;AAC/D,QAAM,OAAO,MAAM,YAAY,WAAW,KAAK;AAAA,IAC7C,QAAQ,aAAa,SAAY,SAAS;AAAA,IAC1C;AAAA,IACA,MAAM,KAAK,UAAU,aAAa,SAAY,EAAE,MAAM,KAAK,MAAM,OAAO,IAAI,MAAM;AAAA,IAClF,QAAQ,QAAQ;AAAA,EAClB,CAAC;AACD,QAAM,UAAU,OAAO,MAAM,YAAY,QAAQ;AACjD,QAAM,YAAY,WAAW,GAAG,MAAM,oBAAoB,mBAAmB,OAAO,CAAC,YAAY;AAAA,IAC/F,QAAQ;AAAA,IACR,SAAS,cAAc,SAAS,EAAE,eAAe,UAAU,OAAO,OAAO,CAAC,GAAG,CAAC;AAAA,IAC9E,QAAQ,QAAQ;AAAA,EAClB,CAAC;AACD,QAAM,QAAqB,EAAE,SAAS,UAAU,MAAM,aAAa,IAAI,EAAE;AACzE,QAAM,IAAI,KAAK,KAAK;AACpB,SAAO;AACT;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -2,6 +2,7 @@ import type { RealtimeModel } from '../models.ts';
|
|
|
2
2
|
import type { ElevenLabsOptions } from './session.ts';
|
|
3
3
|
export declare const elevenLabsAgent: RealtimeModel<'elevenlabs-agents'>;
|
|
4
4
|
export declare function registerElevenLabsAgents(options?: ElevenLabsOptions): () => void;
|
|
5
|
+
export { elevenLabsCustomLlm } from '../custom-llm.ts';
|
|
5
6
|
export type { CustomLlm, HostedAgent, HostedAgentSpec, HostedCache } from '../hosted-agent.ts';
|
|
6
7
|
export { hashHostedSpec, memoryHostedCache } from '../hosted-agent.ts';
|
|
7
8
|
export type { ProvisionOptions } from './provision.ts';
|
|
@@ -2,6 +2,7 @@ import type { RealtimeModel } from '../models.ts';
|
|
|
2
2
|
import type { FishOptions } from './session.ts';
|
|
3
3
|
export declare const fishAgent: RealtimeModel<'fish-agents'>;
|
|
4
4
|
export declare function registerFishAgents(options?: FishOptions): () => void;
|
|
5
|
+
export { fishCustomLlm } from '../custom-llm.ts';
|
|
5
6
|
export type { CustomLlm, HostedAgent, HostedAgentSpec, HostedCache } from '../hosted-agent.ts';
|
|
6
7
|
export { hashHostedSpec, memoryHostedCache } from '../hosted-agent.ts';
|
|
7
8
|
export type { ProvisionOptions } from './provision.ts';
|
package/package.json
CHANGED