claude-flow-novice 2.14.37 → 2.15.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.
@@ -1,30 +1,47 @@
1
1
  ---
2
- description: Switch Main Chat and Task tool between Z.ai and Anthropic providers
2
+ description: Switch Main Chat and Task tool between Z.ai, Kimi, OpenRouter, and Anthropic providers
3
3
  tags: [config, api, cost-optimization]
4
4
  ---
5
5
 
6
- Switch Main Chat and Task() tool API provider between Z.ai (cost-optimized) and Anthropic (high-quality).
6
+ Switch Main Chat and Task() tool API provider between multiple AI providers.
7
7
 
8
- **Important:** CLI agents always use Z.ai (from `.env`). This command only affects Main Chat and Task() spawned agents.
8
+ **Important:** CLI agents support custom routing when enabled. This command affects Main Chat and Task() spawned agents.
9
9
 
10
10
  **Usage:**
11
11
  - `/switch-api` - Show current status
12
- - `/switch-api zai` - Main Chat/Task tool use Z.ai ($0.50/1M tokens)
13
- - `/switch-api max` - Main Chat/Task tool use Anthropic ($15/1M tokens, requires re-login)
12
+ - `/switch-api [zai|kimi|openrouter|max]` - Switch provider
13
+ - `zai` - Z.ai ($0.50/1M tokens)
14
+ - `kimi` - Moonshot Kimi ($2/1M tokens)
15
+ - `openrouter` - OpenRouter (varies by model)
16
+ - `max` or `claude` - Anthropic ($15/1M tokens, requires re-login)
14
17
 
15
18
  **Arguments:**
16
19
  - `status` - Show current routing configuration (default)
17
20
  - `zai` - Route Main Chat + Task tool to Z.ai for cost savings
21
+ - `kimi` - Route Main Chat + Task tool to Moonshot Kimi
22
+ - `openrouter` - Route Main Chat + Task tool to OpenRouter
18
23
  - `max` or `claude` - Route Main Chat + Task tool to Anthropic for quality
19
24
 
20
25
  **What This Does:**
21
26
 
22
27
  `/switch-api zai`:
23
- - Adds env vars to `.claude/settings.json`
28
+ - Adds Z.ai env vars to `.claude/settings.json`
24
29
  - Main Chat + Task() agents use Z.ai
25
30
  - Cost: $0.50/1M tokens (97% savings)
26
31
  - No login required
27
32
 
33
+ `/switch-api kimi`:
34
+ - Adds Kimi env vars to `.claude/settings.json`
35
+ - Main Chat + Task() agents use Moonshot Kimi
36
+ - Cost: ~$2/1M tokens
37
+ - Requires `KIMI_API_KEY` in root `.env`
38
+
39
+ `/switch-api openrouter`:
40
+ - Adds OpenRouter env vars to `.claude/settings.json`
41
+ - Main Chat + Task() agents use OpenRouter
42
+ - Cost: Varies by model
43
+ - Requires `OPENROUTER_API_KEY` in root `.env`
44
+
28
45
  `/switch-api max`:
29
46
  - Removes env vars from `.claude/settings.json`
30
47
  - Main Chat + Task() agents use Anthropic
@@ -33,21 +50,25 @@ Switch Main Chat and Task() tool API provider between Z.ai (cost-optimized) and
33
50
 
34
51
  **Combined Architecture:**
35
52
  ```
36
- Main Chat (Anthropic or Z.ai - your choice)
53
+ Main Chat (Anthropic/Z.ai/Kimi/OpenRouter - your choice)
37
54
 
38
55
  Task() → Coordinator (uses Main Chat provider)
39
56
 
40
- CLI spawn → Workers (always Z.ai from .env)
57
+ CLI spawn → Workers (custom routing when enabled, see agent profiles)
41
58
  ```
42
59
 
43
60
  **Execute:**
44
61
  ```bash
45
- bash scripts/switch-api.sh {{args}}
62
+ bash "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/scripts/switch-api.sh" {{args}}
46
63
  ```
47
64
 
65
+ **Note:** Script automatically resolves to project root directory.
66
+
48
67
  **Examples:**
49
68
  ```bash
50
- /switch-api # Show current routing
51
- /switch-api zai # Cost-optimize Main Chat
52
- /switch-api max # Quality-optimize Main Chat (requires re-login)
69
+ /switch-api # Show current routing
70
+ /switch-api zai # Cost-optimize with Z.ai
71
+ /switch-api kimi # Use Moonshot Kimi
72
+ /switch-api openrouter # Use OpenRouter (access 400+ models)
73
+ /switch-api max # Quality-optimize with Anthropic (requires re-login)
53
74
  ```
