Skip to content

Commit 31b9f79

Browse files
committed
feat: Implement AI Orchestration Protocol with comprehensive schemas and tests
- Added orchestration.zod.ts defining AI orchestration schemas including triggers, tasks, and post-processing actions. - Created orchestration.test.ts to validate the functionality of the new orchestration schemas. - Removed deprecated workflow-automation.zod.ts to streamline the codebase.
1 parent 2943302 commit 31b9f79

File tree

2 files changed

+65
-64
lines changed

2 files changed

+65
-64
lines changed

packages/spec/src/ai/workflow-automation.test.ts renamed to packages/spec/src/ai/orchestration.test.ts

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
import { describe, it, expect } from 'vitest';
22
import {
3-
AIWorkflowAutomationSchema,
4-
AIWorkflowTriggerSchema,
3+
AIOrchestrationSchema,
4+
AIOrchestrationTriggerSchema,
55
AITaskTypeSchema,
66
AITaskSchema,
77
WorkflowFieldConditionSchema,
88
WorkflowScheduleSchema,
99
PostProcessingActionSchema,
10-
BatchAIWorkflowExecutionSchema,
11-
AIWorkflowExecutionResultSchema,
12-
type AIWorkflowAutomation,
10+
BatchAIOrchestrationExecutionSchema,
11+
AIOrchestrationExecutionResultSchema,
12+
type AIOrchestration,
1313
type AITask,
14-
} from './workflow-automation.zod';
14+
} from './orchestration.zod';
1515

