create-byan-agent 2.0.1 → 2.1.1
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/API-BYAN-V2.md +741 -0
- package/BMAD-QUICK-REFERENCE.md +370 -0
- package/CHANGELOG-v2.1.0.md +371 -0
- package/LICENSE +1 -1
- package/MIGRATION-v2.0-to-v2.1.md +430 -0
- package/README-BYAN-V2.md +446 -0
- package/README.md +264 -201
- package/install/.eslintrc.js +20 -0
- package/install/.prettierrc +7 -0
- package/install/BUGFIX-CHALK.md +173 -0
- package/install/BUGFIX-DOCUMENTATION-INDEX.md +299 -0
- package/install/BUGFIX-PATH-RESOLUTION.md +293 -0
- package/install/BUGFIX-QUICKSTART.md +184 -0
- package/install/BUGFIX-SUMMARY.txt +91 -0
- package/install/BUGFIX-VISUAL-SUMMARY.md +253 -0
- package/install/DEPLOYMENT-GUIDE-V2.md +431 -0
- package/install/DOCS-INDEX.md +261 -0
- package/install/GUIDE-INSTALLATION-BYAN-SIMPLE.md +1083 -0
- package/install/INSTALLER-V2-CHANGES.md +472 -0
- package/install/LICENSE +21 -0
- package/install/PUBLICATION-CHECKLIST.md +265 -0
- package/install/PUBLISH-GUIDE.md +190 -0
- package/install/QUICKSTART.md +311 -0
- package/install/README-NPM-PUBLISH.md +298 -0
- package/install/README-NPM-SHORT.md +298 -0
- package/install/README-NPM.md +433 -0
- package/install/README-RACHID.md +302 -0
- package/install/README-V2-INDEX.md +306 -0
- package/install/README.md +298 -0
- package/install/RESUME-EXECUTIF-YAN.md +408 -0
- package/install/UPDATE-SUMMARY.md +205 -0
- package/install/__tests__/integration/detection-flow.test.js +154 -0
- package/install/__tests__/platforms/claude-code.test.js +175 -0
- package/install/__tests__/platforms/codex.test.js +80 -0
- package/install/__tests__/platforms/copilot-cli.test.js +118 -0
- package/install/__tests__/platforms/vscode.test.js +67 -0
- package/install/__tests__/utils/file-utils.test.js +87 -0
- package/install/__tests__/utils/git-detector.test.js +80 -0
- package/install/__tests__/utils/logger.test.js +83 -0
- package/install/__tests__/utils/node-detector.test.js +71 -0
- package/install/__tests__/utils/os-detector.test.js +63 -0
- package/install/__tests__/utils/yaml-utils.test.js +85 -0
- package/install/__tests__/yanstaller/detector.test.js +210 -0
- package/install/coverage/clover.xml +219 -0
- package/install/coverage/coverage-final.json +13 -0
- package/install/coverage/lcov-report/base.css +224 -0
- package/install/coverage/lcov-report/block-navigation.js +87 -0
- package/install/coverage/lcov-report/favicon.png +0 -0
- package/install/coverage/lcov-report/index.html +146 -0
- package/install/coverage/lcov-report/lib/errors.js.html +268 -0
- package/install/coverage/lcov-report/lib/exit-codes.js.html +247 -0
- package/install/coverage/lcov-report/lib/index.html +131 -0
- package/install/coverage/lcov-report/lib/platforms/claude-code.js.html +343 -0
- package/install/coverage/lcov-report/lib/platforms/codex.js.html +361 -0
- package/install/coverage/lcov-report/lib/platforms/copilot-cli.js.html +454 -0
- package/install/coverage/lcov-report/lib/platforms/index.html +176 -0
- package/install/coverage/lcov-report/lib/platforms/index.js.html +127 -0
- package/install/coverage/lcov-report/lib/platforms/vscode.js.html +238 -0
- package/install/coverage/lcov-report/lib/utils/config-loader.js.html +322 -0
- package/install/coverage/lcov-report/lib/utils/file-utils.js.html +397 -0
- package/install/coverage/lcov-report/lib/utils/git-detector.js.html +190 -0
- package/install/coverage/lcov-report/lib/utils/index.html +206 -0
- package/install/coverage/lcov-report/lib/utils/logger.js.html +277 -0
- package/install/coverage/lcov-report/lib/utils/node-detector.js.html +259 -0
- package/install/coverage/lcov-report/lib/utils/os-detector.js.html +307 -0
- package/install/coverage/lcov-report/lib/utils/yaml-utils.js.html +346 -0
- package/install/coverage/lcov-report/lib/yanstaller/backuper.js.html +409 -0
- package/install/coverage/lcov-report/lib/yanstaller/detector.js.html +508 -0
- package/install/coverage/lcov-report/lib/yanstaller/index.html +236 -0
- package/install/coverage/lcov-report/lib/yanstaller/index.js.html +364 -0
- package/install/coverage/lcov-report/lib/yanstaller/installer.js.html +505 -0
- package/install/coverage/lcov-report/lib/yanstaller/interviewer.js.html +349 -0
- package/install/coverage/lcov-report/lib/yanstaller/recommender.js.html +379 -0
- package/install/coverage/lcov-report/lib/yanstaller/troubleshooter.js.html +352 -0
- package/install/coverage/lcov-report/lib/yanstaller/validator.js.html +679 -0
- package/install/coverage/lcov-report/lib/yanstaller/wizard.js.html +412 -0
- package/install/coverage/lcov-report/platforms/claude-code.js.html +343 -0
- package/install/coverage/lcov-report/platforms/codex.js.html +361 -0
- package/install/coverage/lcov-report/platforms/copilot-cli.js.html +454 -0
- package/install/coverage/lcov-report/platforms/index.html +176 -0
- package/install/coverage/lcov-report/platforms/index.js.html +127 -0
- package/install/coverage/lcov-report/platforms/vscode.js.html +238 -0
- package/install/coverage/lcov-report/prettify.css +1 -0
- package/install/coverage/lcov-report/prettify.js +2 -0
- package/install/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/install/coverage/lcov-report/sorter.js +210 -0
- package/install/coverage/lcov-report/utils/file-utils.js.html +397 -0
- package/install/coverage/lcov-report/utils/git-detector.js.html +190 -0
- package/install/coverage/lcov-report/utils/index.html +191 -0
- package/install/coverage/lcov-report/utils/logger.js.html +277 -0
- package/install/coverage/lcov-report/utils/node-detector.js.html +259 -0
- package/install/coverage/lcov-report/utils/os-detector.js.html +307 -0
- package/install/coverage/lcov-report/utils/yaml-utils.js.html +346 -0
- package/install/coverage/lcov-report/yanstaller/detector.js.html +508 -0
- package/install/coverage/lcov-report/yanstaller/index.html +116 -0
- package/install/coverage/lcov.info +414 -0
- package/install/install.sh +239 -0
- package/install/jest.config.js +33 -0
- package/install/lib/errors.js +61 -0
- package/install/lib/exit-codes.js +54 -0
- package/install/lib/platforms/claude-code.js +86 -0
- package/install/lib/platforms/codex.js +92 -0
- package/install/lib/platforms/copilot-cli.js +123 -0
- package/install/lib/platforms/index.js +14 -0
- package/install/lib/platforms/vscode.js +51 -0
- package/install/lib/utils/config-loader.js +79 -0
- package/install/lib/utils/file-utils.js +104 -0
- package/install/lib/utils/git-detector.js +35 -0
- package/install/lib/utils/logger.js +64 -0
- package/install/lib/utils/node-detector.js +58 -0
- package/install/lib/utils/os-detector.js +74 -0
- package/install/lib/utils/yaml-utils.js +87 -0
- package/install/lib/yanstaller/backuper.js +108 -0
- package/install/lib/yanstaller/detector.js +141 -0
- package/install/lib/yanstaller/index.js +93 -0
- package/install/lib/yanstaller/installer.js +140 -0
- package/install/lib/yanstaller/interviewer.js +88 -0
- package/install/lib/yanstaller/recommender.js +98 -0
- package/install/lib/yanstaller/troubleshooter.js +89 -0
- package/install/lib/yanstaller/validator.js +198 -0
- package/install/lib/yanstaller/wizard.js +109 -0
- package/install/package-npm.json +55 -0
- package/install/package.json +63 -0
- package/install/src/byan-v2/context/copilot-context.js +79 -0
- package/install/src/byan-v2/context/session-state.js +98 -0
- package/install/src/byan-v2/dispatcher/complexity-scorer.js +232 -0
- package/install/src/byan-v2/dispatcher/local-executor.js +221 -0
- package/install/src/byan-v2/dispatcher/task-router.js +122 -0
- package/install/src/byan-v2/dispatcher/task-tool-interface-mock.js +134 -0
- package/install/src/byan-v2/dispatcher/task-tool-interface.js +123 -0
- package/install/src/byan-v2/generation/agent-profile-validator.js +113 -0
- package/install/src/byan-v2/generation/profile-template.js +113 -0
- package/install/src/byan-v2/generation/templates/default-agent.md +49 -0
- package/install/src/byan-v2/generation/templates/test-template.md +1 -0
- package/install/src/byan-v2/index.js +199 -0
- package/install/src/byan-v2/observability/error-tracker.js +105 -0
- package/install/src/byan-v2/observability/logger.js +154 -0
- package/install/src/byan-v2/observability/metrics-collector.js +194 -0
- package/install/src/byan-v2/orchestrator/analysis-state.js +268 -0
- package/install/src/byan-v2/orchestrator/generation-state.js +340 -0
- package/install/src/byan-v2/orchestrator/interview-state.js +271 -0
- package/install/src/byan-v2/orchestrator/state-machine.js +204 -0
- package/install/src/core/cache/cache.js +126 -0
- package/install/src/core/context/context.js +86 -0
- package/install/src/core/dispatcher/dispatcher.js +135 -0
- package/install/src/core/worker-pool/worker-pool.js +194 -0
- package/install/src/core/workflow/workflow-executor.js +220 -0
- package/install/src/index.js +139 -0
- package/install/src/observability/dashboard/dashboard.js +191 -0
- package/install/src/observability/logger/structured-logger.js +254 -0
- package/install/src/observability/metrics/metrics-collector.js +325 -0
- package/install/switch-to-v2.sh +126 -0
- package/install/test-chalk-fix.sh +210 -0
- package/install/test-installer-v2.sh +204 -0
- package/install/test-path-resolution.sh +200 -0
- package/package.json +53 -33
- package/src/byan-v2/context/copilot-context.js +79 -0
- package/src/byan-v2/context/session-state.js +98 -0
- package/src/byan-v2/data/mantras.json +852 -0
- package/src/byan-v2/dispatcher/complexity-scorer.js +232 -0
- package/src/byan-v2/dispatcher/five-whys-analyzer.js +310 -0
- package/src/byan-v2/dispatcher/local-executor.js +221 -0
- package/src/byan-v2/dispatcher/task-router.js +122 -0
- package/src/byan-v2/dispatcher/task-tool-interface-mock.js +134 -0
- package/src/byan-v2/dispatcher/task-tool-interface.js +123 -0
- package/src/byan-v2/generation/agent-profile-validator.js +113 -0
- package/src/byan-v2/generation/mantra-validator.js +416 -0
- package/src/byan-v2/generation/profile-template.js +113 -0
- package/src/byan-v2/generation/templates/default-agent.md +49 -0
- package/src/byan-v2/generation/templates/test-template.md +1 -0
- package/src/byan-v2/index.js +652 -0
- package/src/byan-v2/integration/voice-integration.js +295 -0
- package/src/byan-v2/observability/error-tracker.js +105 -0
- package/src/byan-v2/observability/logger.js +154 -0
- package/src/byan-v2/observability/metrics-collector.js +194 -0
- package/src/byan-v2/orchestrator/active-listener.js +541 -0
- package/src/byan-v2/orchestrator/analysis-state.js +268 -0
- package/src/byan-v2/orchestrator/generation-state.js +340 -0
- package/src/byan-v2/orchestrator/glossary-builder.js +431 -0
- package/src/byan-v2/orchestrator/interview-state.js +353 -0
- package/src/byan-v2/orchestrator/state-machine.js +253 -0
- package/src/core/cache/cache.js +126 -0
- package/src/core/context/context.js +86 -0
- package/src/core/dispatcher/dispatcher.js +135 -0
- package/src/core/worker-pool/worker-pool.js +194 -0
- package/src/core/workflow/workflow-executor.js +220 -0
- package/src/index.js +139 -0
- package/src/observability/dashboard/dashboard.js +191 -0
- package/src/observability/logger/structured-logger.js +254 -0
- package/src/observability/metrics/metrics-collector.js +325 -0
- package/templates/.github/agents/bmad-agent-test-dynamic.md +0 -21
- package/templates/.github/agents/franck.md +0 -379
- /package/{CHANGELOG.md → install/CHANGELOG.md} +0 -0
- /package/{bin → install/bin}/create-byan-agent-backup.js +0 -0
- /package/{bin → install/bin}/create-byan-agent-fixed.js +0 -0
- /package/{bin → install/bin}/create-byan-agent-v2.js +0 -0
- /package/{bin → install/bin}/create-byan-agent.js +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmad-master.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmb-agent-builder.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmb-module-builder.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmb-workflow-builder.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-analyst.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-architect.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-dev.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-pm.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-quick-flow-solo-dev.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-quinn.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-sm.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-tech-writer.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-ux-designer.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-byan-test.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-byan.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-carmack.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-cis-brainstorming-coach.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-cis-creative-problem-solver.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-cis-design-thinking-coach.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-cis-innovation-strategist.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-cis-presentation-master.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-cis-storyteller.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-marc.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-patnote.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-rachid.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-tea-tea.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/agents/agent-builder.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/agents/byan-test.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/agents/byan.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/agents/marc.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/agents/module-builder.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/agents/patnote.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/agents/rachid.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/agents/workflow-builder.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/workflows/byan/data/mantras.yaml +0 -0
- /package/{templates → install/templates}/_bmad/bmb/workflows/byan/data/templates.yaml +0 -0
- /package/{templates → install/templates}/_bmad/bmb/workflows/byan/delete-agent-workflow.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/workflows/byan/edit-agent-workflow.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/workflows/byan/interview-workflow.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/workflows/byan/quick-create-workflow.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/workflows/byan/templates/base-agent-template.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/workflows/byan/validate-agent-workflow.md +0 -0
- /package/{templates → install/templates}/_bmad/core/agents/carmack.md +0 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MetricsCollector - Track task execution metrics
|
|
3
|
+
*
|
|
4
|
+
* Tracks:
|
|
5
|
+
* - tasksRouted, taskToolCalls, localExecutions
|
|
6
|
+
* - totalTokens, totalDuration
|
|
7
|
+
* - successfulTasks, failedTasks
|
|
8
|
+
* - Averages (duration, tokens)
|
|
9
|
+
*
|
|
10
|
+
* Methods:
|
|
11
|
+
* - recordTaskRouting(routingData)
|
|
12
|
+
* - recordTaskExecution(executionData)
|
|
13
|
+
* - getMetrics()
|
|
14
|
+
* - reset()
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
class MetricsCollector {
|
|
18
|
+
constructor() {
|
|
19
|
+
this.metrics = {
|
|
20
|
+
tasksRouted: 0,
|
|
21
|
+
taskToolCalls: 0,
|
|
22
|
+
localExecutions: 0,
|
|
23
|
+
totalTokens: 0,
|
|
24
|
+
totalDuration: 0,
|
|
25
|
+
successfulTasks: 0,
|
|
26
|
+
failedTasks: 0
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
this.counters = {
|
|
30
|
+
sessionsStarted: 0,
|
|
31
|
+
questionsAsked: 0,
|
|
32
|
+
analysesCompleted: 0,
|
|
33
|
+
profilesGenerated: 0,
|
|
34
|
+
errors: 0
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
this.taskHistory = [];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Increment a counter by name
|
|
42
|
+
* @param {string} counterName - Name of counter to increment
|
|
43
|
+
* @param {number} amount - Amount to increment by (default 1)
|
|
44
|
+
*/
|
|
45
|
+
increment(counterName, amount = 1) {
|
|
46
|
+
if (this.counters.hasOwnProperty(counterName)) {
|
|
47
|
+
this.counters[counterName] += amount;
|
|
48
|
+
} else if (this.metrics.hasOwnProperty(counterName)) {
|
|
49
|
+
this.metrics[counterName] += amount;
|
|
50
|
+
} else {
|
|
51
|
+
this.counters[counterName] = amount;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Get summary of all metrics
|
|
57
|
+
* @returns {Object} Metrics summary
|
|
58
|
+
*/
|
|
59
|
+
getSummary() {
|
|
60
|
+
const totalTasks = this.metrics.successfulTasks + this.metrics.failedTasks;
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
totalSessions: this.counters.sessionsStarted,
|
|
64
|
+
avgQuestionsPerSession: this.counters.sessionsStarted > 0
|
|
65
|
+
? Math.round(this.counters.questionsAsked / this.counters.sessionsStarted)
|
|
66
|
+
: 0,
|
|
67
|
+
successRate: totalTasks > 0
|
|
68
|
+
? Math.round((this.metrics.successfulTasks / totalTasks) * 100)
|
|
69
|
+
: 0,
|
|
70
|
+
delegationRate: this.metrics.tasksRouted > 0
|
|
71
|
+
? Math.round((this.metrics.taskToolCalls / this.metrics.tasksRouted) * 100)
|
|
72
|
+
: 0,
|
|
73
|
+
...this.counters,
|
|
74
|
+
...this.metrics
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Record task routing decision
|
|
81
|
+
* @param {Object} routingData - Routing decision data
|
|
82
|
+
*/
|
|
83
|
+
recordTaskRouting(routingData) {
|
|
84
|
+
if (!routingData) return;
|
|
85
|
+
|
|
86
|
+
const { executor, complexity, task } = routingData;
|
|
87
|
+
|
|
88
|
+
// Increment counters
|
|
89
|
+
this.metrics.tasksRouted++;
|
|
90
|
+
|
|
91
|
+
if (executor === 'task-tool') {
|
|
92
|
+
this.metrics.taskToolCalls++;
|
|
93
|
+
} else if (executor === 'local') {
|
|
94
|
+
this.metrics.localExecutions++;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Store in history
|
|
98
|
+
this.taskHistory.push({
|
|
99
|
+
type: 'routing',
|
|
100
|
+
timestamp: new Date().toISOString(),
|
|
101
|
+
executor,
|
|
102
|
+
complexity,
|
|
103
|
+
task
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Record task execution result
|
|
109
|
+
* @param {Object} executionData - Execution result data
|
|
110
|
+
*/
|
|
111
|
+
recordTaskExecution(executionData) {
|
|
112
|
+
if (!executionData) return;
|
|
113
|
+
|
|
114
|
+
const { duration, success, tokens, error } = executionData;
|
|
115
|
+
|
|
116
|
+
// Validate and record duration (reject negative)
|
|
117
|
+
if (duration !== undefined && duration >= 0) {
|
|
118
|
+
this.metrics.totalDuration += duration;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Validate and record tokens (reject negative)
|
|
122
|
+
if (tokens !== undefined && tokens >= 0) {
|
|
123
|
+
this.metrics.totalTokens += tokens;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Record success/failure
|
|
127
|
+
if (success === true) {
|
|
128
|
+
this.metrics.successfulTasks++;
|
|
129
|
+
} else if (success === false) {
|
|
130
|
+
this.metrics.failedTasks++;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Store in history
|
|
134
|
+
this.taskHistory.push({
|
|
135
|
+
type: 'execution',
|
|
136
|
+
timestamp: new Date().toISOString(),
|
|
137
|
+
duration,
|
|
138
|
+
success,
|
|
139
|
+
tokens,
|
|
140
|
+
error
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Get current metrics snapshot
|
|
146
|
+
* @returns {Object} Current metrics
|
|
147
|
+
*/
|
|
148
|
+
getMetrics() {
|
|
149
|
+
const totalTasks = this.metrics.successfulTasks + this.metrics.failedTasks;
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
tasksRouted: this.metrics.tasksRouted,
|
|
153
|
+
taskToolCalls: this.metrics.taskToolCalls,
|
|
154
|
+
localExecutions: this.metrics.localExecutions,
|
|
155
|
+
totalTokens: this.metrics.totalTokens,
|
|
156
|
+
totalDuration: this.metrics.totalDuration,
|
|
157
|
+
successfulTasks: this.metrics.successfulTasks,
|
|
158
|
+
failedTasks: this.metrics.failedTasks,
|
|
159
|
+
averageDuration: totalTasks > 0
|
|
160
|
+
? Math.round(this.metrics.totalDuration / totalTasks)
|
|
161
|
+
: 0,
|
|
162
|
+
averageTokens: totalTasks > 0
|
|
163
|
+
? Math.round(this.metrics.totalTokens / totalTasks)
|
|
164
|
+
: 0
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Reset all metrics and history
|
|
170
|
+
*/
|
|
171
|
+
reset() {
|
|
172
|
+
this.metrics = {
|
|
173
|
+
tasksRouted: 0,
|
|
174
|
+
taskToolCalls: 0,
|
|
175
|
+
localExecutions: 0,
|
|
176
|
+
totalTokens: 0,
|
|
177
|
+
totalDuration: 0,
|
|
178
|
+
successfulTasks: 0,
|
|
179
|
+
failedTasks: 0
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
this.counters = {
|
|
183
|
+
sessionsStarted: 0,
|
|
184
|
+
questionsAsked: 0,
|
|
185
|
+
analysesCompleted: 0,
|
|
186
|
+
profilesGenerated: 0,
|
|
187
|
+
errors: 0
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
this.taskHistory = [];
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
module.exports = MetricsCollector;
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AnalysisState - Story 4.3
|
|
3
|
+
* Analyzes interview responses to extract structured requirements
|
|
4
|
+
*
|
|
5
|
+
* Integrates:
|
|
6
|
+
* - TaskRouter: Route tasks based on complexity
|
|
7
|
+
* - LocalExecutor: Execute high-complexity analysis
|
|
8
|
+
* - Logger: Log analysis steps
|
|
9
|
+
* - SessionState: Store analysis results
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const TaskRouter = require('../dispatcher/task-router');
|
|
13
|
+
const LocalExecutor = require('../dispatcher/local-executor');
|
|
14
|
+
const Logger = require('../observability/logger');
|
|
15
|
+
|
|
16
|
+
class AnalysisState {
|
|
17
|
+
constructor(sessionState) {
|
|
18
|
+
this.sessionState = sessionState;
|
|
19
|
+
this.taskRouter = new TaskRouter();
|
|
20
|
+
this.localExecutor = new LocalExecutor();
|
|
21
|
+
this.logger = new Logger();
|
|
22
|
+
|
|
23
|
+
this.analysisComplete = false;
|
|
24
|
+
this.requirements = null;
|
|
25
|
+
this.patterns = null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* AC2: Extract requirements from user responses
|
|
30
|
+
* Identifies: purpose, capabilities, knowledgeAreas, constraints
|
|
31
|
+
*
|
|
32
|
+
* @returns {Promise<Object>} Extracted requirements
|
|
33
|
+
*/
|
|
34
|
+
async extractRequirements() {
|
|
35
|
+
this.logger.info('Analysis started: extracting requirements', {
|
|
36
|
+
responseCount: this.sessionState.userResponses.length
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Prepare analysis task
|
|
40
|
+
const responsesText = this.sessionState.userResponses
|
|
41
|
+
.map((r, i) => `Response ${i + 1}: ${r.response}`)
|
|
42
|
+
.join('\n');
|
|
43
|
+
|
|
44
|
+
const analysisTask = {
|
|
45
|
+
type: 'analysis',
|
|
46
|
+
prompt: `Extract structured requirements from these user responses:
|
|
47
|
+
|
|
48
|
+
${responsesText}
|
|
49
|
+
|
|
50
|
+
Extract and return JSON with:
|
|
51
|
+
- purpose: Main goal/purpose of the agent
|
|
52
|
+
- capabilities: Array of specific capabilities needed
|
|
53
|
+
- knowledgeAreas: Array of knowledge domains required
|
|
54
|
+
- constraints: Array of constraints or limitations`,
|
|
55
|
+
metadata: {
|
|
56
|
+
requiresReasoning: true,
|
|
57
|
+
requiresMultipleSteps: true,
|
|
58
|
+
estimatedDuration: 'medium'
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// AC6: Route through TaskRouter (complexity-based delegation)
|
|
63
|
+
const routing = this.taskRouter.routeTask(analysisTask);
|
|
64
|
+
|
|
65
|
+
this.logger.info('Task routed', {
|
|
66
|
+
executor: routing.executor,
|
|
67
|
+
complexity: routing.complexity
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Execute analysis (typically routed to LocalExecutor due to high complexity)
|
|
71
|
+
let result;
|
|
72
|
+
if (routing.executor === 'local') {
|
|
73
|
+
result = await this.localExecutor.execute(analysisTask);
|
|
74
|
+
} else {
|
|
75
|
+
// Fallback to local if task-tool routing (shouldn't happen for analysis)
|
|
76
|
+
result = await this.localExecutor.execute(analysisTask);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Parse requirements
|
|
80
|
+
try {
|
|
81
|
+
this.requirements = JSON.parse(result.output);
|
|
82
|
+
} catch (error) {
|
|
83
|
+
this.logger.error('Failed to parse analysis output', { error: error.message });
|
|
84
|
+
throw new Error('Invalid analysis output format');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Store in SessionState
|
|
88
|
+
this.sessionState.setAnalysisResults({
|
|
89
|
+
requirements: this.requirements,
|
|
90
|
+
timestamp: Date.now(),
|
|
91
|
+
tokens: result.tokens,
|
|
92
|
+
duration: result.duration
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
this.logger.info('Requirements extraction complete', {
|
|
96
|
+
purpose: this.requirements.purpose,
|
|
97
|
+
capabilitiesCount: this.requirements.capabilities?.length || 0,
|
|
98
|
+
knowledgeAreasCount: this.requirements.knowledgeAreas?.length || 0
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
return this.requirements;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* AC3: Identify patterns and common themes across responses
|
|
106
|
+
* @returns {Promise<Array>} Patterns found
|
|
107
|
+
*/
|
|
108
|
+
async identifyPatterns() {
|
|
109
|
+
this.logger.info('Identifying patterns across responses');
|
|
110
|
+
|
|
111
|
+
if (!this.sessionState.userResponses || this.sessionState.userResponses.length === 0) {
|
|
112
|
+
this.logger.warn('No responses to analyze for patterns');
|
|
113
|
+
this.patterns = [];
|
|
114
|
+
return this.patterns;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Simple pattern detection based on keyword frequency
|
|
118
|
+
const keywordCounts = {};
|
|
119
|
+
const responses = this.sessionState.userResponses
|
|
120
|
+
.map(r => (r.response || '').toLowerCase())
|
|
121
|
+
.join(' ');
|
|
122
|
+
|
|
123
|
+
// Extract words (simple tokenization)
|
|
124
|
+
const words = responses.split(/\s+/).filter(w => w.length > 3);
|
|
125
|
+
|
|
126
|
+
// Count occurrences
|
|
127
|
+
words.forEach(word => {
|
|
128
|
+
keywordCounts[word] = (keywordCounts[word] || 0) + 1;
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// Find patterns (words appearing >= 2 times)
|
|
132
|
+
this.patterns = Object.entries(keywordCounts)
|
|
133
|
+
.filter(([word, count]) => count >= 2)
|
|
134
|
+
.map(([word, count]) => ({
|
|
135
|
+
theme: word,
|
|
136
|
+
occurrences: count,
|
|
137
|
+
relevance: count / words.length
|
|
138
|
+
}))
|
|
139
|
+
.sort((a, b) => b.occurrences - a.occurrences)
|
|
140
|
+
.slice(0, 10); // Top 10 patterns
|
|
141
|
+
|
|
142
|
+
// Update SessionState
|
|
143
|
+
if (this.sessionState.analysisResults) {
|
|
144
|
+
this.sessionState.analysisResults.patterns = this.patterns;
|
|
145
|
+
} else {
|
|
146
|
+
this.sessionState.setAnalysisResults({ patterns: this.patterns });
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
this.logger.info('Pattern identification complete', {
|
|
150
|
+
patternsFound: this.patterns.length
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
return this.patterns;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* AC4: Validate that all required fields are present and complete
|
|
158
|
+
* @param {Object} requirements - Requirements object to validate
|
|
159
|
+
* @returns {boolean} True if complete
|
|
160
|
+
*/
|
|
161
|
+
validateCompleteness(requirements) {
|
|
162
|
+
if (!requirements || typeof requirements !== 'object') {
|
|
163
|
+
this.logger.warn('Requirements validation failed: invalid input');
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Check required fields exist
|
|
168
|
+
const requiredFields = ['purpose', 'capabilities', 'knowledgeAreas', 'constraints'];
|
|
169
|
+
|
|
170
|
+
for (const field of requiredFields) {
|
|
171
|
+
if (!requirements[field]) {
|
|
172
|
+
this.logger.warn(`Requirements validation failed: missing ${field}`);
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Validate purpose is not empty
|
|
178
|
+
if (typeof requirements.purpose !== 'string' || requirements.purpose.trim().length === 0) {
|
|
179
|
+
this.logger.warn('Requirements validation failed: empty purpose');
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Validate arrays are not empty
|
|
184
|
+
const arrayFields = ['capabilities', 'knowledgeAreas'];
|
|
185
|
+
|
|
186
|
+
for (const field of arrayFields) {
|
|
187
|
+
if (!Array.isArray(requirements[field]) || requirements[field].length === 0) {
|
|
188
|
+
this.logger.warn(`Requirements validation failed: empty ${field}`);
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Constraints can be empty array (optional)
|
|
194
|
+
if (!Array.isArray(requirements.constraints)) {
|
|
195
|
+
this.logger.warn('Requirements validation failed: constraints must be array');
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
this.logger.info('Requirements validation passed', {
|
|
200
|
+
purpose: requirements.purpose.substring(0, 50),
|
|
201
|
+
capabilitiesCount: requirements.capabilities.length,
|
|
202
|
+
knowledgeAreasCount: requirements.knowledgeAreas.length
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* AC5: Check if analysis is complete and can transition to GENERATION
|
|
210
|
+
* @returns {boolean} True if ready to transition
|
|
211
|
+
*/
|
|
212
|
+
canTransitionToGeneration() {
|
|
213
|
+
// Check if requirements have been extracted
|
|
214
|
+
if (!this.requirements) {
|
|
215
|
+
this.logger.warn('Cannot transition: requirements not extracted');
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Validate completeness
|
|
220
|
+
if (!this.validateCompleteness(this.requirements)) {
|
|
221
|
+
this.logger.warn('Cannot transition: requirements incomplete');
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Check SessionState has analysis results
|
|
226
|
+
if (!this.sessionState.analysisResults ||
|
|
227
|
+
!this.sessionState.analysisResults.requirements) {
|
|
228
|
+
this.logger.warn('Cannot transition: SessionState missing analysis results');
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
this.logger.info('Analysis complete - ready to transition to GENERATION');
|
|
233
|
+
this.analysisComplete = true;
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Get current analysis results
|
|
239
|
+
* @returns {Object} Analysis results
|
|
240
|
+
*/
|
|
241
|
+
getAnalysisResults() {
|
|
242
|
+
return {
|
|
243
|
+
requirements: this.requirements,
|
|
244
|
+
patterns: this.patterns,
|
|
245
|
+
complete: this.analysisComplete
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Get requirements summary
|
|
251
|
+
* @returns {Object} Requirements summary
|
|
252
|
+
*/
|
|
253
|
+
getRequirementsSummary() {
|
|
254
|
+
if (!this.requirements) {
|
|
255
|
+
return { summary: 'No requirements extracted yet' };
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return {
|
|
259
|
+
purpose: this.requirements.purpose,
|
|
260
|
+
capabilitiesCount: this.requirements.capabilities?.length || 0,
|
|
261
|
+
knowledgeAreasCount: this.requirements.knowledgeAreas?.length || 0,
|
|
262
|
+
constraintsCount: this.requirements.constraints?.length || 0,
|
|
263
|
+
isComplete: this.validateCompleteness(this.requirements)
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
module.exports = AnalysisState;
|