@sequenceholdings/agent-spec 0.1.1 → 0.1.3
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 +93 -0
- package/dist/agent-definition.d.ts +616 -0
- package/dist/agent-definition.js +240 -0
- package/dist/canonical-json.d.ts +2 -0
- package/dist/canonical-json.js +13 -0
- package/dist/index.d.ts +2 -117
- package/dist/index.js +2 -248
- package/dist/input-schema.d.ts +19 -0
- package/dist/input-schema.js +57 -0
- package/dist/voice-access.d.ts +40 -0
- package/dist/voice-access.js +34 -0
- package/dist/voice-actions-contracts.d.ts +423 -0
- package/dist/voice-actions-contracts.js +95 -0
- package/dist/voice-actions-transitions.d.ts +52 -0
- package/dist/voice-actions-transitions.js +170 -0
- package/dist/voice-actions.d.ts +2 -0
- package/dist/voice-actions.js +2 -0
- package/dist/voice-api.d.ts +1102 -0
- package/dist/voice-api.js +164 -0
- package/dist/voice-authoring.d.ts +463 -0
- package/dist/voice-authoring.js +132 -0
- package/dist/voice-authority-contracts.d.ts +247 -0
- package/dist/voice-authority-contracts.js +177 -0
- package/dist/voice-authority-evaluation.d.ts +29 -0
- package/dist/voice-authority-evaluation.js +80 -0
- package/dist/voice-authority-verification.d.ts +47 -0
- package/dist/voice-authority-verification.js +184 -0
- package/dist/voice-authority.d.ts +3 -0
- package/dist/voice-authority.js +3 -0
- package/dist/voice-common.d.ts +21 -0
- package/dist/voice-common.js +23 -0
- package/dist/voice-drafts.d.ts +441 -0
- package/dist/voice-drafts.js +75 -0
- package/dist/voice-grant.d.ts +19 -0
- package/dist/voice-grant.js +21 -0
- package/dist/voice-lifecycle-control.d.ts +130 -0
- package/dist/voice-lifecycle-control.js +138 -0
- package/dist/voice-lifecycle-session.d.ts +168 -0
- package/dist/voice-lifecycle-session.js +114 -0
- package/dist/voice-lifecycle-states.d.ts +96 -0
- package/dist/voice-lifecycle-states.js +139 -0
- package/dist/voice-lifecycle.d.ts +3 -0
- package/dist/voice-lifecycle.js +3 -0
- package/dist/voice-policy-duration.d.ts +46 -0
- package/dist/voice-policy-duration.js +166 -0
- package/dist/voice-policy-limits.d.ts +174 -0
- package/dist/voice-policy-limits.js +188 -0
- package/dist/voice-policy.d.ts +2 -0
- package/dist/voice-policy.js +2 -0
- package/dist/voice-provider-evidence.d.ts +80 -0
- package/dist/voice-provider-evidence.js +115 -0
- package/dist/voice-provider-publication.d.ts +319 -0
- package/dist/voice-provider-publication.js +117 -0
- package/dist/voice-provider-release.d.ts +386 -0
- package/dist/voice-provider-release.js +154 -0
- package/dist/voice-provider.d.ts +3 -0
- package/dist/voice-provider.js +3 -0
- package/dist/voice-release.d.ts +808 -0
- package/dist/voice-release.js +110 -0
- package/dist/voice-runs-audio.d.ts +157 -0
- package/dist/voice-runs-audio.js +85 -0
- package/dist/voice-runs-evidence.d.ts +183 -0
- package/dist/voice-runs-evidence.js +154 -0
- package/dist/voice-runs-model.d.ts +967 -0
- package/dist/voice-runs-model.js +199 -0
- package/dist/voice-runs-tooling.d.ts +88 -0
- package/dist/voice-runs-tooling.js +100 -0
- package/dist/voice-runs.d.ts +4 -0
- package/dist/voice-runs.js +4 -0
- package/dist/voice.d.ts +13 -0
- package/dist/voice.js +13 -0
- package/package.json +8 -3
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { sameVoiceResource } from './voice-authority-contracts.js';
|
|
3
|
+
import { voiceAgentScopeSchema, voiceIdSchema, voiceTimestampSchema } from './voice-common.js';
|
|
4
|
+
import { voiceCallDirectionSchema, voiceCallerIdentitySchema } from './voice-lifecycle.js';
|
|
5
|
+
import { voiceCallDurationSnapshotSchema } from './voice-policy.js';
|
|
6
|
+
import { voiceBusinessOutcomeSchema, voiceCompletionEventSchema, voiceRunEvidenceRetentionSchema, voiceRunEvidenceStatusSchema, voiceRunRecordingSchema, voiceRunWritebackStatusSchema, voiceSyntheticResourceEvidenceSchema, voiceTelephoneOutcomeSchema, voiceTranscriptSchema, } from './voice-runs-evidence.js';
|
|
7
|
+
import { voiceMissingEvidenceSchema, voiceRunAuthenticationEvidenceSchema, voiceRunToolOutcomeSchema, } from './voice-runs-tooling.js';
|
|
8
|
+
const summaryShape = {
|
|
9
|
+
schemaVersion: z.literal('1'),
|
|
10
|
+
scope: voiceAgentScopeSchema,
|
|
11
|
+
runId: voiceIdSchema,
|
|
12
|
+
sessionId: voiceIdSchema,
|
|
13
|
+
agentVersionId: voiceIdSchema,
|
|
14
|
+
releaseId: voiceIdSchema,
|
|
15
|
+
direction: voiceCallDirectionSchema,
|
|
16
|
+
callerIdentity: voiceCallerIdentitySchema,
|
|
17
|
+
runtimeAccountId: voiceIdSchema,
|
|
18
|
+
enablingOperatorPrincipalId: voiceIdSchema.nullable(),
|
|
19
|
+
admittedAt: voiceTimestampSchema,
|
|
20
|
+
startedAt: voiceTimestampSchema.nullable(),
|
|
21
|
+
endedAt: voiceTimestampSchema.nullable(),
|
|
22
|
+
durationSeconds: z.number().int().nonnegative().safe().nullable(),
|
|
23
|
+
telephoneOutcome: voiceTelephoneOutcomeSchema,
|
|
24
|
+
businessOutcome: voiceBusinessOutcomeSchema,
|
|
25
|
+
writebackStatus: voiceRunWritebackStatusSchema,
|
|
26
|
+
evidenceStatus: voiceRunEvidenceStatusSchema,
|
|
27
|
+
syntheticResource: voiceSyntheticResourceEvidenceSchema,
|
|
28
|
+
retention: voiceRunEvidenceRetentionSchema,
|
|
29
|
+
recording: voiceRunRecordingSchema,
|
|
30
|
+
};
|
|
31
|
+
function addIssue({ context, path, message }) {
|
|
32
|
+
context.addIssue({ code: 'custom', path, message });
|
|
33
|
+
}
|
|
34
|
+
function validateSummary({ value, context }) {
|
|
35
|
+
if (value.direction !== value.callerIdentity.direction) {
|
|
36
|
+
addIssue({ context, path: ['callerIdentity', 'direction'],
|
|
37
|
+
message: 'run direction must match caller identity direction' });
|
|
38
|
+
}
|
|
39
|
+
if (value.durationSeconds !== null && (value.startedAt === null || value.endedAt === null)) {
|
|
40
|
+
addIssue({ context, path: ['durationSeconds'],
|
|
41
|
+
message: 'duration requires connected start and end timestamps' });
|
|
42
|
+
}
|
|
43
|
+
if (value.startedAt !== null && Date.parse(value.startedAt) < Date.parse(value.admittedAt)) {
|
|
44
|
+
addIssue({ context, path: ['startedAt'], message: 'connected start cannot precede admission' });
|
|
45
|
+
}
|
|
46
|
+
if (value.endedAt !== null && Date.parse(value.endedAt) <
|
|
47
|
+
Date.parse(value.startedAt ?? value.admittedAt)) {
|
|
48
|
+
addIssue({ context, path: ['endedAt'], message: 'end cannot precede admission or connection' });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export const voiceCompletedRunSummarySchema = z.strictObject(summaryShape)
|
|
52
|
+
.superRefine((value, context) => validateSummary({ value, context }));
|
|
53
|
+
const providerReferencesSchema = z.strictObject({
|
|
54
|
+
provider: z.literal('ELEVENLABS'),
|
|
55
|
+
providerAgentId: voiceIdSchema.nullable(),
|
|
56
|
+
providerConversationId: voiceIdSchema.nullable(),
|
|
57
|
+
conversationBindingStatus: z.enum([
|
|
58
|
+
'CORROBORATED', 'UNVERIFIED', 'MISSING', 'CONTRADICTORY',
|
|
59
|
+
]),
|
|
60
|
+
twilioCallSid: voiceIdSchema.nullable(),
|
|
61
|
+
}).superRefine((value, context) => {
|
|
62
|
+
if (value.conversationBindingStatus === 'CORROBORATED' &&
|
|
63
|
+
[value.providerAgentId, value.providerConversationId, value.twilioCallSid]
|
|
64
|
+
.some((field) => field === null)) {
|
|
65
|
+
context.addIssue({ code: 'custom', message: 'corroborated binding requires all provider IDs' });
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
const monetaryCostFactSchema = z.strictObject({
|
|
69
|
+
source: z.enum(['PROVIDER', 'TWILIO', 'ATLAS']),
|
|
70
|
+
category: z.enum(['CALL', 'MODEL', 'TELEPHONY', 'TOOL']),
|
|
71
|
+
currency: z.string().regex(/^[A-Z]{3}$/),
|
|
72
|
+
amountMinorUnits: z.number().int().nonnegative().safe(),
|
|
73
|
+
});
|
|
74
|
+
const costFactSchema = z.union([monetaryCostFactSchema, z.strictObject({
|
|
75
|
+
source: z.literal('PROVIDER'), category: z.literal('CALL'), unit: z.literal('CREDITS'),
|
|
76
|
+
amount: z.number().finite().nonnegative().max(1_000_000_000_000),
|
|
77
|
+
})]);
|
|
78
|
+
const latencyFactSchema = z.strictObject({
|
|
79
|
+
source: z.enum(['PROVIDER', 'TWILIO', 'ATLAS']),
|
|
80
|
+
metric: z.enum([
|
|
81
|
+
'FIRST_AUDIBLE_RESPONSE', 'FIRST_SUBSTANTIVE_RESPONSE',
|
|
82
|
+
'TOOL_INVOCATION', 'COMPLETION_PROCESSING',
|
|
83
|
+
]),
|
|
84
|
+
milliseconds: z.number().int().nonnegative().safe(),
|
|
85
|
+
});
|
|
86
|
+
const detailSchema = z.strictObject({
|
|
87
|
+
...summaryShape,
|
|
88
|
+
callPolicy: voiceCallDurationSnapshotSchema,
|
|
89
|
+
providerReferences: providerReferencesSchema,
|
|
90
|
+
authentication: voiceRunAuthenticationEvidenceSchema,
|
|
91
|
+
toolOutcomes: z.array(voiceRunToolOutcomeSchema).max(200),
|
|
92
|
+
transcript: voiceTranscriptSchema,
|
|
93
|
+
completionEvent: voiceCompletionEventSchema.nullable(),
|
|
94
|
+
missingEvidence: z.array(voiceMissingEvidenceSchema).max(25),
|
|
95
|
+
costFacts: z.array(costFactSchema).max(20),
|
|
96
|
+
latencyFacts: z.array(latencyFactSchema).max(20),
|
|
97
|
+
terminationReason: z.enum([
|
|
98
|
+
'REMOTE_HANGUP', 'ATLAS_CANCELLED', 'DURATION_LIMIT', 'PROVIDER_FAILURE',
|
|
99
|
+
'TELEPHONY_FAILURE', 'ADMISSION_SHUTDOWN', 'UNKNOWN',
|
|
100
|
+
]),
|
|
101
|
+
});
|
|
102
|
+
function validatePolicyAndBindings({ value, context }) {
|
|
103
|
+
if (Date.parse(value.callPolicy.admittedAt) !== Date.parse(value.admittedAt)) {
|
|
104
|
+
addIssue({ context, path: ['callPolicy', 'admittedAt'],
|
|
105
|
+
message: 'policy admission timestamp must match the run' });
|
|
106
|
+
}
|
|
107
|
+
const policyConnected = value.callPolicy.connectedAt === null
|
|
108
|
+
? null : Date.parse(value.callPolicy.connectedAt);
|
|
109
|
+
const runConnected = value.startedAt === null ? null : Date.parse(value.startedAt);
|
|
110
|
+
if (policyConnected !== runConnected) {
|
|
111
|
+
addIssue({ context, path: ['callPolicy', 'connectedAt'],
|
|
112
|
+
message: 'policy connected timestamp must match the run' });
|
|
113
|
+
}
|
|
114
|
+
if (value.completionEvent !== null &&
|
|
115
|
+
value.completionEvent.logicalIdentity.sessionId !== value.sessionId) {
|
|
116
|
+
addIssue({ context, path: ['completionEvent', 'logicalIdentity', 'sessionId'],
|
|
117
|
+
message: 'completion event must identify the run session' });
|
|
118
|
+
}
|
|
119
|
+
if (value.completionEvent?.evidenceStatus === 'CONFIRMED' &&
|
|
120
|
+
(value.providerReferences.conversationBindingStatus !== 'CORROBORATED' ||
|
|
121
|
+
value.completionEvent.providerConversationId === null ||
|
|
122
|
+
value.completionEvent.providerConversationId !==
|
|
123
|
+
value.providerReferences.providerConversationId)) {
|
|
124
|
+
addIssue({ context, path: ['completionEvent', 'providerConversationId'],
|
|
125
|
+
message: 'confirmed event must match the corroborated provider conversation' });
|
|
126
|
+
}
|
|
127
|
+
const expectedAbsoluteExpiry = Date.parse(value.callPolicy.admittedAt) +
|
|
128
|
+
(value.callPolicy.setupAllowanceSeconds + value.callPolicy.maxCallDurationSeconds) * 1_000;
|
|
129
|
+
if (Date.parse(value.callPolicy.absoluteExpiresAt) !== expectedAbsoluteExpiry) {
|
|
130
|
+
addIssue({ context, path: ['callPolicy', 'absoluteExpiresAt'],
|
|
131
|
+
message: 'absolute expiry must match the admitted policy snapshot' });
|
|
132
|
+
}
|
|
133
|
+
if (policyConnected !== null) {
|
|
134
|
+
const expectedDeadline = Math.min(policyConnected + value.callPolicy.maxCallDurationSeconds * 1_000, expectedAbsoluteExpiry);
|
|
135
|
+
if (value.callPolicy.connectedDeadlineAt === null ||
|
|
136
|
+
Date.parse(value.callPolicy.connectedDeadlineAt) !== expectedDeadline) {
|
|
137
|
+
addIssue({ context, path: ['callPolicy', 'connectedDeadlineAt'],
|
|
138
|
+
message: 'connected deadline must match the admitted duration bound' });
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
else if (value.callPolicy.connectedDeadlineAt !== null) {
|
|
142
|
+
addIssue({ context, path: ['callPolicy', 'connectedDeadlineAt'],
|
|
143
|
+
message: 'an unconnected call cannot claim a connected deadline' });
|
|
144
|
+
}
|
|
145
|
+
if (value.authentication.outcome === 'verified' &&
|
|
146
|
+
(value.authentication.verifiedResource === null || value.syntheticResource.verifiedResource === null ||
|
|
147
|
+
!sameVoiceResource({ left: value.authentication.verifiedResource, right: value.syntheticResource.verifiedResource }))) {
|
|
148
|
+
addIssue({ context, path: ['authentication'],
|
|
149
|
+
message: 'verification and resource evidence must identify the same resource' });
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
function validateEvidenceStatus({ value, context }) {
|
|
153
|
+
if (value.enablingOperatorPrincipalId === null && !value.missingEvidence.some(({ kind }) => kind === 'ENABLING_OPERATOR')) {
|
|
154
|
+
addIssue({ context, path: ['enablingOperatorPrincipalId'], message: 'missing operator provenance requires an explicit indicator' });
|
|
155
|
+
}
|
|
156
|
+
if ((value.evidenceStatus === 'COMPLETE') !== (value.missingEvidence.length === 0)) {
|
|
157
|
+
addIssue({ context, path: ['missingEvidence'],
|
|
158
|
+
message: 'evidence status must agree with explicit missing-evidence indicators' });
|
|
159
|
+
}
|
|
160
|
+
if (value.transcript.status !== 'AVAILABLE' &&
|
|
161
|
+
!value.missingEvidence.some(({ kind }) => kind === 'TRANSCRIPT')) {
|
|
162
|
+
addIssue({ context, path: ['missingEvidence'],
|
|
163
|
+
message: 'unavailable transcript requires an explicit indicator' });
|
|
164
|
+
}
|
|
165
|
+
if (value.completionEvent === null &&
|
|
166
|
+
!value.missingEvidence.some(({ kind }) => kind === 'COMPLETION_EVENT')) {
|
|
167
|
+
addIssue({ context, path: ['missingEvidence'],
|
|
168
|
+
message: 'missing completion event requires an explicit indicator' });
|
|
169
|
+
}
|
|
170
|
+
if (value.businessOutcome === 'SUCCEEDED') {
|
|
171
|
+
const businessEvidence = value.toolOutcomes.filter(({ operationKind }) => operationKind !== 'AUTHENTICATION');
|
|
172
|
+
const hasTerminalSuccess = businessEvidence.some((outcome) => outcome.status === 'SUCCEEDED' &&
|
|
173
|
+
(outcome.operationKind !== 'BUSINESS_ACTION' ||
|
|
174
|
+
outcome.actionPhase === 'CONFIRM' || outcome.actionPhase === 'CANCEL'));
|
|
175
|
+
if (!hasTerminalSuccess || businessEvidence.some(({ status }) => status !== 'SUCCEEDED')) {
|
|
176
|
+
addIssue({ context, path: ['businessOutcome'],
|
|
177
|
+
message: 'SUCCEEDED business outcome requires successful business evidence with no failed or uncertain operation' });
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
export const voiceCompletedRunDetailSchema = detailSchema.superRefine((value, context) => {
|
|
182
|
+
validateSummary({ value, context });
|
|
183
|
+
validatePolicyAndBindings({ value, context });
|
|
184
|
+
validateEvidenceStatus({ value, context });
|
|
185
|
+
});
|
|
186
|
+
export const voiceCompletedRunListRequestSchema = z.strictObject({
|
|
187
|
+
scope: voiceAgentScopeSchema, cursor: z.string().trim().min(1).max(500).nullable(),
|
|
188
|
+
limit: z.number().int().min(1).max(100).safe(),
|
|
189
|
+
telephoneOutcome: voiceTelephoneOutcomeSchema.nullable(),
|
|
190
|
+
evidenceStatus: voiceRunEvidenceStatusSchema.nullable(),
|
|
191
|
+
});
|
|
192
|
+
export const voiceCompletedRunListResponseSchema = z.strictObject({
|
|
193
|
+
items: z.array(voiceCompletedRunSummarySchema).max(100),
|
|
194
|
+
nextCursor: z.string().trim().min(1).max(500).nullable(),
|
|
195
|
+
});
|
|
196
|
+
export const voiceCompletedRunDetailRequestSchema = z.strictObject({
|
|
197
|
+
scope: voiceAgentScopeSchema, runId: voiceIdSchema,
|
|
198
|
+
});
|
|
199
|
+
export const voiceCompletedRunDetailResponseSchema = voiceCompletedRunDetailSchema;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const voiceRunAuthenticationEvidenceSchema: z.ZodObject<{
|
|
3
|
+
outcome: z.ZodEnum<{
|
|
4
|
+
unknown: "unknown";
|
|
5
|
+
verified: "verified";
|
|
6
|
+
locked: "locked";
|
|
7
|
+
rejected: "rejected";
|
|
8
|
+
not_attempted: "not_attempted";
|
|
9
|
+
}>;
|
|
10
|
+
authorityAtRunEnd: z.ZodEnum<{
|
|
11
|
+
unknown: "unknown";
|
|
12
|
+
expired: "expired";
|
|
13
|
+
revoked: "revoked";
|
|
14
|
+
active: "active";
|
|
15
|
+
}>;
|
|
16
|
+
method: z.ZodNullable<z.ZodString>;
|
|
17
|
+
attemptedAt: z.ZodNullable<z.ZodISODateTime>;
|
|
18
|
+
verifiedAt: z.ZodNullable<z.ZodISODateTime>;
|
|
19
|
+
verifiedResource: z.ZodNullable<z.ZodObject<{
|
|
20
|
+
kind: z.ZodString;
|
|
21
|
+
id: z.ZodString;
|
|
22
|
+
}, z.core.$strict>>;
|
|
23
|
+
verifierInvocationId: z.ZodNullable<z.ZodString>;
|
|
24
|
+
observedFunctionVersionId: z.ZodNullable<z.ZodString>;
|
|
25
|
+
}, z.core.$strict>;
|
|
26
|
+
export declare const voiceRunToolOutcomeSchema: z.ZodObject<{
|
|
27
|
+
toolInvocationId: z.ZodString;
|
|
28
|
+
providerToolCallId: z.ZodNullable<z.ZodString>;
|
|
29
|
+
functionInvocationId: z.ZodNullable<z.ZodString>;
|
|
30
|
+
actionIntentId: z.ZodNullable<z.ZodString>;
|
|
31
|
+
actionReceiptId: z.ZodNullable<z.ZodString>;
|
|
32
|
+
actionPhase: z.ZodNullable<z.ZodEnum<{
|
|
33
|
+
UNKNOWN: "UNKNOWN";
|
|
34
|
+
PREPARE: "PREPARE";
|
|
35
|
+
CONFIRM: "CONFIRM";
|
|
36
|
+
CANCEL: "CANCEL";
|
|
37
|
+
}>>;
|
|
38
|
+
actionResolution: z.ZodNullable<z.ZodEnum<{
|
|
39
|
+
CANCELLED: "CANCELLED";
|
|
40
|
+
COMMITTED: "COMMITTED";
|
|
41
|
+
}>>;
|
|
42
|
+
toolAlias: z.ZodString;
|
|
43
|
+
operationKind: z.ZodEnum<{
|
|
44
|
+
AUTHENTICATION: "AUTHENTICATION";
|
|
45
|
+
READ: "READ";
|
|
46
|
+
CALCULATION: "CALCULATION";
|
|
47
|
+
BUSINESS_ACTION: "BUSINESS_ACTION";
|
|
48
|
+
}>;
|
|
49
|
+
status: z.ZodEnum<{
|
|
50
|
+
FAILED: "FAILED";
|
|
51
|
+
SUCCEEDED: "SUCCEEDED";
|
|
52
|
+
UNKNOWN: "UNKNOWN";
|
|
53
|
+
CANCELLED: "CANCELLED";
|
|
54
|
+
DENIED: "DENIED";
|
|
55
|
+
}>;
|
|
56
|
+
startedAt: z.ZodISODateTime;
|
|
57
|
+
completedAt: z.ZodNullable<z.ZodISODateTime>;
|
|
58
|
+
observedFunctionVersionId: z.ZodNullable<z.ZodString>;
|
|
59
|
+
validatedArguments: z.ZodNullable<z.ZodJSONSchema>;
|
|
60
|
+
boundedResult: z.ZodNullable<z.ZodJSONSchema>;
|
|
61
|
+
sanitizedError: z.ZodNullable<z.ZodObject<{
|
|
62
|
+
code: z.ZodString;
|
|
63
|
+
message: z.ZodString;
|
|
64
|
+
}, z.core.$strict>>;
|
|
65
|
+
}, z.core.$strict>;
|
|
66
|
+
export type VoiceRunToolOutcome = z.infer<typeof voiceRunToolOutcomeSchema>;
|
|
67
|
+
export declare const voiceMissingEvidenceSchema: z.ZodObject<{
|
|
68
|
+
kind: z.ZodEnum<{
|
|
69
|
+
TRANSCRIPT: "TRANSCRIPT";
|
|
70
|
+
COMPLETION_EVENT: "COMPLETION_EVENT";
|
|
71
|
+
RECORDING: "RECORDING";
|
|
72
|
+
AUTHENTICATION: "AUTHENTICATION";
|
|
73
|
+
RUNTIME_IDENTITY: "RUNTIME_IDENTITY";
|
|
74
|
+
ENABLING_OPERATOR: "ENABLING_OPERATOR";
|
|
75
|
+
PROVIDER_BINDING: "PROVIDER_BINDING";
|
|
76
|
+
CALL_TIMING: "CALL_TIMING";
|
|
77
|
+
ACTION_RESULT: "ACTION_RESULT";
|
|
78
|
+
WRITEBACK: "WRITEBACK";
|
|
79
|
+
}>;
|
|
80
|
+
status: z.ZodEnum<{
|
|
81
|
+
MISSING: "MISSING";
|
|
82
|
+
CONTRADICTORY: "CONTRADICTORY";
|
|
83
|
+
PENDING: "PENDING";
|
|
84
|
+
}>;
|
|
85
|
+
firstObservedAt: z.ZodISODateTime;
|
|
86
|
+
sanitizedDetail: z.ZodString;
|
|
87
|
+
}, z.core.$strict>;
|
|
88
|
+
export type VoiceMissingEvidence = z.infer<typeof voiceMissingEvidenceSchema>;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { voiceResourceReferenceSchema } from './voice-authority-contracts.js';
|
|
3
|
+
import { voiceIdSchema, voiceLocalKeySchema, voiceTimestampSchema } from './voice-common.js';
|
|
4
|
+
import { voiceBoundedRunEvidenceValueSchema, voiceRunSanitizedTextSchema, } from './voice-runs-evidence.js';
|
|
5
|
+
export const voiceRunAuthenticationEvidenceSchema = z.strictObject({
|
|
6
|
+
outcome: z.enum(['not_attempted', 'verified', 'rejected', 'locked', 'unknown']),
|
|
7
|
+
authorityAtRunEnd: z.enum(['active', 'expired', 'revoked', 'unknown']),
|
|
8
|
+
method: voiceLocalKeySchema.nullable(),
|
|
9
|
+
attemptedAt: voiceTimestampSchema.nullable(),
|
|
10
|
+
verifiedAt: voiceTimestampSchema.nullable(),
|
|
11
|
+
verifiedResource: voiceResourceReferenceSchema.nullable(),
|
|
12
|
+
verifierInvocationId: voiceIdSchema.nullable(),
|
|
13
|
+
observedFunctionVersionId: voiceIdSchema.nullable(),
|
|
14
|
+
}).superRefine((value, context) => {
|
|
15
|
+
const proof = [value.method, value.attemptedAt, value.verifiedAt,
|
|
16
|
+
value.verifiedResource, value.verifierInvocationId,
|
|
17
|
+
value.observedFunctionVersionId];
|
|
18
|
+
if (value.outcome === 'verified' && proof.some((field) => field === null)) {
|
|
19
|
+
context.addIssue({ code: 'custom', message: 'verified outcome requires verifier evidence' });
|
|
20
|
+
}
|
|
21
|
+
if (value.outcome === 'not_attempted' && proof.some((field) => field !== null)) {
|
|
22
|
+
context.addIssue({ code: 'custom', message: 'not-attempted outcome cannot carry verifier evidence' });
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
const toolOutcomeBaseSchema = z.strictObject({
|
|
26
|
+
toolInvocationId: voiceIdSchema,
|
|
27
|
+
providerToolCallId: voiceIdSchema.nullable(),
|
|
28
|
+
functionInvocationId: voiceIdSchema.nullable(),
|
|
29
|
+
actionIntentId: voiceIdSchema.nullable(),
|
|
30
|
+
actionReceiptId: voiceIdSchema.nullable(),
|
|
31
|
+
actionPhase: z.enum(['PREPARE', 'CONFIRM', 'CANCEL', 'UNKNOWN']).nullable(),
|
|
32
|
+
actionResolution: z.enum(['COMMITTED', 'CANCELLED']).nullable(),
|
|
33
|
+
toolAlias: voiceLocalKeySchema,
|
|
34
|
+
operationKind: z.enum(['AUTHENTICATION', 'READ', 'CALCULATION', 'BUSINESS_ACTION']),
|
|
35
|
+
status: z.enum(['SUCCEEDED', 'FAILED', 'DENIED', 'CANCELLED', 'UNKNOWN']),
|
|
36
|
+
startedAt: voiceTimestampSchema,
|
|
37
|
+
completedAt: voiceTimestampSchema.nullable(),
|
|
38
|
+
observedFunctionVersionId: voiceIdSchema.nullable(),
|
|
39
|
+
validatedArguments: voiceBoundedRunEvidenceValueSchema.nullable(),
|
|
40
|
+
boundedResult: voiceBoundedRunEvidenceValueSchema.nullable(),
|
|
41
|
+
sanitizedError: z.strictObject({
|
|
42
|
+
code: z.string().trim().min(1).max(100), message: voiceRunSanitizedTextSchema,
|
|
43
|
+
}).nullable(),
|
|
44
|
+
});
|
|
45
|
+
function validateExecutionEvidence({ value, context }) {
|
|
46
|
+
const executionProof = [value.completedAt, value.functionInvocationId,
|
|
47
|
+
value.observedFunctionVersionId, value.boundedResult];
|
|
48
|
+
if (value.status === 'SUCCEEDED' && executionProof.some((field) => field === null)) {
|
|
49
|
+
context.addIssue({ code: 'custom', message: 'successful tool outcome lacks execution evidence' });
|
|
50
|
+
}
|
|
51
|
+
if (value.status === 'UNKNOWN' && value.sanitizedError === null) {
|
|
52
|
+
context.addIssue({ code: 'custom', message: 'unknown outcome requires reconciliation reason' });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function validateActionEvidence({ value, context }) {
|
|
56
|
+
if (value.actionReceiptId !== null && value.actionIntentId === null) {
|
|
57
|
+
context.addIssue({ code: 'custom', message: 'action receipt requires an action intent' });
|
|
58
|
+
}
|
|
59
|
+
if ((value.actionReceiptId !== null || value.actionResolution !== null) &&
|
|
60
|
+
value.status !== 'SUCCEEDED') {
|
|
61
|
+
context.addIssue({ code: 'custom', message: 'only a successful action can claim resolution evidence' });
|
|
62
|
+
}
|
|
63
|
+
if (value.operationKind === 'BUSINESS_ACTION' && value.actionPhase === null) {
|
|
64
|
+
context.addIssue({ code: 'custom', message: 'business action requires an explicit phase' });
|
|
65
|
+
}
|
|
66
|
+
if (value.operationKind !== 'BUSINESS_ACTION' &&
|
|
67
|
+
[value.actionIntentId, value.actionReceiptId, value.actionPhase, value.actionResolution]
|
|
68
|
+
.some((field) => field !== null)) {
|
|
69
|
+
context.addIssue({ code: 'custom', message: 'non-action tool cannot claim action evidence' });
|
|
70
|
+
}
|
|
71
|
+
if (value.status === 'SUCCEEDED' && value.operationKind === 'BUSINESS_ACTION') {
|
|
72
|
+
if (value.actionPhase === 'UNKNOWN') {
|
|
73
|
+
context.addIssue({ code: 'custom', message: 'unclassified action cannot claim success' });
|
|
74
|
+
}
|
|
75
|
+
if (value.actionIntentId === null) {
|
|
76
|
+
context.addIssue({ code: 'custom', message: 'successful action phase requires an intent' });
|
|
77
|
+
}
|
|
78
|
+
const expectedResolution = value.actionPhase === 'CONFIRM' ? 'COMMITTED'
|
|
79
|
+
: value.actionPhase === 'CANCEL' ? 'CANCELLED' : null;
|
|
80
|
+
if (value.actionResolution !== expectedResolution ||
|
|
81
|
+
(value.actionPhase === 'CONFIRM' && value.actionReceiptId === null) ||
|
|
82
|
+
(value.actionPhase === 'PREPARE' && value.actionReceiptId !== null)) {
|
|
83
|
+
context.addIssue({ code: 'custom', message: 'action phase has invalid resolution evidence' });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
export const voiceRunToolOutcomeSchema = toolOutcomeBaseSchema.superRefine((value, context) => {
|
|
88
|
+
validateExecutionEvidence({ value, context });
|
|
89
|
+
validateActionEvidence({ value, context });
|
|
90
|
+
});
|
|
91
|
+
export const voiceMissingEvidenceSchema = z.strictObject({
|
|
92
|
+
kind: z.enum([
|
|
93
|
+
'RUNTIME_IDENTITY', 'ENABLING_OPERATOR', 'PROVIDER_BINDING', 'CALL_TIMING',
|
|
94
|
+
'AUTHENTICATION', 'ACTION_RESULT', 'TRANSCRIPT', 'COMPLETION_EVENT',
|
|
95
|
+
'WRITEBACK', 'RECORDING',
|
|
96
|
+
]),
|
|
97
|
+
status: z.enum(['PENDING', 'MISSING', 'CONTRADICTORY']),
|
|
98
|
+
firstObservedAt: voiceTimestampSchema,
|
|
99
|
+
sanitizedDetail: voiceRunSanitizedTextSchema,
|
|
100
|
+
});
|
package/dist/voice.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from './voice-common.js';
|
|
2
|
+
export * from './voice-access.js';
|
|
3
|
+
export * from './voice-authoring.js';
|
|
4
|
+
export * from './voice-drafts.js';
|
|
5
|
+
export * from './voice-policy.js';
|
|
6
|
+
export * from './voice-lifecycle.js';
|
|
7
|
+
export * from './voice-authority.js';
|
|
8
|
+
export * from './voice-grant.js';
|
|
9
|
+
export * from './voice-actions.js';
|
|
10
|
+
export * from './voice-provider.js';
|
|
11
|
+
export * from './voice-release.js';
|
|
12
|
+
export * from './voice-runs.js';
|
|
13
|
+
export * from './voice-api.js';
|
package/dist/voice.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from './voice-common.js';
|
|
2
|
+
export * from './voice-access.js';
|
|
3
|
+
export * from './voice-authoring.js';
|
|
4
|
+
export * from './voice-drafts.js';
|
|
5
|
+
export * from './voice-policy.js';
|
|
6
|
+
export * from './voice-lifecycle.js';
|
|
7
|
+
export * from './voice-authority.js';
|
|
8
|
+
export * from './voice-grant.js';
|
|
9
|
+
export * from './voice-actions.js';
|
|
10
|
+
export * from './voice-provider.js';
|
|
11
|
+
export * from './voice-release.js';
|
|
12
|
+
export * from './voice-runs.js';
|
|
13
|
+
export * from './voice-api.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sequenceholdings/agent-spec",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Typed agent definition contract, compiler, hashing, and migration utilities",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"repository": {
|
|
@@ -30,6 +30,11 @@
|
|
|
30
30
|
"types": "./dist/yaml.d.ts",
|
|
31
31
|
"import": "./dist/yaml.js",
|
|
32
32
|
"default": "./dist/yaml.js"
|
|
33
|
+
},
|
|
34
|
+
"./voice-runs-audio": {
|
|
35
|
+
"types": "./dist/voice-runs-audio.d.ts",
|
|
36
|
+
"import": "./dist/voice-runs-audio.js",
|
|
37
|
+
"default": "./dist/voice-runs-audio.js"
|
|
33
38
|
}
|
|
34
39
|
},
|
|
35
40
|
"files": [
|
|
@@ -37,14 +42,14 @@
|
|
|
37
42
|
"README.md"
|
|
38
43
|
],
|
|
39
44
|
"dependencies": {
|
|
40
|
-
"js-yaml": "^4.
|
|
45
|
+
"js-yaml": "^4.3.2",
|
|
41
46
|
"typescript": "^5.6.0",
|
|
42
47
|
"zod": "^4.1.13"
|
|
43
48
|
},
|
|
44
49
|
"devDependencies": {
|
|
45
50
|
"@types/js-yaml": "^4.0.9",
|
|
46
51
|
"@types/node": "^22.0.0",
|
|
47
|
-
"vitest": "^4.1.
|
|
52
|
+
"vitest": "^4.1.11"
|
|
48
53
|
},
|
|
49
54
|
"engines": {
|
|
50
55
|
"node": ">=20"
|