@@ -0,0 +1,107 @@
1
+ #!/bin/bash
2
+
3
+ # Get Agent Provider Environment Variables
4
+ # Determines which provider environment variables to use for CLI/Docker agent spawning
5
+ #
6
+ # Logic:
7
+ # 1. If custom routing is disabled, use Main Chat settings (from .claude/settings.json)
8
+ # 2. If custom routing is enabled:
9
+ # a. Check agent profile for PROVIDER_PARAMETERS
10
+ # b. If found, use agent-specific provider/model
11
+ # c. If not found, use Main Chat settings
12
+ #
13
+ # Usage: source get-agent-provider-env.sh AGENT_TYPE
14
+ # Exports: ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN, ANTHROPIC_MODEL, ANTHROPIC_SMALL_FAST_MODEL
15
+
16
+ set -euo pipefail
17
+
18
+ AGENT_TYPE="${1:-}"
19
+ CUSTOM_ROUTING_ENABLED="${CFN_CUSTOM_ROUTING:-false}"
20
+ SETTINGS_FILE=".claude/settings.json"
21
+
22
+ if [[ -z "$AGENT_TYPE" ]]; then
23
+ echo "Usage: source $0 AGENT_TYPE" >&2
24
+ return 1 2>/dev/null || exit 1
25
+ fi
26
+
27
+ # Function to get provider config (zai, kimi, openrouter, anthropic)
28
+ get_provider_config() {
29
+ local provider="$1"
30
+ local model="${2:-}"
31
+
32
+ case "$provider" in
33
+ zai)
34
+ export ANTHROPIC_BASE_URL="https://api.z.ai/api/anthropic"
35
+ export ANTHROPIC_AUTH_TOKEN="${ZAI_API_KEY:-}"
36
+ export ANTHROPIC_MODEL="${model:-glm-4.6}"
37
+ export ANTHROPIC_SMALL_FAST_MODEL="${model:-glm-4.6}"
38
+ ;;
39
+ kimi)
40
+ export ANTHROPIC_BASE_URL="https://api.moonshot.ai/anthropic"
41
+ export ANTHROPIC_AUTH_TOKEN="${KIMI_API_KEY:-}"
42
+ export ANTHROPIC_MODEL="${model:-kimi-k2-turbo-preview}"
43
+ export ANTHROPIC_SMALL_FAST_MODEL="${model:-kimi-k2-turbo-preview}"
44
+ ;;
45
+ openrouter)
46
+ export ANTHROPIC_BASE_URL="https://openrouter.ai/api/v1"
47
+ export ANTHROPIC_AUTH_TOKEN="${OPENROUTER_API_KEY:-}"
48
+ export ANTHROPIC_MODEL="${model:-anthropic/claude-sonnet-4.5}"
49
+ export ANTHROPIC_SMALL_FAST_MODEL="${model:-anthropic/claude-sonnet-4.5}"
50
+ ;;
51
+ anthropic|*)
52
+ # Use default Anthropic settings (remove custom env vars)
53
+ unset ANTHROPIC_BASE_URL
54
+ unset ANTHROPIC_AUTH_TOKEN
55
+ unset ANTHROPIC_MODEL
56
+ unset ANTHROPIC_SMALL_FAST_MODEL
57
+ ;;
58
+ esac
59
+ }
60
+
61
+ # Function to detect provider from base URL
62
+ detect_provider_from_url() {
63
+ local base_url="$1"
64
+
65
+ if [[ "$base_url" == *"z.ai"* ]]; then
66
+ echo "zai"
67
+ elif [[ "$base_url" == *"moonshot.ai"* ]]; then
68
+ echo "kimi"
69
+ elif [[ "$base_url" == *"openrouter.ai"* ]]; then
70
+ echo "openrouter"
71
+ else
72
+ echo "anthropic"
73
+ fi
74
+ }
75
+
76
+ # Step 1: Check if custom routing is enabled
77
+ if [[ "$CUSTOM_ROUTING_ENABLED" != "true" ]]; then
78
+ # Custom routing disabled - use Main Chat settings from .claude/settings.json
79
+ if [[ -f "$SETTINGS_FILE" ]]; then
80
+ BASE_URL=$(jq -r '.env.ANTHROPIC_BASE_URL // empty' "$SETTINGS_FILE" 2>/dev/null || echo "")
81
+
82
+ if [[ -n "$BASE_URL" ]]; then
83
+ # Main Chat has custom provider configured
84
+ export ANTHROPIC_BASE_URL="$BASE_URL"
85
+ export ANTHROPIC_AUTH_TOKEN=$(jq -r '.env.ANTHROPIC_AUTH_TOKEN // empty' "$SETTINGS_FILE" 2>/dev/null || echo "")
86
+ export ANTHROPIC_MODEL=$(jq -r '.env.ANTHROPIC_MODEL // empty' "$SETTINGS_FILE" 2>/dev/null || echo "")
87
+ export ANTHROPIC_SMALL_FAST_MODEL=$(jq -r '.env.ANTHROPIC_SMALL_FAST_MODEL // empty' "$SETTINGS_FILE" 2>/dev/null || echo "")
88
+ fi
89
+ # else: No custom provider, use default Anthropic
90
+ fi
91
+ return 0 2>/dev/null || exit 0
92
+ fi
93
+
94
+ # Step 2: Custom routing enabled - check agent profile for PROVIDER_PARAMETERS
95
+ AGENT_PROVIDER=$(bash .claude/skills/cfn-agent-spawning/parse-agent-provider.sh "$AGENT_TYPE" --field provider)
96
+ AGENT_MODEL=$(bash .claude/skills/cfn-agent-spawning/parse-agent-provider.sh "$AGENT_TYPE" --field model)
97
+
98
+ if [[ -n "$AGENT_PROVIDER" ]]; then
99
+ # Agent has provider parameters - use them
100
+ get_provider_config "$AGENT_PROVIDER" "$AGENT_MODEL"
101
+ else
102
+ # No agent-specific provider - default to Z.ai with glm-4.6
103
+ export ANTHROPIC_BASE_URL="https://api.z.ai/api/anthropic"
104
+ export ANTHROPIC_AUTH_TOKEN="${ZAI_API_KEY:-}"
105
+ export ANTHROPIC_MODEL="glm-4.6"
106
+ export ANTHROPIC_SMALL_FAST_MODEL="glm-4.6"
107
+ fi
@@ -0,0 +1,59 @@
1
+ #!/bin/bash
2
+
3
+ # Parse Agent Provider Parameters
4
+ # Extracts provider and model from agent profile's PROVIDER_PARAMETERS section
5
+ # Usage: parse-agent-provider.sh AGENT_TYPE [--field provider|model]
6
+
7
+ set -euo pipefail
8
+
9
+ AGENT_TYPE="${1:-}"
10
+ FIELD="${2:---field}"
11
+ FIELD_VALUE="${3:-provider}"
12
+
13
+ if [[ -z "$AGENT_TYPE" ]]; then
14
+ echo "Usage: $0 AGENT_TYPE [--field provider|model]" >&2
15
+ exit 1
16
+ fi
17
+
18
+ # Find agent file in multiple locations
19
+ AGENT_FILE=""
20
+ SEARCH_PATHS=(
21
+ ".claude/agents/cfn-dev-team/**/${AGENT_TYPE}.md"
22
+ ".claude/agents/custom/${AGENT_TYPE}.md"
23
+ ".claude/agents/${AGENT_TYPE}.md"
24
+ )
25
+
26
+ for pattern in "${SEARCH_PATHS[@]}"; do
27
+ # Use find with glob pattern
28
+ while IFS= read -r -d '' file; do
29
+ if [[ -f "$file" ]]; then
30
+ AGENT_FILE="$file"
31
+ break 2
32
+ fi
33
+ done < <(find .claude/agents -type f -name "${AGENT_TYPE}.md" -print0 2>/dev/null)
34
+ done
35
+
36
+ if [[ -z "$AGENT_FILE" ]]; then
37
+ # Agent file not found, return empty (will fallback to main chat settings)
38
+ echo ""
39
+ exit 0
40
+ fi
41
+
42
+ # Extract PROVIDER_PARAMETERS section
43
+ # Format:
44
+ # <!-- PROVIDER_PARAMETERS
45
+ # provider: kimi
46
+ # model: kimi-k2-turbo-preview
47
+ # -->
48
+
49
+ PARAM_VALUE=$(awk '
50
+ /<!-- PROVIDER_PARAMETERS/,/-->/ {
51
+ if ($0 ~ /^'"${FIELD_VALUE}"':/) {
52
+ sub(/^'"${FIELD_VALUE}"':[ \t]*/, "")
53
+ print $0
54
+ exit
55
+ }
56
+ }
57
+ ' "$AGENT_FILE" | tr -d '\r' | xargs)
58
+
59
+ echo "$PARAM_VALUE"
@@ -208,8 +208,12 @@ if ! docker image inspect "$IMAGE" &> /dev/null; then
208
208
  exit 1
209
209
  fi
210
210
 
211
- # Get project root directory
212
- PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd)"
211
+ # Get project root directory (use git root for reliability)
212
+ PROJECT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)"
213
+ if [[ -z "$PROJECT_ROOT" ]]; then
214
+ # Fallback to script-relative path
215
+ PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd -P)"
216
+ fi
213
217
  cd "$PROJECT_ROOT"
