@intern: add intern agent using local ornith:35b model (issue #53)
This commit is contained in:
@@ -14,11 +14,12 @@ jobs:
|
|||||||
(github.event.comment == null && github.event.issue.user.login == 'ffaerber') ||
|
(github.event.comment == null && github.event.issue.user.login == 'ffaerber') ||
|
||||||
(github.event.comment != null && github.event.comment.user.login == 'ffaerber' &&
|
(github.event.comment != null && github.event.comment.user.login == 'ffaerber' &&
|
||||||
!contains(github.event.comment.body, '🤖') &&
|
!contains(github.event.comment.body, '🤖') &&
|
||||||
(contains(github.event.comment.body, '@pm') ||
|
(contains(github.event.comment.body, '@pm') ||
|
||||||
contains(github.event.comment.body, '@junior') ||
|
contains(github.event.comment.body, '@intern') ||
|
||||||
contains(github.event.comment.body, '@senior') ||
|
contains(github.event.comment.body, '@junior') ||
|
||||||
contains(github.event.comment.body, '@lead') ||
|
contains(github.event.comment.body, '@senior') ||
|
||||||
contains(github.event.comment.body, '@qa')))
|
contains(github.event.comment.body, '@lead') ||
|
||||||
|
contains(github.event.comment.body, '@qa')))
|
||||||
runs-on: ci-runner
|
runs-on: ci-runner
|
||||||
steps:
|
steps:
|
||||||
- name: Acknowledge with 👀
|
- name: Acknowledge with 👀
|
||||||
@@ -88,6 +89,7 @@ jobs:
|
|||||||
NUM: ${{ github.event.issue.number }}
|
NUM: ${{ github.event.issue.number }}
|
||||||
GT: ${{ secrets.GITEA_TOKEN }}
|
GT: ${{ secrets.GITEA_TOKEN }}
|
||||||
TOKEN_PM: ${{ secrets.TOKEN_PM }}
|
TOKEN_PM: ${{ secrets.TOKEN_PM }}
|
||||||
|
TOKEN_INTERN: ${{ secrets.TOKEN_INTERN }}
|
||||||
TOKEN_SENIOR: ${{ secrets.TOKEN_SENIOR }}
|
TOKEN_SENIOR: ${{ secrets.TOKEN_SENIOR }}
|
||||||
TOKEN_JUNIOR: ${{ secrets.TOKEN_JUNIOR }}
|
TOKEN_JUNIOR: ${{ secrets.TOKEN_JUNIOR }}
|
||||||
TOKEN_LEAD: ${{ secrets.TOKEN_LEAD }}
|
TOKEN_LEAD: ${{ secrets.TOKEN_LEAD }}
|
||||||
@@ -183,6 +185,7 @@ jobs:
|
|||||||
GT: ${{ secrets.GITEA_TOKEN }}
|
GT: ${{ secrets.GITEA_TOKEN }}
|
||||||
AGENT_TOKEN: ${{ secrets.AGENT_TOKEN }}
|
AGENT_TOKEN: ${{ secrets.AGENT_TOKEN }}
|
||||||
TOKEN_PM: ${{ secrets.TOKEN_PM }}
|
TOKEN_PM: ${{ secrets.TOKEN_PM }}
|
||||||
|
TOKEN_INTERN: ${{ secrets.TOKEN_INTERN }}
|
||||||
TOKEN_SENIOR: ${{ secrets.TOKEN_SENIOR }}
|
TOKEN_SENIOR: ${{ secrets.TOKEN_SENIOR }}
|
||||||
TOKEN_JUNIOR: ${{ secrets.TOKEN_JUNIOR }}
|
TOKEN_JUNIOR: ${{ secrets.TOKEN_JUNIOR }}
|
||||||
TOKEN_LEAD: ${{ secrets.TOKEN_LEAD }}
|
TOKEN_LEAD: ${{ secrets.TOKEN_LEAD }}
|
||||||
@@ -208,6 +211,7 @@ jobs:
|
|||||||
SCRIPTS: ${{ runner.temp }}/agents-scripts
|
SCRIPTS: ${{ runner.temp }}/agents-scripts
|
||||||
GT: ${{ secrets.GITEA_TOKEN }}
|
GT: ${{ secrets.GITEA_TOKEN }}
|
||||||
TOKEN_PM: ${{ secrets.TOKEN_PM }}
|
TOKEN_PM: ${{ secrets.TOKEN_PM }}
|
||||||
|
TOKEN_INTERN: ${{ secrets.TOKEN_INTERN }}
|
||||||
TOKEN_SENIOR: ${{ secrets.TOKEN_SENIOR }}
|
TOKEN_SENIOR: ${{ secrets.TOKEN_SENIOR }}
|
||||||
TOKEN_JUNIOR: ${{ secrets.TOKEN_JUNIOR }}
|
TOKEN_JUNIOR: ${{ secrets.TOKEN_JUNIOR }}
|
||||||
TOKEN_LEAD: ${{ secrets.TOKEN_LEAD }}
|
TOKEN_LEAD: ${{ secrets.TOKEN_LEAD }}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"pm": {"model":"ollama-cloud/gemma4:cloud","vision":true, "mode":"comment","skills":["gitea-api"],"desc":"Product manager — research, plan, ask clarifying questions, and decide which dev should do the work. Comments only; never edits files."},
|
"pm": {"model":"ollama-cloud/gemma4:cloud","vision":true, "mode":"comment","skills":["gitea-api"],"desc":"Product manager — research, plan, ask clarifying questions, and decide which dev should do the work. Comments only; never edits files."},
|
||||||
"junior": {"model":"ollama-cloud/kimi-k2.7-code:cloud","vision":false,"mode":"pr", "skills":[],"desc":"Junior dev — small, low-risk changes (mostly YAML/compose/config). Text-only, cannot read images. Defers complex or image tasks to @senior or @lead."},
|
"intern": {"model":"ornith:35b","vision":false,"mode":"pr", "skills":[],"desc":"Intern — very basic tasks only. Uses the local self-hosted Ollama model (ornith:35b). Text-only; cannot read images. Escalates anything non-trivial to @junior, @senior, or @lead."},
|
||||||
|
"junior": {"model":"ollama-cloud/kimi-k2.7-code:cloud","vision":false,"mode":"pr", "skills":[],"desc":"Junior dev — small, low-risk changes (mostly YAML/compose/config). Text-only; cannot read images. Defers complex or image tasks to @senior or @lead."},
|
||||||
"senior": {"model":"ollama-cloud/glm-5.2:cloud","vision":false,"mode":"pr", "skills":["gitea-api","node1-ssh"],"desc":"Senior dev — complex, multi-file implementation (GLM-5.2 via Ollama Cloud, text-only)."},
|
"senior": {"model":"ollama-cloud/glm-5.2:cloud","vision":false,"mode":"pr", "skills":["gitea-api","node1-ssh"],"desc":"Senior dev — complex, multi-file implementation (GLM-5.2 via Ollama Cloud, text-only)."},
|
||||||
"lead": {"model":"anthropic/claude-opus-4-8","vision":true, "mode":"pr", "skills":["gitea-api","node1-ssh"],"desc":"Tech lead — the hardest problems, architecture, and final calls."},
|
"lead": {"model":"anthropic/claude-opus-4-8","vision":true, "mode":"pr", "skills":["gitea-api","node1-ssh"],"desc":"Tech lead — the hardest problems, architecture, and final calls."},
|
||||||
"qa": {"model":"ollama-cloud/minimax-m3:cloud","vision":true, "mode":"comment","skills":["gitea-api"],"desc":"QA — verifies things work. Drives a headless browser (Playwright) to open a URL/web app, click through it, screenshot, and report bugs or confirm behavior. Comments findings; opens no PRs."}
|
"qa": {"model":"ollama-cloud/minimax-m3:cloud","vision":true, "mode":"comment","skills":["gitea-api"],"desc":"QA — verifies things work. Drives a headless browser (Playwright) to open a URL/web app, click through it, screenshot, and report bugs or confirm behavior. Comments findings; opens no PRs."}
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
# Publish — PR (dev agents) or comment (pm/qa), always reply in the issue.
|
# Publish — PR (dev agents) or comment (pm/qa), always reply in the issue.
|
||||||
#
|
#
|
||||||
# Required env (provided by the workflow step):
|
# Required env (provided by the workflow step):
|
||||||
# GT AGENT_TOKEN TOKEN_PM TOKEN_SENIOR TOKEN_JUNIOR TOKEN_LEAD TOKEN_QA
|
# GT AGENT_TOKEN TOKEN_PM TOKEN_INTERN TOKEN_SENIOR TOKEN_JUNIOR TOKEN_LEAD TOKEN_QA
|
||||||
# NAME MODE NUM TITLE BRANCH NEW GITHUB_SERVER_URL GITHUB_REPOSITORY
|
# NAME MODE NUM TITLE BRANCH NEW GITHUB_SERVER_URL GITHUB_REPOSITORY
|
||||||
# IS_PR AUTOPILOT ISSNUM (autopilot: @qa label-gated merge/halt + auto-trigger @qa on a fresh PR)
|
# IS_PR AUTOPILOT ISSNUM (autopilot: @qa label-gated merge/halt + auto-trigger @qa on a fresh PR)
|
||||||
set +e # publish is best-effort: a grep-no-match / curl non-zero must NOT kill the step
|
set +e # publish is best-effort: a grep-no-match / curl non-zero must NOT kill the step
|
||||||
# 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";; intern) TOK="$TOKEN_INTERN";; senior) TOK="$TOKEN_SENIOR";; junior) TOK="$TOKEN_JUNIOR";;
|
||||||
lead) TOK="$TOKEN_LEAD";; qa) TOK="$TOKEN_QA";; *) TOK="";;
|
lead) TOK="$TOKEN_LEAD";; qa) TOK="$TOKEN_QA";; *) TOK="";;
|
||||||
esac
|
esac
|
||||||
[ -z "$TOK" ] && TOK="$GT"
|
[ -z "$TOK" ] && TOK="$GT"
|
||||||
@@ -64,7 +64,7 @@ prdesc=$(awk '/BEGIN_PR_DESCRIPTION/{f=1;next} /END_PR_DESCRIPTION/{f=0} f' /tmp
|
|||||||
if [ "$MODE" != "pr" ]; then
|
if [ "$MODE" != "pr" ]; then
|
||||||
git checkout -- . 2>/dev/null || true
|
git checkout -- . 2>/dev/null || true
|
||||||
git clean -fd 2>/dev/null || true
|
git clean -fd 2>/dev/null || true
|
||||||
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:]]*@(intern|junior|senior|lead|qa)' /tmp/agent_out.md 2>/dev/null | head -1 | grep -oiE '(intern|junior|senior|lead|qa)' | 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
|
||||||
@@ -184,8 +184,8 @@ if [ "$MODE" != "pr" ]; then
|
|||||||
if [ -n "$AGENT_TOKEN" ]; then
|
if [ -n "$AGENT_TOKEN" ]; then
|
||||||
# Only delegate on an explicit "DELEGATE: @<agent>" line — never on a prose mention,
|
# Only delegate on an explicit "DELEGATE: @<agent>" line — never on a prose mention,
|
||||||
# so an agent that is asking the maintainer a question does not hand off prematurely.
|
# so an agent that is asking the maintainer a question does not hand off prematurely.
|
||||||
target=$(grep -oiE 'DELEGATE:[[:space:]]*@(junior|senior|lead|qa)' /tmp/agent_out.md 2>/dev/null \
|
target=$(grep -oiE 'DELEGATE:[[:space:]]*@(intern|junior|senior|lead|qa)' /tmp/agent_out.md 2>/dev/null \
|
||||||
| head -1 | grep -oiE '(junior|senior|lead|qa)' | tr '[:upper:]' '[:lower:]')
|
| head -1 | grep -oiE '(intern|junior|senior|lead|qa)' | tr '[:upper:]' '[:lower:]')
|
||||||
if [ -n "$target" ] && [ "$target" != "$NAME" ]; then
|
if [ -n "$target" ] && [ "$target" != "$NAME" ]; then
|
||||||
echo "auto-delegating to @$target"
|
echo "auto-delegating to @$target"
|
||||||
curl -sS -X POST -H "Authorization: token $AGENT_TOKEN" -H "Content-Type: application/json" \
|
curl -sS -X POST -H "Authorization: token $AGENT_TOKEN" -H "Content-Type: application/json" \
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
# the run. Comment-only roles (pm/qa) push nothing, so they are skipped.
|
# the run. Comment-only roles (pm/qa) push nothing, so they are skipped.
|
||||||
#
|
#
|
||||||
# Required env (provided by the workflow step):
|
# Required env (provided by the workflow step):
|
||||||
# GT TOKEN_PM TOKEN_SENIOR TOKEN_JUNIOR TOKEN_LEAD TOKEN_QA
|
# GT TOKEN_PM TOKEN_INTERN TOKEN_SENIOR TOKEN_JUNIOR TOKEN_LEAD TOKEN_QA
|
||||||
# NAME MODE NUM TITLE BRANCH GITHUB_SERVER_URL GITHUB_REPOSITORY
|
# NAME MODE NUM TITLE BRANCH GITHUB_SERVER_URL GITHUB_REPOSITORY
|
||||||
set +e
|
set +e
|
||||||
|
|
||||||
@@ -16,7 +16,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";; intern) TOK="$TOKEN_INTERN";; senior) TOK="$TOKEN_SENIOR";; junior) TOK="$TOKEN_JUNIOR";;
|
||||||
lead) TOK="$TOKEN_LEAD";; qa) TOK="$TOKEN_QA";; *) TOK="";;
|
lead) TOK="$TOKEN_LEAD";; qa) TOK="$TOKEN_QA";; *) TOK="";;
|
||||||
esac
|
esac
|
||||||
[ -z "$TOK" ] && TOK="$GT"
|
[ -z "$TOK" ] && TOK="$GT"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
# to $GITHUB_OUTPUT, configures git identity, and prepares/publishes the working branch.
|
# to $GITHUB_OUTPUT, configures git identity, and prepares/publishes the working branch.
|
||||||
#
|
#
|
||||||
# Required env (all provided by the workflow step): BODY IBODY CID IS_PR NUM GT
|
# Required env (all provided by the workflow step): BODY IBODY CID IS_PR NUM GT
|
||||||
# TOKEN_PM TOKEN_SENIOR TOKEN_JUNIOR TOKEN_LEAD TOKEN_QA
|
# TOKEN_PM TOKEN_INTERN TOKEN_SENIOR TOKEN_JUNIOR TOKEN_LEAD TOKEN_QA
|
||||||
# GITHUB_SERVER_URL GITHUB_REPOSITORY GITHUB_OUTPUT
|
# GITHUB_SERVER_URL GITHUB_REPOSITORY GITHUB_OUTPUT
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ cp "$AGENTS_JSON" /tmp/agents.json
|
|||||||
# here — see agent.yml: this reusable workflow sees it as 'workflow_call'.)
|
# here — see agent.yml: this reusable workflow sees it as 'workflow_call'.)
|
||||||
if [ -n "$CID" ]; then scan="$BODY"; else scan="$IBODY"; fi
|
if [ -n "$CID" ]; then scan="$BODY"; else scan="$IBODY"; fi
|
||||||
name=""
|
name=""
|
||||||
for a in pm junior senior lead qa; do
|
for a in pm intern junior senior lead qa; 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
|
||||||
@@ -43,7 +43,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";; intern) TOK="$TOKEN_INTERN";; senior) TOK="$TOKEN_SENIOR";; junior) TOK="$TOKEN_JUNIOR";;
|
||||||
lead) TOK="$TOKEN_LEAD";; qa) TOK="$TOKEN_QA";; *) TOK="";;
|
lead) TOK="$TOKEN_LEAD";; qa) TOK="$TOKEN_QA";; *) TOK="";;
|
||||||
esac
|
esac
|
||||||
[ -z "$TOK" ] && TOK="$GT"
|
[ -z "$TOK" ] && TOK="$GT"
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
# agents
|
# agents
|
||||||
|
|
||||||
Shared **AI dev-team** workflow for Gitea Actions, reusable across repos. It gives any repo the
|
Shared **AI dev-team** workflow for Gitea Actions, reusable across repos. It gives any repo the
|
||||||
`@pm` / `@junior` / `@senior` / `@lead` / `@qa` agents driven from issues and comments.
|
`@pm` / `@intern` / `@junior` / `@senior` / `@lead` / `@qa` agents driven from issues and comments.
|
||||||
|
|
||||||
## Agents
|
## Agents
|
||||||
|
|
||||||
| Agent | Model | Vision | Mode | Skills | Role |
|
| Agent | Model | Vision | Mode | Skills | Role |
|
||||||
|-------|-------|:------:|------|--------|------|
|
|-------|-------|:------:|------|--------|------|
|
||||||
| `@pm` | `ollama-cloud/gemma4:cloud` | yes | comment | `gitea-api` | Product manager — research, plan, ask clarifying questions, and decide which dev should do the work. Comments only; never edits files. |
|
| `@pm` | `ollama-cloud/gemma4:cloud` | yes | comment | `gitea-api` | Product manager — research, plan, ask clarifying questions, and decide which dev should do the work. Comments only; never edits files. |
|
||||||
| `@junior` | `ollama-cloud/kimi-k2.7-code:cloud` | no | pr | — | Junior dev — small, low-risk changes (mostly YAML/compose/config). Text-only, cannot read images. Defers complex or image tasks to `@senior` or `@lead`. |
|
| `@intern` | `ornith:35b` | no | pr | — | Intern — very basic tasks only. Uses the local self-hosted Ollama model (`ornith:35b`). Text-only; cannot read images. Escalates anything non-trivial to `@junior`, `@senior`, or `@lead`. |
|
||||||
|
| `@junior` | `ollama-cloud/kimi-k2.7-code:cloud` | no | pr | — | Junior dev — small, low-risk changes (mostly YAML/compose/config). Text-only; cannot read images. Defers complex or image tasks to `@senior` or `@lead`. |
|
||||||
| `@senior` | `ollama-cloud/glm-5.2:cloud` | no | pr | `gitea-api`, `node1-ssh` | Senior dev — complex, multi-file implementation (GLM-5.2 via Ollama Cloud, text-only). |
|
| `@senior` | `ollama-cloud/glm-5.2:cloud` | no | pr | `gitea-api`, `node1-ssh` | Senior dev — complex, multi-file implementation (GLM-5.2 via Ollama Cloud, text-only). |
|
||||||
| `@lead` | `anthropic/claude-opus-4-8` | yes | pr | `gitea-api`, `node1-ssh` | Tech lead — the hardest problems, architecture, and final calls. |
|
| `@lead` | `anthropic/claude-opus-4-8` | yes | pr | `gitea-api`, `node1-ssh` | Tech lead — the hardest problems, architecture, and final calls. |
|
||||||
| `@qa` | `ollama-cloud/minimax-m3:cloud` | yes | comment | `gitea-api` | QA — verifies things work. Drives a headless browser (Playwright) to open a URL/web app, click through it, screenshot, and report bugs or confirm behavior. Comments findings; opens no PRs. |
|
| `@qa` | `ollama-cloud/minimax-m3:cloud` | yes | comment | `gitea-api` | QA — verifies things work. Drives a headless browser (Playwright) to open a URL/web app, click through it, screenshot, and report bugs or confirm behavior. Comments findings; opens no PRs. |
|
||||||
@@ -76,7 +77,7 @@ points `$SCRIPTS` at it. Keep the workflow and its scripts moving together on `m
|
|||||||
| `ANTHROPIC_API_KEY` | `@lead` (and `@pm`/`@senior`/`@qa` if on Claude) |
|
| `ANTHROPIC_API_KEY` | `@lead` (and `@pm`/`@senior`/`@qa` if on Claude) |
|
||||||
| `OLLAMA_URL`, `OLLAMA_CLOUD_API_KEY` | local ornith / Ollama Cloud (gemma4, kimi-k2.7-code, glm-5.2, minimax-m3) |
|
| `OLLAMA_URL`, `OLLAMA_CLOUD_API_KEY` | local ornith / Ollama Cloud (gemma4, kimi-k2.7-code, glm-5.2, minimax-m3) |
|
||||||
| `AGENT_TOKEN` | PAT (issue/repository/organization/misc read+write, cross-repo) — posts the delegation comment that fires the next agent **and** powers the `gitea-api` skill (read/write issues, PRs, comments, labels, and Actions runs/logs across any repo). Do not re-narrow its scopes without also removing the `gitea-api` skill. |
|
| `AGENT_TOKEN` | PAT (issue/repository/organization/misc read+write, cross-repo) — posts the delegation comment that fires the next agent **and** powers the `gitea-api` skill (read/write issues, PRs, comments, labels, and Actions runs/logs across any repo). Do not re-narrow its scopes without also removing the `gitea-api` skill. |
|
||||||
| `TOKEN_PM`,`TOKEN_SENIOR`,`TOKEN_JUNIOR`,`TOKEN_LEAD`,`TOKEN_QA` | optional — post/commit as each agent's own Gitea user (falls back to the bot) |
|
| `TOKEN_PM`,`TOKEN_INTERN`,`TOKEN_SENIOR`,`TOKEN_JUNIOR`,`TOKEN_LEAD`,`TOKEN_QA` | optional — post/commit as each agent's own Gitea user (falls back to the bot) |
|
||||||
|
|
||||||
`GITEA_TOKEN` is auto-provided. Tip: set these once at the **org** level so every repo inherits
|
`GITEA_TOKEN` is auto-provided. Tip: set these once at the **org** level so every repo inherits
|
||||||
them via `secrets: inherit`.
|
them via `secrets: inherit`.
|
||||||
|
|||||||
Reference in New Issue
Block a user