@sahab-platform/agents 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -0
- package/dist/_internal-agent.d.mts +5 -0
- package/dist/_internal-agent.d.ts +5 -0
- package/dist/_internal-agent.js +87 -0
- package/dist/_internal-agent.js.map +1 -0
- package/dist/_internal-agent.mjs +64 -0
- package/dist/_internal-agent.mjs.map +1 -0
- package/dist/agent-instructions.d.mts +7 -0
- package/dist/agent-instructions.d.ts +7 -0
- package/dist/agent-instructions.js +17 -0
- package/dist/agent-instructions.js.map +1 -0
- package/dist/agent-instructions.mjs +15 -0
- package/dist/agent-instructions.mjs.map +1 -0
- package/dist/index.d.mts +43 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.js +166 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +141 -0
- package/dist/index.mjs.map +1 -0
- package/dist/store.d.mts +8 -0
- package/dist/store.d.ts +8 -0
- package/dist/store.js +34 -0
- package/dist/store.js.map +1 -0
- package/dist/store.mjs +29 -0
- package/dist/store.mjs.map +1 -0
- package/dist/types-DiUcywed.d.mts +185 -0
- package/dist/types-DiUcywed.d.ts +185 -0
- package/package.json +45 -0
package/README.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# @sahab/agents
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for building voice AI agents powered by the Sahab platform.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @sahab/agents
|
|
9
|
+
# or
|
|
10
|
+
bun add @sahab/agents
|
|
11
|
+
# or
|
|
12
|
+
pnpm add @sahab/agents
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Requirements
|
|
16
|
+
|
|
17
|
+
- Node.js >= 18
|
|
18
|
+
- A Sahab API key
|
|
19
|
+
|
|
20
|
+
## Quick start
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { SahabAgents } from "@sahab/agents";
|
|
24
|
+
|
|
25
|
+
const sahab = new SahabAgents({
|
|
26
|
+
apiKey: process.env.SAHAB_API_KEY!,
|
|
27
|
+
stt: {
|
|
28
|
+
model: "deepgram/nova-3",
|
|
29
|
+
apiKey: "",
|
|
30
|
+
},
|
|
31
|
+
tts: {
|
|
32
|
+
model: "cartesia/sonic",
|
|
33
|
+
apiKey: "",
|
|
34
|
+
},
|
|
35
|
+
llm: {
|
|
36
|
+
model: "openai/gpt-4o",
|
|
37
|
+
apiKey: "",
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
await sahab.agents.initialize();
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## STT models
|
|
47
|
+
|
|
48
|
+
| Provider | Models |
|
|
49
|
+
| ---------- | ---------------------------------------------------------------------------------------- |
|
|
50
|
+
| Deepgram | `deepgram/nova-3`, `deepgram/nova-3-medical`, `deepgram/nova-2`, `deepgram/flux-general` |
|
|
51
|
+
| Cartesia | `cartesia/ink-whisper` |
|
|
52
|
+
| AssemblyAI | `assemblyai/universal-streaming`, `assemblyai/universal-streaming-multilingual` |
|
|
53
|
+
| ElevenLabs | `elevenlabs/scribe_v2_realtime` |
|
|
54
|
+
|
|
55
|
+
Supported languages: `multi`, `en`, `de`, `es`, `fr`, `ja`, `pt`, `zh`, `hi`
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## TTS models
|
|
60
|
+
|
|
61
|
+
| Provider | Models |
|
|
62
|
+
| ---------- | ------------------------------------------------------------------------------------------------- |
|
|
63
|
+
| Cartesia | `cartesia/sonic-3`, `cartesia/sonic-2`, `cartesia/sonic-turbo`, `cartesia/sonic` |
|
|
64
|
+
| Deepgram | `deepgram/aura`, `deepgram/aura-2` |
|
|
65
|
+
| ElevenLabs | `elevenlabs/eleven_flash_v2`, `elevenlabs/eleven_flash_v2_5`, `elevenlabs/eleven_multilingual_v2` |
|
|
66
|
+
| Rime | `rime/arcana`, `rime/mistv2` |
|
|
67
|
+
| Inworld | `inworld/inworld-tts-1.5-max`, `inworld/inworld-tts-1.5-mini`, `inworld/inworld-tts-1-max` |
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## LLM models
|
|
72
|
+
|
|
73
|
+
| Provider | Models |
|
|
74
|
+
| -------- | ---------------------------------------------------------------------------------------------- |
|
|
75
|
+
| OpenAI | `openai/gpt-4o`, `openai/gpt-4o-mini`, `openai/gpt-4.1`, `openai/gpt-4.1-mini`, `openai/gpt-5` |
|
|
76
|
+
| Google | `google/gemini-2.5-pro`, `google/gemini-2.5-flash`, `google/gemini-2.0-flash` |
|
|
77
|
+
| DeepSeek | `deepseek-ai/deepseek-v3`, `deepseek-ai/deepseek-v3.2` |
|
|
78
|
+
| Moonshot | `moonshotai/kimi-k2-instruct` |
|
|
79
|
+
|
|
80
|
+
## License
|
|
81
|
+
|
|
82
|
+
MIT
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var agents = require('@livekit/agents');
|
|
4
|
+
var livekit = require('@livekit/agents-plugin-livekit');
|
|
5
|
+
var silero = require('@livekit/agents-plugin-silero');
|
|
6
|
+
|
|
7
|
+
function _interopNamespace(e) {
|
|
8
|
+
if (e && e.__esModule) return e;
|
|
9
|
+
var n = Object.create(null);
|
|
10
|
+
if (e) {
|
|
11
|
+
Object.keys(e).forEach(function (k) {
|
|
12
|
+
if (k !== 'default') {
|
|
13
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
14
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function () { return e[k]; }
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
n.default = e;
|
|
22
|
+
return Object.freeze(n);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
var livekit__namespace = /*#__PURE__*/_interopNamespace(livekit);
|
|
26
|
+
var silero__namespace = /*#__PURE__*/_interopNamespace(silero);
|
|
27
|
+
|
|
28
|
+
// src/_internal-agent.ts
|
|
29
|
+
var Agent = class extends agents.voice.Agent {
|
|
30
|
+
constructor(metadata) {
|
|
31
|
+
const data = JSON.parse(metadata);
|
|
32
|
+
super({
|
|
33
|
+
instructions: "You are a helpful voice AI assistant. The user is interacting with you via voice, even if you perceive the conversation as text.\n" + data.prompt
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
function getOptions() {
|
|
38
|
+
{
|
|
39
|
+
throw new Error(
|
|
40
|
+
"SahabAgents options have not been set. Call initialize() first."
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// src/_internal-agent.ts
|
|
46
|
+
var options = getOptions();
|
|
47
|
+
var internal_agent_default = agents.defineAgent({
|
|
48
|
+
prewarm: async (proc) => {
|
|
49
|
+
proc.userData.vad = await silero__namespace.VAD.load();
|
|
50
|
+
},
|
|
51
|
+
entry: async (ctx) => {
|
|
52
|
+
const metadata = JSON.parse(ctx.job.metadata);
|
|
53
|
+
const session = new agents.voice.AgentSession({
|
|
54
|
+
stt: new agents.inference.STT(options.stt),
|
|
55
|
+
llm: new agents.inference.LLM(options.llm),
|
|
56
|
+
tts: new agents.inference.TTS({
|
|
57
|
+
model: options.tts.model,
|
|
58
|
+
...options.tts
|
|
59
|
+
}),
|
|
60
|
+
turnDetection: new livekit__namespace.turnDetector.MultilingualModel(),
|
|
61
|
+
vad: ctx.proc.userData.vad,
|
|
62
|
+
voiceOptions: {
|
|
63
|
+
preemptiveGeneration: true
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
const usageCollector = new agents.metrics.UsageCollector();
|
|
67
|
+
session.on(agents.voice.AgentSessionEventTypes.MetricsCollected, (ev) => {
|
|
68
|
+
agents.metrics.logMetrics(ev.metrics);
|
|
69
|
+
usageCollector.collect(ev.metrics);
|
|
70
|
+
});
|
|
71
|
+
const logUsage = async () => {
|
|
72
|
+
const summary = usageCollector.getSummary();
|
|
73
|
+
console.log(`Usage: ${JSON.stringify(summary)}`);
|
|
74
|
+
};
|
|
75
|
+
ctx.addShutdownCallback(logUsage);
|
|
76
|
+
await session.start({
|
|
77
|
+
agent: new Agent(ctx.job.metadata),
|
|
78
|
+
room: ctx.room
|
|
79
|
+
});
|
|
80
|
+
await ctx.connect();
|
|
81
|
+
ctx.room.localParticipant?.updateName(metadata.name);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
module.exports = internal_agent_default;
|
|
86
|
+
//# sourceMappingURL=_internal-agent.js.map
|
|
87
|
+
//# sourceMappingURL=_internal-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/agent-instructions.ts","../src/store.ts","../src/_internal-agent.ts"],"names":["voice","defineAgent","silero","inference","livekit","metrics"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEO,IAAM,KAAA,GAAN,cAAoBA,YAAA,CAAM,KAAA,CAAM;AAAA,EACrC,YAAY,QAAA,EAAkB;AAC5B,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,QAAQ,CAAA;AAChC,IAAA,KAAA,CAAM;AAAA,MACJ,YAAA,EACE,uIAEA,IAAA,CAAK;AAAA,KACR,CAAA;AAAA,EACH;AACF,CAAA;ACHO,SAAS,UAAA,GAAiC;AAC/C,EAAe;AACb,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEF;;;ACGA,IAAM,UAAU,UAAA,EAAW;AAE3B,IAAO,yBAAQC,kBAAA,CAAY;AAAA,EACzB,OAAA,EAAS,OAAO,IAAA,KAAqB;AACnC,IAAA,IAAA,CAAK,QAAA,CAAS,GAAA,GAAM,MAAaC,iBAAA,CAAA,GAAA,CAAI,IAAA,EAAK;AAAA,EAC5C,CAAA;AAAA,EACA,KAAA,EAAO,OAAO,GAAA,KAAoB;AAChC,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,IAAI,QAAQ,CAAA;AAE5C,IAAA,MAAM,OAAA,GAAU,IAAIF,YAAAA,CAAM,YAAA,CAAa;AAAA,MACrC,GAAA,EAAK,IAAIG,gBAAA,CAAU,GAAA,CAAI,QAAQ,GAAG,CAAA;AAAA,MAClC,GAAA,EAAK,IAAIA,gBAAA,CAAU,GAAA,CAAI,QAAQ,GAAG,CAAA;AAAA,MAClC,GAAA,EAAK,IAAIA,gBAAA,CAAU,GAAA,CAAI;AAAA,QACrB,KAAA,EAAO,QAAQ,GAAA,CAAI,KAAA;AAAA,QACnB,GAAG,OAAA,CAAQ;AAAA,OACZ,CAAA;AAAA,MACD,aAAA,EAAe,IAAYC,kBAAA,CAAA,YAAA,CAAa,iBAAA,EAAkB;AAAA,MAC1D,GAAA,EAAK,GAAA,CAAI,IAAA,CAAK,QAAA,CAAS,GAAA;AAAA,MACvB,YAAA,EAAc;AAAA,QACZ,oBAAA,EAAsB;AAAA;AACxB,KACD,CAAA;AAED,IAAA,MAAM,cAAA,GAAiB,IAAIC,cAAA,CAAQ,cAAA,EAAe;AAClD,IAAA,OAAA,CAAQ,EAAA,CAAGL,YAAAA,CAAM,sBAAA,CAAuB,gBAAA,EAAkB,CAAC,EAAA,KAAO;AAChE,MAAAK,cAAA,CAAQ,UAAA,CAAW,GAAG,OAAO,CAAA;AAC7B,MAAA,cAAA,CAAe,OAAA,CAAQ,GAAG,OAAO,CAAA;AAAA,IACnC,CAAC,CAAA;AAED,IAAA,MAAM,WAAW,YAAY;AAC3B,MAAA,MAAM,OAAA,GAAU,eAAe,UAAA,EAAW;AAC1C,MAAA,OAAA,CAAQ,IAAI,CAAA,OAAA,EAAU,IAAA,CAAK,SAAA,CAAU,OAAO,CAAC,CAAA,CAAE,CAAA;AAAA,IACjD,CAAA;AAEA,IAAA,GAAA,CAAI,oBAAoB,QAAQ,CAAA;AAEhC,IAAA,MAAM,QAAQ,KAAA,CAAM;AAAA,MAClB,KAAA,EAAO,IAAI,KAAA,CAAM,GAAA,CAAI,IAAI,QAAQ,CAAA;AAAA,MACjC,MAAM,GAAA,CAAI;AAAA,KACX,CAAA;AAED,IAAA,MAAM,IAAI,OAAA,EAAQ;AAElB,IAAA,GAAA,CAAI,IAAA,CAAK,gBAAA,EAAkB,UAAA,CAAW,QAAA,CAAS,IAAI,CAAA;AAAA,EACrD;AACF,CAAC","file":"_internal-agent.js","sourcesContent":["import { voice } from \"@livekit/agents\";\n\nexport class Agent extends voice.Agent {\n constructor(metadata: string) {\n const data = JSON.parse(metadata);\n super({\n instructions:\n \"You are a helpful voice AI assistant. The user is interacting with you via voice, even if you perceive the conversation as text.\" +\n \"\\n\" +\n data.prompt,\n });\n }\n}\n","import type { LiveKitConfig, SahabAgentsOptions } from \"./types.js\";\n\nlet _options: SahabAgentsOptions | undefined;\nlet _livekitConfig: LiveKitConfig | undefined;\n\nexport function setOptions(options: SahabAgentsOptions): void {\n _options = options;\n}\n\nexport function getOptions(): SahabAgentsOptions {\n if (!_options) {\n throw new Error(\n \"SahabAgents options have not been set. Call initialize() first.\",\n );\n }\n return _options;\n}\n\nexport function setLiveKitConfig(config: LiveKitConfig): void {\n _livekitConfig = config;\n}\n\nexport function getLiveKitConfig(): LiveKitConfig {\n if (!_livekitConfig) {\n throw new Error(\n \"LiveKit config has not been set. Call initialize() first.\",\n );\n }\n return _livekitConfig;\n}\n","/**\n * Internal agent entry file — imported by LiveKit's worker process.\n *\n * Do NOT import this file directly. It is referenced by path in\n * `AgentsResource.initialize()` and dynamically loaded by LiveKit.\n */\nimport {\n defineAgent,\n JobContext,\n JobProcess,\n voice,\n metrics,\n inference,\n} from \"@livekit/agents\";\nimport * as livekit from \"@livekit/agents-plugin-livekit\";\nimport * as silero from \"@livekit/agents-plugin-silero\";\nimport { Agent } from \"./agent-instructions.js\";\nimport { getOptions } from \"./store.js\";\n\nconst options = getOptions();\n\nexport default defineAgent({\n prewarm: async (proc: JobProcess) => {\n proc.userData.vad = await silero.VAD.load();\n },\n entry: async (ctx: JobContext) => {\n const metadata = JSON.parse(ctx.job.metadata);\n\n const session = new voice.AgentSession({\n stt: new inference.STT(options.stt),\n llm: new inference.LLM(options.llm),\n tts: new inference.TTS({\n model: options.tts.model!,\n ...options.tts,\n }),\n turnDetection: new livekit.turnDetector.MultilingualModel(),\n vad: ctx.proc.userData.vad! as silero.VAD,\n voiceOptions: {\n preemptiveGeneration: true,\n },\n });\n\n const usageCollector = new metrics.UsageCollector();\n session.on(voice.AgentSessionEventTypes.MetricsCollected, (ev) => {\n metrics.logMetrics(ev.metrics);\n usageCollector.collect(ev.metrics);\n });\n\n const logUsage = async () => {\n const summary = usageCollector.getSummary();\n console.log(`Usage: ${JSON.stringify(summary)}`);\n };\n\n ctx.addShutdownCallback(logUsage);\n\n await session.start({\n agent: new Agent(ctx.job.metadata),\n room: ctx.room,\n });\n\n await ctx.connect();\n\n ctx.room.localParticipant?.updateName(metadata.name);\n },\n});\n"]}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { voice, defineAgent, inference, metrics } from '@livekit/agents';
|
|
2
|
+
import * as livekit from '@livekit/agents-plugin-livekit';
|
|
3
|
+
import * as silero from '@livekit/agents-plugin-silero';
|
|
4
|
+
|
|
5
|
+
// src/_internal-agent.ts
|
|
6
|
+
var Agent = class extends voice.Agent {
|
|
7
|
+
constructor(metadata) {
|
|
8
|
+
const data = JSON.parse(metadata);
|
|
9
|
+
super({
|
|
10
|
+
instructions: "You are a helpful voice AI assistant. The user is interacting with you via voice, even if you perceive the conversation as text.\n" + data.prompt
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
function getOptions() {
|
|
15
|
+
{
|
|
16
|
+
throw new Error(
|
|
17
|
+
"SahabAgents options have not been set. Call initialize() first."
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// src/_internal-agent.ts
|
|
23
|
+
var options = getOptions();
|
|
24
|
+
var internal_agent_default = defineAgent({
|
|
25
|
+
prewarm: async (proc) => {
|
|
26
|
+
proc.userData.vad = await silero.VAD.load();
|
|
27
|
+
},
|
|
28
|
+
entry: async (ctx) => {
|
|
29
|
+
const metadata = JSON.parse(ctx.job.metadata);
|
|
30
|
+
const session = new voice.AgentSession({
|
|
31
|
+
stt: new inference.STT(options.stt),
|
|
32
|
+
llm: new inference.LLM(options.llm),
|
|
33
|
+
tts: new inference.TTS({
|
|
34
|
+
model: options.tts.model,
|
|
35
|
+
...options.tts
|
|
36
|
+
}),
|
|
37
|
+
turnDetection: new livekit.turnDetector.MultilingualModel(),
|
|
38
|
+
vad: ctx.proc.userData.vad,
|
|
39
|
+
voiceOptions: {
|
|
40
|
+
preemptiveGeneration: true
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
const usageCollector = new metrics.UsageCollector();
|
|
44
|
+
session.on(voice.AgentSessionEventTypes.MetricsCollected, (ev) => {
|
|
45
|
+
metrics.logMetrics(ev.metrics);
|
|
46
|
+
usageCollector.collect(ev.metrics);
|
|
47
|
+
});
|
|
48
|
+
const logUsage = async () => {
|
|
49
|
+
const summary = usageCollector.getSummary();
|
|
50
|
+
console.log(`Usage: ${JSON.stringify(summary)}`);
|
|
51
|
+
};
|
|
52
|
+
ctx.addShutdownCallback(logUsage);
|
|
53
|
+
await session.start({
|
|
54
|
+
agent: new Agent(ctx.job.metadata),
|
|
55
|
+
room: ctx.room
|
|
56
|
+
});
|
|
57
|
+
await ctx.connect();
|
|
58
|
+
ctx.room.localParticipant?.updateName(metadata.name);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
export { internal_agent_default as default };
|
|
63
|
+
//# sourceMappingURL=_internal-agent.mjs.map
|
|
64
|
+
//# sourceMappingURL=_internal-agent.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/agent-instructions.ts","../src/store.ts","../src/_internal-agent.ts"],"names":["voice"],"mappings":";;;;;AAEO,IAAM,KAAA,GAAN,cAAoB,KAAA,CAAM,KAAA,CAAM;AAAA,EACrC,YAAY,QAAA,EAAkB;AAC5B,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,QAAQ,CAAA;AAChC,IAAA,KAAA,CAAM;AAAA,MACJ,YAAA,EACE,uIAEA,IAAA,CAAK;AAAA,KACR,CAAA;AAAA,EACH;AACF,CAAA;ACHO,SAAS,UAAA,GAAiC;AAC/C,EAAe;AACb,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEF;;;ACGA,IAAM,UAAU,UAAA,EAAW;AAE3B,IAAO,yBAAQ,WAAA,CAAY;AAAA,EACzB,OAAA,EAAS,OAAO,IAAA,KAAqB;AACnC,IAAA,IAAA,CAAK,QAAA,CAAS,GAAA,GAAM,MAAa,MAAA,CAAA,GAAA,CAAI,IAAA,EAAK;AAAA,EAC5C,CAAA;AAAA,EACA,KAAA,EAAO,OAAO,GAAA,KAAoB;AAChC,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,IAAI,QAAQ,CAAA;AAE5C,IAAA,MAAM,OAAA,GAAU,IAAIA,KAAAA,CAAM,YAAA,CAAa;AAAA,MACrC,GAAA,EAAK,IAAI,SAAA,CAAU,GAAA,CAAI,QAAQ,GAAG,CAAA;AAAA,MAClC,GAAA,EAAK,IAAI,SAAA,CAAU,GAAA,CAAI,QAAQ,GAAG,CAAA;AAAA,MAClC,GAAA,EAAK,IAAI,SAAA,CAAU,GAAA,CAAI;AAAA,QACrB,KAAA,EAAO,QAAQ,GAAA,CAAI,KAAA;AAAA,QACnB,GAAG,OAAA,CAAQ;AAAA,OACZ,CAAA;AAAA,MACD,aAAA,EAAe,IAAY,OAAA,CAAA,YAAA,CAAa,iBAAA,EAAkB;AAAA,MAC1D,GAAA,EAAK,GAAA,CAAI,IAAA,CAAK,QAAA,CAAS,GAAA;AAAA,MACvB,YAAA,EAAc;AAAA,QACZ,oBAAA,EAAsB;AAAA;AACxB,KACD,CAAA;AAED,IAAA,MAAM,cAAA,GAAiB,IAAI,OAAA,CAAQ,cAAA,EAAe;AAClD,IAAA,OAAA,CAAQ,EAAA,CAAGA,KAAAA,CAAM,sBAAA,CAAuB,gBAAA,EAAkB,CAAC,EAAA,KAAO;AAChE,MAAA,OAAA,CAAQ,UAAA,CAAW,GAAG,OAAO,CAAA;AAC7B,MAAA,cAAA,CAAe,OAAA,CAAQ,GAAG,OAAO,CAAA;AAAA,IACnC,CAAC,CAAA;AAED,IAAA,MAAM,WAAW,YAAY;AAC3B,MAAA,MAAM,OAAA,GAAU,eAAe,UAAA,EAAW;AAC1C,MAAA,OAAA,CAAQ,IAAI,CAAA,OAAA,EAAU,IAAA,CAAK,SAAA,CAAU,OAAO,CAAC,CAAA,CAAE,CAAA;AAAA,IACjD,CAAA;AAEA,IAAA,GAAA,CAAI,oBAAoB,QAAQ,CAAA;AAEhC,IAAA,MAAM,QAAQ,KAAA,CAAM;AAAA,MAClB,KAAA,EAAO,IAAI,KAAA,CAAM,GAAA,CAAI,IAAI,QAAQ,CAAA;AAAA,MACjC,MAAM,GAAA,CAAI;AAAA,KACX,CAAA;AAED,IAAA,MAAM,IAAI,OAAA,EAAQ;AAElB,IAAA,GAAA,CAAI,IAAA,CAAK,gBAAA,EAAkB,UAAA,CAAW,QAAA,CAAS,IAAI,CAAA;AAAA,EACrD;AACF,CAAC","file":"_internal-agent.mjs","sourcesContent":["import { voice } from \"@livekit/agents\";\n\nexport class Agent extends voice.Agent {\n constructor(metadata: string) {\n const data = JSON.parse(metadata);\n super({\n instructions:\n \"You are a helpful voice AI assistant. The user is interacting with you via voice, even if you perceive the conversation as text.\" +\n \"\\n\" +\n data.prompt,\n });\n }\n}\n","import type { LiveKitConfig, SahabAgentsOptions } from \"./types.js\";\n\nlet _options: SahabAgentsOptions | undefined;\nlet _livekitConfig: LiveKitConfig | undefined;\n\nexport function setOptions(options: SahabAgentsOptions): void {\n _options = options;\n}\n\nexport function getOptions(): SahabAgentsOptions {\n if (!_options) {\n throw new Error(\n \"SahabAgents options have not been set. Call initialize() first.\",\n );\n }\n return _options;\n}\n\nexport function setLiveKitConfig(config: LiveKitConfig): void {\n _livekitConfig = config;\n}\n\nexport function getLiveKitConfig(): LiveKitConfig {\n if (!_livekitConfig) {\n throw new Error(\n \"LiveKit config has not been set. Call initialize() first.\",\n );\n }\n return _livekitConfig;\n}\n","/**\n * Internal agent entry file — imported by LiveKit's worker process.\n *\n * Do NOT import this file directly. It is referenced by path in\n * `AgentsResource.initialize()` and dynamically loaded by LiveKit.\n */\nimport {\n defineAgent,\n JobContext,\n JobProcess,\n voice,\n metrics,\n inference,\n} from \"@livekit/agents\";\nimport * as livekit from \"@livekit/agents-plugin-livekit\";\nimport * as silero from \"@livekit/agents-plugin-silero\";\nimport { Agent } from \"./agent-instructions.js\";\nimport { getOptions } from \"./store.js\";\n\nconst options = getOptions();\n\nexport default defineAgent({\n prewarm: async (proc: JobProcess) => {\n proc.userData.vad = await silero.VAD.load();\n },\n entry: async (ctx: JobContext) => {\n const metadata = JSON.parse(ctx.job.metadata);\n\n const session = new voice.AgentSession({\n stt: new inference.STT(options.stt),\n llm: new inference.LLM(options.llm),\n tts: new inference.TTS({\n model: options.tts.model!,\n ...options.tts,\n }),\n turnDetection: new livekit.turnDetector.MultilingualModel(),\n vad: ctx.proc.userData.vad! as silero.VAD,\n voiceOptions: {\n preemptiveGeneration: true,\n },\n });\n\n const usageCollector = new metrics.UsageCollector();\n session.on(voice.AgentSessionEventTypes.MetricsCollected, (ev) => {\n metrics.logMetrics(ev.metrics);\n usageCollector.collect(ev.metrics);\n });\n\n const logUsage = async () => {\n const summary = usageCollector.getSummary();\n console.log(`Usage: ${JSON.stringify(summary)}`);\n };\n\n ctx.addShutdownCallback(logUsage);\n\n await session.start({\n agent: new Agent(ctx.job.metadata),\n room: ctx.room,\n });\n\n await ctx.connect();\n\n ctx.room.localParticipant?.updateName(metadata.name);\n },\n});\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var agents = require('@livekit/agents');
|
|
4
|
+
|
|
5
|
+
// src/agent-instructions.ts
|
|
6
|
+
var Agent = class extends agents.voice.Agent {
|
|
7
|
+
constructor(metadata) {
|
|
8
|
+
const data = JSON.parse(metadata);
|
|
9
|
+
super({
|
|
10
|
+
instructions: "You are a helpful voice AI assistant. The user is interacting with you via voice, even if you perceive the conversation as text.\n" + data.prompt
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
exports.Agent = Agent;
|
|
16
|
+
//# sourceMappingURL=agent-instructions.js.map
|
|
17
|
+
//# sourceMappingURL=agent-instructions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/agent-instructions.ts"],"names":["voice"],"mappings":";;;;;AAEO,IAAM,KAAA,GAAN,cAAoBA,YAAA,CAAM,KAAA,CAAM;AAAA,EACrC,YAAY,QAAA,EAAkB;AAC5B,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,QAAQ,CAAA;AAChC,IAAA,KAAA,CAAM;AAAA,MACJ,YAAA,EACE,uIAEA,IAAA,CAAK;AAAA,KACR,CAAA;AAAA,EACH;AACF","file":"agent-instructions.js","sourcesContent":["import { voice } from \"@livekit/agents\";\n\nexport class Agent extends voice.Agent {\n constructor(metadata: string) {\n const data = JSON.parse(metadata);\n super({\n instructions:\n \"You are a helpful voice AI assistant. The user is interacting with you via voice, even if you perceive the conversation as text.\" +\n \"\\n\" +\n data.prompt,\n });\n }\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { voice } from '@livekit/agents';
|
|
2
|
+
|
|
3
|
+
// src/agent-instructions.ts
|
|
4
|
+
var Agent = class extends voice.Agent {
|
|
5
|
+
constructor(metadata) {
|
|
6
|
+
const data = JSON.parse(metadata);
|
|
7
|
+
super({
|
|
8
|
+
instructions: "You are a helpful voice AI assistant. The user is interacting with you via voice, even if you perceive the conversation as text.\n" + data.prompt
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export { Agent };
|
|
14
|
+
//# sourceMappingURL=agent-instructions.mjs.map
|
|
15
|
+
//# sourceMappingURL=agent-instructions.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/agent-instructions.ts"],"names":[],"mappings":";;;AAEO,IAAM,KAAA,GAAN,cAAoB,KAAA,CAAM,KAAA,CAAM;AAAA,EACrC,YAAY,QAAA,EAAkB;AAC5B,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,QAAQ,CAAA;AAChC,IAAA,KAAA,CAAM;AAAA,MACJ,YAAA,EACE,uIAEA,IAAA,CAAK;AAAA,KACR,CAAA;AAAA,EACH;AACF","file":"agent-instructions.mjs","sourcesContent":["import { voice } from \"@livekit/agents\";\n\nexport class Agent extends voice.Agent {\n constructor(metadata: string) {\n const data = JSON.parse(metadata);\n super({\n instructions:\n \"You are a helpful voice AI assistant. The user is interacting with you via voice, even if you perceive the conversation as text.\" +\n \"\\n\" +\n data.prompt,\n });\n }\n}\n"]}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { S as SahabAgentsOptions, A as ApiErrorBody } from './types-DiUcywed.mjs';
|
|
2
|
+
|
|
3
|
+
declare class HttpClient {
|
|
4
|
+
private readonly baseUrl;
|
|
5
|
+
private readonly defaultHeaders;
|
|
6
|
+
private readonly timeout;
|
|
7
|
+
constructor(options: SahabAgentsOptions);
|
|
8
|
+
request<T>(method: string, path: string, options?: {
|
|
9
|
+
body?: unknown;
|
|
10
|
+
params?: Record<string, string | number | undefined>;
|
|
11
|
+
}): Promise<T>;
|
|
12
|
+
get<T>(path: string, params?: Record<string, string | number | undefined>): Promise<T>;
|
|
13
|
+
post<T>(path: string, body?: unknown): Promise<T>;
|
|
14
|
+
patch<T>(path: string, body?: unknown): Promise<T>;
|
|
15
|
+
delete<T>(path: string): Promise<T>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
declare class AgentsResource {
|
|
19
|
+
private readonly http;
|
|
20
|
+
private readonly options;
|
|
21
|
+
constructor(http: HttpClient, options: SahabAgentsOptions);
|
|
22
|
+
initialize(): Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
declare class SahabAgentsError extends Error {
|
|
26
|
+
constructor(message: string);
|
|
27
|
+
}
|
|
28
|
+
declare class ApiError extends SahabAgentsError {
|
|
29
|
+
readonly status: number;
|
|
30
|
+
readonly code?: string;
|
|
31
|
+
readonly details?: unknown;
|
|
32
|
+
constructor(status: number, body: ApiErrorBody);
|
|
33
|
+
}
|
|
34
|
+
declare class TimeoutError extends SahabAgentsError {
|
|
35
|
+
constructor(timeoutMs: number);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
declare class SahabAgents {
|
|
39
|
+
readonly agents: AgentsResource;
|
|
40
|
+
constructor(options: SahabAgentsOptions);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export { ApiError, SahabAgents, SahabAgentsError, SahabAgentsOptions, TimeoutError };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { S as SahabAgentsOptions, A as ApiErrorBody } from './types-DiUcywed.js';
|
|
2
|
+
|
|
3
|
+
declare class HttpClient {
|
|
4
|
+
private readonly baseUrl;
|
|
5
|
+
private readonly defaultHeaders;
|
|
6
|
+
private readonly timeout;
|
|
7
|
+
constructor(options: SahabAgentsOptions);
|
|
8
|
+
request<T>(method: string, path: string, options?: {
|
|
9
|
+
body?: unknown;
|
|
10
|
+
params?: Record<string, string | number | undefined>;
|
|
11
|
+
}): Promise<T>;
|
|
12
|
+
get<T>(path: string, params?: Record<string, string | number | undefined>): Promise<T>;
|
|
13
|
+
post<T>(path: string, body?: unknown): Promise<T>;
|
|
14
|
+
patch<T>(path: string, body?: unknown): Promise<T>;
|
|
15
|
+
delete<T>(path: string): Promise<T>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
declare class AgentsResource {
|
|
19
|
+
private readonly http;
|
|
20
|
+
private readonly options;
|
|
21
|
+
constructor(http: HttpClient, options: SahabAgentsOptions);
|
|
22
|
+
initialize(): Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
declare class SahabAgentsError extends Error {
|
|
26
|
+
constructor(message: string);
|
|
27
|
+
}
|
|
28
|
+
declare class ApiError extends SahabAgentsError {
|
|
29
|
+
readonly status: number;
|
|
30
|
+
readonly code?: string;
|
|
31
|
+
readonly details?: unknown;
|
|
32
|
+
constructor(status: number, body: ApiErrorBody);
|
|
33
|
+
}
|
|
34
|
+
declare class TimeoutError extends SahabAgentsError {
|
|
35
|
+
constructor(timeoutMs: number);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
declare class SahabAgents {
|
|
39
|
+
readonly agents: AgentsResource;
|
|
40
|
+
constructor(options: SahabAgentsOptions);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export { ApiError, SahabAgents, SahabAgentsError, SahabAgentsOptions, TimeoutError };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var agents = require('@livekit/agents');
|
|
4
|
+
var path = require('path');
|
|
5
|
+
|
|
6
|
+
function _interopNamespace(e) {
|
|
7
|
+
if (e && e.__esModule) return e;
|
|
8
|
+
var n = Object.create(null);
|
|
9
|
+
if (e) {
|
|
10
|
+
Object.keys(e).forEach(function (k) {
|
|
11
|
+
if (k !== 'default') {
|
|
12
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
13
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function () { return e[k]; }
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
n.default = e;
|
|
21
|
+
return Object.freeze(n);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
25
|
+
|
|
26
|
+
// src/errors.ts
|
|
27
|
+
var SahabAgentsError = class extends Error {
|
|
28
|
+
constructor(message) {
|
|
29
|
+
super(message);
|
|
30
|
+
this.name = "SahabAgentsError";
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
var ApiError = class extends SahabAgentsError {
|
|
34
|
+
status;
|
|
35
|
+
code;
|
|
36
|
+
details;
|
|
37
|
+
constructor(status, body) {
|
|
38
|
+
super(body.message);
|
|
39
|
+
this.name = "ApiError";
|
|
40
|
+
this.status = status;
|
|
41
|
+
this.code = body.code;
|
|
42
|
+
this.details = body.details;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
var TimeoutError = class extends SahabAgentsError {
|
|
46
|
+
constructor(timeoutMs) {
|
|
47
|
+
super(`Request timed out after ${timeoutMs}ms`);
|
|
48
|
+
this.name = "TimeoutError";
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// src/client.ts
|
|
53
|
+
var DEFAULT_TIMEOUT = 3e4;
|
|
54
|
+
var HttpClient = class {
|
|
55
|
+
baseUrl;
|
|
56
|
+
defaultHeaders;
|
|
57
|
+
timeout;
|
|
58
|
+
constructor(options) {
|
|
59
|
+
this.baseUrl = "https://api.sahab.live/v1";
|
|
60
|
+
this.timeout = options.timeout ?? DEFAULT_TIMEOUT;
|
|
61
|
+
this.defaultHeaders = {
|
|
62
|
+
"Content-Type": "application/json",
|
|
63
|
+
Accept: "application/json",
|
|
64
|
+
"api-key": options.apiKey,
|
|
65
|
+
...options.headers
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
async request(method, path2, options = {}) {
|
|
69
|
+
const url = new URL(`${this.baseUrl}${path2}`);
|
|
70
|
+
if (options.params) {
|
|
71
|
+
for (const [key, value] of Object.entries(options.params)) {
|
|
72
|
+
if (value !== void 0) {
|
|
73
|
+
url.searchParams.set(key, String(value));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const controller = new AbortController();
|
|
78
|
+
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
79
|
+
let response;
|
|
80
|
+
try {
|
|
81
|
+
response = await fetch(url.toString(), {
|
|
82
|
+
method,
|
|
83
|
+
headers: this.defaultHeaders,
|
|
84
|
+
body: options.body !== void 0 ? JSON.stringify(options.body) : void 0,
|
|
85
|
+
signal: controller.signal
|
|
86
|
+
});
|
|
87
|
+
} catch (err) {
|
|
88
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
89
|
+
throw new TimeoutError(this.timeout);
|
|
90
|
+
}
|
|
91
|
+
throw err;
|
|
92
|
+
} finally {
|
|
93
|
+
clearTimeout(timer);
|
|
94
|
+
}
|
|
95
|
+
if (!response.ok) {
|
|
96
|
+
let body = { message: response.statusText };
|
|
97
|
+
try {
|
|
98
|
+
body = await response.json();
|
|
99
|
+
} catch {
|
|
100
|
+
}
|
|
101
|
+
throw new ApiError(response.status, body);
|
|
102
|
+
}
|
|
103
|
+
if (response.status === 204) {
|
|
104
|
+
return void 0;
|
|
105
|
+
}
|
|
106
|
+
return response.json();
|
|
107
|
+
}
|
|
108
|
+
get(path2, params) {
|
|
109
|
+
return this.request("GET", path2, { params });
|
|
110
|
+
}
|
|
111
|
+
post(path2, body) {
|
|
112
|
+
return this.request("POST", path2, { body });
|
|
113
|
+
}
|
|
114
|
+
patch(path2, body) {
|
|
115
|
+
return this.request("PATCH", path2, { body });
|
|
116
|
+
}
|
|
117
|
+
delete(path2) {
|
|
118
|
+
return this.request("DELETE", path2);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
// src/utils/get-config.utils.ts
|
|
123
|
+
async function getConfig(http) {
|
|
124
|
+
const response = await http.get("/auth/config");
|
|
125
|
+
return response;
|
|
126
|
+
}
|
|
127
|
+
function setOptions(options) {
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// src/resources/agents.ts
|
|
131
|
+
var AgentsResource = class {
|
|
132
|
+
constructor(http, options) {
|
|
133
|
+
this.http = http;
|
|
134
|
+
this.options = options;
|
|
135
|
+
}
|
|
136
|
+
async initialize() {
|
|
137
|
+
const livekitConfig = await getConfig(this.http);
|
|
138
|
+
setOptions(this.options);
|
|
139
|
+
const agentPath = path__namespace.resolve(__dirname, "_internal-agent.js");
|
|
140
|
+
agents.cli.runApp(
|
|
141
|
+
new agents.ServerOptions({
|
|
142
|
+
agent: agentPath,
|
|
143
|
+
agentName: "sahab-agent-" + livekitConfig.id,
|
|
144
|
+
wsURL: livekitConfig.url,
|
|
145
|
+
apiKey: livekitConfig.apiKey,
|
|
146
|
+
apiSecret: livekitConfig.apiSecret
|
|
147
|
+
})
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
// src/index.ts
|
|
153
|
+
var SahabAgents = class {
|
|
154
|
+
agents;
|
|
155
|
+
constructor(options) {
|
|
156
|
+
const http = new HttpClient(options);
|
|
157
|
+
this.agents = new AgentsResource(http, options);
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
exports.ApiError = ApiError;
|
|
162
|
+
exports.SahabAgents = SahabAgents;
|
|
163
|
+
exports.SahabAgentsError = SahabAgentsError;
|
|
164
|
+
exports.TimeoutError = TimeoutError;
|
|
165
|
+
//# sourceMappingURL=index.js.map
|
|
166
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/client.ts","../src/utils/get-config.utils.ts","../src/store.ts","../src/resources/agents.ts","../src/index.ts"],"names":["path","cli","ServerOptions"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAEO,IAAM,gBAAA,GAAN,cAA+B,KAAA,CAAM;AAAA,EAC1C,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,kBAAA;AAAA,EACd;AACF;AAEO,IAAM,QAAA,GAAN,cAAuB,gBAAA,CAAiB;AAAA,EACpC,MAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EAET,WAAA,CAAY,QAAgB,IAAA,EAAoB;AAC9C,IAAA,KAAA,CAAM,KAAK,OAAO,CAAA;AAClB,IAAA,IAAA,CAAK,IAAA,GAAO,UAAA;AACZ,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,UAAU,IAAA,CAAK,OAAA;AAAA,EACtB;AACF;AAEO,IAAM,YAAA,GAAN,cAA2B,gBAAA,CAAiB;AAAA,EACjD,YAAY,SAAA,EAAmB;AAC7B,IAAA,KAAA,CAAM,CAAA,wBAAA,EAA2B,SAAS,CAAA,EAAA,CAAI,CAAA;AAC9C,IAAA,IAAA,CAAK,IAAA,GAAO,cAAA;AAAA,EACd;AACF;;;ACzBA,IAAM,eAAA,GAAkB,GAAA;AAEjB,IAAM,aAAN,MAAiB;AAAA,EACL,OAAA;AAAA,EACA,cAAA;AAAA,EACA,OAAA;AAAA,EAEjB,YAAY,OAAA,EAA6B;AACvC,IAAA,IAAA,CAAK,OAAA,GAAU,2BAAA;AACf,IAAA,IAAA,CAAK,OAAA,GAAU,QAAQ,OAAA,IAAW,eAAA;AAClC,IAAA,IAAA,CAAK,cAAA,GAAiB;AAAA,MACpB,cAAA,EAAgB,kBAAA;AAAA,MAChB,MAAA,EAAQ,kBAAA;AAAA,MACR,WAAW,OAAA,CAAQ,MAAA;AAAA,MACnB,GAAG,OAAA,CAAQ;AAAA,KACb;AAAA,EACF;AAAA,EAEA,MAAM,OAAA,CACJ,MAAA,EACAA,KAAAA,EACA,OAAA,GAGI,EAAC,EACO;AACZ,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,CAAA,EAAG,KAAK,OAAO,CAAA,EAAGA,KAAI,CAAA,CAAE,CAAA;AAE5C,IAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,MAAA,KAAA,MAAW,CAAC,KAAK,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,OAAA,CAAQ,MAAM,CAAA,EAAG;AACzD,QAAA,IAAI,UAAU,MAAA,EAAW;AACvB,UAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,GAAA,EAAK,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AAEA,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,WAAW,KAAA,EAAM,EAAG,KAAK,OAAO,CAAA;AAE/D,IAAA,IAAI,QAAA;AAEJ,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,CAAI,QAAA,EAAS,EAAG;AAAA,QACrC,MAAA;AAAA,QACA,SAAS,IAAA,CAAK,cAAA;AAAA,QACd,IAAA,EACE,QAAQ,IAAA,KAAS,KAAA,CAAA,GAAY,KAAK,SAAA,CAAU,OAAA,CAAQ,IAAI,CAAA,GAAI,KAAA,CAAA;AAAA,QAC9D,QAAQ,UAAA,CAAW;AAAA,OACpB,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,IAAI,GAAA,YAAe,KAAA,IAAS,GAAA,CAAI,IAAA,KAAS,YAAA,EAAc;AACrD,QAAA,MAAM,IAAI,YAAA,CAAa,IAAA,CAAK,OAAO,CAAA;AAAA,MACrC;AACA,MAAA,MAAM,GAAA;AAAA,IACR,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AAEA,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,IAAI,IAAA,GAAqB,EAAE,OAAA,EAAS,QAAA,CAAS,UAAA,EAAW;AACxD,MAAA,IAAI;AACF,QAAA,IAAA,GAAQ,MAAM,SAAS,IAAA,EAAK;AAAA,MAC9B,CAAA,CAAA,MAAQ;AAAA,MAER;AACA,MAAA,MAAM,IAAI,QAAA,CAAS,QAAA,CAAS,MAAA,EAAQ,IAAI,CAAA;AAAA,IAC1C;AAGA,IAAA,IAAI,QAAA,CAAS,WAAW,GAAA,EAAK;AAC3B,MAAA,OAAO,MAAA;AAAA,IACT;AAEA,IAAA,OAAO,SAAS,IAAA,EAAK;AAAA,EACvB;AAAA,EAEA,GAAA,CACEA,OACA,MAAA,EACY;AACZ,IAAA,OAAO,KAAK,OAAA,CAAW,KAAA,EAAOA,KAAAA,EAAM,EAAE,QAAQ,CAAA;AAAA,EAChD;AAAA,EAEA,IAAA,CAAQA,OAAc,IAAA,EAA4B;AAChD,IAAA,OAAO,KAAK,OAAA,CAAW,MAAA,EAAQA,KAAAA,EAAM,EAAE,MAAM,CAAA;AAAA,EAC/C;AAAA,EAEA,KAAA,CAASA,OAAc,IAAA,EAA4B;AACjD,IAAA,OAAO,KAAK,OAAA,CAAW,OAAA,EAASA,KAAAA,EAAM,EAAE,MAAM,CAAA;AAAA,EAChD;AAAA,EAEA,OAAUA,KAAAA,EAA0B;AAClC,IAAA,OAAO,IAAA,CAAK,OAAA,CAAW,QAAA,EAAUA,KAAI,CAAA;AAAA,EACvC;AACF,CAAA;;;AC9FA,eAAsB,UAAU,IAAA,EAA0C;AACxE,EAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,GAAA,CAAmB,cAAc,CAAA;AAC7D,EAAA,OAAO,QAAA;AACT;ACDO,SAAS,WAAW,OAAA,EAAmC;AAE9D;;;ACAO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,WAAA,CACmB,MACA,OAAA,EACjB;AAFiB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AACA,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAAA,EAChB;AAAA,EAEH,MAAM,UAAA,GAA4B;AAChC,IAAA,MAAM,aAAA,GAAgB,MAAM,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA;AAC/C,IAAA,UAAA,CAAW,KAAK,OAAO,CAAA;AAEvB,IAAA,MAAM,SAAA,GAAiBA,eAAA,CAAA,OAAA,CAAQ,SAAA,EAAW,oBAAoB,CAAA;AAE9D,IAAAC,UAAA,CAAI,MAAA;AAAA,MACF,IAAIC,oBAAA,CAAc;AAAA,QAChB,KAAA,EAAO,SAAA;AAAA,QACP,SAAA,EAAW,iBAAiB,aAAA,CAAc,EAAA;AAAA,QAC1C,OAAO,aAAA,CAAc,GAAA;AAAA,QACrB,QAAQ,aAAA,CAAc,MAAA;AAAA,QACtB,WAAW,aAAA,CAAc;AAAA,OAC1B;AAAA,KACH;AAAA,EACF;AACF,CAAA;;;ACzBO,IAAM,cAAN,MAAkB;AAAA,EACd,MAAA;AAAA,EAET,YAAY,OAAA,EAA6B;AACvC,IAAA,MAAM,IAAA,GAAO,IAAI,UAAA,CAAW,OAAO,CAAA;AACnC,IAAA,IAAA,CAAK,MAAA,GAAS,IAAI,cAAA,CAAe,IAAA,EAAM,OAAO,CAAA;AAAA,EAChD;AACF","file":"index.js","sourcesContent":["import type { ApiErrorBody } from \"./types.js\";\n\nexport class SahabAgentsError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SahabAgentsError\";\n }\n}\n\nexport class ApiError extends SahabAgentsError {\n readonly status: number;\n readonly code?: string;\n readonly details?: unknown;\n\n constructor(status: number, body: ApiErrorBody) {\n super(body.message);\n this.name = \"ApiError\";\n this.status = status;\n this.code = body.code;\n this.details = body.details;\n }\n}\n\nexport class TimeoutError extends SahabAgentsError {\n constructor(timeoutMs: number) {\n super(`Request timed out after ${timeoutMs}ms`);\n this.name = \"TimeoutError\";\n }\n}\n","import { ApiError, TimeoutError } from \"./errors.js\";\nimport type { ApiErrorBody, SahabAgentsOptions } from \"./types.js\";\n\nconst DEFAULT_TIMEOUT = 30_000;\n\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly defaultHeaders: Record<string, string>;\n private readonly timeout: number;\n\n constructor(options: SahabAgentsOptions) {\n this.baseUrl = \"https://api.sahab.live/v1\";\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT;\n this.defaultHeaders = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n \"api-key\": options.apiKey,\n ...options.headers,\n };\n }\n\n async request<T>(\n method: string,\n path: string,\n options: {\n body?: unknown;\n params?: Record<string, string | number | undefined>;\n } = {},\n ): Promise<T> {\n const url = new URL(`${this.baseUrl}${path}`);\n\n if (options.params) {\n for (const [key, value] of Object.entries(options.params)) {\n if (value !== undefined) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n let response: Response;\n\n try {\n response = await fetch(url.toString(), {\n method,\n headers: this.defaultHeaders,\n body:\n options.body !== undefined ? JSON.stringify(options.body) : undefined,\n signal: controller.signal,\n });\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n throw new TimeoutError(this.timeout);\n }\n throw err;\n } finally {\n clearTimeout(timer);\n }\n\n if (!response.ok) {\n let body: ApiErrorBody = { message: response.statusText };\n try {\n body = (await response.json()) as ApiErrorBody;\n } catch {\n // use default body\n }\n throw new ApiError(response.status, body);\n }\n\n // 204 No Content\n if (response.status === 204) {\n return undefined as T;\n }\n\n return response.json() as Promise<T>;\n }\n\n get<T>(\n path: string,\n params?: Record<string, string | number | undefined>,\n ): Promise<T> {\n return this.request<T>(\"GET\", path, { params });\n }\n\n post<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(\"POST\", path, { body });\n }\n\n patch<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(\"PATCH\", path, { body });\n }\n\n delete<T>(path: string): Promise<T> {\n return this.request<T>(\"DELETE\", path);\n }\n}\n","import { HttpClient } from \"../client.js\";\nimport type { LiveKitConfig } from \"../types.js\";\n\nexport async function getConfig(http: HttpClient): Promise<LiveKitConfig> {\n const response = await http.get<LiveKitConfig>(\"/auth/config\");\n return response;\n}\n","import type { LiveKitConfig, SahabAgentsOptions } from \"./types.js\";\n\nlet _options: SahabAgentsOptions | undefined;\nlet _livekitConfig: LiveKitConfig | undefined;\n\nexport function setOptions(options: SahabAgentsOptions): void {\n _options = options;\n}\n\nexport function getOptions(): SahabAgentsOptions {\n if (!_options) {\n throw new Error(\n \"SahabAgents options have not been set. Call initialize() first.\",\n );\n }\n return _options;\n}\n\nexport function setLiveKitConfig(config: LiveKitConfig): void {\n _livekitConfig = config;\n}\n\nexport function getLiveKitConfig(): LiveKitConfig {\n if (!_livekitConfig) {\n throw new Error(\n \"LiveKit config has not been set. Call initialize() first.\",\n );\n }\n return _livekitConfig;\n}\n","import { cli, ServerOptions } from \"@livekit/agents\";\nimport * as path from \"path\";\nimport type { HttpClient } from \"../client.js\";\nimport type { SahabAgentsOptions } from \"../types.js\";\nimport { getConfig } from \"../utils/get-config.utils.js\";\nimport { setOptions, setLiveKitConfig } from \"../store.js\";\n\nexport class AgentsResource {\n constructor(\n private readonly http: HttpClient,\n private readonly options: SahabAgentsOptions,\n ) {}\n\n async initialize(): Promise<void> {\n const livekitConfig = await getConfig(this.http);\n setOptions(this.options);\n setLiveKitConfig(livekitConfig);\n const agentPath = path.resolve(__dirname, \"_internal-agent.js\");\n\n cli.runApp(\n new ServerOptions({\n agent: agentPath,\n agentName: \"sahab-agent-\" + livekitConfig.id,\n wsURL: livekitConfig.url,\n apiKey: livekitConfig.apiKey,\n apiSecret: livekitConfig.apiSecret,\n }),\n );\n }\n}\n","import { HttpClient } from \"./client.js\";\nimport { AgentsResource } from \"./resources/agents.js\";\nimport type { SahabAgentsOptions } from \"./types.js\";\n\nexport class SahabAgents {\n readonly agents: AgentsResource;\n\n constructor(options: SahabAgentsOptions) {\n const http = new HttpClient(options);\n this.agents = new AgentsResource(http, options);\n }\n}\n\nexport type { SahabAgentsOptions } from \"./types.js\";\n\nexport { ApiError, SahabAgentsError, TimeoutError } from \"./errors.js\";\n"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { cli, ServerOptions } from '@livekit/agents';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
|
|
4
|
+
// src/errors.ts
|
|
5
|
+
var SahabAgentsError = class extends Error {
|
|
6
|
+
constructor(message) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = "SahabAgentsError";
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
var ApiError = class extends SahabAgentsError {
|
|
12
|
+
status;
|
|
13
|
+
code;
|
|
14
|
+
details;
|
|
15
|
+
constructor(status, body) {
|
|
16
|
+
super(body.message);
|
|
17
|
+
this.name = "ApiError";
|
|
18
|
+
this.status = status;
|
|
19
|
+
this.code = body.code;
|
|
20
|
+
this.details = body.details;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
var TimeoutError = class extends SahabAgentsError {
|
|
24
|
+
constructor(timeoutMs) {
|
|
25
|
+
super(`Request timed out after ${timeoutMs}ms`);
|
|
26
|
+
this.name = "TimeoutError";
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// src/client.ts
|
|
31
|
+
var DEFAULT_TIMEOUT = 3e4;
|
|
32
|
+
var HttpClient = class {
|
|
33
|
+
baseUrl;
|
|
34
|
+
defaultHeaders;
|
|
35
|
+
timeout;
|
|
36
|
+
constructor(options) {
|
|
37
|
+
this.baseUrl = "https://api.sahab.live/v1";
|
|
38
|
+
this.timeout = options.timeout ?? DEFAULT_TIMEOUT;
|
|
39
|
+
this.defaultHeaders = {
|
|
40
|
+
"Content-Type": "application/json",
|
|
41
|
+
Accept: "application/json",
|
|
42
|
+
"api-key": options.apiKey,
|
|
43
|
+
...options.headers
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
async request(method, path2, options = {}) {
|
|
47
|
+
const url = new URL(`${this.baseUrl}${path2}`);
|
|
48
|
+
if (options.params) {
|
|
49
|
+
for (const [key, value] of Object.entries(options.params)) {
|
|
50
|
+
if (value !== void 0) {
|
|
51
|
+
url.searchParams.set(key, String(value));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const controller = new AbortController();
|
|
56
|
+
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
57
|
+
let response;
|
|
58
|
+
try {
|
|
59
|
+
response = await fetch(url.toString(), {
|
|
60
|
+
method,
|
|
61
|
+
headers: this.defaultHeaders,
|
|
62
|
+
body: options.body !== void 0 ? JSON.stringify(options.body) : void 0,
|
|
63
|
+
signal: controller.signal
|
|
64
|
+
});
|
|
65
|
+
} catch (err) {
|
|
66
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
67
|
+
throw new TimeoutError(this.timeout);
|
|
68
|
+
}
|
|
69
|
+
throw err;
|
|
70
|
+
} finally {
|
|
71
|
+
clearTimeout(timer);
|
|
72
|
+
}
|
|
73
|
+
if (!response.ok) {
|
|
74
|
+
let body = { message: response.statusText };
|
|
75
|
+
try {
|
|
76
|
+
body = await response.json();
|
|
77
|
+
} catch {
|
|
78
|
+
}
|
|
79
|
+
throw new ApiError(response.status, body);
|
|
80
|
+
}
|
|
81
|
+
if (response.status === 204) {
|
|
82
|
+
return void 0;
|
|
83
|
+
}
|
|
84
|
+
return response.json();
|
|
85
|
+
}
|
|
86
|
+
get(path2, params) {
|
|
87
|
+
return this.request("GET", path2, { params });
|
|
88
|
+
}
|
|
89
|
+
post(path2, body) {
|
|
90
|
+
return this.request("POST", path2, { body });
|
|
91
|
+
}
|
|
92
|
+
patch(path2, body) {
|
|
93
|
+
return this.request("PATCH", path2, { body });
|
|
94
|
+
}
|
|
95
|
+
delete(path2) {
|
|
96
|
+
return this.request("DELETE", path2);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
// src/utils/get-config.utils.ts
|
|
101
|
+
async function getConfig(http) {
|
|
102
|
+
const response = await http.get("/auth/config");
|
|
103
|
+
return response;
|
|
104
|
+
}
|
|
105
|
+
function setOptions(options) {
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// src/resources/agents.ts
|
|
109
|
+
var AgentsResource = class {
|
|
110
|
+
constructor(http, options) {
|
|
111
|
+
this.http = http;
|
|
112
|
+
this.options = options;
|
|
113
|
+
}
|
|
114
|
+
async initialize() {
|
|
115
|
+
const livekitConfig = await getConfig(this.http);
|
|
116
|
+
setOptions(this.options);
|
|
117
|
+
const agentPath = path.resolve(__dirname, "_internal-agent.js");
|
|
118
|
+
cli.runApp(
|
|
119
|
+
new ServerOptions({
|
|
120
|
+
agent: agentPath,
|
|
121
|
+
agentName: "sahab-agent-" + livekitConfig.id,
|
|
122
|
+
wsURL: livekitConfig.url,
|
|
123
|
+
apiKey: livekitConfig.apiKey,
|
|
124
|
+
apiSecret: livekitConfig.apiSecret
|
|
125
|
+
})
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// src/index.ts
|
|
131
|
+
var SahabAgents = class {
|
|
132
|
+
agents;
|
|
133
|
+
constructor(options) {
|
|
134
|
+
const http = new HttpClient(options);
|
|
135
|
+
this.agents = new AgentsResource(http, options);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export { ApiError, SahabAgents, SahabAgentsError, TimeoutError };
|
|
140
|
+
//# sourceMappingURL=index.mjs.map
|
|
141
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/client.ts","../src/utils/get-config.utils.ts","../src/store.ts","../src/resources/agents.ts","../src/index.ts"],"names":["path"],"mappings":"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","file":"index.mjs","sourcesContent":["import type { ApiErrorBody } from \"./types.js\";\n\nexport class SahabAgentsError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SahabAgentsError\";\n }\n}\n\nexport class ApiError extends SahabAgentsError {\n readonly status: number;\n readonly code?: string;\n readonly details?: unknown;\n\n constructor(status: number, body: ApiErrorBody) {\n super(body.message);\n this.name = \"ApiError\";\n this.status = status;\n this.code = body.code;\n this.details = body.details;\n }\n}\n\nexport class TimeoutError extends SahabAgentsError {\n constructor(timeoutMs: number) {\n super(`Request timed out after ${timeoutMs}ms`);\n this.name = \"TimeoutError\";\n }\n}\n","import { ApiError, TimeoutError } from \"./errors.js\";\nimport type { ApiErrorBody, SahabAgentsOptions } from \"./types.js\";\n\nconst DEFAULT_TIMEOUT = 30_000;\n\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly defaultHeaders: Record<string, string>;\n private readonly timeout: number;\n\n constructor(options: SahabAgentsOptions) {\n this.baseUrl = \"https://api.sahab.live/v1\";\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT;\n this.defaultHeaders = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n \"api-key\": options.apiKey,\n ...options.headers,\n };\n }\n\n async request<T>(\n method: string,\n path: string,\n options: {\n body?: unknown;\n params?: Record<string, string | number | undefined>;\n } = {},\n ): Promise<T> {\n const url = new URL(`${this.baseUrl}${path}`);\n\n if (options.params) {\n for (const [key, value] of Object.entries(options.params)) {\n if (value !== undefined) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n let response: Response;\n\n try {\n response = await fetch(url.toString(), {\n method,\n headers: this.defaultHeaders,\n body:\n options.body !== undefined ? JSON.stringify(options.body) : undefined,\n signal: controller.signal,\n });\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n throw new TimeoutError(this.timeout);\n }\n throw err;\n } finally {\n clearTimeout(timer);\n }\n\n if (!response.ok) {\n let body: ApiErrorBody = { message: response.statusText };\n try {\n body = (await response.json()) as ApiErrorBody;\n } catch {\n // use default body\n }\n throw new ApiError(response.status, body);\n }\n\n // 204 No Content\n if (response.status === 204) {\n return undefined as T;\n }\n\n return response.json() as Promise<T>;\n }\n\n get<T>(\n path: string,\n params?: Record<string, string | number | undefined>,\n ): Promise<T> {\n return this.request<T>(\"GET\", path, { params });\n }\n\n post<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(\"POST\", path, { body });\n }\n\n patch<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(\"PATCH\", path, { body });\n }\n\n delete<T>(path: string): Promise<T> {\n return this.request<T>(\"DELETE\", path);\n }\n}\n","import { HttpClient } from \"../client.js\";\nimport type { LiveKitConfig } from \"../types.js\";\n\nexport async function getConfig(http: HttpClient): Promise<LiveKitConfig> {\n const response = await http.get<LiveKitConfig>(\"/auth/config\");\n return response;\n}\n","import type { LiveKitConfig, SahabAgentsOptions } from \"./types.js\";\n\nlet _options: SahabAgentsOptions | undefined;\nlet _livekitConfig: LiveKitConfig | undefined;\n\nexport function setOptions(options: SahabAgentsOptions): void {\n _options = options;\n}\n\nexport function getOptions(): SahabAgentsOptions {\n if (!_options) {\n throw new Error(\n \"SahabAgents options have not been set. Call initialize() first.\",\n );\n }\n return _options;\n}\n\nexport function setLiveKitConfig(config: LiveKitConfig): void {\n _livekitConfig = config;\n}\n\nexport function getLiveKitConfig(): LiveKitConfig {\n if (!_livekitConfig) {\n throw new Error(\n \"LiveKit config has not been set. Call initialize() first.\",\n );\n }\n return _livekitConfig;\n}\n","import { cli, ServerOptions } from \"@livekit/agents\";\nimport * as path from \"path\";\nimport type { HttpClient } from \"../client.js\";\nimport type { SahabAgentsOptions } from \"../types.js\";\nimport { getConfig } from \"../utils/get-config.utils.js\";\nimport { setOptions, setLiveKitConfig } from \"../store.js\";\n\nexport class AgentsResource {\n constructor(\n private readonly http: HttpClient,\n private readonly options: SahabAgentsOptions,\n ) {}\n\n async initialize(): Promise<void> {\n const livekitConfig = await getConfig(this.http);\n setOptions(this.options);\n setLiveKitConfig(livekitConfig);\n const agentPath = path.resolve(__dirname, \"_internal-agent.js\");\n\n cli.runApp(\n new ServerOptions({\n agent: agentPath,\n agentName: \"sahab-agent-\" + livekitConfig.id,\n wsURL: livekitConfig.url,\n apiKey: livekitConfig.apiKey,\n apiSecret: livekitConfig.apiSecret,\n }),\n );\n }\n}\n","import { HttpClient } from \"./client.js\";\nimport { AgentsResource } from \"./resources/agents.js\";\nimport type { SahabAgentsOptions } from \"./types.js\";\n\nexport class SahabAgents {\n readonly agents: AgentsResource;\n\n constructor(options: SahabAgentsOptions) {\n const http = new HttpClient(options);\n this.agents = new AgentsResource(http, options);\n }\n}\n\nexport type { SahabAgentsOptions } from \"./types.js\";\n\nexport { ApiError, SahabAgentsError, TimeoutError } from \"./errors.js\";\n"]}
|
package/dist/store.d.mts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { L as LiveKitConfig, S as SahabAgentsOptions } from './types-DiUcywed.mjs';
|
|
2
|
+
|
|
3
|
+
declare function setOptions(options: SahabAgentsOptions): void;
|
|
4
|
+
declare function getOptions(): SahabAgentsOptions;
|
|
5
|
+
declare function setLiveKitConfig(config: LiveKitConfig): void;
|
|
6
|
+
declare function getLiveKitConfig(): LiveKitConfig;
|
|
7
|
+
|
|
8
|
+
export { getLiveKitConfig, getOptions, setLiveKitConfig, setOptions };
|
package/dist/store.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { L as LiveKitConfig, S as SahabAgentsOptions } from './types-DiUcywed.js';
|
|
2
|
+
|
|
3
|
+
declare function setOptions(options: SahabAgentsOptions): void;
|
|
4
|
+
declare function getOptions(): SahabAgentsOptions;
|
|
5
|
+
declare function setLiveKitConfig(config: LiveKitConfig): void;
|
|
6
|
+
declare function getLiveKitConfig(): LiveKitConfig;
|
|
7
|
+
|
|
8
|
+
export { getLiveKitConfig, getOptions, setLiveKitConfig, setOptions };
|
package/dist/store.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/store.ts
|
|
4
|
+
var _options;
|
|
5
|
+
var _livekitConfig;
|
|
6
|
+
function setOptions(options) {
|
|
7
|
+
_options = options;
|
|
8
|
+
}
|
|
9
|
+
function getOptions() {
|
|
10
|
+
if (!_options) {
|
|
11
|
+
throw new Error(
|
|
12
|
+
"SahabAgents options have not been set. Call initialize() first."
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
return _options;
|
|
16
|
+
}
|
|
17
|
+
function setLiveKitConfig(config) {
|
|
18
|
+
_livekitConfig = config;
|
|
19
|
+
}
|
|
20
|
+
function getLiveKitConfig() {
|
|
21
|
+
if (!_livekitConfig) {
|
|
22
|
+
throw new Error(
|
|
23
|
+
"LiveKit config has not been set. Call initialize() first."
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
return _livekitConfig;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
exports.getLiveKitConfig = getLiveKitConfig;
|
|
30
|
+
exports.getOptions = getOptions;
|
|
31
|
+
exports.setLiveKitConfig = setLiveKitConfig;
|
|
32
|
+
exports.setOptions = setOptions;
|
|
33
|
+
//# sourceMappingURL=store.js.map
|
|
34
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/store.ts"],"names":[],"mappings":";;;AAEA,IAAI,QAAA;AACJ,IAAI,cAAA;AAEG,SAAS,WAAW,OAAA,EAAmC;AAC5D,EAAA,QAAA,GAAW,OAAA;AACb;AAEO,SAAS,UAAA,GAAiC;AAC/C,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,OAAO,QAAA;AACT;AAEO,SAAS,iBAAiB,MAAA,EAA6B;AAC5D,EAAA,cAAA,GAAiB,MAAA;AACnB;AAEO,SAAS,gBAAA,GAAkC;AAChD,EAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,OAAO,cAAA;AACT","file":"store.js","sourcesContent":["import type { LiveKitConfig, SahabAgentsOptions } from \"./types.js\";\n\nlet _options: SahabAgentsOptions | undefined;\nlet _livekitConfig: LiveKitConfig | undefined;\n\nexport function setOptions(options: SahabAgentsOptions): void {\n _options = options;\n}\n\nexport function getOptions(): SahabAgentsOptions {\n if (!_options) {\n throw new Error(\n \"SahabAgents options have not been set. Call initialize() first.\",\n );\n }\n return _options;\n}\n\nexport function setLiveKitConfig(config: LiveKitConfig): void {\n _livekitConfig = config;\n}\n\nexport function getLiveKitConfig(): LiveKitConfig {\n if (!_livekitConfig) {\n throw new Error(\n \"LiveKit config has not been set. Call initialize() first.\",\n );\n }\n return _livekitConfig;\n}\n"]}
|
package/dist/store.mjs
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// src/store.ts
|
|
2
|
+
var _options;
|
|
3
|
+
var _livekitConfig;
|
|
4
|
+
function setOptions(options) {
|
|
5
|
+
_options = options;
|
|
6
|
+
}
|
|
7
|
+
function getOptions() {
|
|
8
|
+
if (!_options) {
|
|
9
|
+
throw new Error(
|
|
10
|
+
"SahabAgents options have not been set. Call initialize() first."
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
return _options;
|
|
14
|
+
}
|
|
15
|
+
function setLiveKitConfig(config) {
|
|
16
|
+
_livekitConfig = config;
|
|
17
|
+
}
|
|
18
|
+
function getLiveKitConfig() {
|
|
19
|
+
if (!_livekitConfig) {
|
|
20
|
+
throw new Error(
|
|
21
|
+
"LiveKit config has not been set. Call initialize() first."
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
return _livekitConfig;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export { getLiveKitConfig, getOptions, setLiveKitConfig, setOptions };
|
|
28
|
+
//# sourceMappingURL=store.mjs.map
|
|
29
|
+
//# sourceMappingURL=store.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/store.ts"],"names":[],"mappings":";AAEA,IAAI,QAAA;AACJ,IAAI,cAAA;AAEG,SAAS,WAAW,OAAA,EAAmC;AAC5D,EAAA,QAAA,GAAW,OAAA;AACb;AAEO,SAAS,UAAA,GAAiC;AAC/C,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,OAAO,QAAA;AACT;AAEO,SAAS,iBAAiB,MAAA,EAA6B;AAC5D,EAAA,cAAA,GAAiB,MAAA;AACnB;AAEO,SAAS,gBAAA,GAAkC;AAChD,EAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,OAAO,cAAA;AACT","file":"store.mjs","sourcesContent":["import type { LiveKitConfig, SahabAgentsOptions } from \"./types.js\";\n\nlet _options: SahabAgentsOptions | undefined;\nlet _livekitConfig: LiveKitConfig | undefined;\n\nexport function setOptions(options: SahabAgentsOptions): void {\n _options = options;\n}\n\nexport function getOptions(): SahabAgentsOptions {\n if (!_options) {\n throw new Error(\n \"SahabAgents options have not been set. Call initialize() first.\",\n );\n }\n return _options;\n}\n\nexport function setLiveKitConfig(config: LiveKitConfig): void {\n _livekitConfig = config;\n}\n\nexport function getLiveKitConfig(): LiveKitConfig {\n if (!_livekitConfig) {\n throw new Error(\n \"LiveKit config has not been set. Call initialize() first.\",\n );\n }\n return _livekitConfig;\n}\n"]}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
type STTEncoding = "pcm_s16le";
|
|
2
|
+
type STTLanguages = "multi" | "en" | "de" | "es" | "fr" | "ja" | "pt" | "zh" | "hi";
|
|
3
|
+
type DeepgramModels = "deepgram/flux-general" | "deepgram/nova-3" | "deepgram/nova-3-medical" | "deepgram/nova-2" | "deepgram/nova-2-medical" | "deepgram/nova-2-conversationalai" | "deepgram/nova-2-phonecall";
|
|
4
|
+
type CartesiaModels = "cartesia/ink-whisper";
|
|
5
|
+
type AssemblyaiModels = "assemblyai/universal-streaming" | "assemblyai/universal-streaming-multilingual";
|
|
6
|
+
type ElevenlabsSTTModels = "elevenlabs/scribe_v2_realtime";
|
|
7
|
+
type _STTModels = DeepgramModels | CartesiaModels | AssemblyaiModels | ElevenlabsSTTModels;
|
|
8
|
+
interface DeepgramOptions {
|
|
9
|
+
/** Enable filler words. Default: true. */
|
|
10
|
+
filler_words?: boolean;
|
|
11
|
+
/** Enable interim results. Default: true. */
|
|
12
|
+
interim_results?: boolean;
|
|
13
|
+
/** Endpointing timeout in milliseconds. Default: 25. */
|
|
14
|
+
endpointing?: number;
|
|
15
|
+
/** Enable punctuation. Default: false. */
|
|
16
|
+
punctuate?: boolean;
|
|
17
|
+
/** Enable smart formatting. */
|
|
18
|
+
smart_format?: boolean;
|
|
19
|
+
/** Keywords with boost values. */
|
|
20
|
+
keywords?: Array<[string, number]>;
|
|
21
|
+
/** Key terms for recognition. */
|
|
22
|
+
keyterms?: string[];
|
|
23
|
+
/** Enable profanity filter. */
|
|
24
|
+
profanity_filter?: boolean;
|
|
25
|
+
/** Convert spoken numbers to numerals. */
|
|
26
|
+
numerals?: boolean;
|
|
27
|
+
/** Opt out of model improvement program. */
|
|
28
|
+
mip_opt_out?: boolean;
|
|
29
|
+
}
|
|
30
|
+
interface CartesiaOptions {
|
|
31
|
+
/** Minimum volume threshold. Default: not specified. */
|
|
32
|
+
min_volume?: number;
|
|
33
|
+
/** Maximum silence duration in seconds. Default: not specified. */
|
|
34
|
+
max_silence_duration_secs?: number;
|
|
35
|
+
}
|
|
36
|
+
interface AssemblyAIOptions {
|
|
37
|
+
/** Enable turn formatting. Default: false. */
|
|
38
|
+
format_turns?: boolean;
|
|
39
|
+
/** End of turn confidence threshold. Default: 0.01. */
|
|
40
|
+
end_of_turn_confidence_threshold?: number;
|
|
41
|
+
/** Minimum silence duration in milliseconds when confident about end of turn. Default: 0. */
|
|
42
|
+
min_end_of_turn_silence_when_confident?: number;
|
|
43
|
+
/** Maximum turn silence in milliseconds. Default: not specified. */
|
|
44
|
+
max_turn_silence?: number;
|
|
45
|
+
/** Key terms prompt for recognition. Default: not specified. */
|
|
46
|
+
keyterms_prompt?: string[];
|
|
47
|
+
}
|
|
48
|
+
type STTModels = _STTModels | "auto";
|
|
49
|
+
type STTOptions<TModel extends STTModels> = TModel extends DeepgramModels ? DeepgramOptions : TModel extends CartesiaModels ? CartesiaOptions : TModel extends AssemblyaiModels ? AssemblyAIOptions : Record<string, unknown>;
|
|
50
|
+
interface STTFallbackModel {
|
|
51
|
+
/** Model name (e.g. "deepgram/nova-3", "assemblyai/universal-streaming", "cartesia/ink-whisper"). */
|
|
52
|
+
model: string;
|
|
53
|
+
/** Extra configuration for the model. */
|
|
54
|
+
extraKwargs?: Record<string, unknown>;
|
|
55
|
+
}
|
|
56
|
+
interface APIConnectOptions {
|
|
57
|
+
/** Maximum number of retries to connect to the API. Default: 3 */
|
|
58
|
+
maxRetry: number;
|
|
59
|
+
/** Interval between retries to connect to the API in milliseconds. Default: 2000 */
|
|
60
|
+
retryIntervalMs: number;
|
|
61
|
+
/** Timeout for connecting to the API in milliseconds. Default: 10000 */
|
|
62
|
+
timeoutMs: number;
|
|
63
|
+
}
|
|
64
|
+
interface InferenceSTTOptions<TModel extends STTModels> {
|
|
65
|
+
model?: TModel;
|
|
66
|
+
language?: STTLanguages;
|
|
67
|
+
encoding: STTEncoding;
|
|
68
|
+
sampleRate: number;
|
|
69
|
+
baseURL: string;
|
|
70
|
+
apiKey: string;
|
|
71
|
+
apiSecret: string;
|
|
72
|
+
modelOptions: STTOptions<TModel>;
|
|
73
|
+
fallback?: STTFallbackModel[];
|
|
74
|
+
connOptions?: APIConnectOptions;
|
|
75
|
+
}
|
|
76
|
+
type TTSEncoding = "pcm_s16le";
|
|
77
|
+
type CartesiaTTSModels = "cartesia/sonic-3" | "cartesia/sonic-2" | "cartesia/sonic-turbo" | "cartesia/sonic";
|
|
78
|
+
type DeepgramTTSModels = "deepgram/aura" | "deepgram/aura-2";
|
|
79
|
+
type ElevenlabsTTSModels = "elevenlabs/eleven_flash_v2" | "elevenlabs/eleven_flash_v2_5" | "elevenlabs/eleven_turbo_v2" | "elevenlabs/eleven_turbo_v2_5" | "elevenlabs/eleven_multilingual_v2";
|
|
80
|
+
type InworldModels = "inworld/inworld-tts-1.5-max" | "inworld/inworld-tts-1.5-mini" | "inworld/inworld-tts-1-max" | "inworld/inworld-tts-1";
|
|
81
|
+
type RimeModels = "rime/arcana" | "rime/mistv2";
|
|
82
|
+
type _TTSModels = CartesiaTTSModels | DeepgramTTSModels | ElevenlabsTTSModels | RimeModels | InworldModels;
|
|
83
|
+
type TTSModels = _TTSModels;
|
|
84
|
+
interface CartesiaTTSOptions {
|
|
85
|
+
/** Maximum duration of audio in seconds. */
|
|
86
|
+
duration?: number;
|
|
87
|
+
/** Speech speed. Default: not specified. */
|
|
88
|
+
speed?: "slow" | "normal" | "fast";
|
|
89
|
+
}
|
|
90
|
+
interface ElevenlabsTTSOptions {
|
|
91
|
+
/** Inactivity timeout in seconds. Default: 60. */
|
|
92
|
+
inactivity_timeout?: number;
|
|
93
|
+
/** Text normalization mode. Default: "auto". */
|
|
94
|
+
apply_text_normalization?: "auto" | "off" | "on";
|
|
95
|
+
}
|
|
96
|
+
interface DeepgramTTSOptions {
|
|
97
|
+
}
|
|
98
|
+
interface RimeTTSOptions {
|
|
99
|
+
}
|
|
100
|
+
interface InworldTTSOptions {
|
|
101
|
+
}
|
|
102
|
+
type TTSOptions<TModel extends TTSModels> = TModel extends CartesiaTTSModels ? CartesiaTTSOptions : TModel extends DeepgramTTSModels ? DeepgramTTSOptions : TModel extends ElevenlabsTTSModels ? ElevenlabsTTSOptions : TModel extends RimeModels ? RimeTTSOptions : TModel extends InworldModels ? InworldTTSOptions : Record<string, unknown>;
|
|
103
|
+
interface TTSFallbackModel {
|
|
104
|
+
/** Model name (e.g. "cartesia/sonic", "elevenlabs/eleven_flash_v2", "rime/arcana"). */
|
|
105
|
+
model: string;
|
|
106
|
+
/** Voice to use for the model. */
|
|
107
|
+
voice: string;
|
|
108
|
+
/** Extra configuration for the model. */
|
|
109
|
+
extraKwargs?: Record<string, unknown>;
|
|
110
|
+
}
|
|
111
|
+
interface InferenceTTSOptions<TModel extends TTSModels> {
|
|
112
|
+
model?: TModel;
|
|
113
|
+
voice?: string;
|
|
114
|
+
language?: string;
|
|
115
|
+
encoding: TTSEncoding;
|
|
116
|
+
sampleRate: number;
|
|
117
|
+
baseURL: string;
|
|
118
|
+
apiKey: string;
|
|
119
|
+
apiSecret: string;
|
|
120
|
+
modelOptions: TTSOptions<TModel>;
|
|
121
|
+
fallback?: TTSFallbackModel[];
|
|
122
|
+
connOptions?: APIConnectOptions;
|
|
123
|
+
}
|
|
124
|
+
type OpenAIModels = "openai/gpt-5.2" | "openai/gpt-5.2-chat-latest" | "openai/gpt-5.1" | "openai/gpt-5.1-chat-latest" | "openai/gpt-5" | "openai/gpt-5-mini" | "openai/gpt-5-nano" | "openai/gpt-4.1" | "openai/gpt-4.1-mini" | "openai/gpt-4.1-nano" | "openai/gpt-4o" | "openai/gpt-4o-mini" | "openai/gpt-oss-120b";
|
|
125
|
+
type GoogleModels = "google/gemini-3-pro" | "google/gemini-3-flash" | "google/gemini-2.5-pro" | "google/gemini-2.5-flash" | "google/gemini-2.5-flash-lite" | "google/gemini-2.0-flash" | "google/gemini-2.0-flash-lite";
|
|
126
|
+
type MoonshotModels = "moonshotai/kimi-k2-instruct";
|
|
127
|
+
type DeepSeekModels = "deepseek-ai/deepseek-v3" | "deepseek-ai/deepseek-v3.2";
|
|
128
|
+
type LLMModels = OpenAIModels | GoogleModels | MoonshotModels | DeepSeekModels;
|
|
129
|
+
interface ChatCompletionOptions extends Record<string, unknown> {
|
|
130
|
+
frequency_penalty?: number;
|
|
131
|
+
logit_bias?: Record<string, number>;
|
|
132
|
+
logprobs?: boolean;
|
|
133
|
+
max_completion_tokens?: number;
|
|
134
|
+
max_tokens?: number;
|
|
135
|
+
metadata?: Record<string, string>;
|
|
136
|
+
modalities?: Array<"text" | "audio">;
|
|
137
|
+
n?: number;
|
|
138
|
+
parallel_tool_calls?: boolean;
|
|
139
|
+
presence_penalty?: number;
|
|
140
|
+
prompt_cache_key?: string;
|
|
141
|
+
reasoning_effort?: "minimal" | "low" | "medium" | "high";
|
|
142
|
+
safety_identifier?: string;
|
|
143
|
+
seed?: number;
|
|
144
|
+
service_tier?: "auto" | "default" | "flex" | "scale" | "priority";
|
|
145
|
+
stop?: string | string[];
|
|
146
|
+
store?: boolean;
|
|
147
|
+
temperature?: number;
|
|
148
|
+
top_logprobs?: number;
|
|
149
|
+
top_p?: number;
|
|
150
|
+
user?: string;
|
|
151
|
+
verbosity?: "low" | "medium" | "high";
|
|
152
|
+
}
|
|
153
|
+
interface InferenceLLMOptions {
|
|
154
|
+
model: LLMModels;
|
|
155
|
+
provider?: string;
|
|
156
|
+
baseURL: string;
|
|
157
|
+
apiKey: string;
|
|
158
|
+
apiSecret: string;
|
|
159
|
+
modelOptions: ChatCompletionOptions;
|
|
160
|
+
strictToolSchema?: boolean;
|
|
161
|
+
}
|
|
162
|
+
interface SahabAgentsOptions {
|
|
163
|
+
/** Sahab API key — used to authenticate with the Sahab backend */
|
|
164
|
+
apiKey: string;
|
|
165
|
+
stt: InferenceSTTOptions<STTModels>;
|
|
166
|
+
tts: InferenceTTSOptions<TTSModels>;
|
|
167
|
+
llm: InferenceLLMOptions;
|
|
168
|
+
/** Optional extra headers merged into every request */
|
|
169
|
+
headers?: Record<string, string>;
|
|
170
|
+
/** Request timeout in milliseconds (default: 30_000) */
|
|
171
|
+
timeout?: number;
|
|
172
|
+
}
|
|
173
|
+
interface LiveKitConfig {
|
|
174
|
+
id: string;
|
|
175
|
+
url: string;
|
|
176
|
+
apiKey: string;
|
|
177
|
+
apiSecret: string;
|
|
178
|
+
}
|
|
179
|
+
interface ApiErrorBody {
|
|
180
|
+
message: string;
|
|
181
|
+
code?: string;
|
|
182
|
+
details?: unknown;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export type { ApiErrorBody as A, LiveKitConfig as L, SahabAgentsOptions as S };
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
type STTEncoding = "pcm_s16le";
|
|
2
|
+
type STTLanguages = "multi" | "en" | "de" | "es" | "fr" | "ja" | "pt" | "zh" | "hi";
|
|
3
|
+
type DeepgramModels = "deepgram/flux-general" | "deepgram/nova-3" | "deepgram/nova-3-medical" | "deepgram/nova-2" | "deepgram/nova-2-medical" | "deepgram/nova-2-conversationalai" | "deepgram/nova-2-phonecall";
|
|
4
|
+
type CartesiaModels = "cartesia/ink-whisper";
|
|
5
|
+
type AssemblyaiModels = "assemblyai/universal-streaming" | "assemblyai/universal-streaming-multilingual";
|
|
6
|
+
type ElevenlabsSTTModels = "elevenlabs/scribe_v2_realtime";
|
|
7
|
+
type _STTModels = DeepgramModels | CartesiaModels | AssemblyaiModels | ElevenlabsSTTModels;
|
|
8
|
+
interface DeepgramOptions {
|
|
9
|
+
/** Enable filler words. Default: true. */
|
|
10
|
+
filler_words?: boolean;
|
|
11
|
+
/** Enable interim results. Default: true. */
|
|
12
|
+
interim_results?: boolean;
|
|
13
|
+
/** Endpointing timeout in milliseconds. Default: 25. */
|
|
14
|
+
endpointing?: number;
|
|
15
|
+
/** Enable punctuation. Default: false. */
|
|
16
|
+
punctuate?: boolean;
|
|
17
|
+
/** Enable smart formatting. */
|
|
18
|
+
smart_format?: boolean;
|
|
19
|
+
/** Keywords with boost values. */
|
|
20
|
+
keywords?: Array<[string, number]>;
|
|
21
|
+
/** Key terms for recognition. */
|
|
22
|
+
keyterms?: string[];
|
|
23
|
+
/** Enable profanity filter. */
|
|
24
|
+
profanity_filter?: boolean;
|
|
25
|
+
/** Convert spoken numbers to numerals. */
|
|
26
|
+
numerals?: boolean;
|
|
27
|
+
/** Opt out of model improvement program. */
|
|
28
|
+
mip_opt_out?: boolean;
|
|
29
|
+
}
|
|
30
|
+
interface CartesiaOptions {
|
|
31
|
+
/** Minimum volume threshold. Default: not specified. */
|
|
32
|
+
min_volume?: number;
|
|
33
|
+
/** Maximum silence duration in seconds. Default: not specified. */
|
|
34
|
+
max_silence_duration_secs?: number;
|
|
35
|
+
}
|
|
36
|
+
interface AssemblyAIOptions {
|
|
37
|
+
/** Enable turn formatting. Default: false. */
|
|
38
|
+
format_turns?: boolean;
|
|
39
|
+
/** End of turn confidence threshold. Default: 0.01. */
|
|
40
|
+
end_of_turn_confidence_threshold?: number;
|
|
41
|
+
/** Minimum silence duration in milliseconds when confident about end of turn. Default: 0. */
|
|
42
|
+
min_end_of_turn_silence_when_confident?: number;
|
|
43
|
+
/** Maximum turn silence in milliseconds. Default: not specified. */
|
|
44
|
+
max_turn_silence?: number;
|
|
45
|
+
/** Key terms prompt for recognition. Default: not specified. */
|
|
46
|
+
keyterms_prompt?: string[];
|
|
47
|
+
}
|
|
48
|
+
type STTModels = _STTModels | "auto";
|
|
49
|
+
type STTOptions<TModel extends STTModels> = TModel extends DeepgramModels ? DeepgramOptions : TModel extends CartesiaModels ? CartesiaOptions : TModel extends AssemblyaiModels ? AssemblyAIOptions : Record<string, unknown>;
|
|
50
|
+
interface STTFallbackModel {
|
|
51
|
+
/** Model name (e.g. "deepgram/nova-3", "assemblyai/universal-streaming", "cartesia/ink-whisper"). */
|
|
52
|
+
model: string;
|
|
53
|
+
/** Extra configuration for the model. */
|
|
54
|
+
extraKwargs?: Record<string, unknown>;
|
|
55
|
+
}
|
|
56
|
+
interface APIConnectOptions {
|
|
57
|
+
/** Maximum number of retries to connect to the API. Default: 3 */
|
|
58
|
+
maxRetry: number;
|
|
59
|
+
/** Interval between retries to connect to the API in milliseconds. Default: 2000 */
|
|
60
|
+
retryIntervalMs: number;
|
|
61
|
+
/** Timeout for connecting to the API in milliseconds. Default: 10000 */
|
|
62
|
+
timeoutMs: number;
|
|
63
|
+
}
|
|
64
|
+
interface InferenceSTTOptions<TModel extends STTModels> {
|
|
65
|
+
model?: TModel;
|
|
66
|
+
language?: STTLanguages;
|
|
67
|
+
encoding: STTEncoding;
|
|
68
|
+
sampleRate: number;
|
|
69
|
+
baseURL: string;
|
|
70
|
+
apiKey: string;
|
|
71
|
+
apiSecret: string;
|
|
72
|
+
modelOptions: STTOptions<TModel>;
|
|
73
|
+
fallback?: STTFallbackModel[];
|
|
74
|
+
connOptions?: APIConnectOptions;
|
|
75
|
+
}
|
|
76
|
+
type TTSEncoding = "pcm_s16le";
|
|
77
|
+
type CartesiaTTSModels = "cartesia/sonic-3" | "cartesia/sonic-2" | "cartesia/sonic-turbo" | "cartesia/sonic";
|
|
78
|
+
type DeepgramTTSModels = "deepgram/aura" | "deepgram/aura-2";
|
|
79
|
+
type ElevenlabsTTSModels = "elevenlabs/eleven_flash_v2" | "elevenlabs/eleven_flash_v2_5" | "elevenlabs/eleven_turbo_v2" | "elevenlabs/eleven_turbo_v2_5" | "elevenlabs/eleven_multilingual_v2";
|
|
80
|
+
type InworldModels = "inworld/inworld-tts-1.5-max" | "inworld/inworld-tts-1.5-mini" | "inworld/inworld-tts-1-max" | "inworld/inworld-tts-1";
|
|
81
|
+
type RimeModels = "rime/arcana" | "rime/mistv2";
|
|
82
|
+
type _TTSModels = CartesiaTTSModels | DeepgramTTSModels | ElevenlabsTTSModels | RimeModels | InworldModels;
|
|
83
|
+
type TTSModels = _TTSModels;
|
|
84
|
+
interface CartesiaTTSOptions {
|
|
85
|
+
/** Maximum duration of audio in seconds. */
|
|
86
|
+
duration?: number;
|
|
87
|
+
/** Speech speed. Default: not specified. */
|
|
88
|
+
speed?: "slow" | "normal" | "fast";
|
|
89
|
+
}
|
|
90
|
+
interface ElevenlabsTTSOptions {
|
|
91
|
+
/** Inactivity timeout in seconds. Default: 60. */
|
|
92
|
+
inactivity_timeout?: number;
|
|
93
|
+
/** Text normalization mode. Default: "auto". */
|
|
94
|
+
apply_text_normalization?: "auto" | "off" | "on";
|
|
95
|
+
}
|
|
96
|
+
interface DeepgramTTSOptions {
|
|
97
|
+
}
|
|
98
|
+
interface RimeTTSOptions {
|
|
99
|
+
}
|
|
100
|
+
interface InworldTTSOptions {
|
|
101
|
+
}
|
|
102
|
+
type TTSOptions<TModel extends TTSModels> = TModel extends CartesiaTTSModels ? CartesiaTTSOptions : TModel extends DeepgramTTSModels ? DeepgramTTSOptions : TModel extends ElevenlabsTTSModels ? ElevenlabsTTSOptions : TModel extends RimeModels ? RimeTTSOptions : TModel extends InworldModels ? InworldTTSOptions : Record<string, unknown>;
|
|
103
|
+
interface TTSFallbackModel {
|
|
104
|
+
/** Model name (e.g. "cartesia/sonic", "elevenlabs/eleven_flash_v2", "rime/arcana"). */
|
|
105
|
+
model: string;
|
|
106
|
+
/** Voice to use for the model. */
|
|
107
|
+
voice: string;
|
|
108
|
+
/** Extra configuration for the model. */
|
|
109
|
+
extraKwargs?: Record<string, unknown>;
|
|
110
|
+
}
|
|
111
|
+
interface InferenceTTSOptions<TModel extends TTSModels> {
|
|
112
|
+
model?: TModel;
|
|
113
|
+
voice?: string;
|
|
114
|
+
language?: string;
|
|
115
|
+
encoding: TTSEncoding;
|
|
116
|
+
sampleRate: number;
|
|
117
|
+
baseURL: string;
|
|
118
|
+
apiKey: string;
|
|
119
|
+
apiSecret: string;
|
|
120
|
+
modelOptions: TTSOptions<TModel>;
|
|
121
|
+
fallback?: TTSFallbackModel[];
|
|
122
|
+
connOptions?: APIConnectOptions;
|
|
123
|
+
}
|
|
124
|
+
type OpenAIModels = "openai/gpt-5.2" | "openai/gpt-5.2-chat-latest" | "openai/gpt-5.1" | "openai/gpt-5.1-chat-latest" | "openai/gpt-5" | "openai/gpt-5-mini" | "openai/gpt-5-nano" | "openai/gpt-4.1" | "openai/gpt-4.1-mini" | "openai/gpt-4.1-nano" | "openai/gpt-4o" | "openai/gpt-4o-mini" | "openai/gpt-oss-120b";
|
|
125
|
+
type GoogleModels = "google/gemini-3-pro" | "google/gemini-3-flash" | "google/gemini-2.5-pro" | "google/gemini-2.5-flash" | "google/gemini-2.5-flash-lite" | "google/gemini-2.0-flash" | "google/gemini-2.0-flash-lite";
|
|
126
|
+
type MoonshotModels = "moonshotai/kimi-k2-instruct";
|
|
127
|
+
type DeepSeekModels = "deepseek-ai/deepseek-v3" | "deepseek-ai/deepseek-v3.2";
|
|
128
|
+
type LLMModels = OpenAIModels | GoogleModels | MoonshotModels | DeepSeekModels;
|
|
129
|
+
interface ChatCompletionOptions extends Record<string, unknown> {
|
|
130
|
+
frequency_penalty?: number;
|
|
131
|
+
logit_bias?: Record<string, number>;
|
|
132
|
+
logprobs?: boolean;
|
|
133
|
+
max_completion_tokens?: number;
|
|
134
|
+
max_tokens?: number;
|
|
135
|
+
metadata?: Record<string, string>;
|
|
136
|
+
modalities?: Array<"text" | "audio">;
|
|
137
|
+
n?: number;
|
|
138
|
+
parallel_tool_calls?: boolean;
|
|
139
|
+
presence_penalty?: number;
|
|
140
|
+
prompt_cache_key?: string;
|
|
141
|
+
reasoning_effort?: "minimal" | "low" | "medium" | "high";
|
|
142
|
+
safety_identifier?: string;
|
|
143
|
+
seed?: number;
|
|
144
|
+
service_tier?: "auto" | "default" | "flex" | "scale" | "priority";
|
|
145
|
+
stop?: string | string[];
|
|
146
|
+
store?: boolean;
|
|
147
|
+
temperature?: number;
|
|
148
|
+
top_logprobs?: number;
|
|
149
|
+
top_p?: number;
|
|
150
|
+
user?: string;
|
|
151
|
+
verbosity?: "low" | "medium" | "high";
|
|
152
|
+
}
|
|
153
|
+
interface InferenceLLMOptions {
|
|
154
|
+
model: LLMModels;
|
|
155
|
+
provider?: string;
|
|
156
|
+
baseURL: string;
|
|
157
|
+
apiKey: string;
|
|
158
|
+
apiSecret: string;
|
|
159
|
+
modelOptions: ChatCompletionOptions;
|
|
160
|
+
strictToolSchema?: boolean;
|
|
161
|
+
}
|
|
162
|
+
interface SahabAgentsOptions {
|
|
163
|
+
/** Sahab API key — used to authenticate with the Sahab backend */
|
|
164
|
+
apiKey: string;
|
|
165
|
+
stt: InferenceSTTOptions<STTModels>;
|
|
166
|
+
tts: InferenceTTSOptions<TTSModels>;
|
|
167
|
+
llm: InferenceLLMOptions;
|
|
168
|
+
/** Optional extra headers merged into every request */
|
|
169
|
+
headers?: Record<string, string>;
|
|
170
|
+
/** Request timeout in milliseconds (default: 30_000) */
|
|
171
|
+
timeout?: number;
|
|
172
|
+
}
|
|
173
|
+
interface LiveKitConfig {
|
|
174
|
+
id: string;
|
|
175
|
+
url: string;
|
|
176
|
+
apiKey: string;
|
|
177
|
+
apiSecret: string;
|
|
178
|
+
}
|
|
179
|
+
interface ApiErrorBody {
|
|
180
|
+
message: string;
|
|
181
|
+
code?: string;
|
|
182
|
+
details?: unknown;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export type { ApiErrorBody as A, LiveKitConfig as L, SahabAgentsOptions as S };
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sahab-platform/agents",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "TypeScript SDK for the Sahab Agents API",
|
|
5
|
+
"author": "",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"sahab",
|
|
9
|
+
"agents",
|
|
10
|
+
"sdk",
|
|
11
|
+
"api"
|
|
12
|
+
],
|
|
13
|
+
"main": "./dist/index.js",
|
|
14
|
+
"module": "./dist/index.mjs",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"import": "./dist/index.mjs",
|
|
20
|
+
"require": "./dist/index.js"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"dist"
|
|
25
|
+
],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsup",
|
|
28
|
+
"dev": "tsup --watch",
|
|
29
|
+
"lint": "tsc --noEmit",
|
|
30
|
+
"test:agent": "tsup && node --env-file=.env dist/define-agent.js dev",
|
|
31
|
+
"prepublishOnly": "npm run build"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"tsup": "^8.3.0",
|
|
35
|
+
"typescript": "^5.7.2"
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=18"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@livekit/agents": "^1.0.48",
|
|
42
|
+
"@livekit/agents-plugin-livekit": "^1.0.48",
|
|
43
|
+
"@livekit/agents-plugin-silero": "^1.0.48"
|
|
44
|
+
}
|
|
45
|
+
}
|