From bf75cd5035daf26b63e359cca4cd89da051f0080 Mon Sep 17 00:00:00 2001 From: junior Date: Sun, 5 Jul 2026 06:28:30 +0000 Subject: [PATCH] @intern: add intern agent using local ornith:35b model (issue #53) --- .gitea/workflows/agent.yml | 14 +++++++++----- .gitea/workflows/scripts/agents.json | 3 ++- .gitea/workflows/scripts/publish.sh | 10 +++++----- .gitea/workflows/scripts/rescue-pr.sh | 4 ++-- .gitea/workflows/scripts/route.sh | 6 +++--- README.md | 7 ++++--- 6 files changed, 25 insertions(+), 19 deletions(-) diff --git a/.gitea/workflows/agent.yml b/.gitea/workflows/agent.yml index a233df2..5be7e29 100644 --- a/.gitea/workflows/agent.yml +++ b/.gitea/workflows/agent.yml @@ -14,11 +14,12 @@ jobs: (github.event.comment == null && github.event.issue.user.login == 'ffaerber') || (github.event.comment != null && github.event.comment.user.login == 'ffaerber' && !contains(github.event.comment.body, '🤖') && - (contains(github.event.comment.body, '@pm') || - contains(github.event.comment.body, '@junior') || - contains(github.event.comment.body, '@senior') || - contains(github.event.comment.body, '@lead') || - contains(github.event.comment.body, '@qa'))) + (contains(github.event.comment.body, '@pm') || + contains(github.event.comment.body, '@intern') || + contains(github.event.comment.body, '@junior') || + contains(github.event.comment.body, '@senior') || + contains(github.event.comment.body, '@lead') || + contains(github.event.comment.body, '@qa'))) runs-on: ci-runner steps: - name: Acknowledge with 👀 @@ -88,6 +89,7 @@ jobs: NUM: ${{ github.event.issue.number }} GT: ${{ secrets.GITEA_TOKEN }} TOKEN_PM: ${{ secrets.TOKEN_PM }} + TOKEN_INTERN: ${{ secrets.TOKEN_INTERN }} TOKEN_SENIOR: ${{ secrets.TOKEN_SENIOR }} TOKEN_JUNIOR: ${{ secrets.TOKEN_JUNIOR }} TOKEN_LEAD: ${{ secrets.TOKEN_LEAD }} @@ -183,6 +185,7 @@ jobs: GT: ${{ secrets.GITEA_TOKEN }} AGENT_TOKEN: ${{ secrets.AGENT_TOKEN }} TOKEN_PM: ${{ secrets.TOKEN_PM }} + TOKEN_INTERN: ${{ secrets.TOKEN_INTERN }} TOKEN_SENIOR: ${{ secrets.TOKEN_SENIOR }} TOKEN_JUNIOR: ${{ secrets.TOKEN_JUNIOR }} TOKEN_LEAD: ${{ secrets.TOKEN_LEAD }} @@ -208,6 +211,7 @@ jobs: SCRIPTS: ${{ runner.temp }}/agents-scripts GT: ${{ secrets.GITEA_TOKEN }} TOKEN_PM: ${{ secrets.TOKEN_PM }} + TOKEN_INTERN: ${{ secrets.TOKEN_INTERN }} TOKEN_SENIOR: ${{ secrets.TOKEN_SENIOR }} TOKEN_JUNIOR: ${{ secrets.TOKEN_JUNIOR }} TOKEN_LEAD: ${{ secrets.TOKEN_LEAD }} diff --git a/.gitea/workflows/scripts/agents.json b/.gitea/workflows/scripts/agents.json index 549c15a..5b2827a 100644 --- a/.gitea/workflows/scripts/agents.json +++ b/.gitea/workflows/scripts/agents.json @@ -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."}, - "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)."}, "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."} diff --git a/.gitea/workflows/scripts/publish.sh b/.gitea/workflows/scripts/publish.sh index 29740fc..c7e9271 100755 --- a/.gitea/workflows/scripts/publish.sh +++ b/.gitea/workflows/scripts/publish.sh @@ -2,13 +2,13 @@ # Publish — PR (dev agents) or comment (pm/qa), always reply in the issue. # # 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 # 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 # Post/PR as the agent's OWN Gitea user when its token is configured; else the built-in bot. 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="";; esac [ -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 git checkout -- . 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. msg="$reply" 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 # Only delegate on an explicit "DELEGATE: @" line — never on a prose mention, # 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 \ - | 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:]') if [ -n "$target" ] && [ "$target" != "$NAME" ]; then echo "auto-delegating to @$target" curl -sS -X POST -H "Authorization: token $AGENT_TOKEN" -H "Content-Type: application/json" \ diff --git a/.gitea/workflows/scripts/rescue-pr.sh b/.gitea/workflows/scripts/rescue-pr.sh index 2579696..5211878 100755 --- a/.gitea/workflows/scripts/rescue-pr.sh +++ b/.gitea/workflows/scripts/rescue-pr.sh @@ -6,7 +6,7 @@ # the run. Comment-only roles (pm/qa) push nothing, so they are skipped. # # 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 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. 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="";; esac [ -z "$TOK" ] && TOK="$GT" diff --git a/.gitea/workflows/scripts/route.sh b/.gitea/workflows/scripts/route.sh index 32328dd..ff59d57 100755 --- a/.gitea/workflows/scripts/route.sh +++ b/.gitea/workflows/scripts/route.sh @@ -5,7 +5,7 @@ # 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 -# 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 set -eu @@ -27,7 +27,7 @@ cp "$AGENTS_JSON" /tmp/agents.json # here — see agent.yml: this reusable workflow sees it as 'workflow_call'.) if [ -n "$CID" ]; then scan="$BODY"; else scan="$IBODY"; fi 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 done 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. 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="";; esac [ -z "$TOK" ] && TOK="$GT" diff --git a/README.md b/README.md index ff1ed4e..d8fa783 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,15 @@ # agents 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 | 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. | -| `@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). | | `@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. | @@ -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) | | `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. | -| `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 them via `secrets: inherit`. -- 2.54.0