Compare commits

...
Author SHA1 Message Date
Felix FaerberandClaude Opus 4.8 658c10fc35 chore: standardize the ai-agent caller stub (identical in every repo)
The caller workflow had drifted between repos (run-name, stale SHA comment, trigger ordering,
different comment text) though all were functionally the same `uses: agent.yml@main`. Define one
canonical stub: make this repo's own ai-agent.yml the reference and update the README "Use it in a
repo" block to match it verbatim, noting that the on: triggers and the jobs.agent wrapper are the
irreducible minimum for a reusable (workflow_call) workflow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 12:17:13 +03:00
ffaerber 649cd4ea9b Merge pull request 'fix(routing): expose agent skills in the roster' (#40) from fix/roster-skills into main 2026-07-04 11:00:39 +02:00
Felix FaerberandClaude Opus 4.8 509b10ac57 fix(routing): expose agent skills in the roster so pm routes by capability
The homelab health-check test mis-routed a node1 inspection to @junior (skills: []), which cannot
reach node1 — only @senior/@lead hold node1-ssh. Root cause: the roster shown to agents listed
desc + vision but not skills, so @pm had no way to route by capability (despite a comment claiming
it could). Add each teammate's skill names to the roster line. Names only; the scoped how-to detail
stays hidden via permission.skill.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 11:56:27 +03:00
3 changed files with 18 additions and 5 deletions
+4 -2
View File
@@ -1,6 +1,8 @@
name: ai-agent name: ai-agent
# Thin caller so the agents work on THIS repo too (their own workflow). Same shared logic. # Standard caller for the shared AI-agent workflow (ffaerber/agents). Copy this file VERBATIM into
# New issues opened by ffaerber auto-start @pm; @mention an agent in a comment to route on replies. # any repo that should get the agents — it is identical in every repo. All logic + scripts live in
# agents/.gitea/workflows/; scripts are fetched from @main at run time. The `jobs.agent` wrapper is
# required: a reusable (workflow_call) workflow can only be invoked from a caller job, not top-level.
on: on:
issue_comment: issue_comment:
types: [created] types: [created]
+4 -1
View File
@@ -10,7 +10,10 @@ set -u
[ -z "$CMT" ] && CMT="(a new issue was just opened — assess it)" [ -z "$CMT" ] && CMT="(a new issue was just opened — assess it)"
THREAD=$(cat /tmp/thread.md 2>/dev/null); [ -z "$THREAD" ] && THREAD="(no prior comments)" THREAD=$(cat /tmp/thread.md 2>/dev/null); [ -z "$THREAD" ] && THREAD="(no prior comments)"
DESC=$(jq -r --arg a "$NAME" '.[$a].desc' /tmp/agents.json) DESC=$(jq -r --arg a "$NAME" '.[$a].desc' /tmp/agents.json)
ROSTER=$(jq -r 'to_entries | map("- @\(.key): \(.value.desc) (vision: \(.value.vision))") | join("\n")' /tmp/agents.json) # Include each teammate's skills so an agent (esp. @pm) can route by capability — e.g. only
# @senior/@lead hold node1-ssh, so a node1 task must not go to @junior. Skill *names* only; the
# scoped how-to detail stays hidden per the permission.skill allow-list.
ROSTER=$(jq -r 'to_entries | map("- @\(.key): \(.value.desc) (vision: \(.value.vision); skills: \(.value.skills | if length>0 then join(", ") else "none" end))") | join("\n")' /tmp/agents.json)
if [ "$VISION" = "true" ]; then CAP="You CAN read images attached to the issue."; else CAP="You CANNOT read images — you are a text-only model."; fi if [ "$VISION" = "true" ]; then CAP="You CAN read images attached to the issue."; else CAP="You CANNOT read images — you are a text-only model."; fi
NOTE="" NOTE=""
if [ "$VISION" != "true" ] && [ "${HAS_IMAGES:-0}" -gt 0 ]; then if [ "$VISION" != "true" ] && [ "${HAS_IMAGES:-0}" -gt 0 ]; then
+10 -2
View File
@@ -29,10 +29,16 @@ detail out of agents that shouldn't act on it while still letting them know the
## Use it in a repo ## Use it in a repo
Add `.gitea/workflows/ai-agent.yml` to the consuming repo: **The standard caller is one file, identical in every repo.** Copy this repo's own
[`.gitea/workflows/ai-agent.yml`](.gitea/workflows/ai-agent.yml) verbatim into the consuming repo —
it is the source of truth, and `agents` itself uses the same file:
```yaml ```yaml
name: ai-agent name: ai-agent
# Standard caller for the shared AI-agent workflow (ffaerber/agents). Copy this file VERBATIM into
# any repo that should get the agents — it is identical in every repo. All logic + scripts live in
# agents/.gitea/workflows/; scripts are fetched from @main at run time. The `jobs.agent` wrapper is
# required: a reusable (workflow_call) workflow can only be invoked from a caller job, not top-level.
on: on:
issue_comment: issue_comment:
types: [created] types: [created]
@@ -44,7 +50,9 @@ jobs:
secrets: inherit secrets: inherit
``` ```
That's the whole per-repo footprint. All the logic (agent registry, routing, delegation, That's the whole per-repo footprint, and it's the minimum a caller can be: the `on:` triggers must
live in each repo (a reusable workflow can't declare its callers' triggers) and the `jobs.agent`
wrapper is mandatory for `workflow_call`. Everything else (agent registry, routing, delegation,
reactions, PR/issue plumbing) lives here in `agent.yml`. reactions, PR/issue plumbing) lives here in `agent.yml`.
## Repo layout ## Repo layout