214
218
 
215
219
  # Create workspace directory with proper permissions
@@ -328,16 +332,30 @@ DOCKER_CMD="$DOCKER_CMD --env AGENT_TYPE=${AGENT_TYPE}"
328
332
  DOCKER_CMD="$DOCKER_CMD --env TASK_ID=${TASK_ID}"
329
333
  DOCKER_CMD="$DOCKER_CMD --env PROJECT_ROOT=/app"
330
334
 
331
- # Add Redis URL if Redis is available
332
- if command -v redis-cli &> /dev/null && redis-cli ping &> /dev/null; then
333
- DOCKER_CMD="$DOCKER_CMD --env REDIS_URL=redis://redis:6379"
334
- fi
335
+ # Add Redis URL for container-to-container networking
336
+ # Always set Redis URL regardless of host Redis status
337
+ DOCKER_CMD="$DOCKER_CMD --env REDIS_URL=redis://redis:6379"
335
338
 
336
339
  # Add MCP tokens file path if tokens generated
337
340
  if [[ -n "$TOKENS_FILE" ]]; then
338
341
  DOCKER_CMD="$DOCKER_CMD --env MCP_TOKENS_FILE=/app/workspace/mcp-tokens.json"
339
342
  fi
340
343
 
344
+ # Add provider routing environment variables (custom routing support)
345
+ source .claude/skills/cfn-agent-spawning/get-agent-provider-env.sh "$AGENT_TYPE"
346
+ if [[ -n "${ANTHROPIC_BASE_URL:-}" ]]; then
347
+ DOCKER_CMD="$DOCKER_CMD --env ANTHROPIC_BASE_URL=${ANTHROPIC_BASE_URL}"
348
+ fi
349
+ if [[ -n "${ANTHROPIC_AUTH_TOKEN:-}" ]]; then
350
+ DOCKER_CMD="$DOCKER_CMD --env ANTHROPIC_AUTH_TOKEN=${ANTHROPIC_AUTH_TOKEN}"
351
+ fi
352
+ if [[ -n "${ANTHROPIC_MODEL:-}" ]]; then
353
+ DOCKER_CMD="$DOCKER_CMD --env ANTHROPIC_MODEL=${ANTHROPIC_MODEL}"
354
+ fi
355
+ if [[ -n "${ANTHROPIC_SMALL_FAST_MODEL:-}" ]]; then
356
+ DOCKER_CMD="$DOCKER_CMD --env ANTHROPIC_SMALL_FAST_MODEL=${ANTHROPIC_SMALL_FAST_MODEL}"
357
+ fi
358
+
341
359
  # Add custom environment variables
342
360
  if [[ -n "$ENVIRONMENT" ]]; then
343
361
  IFS=',' read -ra ENV_ARRAY <<< "$ENVIRONMENT"
