Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions web/lib/flow-local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,20 @@ import { workflowAgents } from './flow-workflows';
*
* So the guards that turn a ticket away still park with `f.done("needs_human")`
* (see flow-onboarding.ts). The reason they actually want is a deliberate
* declination, proposed as `declined` in AgentWorkforce/flows#438 and
* implemented in PR #439 — open, unmerged, and not in any published release.
* Do not generate `declined` until a pin here contains it. The test that
* asserts this exact version is the tripwire for that: it fails on the next
* bump and names what to revisit.
* declination, `declined` (AgentWorkforce/flows#438, merged as #439). It first
* shipped in 2.0.16, and the 2.0.22 executor lowers it: its
* `LOWERED_COMPLETIONS` is `['success', 'needs_human', 'step_failed',
* 'declined']`. This pin now contains it, but the guards stay on
* `needs_human` on purpose: the same generated source runs on Agent Relay
* Cloud, which must render a `declined` run before any flow emits one. Switch
* the two guards together with that Cloud change, not as part of a pin bump.
*
* 2.0.22 is the current release. Beyond the above it carries
* AgentWorkforce/flows#484: a Claude agent step completes on Claude's own
* result rather than on process exit, so an agent that started a background
* task no longer holds the run open until its wall-clock limit.
*/
export const RELAYFLOWS_VERSION = '2.0.15';
export const RELAYFLOWS_VERSION = '2.0.22';
export const LOCAL_PREFLIGHT = 'relay-preflight.mjs';

export const LOCAL_INSTALL = `npm install --save-dev relayflows@${RELAYFLOWS_VERSION} @relayflows/surface@${RELAYFLOWS_VERSION}`;
Expand Down
4 changes: 2 additions & 2 deletions web/lib/flow-workflows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ const REVIEW_BLOCKED_HEADING ='**Relayflow: the adversarial review did not pass.
* Puts the failed review where an operator acts on it: on the pull request.
*
* `done("step_failed")` is the honest end for a review that found problems, and
* as of the 2.0.15 pin the runtime lowers it (AgentWorkforce/flows#436), so the
* since the 2.0.15 pin the runtime lowers it (AgentWorkforce/flows#436), so the
* flow reports it. Up to 2.0.14 it did not: the authored executor lowered only
* `success` and `needs_human` and threw `the initial authored executor cannot
* lower done("step_failed")`, and a real run paid for it — 15 agent steps, a
Expand Down Expand Up @@ -553,7 +553,7 @@ export function workflowCode(workflow: WorkflowId, agents: ReturnType<typeof wor
}` });
if (workflow !== 'simple') sections.push({ id: 'review', code: ` // ${workflow === 'traditional' ? 'Always run two independent adversarial reviews, even if the first passes.' : 'Review the final implementation against the ticket and comparison findings.'}
// A review that found problems is this flow's verdict on its own work, so it
// reports done("step_failed"). The pinned 2.0.15 runtime lowers that reason
// reports done("step_failed"). The pinned runtime (2.0.15 and later) lowers that reason
// (AgentWorkforce/flows#436) and the CLI gives it exit 1, distinct from the
// exit 3 a clean run parks with. An exit code cannot carry what the reviewer
// found, so the step below still drafts the pull request and posts the
Expand Down
16 changes: 10 additions & 6 deletions web/lib/test/flow-local.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,17 @@ describe('local flow starter kit', () => {
// `run.cancel`, budget from the enforced budget) that a flow body cannot
// declare. flows#401, which promised `canceled`, is closed and superseded
// by #436. The guards in flow-onboarding.ts want a deliberate declination
// instead — `declined`, proposed in AgentWorkforce/flows#438 and
// implemented in PR #439, which is open and unmerged. When a pinned release
// contains it, turn those two f.done("needs_human") calls into
// f.done("declined"), and not before.
// instead — `declined` (AgentWorkforce/flows#438, merged as #439), which
// every release from 2.0.16 lowers. 2.0.22 contains it, yet the guards
// deliberately stay on f.done("needs_human"): the same source runs on Agent
// Relay Cloud, which has to render a declined run first. Switch the two
// guards in the same change that teaches Cloud `declined`.
// 2.0.22 also carries AgentWorkforce/flows#484: a Claude agent step ends on
// Claude's result, not on process exit, so a background task the agent
// started can no longer hold the run open until its wall-clock limit.
expect(LOCAL_INSTALL).toContain(`relayflows@${RELAYFLOWS_VERSION}`);
expect(LOCAL_INSTALL).toContain(`@relayflows/surface@${RELAYFLOWS_VERSION}`);
expect(RELAYFLOWS_VERSION).toBe('2.0.15');
expect(RELAYFLOWS_VERSION).toBe('2.0.22');
for (const workflow of ['traditional', 'prototype', 'simple'] as const) {
const source = factorySource({ ...draft, workflow }, 'local');
const code = withoutComments(source);
Expand Down Expand Up @@ -518,7 +522,7 @@ describe('relocating a kit that was extracted outside a repository', () => {
if (options.dependency) {
const pkg = join(target, 'node_modules', 'relayflows');
mkdirSync(pkg, { recursive: true });
// The shape relayflows@2.0.15 really publishes: a bin and nothing to
// The shape relayflows really publishes (still true of 2.0.22): a bin and nothing to
// import. A fake with a "main" let a bare resolve("relayflows") pass here
// while it failed against every real install.
mkdirSync(join(pkg, 'bin'), { recursive: true });
Expand Down
2 changes: 1 addition & 1 deletion web/lib/test/flow-onboarding.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ describe('software factory onboarding', () => {
const { calls, finish } = await runFactory([false, false, false]);
expect(calls.filter(call => call.startsWith('adversary-'))).toHaveLength(2);
expect(calls).not.toContain('human');
// done("step_failed") is the honest reason, and as of the 2.0.15 pin the
// done("step_failed") is the honest reason, and since the 2.0.15 pin the
// runtime lowers it (AgentWorkforce/flows#436). Before that it did not: a
// real run did all 15 steps, opened AgentWorkforce/cloud-e2e-sandbox#25,
// and then died as FAILED [protocol_error] unsupported_completion — the one
Expand Down
2 changes: 1 addition & 1 deletion web/lib/test/flow-workflows.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ describe('FLOW_CHECK_RUN_COMMAND', () => {

/**
* The step that runs when an adversarial review does not pass. The run itself
* reports `f.done("step_failed")` again: the 2.0.15 pin lowers that reason
* reports `f.done("step_failed")` again: every pin since 2.0.15 lowers that reason
* (AgentWorkforce/flows#436), where 2.0.14 failed the whole run with
* `unsupported_completion` after every agent had finished. An exit code still
* cannot carry what the reviewer found, so this step puts the verdict where an
Expand Down
Loading