@absolutejs/voice 0.0.22-beta.193 → 0.0.22-beta.194
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 +17 -0
- package/dist/agent.d.ts +15 -0
- package/dist/client/index.js +2 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +42 -3
- package/dist/svelte/index.js +2 -0
- package/dist/trace.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1045,6 +1045,19 @@ const frontDesk = createVoiceAgentSquad({
|
|
|
1045
1045
|
id: 'front-desk',
|
|
1046
1046
|
defaultAgentId: 'support',
|
|
1047
1047
|
agents: [supportAgent, billingAgent],
|
|
1048
|
+
contextPolicy: ({ summaryMessage, turn }) => ({
|
|
1049
|
+
messages: [
|
|
1050
|
+
summaryMessage,
|
|
1051
|
+
{
|
|
1052
|
+
content: turn.text,
|
|
1053
|
+
role: 'user'
|
|
1054
|
+
}
|
|
1055
|
+
],
|
|
1056
|
+
metadata: {
|
|
1057
|
+
contextPolicy: 'handoff-summary-and-current-turn'
|
|
1058
|
+
},
|
|
1059
|
+
system: 'Use only the handoff summary and current caller turn.'
|
|
1060
|
+
}),
|
|
1048
1061
|
handoffPolicy: ({ handoff }) => {
|
|
1049
1062
|
if (handoff.targetAgentId === 'billing') {
|
|
1050
1063
|
return {
|
|
@@ -1074,6 +1087,10 @@ voice({
|
|
|
1074
1087
|
|
|
1075
1088
|
For production call centers, pass `handoffPolicy` to keep routing code-owned instead of dashboard-owned. The policy can allow a handoff, reroute it to a different specialist, merge handoff metadata, summarize the reason for the target agent, or block the handoff and return an escalation. Squad traces mark each handoff as `allowed`, `blocked`, `unknown-target`, or `max-exceeded`, so support teams can audit why a caller moved between specialists.
|
|
1076
1089
|
|
|
1090
|
+
Pass `contextPolicy` when a specialist should receive a controlled context window. The default behavior preserves the accumulated conversation plus a system handoff summary. A context policy can trim that to a handoff summary and current turn, add a specialist-specific system prompt, or attach metadata that appears in the returned squad state. This is the code-owned equivalent of Vapi Squads context controls: the app decides what each specialist sees, and `agent.context` traces show whether default or custom context was applied.
|
|
1091
|
+
|
|
1092
|
+
Each specialist owns its own `tools`, so tool permissions stay explicit per agent. For example, support can have `lookup_order`, billing can have `refund_invoice`, and scheduling can have `book_appointment`. The squad only routes; it does not give every specialist every tool by default.
|
|
1093
|
+
|
|
1077
1094
|
Use `runVoiceAgentSquadContract(...)` in tests or readiness checks when you need proof that a specialist graph still routes correctly:
|
|
1078
1095
|
|
|
1079
1096
|
```ts
|
package/dist/agent.d.ts
CHANGED
|
@@ -95,6 +95,11 @@ export type VoiceAgentSquadHandoffPolicyResult<TResult = unknown> = {
|
|
|
95
95
|
summary?: string;
|
|
96
96
|
targetAgentId?: string;
|
|
97
97
|
};
|
|
98
|
+
export type VoiceAgentSquadContextPolicyResult = {
|
|
99
|
+
messages?: VoiceAgentMessage[];
|
|
100
|
+
metadata?: Record<string, unknown>;
|
|
101
|
+
system?: string;
|
|
102
|
+
};
|
|
98
103
|
export type VoiceAgent<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = {
|
|
99
104
|
id: string;
|
|
100
105
|
onTurn: VoiceOnTurnObjectHandler<TContext, TSession, TResult>;
|
|
@@ -136,6 +141,16 @@ export type VoiceAgentSquadOptions<TContext = unknown, TSession extends VoiceSes
|
|
|
136
141
|
targetAgent?: VoiceAgent<TContext, TSession, TResult>;
|
|
137
142
|
turn: VoiceTurnRecord;
|
|
138
143
|
}) => Promise<VoiceAgentSquadHandoffPolicyResult<TResult> | void> | VoiceAgentSquadHandoffPolicyResult<TResult> | void;
|
|
144
|
+
contextPolicy?: (input: {
|
|
145
|
+
context: TContext;
|
|
146
|
+
fromAgentId: string;
|
|
147
|
+
handoff: VoiceAgentSquadStateHandoff;
|
|
148
|
+
messages: VoiceAgentMessage[];
|
|
149
|
+
session: TSession;
|
|
150
|
+
summaryMessage: VoiceAgentMessage;
|
|
151
|
+
targetAgent: VoiceAgent<TContext, TSession, TResult>;
|
|
152
|
+
turn: VoiceTurnRecord;
|
|
153
|
+
}) => Promise<VoiceAgentSquadContextPolicyResult | void> | VoiceAgentSquadContextPolicyResult | void;
|
|
139
154
|
id: string;
|
|
140
155
|
maxHandoffsPerTurn?: number;
|
|
141
156
|
onHandoff?: (input: {
|
package/dist/client/index.js
CHANGED
|
@@ -3533,6 +3533,8 @@ var renderTraceEventMarkdown = (event, startedAt) => {
|
|
|
3533
3533
|
return event.payload.text ? `${label} assistant "${formatTraceValue(event.payload.text)}"` : `${label} ${formatTraceValue(event.payload.status)}`;
|
|
3534
3534
|
case "agent.tool":
|
|
3535
3535
|
return `${label} ${formatTraceValue(event.payload.toolName)} ${formatTraceValue(event.payload.status)}`;
|
|
3536
|
+
case "agent.context":
|
|
3537
|
+
return `${label} ${formatTraceValue(event.payload.fromAgentId)} -> ${formatTraceValue(event.payload.targetAgentId)} ${formatTraceValue(event.payload.status)}`;
|
|
3536
3538
|
case "agent.handoff":
|
|
3537
3539
|
return `${label} ${formatTraceValue(event.payload.fromAgentId)} -> ${formatTraceValue(event.payload.targetAgentId)}`;
|
|
3538
3540
|
case "session.error":
|
package/dist/index.d.ts
CHANGED
|
@@ -118,7 +118,7 @@ export type { StoredVoiceIncidentBundleArtifact, VoiceIncidentBundle, VoiceIncid
|
|
|
118
118
|
export type { VoiceQualityLink, VoiceQualityMetric, VoiceQualityReport, VoiceQualityRoutesOptions, VoiceQualityStatus, VoiceQualityThresholds } from './qualityRoutes';
|
|
119
119
|
export type { VoiceResilienceIOSimulator, VoiceResilienceLink, VoiceResiliencePageData, VoiceResilienceRoutesOptions, VoiceResilienceSimulationProvider, VoiceRoutingKindSummary, VoiceRoutingDecisionSummary, VoiceRoutingDecisionSummaryOptions, VoiceRoutingEvent, VoiceRoutingEventKind, VoiceRoutingSessionSummary, VoiceRoutingSessionSummaryOptions } from './resilienceRoutes';
|
|
120
120
|
export type { VoiceIOProviderRouterEvent, VoiceIOProviderRouterOptions, VoiceIOProviderRouterPolicy, VoiceIOProviderRouterPolicyConfig, VoiceSTTProviderRouterOptions, VoiceTTSProviderRouterOptions } from './providerAdapters';
|
|
121
|
-
export type { VoiceAgent, VoiceAgentMessage, VoiceAgentMessageRole, VoiceAgentModel, VoiceAgentModelInput, VoiceAgentModelOutput, VoiceAgentOptions, VoiceAgentRunResult, VoiceAgentSquadHandoffPolicyResult, VoiceAgentSquadHandoffStatus, VoiceAgentSquadOptions, VoiceAgentSquadState, VoiceAgentSquadStateHandoff, VoiceAgentTool, VoiceAgentToolCall, VoiceAgentToolResult } from './agent';
|
|
121
|
+
export type { VoiceAgent, VoiceAgentMessage, VoiceAgentMessageRole, VoiceAgentModel, VoiceAgentModelInput, VoiceAgentModelOutput, VoiceAgentOptions, VoiceAgentRunResult, VoiceAgentSquadContextPolicyResult, VoiceAgentSquadHandoffPolicyResult, VoiceAgentSquadHandoffStatus, VoiceAgentSquadOptions, VoiceAgentSquadState, VoiceAgentSquadStateHandoff, VoiceAgentTool, VoiceAgentToolCall, VoiceAgentToolResult } from './agent';
|
|
122
122
|
export type { VoiceAgentSquadContractDefinition, VoiceAgentSquadContractIssue, VoiceAgentSquadContractOutcome, VoiceAgentSquadContractReport, VoiceAgentSquadContractRunOptions, VoiceAgentSquadContractTurn, VoiceAgentSquadContractTurnReport, VoiceAgentSquadHandoffExpectation, VoiceAgentSquadTurnExpectation } from './agentSquadContract';
|
|
123
123
|
export type { VoiceToolRetryDelay, VoiceToolRuntime, VoiceToolRuntimeExecuteInput, VoiceToolRuntimeOptions, VoiceToolRuntimeResult } from './toolRuntime';
|
|
124
124
|
export type { VoiceToolContractCase, VoiceToolContractCaseReport, VoiceToolContractDefinition, VoiceToolContractExpectation, VoiceToolContractHandlerOptions, VoiceToolContractHTMLHandlerOptions, VoiceToolContractIssue, VoiceToolContractReport, VoiceToolContractRoutesOptions, VoiceToolContractSuiteReport } from './toolContract';
|
package/dist/index.js
CHANGED
|
@@ -7756,7 +7756,7 @@ var createVoiceAgentSquad = (options) => {
|
|
|
7756
7756
|
targetAgentId: nextAgent.id,
|
|
7757
7757
|
turn: input.turn
|
|
7758
7758
|
});
|
|
7759
|
-
await appendVoiceAgentSquadHandoff({
|
|
7759
|
+
const handoff = await appendVoiceAgentSquadHandoff({
|
|
7760
7760
|
agentId: options.id,
|
|
7761
7761
|
fromAgentId: agent.id,
|
|
7762
7762
|
handoffs,
|
|
@@ -7782,17 +7782,54 @@ var createVoiceAgentSquad = (options) => {
|
|
|
7782
7782
|
sessionId: input.session.id,
|
|
7783
7783
|
toAgentId: nextAgent.id
|
|
7784
7784
|
});
|
|
7785
|
-
|
|
7785
|
+
const summaryMessage = {
|
|
7786
7786
|
content: handoffSummary ?? handoffReason ?? `Handoff to ${nextAgent.id}`,
|
|
7787
7787
|
metadata,
|
|
7788
7788
|
name: nextAgent.id,
|
|
7789
7789
|
role: "system"
|
|
7790
|
+
};
|
|
7791
|
+
messages.push(summaryMessage);
|
|
7792
|
+
const contextPolicy = await options.contextPolicy?.({
|
|
7793
|
+
context: input.context,
|
|
7794
|
+
fromAgentId: agent.id,
|
|
7795
|
+
handoff,
|
|
7796
|
+
messages,
|
|
7797
|
+
session: input.session,
|
|
7798
|
+
summaryMessage,
|
|
7799
|
+
targetAgent: nextAgent,
|
|
7800
|
+
turn: input.turn
|
|
7801
|
+
});
|
|
7802
|
+
if (contextPolicy?.metadata && Object.keys(contextPolicy.metadata).length > 0) {
|
|
7803
|
+
handoff.metadata = {
|
|
7804
|
+
...handoff.metadata,
|
|
7805
|
+
...contextPolicy.metadata
|
|
7806
|
+
};
|
|
7807
|
+
const latest = handoffs.at(-1);
|
|
7808
|
+
if (latest === handoff) {
|
|
7809
|
+
latest.metadata = handoff.metadata;
|
|
7810
|
+
}
|
|
7811
|
+
}
|
|
7812
|
+
await appendVoiceAgentTrace({
|
|
7813
|
+
agentId: options.id,
|
|
7814
|
+
event: {
|
|
7815
|
+
fromAgentId: handoff.fromAgentId,
|
|
7816
|
+
messageCount: messages.length,
|
|
7817
|
+
nextMessageCount: contextPolicy?.messages?.length ?? messages.length,
|
|
7818
|
+
status: contextPolicy ? "applied" : "default",
|
|
7819
|
+
summaryIncluded: (contextPolicy?.messages ?? messages).some((message) => message === summaryMessage),
|
|
7820
|
+
targetAgentId: nextAgent.id
|
|
7821
|
+
},
|
|
7822
|
+
session: input.session,
|
|
7823
|
+
trace: options.trace,
|
|
7824
|
+
turn: input.turn,
|
|
7825
|
+
type: "agent.context"
|
|
7790
7826
|
});
|
|
7791
7827
|
agent = nextAgent;
|
|
7792
7828
|
agentId = nextAgent.id;
|
|
7793
7829
|
result = await agent.run({
|
|
7794
7830
|
...input,
|
|
7795
|
-
messages
|
|
7831
|
+
messages: contextPolicy?.messages ?? messages,
|
|
7832
|
+
system: contextPolicy?.system ?? input.system
|
|
7796
7833
|
});
|
|
7797
7834
|
toolResults.push(...result.toolResults);
|
|
7798
7835
|
}
|
|
@@ -9503,6 +9540,8 @@ var renderTraceEventMarkdown = (event, startedAt) => {
|
|
|
9503
9540
|
return event.payload.text ? `${label} assistant "${formatTraceValue(event.payload.text)}"` : `${label} ${formatTraceValue(event.payload.status)}`;
|
|
9504
9541
|
case "agent.tool":
|
|
9505
9542
|
return `${label} ${formatTraceValue(event.payload.toolName)} ${formatTraceValue(event.payload.status)}`;
|
|
9543
|
+
case "agent.context":
|
|
9544
|
+
return `${label} ${formatTraceValue(event.payload.fromAgentId)} -> ${formatTraceValue(event.payload.targetAgentId)} ${formatTraceValue(event.payload.status)}`;
|
|
9506
9545
|
case "agent.handoff":
|
|
9507
9546
|
return `${label} ${formatTraceValue(event.payload.fromAgentId)} -> ${formatTraceValue(event.payload.targetAgentId)}`;
|
|
9508
9547
|
case "session.error":
|
package/dist/svelte/index.js
CHANGED
|
@@ -1621,6 +1621,8 @@ var renderTraceEventMarkdown = (event, startedAt) => {
|
|
|
1621
1621
|
return event.payload.text ? `${label} assistant "${formatTraceValue(event.payload.text)}"` : `${label} ${formatTraceValue(event.payload.status)}`;
|
|
1622
1622
|
case "agent.tool":
|
|
1623
1623
|
return `${label} ${formatTraceValue(event.payload.toolName)} ${formatTraceValue(event.payload.status)}`;
|
|
1624
|
+
case "agent.context":
|
|
1625
|
+
return `${label} ${formatTraceValue(event.payload.fromAgentId)} -> ${formatTraceValue(event.payload.targetAgentId)} ${formatTraceValue(event.payload.status)}`;
|
|
1624
1626
|
case "agent.handoff":
|
|
1625
1627
|
return `${label} ${formatTraceValue(event.payload.fromAgentId)} -> ${formatTraceValue(event.payload.targetAgentId)}`;
|
|
1626
1628
|
case "session.error":
|
package/dist/trace.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { S3Client, S3Options } from 'bun';
|
|
2
|
-
export type VoiceTraceEventType = 'assistant.guardrail' | 'assistant.memory' | 'assistant.run' | 'agent.handoff' | 'agent.model' | 'agent.result' | 'agent.tool' | 'call.handoff' | 'call.lifecycle' | 'client.barge_in' | 'client.live_latency' | 'client.reconnect' | 'operator.action' | 'session.error' | 'turn.assistant' | 'turn.committed' | 'turn.cost' | 'turn_latency.stage' | 'turn.transcript' | 'workflow.contract';
|
|
2
|
+
export type VoiceTraceEventType = 'assistant.guardrail' | 'assistant.memory' | 'assistant.run' | 'agent.context' | 'agent.handoff' | 'agent.model' | 'agent.result' | 'agent.tool' | 'call.handoff' | 'call.lifecycle' | 'client.barge_in' | 'client.live_latency' | 'client.reconnect' | 'operator.action' | 'session.error' | 'turn.assistant' | 'turn.committed' | 'turn.cost' | 'turn_latency.stage' | 'turn.transcript' | 'workflow.contract';
|
|
3
3
|
export type VoiceTraceEvent<TPayload extends Record<string, unknown> = Record<string, unknown>> = {
|
|
4
4
|
at: number;
|
|
5
5
|
id?: string;
|