@@ -190,15 +190,24 @@ spawn_agents_with_context() {
190
190
  ((injection_success_count++))
191
191
  fi
192
192
 
193
- # Spawn agent in background with enriched context
194
- npx claude-flow-novice agent "$safe_agent_type" \
195
- --task-id "$safe_task_id" \
196
- --agent-id "$safe_agent_id" \
197
- --iteration "$iteration" \
198
- --context "$context_to_use" &
199
-
200
- # Store PID for monitoring
201
- AGENT_PID=$!
193
+ # Set provider environment variables for this agent (custom routing support)
194
+ # Spawn in subshell to isolate provider env vars per agent
195
+ (
196
+ source .claude/skills/cfn-agent-spawning/get-agent-provider-env.sh "$safe_agent_type"
197
+
198
+ # Spawn agent in background with enriched context and custom provider
199
+ npx claude-flow-novice agent "$safe_agent_type" \
200
+ --task-id "$safe_task_id" \
201
+ --agent-id "$safe_agent_id" \
202
+ --iteration "$iteration" \
203
+ --context "$context_to_use" &
204
+
205
+ AGENT_PID=$!
206
+ echo $AGENT_PID
207
+ )
208
+
209
+ # Capture PID from subshell output
210
+ AGENT_PID=$(jobs -p | tail -1)
202
211
  "$REDIS_COORD_SKILL/store-context.sh" \
203
212
  --task-id "$task_id" \
204
213
  --key "${UNIQUE_AGENT_ID}:pid" \
@@ -10,6 +10,11 @@ validation_hooks:
10
10
  - test-coverage-validator
11
11
  ---
12
12
 
13
+ <!-- PROVIDER_PARAMETERS
14
+ provider: zai
15
+ model: glm-4.6
16
+ -->
17
+
13
18
  # Backend Developer Agent
14
19
 
15
20
  ## Core Responsibilities
@@ -1,30 +1,47 @@
1
1
  ---
2
- description: Switch Main Chat and Task tool between Z.ai and Anthropic providers
2
+ description: Switch Main Chat and Task tool between Z.ai, Kimi, OpenRouter, and Anthropic providers
3
3
  tags: [config, api, cost-optimization]
4
4
  ---
5
5
 
6
- Switch Main Chat and Task() tool API provider between Z.ai (cost-optimized) and Anthropic (high-quality).
6
+ Switch Main Chat and Task() tool API provider between multiple AI providers.
7
7
 
8
- **Important:** CLI agents always use Z.ai (from `.env`). This command only affects Main Chat and Task() spawned agents.
8
+ **Important:** CLI agents support custom routing when enabled. This command affects Main Chat and Task() spawned agents.
9
9
 
10
10
  **Usage:**
11
11
  - `/switch-api` - Show current status
12
- - `/switch-api zai` - Main Chat/Task tool use Z.ai ($0.50/1M tokens)
13
- - `/switch-api max` - Main Chat/Task tool use Anthropic ($15/1M tokens, requires re-login)
12
+ - `/switch-api [zai|kimi|openrouter|max]` - Switch provider
13
+ - `zai` - Z.ai ($0.50/1M tokens)
14
+ - `kimi` - Moonshot Kimi ($2/1M tokens)
15
+ - `openrouter` - OpenRouter (varies by model)
16
+ - `max` or `claude` - Anthropic ($15/1M tokens, requires re-login)
14
17
 
15
18
  **Arguments:**
16
19
  - `status` - Show current routing configuration (default)
17
20
  - `zai` - Route Main Chat + Task tool to Z.ai for cost savings
21
+ - `kimi` - Route Main Chat + Task tool to Moonshot Kimi
22
+ - `openrouter` - Route Main Chat + Task tool to OpenRouter
18
23
  - `max` or `claude` - Route Main Chat + Task tool to Anthropic for quality
19
24
 
20
25
  **What This Does:**
21
26
 
22
27
  `/switch-api zai`:
23
- - Adds env vars to `.claude/settings.json`
28
+ - Adds Z.ai env vars to `.claude/settings.json`
24
29
  - Main Chat + Task() agents use Z.ai
25
30
  - Cost: $0.50/1M tokens (97% savings)
26
31
  - No login required
27
32
 
33
+ `/switch-api kimi`:
34
+ - Adds Kimi env vars to `.claude/settings.json`
35
+ - Main Chat + Task() agents use Moonshot Kimi
36
+ - Cost: ~$2/1M tokens
37
+ - Requires `KIMI_API_KEY` in root `.env`
38
+
39
+ `/switch-api openrouter`:
40
+ - Adds OpenRouter env vars to `.claude/settings.json`
41
+ - Main Chat + Task() agents use OpenRouter
42
+ - Cost: Varies by model
43
+ - Requires `OPENROUTER_API_KEY` in root `.env`
44
+
28
45
  `/switch-api max`:
29
46
  - Removes env vars from `.claude/settings.json`
30
47
  - Main Chat + Task() agents use Anthropic
@@ -33,21 +50,25 @@ Switch Main Chat and Task() tool API provider between Z.ai (cost-optimized) and
33
50
 
34
51
  **Combined Architecture:**
35
52
  ```
36
- Main Chat (Anthropic or Z.ai - your choice)
53
+ Main Chat (Anthropic/Z.ai/Kimi/OpenRouter - your choice)
37
54
 
38
55
  Task() → Coordinator (uses Main Chat provider)
39
56
 
40
- CLI spawn → Workers (always Z.ai from .env)
57
+ CLI spawn → Workers (custom routing when enabled, see agent profiles)
41
58
  ```
42
59
 
43
60
  **Execute:**
44
61
  ```bash
45
- bash scripts/switch-api.sh {{args}}
62
+ bash "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/scripts/switch-api.sh" {{args}}
46
63
  ```
47
64
 
65
+ **Note:** Script automatically resolves to project root directory.
66
+
48
67
  **Examples:**
49
68
  ```bash
50
- /switch-api # Show current routing
51
- /switch-api zai # Cost-optimize Main Chat
52
- /switch-api max # Quality-optimize Main Chat (requires re-login)
69
+ /switch-api # Show current routing
70
+ /switch-api zai # Cost-optimize with Z.ai
71
+ /switch-api kimi # Use Moonshot Kimi
72
+ /switch-api openrouter # Use OpenRouter (access 400+ models)
73
+ /switch-api max # Quality-optimize with Anthropic (requires re-login)
53
74
  ```
@@ -0,0 +1,107 @@
1
+ #!/bin/bash
2
+
3
+ # Get Agent Provider Environment Variables
4
+ # Determines which provider environment variables to use for CLI/Docker agent spawning
5
+ #
6
+ # Logic:
7
+ # 1. If custom routing is disabled, use Main Chat settings (from .claude/settings.json)
8
+ # 2. If custom routing is enabled:
9
+ # a. Check agent profile for PROVIDER_PARAMETERS
10
+ # b. If found, use agent-specific provider/model
11
+ # c. If not found, use Main Chat settings
12
+ #
13
+ # Usage: source get-agent-provider-env.sh AGENT_TYPE
14
+ # Exports: ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN, ANTHROPIC_MODEL, ANTHROPIC_SMALL_FAST_MODEL
15
+
16
+ set -euo pipefail
17
+
18
+ AGENT_TYPE="${1:-}"
19
+ CUSTOM_ROUTING_ENABLED="${CFN_CUSTOM_ROUTING:-false}"
20
+ SETTINGS_FILE=".claude/settings.json"
21
+
22
+ if [[ -z "$AGENT_TYPE" ]]; then
23
+ echo "Usage: source $0 AGENT_TYPE" >&2
24
+ return 1 2>/dev/null || exit 1
25
+ fi
26
+
27
+ # Function to get provider config (zai, kimi, openrouter, anthropic)
28
+ get_provider_config() {
29
+ local provider="$1"
30
+ local model="${2:-}"
31
+
32
+ case "$provider" in
33
+ zai)
34
+ export ANTHROPIC_BASE_URL="https://api.z.ai/api/anthropic"
35
+ export ANTHROPIC_AUTH_TOKEN="${ZAI_API_KEY:-}"
36
+ export ANTHROPIC_MODEL="${model:-glm-4.6}"
37
+ export ANTHROPIC_SMALL_FAST_MODEL="${model:-glm-4.6}"
38
+ ;;
39
+ kimi)
40
+ export ANTHROPIC_BASE_URL="https://api.moonshot.ai/anthropic"
41
+ export ANTHROPIC_AUTH_TOKEN="${KIMI_API_KEY:-}"
42
+ export ANTHROPIC_MODEL="${model:-kimi-k2-turbo-preview}"
43
+ export ANTHROPIC_SMALL_FAST_MODEL="${model:-kimi-k2-turbo-preview}"
44
+ ;;
45
+ openrouter)
46
+ export ANTHROPIC_BASE_URL="https://openrouter.ai/api/v1"
47
+ export ANTHROPIC_AUTH_TOKEN="${OPENROUTER_API_KEY:-}"
48
+ export ANTHROPIC_MODEL="${model:-anthropic/claude-sonnet-4.5}"
49
+ export ANTHROPIC_SMALL_FAST_MODEL="${model:-anthropic/claude-sonnet-4.5}"
50
+ ;;
51
+ anthropic|*)
52
+ # Use default Anthropic settings (remove custom env vars)
53
+ unset ANTHROPIC_BASE_URL
54
+ unset ANTHROPIC_AUTH_TOKEN
55
+ unset ANTHROPIC_MODEL
56
+ unset ANTHROPIC_SMALL_FAST_MODEL
57
+ ;;
58
+ esac
59
+ }
60
+
61
+ # Function to detect provider from base URL
62
+ detect_provider_from_url() {
63
+ local base_url="$1"
64
+
65
+ if [[ "$base_url" == *"z.ai"* ]]; then
66
+ echo "zai"
67
+ elif [[ "$base_url" == *"moonshot.ai"* ]]; then
68
+ echo "kimi"
69
+ elif [[ "$base_url" == *"openrouter.ai"* ]]; then
70
+ echo "openrouter"
71
+ else
72
+ echo "anthropic"
73
+ fi
74
+ }
75
+
76
+ # Step 1: Check if custom routing is enabled
77
+ if [[ "$CUSTOM_ROUTING_ENABLED" != "true" ]]; then
78
+ # Custom routing disabled - use Main Chat settings from .claude/settings.json
79
+ if [[ -f "$SETTINGS_FILE" ]]; then
80
+ BASE_URL=$(jq -r '.env.ANTHROPIC_BASE_URL // empty' "$SETTINGS_FILE" 2>/dev/null || echo "")
81
+
82
+ if [[ -n "$BASE_URL" ]]; then
83
+ # Main Chat has custom provider configured
84
+ export ANTHROPIC_BASE_URL="$BASE_URL"
85
+ export ANTHROPIC_AUTH_TOKEN=$(jq -r '.env.ANTHROPIC_AUTH_TOKEN // empty' "$SETTINGS_FILE" 2>/dev/null || echo "")
86
+ export ANTHROPIC_MODEL=$(jq -r '.env.ANTHROPIC_MODEL // empty' "$SETTINGS_FILE" 2>/dev/null || echo "")
87
+ export ANTHROPIC_SMALL_FAST_MODEL=$(jq -r '.env.ANTHROPIC_SMALL_FAST_MODEL // empty' "$SETTINGS_FILE" 2>/dev/null || echo "")
88
+ fi
89
+ # else: No custom provider, use default Anthropic
90
+ fi
91
+ return 0 2>/dev/null || exit 0
92
+ fi
93
+
94
+ # Step 2: Custom routing enabled - check agent profile for PROVIDER_PARAMETERS
95
+ AGENT_PROVIDER=$(bash .claude/skills/cfn-agent-spawning/parse-agent-provider.sh "$AGENT_TYPE" --field provider)
96
+ AGENT_MODEL=$(bash .claude/skills/cfn-agent-spawning/parse-agent-provider.sh "$AGENT_TYPE" --field model)
97
+
98
+ if [[ -n "$AGENT_PROVIDER" ]]; then
99
+ # Agent has provider parameters - use them
100
+ get_provider_config "$AGENT_PROVIDER" "$AGENT_MODEL"
101
+ else
102
+ # No agent-specific provider - default to Z.ai with glm-4.6
103
+ export ANTHROPIC_BASE_URL="https://api.z.ai/api/anthropic"
104
+ export ANTHROPIC_AUTH_TOKEN="${ZAI_API_KEY:-}"
105
+ export ANTHROPIC_MODEL="glm-4.6"
106
+ export ANTHROPIC_SMALL_FAST_MODEL="glm-4.6"
107
+ fi
@@ -0,0 +1,59 @@
1
+ #!/bin/bash
2
+
3
+ # Parse Agent Provider Parameters
4
+ # Extracts provider and model from agent profile's PROVIDER_PARAMETERS section
5
+ # Usage: parse-agent-provider.sh AGENT_TYPE [--field provider|model]
6
+
7
+ set -euo pipefail
8
+
9
+ AGENT_TYPE="${1:-}"
10
+ FIELD="${2:---field}"
11
+ FIELD_VALUE="${3:-provider}"
12
+
13
+ if [[ -z "$AGENT_TYPE" ]]; then
14
+ echo "Usage: $0 AGENT_TYPE [--field provider|model]" >&2
15
+ exit 1
16
+ fi
17
+
18
+ # Find agent file in multiple locations
19
+ AGENT_FILE=""
20
+ SEARCH_PATHS=(
21
+ ".claude/agents/cfn-dev-team/**/${AGENT_TYPE}.md"
22
+ ".claude/agents/custom/${AGENT_TYPE}.md"
23
+ ".claude/agents/${AGENT_TYPE}.md"
24
+ )
25
+
26
+ for pattern in "${SEARCH_PATHS[@]}"; do
27
+ # Use find with glob pattern
28
+ while IFS= read -r -d '' file; do
29
+ if [[ -f "$file" ]]; then
30
+ AGENT_FILE="$file"
31
+ break 2
32
+ fi
33
+ done < <(find .claude/agents -type f -name "${AGENT_TYPE}.md" -print0 2>/dev/null)
34
+ done
35
+
36
+ if [[ -z "$AGENT_FILE" ]]; then
37
+ # Agent file not found, return empty (will fallback to main chat settings)
38
+ echo ""
39
+ exit 0
40
+ fi
41
+
42
+ # Extract PROVIDER_PARAMETERS section
43
+ # Format:
44
+ # <!-- PROVIDER_PARAMETERS
45
+ # provider: kimi
46
+ # model: kimi-k2-turbo-preview
47
+ # -->
48
+
49
+ PARAM_VALUE=$(awk '
50
+ /<!-- PROVIDER_PARAMETERS/,/-->/ {
51
+ if ($0 ~ /^'"${FIELD_VALUE}"':/) {
52
+ sub(/^'"${FIELD_VALUE}"':[ \t]*/, "")
53
+ print $0
54
+ exit
55
+ }
56
+ }
57
+ ' "$AGENT_FILE" | tr -d '\r' | xargs)
58
+
59
+ echo "$PARAM_VALUE"
@@ -208,8 +208,12 @@ if ! docker image inspect "$IMAGE" &> /dev/null; then
208
208
  exit 1
209
209
  fi
210
210
 
211
- # Get project root directory
212
- PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd)"
211
+ # Get project root directory (use git root for reliability)
212
+ PROJECT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)"
213
+ if [[ -z "$PROJECT_ROOT" ]]; then
214
+ # Fallback to script-relative path
215
+ PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd -P)"
216
+ fi
213
217
  cd "$PROJECT_ROOT"
