@plainconceptsplatform/workflows 1.6.11 → 1.6.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/loops/actions/housekeeping/action.yml +15 -0
- package/loops/actions/merge-train/action.yml +7 -0
- package/loops/actions/merge-train/merge-train.sh +29 -1
- package/loops/actions/report-workflow-errors/action.yml +92 -23
- package/loops/actions/report-workflow-errors/report-policy.cjs +110 -0
- package/loops/actions/verify-route-matrix/verify-route-matrix.sh +198 -0
- package/loops/docs/diagrams.md +8 -4
- package/loops/templates/agentics/agentics-error-report.yml +2 -0
- package/loops/templates/opencode/opencode.ci.json +118 -1
- package/loops/workflows/agent-apply-review.md +12 -1
- package/loops/workflows/agent-audit.md +6 -1
- package/loops/workflows/agent-implement.md +109 -13
- package/loops/workflows/agent-merge-gate.md +6 -1
- package/loops/workflows/agent-refine.md +10 -1
- package/loops/workflows/agent-release.md +6 -1
- package/loops/workflows/agent-triage.md +10 -1
- package/loops/workflows/shared/opencode-ci.md +7 -1
- package/loops/workflows/work-router.yml +22 -2
- package/package.json +1 -1
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
# Managed by @plainconceptsplatform/workflows. Source: loops/workflows/agent-implement.md. Update with `workflows update --force`; consumer edits may be overwritten.
|
|
3
3
|
env:
|
|
4
|
+
# The model this worker's own session runs on. opencode.ci.json's `model` is the cheap default
|
|
5
|
+
# every agent without its own model falls back to; the lead is where a wrong call costs a run,
|
|
6
|
+
# so it names its model here. `model:` below only satisfies the compiler. A repository may
|
|
7
|
+
# change it to any model its opencode.ci.json declares.
|
|
8
|
+
AGENT_LEAD_MODEL: "forge/quasar-438b"
|
|
4
9
|
VERIFY_COMMANDS: ""
|
|
5
10
|
REPO_RULES: "Implement only the selected issue. Follow repository documentation and existing conventions. Do not weaken tests, lower coverage thresholds, or bypass checks."
|
|
6
11
|
# Split out of REPO_RULES because one field asked to carry architecture, testing, coverage and
|
|
@@ -247,6 +252,10 @@ jobs:
|
|
|
247
252
|
pull-requests: write
|
|
248
253
|
# reads the agent job's log and annotations, and re-enters through the router on a retry
|
|
249
254
|
actions: write
|
|
255
|
+
# decide-agent-retry reads why the agent job died from its annotations, and the annotations API needs this scope.
|
|
256
|
+
# Without it the read fails quietly, a runner shut down mid-job (exit code 143) reads as no cause,
|
|
257
|
+
# and the issue is parked for a person instead of being run again (Pliny-Bot #750).
|
|
258
|
+
checks: read
|
|
250
259
|
steps:
|
|
251
260
|
- name: Checkout workflow actions
|
|
252
261
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
@@ -509,6 +518,10 @@ jobs:
|
|
|
509
518
|
issues: write
|
|
510
519
|
# the retry re-enters through the router, which is a workflow_dispatch
|
|
511
520
|
actions: write
|
|
521
|
+
# decide-agent-retry reads why the agent job died from its annotations, and the annotations API needs this scope.
|
|
522
|
+
# Without it the read fails quietly, a runner shut down mid-job (exit code 143) reads as no cause,
|
|
523
|
+
# and the issue is parked for a person instead of being run again (Pliny-Bot #750).
|
|
524
|
+
checks: read
|
|
512
525
|
steps:
|
|
513
526
|
- name: Checkout workflow actions
|
|
514
527
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
@@ -614,7 +627,7 @@ engine:
|
|
|
614
627
|
env:
|
|
615
628
|
OPENAI_BASE_URL: https://forge.plainconcepts.com/v1
|
|
616
629
|
|
|
617
|
-
model: openai/
|
|
630
|
+
model: openai/quasar-438b
|
|
618
631
|
|
|
619
632
|
max-turns: 300
|
|
620
633
|
max-turn-cache-misses: 3000
|
|
@@ -732,18 +745,33 @@ timeout-minutes: 180
|
|
|
732
745
|
wrote instead:
|
|
733
746
|
|
|
734
747
|
1. `pc-plan-goal`, then Phase 0 as it describes.
|
|
748
|
+
|
|
749
|
+
**Propose and archive run in the `planner` agent, not in this session.** Spawn it with the
|
|
750
|
+
task tool (`subagent_type: planner`) and a prompt that names the skill to load
|
|
751
|
+
(`pc-plan-propose` or `pc-plan-archive`), the issue context path above, the branch, and that it
|
|
752
|
+
runs in autonomous mode with no one to ask. `planner` runs on the repository's plan model, which
|
|
753
|
+
is stronger than this session's, and these two steps decide the whole change. Wait for it in the
|
|
754
|
+
same turn, then continue with the next phase yourself. Only when no `planner` agent exists
|
|
755
|
+
(agent-harness older than 3.4.0) load the skill here instead.
|
|
756
|
+
|
|
735
757
|
2. `pc-plan-propose`, even when the issue is refined. It is what turns the issue into
|
|
736
758
|
`openspec/changes/<id>/tasks.md` with every task annotated
|
|
737
759
|
`<!-- agent: <engineer>.<tier>, depends_on: [...], touches: [...] -->`. **You never write
|
|
738
760
|
`proposal.md` or `tasks.md` yourself.** A hand-written `tasks.md` carries no annotations,
|
|
739
761
|
and without them `pc-plan-apply` has no workers to spawn, so the whole change is done by
|
|
740
762
|
you alone, in sequence, on one model. That is the failure this step exists to prevent.
|
|
763
|
+
Ask it for few, coarse tasks: one task per area of files, the tests for that code in the
|
|
764
|
+
same task, and no task whose only job is to repair what an earlier task broke. Five tasks
|
|
765
|
+
in three waves cover most issues. Every task is a fresh worker that rereads the code it
|
|
766
|
+
needs before it edits anything, one to three minutes each: Pliny-Bot #751 split a small
|
|
767
|
+
web feature into twelve tasks and spent fifteen of its twenty-two minutes in them, and
|
|
768
|
+
#696 ended with a twelve-minute task that fixed the test doubles the earlier tasks broke.
|
|
741
769
|
3. `pc-plan-apply`. The tasks are implemented by the subagents it spawns, in waves, each on
|
|
742
770
|
the model tier its annotation names. **In this phase you do not edit source files
|
|
743
771
|
yourself.** If it stops because a worker cannot be resolved, report that with
|
|
744
772
|
`report_incomplete`, naming the task and the missing worker; do not do the task yourself
|
|
745
773
|
to get past it.
|
|
746
|
-
4. `pc-repo-verify`, then `pc-plan-archive`, as `pc-plan-goal` directs.
|
|
774
|
+
4. `pc-repo-verify`, then `pc-plan-archive` in `planner`, as `pc-plan-goal` directs.
|
|
747
775
|
|
|
748
776
|
Before the first edit to a source file, check that
|
|
749
777
|
`openspec/changes/<id>/tasks.md` exists and that its tasks carry the annotation above. If it
|
|
@@ -767,6 +795,12 @@ timeout-minutes: 180
|
|
|
767
795
|
Adhere to ${{ env.REPO_RULES }}, ${{ env.ARCHITECTURE_RULES }} and
|
|
768
796
|
${{ env.TESTING_RULES }}.
|
|
769
797
|
|
|
798
|
+
**WORK IN FEW TURNS**, on both paths. Every turn is a model call of three to twenty
|
|
799
|
+
seconds, and the turns, not the commands, are most of a run. Read a file whole, or in
|
|
800
|
+
ranges of a few hundred lines, once; never eight or fifteen lines at a time. Put
|
|
801
|
+
independent reads and searches in the same turn. Leave whitespace and line endings to the
|
|
802
|
+
formatter instead of inspecting them with `hexdump` or `cat -A`.
|
|
803
|
+
|
|
770
804
|
**DECISIVE IMPLEMENTATION**, on both paths. When a design choice is ambiguous, pick the most
|
|
771
805
|
standard interpretation and implement it immediately. Do not deliberate between options for
|
|
772
806
|
more than one turn. Do not ask clarifying questions the issue author expects you to use good
|
|
@@ -781,14 +815,55 @@ timeout-minutes: 180
|
|
|
781
815
|
|
|
782
816
|
Never open a pull request that does not pass them.
|
|
783
817
|
|
|
818
|
+
**Run them once, on the final tree.** They are slow: Pliny-Bot's `pnpm verify` is about
|
|
819
|
+
twenty minutes of work on this runner. `pc-plan-apply` runs them in its verify step, and
|
|
820
|
+
that run is this one: do not run them again when nothing changed since. Order the end of
|
|
821
|
+
the run so the last run is the only one: first `check-diff` below, which takes seconds, and
|
|
822
|
+
fix what it lists; then these commands. While you work, check with the narrowest command
|
|
823
|
+
that covers what you changed (build the project you edited, run the test files you
|
|
824
|
+
edited, typecheck the web app), not with these. Pliny-Bot #694 ran three typechecks and
|
|
825
|
+
three test runs of its own before it reached the full verification at minute forty-one.
|
|
826
|
+
|
|
827
|
+
A test that cannot start in this sandbox (it needs Docker, a database or a host the
|
|
828
|
+
firewall blocks) and fails the same way on the default branch is not yours to fix: say so
|
|
829
|
+
in the pull request and move on, CI runs it with the service. Pliny-Bot #696 spent its
|
|
830
|
+
turns on 365 integration tests that could not start here because Testcontainers found an
|
|
831
|
+
empty Docker configuration.
|
|
832
|
+
|
|
833
|
+
**Run every command in the foreground and wait for it in the same turn. Never move a command
|
|
834
|
+
to the background and never end a turn to wait for it.** This run is not interactive: nothing
|
|
835
|
+
resumes you. A turn that ends with text and no tool call ends the whole run, and the work is
|
|
836
|
+
discarded. Pliny-Bot #750 started `pnpm verify` in the background, wrote "I'll be resumed with
|
|
837
|
+
its result" and stopped: the run ended green with eight commits and no pull request, and #694
|
|
838
|
+
lost seventy-eight minutes the same way. The bash tool cuts a command at 120 seconds unless you
|
|
839
|
+
pass a `timeout` (milliseconds, up to 600000). Give a long command that timeout, and when it is
|
|
840
|
+
still too long, run it in parts (lint, typecheck, web tests, web build, dotnet build, dotnet test)
|
|
841
|
+
so every part finishes inside one call. The only valid way to end the run is the safe-output
|
|
842
|
+
call in step 6.
|
|
843
|
+
|
|
844
|
+
**Two things the unit tests do not catch, and CI will.** When you add a dependency, take the
|
|
845
|
+
latest released version and run the repository's audit for it (`pnpm audit --audit-level high`
|
|
846
|
+
for the web, `dotnet list package --vulnerable` for the backend): Pliny-Bot #752 added a PDF
|
|
847
|
+
library at a version with two critical and eight high advisories and the dependency scan
|
|
848
|
+
blocked it. When you register a new service, interface or handler, run at least one test that
|
|
849
|
+
boots the whole application, not only unit tests: Pliny-Bot #753 registered an interface for
|
|
850
|
+
one engine only, the application could not start under the others and every integration test
|
|
851
|
+
failed.
|
|
852
|
+
|
|
784
853
|
When `.opencode/scripts/check-diff.mjs` exists, also run
|
|
785
854
|
`node .opencode/scripts/check-diff.mjs`
|
|
786
|
-
on both paths. It must exit 0. It holds the comments and tests you add to the size of the
|
|
855
|
+
on both paths, before the commands above. It must exit 0. It holds the comments and tests you add to the size of the
|
|
787
856
|
change and makes you clean the files you touched; fix every line it lists. The merge gate
|
|
788
857
|
runs it again and does not merge while it fails.
|
|
789
858
|
|
|
790
|
-
|
|
791
|
-
|
|
859
|
+
Shape what you test like a trophy, not a pyramid: put new tests at the integration or
|
|
860
|
+
acceptance layer, through the public surface of the code you changed, and write a plain
|
|
861
|
+
unit test only for logic with real branching. A bug fix gets one regression test. Do not
|
|
862
|
+
write tests of constants, configured defaults, mocks of your own code or markup attributes.
|
|
863
|
+
|
|
864
|
+
Anything you change to satisfy `check-diff` is a change: run it again, and run the
|
|
865
|
+
verification commands only after it passes, so they run on the tree you ship. Open the
|
|
866
|
+
pull request only from a tree where both pass. Do not delete
|
|
792
867
|
a test that covers a branch you added to fit the budget; the complexity gate in CI measures
|
|
793
868
|
that coverage.
|
|
794
869
|
|
|
@@ -798,16 +873,37 @@ timeout-minutes: 180
|
|
|
798
873
|
code already written.
|
|
799
874
|
|
|
800
875
|
6. Finish by calling **exactly one** safe-output tool. A run that calls none is a wasted run:
|
|
801
|
-
the workflow reports a failure and everything you just did is discarded.
|
|
802
|
-
|
|
876
|
+
the workflow reports a failure and everything you just did is discarded. Pliny-Bot #694 spent
|
|
877
|
+
seventy-eight minutes and sixteen commits on a finished change and ended with nothing: the
|
|
878
|
+
agent searched for the tool in the `tools` object of the `execute` tool, did not find it
|
|
879
|
+
there, and concluded it did not exist.
|
|
880
|
+
|
|
881
|
+
**The safe-output tools are shell commands on your PATH, not entries in `tools`.** The sandbox
|
|
882
|
+
mounts the `safeoutputs` server as a command-line program. It is not under `tools.*`, `search`
|
|
883
|
+
does not return it, and an empty result from either says nothing about it. Run it with the
|
|
884
|
+
bash tool, and run `command -v safeoutputs` there first if you are unsure it is present.
|
|
885
|
+
|
|
886
|
+
**Pipe the JSON on stdin, put every parameter inside the JSON, and pass a lone `.` and no
|
|
887
|
+
flags.** The bridge reads the payload from stdin only when the command line is the tool name
|
|
888
|
+
followed by `.`. A `--flag` on the line makes it skip stdin and send just the flags, drop the
|
|
889
|
+
body and still report success. Correct:
|
|
890
|
+
|
|
891
|
+
`printf '%s' "$JSON" | safeoutputs create_pull_request .` with
|
|
892
|
+
`{"title":"[bot] Fix X","body":"Closes #${{ inputs.issue-number }}\n\n...","branch":"${{ env.IMPLEMENT_BRANCH_PREFIX }}${{ inputs.issue-number }}"}`
|
|
893
|
+
|
|
894
|
+
`printf '%s' "$JSON" | safeoutputs report_incomplete .` with `{"reason":"..."}`
|
|
895
|
+
|
|
896
|
+
`printf '%s' "$JSON" | safeoutputs noop .` with `{"message":"..."}`
|
|
897
|
+
|
|
898
|
+
Wrong (the body is silently empty): `safeoutputs create_pull_request --title "..." .`
|
|
803
899
|
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
900
|
+
If the call fails, read the error and send the whole payload again once. If it fails twice,
|
|
901
|
+
call `report_incomplete` the same way with the reason; never end the run with finished work
|
|
902
|
+
and no call.
|
|
807
903
|
|
|
808
904
|
Choose exactly one:
|
|
809
905
|
|
|
810
|
-
- **`
|
|
906
|
+
- **`create_pull_request`** , the normal path. Propose a pull request with the
|
|
811
907
|
verified changes. Do not pass `base`: the workflow sets it to the branch this run started
|
|
812
908
|
on, which is the branch you are working from, so a stack child lands on its feature branch
|
|
813
909
|
without you doing anything. The `body` **must close exactly this issue and nothing else**
|
|
@@ -815,10 +911,10 @@ timeout-minutes: 180
|
|
|
815
911
|
the branch you are on, the one named in step 1; do not invent another name. You do not
|
|
816
912
|
need to check whether a pull request already exists for this issue: the router does
|
|
817
913
|
that before dispatching you and does not start this workflow when one does.
|
|
818
|
-
- **`
|
|
914
|
+
- **`report_incomplete`** , only when infrastructure or tooling prevents you
|
|
819
915
|
from completing the task, such as a pre-existing build failure you cannot fix. Provide a
|
|
820
916
|
specific `reason`.
|
|
821
|
-
- **`
|
|
917
|
+
- **`noop`** , only when the issue context shows the work is already done and no
|
|
822
918
|
changes are needed. Provide a `message` explaining what you found.
|
|
823
919
|
|
|
824
920
|
Do not manage labels or post comments , the conclude job handles that.
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
# Managed by @plainconceptsplatform/workflows. Source: loops/workflows/agent-merge-gate.md. Update with `workflows update --force`; consumer edits may be overwritten.
|
|
3
3
|
env:
|
|
4
|
+
# The model this worker's own session runs on. opencode.ci.json's `model` is the cheap default
|
|
5
|
+
# every agent without its own model falls back to; the lead is where a wrong call costs a run,
|
|
6
|
+
# so it names its model here. `model:` below only satisfies the compiler. A repository may
|
|
7
|
+
# change it to any model its opencode.ci.json declares.
|
|
8
|
+
AGENT_LEAD_MODEL: "forge/quasar-438b"
|
|
4
9
|
VERIFY_COMMANDS: ""
|
|
5
10
|
REPO_RULES: "Review the selected pull request for defects and report what you verified. Do not decide the outcome: the workflow computes it from your report and from facts it measured before you ran."
|
|
6
11
|
# Where to look first, not what to escalate on. This list used to be the check that decided
|
|
@@ -870,7 +875,7 @@ engine:
|
|
|
870
875
|
env:
|
|
871
876
|
OPENAI_BASE_URL: https://forge.plainconcepts.com/v1
|
|
872
877
|
|
|
873
|
-
model: openai/
|
|
878
|
+
model: openai/quasar-438b
|
|
874
879
|
|
|
875
880
|
max-turns: 300
|
|
876
881
|
max-turn-cache-misses: 3000
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
# Managed by @plainconceptsplatform/workflows. Source: loops/workflows/agent-refine.md. Update with `workflows update --force`; consumer edits may be overwritten.
|
|
3
3
|
env:
|
|
4
|
+
# The model this worker's own session runs on. opencode.ci.json's `model` is the cheap default
|
|
5
|
+
# every agent without its own model falls back to; the lead is where a wrong call costs a run,
|
|
6
|
+
# so it names its model here. `model:` below only satisfies the compiler. A repository may
|
|
7
|
+
# change it to any model its opencode.ci.json declares.
|
|
8
|
+
AGENT_LEAD_MODEL: "forge/glm-5-3"
|
|
4
9
|
REPO_RULES: "Refine only the selected issue into a grounded, implementation-ready user story. Read repository documentation for domain context. Write acceptance criteria that match existing patterns. Where a story or its open questions decide how business data (named people, roles, addresses) is stored, resolve it toward the repository's convention for that data -- a database entity or a settings entry -- and record that choice in the acceptance criteria; do not carry a person's name or email address into the story as something the code reads from a constant. Do not implement code. Do not use web search or web fetch tools. The issue body already contains the research that motivated it; derive your domain context from the repository's own code and documentation only."
|
|
5
10
|
# The estimate decides whether a story gets split, and the prompt tells the agent these bands
|
|
6
11
|
# come from this repository's own merged pull requests. They have to actually come from it, or
|
|
@@ -672,6 +677,10 @@ jobs:
|
|
|
672
677
|
issues: write
|
|
673
678
|
# the retry re-enters through the router, which is a workflow_dispatch
|
|
674
679
|
actions: write
|
|
680
|
+
# decide-agent-retry reads why the agent job died from its annotations, and the annotations API needs this scope.
|
|
681
|
+
# Without it the read fails quietly, a runner shut down mid-job (exit code 143) reads as no cause,
|
|
682
|
+
# and the issue is parked for a person instead of being run again (Pliny-Bot #750).
|
|
683
|
+
checks: read
|
|
675
684
|
steps:
|
|
676
685
|
- name: Checkout workflow actions
|
|
677
686
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
@@ -803,7 +812,7 @@ engine:
|
|
|
803
812
|
env:
|
|
804
813
|
OPENAI_BASE_URL: https://forge.plainconcepts.com/v1
|
|
805
814
|
|
|
806
|
-
model: openai/glm-5-
|
|
815
|
+
model: openai/glm-5-3
|
|
807
816
|
# 150 rather than 500. With a four-hour clock this is the loop guard, and the worst
|
|
808
817
|
# observed run used 44 turns, so this leaves better than three times the worst case.
|
|
809
818
|
max-turns: 150
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
# Managed by @plainconceptsplatform/workflows. Source: loops/workflows/agent-release.md. Update with `workflows update --force`; consumer edits may be overwritten.
|
|
3
3
|
env:
|
|
4
|
+
# The model this worker's own session runs on. opencode.ci.json's `model` is the cheap default
|
|
5
|
+
# every agent without its own model falls back to; the lead is where a wrong call costs a run,
|
|
6
|
+
# so it names its model here. `model:` below only satisfies the compiler. A repository may
|
|
7
|
+
# change it to any model its opencode.ci.json declares.
|
|
8
|
+
AGENT_LEAD_MODEL: "forge/quasar-438b"
|
|
4
9
|
GIT_AUTHOR_NAME: "github-actions[bot]"
|
|
5
10
|
GIT_AUTHOR_EMAIL: "github-actions[bot]@users.noreply.github.com"
|
|
6
11
|
GIT_COMMITTER_NAME: "github-actions[bot]"
|
|
@@ -42,7 +47,7 @@ engine:
|
|
|
42
47
|
env:
|
|
43
48
|
OPENAI_BASE_URL: https://forge.plainconcepts.com/v1
|
|
44
49
|
|
|
45
|
-
model: openai/
|
|
50
|
+
model: openai/quasar-438b
|
|
46
51
|
|
|
47
52
|
max-turns: 100
|
|
48
53
|
max-turn-cache-misses: 3000
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
# Managed by @plainconceptsplatform/workflows. Source: loops/workflows/agent-triage.md. Update with `workflows update --force`; consumer edits may be overwritten.
|
|
3
3
|
env:
|
|
4
|
+
# The model this worker's own session runs on. opencode.ci.json's `model` is the cheap default
|
|
5
|
+
# every agent without its own model falls back to; the lead is where a wrong call costs a run,
|
|
6
|
+
# so it names its model here. `model:` below only satisfies the compiler. A repository may
|
|
7
|
+
# change it to any model its opencode.ci.json declares.
|
|
8
|
+
AGENT_LEAD_MODEL: "forge/quasar-438b"
|
|
4
9
|
REPO_RULES: "Triage issues opened by outside collaborators. Assess template completeness, security risk, change size, danger level, duplicates, clarity, reproducibility, acceptance criteria, and cross-cutting impact. When the request names specific people, email addresses, or business entities as the thing the code acts on, judge where that data is meant to live: business data that belongs in the database or a settings page is a design decision, not a wording detail, and it must not be left for the implementer to decide by hardcoding it. Do not implement code. Do not modify the issue body."
|
|
5
10
|
# What a product owner may ask for, and what has to become a maintainer-owned technical
|
|
6
11
|
# proposal instead. This is business policy, so it belongs to the repository rather than to
|
|
@@ -314,6 +319,10 @@ jobs:
|
|
|
314
319
|
issues: write
|
|
315
320
|
# the retry re-enters through the router, which is a workflow_dispatch
|
|
316
321
|
actions: write
|
|
322
|
+
# decide-agent-retry reads why the agent job died from its annotations, and the annotations API needs this scope.
|
|
323
|
+
# Without it the read fails quietly, a runner shut down mid-job (exit code 143) reads as no cause,
|
|
324
|
+
# and the issue is parked for a person instead of being run again (Pliny-Bot #750).
|
|
325
|
+
checks: read
|
|
317
326
|
steps:
|
|
318
327
|
- name: Checkout workflow actions
|
|
319
328
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
@@ -408,7 +417,7 @@ engine:
|
|
|
408
417
|
env:
|
|
409
418
|
OPENAI_BASE_URL: https://forge.plainconcepts.com/v1
|
|
410
419
|
|
|
411
|
-
model: openai/
|
|
420
|
+
model: openai/quasar-438b
|
|
412
421
|
max-turns: 120
|
|
413
422
|
max-turn-cache-misses: 3000
|
|
414
423
|
max-ai-credits: 5000
|
|
@@ -195,6 +195,12 @@ pre-agent-steps:
|
|
|
195
195
|
merged=$(jq -S . "$FRAGMENT")
|
|
196
196
|
fi
|
|
197
197
|
|
|
198
|
+
# The worker's lead model, from its env. gh-aw leaves OPENCODE_MODEL empty, so without this
|
|
199
|
+
# every worker's session would run on opencode.ci.json's default.
|
|
200
|
+
if [ -n "${AGENT_LEAD_MODEL:-}" ]; then
|
|
201
|
+
merged=$(printf '%s' "$merged" | jq --arg model "$AGENT_LEAD_MODEL" '.agents["ci-workflow-agent"].model = $model')
|
|
202
|
+
fi
|
|
203
|
+
|
|
198
204
|
printf '%s\n' "$merged" > "$CONFIG"
|
|
199
205
|
|
|
200
206
|
# A tracked config now differs from HEAD, so the agent sees it in `git diff`, takes it for
|
|
@@ -210,5 +216,5 @@ pre-agent-steps:
|
|
|
210
216
|
# `$existing * $base`. Base wins on conflicting keys, but it defines neither `model`
|
|
211
217
|
# nor this provider, so both survive and `awf-proxy` is added alongside.
|
|
212
218
|
echo "Wrote $CONFIG from $FRAGMENT:"
|
|
213
|
-
jq -r '" model: \(.model // "unset")", " plugins: \(.plugins // [] | join(", "))", " providers: \(.providers // {} | keys | join(", "))"' "$CONFIG"
|
|
219
|
+
jq -r '" model: \(.model // "unset")", " lead: \(.agents["ci-workflow-agent"].model // "the default")", " plugins: \(.plugins // [] | join(", "))", " providers: \(.providers // {} | keys | join(", "))"' "$CONFIG"
|
|
214
220
|
---
|
|
@@ -551,9 +551,29 @@ jobs:
|
|
|
551
551
|
body=$(gh issue view "$ISSUE_NUMBER" --repo "$REPO" --json body --jq '.body // ""' 2>/dev/null || echo '')
|
|
552
552
|
parent=$(printf '%s' "$body" | grep -oE '<!-- split-parent: [0-9]+ -->' | head -1 | grep -oE '[0-9]+' || true)
|
|
553
553
|
key="${parent:-$ISSUE_NUMBER}"
|
|
554
|
-
|
|
554
|
+
|
|
555
|
+
# The queue is the key's place among the keys of every issue waiting for an implement, not
|
|
556
|
+
# the key modulo the number of queues. Three independent issues whose numbers were all
|
|
557
|
+
# multiples of three (Pliny-Bot #726, #750 and #694, whose parent is #690) landed in queue
|
|
558
|
+
# zero together and ran one after another behind a three-hour run while two queues sat
|
|
559
|
+
# empty. A place among the waiting keys puts independent issues in different queues, and
|
|
560
|
+
# the children of one refine, which share a key, still share one.
|
|
561
|
+
waiting=$(
|
|
562
|
+
{ printf '%s\n' "$key"
|
|
563
|
+
gh issue list --repo "$REPO" --label "implement" --state open --limit 100 --json number,body \
|
|
564
|
+
--jq '.[] | ((.body // "") | capture("<!-- split-parent: (?<p>[0-9]+) -->").p) // (.number | tostring)' \
|
|
565
|
+
2>/dev/null || true
|
|
566
|
+
} | grep -E '^[0-9]+$' | sort -un
|
|
567
|
+
)
|
|
568
|
+
place=0
|
|
569
|
+
index=0
|
|
570
|
+
for candidate in $waiting; do
|
|
571
|
+
[ "$candidate" = "$key" ] && place=$index
|
|
572
|
+
index=$((index + 1))
|
|
573
|
+
done
|
|
574
|
+
queue=$(( place % queues ))
|
|
555
575
|
echo "queue=$queue" >> "$GITHUB_OUTPUT"
|
|
556
|
-
echo "#$ISSUE_NUMBER waits in implement queue $queue of $queues (keyed on #$key)."
|
|
576
|
+
echo "#$ISSUE_NUMBER waits in implement queue $queue of $queues (keyed on #$key, place $place among $index waiting)."
|
|
557
577
|
- name: Resolve the feature branch from the stack markers
|
|
558
578
|
id: stack
|
|
559
579
|
env:
|