Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions config/cliproxyapi/config.template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ openai-compatibility:
models:
- name: "glm-4.7"
alias: "glm-4.7"

# payload: # Optional payload configuration
# default: # Default rules only set parameters when they are missing in the payload.
# - models:
Expand All @@ -109,7 +108,6 @@ openai-compatibility:
# protocol: "codex" # restricts the rule to a specific protocol, options: openai, gemini, claude, codex
# params: # JSON path (gjson/sjson syntax) -> value
# "reasoning.effort": "high"

oauth-model-alias:
antigravity:
- name: "claude-opus-4-6-thinking"
Expand Down
2 changes: 0 additions & 2 deletions config/cliproxyapi/config.tpl.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ openai-compatibility:
models:
- name: "glm-4.7"
alias: "glm-4.7"

# payload: # Optional payload configuration
# default: # Default rules only set parameters when they are missing in the payload.
# - models:
Expand All @@ -109,7 +108,6 @@ openai-compatibility:
# protocol: "codex" # restricts the rule to a specific protocol, options: openai, gemini, claude, codex
# params: # JSON path (gjson/sjson syntax) -> value
# "reasoning.effort": "high"

oauth-model-alias:
antigravity:
- name: "__CLAUDE_OPUS_THINKING__"
Expand Down
30 changes: 18 additions & 12 deletions scripts/llm-update.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
MODELS="$ROOT/models.json"

