59 lines
3.6 KiB
Bash
Executable File
59 lines
3.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Install opencode + provider config (+ Playwright MCP for browser agents).
|
|
#
|
|
# Required env (provided by the workflow step): OLLAMA_URL OLLAMA_CLOUD_API_KEY NAME SKILLS
|
|
# GITHUB_PATH HOME
|
|
set -eu
|
|
|
|
# PIN the opencode version: an unpinned `latest` means a breaking release (CLI flags, or the
|
|
# --format json event schema that build-activity-log.sh parses) breaks every agent in every repo
|
|
# at once. Bump deliberately by changing this default (or set OPENCODE_VERSION in the step env).
|
|
OPENCODE_VERSION="${OPENCODE_VERSION:-1.17.13}"
|
|
# Skip the download when a cache hit already restored the pinned binary (see the Cache
|
|
# opencode CLI step in agent.yml). The installer always re-fetches otherwise.
|
|
OC_BIN="$HOME/.opencode/bin/opencode"
|
|
if [ -x "$OC_BIN" ] && "$OC_BIN" --version 2>/dev/null | grep -qF "$OPENCODE_VERSION"; then
|
|
echo "opencode $OPENCODE_VERSION already present (cache hit) — skipping install"
|
|
else
|
|
curl -fsSL https://opencode.ai/install | bash -s -- --version "$OPENCODE_VERSION"
|
|
fi
|
|
echo "$HOME/.opencode/bin" >> "$GITHUB_PATH"
|
|
mkdir -p ~/.config/opencode
|
|
# Playwright browser MCP only for agents that need to drive a web app
|
|
MCP='{}'
|
|
case "$NAME" in
|
|
senior|lead|qa)
|
|
echo "Enabling Playwright MCP for @$NAME"
|
|
MCP='{"playwright":{"type":"local","command":["npx","-y","@playwright/mcp@latest","--headless"],"enabled":true}}'
|
|
npx -y playwright install --with-deps chromium || npx -y playwright install chromium || true
|
|
;;
|
|
esac
|
|
# Per-agent skill scoping. Skills are loaded on-demand by opencode: only a skill's one-line
|
|
# `description` ever appears in an agent's <available_skills> list, and the full SKILL.md body
|
|
# (curl/API how-to) is loaded ONLY when the agent calls the `skill` tool — it is never in any
|
|
# system prompt. To also hide the summary from agents that shouldn't use a skill, we deny all
|
|
# skills by default and allow only the ones in this agent's registry list (passed via $SKILLS).
|
|
# A denied skill is hidden entirely (name + description omitted), so e.g. @junior never sees
|
|
# gitea-api at all; it just knows from the roster that @senior/@lead can, and asks them.
|
|
SKILLS="${SKILLS:-[]}"
|
|
PERM=$(jq -nc --argjson s "$SKILLS" '
|
|
{skill: ( {"*":"deny"} + (reduce $s[] as $k ({}; . + {($k):"allow"})) )}')
|
|
# Two ollama providers: local self-hosted (ornith) + Ollama Cloud (gemma4/kimi-k2.7-code/glm-5.2/minimax-m3).
|
|
# The provider `models:` maps are DERIVED from agents.json (the single source of truth, shared with
|
|
# route.sh) so every model an agent is routed to is always declared in the provider config.
|
|
# `ollama-cloud/` prefix models go to the cloud provider; `ollama/` prefix models go to the local
|
|
# provider. Built-in providers (e.g. `anthropic/claude-opus-4-8` for @lead) are not derived here.
|
|
# See issue #31.
|
|
AGENTS_JSON="${SCRIPTS:-$(dirname -- "$0")}/agents.json"
|
|
CLOUD_MODELS=$(jq -r '[.[] | .model | select(startswith("ollama-cloud/")) | sub("^ollama-cloud/";"")] | map({(.):{}}) | add // {}' "$AGENTS_JSON")
|
|
LOCAL_MODELS=$(jq -r '[.[] | .model | select(startswith("ollama/")) | sub("^ollama/";"")] | map({(.):{}}) | add // {"ornith:35b":{}}' "$AGENTS_JSON")
|
|
jq -n --argjson mcp "$MCP" --argjson perm "$PERM" --argjson cloud "$CLOUD_MODELS" --argjson local "$LOCAL_MODELS" --arg url "$OLLAMA_URL" --arg ckey "$OLLAMA_CLOUD_API_KEY" '{
|
|
provider: {
|
|
ollama: {npm:"@ai-sdk/openai-compatible", options:{baseURL:($url+"/v1")}, models:$local},
|
|
"ollama-cloud": {npm:"@ai-sdk/openai-compatible", options:{baseURL:"https://ollama.com/v1", apiKey:$ckey}, models:$cloud}
|
|
},
|
|
permission: $perm,
|
|
mcp: $mcp
|
|
}' > ~/.config/opencode/opencode.json
|
|
echo "opencode config (secrets masked):"; cat ~/.config/opencode/opencode.json
|