214
218
 
215
219
  # Create workspace directory with proper permissions
@@ -328,16 +332,30 @@ DOCKER_CMD="$DOCKER_CMD --env AGENT_TYPE=${AGENT_TYPE}"
328
332
  DOCKER_CMD="$DOCKER_CMD --env TASK_ID=${TASK_ID}"
329
333
  DOCKER_CMD="$DOCKER_CMD --env PROJECT_ROOT=/app"
330
334
 
331
- # Add Redis URL if Redis is available
332
- if command -v redis-cli &> /dev/null && redis-cli ping &> /dev/null; then
333
- DOCKER_CMD="$DOCKER_CMD --env REDIS_URL=redis://redis:6379"
334
- fi
335
+ # Add Redis URL for container-to-container networking
336
+ # Always set Redis URL regardless of host Redis status
337
+ DOCKER_CMD="$DOCKER_CMD --env REDIS_URL=redis://redis:6379"
335
338
 
336
339
  # Add MCP tokens file path if tokens generated
337
340
  if [[ -n "$TOKENS_FILE" ]]; then
338
341
  DOCKER_CMD="$DOCKER_CMD --env MCP_TOKENS_FILE=/app/workspace/mcp-tokens.json"
339
342
  fi
340
343
 
344
+ # Add provider routing environment variables (custom routing support)
345
+ source .claude/skills/cfn-agent-spawning/get-agent-provider-env.sh "$AGENT_TYPE"
346
+ if [[ -n "${ANTHROPIC_BASE_URL:-}" ]]; then
347
+ DOCKER_CMD="$DOCKER_CMD --env ANTHROPIC_BASE_URL=${ANTHROPIC_BASE_URL}"
348
+ fi
349
+ if [[ -n "${ANTHROPIC_AUTH_TOKEN:-}" ]]; then
350
+ DOCKER_CMD="$DOCKER_CMD --env ANTHROPIC_AUTH_TOKEN=${ANTHROPIC_AUTH_TOKEN}"
351
+ fi
352
+ if [[ -n "${ANTHROPIC_MODEL:-}" ]]; then
353
+ DOCKER_CMD="$DOCKER_CMD --env ANTHROPIC_MODEL=${ANTHROPIC_MODEL}"
354
+ fi
355
+ if [[ -n "${ANTHROPIC_SMALL_FAST_MODEL:-}" ]]; then
356
+ DOCKER_CMD="$DOCKER_CMD --env ANTHROPIC_SMALL_FAST_MODEL=${ANTHROPIC_SMALL_FAST_MODEL}"
357
+ fi
358
+
341
359
  # Add custom environment variables