[[ -f "$MODELS" ]] || { echo "ERROR: models.json not found" >&2; exit 1; }
[[ -f $MODELS ]] || {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The $MODELS variable should be quoted to prevent issues with word splitting if the file path contains spaces. It's a good practice to always quote variables that hold file paths, as this will prevent bugs if the script is run from a directory with spaces in its name.

Suggested change
[[ -f $MODELS ]] || {
[[ -f "$MODELS" ]] || {

Copilot AI Feb 15, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable $MODELS should be quoted in the test to be consistent with line 63 and to follow shell best practices. While the [[ ]] construct is more forgiving than [ ], it's safer and more consistent to quote variables to prevent potential issues with special characters or whitespace in paths.

Suggested change
[[ -f $MODELS ]] || {
[[ -f "$MODELS" ]] || {

Copilot uses AI. Check for mistakes.
echo "ERROR: models.json not found" >&2
exit 1
}

# jq function: derive display name from a model ID
# claude-opus-4.6 → "Claude Opus 4.6", claude-sonnet-4.5-20250929 → "Claude Sonnet 4.5"
Expand Down Expand Up @@ -41,24 +44,27 @@ done < <(jq -r "$JQ_PRETTY"'

# Template → output pairs
declare -A TEMPLATES=(
[config/openclaw/openclaw.tpl.json]=config/openclaw/openclaw.template.json
[config/opencode/opencode.tpl.jsonc]=config/opencode/opencode.jsonc
[config/llm/extra-openai-models.tpl.yaml]=config/llm/extra-openai-models.yaml
[config/ccs/agy.settings.tpl.json]=config/ccs/agy.settings.template.json
[config/ccs/codex.settings.tpl.json]=config/ccs/codex.settings.template.json
[config/ccs/gemini.settings.tpl.json]=config/ccs/gemini.settings.template.json
[config/ccs/glm.settings.tpl.json]=config/ccs/glm.settings.template.json
[config/codex/config.tpl.toml]=config/codex/config.toml
[config/cliproxyapi/config.tpl.yaml]=config/cliproxyapi/config.template.yaml
["config/openclaw/openclaw.tpl.json"]=config/openclaw/openclaw.template.json
["config/opencode/opencode.tpl.jsonc"]=config/opencode/opencode.jsonc
["config/llm/extra-openai-models.tpl.yaml"]=config/llm/extra-openai-models.yaml
["config/ccs/agy.settings.tpl.json"]=config/ccs/agy.settings.template.json
["config/ccs/codex.settings.tpl.json"]=config/ccs/codex.settings.template.json
["config/ccs/gemini.settings.tpl.json"]=config/ccs/gemini.settings.template.json
["config/ccs/glm.settings.tpl.json"]=config/ccs/glm.settings.template.json
["config/codex/config.tpl.toml"]=config/codex/config.toml
["config/cliproxyapi/config.tpl.yaml"]=config/cliproxyapi/config.template.yaml
)

echo "Updating tool configs from $MODELS ..."
echo

for src in "${!TEMPLATES[@]}"; do
dst="${TEMPLATES[$src]}"
[[ -f "$ROOT/$src" ]] || { echo "SKIP: $src"; continue; }
sed "${sed_args[@]}" "$ROOT/$src" > "$ROOT/$dst"
[[ -f "$ROOT/$src" ]] || {
echo "SKIP: $src"
continue
}
sed "${sed_args[@]}" "$ROOT/$src" >"$ROOT/$dst"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

The sed command is vulnerable to command injection because it uses unvalidated input from models.json to construct substitution expressions. If a value in models.json contains the delimiter | followed by the e flag (e.g., value|e;s|a|b), GNU sed will execute the replacement as a shell command. This could lead to Remote Code Execution (RCE) if models.json is influenced by an attacker (e.g., via a malicious Pull Request).

To remediate this, ensure that all values from models.json are properly escaped before being added to sed_args. For example, you can escape the pipe character using Bash string replacement: ${value//|/\\|}. This should be applied to the value, pretty, and nondot variables where they are added to the sed_args array.

echo "OK: $dst"
done

Expand Down
1 change: 1 addition & 0 deletions spec/coverage_spec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ home-manager/services/neverssl-keepalive/keepalive.sh
install.sh
named-hosts/kyber/rekey-galactica.sh
named-hosts/kyber/setup.sh
scripts/llm-update.sh
scripts/update-gitalias.sh
scripts/update-local-binaries.sh
scripts/upgrade-overlays.sh"
Expand Down
77 changes: 77 additions & 0 deletions spec/llm_update_spec.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#!/usr/bin/env bash
# shellcheck disable=SC2329,SC2034

Describe 'scripts/llm-update.sh'
SCRIPT="$PWD/scripts/llm-update.sh"

Describe 'script properties'
It 'uses bash shebang'
When run bash -c "head -1 '$SCRIPT'"
The output should include '#!/usr/bin/env bash'
End

It 'uses strict mode'
When run bash -c "head -5 '$SCRIPT'"
The output should include 'set -euo pipefail'
End
End

Describe 'models.json dependency'
It 'references models.json'
When run bash -c "grep 'models.json' '$SCRIPT'"
The output should include 'models.json'
End

It 'exits if models.json is missing'
When run bash -c "grep 'models.json not found' '$SCRIPT'"
The output should include 'ERROR'
End
Comment on lines +25 to +28

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This test only verifies that the error message string exists within the script file, but it doesn't test the actual runtime behavior. A more robust test would execute the script in a state where models.json is absent and assert that the script exits with a failure status code and prints the expected error message to stderr. This would provide stronger guarantees about the script's correctness.

Here's an example of how you could write a functional test for this case using shellspec features:

It 'exits if models.json is missing'
  # Temporarily move models.json to simulate its absence
  Before 'mv "$PWD/models.json" "$PWD/models.json.bak"'
  After 'mv "$PWD/models.json.bak" "$PWD/models.json"'

  When run script "$SCRIPT"
  The status should be failure
  The stderr should include 'ERROR: models.json not found'
End

This approach of testing behavior over implementation details could be applied to other tests in this file to make them more effective.

End

Describe 'template processing'
It 'uses sed for substitution'
When run bash -c "grep 'sed' '$SCRIPT'"
The output should include 'sed'
End

It 'defines template-to-output mappings'
When run bash -c "grep 'TEMPLATES' '$SCRIPT'"
The output should include 'TEMPLATES'
End

It 'processes .tpl. template files'
When run bash -c "grep '\.tpl\.' '$SCRIPT'"
The output should include '.tpl.'
End
End

Describe 'jq pretty-printing'
It 'defines a jq pretty function for model names'
When run bash -c "grep 'def pretty' '$SCRIPT'"
The output should include 'def pretty'
End

It 'capitalizes Claude model names'
When run bash -c "grep '"Claude"' '$SCRIPT'"
The output should include 'Claude'
End
End

Describe 'placeholder generation'
It 'converts keys to uppercase placeholders'
When run bash -c "grep 'placeholder=' '$SCRIPT'"
The output should include '__'
End

It 'generates PRETTY variant placeholders'
When run bash -c "grep '_PRETTY__' '$SCRIPT'"
The output should include '_PRETTY__'
End

It 'generates NONDOT variant placeholders'
When run bash -c "grep '_NONDOT__' '$SCRIPT'"
The output should include '_NONDOT__'
End
End

End
Loading