@kivox/client 0.1.0-beta.16 → 0.1.0-beta.18
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 +3 -3
- package/dist/index.d.ts +43 -25
- package/dist/index.js +1 -1
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Kivox JavaScript client
|
|
2
2
|
|
|
3
|
-
`@kivox/client` is the official JavaScript/TypeScript client for interacting with
|
|
3
|
+
`@kivox/client` is the official JavaScript/TypeScript client for interacting with Kivox. It provides the necessary abstractions and bindings to handle sessions, real-time events, audio, and communication with agents.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- Unified client for the
|
|
7
|
+
- Unified client for the Kivox API
|
|
8
8
|
- Conversation and voice session management
|
|
9
9
|
- WebSockets, events, and real-time state
|
|
10
10
|
- Audio recording and playback
|
package/dist/index.d.ts
CHANGED
|
@@ -68,8 +68,8 @@ type Agent = {
|
|
|
68
68
|
id: string
|
|
69
69
|
template_id: string
|
|
70
70
|
config: AgentConfig
|
|
71
|
-
blueprint: AgentBlueprint
|
|
72
71
|
variables: AgentVariable[]
|
|
72
|
+
ork_source: string
|
|
73
73
|
status: AgentStatus
|
|
74
74
|
created_at: Date
|
|
75
75
|
updated_at: Date
|
|
@@ -83,13 +83,6 @@ type AgentConfig = {
|
|
|
83
83
|
max_silence_timeout_seconds: number
|
|
84
84
|
allow_interruptions: boolean
|
|
85
85
|
};
|
|
86
|
-
type AgentBlueprint<
|
|
87
|
-
NodeType = unknown,
|
|
88
|
-
EdgeType = unknown
|
|
89
|
-
> = {
|
|
90
|
-
nodes: NodeType[]
|
|
91
|
-
edges: EdgeType[]
|
|
92
|
-
};
|
|
93
86
|
type AgentVariable = {
|
|
94
87
|
key: string
|
|
95
88
|
value: string
|
|
@@ -97,8 +90,12 @@ type AgentVariable = {
|
|
|
97
90
|
is_secret: boolean
|
|
98
91
|
description: string
|
|
99
92
|
};
|
|
100
|
-
type AgentCreate = Partial<Pick<Agent, "config" | "
|
|
101
|
-
type AgentUpdate = Partial<Pick<AgentCreate, "config" | "
|
|
93
|
+
type AgentCreate = Partial<Pick<Agent, "config" | "variables" | "ork_source" | "status" | "template_id">>;
|
|
94
|
+
type AgentUpdate = Partial<Pick<AgentCreate, "config" | "variables" | "ork_source">>;
|
|
95
|
+
type AgentCompilationDiagnostic = {
|
|
96
|
+
errors: string[]
|
|
97
|
+
warnings: string[]
|
|
98
|
+
};
|
|
102
99
|
/**
|
|
103
100
|
* Configuration for listing agents.
|
|
104
101
|
*/
|
|
@@ -111,7 +108,7 @@ type AgentListParams = {
|
|
|
111
108
|
search?: string
|
|
112
109
|
};
|
|
113
110
|
/**
|
|
114
|
-
* Client for interacting with
|
|
111
|
+
* Client for interacting with Kivox agents.
|
|
115
112
|
*
|
|
116
113
|
* @example
|
|
117
114
|
* ```ts
|
|
@@ -200,6 +197,14 @@ declare class AgentClient {
|
|
|
200
197
|
*/
|
|
201
198
|
delete(id: string): Promise<Agent>;
|
|
202
199
|
/**
|
|
200
|
+
* Compiles the Ork source code of an agent.
|
|
201
|
+
*
|
|
202
|
+
* @param id Agent ID
|
|
203
|
+
* @param orkSource Updated Ork source code. If not provided, the current Ork source code is used.
|
|
204
|
+
* @returns Compiled agent
|
|
205
|
+
*/
|
|
206
|
+
compile(id: string, orkSource?: string): Promise<AgentCompilationDiagnostic>;
|
|
207
|
+
/**
|
|
203
208
|
* Parses a list of agents with stringified config and blueprint fields.
|
|
204
209
|
*
|
|
205
210
|
* @returns List of parsed agents.
|
|
@@ -325,6 +330,7 @@ type ServerAudioDelta = {
|
|
|
325
330
|
*/
|
|
326
331
|
type ServerTurnComplete = {
|
|
327
332
|
type: "turn_complete"
|
|
333
|
+
stats: UsageStats
|
|
328
334
|
};
|
|
329
335
|
/**
|
|
330
336
|
* Signals that the conversation flow reached its exit node.
|
|
@@ -332,6 +338,7 @@ type ServerTurnComplete = {
|
|
|
332
338
|
*/
|
|
333
339
|
type ServerFlowComplete = {
|
|
334
340
|
type: "flow_complete"
|
|
341
|
+
stats: UsageStats
|
|
335
342
|
};
|
|
336
343
|
/**
|
|
337
344
|
* Represents a non-fatal execution or protocol error.
|
|
@@ -357,7 +364,19 @@ type ServerTick = {
|
|
|
357
364
|
*/
|
|
358
365
|
type ServerSessionClosed = {
|
|
359
366
|
type: "session_closed"
|
|
360
|
-
reason:
|
|
367
|
+
reason: string
|
|
368
|
+
stats: UsageStats
|
|
369
|
+
};
|
|
370
|
+
/**
|
|
371
|
+
* Snapshot of runtime resource consumption.
|
|
372
|
+
*/
|
|
373
|
+
type UsageStats = {
|
|
374
|
+
http_calls: number
|
|
375
|
+
http_limit: number
|
|
376
|
+
llm_calls: number
|
|
377
|
+
llm_limit: number
|
|
378
|
+
steps: number
|
|
379
|
+
steps_limit: number
|
|
361
380
|
};
|
|
362
381
|
/**
|
|
363
382
|
* Union type for all messages sent from the server to the client.
|
|
@@ -458,7 +477,7 @@ type ConversationSessionConfig = {
|
|
|
458
477
|
onEvent?: (event: ServerSessionEvent) => void
|
|
459
478
|
};
|
|
460
479
|
/**
|
|
461
|
-
* Represents an active, real-time conversation session with a
|
|
480
|
+
* Represents an active, real-time conversation session with a Kivox agent.
|
|
462
481
|
* Provides methods to dispatch user inputs and lifecycle commands, as well as tracking basic session state.
|
|
463
482
|
*/
|
|
464
483
|
declare class ConversationSession {
|
|
@@ -567,7 +586,7 @@ type ConversationConnectParams = ConversationSessionConfig & {
|
|
|
567
586
|
*
|
|
568
587
|
* @example
|
|
569
588
|
* ```ts
|
|
570
|
-
* // Connect to a
|
|
589
|
+
* // Connect to a Kivox agent
|
|
571
590
|
* const session = await kivox.conversations.connect({
|
|
572
591
|
* agentId: 'agent-123',
|
|
573
592
|
* onEvent: (event) => {
|
|
@@ -666,11 +685,11 @@ type Template = {
|
|
|
666
685
|
id: string
|
|
667
686
|
name: string
|
|
668
687
|
description?: string
|
|
669
|
-
|
|
688
|
+
ork_source: string
|
|
670
689
|
created_at: Date
|
|
671
690
|
updated_at: Date
|
|
672
691
|
};
|
|
673
|
-
type TemplateCreate = Pick<Template, "name" | "description" | "
|
|
692
|
+
type TemplateCreate = Pick<Template, "name" | "description" | "ork_source">;
|
|
674
693
|
type TemplateUpdate = Partial<TemplateCreate>;
|
|
675
694
|
/**
|
|
676
695
|
* Configuration for listing templates.
|
|
@@ -682,7 +701,7 @@ type TemplateListParams = {
|
|
|
682
701
|
page?: number
|
|
683
702
|
};
|
|
684
703
|
/**
|
|
685
|
-
* Client for interacting with
|
|
704
|
+
* Client for interacting with Kivox templates.
|
|
686
705
|
*
|
|
687
706
|
* @example
|
|
688
707
|
* ```ts
|
|
@@ -730,11 +749,11 @@ declare class TemplateClient {
|
|
|
730
749
|
delete(id: string): Promise<void>;
|
|
731
750
|
}
|
|
732
751
|
/**
|
|
733
|
-
* Configuration for the
|
|
752
|
+
* Configuration for the Kivox client.
|
|
734
753
|
*/
|
|
735
754
|
type KivoxConfig = {
|
|
736
755
|
/**
|
|
737
|
-
* Base URL of your self-hosted
|
|
756
|
+
* Base URL of your self-hosted Kivox instance.
|
|
738
757
|
* @example 'http://localhost:8787'
|
|
739
758
|
* @example 'https://api.kivox.io'
|
|
740
759
|
*/
|
|
@@ -746,8 +765,8 @@ type KivoxConfig = {
|
|
|
746
765
|
headers?: Record<string, string>
|
|
747
766
|
};
|
|
748
767
|
/**
|
|
749
|
-
* Main
|
|
750
|
-
* Provides unified access to all
|
|
768
|
+
* Main Kivox client.
|
|
769
|
+
* Provides unified access to all Kivox resources.
|
|
751
770
|
*
|
|
752
771
|
* @example
|
|
753
772
|
* ```ts
|
|
@@ -780,18 +799,17 @@ declare class KivoxClient {
|
|
|
780
799
|
readonly messages: MessageClient;
|
|
781
800
|
constructor(config: KivoxConfig);
|
|
782
801
|
}
|
|
783
|
-
import { AgentBlueprint as AgentBlueprint2, AgentConfig as AgentConfig2, AgentVariable as AgentVariable2 } from "@kivox/client";
|
|
784
802
|
declare const REGEX_VARIABLE: RegExp;
|
|
785
803
|
/**
|
|
786
804
|
* Extracts all variable references from config and blueprint.
|
|
787
805
|
*/
|
|
788
|
-
declare function extractAllVariables(config:
|
|
806
|
+
declare function extractAllVariables(config: AgentConfig): string[];
|
|
789
807
|
/**
|
|
790
808
|
* Replaces variable references with their values
|
|
791
809
|
*/
|
|
792
|
-
declare function interpolateVariables(text: string, variables:
|
|
810
|
+
declare function interpolateVariables(text: string, variables: AgentVariable[]): string;
|
|
793
811
|
/**
|
|
794
812
|
* Checks if a string contains any variable references.
|
|
795
813
|
*/
|
|
796
814
|
declare function hasVariables(text: string): boolean;
|
|
797
|
-
export { interpolateVariables, hasVariables, extractAllVariables, TemplateUpdate, TemplateCreate, Template, SessionConnectionLostEvent, ServerTurnComplete, ServerTick, ServerTextFull, ServerTextDelta, ServerSessionEvent, ServerSessionClosed, ServerMessage, ServerHandshakeOK, ServerHandshakeError, ServerFlowComplete, ServerError, ServerConnectionMessage, ServerAudioDelta, REGEX_VARIABLE, Paginated, MessageRole, Message, KivoxConfig, KivoxClient, HttpTransportError, ConversationTransportError, ConversationSessionConfig, ConversationSession, Conversation, ClientMessage, ClientInputText, ClientInputAudioStream, ClientInputAudio, ClientHandshake, ClientEndSession, ClientCancel, AgentVariable, AgentUpdate, AgentStatus, AgentCreate, AgentConfig,
|
|
815
|
+
export { interpolateVariables, hasVariables, extractAllVariables, UsageStats, TemplateUpdate, TemplateCreate, Template, SessionConnectionLostEvent, ServerTurnComplete, ServerTick, ServerTextFull, ServerTextDelta, ServerSessionEvent, ServerSessionClosed, ServerMessage, ServerHandshakeOK, ServerHandshakeError, ServerFlowComplete, ServerError, ServerConnectionMessage, ServerAudioDelta, REGEX_VARIABLE, Paginated, MessageRole, Message, KivoxConfig, KivoxClient, HttpTransportError, ConversationTransportError, ConversationSessionConfig, ConversationSession, Conversation, ClientMessage, ClientInputText, ClientInputAudioStream, ClientInputAudio, ClientHandshake, ClientEndSession, ClientCancel, AgentVariable, AgentUpdate, AgentStatus, AgentCreate, AgentConfig, AgentCompilationDiagnostic, Agent };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
class
|
|
1
|
+
class z{http;constructor(_){this.http=_}async list(_={}){let x={limit:(_.limit??10).toString(),page:(_.page??1).toString()};if(_.search)x.search=_.search;let D=await this.http.get("/agents",x);return{...D,items:z.parseAgents(D.items)}}async listLive(_={}){let x={limit:(_.limit??10).toString(),page:(_.page??1).toString()};if(_.search)x.search=_.search;let D=await this.http.get("/agents/live",x);return{...D,items:z.parseAgents(D.items)}}async listDraft(_={}){let x={limit:(_.limit??10).toString(),page:(_.page??1).toString()};if(_.search)x.search=_.search;let D=await this.http.get("/agents/draft",x);return{...D,items:z.parseAgents(D.items)}}async listArchived(_={}){let x={limit:(_.limit??10).toString(),page:(_.page??1).toString()};if(_.search)x.search=_.search;let D=await this.http.get("/agents/archived",x);return{...D,items:z.parseAgents(D.items)}}async get(_){let x=await this.http.get(`/agents/${_}`);return z.parseAgent(x)}async create(_){let x=await this.http.post("/agents",_);return z.parseAgent(x)}async update(_,x){let D=await this.http.put(`/agents/${_}`,x);return z.parseAgent(D)}async markAsLive(_){let x=await this.http.patch(`/agents/${_}/live`);return z.parseAgent(x)}async markAsDraft(_){let x=await this.http.patch(`/agents/${_}/draft`);return z.parseAgent(x)}async markAsArchived(_){let x=await this.http.patch(`/agents/${_}/archived`);return z.parseAgent(x)}async delete(_){let x=await this.http.delete(`/agents/${_}`);return z.parseAgent(x)}async compile(_,x){return await this.http.post(`/agents/${_}/compile`,{ork_source:x})}static parseAgents(_){return _.map(z.parseAgent)}static parseAgent(_){return{..._,config:JSON.parse(_.config),variables:JSON.parse(_.variables)}}}class ${_transport;_conversationId;_closed=!1;_onEvent;_pendingAudioMetadata=null;_remainingMs=0;_elapsedMs=0;get conversationId(){return this._conversationId}get remainingMs(){return this._remainingMs}get elapsedMs(){return this._elapsedMs}get closed(){return this._closed}constructor(_,x,D){this._transport=_,this._conversationId=x,this._onEvent=D.onEvent,this.#_()}sendText(_){if(this._closed){console.warn("Cannot send text: session is closed");return}this._transport.send({type:"input_text",text:_})}sendAudio(_){if(this._closed){console.warn("Cannot send audio: session is closed");return}this._transport.send({type:"input_audio"}),this._transport.sendBinary(_)}streamAudio(_){if(this._closed){console.warn("Cannot stream audio: session is closed");return}this._transport.send({type:"input_audio_stream"}),this._transport.sendBinary(_)}cancelRequest(){if(this._closed){console.warn("Cannot cancel request: session is closed");return}this._transport.send({type:"cancel"})}end(){if(this._closed){console.warn("Cannot end session: session is closed");return}this._transport.send({type:"end"})}close(){if(this._closed)return;this._closed=!0,this._transport.close()}#_(){this._transport.onMessage((_)=>{let x=_;if(x.type==="audio_delta"){this._pendingAudioMetadata={size:x.size};return}if(x.type==="tick")this._remainingMs=x.remaining_ms,this._elapsedMs=x.elapsed_ms;if(x.type==="session_closed")this._closed=!0;this._onEvent?.(x)}),this._transport.onBinary((_)=>{if(this._pendingAudioMetadata){let x={type:"audio_delta",size:this._pendingAudioMetadata.size,audio:_};this._pendingAudioMetadata=null,this._onEvent?.(x)}}),this._transport.onClose(()=>{if(this._closed)return;this._closed=!0,this._onEvent?.({type:"connection_lost",reason:"socket_closed"})}),this._transport.onError(()=>{if(this._closed)return;this._closed=!0,this._onEvent?.({type:"connection_lost",reason:"socket_error"})})}}class Q extends Error{code;constructor(_,x="TRANSPORT_ERROR"){super(_);this.code=x;this.name="ConversationTransportError"}}class N{_ws;_closed=!1;_onMessage=null;_onBinary=null;_onError=null;_onClose=null;constructor(_){this._ws=_}async connect(){if(this._ws.readyState===WebSocket.OPEN)throw new Q("Already connected","ALREADY_CONNECTED");if(this._ws.readyState===WebSocket.CLOSING||this._ws.readyState===WebSocket.CLOSED)throw new Q("Socket is closing or closed","SOCKET_CLOSED");return new Promise((_,x)=>{let D=()=>{this._ws.removeEventListener("open",D),this._ws.removeEventListener("error",K),this.#_(),_()},K=()=>{this._ws.removeEventListener("open",D),this._ws.removeEventListener("error",K),x(new Q("Connection failed","CONNECTION_FAILED"))};this._ws.addEventListener("open",D),this._ws.addEventListener("error",K)})}send(_){if(this._ws.readyState!==WebSocket.OPEN)throw new Q("Not connected","NOT_CONNECTED");this._ws.send(JSON.stringify(_))}async sendBinary(_){if(this._ws.readyState!==WebSocket.OPEN)throw new Q("Not connected","NOT_CONNECTED");let x=await _.arrayBuffer();this._ws.send(x)}onMessage(_){this._onMessage=_}onBinary(_){this._onBinary=_}onError(_){this._onError=_}onClose(_){this._onClose=_}close(){if(this._closed)return;if(this._closed=!0,this._ws.readyState===WebSocket.OPEN||this._ws.readyState===WebSocket.CONNECTING)this._ws.close();this._onClose?.()}#_(){this._ws.addEventListener("message",(_)=>{if(_.data instanceof Blob)this._onBinary?.(_.data);else if(_.data instanceof ArrayBuffer)this._onBinary?.(new Blob([_.data]));else if(typeof _.data==="string")try{let x=JSON.parse(_.data);this._onMessage?.(x)}catch(x){console.warn("Failed to parse JSON message:",_.data,x)}}),this._ws.addEventListener("error",()=>{if(this._closed)return;this._onError?.(new Q("WebSocket error")),this.close()}),this._ws.addEventListener("close",()=>{if(this._closed)return;this.close()})}}class B{http;ws;constructor(_,x){this.http=_;this.ws=x}async list(_){let x={limit:(_.limit??20).toString(),page:(_.page??1).toString()};return this.http.get(`/agents/${_.agentId}/conversations`,x)}async get(_){return this.http.get(`/conversations/${_}`)}async connect(_){let x=this.ws.connect("/conversations/websocket"),D=new N(x);return await D.connect(),D.send({type:"handshake",agent_id:_.agentId}),new Promise((K,J)=>{let Z=!1;D.onMessage((Y)=>{switch(Y.type){case"handshake_ok":Z=!0,_.onConnection?.(Y),K(new $(D,Y.conversation_id,_));break;case"handshake_error":Z=!0,_.onConnection?.(Y),D.close(),J(Error(`Handshake rejected: ${Y.reason}`));break;default:break}}),D.onError((Y)=>{if(!Z)J(Y)}),D.onClose(()=>{if(!Z)J(Error("WebSocket connection lost during handshake"))})})}}function L(_){let x=new URL(_),D=x.protocol==="https:"?"wss:":"ws:";return{rest:`${x.origin}/v1`,ws:`${D}//${x.host}/v1`}}class M extends Error{status;statusText;body;constructor(_,x,D,K){super(_);this.status=x;this.statusText=D;this.body=K;this.name="HttpTransportError"}}class O{config;constructor(_){this.config=_}async request(_,x){let D=`${this.config.baseUrl}${_}`,K=await fetch(D,{...x,headers:{"Content-Type":"application/json",...this.config.headers,...x?.headers}});if(!K.ok){let J=await K.text();throw new M(`HTTP ${K.status}: ${K.statusText}`,K.status,K.statusText,J)}return K.json()}async get(_,x){let D=new URL(`${this.config.baseUrl}${_}`);if(x){let K=Object.entries(x);for(let[J,Z]of K)D.searchParams.set(J,Z)}return this.request(_+D.search,{method:"GET"})}async post(_,x){return this.request(_,{method:"POST",body:x?JSON.stringify(x):void 0})}async put(_,x){return this.request(_,{method:"PUT",body:x?JSON.stringify(x):void 0})}async patch(_,x){return this.request(_,{method:"PATCH",body:x?JSON.stringify(x):void 0})}async delete(_){return this.request(_,{method:"DELETE"})}}class X{config;constructor(_){this.config=_}connect(_){let x=`${this.config.baseUrl}${_}`;return new WebSocket(x)}}class F{http;constructor(_){this.http=_}async list(_={}){let x={limit:(_.limit??50).toString(),page:(_.page??1).toString()};if(_.conversationId)x.conversation_id=_.conversationId;return this.http.get("/messages",x)}async get(_){return this.http.get(`/messages/${_}`)}}class G{http;constructor(_){this.http=_}async list(_={}){let x={limit:(_.limit??10).toString(),page:(_.page??1).toString()};return this.http.get("/templates",x)}async get(_){return this.http.get(`/templates/${_}`)}async create(_){return this.http.post("/templates",_)}async update(_,x){return this.http.put(`/templates/${_}`,x)}async delete(_){return this.http.delete(`/templates/${_}`)}}class P{agents;conversations;templates;messages;constructor(_){let x=L(_.baseUrl),D=new O({baseUrl:x.rest,headers:_.headers}),K=new X({baseUrl:x.ws,headers:_.headers});this.agents=new z(D),this.templates=new G(D),this.conversations=new B(D,K),this.messages=new F(D)}}var H=/\{\{([a-zA-Z_][a-zA-Z0-9_]*)\}\}/g;function W(_){let x=new Set,D;while((D=H.exec(_))!==null){let K=D[1];if(!K)continue;x.add(K)}return x}function U(_,x){if(typeof _==="string"){let D=W(_);for(let K of D)x.add(K)}else if(Array.isArray(_))for(let D of _)U(D,x);else if(typeof _==="object"&&_!==null){let D=Object.values(_);for(let K of D)U(K,x)}}function h(_){let x=new Set;return U(_,x),Array.from(x).toSorted()}function v(_,x){let D=new Map(x.map((K)=>[K.key,K.value]));return _.replace(H,(K,J)=>{return D.get(J)??K})}function m(_){return H.test(_)}export{v as interpolateVariables,m as hasVariables,h as extractAllVariables,H as REGEX_VARIABLE,P as KivoxClient,M as HttpTransportError,Q as ConversationTransportError,$ as ConversationSession};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kivox/client",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
4
|
-
"description": "JavaScript/TypeScript client for
|
|
3
|
+
"version": "0.1.0-beta.18",
|
|
4
|
+
"description": "JavaScript/TypeScript client for Kivox",
|
|
5
5
|
"homepage": "https://github.com/ekisa-team/kivox#readme",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/ekisa-team/kivox/issues"
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
"email": "ju4n97@proton.me",
|
|
16
16
|
"url": "https://github.com/ju4n97"
|
|
17
17
|
},
|
|
18
|
-
"sideEffects": false,
|
|
19
18
|
"type": "module",
|
|
20
19
|
"exports": {
|
|
21
20
|
".": {
|