musubi-sdd 3.7.1 → 3.8.0
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.ja.md +8 -8
- package/README.md +8 -7
- package/bin/musubi-orchestrate.js +317 -1
- package/package.json +1 -1
- package/src/orchestration/index.js +39 -1
- package/src/orchestration/orchestration-engine.js +5 -1
- package/src/orchestration/patterns/handoff.js +558 -0
- package/src/orchestration/patterns/triage.js +818 -0
package/README.ja.md
CHANGED
|
@@ -71,14 +71,14 @@ musubi init --windsurf # Windsurf IDE
|
|
|
71
71
|
|
|
72
72
|
---
|
|
73
73
|
|
|
74
|
-
## 📊
|
|
75
|
-
|
|
76
|
-
-
|
|
77
|
-
-
|
|
78
|
-
-
|
|
79
|
-
-
|
|
80
|
-
-
|
|
81
|
-
-
|
|
74
|
+
## 📊 v3.7.1 の新機能
|
|
75
|
+
|
|
76
|
+
- 🌐 **WebSocketリアルタイムGUI** - `musubi-browser`ダッシュボードでライブ更新
|
|
77
|
+
- 📋 **GUIクイックアクション** - 新規要件モーダル、プロジェクト検証、レポートエクスポート
|
|
78
|
+
- 🔄 **GitHub Actions統合** - `musubi-action`でCI/CD検証
|
|
79
|
+
- 🔧 **OpenAPIコンバーター** - OpenAPI 3.x/Swagger 2.xスペックをMUSUBI形式に変換
|
|
80
|
+
- 🌍 **多言語テンプレート** - 7言語対応(EN, JA, ZH, KO, ES, DE, FR)
|
|
81
|
+
- 🤖 **Ollama統合** - 9つのモデルプリセットでローカルLLMをサポート
|
|
82
82
|
|
|
83
83
|
### 以前のバージョン (v2.0.0)
|
|
84
84
|
|
package/README.md
CHANGED
|
@@ -71,13 +71,14 @@ musubi init --windsurf # Windsurf IDE
|
|
|
71
71
|
|
|
72
72
|
---
|
|
73
73
|
|
|
74
|
-
## 📊 What's New in v3.
|
|
75
|
-
|
|
76
|
-
-
|
|
77
|
-
-
|
|
78
|
-
- 🔄 **
|
|
79
|
-
-
|
|
80
|
-
-
|
|
74
|
+
## 📊 What's New in v3.7.1
|
|
75
|
+
|
|
76
|
+
- 🌐 **WebSocket Real-time GUI** - Live replanning updates with `musubi-browser` dashboard
|
|
77
|
+
- 📋 **GUI Quick Actions** - Modal dialog for New Requirement, Validate Project, Export Report
|
|
78
|
+
- 🔄 **GitHub Actions Integration** - `musubi-action` for CI/CD with MUSUBI validation
|
|
79
|
+
- 🔧 **OpenAPI Converter** - Convert OpenAPI 3.x/Swagger 2.x specs to MUSUBI format
|
|
80
|
+
- 🌍 **Multi-language Templates** - 7 language support (EN, JA, ZH, KO, ES, DE, FR)
|
|
81
|
+
- 🤖 **Ollama Integration** - Local LLM support with 9 model presets
|
|
81
82
|
|
|
82
83
|
### Previous (v3.6.0)
|
|
83
84
|
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
* musubi-orchestrate run <pattern> --skills <skills...> # Execute pattern with skills
|
|
10
10
|
* musubi-orchestrate auto <task> # Auto-select and execute skill
|
|
11
11
|
* musubi-orchestrate sequential --skills <skills...> # Execute skills sequentially
|
|
12
|
+
* musubi-orchestrate handoff --from <agent> --to <agent> # Delegate to another agent
|
|
13
|
+
* musubi-orchestrate triage --message <msg> # Classify and route request
|
|
12
14
|
* musubi-orchestrate list-patterns # List available patterns
|
|
13
15
|
* musubi-orchestrate list-skills # List available skills
|
|
14
16
|
* musubi-orchestrate status # Show orchestration status
|
|
@@ -23,7 +25,15 @@ const {
|
|
|
23
25
|
createOrchestrationEngine,
|
|
24
26
|
PatternType,
|
|
25
27
|
ExecutionStatus,
|
|
26
|
-
Priority
|
|
28
|
+
Priority,
|
|
29
|
+
HandoffPattern,
|
|
30
|
+
HandoffFilters,
|
|
31
|
+
HandoffConfig,
|
|
32
|
+
handoff,
|
|
33
|
+
TriagePattern,
|
|
34
|
+
TriageCategory,
|
|
35
|
+
TriageStrategy,
|
|
36
|
+
AgentCapability
|
|
27
37
|
} = require('../src/orchestration');
|
|
28
38
|
|
|
29
39
|
const {
|
|
@@ -758,6 +768,312 @@ program
|
|
|
758
768
|
}
|
|
759
769
|
});
|
|
760
770
|
|
|
771
|
+
// Handoff command - Explicit agent-to-agent delegation
|
|
772
|
+
program
|
|
773
|
+
.command('handoff')
|
|
774
|
+
.description('Execute handoff pattern - Delegate task to another agent')
|
|
775
|
+
.requiredOption('-t, --task <task>', 'Task to handoff')
|
|
776
|
+
.requiredOption('--from <agent>', 'Source agent')
|
|
777
|
+
.requiredOption('--to <agent>', 'Target agent')
|
|
778
|
+
.option('-s, --skills <skills...>', 'Available skills/agents')
|
|
779
|
+
.option('--filter <filter>', 'Input filter (removeAllTools|userMessagesOnly|lastN|summarize|keepAll)', 'keepAll')
|
|
780
|
+
.option('--filter-n <n>', 'N value for lastN filter', '10')
|
|
781
|
+
.option('--reason <reason>', 'Handoff reason')
|
|
782
|
+
.option('--priority <priority>', 'Priority (low|normal|high|urgent)', 'normal')
|
|
783
|
+
.option('-i, --input <json>', 'Additional input data as JSON')
|
|
784
|
+
.option('-f, --format <type>', 'Output format (text|json)', 'text')
|
|
785
|
+
.action(async (options) => {
|
|
786
|
+
try {
|
|
787
|
+
console.log(chalk.bold('\n🤝 Handoff Pattern - Agent Delegation\n'));
|
|
788
|
+
console.log(chalk.dim(`From: ${options.from} → To: ${options.to}\n`));
|
|
789
|
+
|
|
790
|
+
const engine = await createEngine(process.cwd());
|
|
791
|
+
|
|
792
|
+
// Parse additional input
|
|
793
|
+
const additionalInput = options.input ? JSON.parse(options.input) : {};
|
|
794
|
+
|
|
795
|
+
// Select input filter
|
|
796
|
+
let inputFilter;
|
|
797
|
+
switch (options.filter) {
|
|
798
|
+
case 'removeAllTools':
|
|
799
|
+
inputFilter = HandoffFilters.removeAllTools;
|
|
800
|
+
break;
|
|
801
|
+
case 'userMessagesOnly':
|
|
802
|
+
inputFilter = HandoffFilters.userMessagesOnly;
|
|
803
|
+
break;
|
|
804
|
+
case 'lastN':
|
|
805
|
+
inputFilter = HandoffFilters.lastN(parseInt(options.filterN, 10));
|
|
806
|
+
break;
|
|
807
|
+
case 'summarize':
|
|
808
|
+
inputFilter = HandoffFilters.summarize;
|
|
809
|
+
break;
|
|
810
|
+
default:
|
|
811
|
+
inputFilter = HandoffFilters.keepAll;
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
// Create handoff configuration
|
|
815
|
+
const handoffConfig = new HandoffConfig({
|
|
816
|
+
targetAgent: options.to,
|
|
817
|
+
reason: options.reason || `Handoff from ${options.from} to ${options.to}`,
|
|
818
|
+
inputFilter,
|
|
819
|
+
priority: options.priority
|
|
820
|
+
});
|
|
821
|
+
|
|
822
|
+
// Prepare agent definitions
|
|
823
|
+
const agents = [];
|
|
824
|
+
const skills = options.skills || [options.from, options.to];
|
|
825
|
+
|
|
826
|
+
for (const skillName of skills) {
|
|
827
|
+
const skill = engine.getSkill(skillName);
|
|
828
|
+
if (skill) {
|
|
829
|
+
agents.push({
|
|
830
|
+
name: skillName,
|
|
831
|
+
...skill,
|
|
832
|
+
handoffs: skillName === options.from ? [handoffConfig] : []
|
|
833
|
+
});
|
|
834
|
+
} else {
|
|
835
|
+
// Create placeholder agent
|
|
836
|
+
agents.push({
|
|
837
|
+
name: skillName,
|
|
838
|
+
description: `${skillName} agent`,
|
|
839
|
+
execute: async (input) => ({ agent: skillName, input, executed: true }),
|
|
840
|
+
handoffs: skillName === options.from ? [handoffConfig] : []
|
|
841
|
+
});
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
// Create target agents array as required by HandoffPattern
|
|
846
|
+
const targetAgent = agents.find(a => a.name === options.to) || {
|
|
847
|
+
name: options.to,
|
|
848
|
+
description: `${options.to} agent`,
|
|
849
|
+
execute: async (input) => ({ agent: options.to, input, executed: true })
|
|
850
|
+
};
|
|
851
|
+
|
|
852
|
+
const context = await engine.execute(PatternType.HANDOFF, {
|
|
853
|
+
task: options.task,
|
|
854
|
+
input: {
|
|
855
|
+
sourceAgent: options.from,
|
|
856
|
+
targetAgents: [targetAgent], // Array of target agents
|
|
857
|
+
agents,
|
|
858
|
+
reason: options.reason || `Handoff from ${options.from} to ${options.to}`,
|
|
859
|
+
...additionalInput
|
|
860
|
+
}
|
|
861
|
+
});
|
|
862
|
+
|
|
863
|
+
if (options.format === 'json') {
|
|
864
|
+
console.log(JSON.stringify({
|
|
865
|
+
success: context.status === ExecutionStatus.COMPLETED,
|
|
866
|
+
sourceAgent: options.from,
|
|
867
|
+
targetAgent: options.to,
|
|
868
|
+
result: context.output,
|
|
869
|
+
handoffChain: context.output?.handoffChain || []
|
|
870
|
+
}, null, 2));
|
|
871
|
+
} else {
|
|
872
|
+
if (context.status === ExecutionStatus.COMPLETED) {
|
|
873
|
+
console.log(chalk.green('✓ Handoff completed successfully\n'));
|
|
874
|
+
|
|
875
|
+
if (context.output?.handoffChain) {
|
|
876
|
+
console.log(chalk.bold('Handoff Chain:'));
|
|
877
|
+
for (const hop of context.output.handoffChain) {
|
|
878
|
+
console.log(` ${chalk.cyan(hop.from)} → ${chalk.yellow(hop.to)}`);
|
|
879
|
+
if (hop.reason) {
|
|
880
|
+
console.log(chalk.dim(` Reason: ${hop.reason}`));
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
console.log('');
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
console.log(chalk.bold('Result:'));
|
|
887
|
+
console.log(` Final Agent: ${chalk.cyan(context.output?.finalAgent || options.to)}`);
|
|
888
|
+
console.log(` Status: ${chalk.green('Completed')}`);
|
|
889
|
+
} else {
|
|
890
|
+
console.log(chalk.red(`✗ Handoff failed: ${context.error}\n`));
|
|
891
|
+
process.exit(1);
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
console.log('');
|
|
896
|
+
|
|
897
|
+
} catch (error) {
|
|
898
|
+
console.error(chalk.red(`\n✗ Error: ${error.message}\n`));
|
|
899
|
+
if (process.env.DEBUG) {
|
|
900
|
+
console.error(error.stack);
|
|
901
|
+
}
|
|
902
|
+
process.exit(1);
|
|
903
|
+
}
|
|
904
|
+
});
|
|
905
|
+
|
|
906
|
+
// Triage command - Request classification and routing
|
|
907
|
+
program
|
|
908
|
+
.command('triage')
|
|
909
|
+
.description('Execute triage pattern - Classify and route request to appropriate agent')
|
|
910
|
+
.requiredOption('-m, --message <message>', 'Message/request to classify')
|
|
911
|
+
.option('-s, --skills <skills...>', 'Available agents/skills to route to')
|
|
912
|
+
.option('--strategy <strategy>', 'Classification strategy (keyword|intent|capability|hybrid|llm)', 'hybrid')
|
|
913
|
+
.option('--default-category <category>', 'Default category if no match', 'general')
|
|
914
|
+
.option('--threshold <threshold>', 'Confidence threshold (0-1)', '0.3')
|
|
915
|
+
.option('--auto-handoff', 'Automatically handoff to selected agent', false)
|
|
916
|
+
.option('-f, --format <type>', 'Output format (text|json)', 'text')
|
|
917
|
+
.action(async (options) => {
|
|
918
|
+
try {
|
|
919
|
+
console.log(chalk.bold('\n🎯 Triage Pattern - Request Classification\n'));
|
|
920
|
+
console.log(chalk.dim(`Message: "${options.message.substring(0, 50)}${options.message.length > 50 ? '...' : ''}"\n`));
|
|
921
|
+
|
|
922
|
+
const engine = await createEngine(process.cwd());
|
|
923
|
+
|
|
924
|
+
// Map strategy string to enum
|
|
925
|
+
const strategyMap = {
|
|
926
|
+
'keyword': TriageStrategy.KEYWORD,
|
|
927
|
+
'intent': TriageStrategy.INTENT,
|
|
928
|
+
'capability': TriageStrategy.CAPABILITY,
|
|
929
|
+
'hybrid': TriageStrategy.HYBRID,
|
|
930
|
+
'llm': TriageStrategy.LLM
|
|
931
|
+
};
|
|
932
|
+
|
|
933
|
+
const strategy = strategyMap[options.strategy] || TriageStrategy.HYBRID;
|
|
934
|
+
|
|
935
|
+
// Prepare agents with capabilities
|
|
936
|
+
const agents = [];
|
|
937
|
+
const defaultSkills = [
|
|
938
|
+
{ name: 'billing-agent', categories: [TriageCategory.BILLING, TriageCategory.REFUND], keywords: ['invoice', 'payment', 'refund', 'charge', 'billing'] },
|
|
939
|
+
{ name: 'support-agent', categories: [TriageCategory.SUPPORT], keywords: ['help', 'issue', 'problem', 'broken', 'support'] },
|
|
940
|
+
{ name: 'sales-agent', categories: [TriageCategory.SALES], keywords: ['buy', 'purchase', 'pricing', 'discount', 'order'] },
|
|
941
|
+
{ name: 'technical-agent', categories: [TriageCategory.TECHNICAL], keywords: ['api', 'bug', 'error', 'integration', 'code'] },
|
|
942
|
+
{ name: 'general-agent', categories: [TriageCategory.GENERAL], keywords: [] }
|
|
943
|
+
];
|
|
944
|
+
|
|
945
|
+
const skillNames = options.skills || defaultSkills.map(s => s.name);
|
|
946
|
+
|
|
947
|
+
for (const skillName of skillNames) {
|
|
948
|
+
const skill = engine.getSkill(skillName);
|
|
949
|
+
const defaultSkill = defaultSkills.find(s => s.name === skillName);
|
|
950
|
+
|
|
951
|
+
const agentObj = {
|
|
952
|
+
name: skillName,
|
|
953
|
+
description: skill?.description || `${skillName} agent`,
|
|
954
|
+
execute: skill?.execute || (async (input) => ({ agent: skillName, input, executed: true }))
|
|
955
|
+
};
|
|
956
|
+
|
|
957
|
+
agentObj.capability = new AgentCapability({
|
|
958
|
+
agent: agentObj, // Reference to agent object
|
|
959
|
+
categories: defaultSkill?.categories || [TriageCategory.GENERAL],
|
|
960
|
+
keywords: defaultSkill?.keywords || [],
|
|
961
|
+
priority: 1
|
|
962
|
+
});
|
|
963
|
+
|
|
964
|
+
agents.push(agentObj);
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
const context = await engine.execute(PatternType.TRIAGE, {
|
|
968
|
+
task: 'Classify and route request',
|
|
969
|
+
input: {
|
|
970
|
+
message: options.message,
|
|
971
|
+
agents,
|
|
972
|
+
strategy,
|
|
973
|
+
defaultCategory: options.defaultCategory.toUpperCase(),
|
|
974
|
+
confidenceThreshold: parseFloat(options.threshold),
|
|
975
|
+
enableHandoff: options.autoHandoff // Only handoff if explicitly requested
|
|
976
|
+
}
|
|
977
|
+
});
|
|
978
|
+
|
|
979
|
+
if (options.format === 'json') {
|
|
980
|
+
console.log(JSON.stringify({
|
|
981
|
+
success: context.status === ExecutionStatus.COMPLETED,
|
|
982
|
+
classification: context.output?.classification,
|
|
983
|
+
selectedAgent: context.output?.selectedAgent,
|
|
984
|
+
confidence: context.output?.confidence,
|
|
985
|
+
category: context.output?.category
|
|
986
|
+
}, null, 2));
|
|
987
|
+
} else {
|
|
988
|
+
if (context.status === ExecutionStatus.COMPLETED) {
|
|
989
|
+
console.log(chalk.green('✓ Triage completed\n'));
|
|
990
|
+
|
|
991
|
+
const classification = context.output?.classification || context.output;
|
|
992
|
+
|
|
993
|
+
console.log(chalk.bold('Classification Result:'));
|
|
994
|
+
console.log(` Category: ${chalk.cyan(classification?.category || 'N/A')}`);
|
|
995
|
+
console.log(` Confidence: ${formatConfidence(classification?.confidence || 0)}`);
|
|
996
|
+
if (classification?.reasoning) {
|
|
997
|
+
console.log(` Reasoning: ${chalk.dim(classification.reasoning)}`);
|
|
998
|
+
}
|
|
999
|
+
console.log('');
|
|
1000
|
+
|
|
1001
|
+
if (context.output?.selectedAgent) {
|
|
1002
|
+
console.log(chalk.bold('Routing Decision:'));
|
|
1003
|
+
console.log(` Selected Agent: ${chalk.yellow(context.output.selectedAgent)}`);
|
|
1004
|
+
console.log(` Agent Score: ${(context.output.agentScore || 0).toFixed(2)}`);
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
if (options.autoHandoff && context.output?.handoffResult) {
|
|
1008
|
+
console.log('');
|
|
1009
|
+
console.log(chalk.bold('Handoff Result:'));
|
|
1010
|
+
console.log(` Status: ${chalk.green('Executed')}`);
|
|
1011
|
+
}
|
|
1012
|
+
} else {
|
|
1013
|
+
console.log(chalk.red(`✗ Triage failed: ${context.error}\n`));
|
|
1014
|
+
process.exit(1);
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
console.log('');
|
|
1019
|
+
|
|
1020
|
+
} catch (error) {
|
|
1021
|
+
console.error(chalk.red(`\n✗ Error: ${error.message}\n`));
|
|
1022
|
+
if (process.env.DEBUG) {
|
|
1023
|
+
console.error(error.stack);
|
|
1024
|
+
}
|
|
1025
|
+
process.exit(1);
|
|
1026
|
+
}
|
|
1027
|
+
});
|
|
1028
|
+
|
|
1029
|
+
// Triage categories command - List available categories
|
|
1030
|
+
program
|
|
1031
|
+
.command('triage-categories')
|
|
1032
|
+
.description('List available triage categories')
|
|
1033
|
+
.option('-f, --format <type>', 'Output format (text|json)', 'text')
|
|
1034
|
+
.action(async (options) => {
|
|
1035
|
+
try {
|
|
1036
|
+
console.log(chalk.bold('\n📋 Triage Categories\n'));
|
|
1037
|
+
|
|
1038
|
+
const categories = Object.entries(TriageCategory).map(([key, value]) => ({
|
|
1039
|
+
key,
|
|
1040
|
+
value,
|
|
1041
|
+
description: getCategoryDescription(value)
|
|
1042
|
+
}));
|
|
1043
|
+
|
|
1044
|
+
if (options.format === 'json') {
|
|
1045
|
+
console.log(JSON.stringify(categories, null, 2));
|
|
1046
|
+
} else {
|
|
1047
|
+
for (const cat of categories) {
|
|
1048
|
+
console.log(` ${chalk.cyan(cat.value.padEnd(12))} - ${cat.description}`);
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
console.log('');
|
|
1053
|
+
|
|
1054
|
+
} catch (error) {
|
|
1055
|
+
console.error(chalk.red(`\n✗ Error: ${error.message}\n`));
|
|
1056
|
+
process.exit(1);
|
|
1057
|
+
}
|
|
1058
|
+
});
|
|
1059
|
+
|
|
1060
|
+
/**
|
|
1061
|
+
* Get category description
|
|
1062
|
+
*/
|
|
1063
|
+
function getCategoryDescription(category) {
|
|
1064
|
+
const descriptions = {
|
|
1065
|
+
[TriageCategory.BILLING]: 'Billing, invoices, payments, refunds',
|
|
1066
|
+
[TriageCategory.SUPPORT]: 'General support, help requests, issues',
|
|
1067
|
+
[TriageCategory.SALES]: 'Sales inquiries, purchases, pricing',
|
|
1068
|
+
[TriageCategory.TECHNICAL]: 'Technical issues, bugs, API, integrations',
|
|
1069
|
+
[TriageCategory.REFUND]: 'Refund requests and processing',
|
|
1070
|
+
[TriageCategory.GENERAL]: 'General inquiries, catch-all category',
|
|
1071
|
+
[TriageCategory.ESCALATION]: 'Escalated issues requiring supervisor attention',
|
|
1072
|
+
[TriageCategory.UNKNOWN]: 'Unclassified requests'
|
|
1073
|
+
};
|
|
1074
|
+
return descriptions[category] || 'Unknown category';
|
|
1075
|
+
}
|
|
1076
|
+
|
|
761
1077
|
program.parse(process.argv);
|
|
762
1078
|
|
|
763
1079
|
if (!process.argv.slice(2).length) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "musubi-sdd",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.8.0",
|
|
4
4
|
"description": "Ultimate Specification Driven Development Tool with 27 Agents for 7 AI Coding Platforms + MCP Integration (Claude Code, GitHub Copilot, Cursor, Gemini CLI, Windsurf, Codex, Qwen Code)",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -6,8 +6,10 @@
|
|
|
6
6
|
* - Sequential: Linear skill execution
|
|
7
7
|
* - Nested: Hierarchical skill delegation
|
|
8
8
|
* - GroupChat: Multi-skill collaborative discussion
|
|
9
|
-
* - Swarm: Parallel skill execution
|
|
9
|
+
* - Swarm: Parallel skill execution
|
|
10
10
|
* - HumanInLoop: Validation gates
|
|
11
|
+
* - Handoff: Explicit agent-to-agent delegation (OpenAI Agents SDK inspired)
|
|
12
|
+
* - Triage: Request classification and routing (OpenAI Agents SDK inspired)
|
|
11
13
|
*/
|
|
12
14
|
|
|
13
15
|
const {
|
|
@@ -63,6 +65,25 @@ const {
|
|
|
63
65
|
createSwarmPattern
|
|
64
66
|
} = require('./patterns/swarm');
|
|
65
67
|
|
|
68
|
+
const {
|
|
69
|
+
HandoffPattern,
|
|
70
|
+
HandoffFilters,
|
|
71
|
+
EscalationData,
|
|
72
|
+
HandoffConfig,
|
|
73
|
+
handoff,
|
|
74
|
+
createHandoffPattern
|
|
75
|
+
} = require('./patterns/handoff');
|
|
76
|
+
|
|
77
|
+
const {
|
|
78
|
+
TriagePattern,
|
|
79
|
+
TriageCategory,
|
|
80
|
+
TriageStrategy,
|
|
81
|
+
AgentCapability,
|
|
82
|
+
TriageResult,
|
|
83
|
+
DEFAULT_KEYWORD_MAPPINGS,
|
|
84
|
+
createTriagePattern
|
|
85
|
+
} = require('./patterns/triage');
|
|
86
|
+
|
|
66
87
|
const {
|
|
67
88
|
WorkflowOrchestrator,
|
|
68
89
|
StepType,
|
|
@@ -102,6 +123,8 @@ function createOrchestrationEngine(options = {}) {
|
|
|
102
123
|
registry.register(PatternType.GROUP_CHAT, createGroupChatPattern());
|
|
103
124
|
registry.register(PatternType.HUMAN_IN_LOOP, createHumanInLoopPattern());
|
|
104
125
|
registry.register(PatternType.SWARM, createSwarmPattern());
|
|
126
|
+
registry.register(PatternType.HANDOFF, createHandoffPattern());
|
|
127
|
+
registry.register(PatternType.TRIAGE, createTriagePattern());
|
|
105
128
|
|
|
106
129
|
// Register patterns with engine
|
|
107
130
|
registry.registerWithEngine(engine);
|
|
@@ -167,6 +190,21 @@ module.exports = {
|
|
|
167
190
|
SwarmStrategy,
|
|
168
191
|
createSwarmPattern,
|
|
169
192
|
|
|
193
|
+
HandoffPattern,
|
|
194
|
+
HandoffFilters,
|
|
195
|
+
EscalationData,
|
|
196
|
+
HandoffConfig,
|
|
197
|
+
handoff,
|
|
198
|
+
createHandoffPattern,
|
|
199
|
+
|
|
200
|
+
TriagePattern,
|
|
201
|
+
TriageCategory,
|
|
202
|
+
TriageStrategy,
|
|
203
|
+
AgentCapability,
|
|
204
|
+
TriageResult,
|
|
205
|
+
DEFAULT_KEYWORD_MAPPINGS,
|
|
206
|
+
createTriagePattern,
|
|
207
|
+
|
|
170
208
|
// Workflow Orchestrator
|
|
171
209
|
WorkflowOrchestrator,
|
|
172
210
|
StepType,
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
* - GroupChat: Multi-skill collaborative discussion
|
|
9
9
|
* - Swarm: Parallel skill execution
|
|
10
10
|
* - HumanInLoop: Validation gates
|
|
11
|
+
* - Handoff: Agent delegation (v3.8.0)
|
|
12
|
+
* - Triage: Request classification and routing (v3.8.0)
|
|
11
13
|
*/
|
|
12
14
|
|
|
13
15
|
const EventEmitter = require('events');
|
|
@@ -21,7 +23,9 @@ const PatternType = {
|
|
|
21
23
|
NESTED: 'nested',
|
|
22
24
|
GROUP_CHAT: 'group-chat',
|
|
23
25
|
SWARM: 'swarm',
|
|
24
|
-
HUMAN_IN_LOOP: 'human-in-loop'
|
|
26
|
+
HUMAN_IN_LOOP: 'human-in-loop',
|
|
27
|
+
HANDOFF: 'handoff',
|
|
28
|
+
TRIAGE: 'triage'
|
|
25
29
|
};
|
|
26
30
|
|
|
27
31
|
/**
|