@absolutejs/voice 0.0.22-beta.4 → 0.0.22-beta.5

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/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export { createVoiceAssistant, createVoiceExperiment, summarizeVoiceAssistantRun
3
3
  export { createVoiceAgent, createVoiceAgentSquad, createVoiceAgentTool } from './agent';
4
4
  export { createStoredVoiceCallReviewArtifact, createStoredVoiceExternalObjectMap, createStoredVoiceIntegrationEvent, createStoredVoiceOpsTask, createVoiceFileExternalObjectMapStore, createVoiceFileAssistantMemoryStore, createVoiceFileIntegrationEventStore, createVoiceFileReviewStore, createVoiceFileRuntimeStorage, createVoiceFileSessionStore, createVoiceFileTaskStore, createVoiceFileTraceSinkDeliveryStore, createVoiceFileTraceEventStore } from './fileStore';
5
5
  export { createVoiceAssistantMemoryHandle, createVoiceAssistantMemoryRecord, createVoiceMemoryAssistantMemoryStore, resolveVoiceAssistantMemoryNamespace } from './assistantMemory';
6
+ export { createJSONVoiceAssistantModel, createOpenAIVoiceAssistantModel } from './modelAdapters';
6
7
  export { buildVoiceTraceReplay, createVoiceMemoryTraceSinkDeliveryStore, createVoiceTraceHTTPSink, createVoiceMemoryTraceEventStore, createVoiceTraceSinkDeliveryId, createVoiceTraceSinkDeliveryRecord, createVoiceTraceSinkStore, createVoiceTraceEvent, createVoiceTraceEventId, deliverVoiceTraceEventsToSinks, evaluateVoiceTrace, exportVoiceTrace, filterVoiceTraceEvents, pruneVoiceTraceEvents, redactVoiceTraceEvent, redactVoiceTraceEvents, redactVoiceTraceText, renderVoiceTraceHTML, renderVoiceTraceMarkdown, resolveVoiceTraceRedactionOptions, selectVoiceTraceEventsForPrune, summarizeVoiceTrace } from './trace';
7
8
  export { createVoiceSQLiteExternalObjectMapStore, createVoiceSQLiteIntegrationEventStore, createVoiceSQLiteReviewStore, createVoiceSQLiteRuntimeStorage, createVoiceSQLiteSessionStore, createVoiceSQLiteTaskStore, createVoiceSQLiteTraceSinkDeliveryStore, createVoiceSQLiteTraceEventStore } from './sqliteStore';
8
9
  export { createVoicePostgresExternalObjectMapStore, createVoicePostgresIntegrationEventStore, createVoicePostgresReviewStore, createVoicePostgresRuntimeStorage, createVoicePostgresSessionStore, createVoicePostgresTaskStore, createVoicePostgresTraceSinkDeliveryStore, createVoicePostgresTraceEventStore } from './postgresStore';
@@ -25,6 +26,7 @@ export { resolveTurnDetectionConfig, TURN_PROFILE_DEFAULTS } from './turnProfile
25
26
  export { createVoiceCallReviewFromLiveTelephonyReport, createVoiceCallReviewRecorder, renderVoiceCallReviewHTML, renderVoiceCallReviewMarkdown } from './testing/review';
26
27
  export type { VoiceAssistant, VoiceAssistantArtifactPlan, VoiceAssistantExperiment, VoiceAssistantExperimentOptions, VoiceAssistantGuardrailInput, VoiceAssistantGuardrails, VoiceAssistantMemoryLifecycle, VoiceAssistantMemoryLifecycleInput, VoiceAssistantOptions, VoiceAssistantOutputGuardrailInput, VoiceAssistantPreset, VoiceAssistantRunsSummary, VoiceAssistantRunSummary, VoiceAssistantVariant } from './assistant';
27
28
  export type { VoiceAssistantMemoryBinding, VoiceAssistantMemoryHandle, VoiceAssistantMemoryOptions, VoiceAssistantMemoryRecord, VoiceAssistantMemoryStore } from './assistantMemory';
29
+ export type { OpenAIVoiceAssistantModelOptions, VoiceJSONAssistantModelHandler, VoiceJSONAssistantModelOptions } from './modelAdapters';
28
30
  export type { VoiceAgent, VoiceAgentMessage, VoiceAgentMessageRole, VoiceAgentModel, VoiceAgentModelInput, VoiceAgentModelOutput, VoiceAgentOptions, VoiceAgentRunResult, VoiceAgentSquadOptions, VoiceAgentTool, VoiceAgentToolCall, VoiceAgentToolResult } from './agent';
29
31
  export type { VoiceOpsRuntime, VoiceOpsRuntimeConfig, VoiceOpsRuntimeSummary, VoiceOpsRuntimeSinkWorkerConfig, VoiceOpsRuntimeTaskWorkerConfig, VoiceOpsRuntimeTickResult, VoiceOpsRuntimeWebhookWorkerConfig } from './opsRuntime';
30
32
  export type { VoiceOpsPresetName, VoiceOpsPresetOverrides, VoiceResolvedOpsPreset } from './opsPresets';
package/dist/index.js CHANGED
@@ -7073,6 +7073,254 @@ var createStoredVoiceExternalObjectMap = (mapping) => createVoiceExternalObjectM
7073
7073
  sourceId: mapping.sourceId,
7074
7074
  sourceType: mapping.sourceType
7075
7075
  });
