This commit is contained in:
@@ -107,6 +107,7 @@ jobs:
|
|||||||
TOKEN_LEAD: ${{ secrets.TOKEN_LEAD }}
|
TOKEN_LEAD: ${{ secrets.TOKEN_LEAD }}
|
||||||
TOKEN_QA: ${{ secrets.TOKEN_QA }}
|
TOKEN_QA: ${{ secrets.TOKEN_QA }}
|
||||||
TOKEN_OPS: ${{ secrets.TOKEN_OPS }}
|
TOKEN_OPS: ${{ secrets.TOKEN_OPS }}
|
||||||
|
TOKEN_INTERN: ${{ secrets.TOKEN_INTERN }}
|
||||||
run: bash "$SCRIPTS/route.sh"
|
run: bash "$SCRIPTS/route.sh"
|
||||||
|
|
||||||
- name: Install opencode + provider config (+ Playwright MCP for browser agents)
|
- name: Install opencode + provider config (+ Playwright MCP for browser agents)
|
||||||
@@ -176,7 +177,7 @@ jobs:
|
|||||||
# Powers the gitea-api / gitea-admin skills — each agent calls Gitea as itself. Every
|
# Powers the gitea-api / gitea-admin skills — each agent calls Gitea as itself. Every
|
||||||
# consuming repo now carries the per-agent TOKEN_* secrets (org-level for gitea/*, user-level
|
# consuming repo now carries the per-agent TOKEN_* secrets (org-level for gitea/*, user-level
|
||||||
# for ffaerber/*), so there is no shared-token fallback.
|
# for ffaerber/*), so there is no shared-token fallback.
|
||||||
SELF_TOKEN: ${{ steps.prep.outputs.name == 'pm' && secrets.TOKEN_PM || steps.prep.outputs.name == 'junior' && secrets.TOKEN_JUNIOR || steps.prep.outputs.name == 'senior' && secrets.TOKEN_SENIOR || steps.prep.outputs.name == 'lead' && secrets.TOKEN_LEAD || steps.prep.outputs.name == 'qa' && secrets.TOKEN_QA || steps.prep.outputs.name == 'ops' && secrets.TOKEN_OPS || '' }}
|
SELF_TOKEN: ${{ steps.prep.outputs.name == 'pm' && secrets.TOKEN_PM || steps.prep.outputs.name == 'junior' && secrets.TOKEN_JUNIOR || steps.prep.outputs.name == 'senior' && secrets.TOKEN_SENIOR || steps.prep.outputs.name == 'lead' && secrets.TOKEN_LEAD || steps.prep.outputs.name == 'qa' && secrets.TOKEN_QA || steps.prep.outputs.name == 'ops' && secrets.TOKEN_OPS || steps.prep.outputs.name == 'intern' && secrets.TOKEN_INTERN || '' }}
|
||||||
NAME: ${{ steps.prep.outputs.name }}
|
NAME: ${{ steps.prep.outputs.name }}
|
||||||
MODEL: ${{ steps.prep.outputs.model }}
|
MODEL: ${{ steps.prep.outputs.model }}
|
||||||
VISION: ${{ steps.prep.outputs.vision }}
|
VISION: ${{ steps.prep.outputs.vision }}
|
||||||
@@ -209,6 +210,7 @@ jobs:
|
|||||||
TOKEN_LEAD: ${{ secrets.TOKEN_LEAD }}
|
TOKEN_LEAD: ${{ secrets.TOKEN_LEAD }}
|
||||||
TOKEN_QA: ${{ secrets.TOKEN_QA }}
|
TOKEN_QA: ${{ secrets.TOKEN_QA }}
|
||||||
TOKEN_OPS: ${{ secrets.TOKEN_OPS }}
|
TOKEN_OPS: ${{ secrets.TOKEN_OPS }}
|
||||||
|
TOKEN_INTERN: ${{ secrets.TOKEN_INTERN }}
|
||||||
NAME: ${{ steps.prep.outputs.name }}
|
NAME: ${{ steps.prep.outputs.name }}
|
||||||
MODE: ${{ steps.prep.outputs.mode }}
|
MODE: ${{ steps.prep.outputs.mode }}
|
||||||
NUM: ${{ github.event.issue.number }}
|
NUM: ${{ github.event.issue.number }}
|
||||||
@@ -235,6 +237,7 @@ jobs:
|
|||||||
TOKEN_LEAD: ${{ secrets.TOKEN_LEAD }}
|
TOKEN_LEAD: ${{ secrets.TOKEN_LEAD }}
|
||||||
TOKEN_QA: ${{ secrets.TOKEN_QA }}
|
TOKEN_QA: ${{ secrets.TOKEN_QA }}
|
||||||
TOKEN_OPS: ${{ secrets.TOKEN_OPS }}
|
TOKEN_OPS: ${{ secrets.TOKEN_OPS }}
|
||||||
|
TOKEN_INTERN: ${{ secrets.TOKEN_INTERN }}
|
||||||
NAME: ${{ steps.prep.outputs.name }}
|
NAME: ${{ steps.prep.outputs.name }}
|
||||||
MODE: ${{ steps.prep.outputs.mode }}
|
MODE: ${{ steps.prep.outputs.mode }}
|
||||||
NUM: ${{ github.event.issue.number }}
|
NUM: ${{ github.event.issue.number }}
|
||||||
|
|||||||
@@ -50,5 +50,12 @@
|
|||||||
"gitea-admin"
|
"gitea-admin"
|
||||||
],
|
],
|
||||||
"desc": "Gitea operator — administers the Gitea instance itself: create orgs/users/repos, manage labels and secrets, mint scoped per-user tokens, bootstrap new repos with the agent caller. Comments only; never edits code. ALWAYS confirms before any destructive action (delete user/repo/org)."
|
"desc": "Gitea operator — administers the Gitea instance itself: create orgs/users/repos, manage labels and secrets, mint scoped per-user tokens, bootstrap new repos with the agent caller. Comments only; never edits code. ALWAYS confirms before any destructive action (delete user/repo/org)."
|
||||||
|
},
|
||||||
|
"intern": {
|
||||||
|
"model": "ollama/ornith:35b",
|
||||||
|
"vision": false,
|
||||||
|
"mode": "pr",
|
||||||
|
"skills": [],
|
||||||
|
"desc": "Intern — very basic tasks only, routed to the local Ollama model (ornith:35b). Text-only, cannot read images. Escalates anything non-trivial to @junior, @senior or @lead."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,15 +32,17 @@ SKILLS="${SKILLS:-[]}"
|
|||||||
PERM=$(jq -nc --argjson s "$SKILLS" '
|
PERM=$(jq -nc --argjson s "$SKILLS" '
|
||||||
{skill: ( {"*":"deny"} + (reduce $s[] as $k ({}; . + {($k):"allow"})) )}')
|
{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).
|
# Two ollama providers: local self-hosted (ornith) + Ollama Cloud (gemma4/kimi-k2.7-code/glm-5.2/minimax-m3).
|
||||||
# The ollama-cloud `models:` map is DERIVED from agents.json (the single source of truth, shared with
|
# 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. Only the
|
# route.sh) so every model an agent is routed to is always declared in the provider config.
|
||||||
# `ollama-cloud/` provider prefix models participate — e.g. `anthropic/claude-opus-4-8` (@lead) is a
|
# `ollama-cloud/` prefix models go to the cloud provider; `ollama/` prefix models go to the local
|
||||||
# built-in provider and `ornith:35b` is local-only, neither belongs here. See issue #31.
|
# 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"
|
AGENTS_JSON="${SCRIPTS:-$(dirname -- "$0")}/agents.json"
|
||||||
CLOUD_MODELS=$(jq -r '[.[] | .model | select(startswith("ollama-cloud/")) | sub("^ollama-cloud/";"")] | map({(.):{}}) | add // {}' "$AGENTS_JSON")
|
CLOUD_MODELS=$(jq -r '[.[] | .model | select(startswith("ollama-cloud/")) | sub("^ollama-cloud/";"")] | map({(.):{}}) | add // {}' "$AGENTS_JSON")
|
||||||
jq -n --argjson mcp "$MCP" --argjson perm "$PERM" --argjson cloud "$CLOUD_MODELS" --arg url "$OLLAMA_URL" --arg ckey "$OLLAMA_CLOUD_API_KEY" '{
|
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: {
|
provider: {
|
||||||
ollama: {npm:"@ai-sdk/openai-compatible", options:{baseURL:($url+"/v1")}, models:{"ornith:35b":{}}},
|
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}
|
"ollama-cloud": {npm:"@ai-sdk/openai-compatible", options:{baseURL:"https://ollama.com/v1", apiKey:$ckey}, models:$cloud}
|
||||||
},
|
},
|
||||||
permission: $perm,
|
permission: $perm,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ set +e # publish is best-effort: a grep-no-match / curl non-zero must NOT kill
|
|||||||
# Post/PR as the agent's OWN Gitea user when its token is configured; else the built-in bot.
|
# Post/PR as the agent's OWN Gitea user when its token is configured; else the built-in bot.
|
||||||
case "$NAME" in
|
case "$NAME" in
|
||||||
pm) TOK="$TOKEN_PM";; senior) TOK="$TOKEN_SENIOR";; junior) TOK="$TOKEN_JUNIOR";;
|
pm) TOK="$TOKEN_PM";; senior) TOK="$TOKEN_SENIOR";; junior) TOK="$TOKEN_JUNIOR";;
|
||||||
lead) TOK="$TOKEN_LEAD";; qa) TOK="$TOKEN_QA";; ops) TOK="$TOKEN_OPS";; *) TOK="";;
|
lead) TOK="$TOKEN_LEAD";; qa) TOK="$TOKEN_QA";; ops) TOK="$TOKEN_OPS";; intern) TOK="$TOKEN_INTERN";; *) TOK="";;
|
||||||
esac
|
esac
|
||||||
[ -z "$TOK" ] && TOK="$GT"
|
[ -z "$TOK" ] && TOK="$GT"
|
||||||
# Trigger token: comments that must FIRE the next workflow (delegation, autopilot) and PR merges
|
# Trigger token: comments that must FIRE the next workflow (delegation, autopilot) and PR merges
|
||||||
@@ -108,8 +108,8 @@ if [ "$MODE" != "pr" ]; then
|
|||||||
if grep -qiE '^[[:space:]]*APPROVE[[:space:]]*$' /tmp/agent_out.md; then
|
if grep -qiE '^[[:space:]]*APPROVE[[:space:]]*$' /tmp/agent_out.md; then
|
||||||
post_to "$ISSN" "$(printf '✅ Reviewed PR #%s — looks good.\n\n%s%s' "${PRN:-?}" "$reply" "$activity")"
|
post_to "$ISSN" "$(printf '✅ Reviewed PR #%s — looks good.\n\n%s%s' "${PRN:-?}" "$reply" "$activity")"
|
||||||
trig "$ISSN" "@pm — I have reviewed and approved PR #${PRN:-?} (issue #$ISSN). Over to you."
|
trig "$ISSN" "@pm — I have reviewed and approved PR #${PRN:-?} (issue #$ISSN). Over to you."
|
||||||
elif grep -qiE '^[[:space:]]*BOUNCE:[[:space:]]*@(junior|senior|lead)' /tmp/agent_out.md; then
|
elif grep -qiE '^[[:space:]]*BOUNCE:[[:space:]]*@(junior|senior|lead|intern)' /tmp/agent_out.md; then
|
||||||
dev=$(grep -oiE 'BOUNCE:[[:space:]]*@(junior|senior|lead)' /tmp/agent_out.md | head -1 | grep -oiE '(junior|senior|lead)' | tr '[:upper:]' '[:lower:]')
|
dev=$(grep -oiE 'BOUNCE:[[:space:]]*@(junior|senior|lead|intern)' /tmp/agent_out.md | head -1 | grep -oiE '(junior|senior|lead|intern)' | tr '[:upper:]' '[:lower:]')
|
||||||
[ -z "$dev" ] && [ -n "$PRN" ] && dev=$(curl -sS "${hdr[@]}" "$API/pulls/$PRN" | jq -r '.user.login // "junior"')
|
[ -z "$dev" ] && [ -n "$PRN" ] && dev=$(curl -sS "${hdr[@]}" "$API/pulls/$PRN" | jq -r '.user.login // "junior"')
|
||||||
dest="${PRN:-$NUM}"
|
dest="${PRN:-$NUM}"
|
||||||
post_to "$dest" "$reply$activity" # recommendations, on the PR
|
post_to "$dest" "$reply$activity" # recommendations, on the PR
|
||||||
@@ -121,6 +121,7 @@ if [ "$MODE" != "pr" ]; then
|
|||||||
else
|
else
|
||||||
n=$((prior + 1))
|
n=$((prior + 1))
|
||||||
trig "$dest" "@${dev:-junior} please address my review above and update PR #${PRN:-?} (fix attempt $n/3)."
|
trig "$dest" "@${dev:-junior} please address my review above and update PR #${PRN:-?} (fix attempt $n/3)."
|
||||||
|
|
||||||
fi
|
fi
|
||||||
elif grep -qiE '^[[:space:]]*HALT([_ ]AUTOPILOT)?[[:space:]]*$' /tmp/agent_out.md; then
|
elif grep -qiE '^[[:space:]]*HALT([_ ]AUTOPILOT)?[[:space:]]*$' /tmp/agent_out.md; then
|
||||||
[ "$AUTOPILOT" = "true" ] && del_autopilot_label "$ISSN"
|
[ "$AUTOPILOT" = "true" ] && del_autopilot_label "$ISSN"
|
||||||
@@ -132,7 +133,7 @@ if [ "$MODE" != "pr" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# ---------- @pm / @ops: issue-thread orchestration ----------
|
# ---------- @pm / @ops: issue-thread orchestration ----------
|
||||||
target=$(grep -oiE 'DELEGATE:[[:space:]]*@(junior|senior|lead|qa)' /tmp/agent_out.md 2>/dev/null | head -1 | grep -oiE '(junior|senior|lead|qa)' | tr '[:upper:]' '[:lower:]')
|
target=$(grep -oiE 'DELEGATE:[[:space:]]*@(junior|senior|lead|qa|intern)' /tmp/agent_out.md 2>/dev/null | head -1 | grep -oiE '(junior|senior|lead|qa|intern)' | tr '[:upper:]' '[:lower:]')
|
||||||
# Visible comment: the reply text, or a sensible line if the agent only emitted a marker.
|
# Visible comment: the reply text, or a sensible line if the agent only emitted a marker.
|
||||||
msg="$reply"
|
msg="$reply"
|
||||||
case "$msg" in ""|"_(Made changes"*) msg=$([ -n "$target" ] && echo "Handing off to @$target." || echo "_(no further comment)_") ;; esac
|
case "$msg" in ""|"_(Made changes"*) msg=$([ -n "$target" ] && echo "Handing off to @$target." || echo "_(no further comment)_") ;; esac
|
||||||
@@ -297,6 +298,6 @@ else
|
|||||||
# on the PR thread. The qa↔dev loop is direct — it does NOT go back through @pm each round.
|
# on the PR thread. The qa↔dev loop is direct — it does NOT go back through @pm each round.
|
||||||
prpost "$prnum" "$(printf 'Pushed an update to PR #%s.%s' "$prnum" "$activity")"
|
prpost "$prnum" "$(printf 'Pushed an update to PR #%s.%s' "$prnum" "$activity")"
|
||||||
case "$NAME" in
|
case "$NAME" in
|
||||||
junior|senior|lead) trig "$prnum" "@qa please re-verify PR #$prnum — I have pushed an update." ;;
|
junior|senior|lead|intern) trig "$prnum" "@qa please re-verify PR #$prnum — I have pushed an update." ;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ set +e
|
|||||||
# Post/PR as the agent's OWN Gitea user when its token is configured; else the built-in bot.
|
# Post/PR as the agent's OWN Gitea user when its token is configured; else the built-in bot.
|
||||||
case "$NAME" in
|
case "$NAME" in
|
||||||
pm) TOK="$TOKEN_PM";; senior) TOK="$TOKEN_SENIOR";; junior) TOK="$TOKEN_JUNIOR";;
|
pm) TOK="$TOKEN_PM";; senior) TOK="$TOKEN_SENIOR";; junior) TOK="$TOKEN_JUNIOR";;
|
||||||
lead) TOK="$TOKEN_LEAD";; qa) TOK="$TOKEN_QA";; ops) TOK="$TOKEN_OPS";; *) TOK="";;
|
lead) TOK="$TOKEN_LEAD";; qa) TOK="$TOKEN_QA";; ops) TOK="$TOKEN_OPS";; intern) TOK="$TOKEN_INTERN";; *) TOK="";;
|
||||||
esac
|
esac
|
||||||
[ -z "$TOK" ] && TOK="$GT"
|
[ -z "$TOK" ] && TOK="$GT"
|
||||||
# Trigger token: the @pm hand-back below must FIRE a new run, which the built-in token cannot.
|
# Trigger token: the @pm hand-back below must FIRE a new run, which the built-in token cannot.
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ name=""
|
|||||||
# load-bearing for the flow's trigger comments: "@pm — @qa approved …" must route to @pm (pm is
|
# load-bearing for the flow's trigger comments: "@pm — @qa approved …" must route to @pm (pm is
|
||||||
# checked first), while "@junior please address @qa's review …" must route to the dev (devs are
|
# checked first), while "@junior please address @qa's review …" must route to the dev (devs are
|
||||||
# checked before qa). If you add an agent or reword a trigger in publish.sh, re-check this order.
|
# checked before qa). If you add an agent or reword a trigger in publish.sh, re-check this order.
|
||||||
for a in pm junior senior lead qa ops; do
|
for a in pm junior senior lead qa ops intern; do
|
||||||
case "$scan" in *"@$a"*) name=$a; break;; esac
|
case "$scan" in *"@$a"*) name=$a; break;; esac
|
||||||
done
|
done
|
||||||
if [ -z "$name" ]; then
|
if [ -z "$name" ]; then
|
||||||
@@ -48,7 +48,7 @@ echo "Routing to @$name (model=$model vision=$vision mode=$mode skills=$skills)"
|
|||||||
# Act as the agent's own Gitea user when its token is set; else the built-in bot.
|
# Act as the agent's own Gitea user when its token is set; else the built-in bot.
|
||||||
case "$name" in
|
case "$name" in
|
||||||
pm) TOK="$TOKEN_PM";; senior) TOK="$TOKEN_SENIOR";; junior) TOK="$TOKEN_JUNIOR";;
|
pm) TOK="$TOKEN_PM";; senior) TOK="$TOKEN_SENIOR";; junior) TOK="$TOKEN_JUNIOR";;
|
||||||
lead) TOK="$TOKEN_LEAD";; qa) TOK="$TOKEN_QA";; ops) TOK="$TOKEN_OPS";; *) TOK="";;
|
lead) TOK="$TOKEN_LEAD";; qa) TOK="$TOKEN_QA";; ops) TOK="$TOKEN_OPS";; intern) TOK="$TOKEN_INTERN";; *) TOK="";;
|
||||||
esac
|
esac
|
||||||
[ -z "$TOK" ] && TOK="$GT"
|
[ -z "$TOK" ] && TOK="$GT"
|
||||||
git config user.name "$name"
|
git config user.name "$name"
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ if [ "$MODE" = "comment" ]; then
|
|||||||
ACTION="You do NOT edit files, create branches, or write a PR description. Respond with your analysis,
|
ACTION="You do NOT edit files, create branches, or write a PR description. Respond with your analysis,
|
||||||
plan, research, or clarifying questions — your reply becomes a comment on the issue.
|
plan, research, or clarifying questions — your reply becomes a comment on the issue.
|
||||||
To hand work to a teammate, end your reply with EXACTLY one line: 'DELEGATE: @<agent>' (one of
|
To hand work to a teammate, end your reply with EXACTLY one line: 'DELEGATE: @<agent>' (one of
|
||||||
@junior @senior @lead @qa) — but ONLY when you are ready to hand off AND need nothing further from the
|
@junior @senior @lead @qa @intern) — but ONLY when you are ready to hand off AND need nothing further from the
|
||||||
maintainer. If you are asking @ffaerber to confirm or decide ANYTHING, do NOT include a DELEGATE line;
|
maintainer. If you are asking @ffaerber to confirm or decide ANYTHING, do NOT include a DELEGATE line;
|
||||||
just ask and wait. Never ask for confirmation and delegate in the same reply. Mentioning a teammate in
|
just ask and wait. Never ask for confirmation and delegate in the same reply. Mentioning a teammate in
|
||||||
prose does NOT delegate — only the DELEGATE line does.
|
prose does NOT delegate — only the DELEGATE line does.
|
||||||
@@ -86,7 +86,7 @@ if [ "$MODE" = "comment" ]; then
|
|||||||
issue and hands back to @pm (who tells the creator, or in autopilot merges). You do NOT merge.
|
issue and hands back to @pm (who tells the creator, or in autopilot merges). You do NOT merge.
|
||||||
- 'BOUNCE: @<dev>' — something needs changing. FIRST spell out, specifically and actionably, exactly
|
- 'BOUNCE: @<dev>' — something needs changing. FIRST spell out, specifically and actionably, exactly
|
||||||
what to change (file, label, value, hostname, …), THEN end with the BOUNCE line naming who fixes
|
what to change (file, label, value, hostname, …), THEN end with the BOUNCE line naming who fixes
|
||||||
it (@junior / @senior / @lead — usually whoever built it). The automation sends the PR back and
|
it (@junior / @senior / @lead / @intern — usually whoever built it). The automation sends the PR back and
|
||||||
re-verifies with you. After 3 rounds it stops and hands to @ffaerber — so list ALL problems at
|
re-verifies with you. After 3 rounds it stops and hands to @ffaerber — so list ALL problems at
|
||||||
once, not one at a time.
|
once, not one at a time.
|
||||||
- 'HALT' — the problem is NOT something a dev can fix (the request is ambiguous / needs a human
|
- 'HALT' — the problem is NOT something a dev can fix (the request is ambiguous / needs a human
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ Shared **AI dev-team** workflow for Gitea Actions, reusable across repos. It giv
|
|||||||
| `@lead` | `anthropic/claude-opus-4-8` | yes | pr | `gitea-api` | Tech lead — the hardest problems, architecture, and final calls. |
|
| `@lead` | `anthropic/claude-opus-4-8` | yes | pr | `gitea-api` | Tech lead — the hardest problems, architecture, and final calls. |
|
||||||
| `@qa` | `ollama-cloud/minimax-m3:cloud` | yes | comment | `gitea-api` | QA / reviewer — reads the PR diff, drives a headless browser (Playwright) to verify behavior; recommendations on the PR, pass/fail verdict on the issue. Never edits code, never merges. |
|
| `@qa` | `ollama-cloud/minimax-m3:cloud` | yes | comment | `gitea-api` | QA / reviewer — reads the PR diff, drives a headless browser (Playwright) to verify behavior; recommendations on the PR, pass/fail verdict on the issue. Never edits code, never merges. |
|
||||||
| `@ops` | `anthropic/claude-opus-4-8` | no | comment | `gitea-admin` | Gitea operator — administers the instance itself (create orgs/users/repos, labels, secrets, scoped per-user tokens, bootstrap repos). Comments only; never edits code. Confirms before destructive actions. |
|
| `@ops` | `anthropic/claude-opus-4-8` | no | comment | `gitea-admin` | Gitea operator — administers the instance itself (create orgs/users/repos, labels, secrets, scoped per-user tokens, bootstrap repos). Comments only; never edits code. Confirms before destructive actions. |
|
||||||
|
| `@intern` | `ollama/ornith:35b` | no | pr | — | Intern — very basic tasks only, routed to the local Ollama model (`ornith:35b`). Text-only, cannot read images. Escalates anything non-trivial to `@junior`, `@senior` or `@lead`. |
|
||||||
|
|
||||||
The registry `.gitea/workflows/scripts/agents.json` is the source of truth for this mapping — if you
|
The registry `.gitea/workflows/scripts/agents.json` is the source of truth for this mapping — if you
|
||||||
change a model or an agent's skills there, update this table too. (Repo-specific skills, e.g. a
|
change a model or an agent's skills there, update this table too. (Repo-specific skills, e.g. a
|
||||||
|
|||||||
Reference in New Issue
Block a user