342
360
  if [[ -n "$ENVIRONMENT" ]]; then
343
361
  IFS=',' read -ra ENV_ARRAY <<< "$ENVIRONMENT"
@@ -190,15 +190,24 @@ spawn_agents_with_context() {
190
190
  ((injection_success_count++))
191
191
  fi
192
192
 
193
- # Spawn agent in background with enriched context
194
- npx claude-flow-novice agent "$safe_agent_type" \
195
- --task-id "$safe_task_id" \
196
- --agent-id "$safe_agent_id" \
197
- --iteration "$iteration" \
198
- --context "$context_to_use" &
199
-
200
- # Store PID for monitoring
201
- AGENT_PID=$!
193
+ # Set provider environment variables for this agent (custom routing support)
194
+ # Spawn in subshell to isolate provider env vars per agent
195
+ (
196
+ source .claude/skills/cfn-agent-spawning/get-agent-provider-env.sh "$safe_agent_type"
197
+
198
+ # Spawn agent in background with enriched context and custom provider
199
+ npx claude-flow-novice agent "$safe_agent_type" \
200
+ --task-id "$safe_task_id" \
201
+ --agent-id "$safe_agent_id" \
202
+ --iteration "$iteration" \
203
+ --context "$context_to_use" &
204
+
205
+ AGENT_PID=$!
206
+ echo $AGENT_PID
207
+ )
208
+
209
+ # Capture PID from subshell output
210
+ AGENT_PID=$(jobs -p | tail -1)
202
211
  "$REDIS_COORD_SKILL/store-context.sh" \
203
212
  --task-id "$task_id" \
204
213
  --key "${UNIQUE_AGENT_ID}:pid" \
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-flow-novice",
3
- "version": "2.14.37",
3
+ "version": "2.15.0",
4
4
  "description": "AI agent orchestration framework with namespace-isolated skills, agents, and CFN Loop validation. Safe installation with ~0.01% collision risk.",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -2,12 +2,14 @@
2
2
  ##############################################################################
3
3
  # Claude API Switcher - Main Chat & Task Tool Provider Routing
4
4
  #
5
- # Usage: scripts/switch-api.sh [zai|max|status]
5
+ # Usage: scripts/switch-api.sh [zai|kimi|openrouter|max|status]
6
6
  #
7
7
  # What it does:
8
- # - zai: Main Chat + Task tool use Z.ai (add env vars to settings.json)
9
- # - max: Main Chat + Task tool use Anthropic (remove env vars, requires re-login)
10
- # - CLI: Always uses Z.ai (controlled by .env CLAUDE_API_PROVIDER=zai)
8
+ # - zai: Main Chat + Task tool use Z.ai
9
+ # - kimi: Main Chat + Task tool use Moonshot Kimi
10
+ # - openrouter: Main Chat + Task tool use OpenRouter
11
+ # - max: Main Chat + Task tool use Anthropic (requires re-login)
12
+ # - CLI: Respects custom routing when enabled (see agent profiles)
11
13
  #
12
14
  # Settings file: .claude/settings.json (project local)
13
15
  ##############################################################################
@@ -43,14 +45,25 @@ show_status() {
43
45
  return
44
46
  fi
45
47
 
46
- # Check for Z.ai env vars in settings
48
+ # Check for custom provider env vars in settings
47
49
  if grep -q "ANTHROPIC_BASE_URL" "$SETTINGS_FILE" 2>/dev/null; then
48
50
  BASE_URL=$(jq -r '.env.ANTHROPIC_BASE_URL // empty' "$SETTINGS_FILE" 2>/dev/null || echo "")
51
+ MODEL=$(jq -r '.env.ANTHROPIC_MODEL // empty' "$SETTINGS_FILE" 2>/dev/null || echo "")
49
52
 
50
53
  if [[ "$BASE_URL" == *"z.ai"* ]]; then
51
54
  echo -e "${GREEN}✓ Main Chat/Task Tool:${NC} Z.ai"
52
55
  echo " Base URL: $BASE_URL"
53
56
  echo " Cost: \$0.50/1M tokens"
57
+ elif [[ "$BASE_URL" == *"moonshot.ai"* ]]; then
58
+ echo -e "${GREEN}✓ Main Chat/Task Tool:${NC} Moonshot Kimi"
59
+ echo " Base URL: $BASE_URL"
60
+ echo " Model: $MODEL"
61
+ echo " Cost: ~\$2/1M tokens"
62
+ elif [[ "$BASE_URL" == *"openrouter.ai"* ]]; then
63
+ echo -e "${GREEN}✓ Main Chat/Task Tool:${NC} OpenRouter"
64
+ echo " Base URL: $BASE_URL"
65
+ echo " Model: $MODEL"
66
+ echo " Cost: Varies by model"
54
67
  else
55
68
  echo -e "${GREEN}✓ Main Chat/Task Tool:${NC} Custom"
56
69
  echo " Base URL: $BASE_URL"
@@ -129,6 +142,107 @@ switch_to_zai() {
129
142
  echo ""
130
143
  }
131
144
 
145
+ ##############################################################################
146
+ # Switch to Kimi for Main Chat and Task Tool
147
+ ##############################################################################
148
+ switch_to_kimi() {
149
+ echo -e "${BLUE}Switching Main Chat/Task Tool to Moonshot Kimi...${NC}"
150
+ echo ""
151
+
152
+ # Backup current settings
153
+ if [ -f "$SETTINGS_FILE" ]; then
154
+ BACKUP_NAME="settings-$(date +%Y%m%d-%H%M%S)-before-kimi.json"
155
+ cp "$SETTINGS_FILE" "$BACKUP_DIR/$BACKUP_NAME"
156
+ echo -e "${GREEN}✓${NC} Backed up: $BACKUP_DIR/$BACKUP_NAME"
157
+ fi
158
+
159
+ # Read current settings or create empty object
160
+ if [ -f "$SETTINGS_FILE" ]; then
161
+ CURRENT_SETTINGS=$(cat "$SETTINGS_FILE")
162
+ else
163
+ CURRENT_SETTINGS='{}'
164
+ fi
165
+
166
+ # Add Kimi env vars to settings (read from .env)
167
+ KIMI_KEY=$(grep -E "^KIMI_API_KEY=" .env | head -1 | cut -d'=' -f2 | sed 's/#.*//' | xargs)
168
+ if [ -z "$KIMI_KEY" ]; then
169
+ echo -e "${RED}Error: KIMI_API_KEY not found in .env${NC}"
170
+ exit 1
171
+ fi
172
+ NEW_SETTINGS=$(echo "$CURRENT_SETTINGS" | jq --arg key "$KIMI_KEY" '. + {"env": ((.env // {}) + {"ANTHROPIC_BASE_URL": "https://api.moonshot.ai/anthropic", "ANTHROPIC_AUTH_TOKEN": $key, "ANTHROPIC_MODEL": "kimi-k2-turbo-preview", "ANTHROPIC_SMALL_FAST_MODEL": "kimi-k2-turbo-preview"})}')
173
+
174
+ echo "$NEW_SETTINGS" > "$SETTINGS_FILE"
175
+
176
+ echo ""
177
+ echo -e "${GREEN}═══════════════════════════════════════${NC}"
178
+ echo -e "${GREEN}✓ Switched to Moonshot Kimi${NC}"
179
+ echo -e "${GREEN}═══════════════════════════════════════${NC}"
180
+ echo ""
181
+ echo -e "${GREEN}Main Chat + Task Tool:${NC} Kimi"
182
+ echo " • All Task() spawned agents use Kimi"
183
+ echo " • Cost: ~\$2/1M tokens"
184
+ echo " • No login required"
185
+ echo ""
186
+ echo -e "${YELLOW}Next Steps:${NC}"
187
+ echo " 1. Restart Claude desktop (if running)"
188
+ echo " 2. Test: Main Chat should use Kimi"
189
+ echo ""
190
+ }
191
+
192
+ ##############################################################################
193
+ # Switch to OpenRouter for Main Chat and Task Tool
194
+ ##############################################################################
195
+ switch_to_openrouter() {
196
+ echo -e "${BLUE}Switching Main Chat/Task Tool to OpenRouter...${NC}"
197
+ echo ""
198
+
199
+ # Backup current settings
200
+ if [ -f "$SETTINGS_FILE" ]; then
201
+ BACKUP_NAME="settings-$(date +%Y%m%d-%H%M%S)-before-openrouter.json"
202
+ cp "$SETTINGS_FILE" "$BACKUP_DIR/$BACKUP_NAME"
203
+ echo -e "${GREEN}✓${NC} Backed up: $BACKUP_DIR/$BACKUP_NAME"
204
+ fi
205
+
206
+ # Read current settings or create empty object
207
+ if [ -f "$SETTINGS_FILE" ]; then
208
+ CURRENT_SETTINGS=$(cat "$SETTINGS_FILE")
209
+ else
210
+ CURRENT_SETTINGS='{}'
211
+ fi
212
+
213
+ # Add OpenRouter env vars to settings (read from .env)
214
+ OPENROUTER_KEY=$(grep -E "^OPENROUTER_API_KEY=" .env | head -1 | cut -d'=' -f2 | sed 's/#.*//' | xargs)
215
+ if [ -z "$OPENROUTER_KEY" ]; then
216
+ echo -e "${RED}Error: OPENROUTER_API_KEY not found in .env${NC}"
217
+ exit 1
218
+ fi
219
+ # Default to Claude Sonnet 4.5 on OpenRouter
220
+ NEW_SETTINGS=$(echo "$CURRENT_SETTINGS" | jq --arg key "$OPENROUTER_KEY" '. + {"env": ((.env // {}) + {"ANTHROPIC_BASE_URL": "https://openrouter.ai/api/v1", "ANTHROPIC_AUTH_TOKEN": $key, "ANTHROPIC_MODEL": "anthropic/claude-sonnet-4.5", "ANTHROPIC_SMALL_FAST_MODEL": "anthropic/claude-sonnet-4.5"})}')
221
+
222
+ echo "$NEW_SETTINGS" > "$SETTINGS_FILE"
223
+
224
+ echo ""
225
+ echo -e "${GREEN}═══════════════════════════════════════${NC}"
226
+ echo -e "${GREEN}✓ Switched to OpenRouter${NC}"
227
+ echo -e "${GREEN}═══════════════════════════════════════${NC}"
228
+ echo ""
229
+ echo -e "${GREEN}Main Chat + Task Tool:${NC} OpenRouter"
230
+ echo " • All Task() spawned agents use OpenRouter"
231
+ echo " • Default Model: anthropic/claude-sonnet-4.5"
232
+ echo " • Cost: Varies by model"
233
+ echo " • No login required"
234
+ echo ""
235
+ echo -e "${BLUE}Available Models:${NC}"
236
+ echo " • 400+ models from 60+ providers"
237
+ echo " • Change model in .claude/settings.json"
238
+ echo " • Visit: https://openrouter.ai/models"
239
+ echo ""
240
+ echo -e "${YELLOW}Next Steps:${NC}"
241
+ echo " 1. Restart Claude desktop (if running)"
242
+ echo " 2. Test: Main Chat should use OpenRouter"
243
+ echo ""
244
+ }
245
+
132
246
  ##############################################################################
133
247
  # Switch to Anthropic Max for Main Chat and Task Tool
134
248
  ##############################################################################
@@ -197,6 +311,16 @@ case "${1:-status}" in
197
311
  show_status
198
312
  ;;
199
313
 
314
+ kimi|moonshot)
315
+ switch_to_kimi
316
+ show_status
317
+ ;;
318
+
319
+ openrouter|or)
320
+ switch_to_openrouter
321
+ show_status
322
+ ;;
323
+
200
324
  max|claude|anthropic)