7076
+ // src/modelAdapters.ts
7077
+ var OUTPUT_SCHEMA = {
7078
+ additionalProperties: false,
7079
+ properties: {
7080
+ assistantText: {
7081
+ type: "string"
7082
+ },
7083
+ complete: {
7084
+ type: "boolean"
7085
+ },
7086
+ escalate: {
7087
+ additionalProperties: false,
7088
+ properties: {
7089
+ metadata: {
7090
+ additionalProperties: true,
7091
+ type: "object"
7092
+ },
7093
+ reason: {
7094
+ type: "string"
7095
+ }
7096
+ },
7097
+ required: ["reason"],
7098
+ type: "object"
7099
+ },
7100
+ noAnswer: {
7101
+ additionalProperties: false,
7102
+ properties: {
7103
+ metadata: {
7104
+ additionalProperties: true,
7105
+ type: "object"
7106
+ }
7107
+ },
7108
+ type: "object"
7109
+ },
7110
+ result: {
7111
+ additionalProperties: true,
7112
+ type: "object"
7113
+ },
7114
+ transfer: {
7115
+ additionalProperties: false,
7116
+ properties: {
7117
+ metadata: {
7118
+ additionalProperties: true,
7119
+ type: "object"
7120
+ },
7121
+ reason: {
7122
+ type: "string"
7123
+ },
7124
+ target: {
7125
+ type: "string"
7126
+ }
7127
+ },
7128
+ required: ["target"],
7129
+ type: "object"
7130
+ },
7131
+ voicemail: {
7132
+ additionalProperties: false,
7133
+ properties: {
7134
+ metadata: {
7135
+ additionalProperties: true,
7136
+ type: "object"
7137
+ }
7138
+ },
7139
+ type: "object"
7140
+ }
7141
+ },
7142
+ type: "object"
7143
+ };
7144
+ var parseJSON = (value) => {
7145
+ try {
7146
+ const parsed = JSON.parse(value);
7147
+ return parsed && typeof parsed === "object" ? parsed : {};
7148
+ } catch {
7149
+ return {
7150
+ assistantText: value
7151
+ };
7152
+ }
7153
+ };
7154
+ var normalizeRouteOutput = (output) => {
7155
+ const result = {};
7156
+ if (typeof output.assistantText === "string") {
7157
+ result.assistantText = output.assistantText;
7158
+ }
7159
+ if (typeof output.complete === "boolean") {
7160
+ result.complete = output.complete;
7161
+ }
7162
+ if (output.result !== undefined) {
7163
+ result.result = output.result;
7164
+ }
7165
+ if (output.transfer && typeof output.transfer === "object") {
7166
+ const transfer = output.transfer;
7167
+ if (typeof transfer.target === "string") {
7168
+ result.transfer = {
7169
+ metadata: transfer.metadata && typeof transfer.metadata === "object" ? transfer.metadata : undefined,
7170
+ reason: typeof transfer.reason === "string" ? transfer.reason : undefined,
7171
+ target: transfer.target
7172
+ };
7173
+ }
7174
+ }
7175
+ if (output.escalate && typeof output.escalate === "object") {
7176
+ const escalate = output.escalate;
7177
+ if (typeof escalate.reason === "string") {
7178
+ result.escalate = {
7179
+ metadata: escalate.metadata && typeof escalate.metadata === "object" ? escalate.metadata : undefined,
7180
+ reason: escalate.reason
7181
+ };
7182
+ }
7183
+ }
7184
+ if (output.voicemail && typeof output.voicemail === "object") {
7185
+ const voicemail = output.voicemail;
7186
+ result.voicemail = {
7187
+ metadata: voicemail.metadata && typeof voicemail.metadata === "object" ? voicemail.metadata : undefined
7188
+ };
7189
+ }
7190
+ if (output.noAnswer && typeof output.noAnswer === "object") {
7191
+ const noAnswer = output.noAnswer;
7192
+ result.noAnswer = {
7193
+ metadata: noAnswer.metadata && typeof noAnswer.metadata === "object" ? noAnswer.metadata : undefined
7194
+ };
7195
+ }
7196
+ return result;
7197
+ };
7198
+ var createJSONVoiceAssistantModel = (options) => ({
7199
+ generate: async (input) => {
7200
+ const output = await options.generate(input);
7201
+ if ("assistantText" in output || "toolCalls" in output || "complete" in output || "transfer" in output || "escalate" in output) {
7202
+ return output;
7203
+ }
7204
+ return options.mapOutput?.(output) ?? normalizeRouteOutput(output);
7205
+ }
7206
+ });
7207
+ var messageToOpenAIInput = (message) => {
7208
+ if (message.role === "tool") {
7209
+ return {
7210
+ call_id: message.toolCallId ?? message.name ?? crypto.randomUUID(),
7211
+ output: message.content,
7212
+ type: "function_call_output"
7213
+ };
7214
+ }
7215
+ return {
7216
+ content: message.content,
7217
+ role: message.role === "system" ? "developer" : message.role
7218
+ };
7219
+ };
7220
+ var extractText = (response) => {
7221
+ if (typeof response.output_text === "string") {
7222
+ return response.output_text;
7223
+ }
7224
+ const output = Array.isArray(response.output) ? response.output : [];
7225
+ for (const item of output) {
7226
+ if (!item || typeof item !== "object") {
7227
+ continue;
7228
+ }
7229
+ const record = item;
7230
+ const content = Array.isArray(record.content) ? record.content : [];
7231
+ for (const contentItem of content) {
7232
+ if (!contentItem || typeof contentItem !== "object") {
7233
+ continue;
7234
+ }
7235
+ const contentRecord = contentItem;
7236
+ if (typeof contentRecord.text === "string") {
7237
+ return contentRecord.text;
7238
+ }
7239
+ }
7240
+ }
7241
+ return "";
7242
+ };
7243
+ var extractToolCalls = (response) => {
7244
+ const output = Array.isArray(response.output) ? response.output : [];
7245
+ const toolCalls = [];
7246
+ for (const item of output) {
7247
+ if (!item || typeof item !== "object") {
7248
+ continue;
7249
+ }
7250
+ const record = item;
7251
+ if (record.type !== "function_call" || typeof record.name !== "string") {
7252
+ continue;
7253
+ }
7254
+ const args = typeof record.arguments === "string" ? parseJSON(record.arguments) : {};
7255
+ toolCalls.push({
7256
+ args,
7257
+ id: typeof record.call_id === "string" ? record.call_id : typeof record.id === "string" ? record.id : undefined,
7258
+ name: record.name
7259
+ });
7260
+ }
7261
+ return toolCalls;
7262
+ };
7263
+ var createOpenAIVoiceAssistantModel = (options) => {
7264
+ const fetchImpl = options.fetch ?? globalThis.fetch;
7265
+ const baseUrl = options.baseUrl ?? "https://api.openai.com/v1";
7266
+ const model = options.model ?? "gpt-4.1-mini";
7267
+ return {
7268
+ generate: async (input) => {
7269
+ const response = await fetchImpl(`${baseUrl.replace(/\/$/, "")}/responses`, {
7270
+ body: JSON.stringify({
7271
+ input: input.messages.map(messageToOpenAIInput),
7272
+ instructions: [
7273
+ input.system,
7274
+ "Return a JSON object with assistantText, complete, transfer, escalate, voicemail, noAnswer, and result when you are not calling tools."
7275
+ ].filter(Boolean).join(`
7276
+
7277
+ `),
7278
+ max_output_tokens: options.maxOutputTokens,
7279
+ model,
7280
+ temperature: options.temperature,
7281
+ text: {
7282
+ format: {
7283
+ name: "voice_route_result",
7284
+ schema: OUTPUT_SCHEMA,
7285
+ strict: false,
7286
+ type: "json_schema"
7287
+ }
7288
+ },
7289
+ tool_choice: input.tools.length ? "auto" : "none",
7290
+ tools: input.tools.map((tool) => ({
7291
+ description: tool.description,
7292
+ name: tool.name,
7293
+ parameters: tool.parameters ?? {
7294
+ additionalProperties: true,
7295
+ type: "object"
7296
+ },
7297
+ strict: false,
7298
+ type: "function"
7299
+ }))
7300
+ }),
7301
+ headers: {
7302
+ authorization: `Bearer ${options.apiKey}`,
7303
+ "content-type": "application/json"
7304
+ },
7305
+ method: "POST"
7306
+ });
7307
+ if (!response.ok) {
7308
+ throw new Error(`OpenAI voice assistant model failed: HTTP ${response.status}`);
7309
+ }
7310
+ const body = await response.json();
7311
+ if (body.usage && typeof body.usage === "object") {
7312
+ await options.onUsage?.(body.usage);
7313
+ }
7314
+ const toolCalls = extractToolCalls(body);
7315
+ if (toolCalls.length) {
7316
+ return {
7317
+ toolCalls
7318
+ };
7319
+ }
7320
+ return normalizeRouteOutput(parseJSON(extractText(body)));
7321
+ }
7322
+ };
7323
+ };
7076
7324
  // src/sqliteStore.ts
