Skip to content

Commit 5c8f826

Browse files
authored
Merge pull request #35 from vcon-dev/CON-349/relax-validation-for-dispositions-in-vcon-mcp
Refactor dialog disposition handling to accept any string value
2 parents 8e28799 + 2b4cfc8 commit 5c8f826

5 files changed

Lines changed: 19 additions & 17 deletions

File tree

src/tools/vcon-crud.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export const DialogSchema = z.object({
5656
encoding: z.enum(['base64url', 'json', 'none']).optional(),
5757
url: z.string().optional(),
5858
content_hash: z.union([z.string(), z.array(z.string())]).optional(),
59-
disposition: z.enum(['no-answer', 'congestion', 'failed', 'busy', 'hung-up', 'voicemail-no-message']).optional(),
59+
disposition: z.string().optional().describe('Call disposition; any string accepted (spec suggests no-answer, congestion, failed, busy, hung-up, voicemail-no-message)'),
6060
session_id: z.string().optional().describe('Session identifier'), // ✅ New field
6161
application: z.string().optional().describe('Application that created this dialog'), // ✅ New field
6262
message_id: z.string().optional().describe('Message identifier'), // ✅ New field

src/types/vcon.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ export interface Dialog {
107107
url?: string; // HTTPS URL to external content
108108
content_hash?: string | string[]; // SHA-256 hash for integrity verification
109109

110-
disposition?: DialogDisposition;
110+
disposition?: string; // Any string accepted; spec suggests no-answer, congestion, failed, busy, hung-up, voicemail-no-message
111111
session_id?: string; // Section 4.3.10 - Session identifier
112112
party_history?: PartyHistory[]; // Section 4.3.11
113113
application?: string; // Section 4.3.13 - Application identifier
@@ -249,10 +249,11 @@ export function isValidEncoding(encoding: string): encoding is Encoding {
249249
}
250250

251251
/**
252-
* Type guard to check if a string is a valid DialogDisposition
252+
* Accept any non-empty string as disposition (forgiving of values outside spec).
253+
* Spec suggests: no-answer, congestion, failed, busy, hung-up, voicemail-no-message.
253254
*/
254-
export function isValidDisposition(disposition: string): disposition is DialogDisposition {
255-
return ['no-answer', 'congestion', 'failed', 'busy', 'hung-up', 'voicemail-no-message'].includes(disposition);
255+
export function isValidDisposition(disposition: string): boolean {
256+
return typeof disposition === 'string';
256257
}
257258

258259
/**

src/utils/validation.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ import {
1111
Dialog,
1212
Party,
1313
isValidDialogType,
14-
isValidEncoding,
15-
isValidDisposition
14+
isValidEncoding
1615
} from '../types/vcon.js';
1716

1817
export interface ValidationResult {
@@ -114,16 +113,13 @@ export class VConValidator {
114113
);
115114
}
116115

117-
// Incomplete dialogs must have disposition
116+
// Incomplete dialogs must have disposition (any string is accepted)
118117
if (dialog.type === 'incomplete' && !dialog.disposition) {
119118
this.errors.push(`Dialog ${index} is incomplete but has no disposition`);
120119
}
121120

122-
// Validate disposition values
123-
if (dialog.disposition && !isValidDisposition(dialog.disposition)) {
124-
this.errors.push(
125-
`Dialog ${index} has invalid disposition: ${dialog.disposition}`
126-
);
121+
if (dialog.disposition != null && typeof dialog.disposition !== 'string') {
122+
this.errors.push(`Dialog ${index} disposition must be a string`);
127123
}
128124

129125
// Transfer dialogs must have transfer fields
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
-- Allow any string for dialog.disposition (forgiving of values outside spec).
2+
-- Spec suggests: no-answer, congestion, failed, busy, hung-up, voicemail-no-message.
3+
-- Drop the CHECK that restricted to only those values.
4+
ALTER TABLE dialog DROP CONSTRAINT IF EXISTS dialog_disposition_check;

tests/crud-schemas.test.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,11 @@ describe('CRUD Schema Validation', () => {
178178
}
179179
});
180180

181-
it('should validate disposition values', () => {
182-
const validDispositions = ['no-answer', 'congestion', 'failed', 'busy', 'hung-up', 'voicemail-no-message'];
183-
184-
validDispositions.forEach(disposition => {
181+
it('should accept any string for disposition (spec values and custom)', () => {
182+
const specDispositions = ['no-answer', 'congestion', 'failed', 'busy', 'hung-up', 'voicemail-no-message'];
183+
const customDispositions = ['Customer Hung Up', 'Abandoned', ''];
184+
185+
[...specDispositions, ...customDispositions].forEach(disposition => {
185186
const dialog = {
186187
type: 'incomplete',
187188
disposition,

0 commit comments

Comments
 (0)