201
325
  switch_to_max
202
326
  show_status
@@ -208,17 +332,21 @@ case "${1:-status}" in
208
332
  echo "Usage: $0 [command]"
209
333
  echo ""
210
334
  echo "Commands:"
211
- echo " status Show current API configuration (default)"
212
- echo " zai Switch Main Chat/Task tool to Z.ai"
213
- echo " max Switch Main Chat/Task tool to Anthropic"
335
+ echo " status Show current API configuration (default)"
336
+ echo " zai Switch Main Chat/Task tool to Z.ai"
337
+ echo " kimi Switch Main Chat/Task tool to Moonshot Kimi"
338
+ echo " openrouter Switch Main Chat/Task tool to OpenRouter"
339
+ echo " max Switch Main Chat/Task tool to Anthropic"
214
340
  echo ""
215
341
  echo "Examples:"
216
- echo " $0 # Show current status"
217
- echo " $0 zai # Use Z.ai for Main Chat"
218
- echo " $0 max # Use Anthropic for Main Chat (requires re-login)"
342
+ echo " $0 # Show current status"
343
+ echo " $0 zai # Use Z.ai for Main Chat (\$0.50/1M tokens)"
344
+ echo " $0 kimi # Use Moonshot Kimi (~\$2/1M tokens)"
345
+ echo " $0 openrouter # Use OpenRouter (varies by model)"
346
+ echo " $0 max # Use Anthropic (\$15/1M tokens, requires re-login)"
219
347
  echo ""
220
348
  echo "Notes:"
221
- echo " • CLI agents always use Z.ai (from .env CLAUDE_API_PROVIDER=zai)"
349
+ echo " • CLI agents respect custom routing when enabled"
222
350
  echo " • Main Chat routing affects Task() spawned agents"
223
351
  echo " • Settings file: .claude/settings.json"
224
352
  echo " • Backups saved to: .claude/backups/"