7077
7325
  import { Database } from "bun:sqlite";
7078
7326
  var normalizeTableNameSegment = (value) => value.trim().replace(/[^a-zA-Z0-9_]+/g, "_").replace(/^_+|_+$/g, "") || "voice";
@@ -9658,6 +9906,8 @@ export {
9658
9906
  createStoredVoiceCallReviewArtifact,
9659
9907
  createRiskyTurnCorrectionHandler,
9660
9908
  createPhraseHintCorrectionHandler,
9909
+ createOpenAIVoiceAssistantModel,
9910
+ createJSONVoiceAssistantModel,
9661
9911
  createId,
9662
9912
  createDomainPhraseHints,
9663
9913
  createDomainLexicon,
@@ -0,0 +1,18 @@
1
+ import type { VoiceAgentModel, VoiceAgentModelInput, VoiceAgentModelOutput } from './agent';
2
+ import type { VoiceSessionRecord } from './types';
3
+ export type VoiceJSONAssistantModelHandler<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = (input: VoiceAgentModelInput<TContext, TSession>) => Promise<Record<string, unknown> | VoiceAgentModelOutput<TResult>> | Record<string, unknown> | VoiceAgentModelOutput<TResult>;
4
+ export type VoiceJSONAssistantModelOptions<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = {
5
+ generate: VoiceJSONAssistantModelHandler<TContext, TSession, TResult>;
6
+ mapOutput?: (output: Record<string, unknown>) => VoiceAgentModelOutput<TResult>;
7
+ };
8
+ export type OpenAIVoiceAssistantModelOptions = {
9
+ apiKey: string;
10
+ baseUrl?: string;
11
+ fetch?: typeof fetch;
12
+ maxOutputTokens?: number;
13
+ model?: string;
14
+ onUsage?: (usage: Record<string, unknown>) => Promise<void> | void;
15
+ temperature?: number;
16
+ };
17
+ export declare const createJSONVoiceAssistantModel: <TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown>(options: VoiceJSONAssistantModelOptions<TContext, TSession, TResult>) => VoiceAgentModel<TContext, TSession, TResult>;
18
+ export declare const createOpenAIVoiceAssistantModel: <TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown>(options: OpenAIVoiceAssistantModelOptions) => VoiceAgentModel<TContext, TSession, TResult>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.4",
3
+ "version": "0.0.22-beta.5",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",