16-
describe('AIWorkflowTriggerSchema', () => {
16+
describe('AIOrchestrationTriggerSchema', () => {
1717
it('should accept all trigger types', () => {
1818
const triggers = [
1919
'record_created',
@@ -26,7 +26,7 @@ describe('AIWorkflowTriggerSchema', () => {
2626
] as const;
2727

2828
triggers.forEach(trigger => {
29-
expect(() => AIWorkflowTriggerSchema.parse(trigger)).not.toThrow();
29+
expect(() => AIOrchestrationTriggerSchema.parse(trigger)).not.toThrow();
3030
});
3131
});
3232
});
@@ -253,10 +253,10 @@ describe('PostProcessingActionSchema', () => {
253253
});
254254
});
255255

256-
describe('AIWorkflowAutomationSchema', () => {
256+
describe('AIOrchestrationSchema', () => {
257257
describe('Basic Properties', () => {
258258
it('should accept minimal workflow', () => {
259-
const workflow: AIWorkflowAutomation = {
259+
const workflow: AIOrchestration = {
260260
name: 'auto_classify_tickets',
261261
label: 'Auto-classify Support Tickets',
262262
objectName: 'support_ticket',
@@ -272,7 +272,7 @@ describe('AIWorkflowAutomationSchema', () => {
272272
],
273273
};
274274

275-
const result = AIWorkflowAutomationSchema.parse(workflow);
275+
const result = AIOrchestrationSchema.parse(workflow);
276276
expect(result.active).toBe(true);
277277
expect(result.version).toBe('1.0.0');
278278
expect(result.executionMode).toBe('sequential');
@@ -283,7 +283,7 @@ describe('AIWorkflowAutomationSchema', () => {
283283
it('should enforce snake_case for workflow name', () => {
284284
const validNames = ['auto_classify', 'lead_scoring', '_internal_workflow'];
285285
validNames.forEach(name => {
286-
expect(() => AIWorkflowAutomationSchema.parse({
286+
expect(() => AIOrchestrationSchema.parse({
287287
name,
288288
label: 'Test',
289289
objectName: 'test_object',
@@ -299,7 +299,7 @@ describe('AIWorkflowAutomationSchema', () => {
299299

300300
const invalidNames = ['autoClassify', 'Auto-Classify', '123workflow'];
301301
invalidNames.forEach(name => {
302-
expect(() => AIWorkflowAutomationSchema.parse({
302+
expect(() => AIOrchestrationSchema.parse({
303303
name,
304304
label: 'Test',
305305
objectName: 'test_object',
@@ -317,7 +317,7 @@ describe('AIWorkflowAutomationSchema', () => {
317317

318318
describe('Field Change Trigger', () => {
319319
it('should accept field change workflow', () => {
320-
const workflow: AIWorkflowAutomation = {
320+
const workflow: AIOrchestration = {
321321
name: 'priority_change_handler',
322322
label: 'Handle Priority Changes',
323323
objectName: 'ticket',
@@ -339,13 +339,13 @@ describe('AIWorkflowAutomationSchema', () => {
339339
],
340340
};
341341

342-
expect(() => AIWorkflowAutomationSchema.parse(workflow)).not.toThrow();
342+
expect(() => AIOrchestrationSchema.parse(workflow)).not.toThrow();
343343
});
344344
});
345345

346346
describe('Scheduled Workflow', () => {
347347
it('should accept scheduled workflow', () => {
348-
const workflow: AIWorkflowAutomation = {
348+
const workflow: AIOrchestration = {
349349
name: 'daily_lead_scoring',
350350
label: 'Daily Lead Scoring',
351351
objectName: 'lead',
@@ -366,13 +366,13 @@ describe('AIWorkflowAutomationSchema', () => {
366366
],
367367
};
368368

369-
expect(() => AIWorkflowAutomationSchema.parse(workflow)).not.toThrow();
369+
expect(() => AIOrchestrationSchema.parse(workflow)).not.toThrow();
370370
});
371371
});
372372

373373
describe('Complex Workflows', () => {
374374
it('should accept workflow with multiple AI tasks', () => {
375-
const workflow: AIWorkflowAutomation = {
375+
const workflow: AIOrchestration = {
376376
name: 'comprehensive_ticket_handler',
377377
label: 'Comprehensive Ticket Handler',
378378
objectName: 'support_ticket',
@@ -421,11 +421,11 @@ describe('AIWorkflowAutomationSchema', () => {
421421
],
422422
};
423423

424-
expect(() => AIWorkflowAutomationSchema.parse(workflow)).not.toThrow();
424+
expect(() => AIOrchestrationSchema.parse(workflow)).not.toThrow();
425425
});
426426

427427
it('should accept workflow with all features', () => {
428-
const workflow: AIWorkflowAutomation = {
428+
const workflow: AIOrchestration = {
429429
name: 'advanced_automation',
430430
label: 'Advanced Automation Workflow',
431431
description: 'Comprehensive AI-powered automation',
@@ -474,19 +474,19 @@ describe('AIWorkflowAutomationSchema', () => {
474474
owner: 'user_123',
475475
};
476476

477-
expect(() => AIWorkflowAutomationSchema.parse(workflow)).not.toThrow();
477+
expect(() => AIOrchestrationSchema.parse(workflow)).not.toThrow();
478478
});
479479
});
480480
});
481481

482-
describe('BatchAIWorkflowExecutionSchema', () => {
482+
describe('BatchAIOrchestrationExecutionSchema', () => {
483483
it('should accept batch execution request', () => {
484484
const request = {
485485
workflowName: 'auto_classify_tickets',
486486
recordIds: ['rec_1', 'rec_2', 'rec_3'],
487487
};
488488

489-
const result = BatchAIWorkflowExecutionSchema.parse(request);
489+
const result = BatchAIOrchestrationExecutionSchema.parse(request);
490490
expect(result.batchSize).toBe(10);
491491
expect(result.parallelism).toBe(3);
492492
expect(result.priority).toBe('normal');
@@ -501,25 +501,25 @@ describe('BatchAIWorkflowExecutionSchema', () => {
501501
priority: 'high' as const,
502502
};
503503

504-
expect(() => BatchAIWorkflowExecutionSchema.parse(request)).not.toThrow();
504+
expect(() => BatchAIOrchestrationExecutionSchema.parse(request)).not.toThrow();
505505
});
506506

507507
it('should enforce batch size limits', () => {
508-
expect(() => BatchAIWorkflowExecutionSchema.parse({
508+
expect(() => BatchAIOrchestrationExecutionSchema.parse({
509509
workflowName: 'test',
510510
recordIds: ['rec_1'],
511511
batchSize: 0,
512512
})).toThrow();
513513

514-
expect(() => BatchAIWorkflowExecutionSchema.parse({
514+
expect(() => BatchAIOrchestrationExecutionSchema.parse({
515515
workflowName: 'test',
516516
recordIds: ['rec_1'],
517517
batchSize: 1001,
518518
})).toThrow();
519519
});
520520
});
521521

522-
describe('AIWorkflowExecutionResultSchema', () => {
522+
describe('AIOrchestrationExecutionResultSchema', () => {
523523
it('should accept successful execution result', () => {
524524
const result = {
525525
workflowName: 'auto_classify_tickets',
@@ -533,7 +533,7 @@ describe('AIWorkflowExecutionResultSchema', () => {
533533
completedAt: '2024-01-01T10:00:01Z',
534534
};
535535

536-
expect(() => AIWorkflowExecutionResultSchema.parse(result)).not.toThrow();
536+
expect(() => AIOrchestrationExecutionResultSchema.parse(result)).not.toThrow();
537537
});
538538

539539
it('should accept result with task details', () => {
@@ -571,7 +571,7 @@ describe('AIWorkflowExecutionResultSchema', () => {
571571
completedAt: '2024-01-01T10:00:02Z',
572572
};
573573

574-
expect(() => AIWorkflowExecutionResultSchema.parse(result)).not.toThrow();
574+
expect(() => AIOrchestrationExecutionResultSchema.parse(result)).not.toThrow();
575575
});
576576

577577
it('should accept failed execution result', () => {
@@ -587,13 +587,13 @@ describe('AIWorkflowExecutionResultSchema', () => {
587587
startedAt: '2024-01-01T10:00:00Z',
588588
};
589589

590-
expect(() => AIWorkflowExecutionResultSchema.parse(result)).not.toThrow();
590+
expect(() => AIOrchestrationExecutionResultSchema.parse(result)).not.toThrow();
591591
});
592592
});
593593

594594
describe('Real-World Workflow Examples', () => {
595595
it('should accept customer support ticket automation', () => {
596-
const workflow: AIWorkflowAutomation = {
596+
const workflow: AIOrchestration = {
597597
name: 'auto_triage_support_tickets',
598598
label: 'Auto-Triage Support Tickets',
599599
description: 'Automatically classify, prioritize, and route support tickets',
@@ -654,11 +654,11 @@ describe('Real-World Workflow Examples', () => {
654654
tags: ['automation', 'ai', 'support'],
655655
};
656656

657-
expect(() => AIWorkflowAutomationSchema.parse(workflow)).not.toThrow();
657+
expect(() => AIOrchestrationSchema.parse(workflow)).not.toThrow();
658658
});
659659

660660
it('should accept lead scoring automation', () => {
661-
const workflow: AIWorkflowAutomation = {
661+
const workflow: AIOrchestration = {
662662
name: 'ai_lead_scoring',
663663
label: 'AI-Powered Lead Scoring',
664664
objectName: 'lead',
@@ -715,11 +715,11 @@ describe('Real-World Workflow Examples', () => {
715715
tags: ['lead-scoring', 'ml', 'automation'],
716716
};
717717

718-
expect(() => AIWorkflowAutomationSchema.parse(workflow)).not.toThrow();
718+
expect(() => AIOrchestrationSchema.parse(workflow)).not.toThrow();
719719
});
720720

721721
it('should accept document processing workflow', () => {
722-
const workflow: AIWorkflowAutomation = {
722+
const workflow: AIOrchestration = {
723723
name: 'process_invoice_documents',
724724
label: 'Process Invoice Documents',
725725
objectName: 'invoice',
@@ -784,6 +784,6 @@ describe('Real-World Workflow Examples', () => {
784784
tags: ['document-processing', 'ocr', 'automation'],
785785
};
786786

787-
expect(() => AIWorkflowAutomationSchema.parse(workflow)).not.toThrow();
787+
expect(() => AIOrchestrationSchema.parse(workflow)).not.toThrow();
788788
});
789789
});

packages/spec/src/ai/workflow-automation.zod.ts renamed to packages/spec/src/ai/orchestration.zod.ts

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,26 @@
11
import { z } from 'zod';
22

33
/**
4-
* AI Workflow Automation Protocol
4+
* AI Agentic Orchestration Protocol
55
*
6-
* Defines intelligent automation workflows that leverage AI/ML capabilities
7-
* to automate business processes with cognitive tasks like classification,
8-
* extraction, summarization, content generation, and prediction.
6+
* Defines intelligent orchestration flows where AI Agents leverage cognitive skills
7+
* to automate business processes with dynamic reasoning, planning, and execution.
8+
*
9+
* Distinction from Standard Workflows:
10+
* - Standard Workflow: Deterministic (If X then Y). defined in src/data/workflow.zod.ts
11+
* - AI Orchestration: Probabilistic & Agentic (Goal -> Plan -> Execute).
912
*
1013
* Use Cases:
11-
* - Automatically classify support tickets by urgency and route to teams
12-
* - Extract key information from documents and populate fields
13-
* - Generate summaries of long text content
14-
* - Predict lead scores or customer churn risk
15-
* - Auto-fill forms based on natural language input
14+
* - Complex Support Triage (Analyze sentiment + intent -> Draft response -> Route)
15+
* - Intelligent Document Processing (OCR -> Extract Entities -> Validate -> Entry)
16+
* - Research Agent (Search Web -> Summarize -> Generate Report)
1617
*/
1718

1819
/**
19-
* Workflow Trigger Types
20-
* Defines when an AI workflow should be initiated
20+
* Orchestration Trigger Types
21+
* Defines when an AI Agentic Flow should be initiated
2122
*/
22-
export const AIWorkflowTriggerSchema = z.enum([
23+
export const AIOrchestrationTriggerSchema = z.enum([
2324
'record_created', // When a new record is created
2425
'record_updated', // When a record is updated
2526
'field_changed', // When specific field(s) change
@@ -127,20 +128,20 @@ export const PostProcessingActionSchema = z.object({
127128
});
128129

129130
/**
130-
* AI Workflow Automation Schema
131+
* AI Agentic Orchestration Schema
131132
* Complete workflow definition with AI-powered tasks
132133
*/
133-
export const AIWorkflowAutomationSchema = z.object({
134+
export const AIOrchestrationSchema = z.object({
134135
/** Identity */
135-
name: z.string().regex(/^[a-z_][a-z0-9_]*$/).describe('Workflow unique identifier (snake_case)'),
136-
label: z.string().describe('Workflow display name'),
136+
name: z.string().regex(/^[a-z_][a-z0-9_]*$/).describe('Orchestration unique identifier (snake_case)'),
137+
label: z.string().describe('Display name'),
137138
description: z.string().optional(),
138139

139140
/** Target Object */
140-
objectName: z.string().describe('Target object for this workflow'),
141+
objectName: z.string().describe('Target object for this orchestration'),
141142

142143
/** Trigger Configuration */
143-
trigger: AIWorkflowTriggerSchema,
144+
trigger: AIOrchestrationTriggerSchema,
144145

145146
/** Trigger-specific configuration */
146147
fieldConditions: z.array(WorkflowFieldConditionSchema).optional().describe('Fields to monitor (for field_changed trigger)'),
@@ -185,22 +186,22 @@ export const AIWorkflowAutomationSchema = z.object({
185186
});
186187

187188
/**
188-
* Batch AI Workflow Execution Request
189+
* Batch AI Orchestration Execution Request
189190
* For processing multiple records at once
190191
*/
191-
export const BatchAIWorkflowExecutionSchema = z.object({
192-
workflowName: z.string().describe('Workflow to execute'),
192+
export const BatchAIOrchestrationExecutionSchema = z.object({
193+
workflowName: z.string().describe('Orchestration to execute'),
193194
recordIds: z.array(z.string()).describe('Records to process'),
194195
batchSize: z.number().int().min(1).max(1000).optional().default(10),
195196
parallelism: z.number().int().min(1).max(10).optional().default(3),
196197
priority: z.enum(['low', 'normal', 'high']).optional().default('normal'),
197198
});
198199

199200
/**
200-
* AI Workflow Execution Result
201-
* Result of a single workflow execution
201+
* AI Orchestration Execution Result
202+
* Result of a single execution
202203
*/
203-
export const AIWorkflowExecutionResultSchema = z.object({
204+
export const AIOrchestrationExecutionResultSchema = z.object({
204205
workflowName: z.string(),
205206
recordId: z.string(),
206207
status: z.enum(['success', 'partial_success', 'failed', 'skipped']),
@@ -224,12 +225,12 @@ export const AIWorkflowExecutionResultSchema = z.object({
224225
});
225226

226227
// Type exports
227-
export type AIWorkflowTrigger = z.infer<typeof AIWorkflowTriggerSchema>;
228+
export type AIOrchestrationTrigger = z.infer<typeof AIOrchestrationTriggerSchema>;
228229
export type AITaskType = z.infer<typeof AITaskTypeSchema>;
229230
export type AITask = z.infer<typeof AITaskSchema>;
230231
export type WorkflowFieldCondition = z.infer<typeof WorkflowFieldConditionSchema>;
231232
export type WorkflowSchedule = z.infer<typeof WorkflowScheduleSchema>;
232233
export type PostProcessingAction = z.infer<typeof PostProcessingActionSchema>;
233-
export type AIWorkflowAutomation = z.infer<typeof AIWorkflowAutomationSchema>;
234-
export type BatchAIWorkflowExecution = z.infer<typeof BatchAIWorkflowExecutionSchema>;
235-
export type AIWorkflowExecutionResult = z.infer<typeof AIWorkflowExecutionResultSchema>;
234+
export type AIOrchestration = z.infer<typeof AIOrchestrationSchema>;
235+
export type BatchAIOrchestrationExecution = z.infer<typeof BatchAIOrchestrationExecutionSchema>;
236+
export type AIOrchestrationExecutionResult = z.infer<typeof AIOrchestrationExecutionResultSchema>;

0 commit comments

Comments
 (0)