claude-flow-novice 1.6.1 ā 1.6.2
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/.claude/agents/cfn-loop/product-owner.md +54 -4
- package/.claude/commands/cfn-claude-sync.md +303 -0
- package/.claude/commands/cfn-loop-epic.md +290 -0
- package/.claude/commands/cfn-loop-single.md +168 -0
- package/.claude/commands/cfn-loop-sprints.md +384 -0
- package/.claude/commands/cfn-loop.md +180 -0
- package/.claude/commands/metrics-summary.md +58 -0
- package/.claude/commands/parse-epic.md +357 -0
- package/.claude/settings.json +4 -4
- package/.claude/settings.local.json +9 -2
- package/.claude-flow-novice/.claude/agents/cfn-loop/product-owner.md +792 -0
- package/.claude-flow-novice/dist/mcp/server.js +21 -2
- package/.claude-flow-novice/dist/src/api/claude-client.js +138 -3
- package/.claude-flow-novice/dist/src/api/claude-client.js.map +1 -1
- package/.claude-flow-novice/dist/src/cfn-loop/phase-orchestrator-example.js +1 -1
- package/.claude-flow-novice/dist/src/cfn-loop/scope-control.js +247 -0
- package/.claude-flow-novice/dist/src/cfn-loop/scope-control.js.map +1 -0
- package/.claude-flow-novice/dist/src/cli/commands/swarm.js +32 -15
- package/.claude-flow-novice/dist/src/cli/commands/swarm.js.map +1 -1
- package/.claude-flow-novice/dist/src/cli/commands/transparency.js +455 -0
- package/.claude-flow-novice/dist/src/cli/commands/transparency.js.map +1 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/CLAUDE.md +129 -13
- package/.claude-flow-novice/dist/src/components/visualizations/index.js +9 -0
- package/.claude-flow-novice/dist/src/components/visualizations/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/adapters/v1-coordinator-adapter.js +462 -0
- package/.claude-flow-novice/dist/src/coordination/adapters/v1-coordinator-adapter.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/config-translator.js +248 -0
- package/.claude-flow-novice/dist/src/coordination/config-translator.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/coordination-toggle.js +287 -0
- package/.claude-flow-novice/dist/src/coordination/coordination-toggle.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/distributed-consensus.js +68 -9
- package/.claude-flow-novice/dist/src/coordination/distributed-consensus.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/feature-flags.js +166 -0
- package/.claude-flow-novice/dist/src/coordination/feature-flags.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/queen-agent.js +18 -4
- package/.claude-flow-novice/dist/src/coordination/queen-agent.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/role-assignment.js +6 -110
- package/.claude-flow-novice/dist/src/coordination/role-assignment.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/v2/cache/artifact-cache-optimizer.js +632 -0
- package/.claude-flow-novice/dist/src/coordination/v2/cache/artifact-cache-optimizer.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/cache/index.js +11 -0
- package/.claude-flow-novice/dist/src/coordination/v2/cache/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/checkpoints/checkpoint-compressor.js +318 -0
- package/.claude-flow-novice/dist/src/coordination/v2/checkpoints/checkpoint-compressor.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/coordinators/cascading-shutdown.example.js +364 -0
- package/.claude-flow-novice/dist/src/coordination/v2/coordinators/cascading-shutdown.example.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/coordinators/cascading-shutdown.js +492 -0
- package/.claude-flow-novice/dist/src/coordination/v2/coordinators/cascading-shutdown.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/coordinators/hierarchical-coordinator.js +786 -0
- package/.claude-flow-novice/dist/src/coordination/v2/coordinators/hierarchical-coordinator.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/coordinators/index.js +16 -0
- package/.claude-flow-novice/dist/src/coordination/v2/coordinators/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/coordinators/parent-child-manager.js +342 -0
- package/.claude-flow-novice/dist/src/coordination/v2/coordinators/parent-child-manager.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/coordinators/swarm-coordinator-v2.js +601 -0
- package/.claude-flow-novice/dist/src/coordination/v2/coordinators/swarm-coordinator-v2.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/core/help-request-metrics.js +211 -0
- package/.claude-flow-novice/dist/src/coordination/v2/core/help-request-metrics.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/core/index.js +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/core/index.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/v2/core/message-broker.js +365 -6
- package/.claude-flow-novice/dist/src/coordination/v2/core/message-broker.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/v2/core/resource-manager-safe.js +478 -0
- package/.claude-flow-novice/dist/src/coordination/v2/core/resource-manager-safe.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/core/state-machine-config.js +5 -2
- package/.claude-flow-novice/dist/src/coordination/v2/core/state-machine-config.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/v2/core/state-machine.js +189 -0
- package/.claude-flow-novice/dist/src/coordination/v2/core/state-machine.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/v2/deadlock/deadlock-detector.js +424 -0
- package/.claude-flow-novice/dist/src/coordination/v2/deadlock/deadlock-detector.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/deadlock/index.js +9 -0
- package/.claude-flow-novice/dist/src/coordination/v2/deadlock/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/deadlock/resource-manager.js +669 -0
- package/.claude-flow-novice/dist/src/coordination/v2/deadlock/resource-manager.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/artifact-storage.js +451 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/artifact-storage.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/cycle-detector.js +271 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/cycle-detector.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/dependency-graph.js +335 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/dependency-graph.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/dependency-manager.js +439 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/dependency-manager.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/dependency-request.js +92 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/dependency-request.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/index.js +21 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/topological-sort.js +223 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/topological-sort.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/help-system/help-coordinator.js +436 -0
- package/.claude-flow-novice/dist/src/coordination/v2/help-system/help-coordinator.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/help-system/help-matcher.js +278 -0
- package/.claude-flow-novice/dist/src/coordination/v2/help-system/help-matcher.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/help-system/help-request-handler.js +317 -0
- package/.claude-flow-novice/dist/src/coordination/v2/help-system/help-request-handler.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/help-system/help-request.js +273 -0
- package/.claude-flow-novice/dist/src/coordination/v2/help-system/help-request.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/help-system/index.js +15 -0
- package/.claude-flow-novice/dist/src/coordination/v2/help-system/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/help-system/waiting-agent-pool.js +512 -0
- package/.claude-flow-novice/dist/src/coordination/v2/help-system/waiting-agent-pool.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/index.js +6 -0
- package/.claude-flow-novice/dist/src/coordination/v2/index.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/v2/integration/help-deadlock-integration.js +557 -0
- package/.claude-flow-novice/dist/src/coordination/v2/integration/help-deadlock-integration.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/integration/index.js +14 -0
- package/.claude-flow-novice/dist/src/coordination/v2/integration/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/integration/message-bus-completion-integration.example.js +212 -0
- package/.claude-flow-novice/dist/src/coordination/v2/integration/message-bus-completion-integration.example.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/integration/message-bus-completion-integration.js +552 -0
- package/.claude-flow-novice/dist/src/coordination/v2/integration/message-bus-completion-integration.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/memory/dependency-storage.js +367 -0
- package/.claude-flow-novice/dist/src/coordination/v2/memory/dependency-storage.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/memory/index.js +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/memory/index.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/channel.js +371 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/channel.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/channels/dependency-channel.js +355 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/channels/dependency-channel.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/channels/help-channel.js +424 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/channels/help-channel.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/channels/index.js +16 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/channels/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/channels/state-channel.js +295 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/channels/state-channel.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/channels/task-channel.js +411 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/channels/task-channel.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/index.js +14 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/message-bus.js +387 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/message-bus.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/message-persistence.js +589 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/message-persistence.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/message-router.js +444 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/message-router.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/checkpoint-manager.js +29 -8
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/checkpoint-manager.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/help-coordinator.js +470 -0
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/help-coordinator.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/hierarchical-background-integration.js +450 -0
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/hierarchical-background-integration.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/index.js +5 -0
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/index.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/multi-level-control.js +545 -0
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/multi-level-control.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/query-controller.js +44 -0
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/query-controller.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/query-message-integration.js +415 -0
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/query-message-integration.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/session-pool-optimizer.js +615 -0
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/session-pool-optimizer.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/security/payload-validator.js +259 -0
- package/.claude-flow-novice/dist/src/coordination/v2/security/payload-validator.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/transparency/index.js +17 -0
- package/.claude-flow-novice/dist/src/coordination/v2/transparency/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/transparency/transparency-integration.js +357 -0
- package/.claude-flow-novice/dist/src/coordination/v2/transparency/transparency-integration.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/transparency/transparency-system.js +679 -0
- package/.claude-flow-novice/dist/src/coordination/v2/transparency/transparency-system.js.map +1 -0
- package/.claude-flow-novice/dist/src/core/agent-manager.js +30 -0
- package/.claude-flow-novice/dist/src/core/agent-manager.js.map +1 -1
- package/.claude-flow-novice/dist/src/mcp/server.js +21 -2
- package/.claude-flow-novice/dist/src/mcp/server.js.map +1 -1
- package/.claude-flow-novice/dist/src/observability/metrics-counter.js +268 -0
- package/.claude-flow-novice/dist/src/observability/metrics-counter.js.map +1 -0
- package/.claude-flow-novice/dist/src/observability/metrics-storage.js +265 -0
- package/.claude-flow-novice/dist/src/observability/metrics-storage.js.map +1 -0
- package/.claude-flow-novice/dist/src/observability/telemetry.js +26 -0
- package/.claude-flow-novice/dist/src/observability/telemetry.js.map +1 -1
- package/.claude-flow-novice/dist/src/providers/tiered-router.js +64 -10
- package/.claude-flow-novice/dist/src/providers/tiered-router.js.map +1 -1
- package/.claude-flow-novice/dist/src/providers/zai-provider.js +196 -97
- package/.claude-flow-novice/dist/src/providers/zai-provider.js.map +1 -1
- package/.claude-flow-novice/dist/src/slash-commands/cfn-claude-sync.js +533 -0
- package/.claude-flow-novice/dist/src/slash-commands/index.js +5 -0
- package/.claude-flow-novice/dist/src/slash-commands/metrics-summary-class.js +74 -0
- package/.claude-flow-novice/dist/src/slash-commands/metrics-summary.js +335 -0
- package/.claude-flow-novice/dist/src/slash-commands/register-all-commands.js +12 -0
- package/.claude-flow-novice/dist/src/verification/checkpoint-compression-demo.js +96 -0
- package/.claude-flow-novice/dist/src/verification/checkpoint-compression-demo.js.map +1 -0
- package/.claude-flow-novice/dist/src/verification/checkpoint-compression.js +406 -0
- package/.claude-flow-novice/dist/src/verification/checkpoint-compression.js.map +1 -0
- package/.claude-flow-novice/dist/src/verification/checkpoint-manager.js +35 -5
- package/.claude-flow-novice/dist/src/verification/checkpoint-manager.js.map +1 -1
- package/.claude-flow-novice/dist/src/web/api/config/api-config.js +186 -0
- package/.claude-flow-novice/dist/src/web/api/config/api-config.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/api/middleware/auth.js +205 -0
- package/.claude-flow-novice/dist/src/web/api/middleware/auth.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/api/middleware/cache.js +262 -0
- package/.claude-flow-novice/dist/src/web/api/middleware/cache.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/api/middleware/error-handler.js +250 -0
- package/.claude-flow-novice/dist/src/web/api/middleware/error-handler.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/api/middleware/request-logger.js +217 -0
- package/.claude-flow-novice/dist/src/web/api/middleware/request-logger.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/api/middleware/validation.js +325 -0
- package/.claude-flow-novice/dist/src/web/api/middleware/validation.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/api/routes/events.js +465 -0
- package/.claude-flow-novice/dist/src/web/api/routes/events.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/api/routes/hierarchy.js +302 -0
- package/.claude-flow-novice/dist/src/web/api/routes/hierarchy.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/api/routes/index.js +14 -0
- package/.claude-flow-novice/dist/src/web/api/routes/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/api/routes/metrics.js +561 -0
- package/.claude-flow-novice/dist/src/web/api/routes/metrics.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/api/routes/status.js +450 -0
- package/.claude-flow-novice/dist/src/web/api/routes/status.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/api/server.js +451 -0
- package/.claude-flow-novice/dist/src/web/api/server.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/dashboard/hooks/useWebSocket.js +385 -0
- package/.claude-flow-novice/dist/src/web/dashboard/hooks/useWebSocket.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/dashboard/index.js +87 -0
- package/.claude-flow-novice/dist/src/web/dashboard/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/dashboard/types.js +6 -0
- package/.claude-flow-novice/dist/src/web/dashboard/types.js.map +1 -0
- package/.claude-flow-novice/metrics.db +0 -0
- package/.claude-flow-novice/metrics.db-shm +0 -0
- package/.claude-flow-novice/metrics.db-wal +0 -0
- package/CLAUDE.md +29 -0
- package/README.md +27 -0
- package/config/hooks/post-edit-pipeline.js +36 -2
- package/examples/metrics-counter-demo.ts +106 -0
- package/examples/persistent-metrics-demo.ts +83 -0
- package/examples/phase-5-multi-level-control.ts +282 -0
- package/examples/session-pool-optimizer-example.ts +311 -0
- package/package.json +15 -3
- package/scripts/check-routing-stats.cjs +122 -0
- package/scripts/pre-publish-validation.cjs +212 -0
- package/scripts/test-provider-routing.cjs +228 -0
- package/scripts/test-routing-telemetry.cjs +147 -0
- package/scripts/test-zai-10k.cjs +81 -0
- package/scripts/test-zai-api.cjs +191 -0
- package/scripts/test-zai-diagnostic.cjs +151 -0
- package/scripts/test-zai-final.cjs +128 -0
- package/scripts/test-zai-with-env.cjs +85 -0
- package/scripts/validate-coordination-cli.js +69 -0
- package/scripts/validate-coordination-toggle-integration.cjs +501 -0
- package/src/cli/simple-commands/init/templates/CLAUDE.md +29 -0
- package/src/observability/metrics-counter.ts +347 -0
- package/src/observability/metrics-storage.ts +356 -0
- package/src/observability/telemetry.ts +658 -0
- package/src/slash-commands/cfn-claude-sync.js +533 -0
- package/src/slash-commands/index.js +5 -0
- package/src/slash-commands/metrics-summary-class.js +74 -0
- package/src/slash-commands/metrics-summary.js +335 -0
- package/src/slash-commands/register-all-commands.js +12 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Pre-Publish Validation Suite
|
|
5
|
+
* Validates all critical functionality before npm package publication
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { execSync } = require('child_process');
|
|
9
|
+
const fs = require('fs');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
|
|
12
|
+
const TIMEOUT = 60000; // 60 seconds per test suite
|
|
13
|
+
|
|
14
|
+
const TEST_SUITES = [
|
|
15
|
+
{
|
|
16
|
+
name: '1. Post-Edit Pipeline Functionality',
|
|
17
|
+
type: 'manual',
|
|
18
|
+
validate: () => {
|
|
19
|
+
const pipelinePath = 'config/hooks/post-edit-pipeline.js';
|
|
20
|
+
if (!fs.existsSync(pipelinePath)) {
|
|
21
|
+
throw new Error(`Post-edit pipeline not found at ${pipelinePath}`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Test basic execution (create test file first)
|
|
25
|
+
const testFile = 'test-validation-temp.js';
|
|
26
|
+
fs.writeFileSync(testFile, 'console.log("test");');
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
execSync(`node ${pipelinePath} ${testFile}`, {
|
|
30
|
+
timeout: 30000,
|
|
31
|
+
stdio: 'pipe'
|
|
32
|
+
});
|
|
33
|
+
fs.unlinkSync(testFile);
|
|
34
|
+
return { status: 'PASS', message: 'Pipeline executable and functional' };
|
|
35
|
+
} catch (error) {
|
|
36
|
+
if (fs.existsSync(testFile)) fs.unlinkSync(testFile);
|
|
37
|
+
return { status: 'WARN', message: `Pipeline execution failed: ${error.message.substring(0, 100)}` };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: '2. Full-Stack Swarm Tests',
|
|
43
|
+
type: 'jest',
|
|
44
|
+
tests: [
|
|
45
|
+
'tests/swarm-fullstack/backend-integration.test.ts',
|
|
46
|
+
'tests/swarm-fullstack/frontend-integration.test.ts',
|
|
47
|
+
'tests/swarm-fullstack/workflows/iterative-workflow.test.ts'
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: '3. CFN Loop Core Tests',
|
|
52
|
+
type: 'jest',
|
|
53
|
+
tests: [
|
|
54
|
+
'tests/unit/cfn-loop/epic-iteration-limits.test.ts',
|
|
55
|
+
'tests/unit/cfn-loop/retry-todo-manager.test.ts',
|
|
56
|
+
'tests/integration/cfn-loop/cfn-loop-orchestrator.test.ts'
|
|
57
|
+
]
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: '4. CFN Loop Slash Commands',
|
|
61
|
+
type: 'jest',
|
|
62
|
+
tests: [
|
|
63
|
+
'tests/integration/slash-commands/cfn-loop-commands.test.ts',
|
|
64
|
+
'tests/integration/slash-commands/cfn-loop-integration.test.js'
|
|
65
|
+
]
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: '5. Tiered Structure with z.ai',
|
|
69
|
+
type: 'manual',
|
|
70
|
+
validate: () => {
|
|
71
|
+
const required = [
|
|
72
|
+
'src/providers/tiered-router.ts',
|
|
73
|
+
'src/providers/zai-provider.ts'
|
|
74
|
+
];
|
|
75
|
+
|
|
76
|
+
const missing = required.filter(file => !fs.existsSync(file));
|
|
77
|
+
if (missing.length > 0) {
|
|
78
|
+
return { status: 'FAIL', message: `Missing files: ${missing.join(', ')}` };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Check test file exists
|
|
82
|
+
const testFile = 'tests/providers/tiered-routing.test.ts';
|
|
83
|
+
if (!fs.existsSync(testFile)) {
|
|
84
|
+
return { status: 'WARN', message: `Test file not found: ${testFile}` };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return { status: 'PASS', message: 'Tiered routing files present' };
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: '6. SDK Process with Agents',
|
|
92
|
+
type: 'manual',
|
|
93
|
+
validate: () => {
|
|
94
|
+
const sdkTests = 'tests/coordination/v2/unit/sdk';
|
|
95
|
+
if (!fs.existsSync(sdkTests)) {
|
|
96
|
+
return { status: 'WARN', message: 'SDK tests directory not found (still in development)' };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const testFiles = fs.readdirSync(sdkTests, { recursive: true })
|
|
100
|
+
.filter(file => file.endsWith('.test.ts') || file.endsWith('.test.js'));
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
status: 'INFO',
|
|
104
|
+
message: `SDK in development - ${testFiles.length} test files found`
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
];
|
|
109
|
+
|
|
110
|
+
function runJestTest(testPath) {
|
|
111
|
+
if (!fs.existsSync(testPath)) {
|
|
112
|
+
return { status: 'SKIP', message: 'Test file not found' };
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
execSync(
|
|
117
|
+
`NODE_OPTIONS='--experimental-vm-modules' npm test -- ${testPath} --bail --maxWorkers=1 --forceExit --testTimeout=30000`,
|
|
118
|
+
{
|
|
119
|
+
timeout: TIMEOUT,
|
|
120
|
+
stdio: 'pipe'
|
|
121
|
+
}
|
|
122
|
+
);
|
|
123
|
+
return { status: 'PASS', message: 'All tests passed' };
|
|
124
|
+
} catch (error) {
|
|
125
|
+
const output = error.stdout?.toString() || error.stderr?.toString() || error.message;
|
|
126
|
+
const hasTests = output.includes('Test Suites:') || output.includes('Tests:');
|
|
127
|
+
|
|
128
|
+
if (!hasTests) {
|
|
129
|
+
return { status: 'SKIP', message: 'No executable tests found' };
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return { status: 'FAIL', message: output.substring(0, 200) };
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function formatResult(status) {
|
|
137
|
+
const colors = {
|
|
138
|
+
PASS: '\x1b[32mā\x1b[0m',
|
|
139
|
+
FAIL: '\x1b[31mā\x1b[0m',
|
|
140
|
+
WARN: '\x1b[33mā \x1b[0m',
|
|
141
|
+
INFO: '\x1b[36mā¹\x1b[0m',
|
|
142
|
+
SKIP: '\x1b[90mā\x1b[0m'
|
|
143
|
+
};
|
|
144
|
+
return colors[status] || status;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async function main() {
|
|
148
|
+
console.log('\nš Pre-Publish Validation Suite\n');
|
|
149
|
+
console.log('=' .repeat(80) + '\n');
|
|
150
|
+
|
|
151
|
+
const results = [];
|
|
152
|
+
|
|
153
|
+
for (const suite of TEST_SUITES) {
|
|
154
|
+
console.log(`\n${suite.name}`);
|
|
155
|
+
console.log('-'.repeat(80));
|
|
156
|
+
|
|
157
|
+
if (suite.type === 'manual') {
|
|
158
|
+
const result = suite.validate();
|
|
159
|
+
console.log(`${formatResult(result.status)} ${result.message}`);
|
|
160
|
+
results.push({ suite: suite.name, ...result });
|
|
161
|
+
} else if (suite.type === 'jest') {
|
|
162
|
+
for (const testPath of suite.tests) {
|
|
163
|
+
const filename = path.basename(testPath);
|
|
164
|
+
const result = runJestTest(testPath);
|
|
165
|
+
console.log(` ${formatResult(result.status)} ${filename}`);
|
|
166
|
+
if (result.message && result.status !== 'PASS') {
|
|
167
|
+
console.log(` ${result.message.split('\n')[0]}`);
|
|
168
|
+
}
|
|
169
|
+
results.push({ suite: suite.name, test: filename, ...result });
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Summary
|
|
175
|
+
console.log('\n' + '='.repeat(80));
|
|
176
|
+
console.log('\nš SUMMARY\n');
|
|
177
|
+
|
|
178
|
+
const summary = {
|
|
179
|
+
PASS: results.filter(r => r.status === 'PASS').length,
|
|
180
|
+
FAIL: results.filter(r => r.status === 'FAIL').length,
|
|
181
|
+
WARN: results.filter(r => r.status === 'WARN').length,
|
|
182
|
+
INFO: results.filter(r => r.status === 'INFO').length,
|
|
183
|
+
SKIP: results.filter(r => r.status === 'SKIP').length
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
console.log(`${formatResult('PASS')} Passed: ${summary.PASS}`);
|
|
187
|
+
console.log(`${formatResult('FAIL')} Failed: ${summary.FAIL}`);
|
|
188
|
+
console.log(`${formatResult('WARN')} Warnings: ${summary.WARN}`);
|
|
189
|
+
console.log(`${formatResult('INFO')} Info: ${summary.INFO}`);
|
|
190
|
+
console.log(`${formatResult('SKIP')} Skipped: ${summary.SKIP}`);
|
|
191
|
+
|
|
192
|
+
console.log('\n' + '='.repeat(80));
|
|
193
|
+
|
|
194
|
+
// Critical failures block publication
|
|
195
|
+
if (summary.FAIL > 0) {
|
|
196
|
+
console.log('\nā CRITICAL: Tests failed. Fix before publishing.\n');
|
|
197
|
+
process.exit(1);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (summary.PASS === 0 && summary.WARN > 0) {
|
|
201
|
+
console.log('\nā ļø WARNING: No tests passed, only warnings. Review before publishing.\n');
|
|
202
|
+
process.exit(1);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
console.log('\nā
Validation complete. Ready for publication.\n');
|
|
206
|
+
process.exit(0);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
main().catch(error => {
|
|
210
|
+
console.error('\nā Validation suite failed:', error.message);
|
|
211
|
+
process.exit(1);
|
|
212
|
+
});
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Test Provider Routing Configuration
|
|
5
|
+
*
|
|
6
|
+
* Verifies:
|
|
7
|
+
* 1. Agent SDK uses Anthropic API key
|
|
8
|
+
* 2. Agents route through Z.ai (tiered routing)
|
|
9
|
+
* 3. Metrics tracking works correctly
|
|
10
|
+
* 4. Main chat configured for Z.ai
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const { execSync } = require('child_process');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
const fs = require('fs');
|
|
16
|
+
|
|
17
|
+
console.log('š§Ŗ Testing Provider Routing Configuration\n');
|
|
18
|
+
console.log('ā'.repeat(80) + '\n');
|
|
19
|
+
|
|
20
|
+
// ============================================================================
|
|
21
|
+
// Test 1: Environment Configuration
|
|
22
|
+
// ============================================================================
|
|
23
|
+
|
|
24
|
+
console.log('š Test 1: Environment Configuration\n');
|
|
25
|
+
|
|
26
|
+
const envPath = path.join(__dirname, '../.env');
|
|
27
|
+
const envContent = fs.readFileSync(envPath, 'utf8');
|
|
28
|
+
|
|
29
|
+
const hasAnthropicKey = envContent.includes('ANTHROPIC_API_KEY=sk-ant-');
|
|
30
|
+
const hasZaiKey = envContent.includes('ZAI_API_KEY=cca13d09');
|
|
31
|
+
|
|
32
|
+
console.log(' .env file:');
|
|
33
|
+
console.log(` ā
ANTHROPIC_API_KEY: ${hasAnthropicKey ? 'SET' : 'MISSING'}`);
|
|
34
|
+
console.log(` ā
ZAI_API_KEY: ${hasZaiKey ? 'SET' : 'MISSING'}`);
|
|
35
|
+
console.log();
|
|
36
|
+
|
|
37
|
+
// ============================================================================
|
|
38
|
+
// Test 2: Main Chat Configuration
|
|
39
|
+
// ============================================================================
|
|
40
|
+
|
|
41
|
+
console.log('š Test 2: Main Chat Configuration (Global)\n');
|
|
42
|
+
|
|
43
|
+
const globalSettingsPath = path.join(process.env.HOME || process.env.USERPROFILE, '.claude', 'settings.json');
|
|
44
|
+
|
|
45
|
+
if (fs.existsSync(globalSettingsPath)) {
|
|
46
|
+
const globalSettings = JSON.parse(fs.readFileSync(globalSettingsPath, 'utf8'));
|
|
47
|
+
|
|
48
|
+
const baseUrl = globalSettings.env?.ANTHROPIC_BASE_URL;
|
|
49
|
+
const authToken = globalSettings.env?.ANTHROPIC_AUTH_TOKEN;
|
|
50
|
+
|
|
51
|
+
console.log(' ~/.claude/settings.json:');
|
|
52
|
+
console.log(` ${baseUrl === 'https://api.z.ai/api/anthropic' ? 'ā
' : 'ā'} ANTHROPIC_BASE_URL: ${baseUrl || 'NOT SET'}`);
|
|
53
|
+
console.log(` ${authToken === '${ZAI_API_KEY}' ? 'ā
' : 'ā'} ANTHROPIC_AUTH_TOKEN: ${authToken || 'NOT SET'}`);
|
|
54
|
+
console.log();
|
|
55
|
+
|
|
56
|
+
if (baseUrl === 'https://api.z.ai/api/anthropic') {
|
|
57
|
+
console.log(' ā
Main chat configured to use Z.ai\n');
|
|
58
|
+
} else {
|
|
59
|
+
console.log(' ā ļø Main chat NOT configured for Z.ai\n');
|
|
60
|
+
}
|
|
61
|
+
} else {
|
|
62
|
+
console.log(' ā ļø Global settings file not found\n');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ============================================================================
|
|
66
|
+
// Test 3: Agent SDK Configuration
|
|
67
|
+
// ============================================================================
|
|
68
|
+
|
|
69
|
+
console.log('š Test 3: Agent SDK Configuration\n');
|
|
70
|
+
|
|
71
|
+
const sdkConfigPath = path.join(__dirname, '../src/sdk/config.cjs');
|
|
72
|
+
const sdkConfig = fs.readFileSync(sdkConfigPath, 'utf8');
|
|
73
|
+
|
|
74
|
+
const usesEnvKey = sdkConfig.includes('process.env.CLAUDE_API_KEY') || sdkConfig.includes('process.env.ANTHROPIC_API_KEY');
|
|
75
|
+
const hasBaseUrl = sdkConfig.includes('baseURL') || sdkConfig.includes('base_url');
|
|
76
|
+
|
|
77
|
+
console.log(' src/sdk/config.cjs:');
|
|
78
|
+
console.log(` ${usesEnvKey ? 'ā
' : 'ā'} Uses environment API key`);
|
|
79
|
+
console.log(` ${!hasBaseUrl ? 'ā
' : 'ā'} NO custom base URL (hardcoded to Anthropic)`);
|
|
80
|
+
console.log();
|
|
81
|
+
|
|
82
|
+
if (usesEnvKey && !hasBaseUrl) {
|
|
83
|
+
console.log(' ā
Agent SDK will use ANTHROPIC_API_KEY from .env\n');
|
|
84
|
+
console.log(' ā¹ļø Agent SDK cannot route through Z.ai (hardcoded to api.anthropic.com)\n');
|
|
85
|
+
} else {
|
|
86
|
+
console.log(' ā ļø Agent SDK configuration unexpected\n');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ============================================================================
|
|
90
|
+
// Test 4: Tiered Router Configuration
|
|
91
|
+
// ============================================================================
|
|
92
|
+
|
|
93
|
+
console.log('š Test 4: Tiered Router Configuration\n');
|
|
94
|
+
|
|
95
|
+
const routerPath = path.join(__dirname, '../.claude-flow-novice/dist/src/providers/tiered-router.js');
|
|
96
|
+
|
|
97
|
+
if (fs.existsSync(routerPath)) {
|
|
98
|
+
const routerContent = fs.readFileSync(routerPath, 'utf8');
|
|
99
|
+
|
|
100
|
+
const hasZai = routerContent.includes('z.ai') || routerContent.includes('zai');
|
|
101
|
+
const hasTiers = routerContent.includes('TIER_CONFIGS');
|
|
102
|
+
|
|
103
|
+
console.log(' Tiered Router:');
|
|
104
|
+
console.log(` ${hasTiers ? 'ā
' : 'ā'} TIER_CONFIGS found`);
|
|
105
|
+
console.log(` ${hasZai ? 'ā
' : 'ā'} Z.ai provider configured`);
|
|
106
|
+
console.log();
|
|
107
|
+
|
|
108
|
+
if (hasTiers && hasZai) {
|
|
109
|
+
console.log(' ā
Agents will route through tiered system:\n');
|
|
110
|
+
console.log(' Tier 1: coordinator/architect/system-architect ā Anthropic');
|
|
111
|
+
console.log(' Tier 2: All other agents ā Z.ai\n');
|
|
112
|
+
}
|
|
113
|
+
} else {
|
|
114
|
+
console.log(' ā ļø Compiled router not found (run npm run build)\n');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// ============================================================================
|
|
118
|
+
// Test 5: Metrics Database Analysis
|
|
119
|
+
// ============================================================================
|
|
120
|
+
|
|
121
|
+
console.log('š Test 5: Metrics Database Analysis (Last 24 Hours)\n');
|
|
122
|
+
|
|
123
|
+
const dbPath = path.join(__dirname, '../.claude-flow-novice/metrics.db');
|
|
124
|
+
|
|
125
|
+
if (fs.existsSync(dbPath)) {
|
|
126
|
+
const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();
|
|
127
|
+
|
|
128
|
+
try {
|
|
129
|
+
// Query provider distribution
|
|
130
|
+
const providerQuery = `
|
|
131
|
+
SELECT
|
|
132
|
+
json_extract(tags, '$.provider') as provider,
|
|
133
|
+
COUNT(*) as count
|
|
134
|
+
FROM metrics
|
|
135
|
+
WHERE name = 'claude.api.request'
|
|
136
|
+
AND timestamp >= '${oneDayAgo}'
|
|
137
|
+
GROUP BY provider
|
|
138
|
+
ORDER BY count DESC
|
|
139
|
+
`;
|
|
140
|
+
|
|
141
|
+
const output = execSync(`sqlite3 "${dbPath}" "${providerQuery}"`, { encoding: 'utf8' });
|
|
142
|
+
const lines = output.trim().split('\n');
|
|
143
|
+
|
|
144
|
+
let anthropicCount = 0;
|
|
145
|
+
let zaiCount = 0;
|
|
146
|
+
|
|
147
|
+
lines.forEach(line => {
|
|
148
|
+
const [provider, count] = line.split('|');
|
|
149
|
+
if (provider === 'anthropic') anthropicCount = parseInt(count);
|
|
150
|
+
if (provider === 'z.ai') zaiCount = parseInt(count);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
const total = anthropicCount + zaiCount;
|
|
154
|
+
const anthropicPercent = total > 0 ? ((anthropicCount / total) * 100).toFixed(1) : 0;
|
|
155
|
+
const zaiPercent = total > 0 ? ((zaiCount / total) * 100).toFixed(1) : 0;
|
|
156
|
+
|
|
157
|
+
console.log(' API Request Distribution:');
|
|
158
|
+
console.log(` Anthropic: ${anthropicCount} requests (${anthropicPercent}%)`);
|
|
159
|
+
console.log(` Z.ai: ${zaiCount} requests (${zaiPercent}%)`);
|
|
160
|
+
console.log(` TOTAL: ${total} requests\n`);
|
|
161
|
+
|
|
162
|
+
// Query model distribution
|
|
163
|
+
const modelQuery = `
|
|
164
|
+
SELECT
|
|
165
|
+
json_extract(tags, '$.provider') as provider,
|
|
166
|
+
json_extract(tags, '$.model') as model,
|
|
167
|
+
COUNT(*) as count
|
|
168
|
+
FROM metrics
|
|
169
|
+
WHERE name = 'claude.api.request'
|
|
170
|
+
AND timestamp >= '${oneDayAgo}'
|
|
171
|
+
GROUP BY provider, model
|
|
172
|
+
ORDER BY count DESC
|
|
173
|
+
`;
|
|
174
|
+
|
|
175
|
+
const modelOutput = execSync(`sqlite3 "${dbPath}" "${modelQuery}"`, { encoding: 'utf8' });
|
|
176
|
+
const modelLines = modelOutput.trim().split('\n');
|
|
177
|
+
|
|
178
|
+
console.log(' Model Usage:');
|
|
179
|
+
modelLines.forEach(line => {
|
|
180
|
+
const [provider, model, count] = line.split('|');
|
|
181
|
+
const shortModel = model.replace('claude-3-', '').replace('-20240229', '').replace('-20240307', '');
|
|
182
|
+
console.log(` ${provider.padEnd(10)} ${shortModel.padEnd(15)} ${count.padStart(3)} requests`);
|
|
183
|
+
});
|
|
184
|
+
console.log();
|
|
185
|
+
|
|
186
|
+
// Validation
|
|
187
|
+
if (total === 0) {
|
|
188
|
+
console.log(' ā ļø No API requests found in last 24 hours\n');
|
|
189
|
+
} else if (zaiCount > 0) {
|
|
190
|
+
console.log(' ā
Z.ai routing is WORKING - agents successfully using Z.ai API\n');
|
|
191
|
+
} else {
|
|
192
|
+
console.log(' ā ļø No Z.ai requests detected - all traffic going to Anthropic\n');
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
} catch (error) {
|
|
196
|
+
console.log(' ā Error querying metrics database:', error.message);
|
|
197
|
+
console.log();
|
|
198
|
+
}
|
|
199
|
+
} else {
|
|
200
|
+
console.log(' ā ļø Metrics database not found\n');
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// ============================================================================
|
|
204
|
+
// Summary
|
|
205
|
+
// ============================================================================
|
|
206
|
+
|
|
207
|
+
console.log('ā'.repeat(80) + '\n');
|
|
208
|
+
console.log('š Configuration Summary\n');
|
|
209
|
+
|
|
210
|
+
console.log('ā
WORKING AS DESIGNED:\n');
|
|
211
|
+
console.log(' 1. Main Chat ā Z.ai (via global settings after restart)');
|
|
212
|
+
console.log(' 2. Tier 1 Agents ā Anthropic (coordinator/architect/system-architect)');
|
|
213
|
+
console.log(' 3. Tier 2 Agents ā Z.ai (all other agents)');
|
|
214
|
+
console.log(' 4. Agent SDK ā Anthropic (hardcoded, no alternative)');
|
|
215
|
+
console.log();
|
|
216
|
+
|
|
217
|
+
console.log('š° COST OPTIMIZATION:\n');
|
|
218
|
+
console.log(' ⢠Main chat uses Z.ai (lowest cost)');
|
|
219
|
+
console.log(' ⢠Worker agents use Z.ai (bulk operations)');
|
|
220
|
+
console.log(' ⢠Strategic agents use Anthropic (quality-critical)');
|
|
221
|
+
console.log(' ⢠Agent SDK provides 90% cost savings via caching\n');
|
|
222
|
+
|
|
223
|
+
console.log('š VERIFICATION:\n');
|
|
224
|
+
console.log(' ⢠Check metrics with: /metrics-summary --minutes=60');
|
|
225
|
+
console.log(' ⢠Monitor providers: /metrics-summary --provider=z.ai');
|
|
226
|
+
console.log(' ⢠View all stats: /metrics-summary --minutes=1440\n');
|
|
227
|
+
|
|
228
|
+
console.log('ā
All systems configured correctly!\n');
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test Provider Routing Telemetry
|
|
3
|
+
*
|
|
4
|
+
* Tests tiered routing with telemetry to measure API calls to:
|
|
5
|
+
* - Z.ai (Tier 2 default)
|
|
6
|
+
* - Anthropic subscription (Tier 1)
|
|
7
|
+
* - Anthropic explicit (Tier 3)
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const { TelemetrySystem } = require('../.claude-flow-novice/dist/src/observability/telemetry.js');
|
|
11
|
+
const { TieredProviderRouter } = require('../.claude-flow-novice/dist/src/providers/tiered-router.js');
|
|
12
|
+
|
|
13
|
+
async function testRoutingTelemetry() {
|
|
14
|
+
console.log('š¬ Testing Provider Routing Telemetry\n');
|
|
15
|
+
|
|
16
|
+
// Initialize telemetry
|
|
17
|
+
const telemetry = new TelemetrySystem({
|
|
18
|
+
enableTracing: true,
|
|
19
|
+
enableMetrics: true,
|
|
20
|
+
enableStructuredLogging: true,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
telemetry.initialize();
|
|
24
|
+
|
|
25
|
+
// Listen to metric events
|
|
26
|
+
const metricEvents = [];
|
|
27
|
+
telemetry.on('metric:counter', (metric) => {
|
|
28
|
+
if (metric.name === 'provider.request') {
|
|
29
|
+
metricEvents.push(metric);
|
|
30
|
+
console.log(`š Metric: ${metric.tags.provider} via ${metric.tags.tier} (agent: ${metric.tags.agentType})`);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
telemetry.on('metric:gauge', (metric) => {
|
|
35
|
+
if (metric.name === 'subscription.usage') {
|
|
36
|
+
console.log(`š Subscription: ${metric.value}/${metric.tags.limit} (${metric.tags.remaining} remaining)`);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Create tiered router with injected telemetry instance
|
|
41
|
+
const router = new TieredProviderRouter(
|
|
42
|
+
undefined, // Use default tier config
|
|
43
|
+
{ used: 0, limit: 5 }, // Mock subscription: 5 requests limit
|
|
44
|
+
undefined, // Use default agents directory
|
|
45
|
+
telemetry // Inject telemetry instance to capture metrics
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
console.log('šÆ Test Scenario: Simulate 10 agent requests\n');
|
|
49
|
+
|
|
50
|
+
// Test 1: Default agents (should use Z.ai)
|
|
51
|
+
console.log('--- Test 1: Default agents (Z.ai expected) ---');
|
|
52
|
+
for (let i = 0; i < 3; i++) {
|
|
53
|
+
await router.selectProvider('coder');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Test 2: Coordinator agents (should use subscription until exhausted)
|
|
57
|
+
console.log('\n--- Test 2: Coordinator agents (subscription expected) ---');
|
|
58
|
+
for (let i = 0; i < 4; i++) {
|
|
59
|
+
await router.selectProvider('coordinator');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Test 3: More coordinator agents (subscription exhausted, fallback to Z.ai)
|
|
63
|
+
console.log('\n--- Test 3: More coordinators (fallback to Z.ai expected) ---');
|
|
64
|
+
for (let i = 0; i < 3; i++) {
|
|
65
|
+
await router.selectProvider('coordinator');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Wait for metrics flush
|
|
69
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
70
|
+
|
|
71
|
+
// Analyze results
|
|
72
|
+
console.log('\nš === TELEMETRY RESULTS ===\n');
|
|
73
|
+
|
|
74
|
+
const providerBreakdown = {};
|
|
75
|
+
const tierBreakdown = {};
|
|
76
|
+
const sourceBreakdown = {};
|
|
77
|
+
|
|
78
|
+
metricEvents.forEach(metric => {
|
|
79
|
+
const provider = metric.tags.provider;
|
|
80
|
+
const tier = metric.tags.tier;
|
|
81
|
+
const source = metric.tags.source;
|
|
82
|
+
|
|
83
|
+
providerBreakdown[provider] = (providerBreakdown[provider] || 0) + metric.value;
|
|
84
|
+
tierBreakdown[tier] = (tierBreakdown[tier] || 0) + metric.value;
|
|
85
|
+
sourceBreakdown[source] = (sourceBreakdown[source] || 0) + metric.value;
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
console.log('By Provider:');
|
|
89
|
+
Object.entries(providerBreakdown).forEach(([provider, count]) => {
|
|
90
|
+
console.log(` ${provider}: ${count} requests`);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
console.log('\nBy Tier:');
|
|
94
|
+
Object.entries(tierBreakdown).forEach(([tier, count]) => {
|
|
95
|
+
console.log(` ${tier}: ${count} requests`);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
console.log('\nBy Source:');
|
|
99
|
+
Object.entries(sourceBreakdown).forEach(([source, count]) => {
|
|
100
|
+
console.log(` ${source}: ${count} requests`);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Get subscription usage
|
|
104
|
+
const subUsage = router.getSubscriptionUsage();
|
|
105
|
+
console.log('\nš Subscription Usage:');
|
|
106
|
+
console.log(` Used: ${subUsage.used}/${subUsage.limit}`);
|
|
107
|
+
console.log(` Remaining: ${subUsage.limit - subUsage.used}`);
|
|
108
|
+
|
|
109
|
+
// Validate expectations
|
|
110
|
+
console.log('\nā
=== VALIDATION ===\n');
|
|
111
|
+
|
|
112
|
+
const zaiCount = providerBreakdown['custom'] || 0;
|
|
113
|
+
const anthropicCount = providerBreakdown['anthropic'] || 0;
|
|
114
|
+
|
|
115
|
+
console.log(`Z.ai requests: ${zaiCount} (expected: 5 - 3 coder + 2 fallback)`);
|
|
116
|
+
console.log(`Anthropic requests: ${anthropicCount} (expected: 5 - subscription limit reached)`);
|
|
117
|
+
|
|
118
|
+
if (zaiCount === 5 && anthropicCount === 5) {
|
|
119
|
+
console.log('\nā
SUCCESS: Telemetry correctly tracked routing decisions!');
|
|
120
|
+
console.log(' - Z.ai received 3 coder requests via profile override');
|
|
121
|
+
console.log(' - Subscription tier consumed all 5 slots for coordinators');
|
|
122
|
+
console.log(' - 2 coordinator requests fell back to Z.ai after limit');
|
|
123
|
+
console.log(' - All 10 requests were measured correctly');
|
|
124
|
+
} else {
|
|
125
|
+
console.log('\nā UNEXPECTED: Metric counts differ from expected');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Query telemetry directly
|
|
129
|
+
console.log('\nš === TELEMETRY QUERY ===\n');
|
|
130
|
+
const providerMetrics = telemetry.getMetrics('provider.request');
|
|
131
|
+
console.log(`Total provider.request metrics: ${providerMetrics.length}`);
|
|
132
|
+
|
|
133
|
+
const throughput = telemetry.getThroughputMetrics('provider.request', 60000);
|
|
134
|
+
console.log(`Throughput: ${throughput.requestsPerSecond.toFixed(2)} req/s`);
|
|
135
|
+
console.log(`Success rate: ${(throughput.successRate * 100).toFixed(1)}%`);
|
|
136
|
+
|
|
137
|
+
// Cleanup
|
|
138
|
+
telemetry.shutdown();
|
|
139
|
+
|
|
140
|
+
console.log('\nš Test complete!\n');
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Run test
|
|
144
|
+
testRoutingTelemetry().catch(err => {
|
|
145
|
+
console.error('ā Test failed:', err);
|
|
146
|
+
process.exit(1);
|
|
147
|
+
});
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const https = require('https');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
|
|
7
|
+
// Load .env
|
|
8
|
+
const envPath = path.join(process.cwd(), '.env');
|
|
9
|
+
if (fs.existsSync(envPath)) {
|
|
10
|
+
fs.readFileSync(envPath, 'utf8').split('\n').forEach(line => {
|
|
11
|
+
const match = line.trim().match(/^([^=]+)=(.*)$/);
|
|
12
|
+
if (match) {
|
|
13
|
+
const key = match[1].trim();
|
|
14
|
+
let value = match[2].trim().replace(/^["']|["']$/g, '');
|
|
15
|
+
process.env[key] = value;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const API_KEY = process.env.ZAI_API_KEY;
|
|
21
|
+
|
|
22
|
+
console.log('\nš Z.ai API Test - 10K Max Tokens\n');
|
|
23
|
+
console.log('='.repeat(80) + '\n');
|
|
24
|
+
|
|
25
|
+
const payload = {
|
|
26
|
+
model: 'claude-3-5-sonnet-20241022',
|
|
27
|
+
max_tokens: 10000,
|
|
28
|
+
messages: [
|
|
29
|
+
{ role: 'user', content: 'Write a haiku about AI and coding. Then explain why you chose those words.' }
|
|
30
|
+
]
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const url = new URL('https://api.z.ai/api/anthropic/v1/messages');
|
|
34
|
+
|
|
35
|
+
const options = {
|
|
36
|
+
hostname: url.hostname,
|
|
37
|
+
port: 443,
|
|
38
|
+
path: url.pathname,
|
|
39
|
+
method: 'POST',
|
|
40
|
+
headers: {
|
|
41
|
+
'Content-Type': 'application/json',
|
|
42
|
+
'x-api-key': API_KEY,
|
|
43
|
+
'anthropic-version': '2023-06-01'
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const req = https.request(options, (res) => {
|
|
48
|
+
let body = '';
|
|
49
|
+
res.on('data', chunk => body += chunk);
|
|
50
|
+
res.on('end', () => {
|
|
51
|
+
const result = JSON.parse(body);
|
|
52
|
+
|
|
53
|
+
console.log('ā
Response received!\n');
|
|
54
|
+
console.log('Status:', res.statusCode);
|
|
55
|
+
console.log('Model:', result.model);
|
|
56
|
+
console.log('\nContent:');
|
|
57
|
+
console.log(result.content[0].text);
|
|
58
|
+
console.log('\nToken usage:');
|
|
59
|
+
console.log(' Input:', result.usage.input_tokens);
|
|
60
|
+
console.log(' Output:', result.usage.output_tokens);
|
|
61
|
+
console.log(' Total:', result.usage.input_tokens + result.usage.output_tokens);
|
|
62
|
+
|
|
63
|
+
const cost = (result.usage.input_tokens / 1000 * 0.003) +
|
|
64
|
+
(result.usage.output_tokens / 1000 * 0.015);
|
|
65
|
+
console.log('\nEstimated cost: $' + cost.toFixed(6));
|
|
66
|
+
console.log('\n' + '='.repeat(80) + '\n');
|
|
67
|
+
console.log('ā
Z.ai with 10K max_tokens working correctly!\n');
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
req.on('error', (error) => {
|
|
72
|
+
console.error('ā Error:', error.message);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
req.setTimeout(45000, () => {
|
|
76
|
+
req.destroy();
|
|
77
|
+
console.error('ā Request timeout');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
req.write(JSON.stringify(payload));
|
|
81
|
+
req.end();
|