Repository navigation
feat(sdk,kernel): f.agent resume continues a recorded CLI session #636
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| # packages/sdk/src and packages/surface/src at origin/main (22cd1836) via git stash; tests and testdata from this branch. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The transcript claims the product sources were reverted to AGENTS.md reference: AGENTS.md:L98-L100 Useful? React with 👍 / 👎. |
||
| $ (cd packages/sdk && npx vitest run tests/agent-resume.test.ts tests/spec-parity.test.ts) | ||
| × spec parity: one dialect at the SDK<->kernel boundary > compiles agent-resume to the pinned canonical JSON 5ms | ||
| × spec parity: one dialect at the SDK<->kernel boundary > hashes agent-resume to the pinned spec_hash 1ms | ||
| × spec parity: one dialect at the SDK<->kernel boundary > round-trips agent-resume across the kernel dialect 1ms | ||
| Error: Failed to load url ../src/agent-resume.js (resolved id: ../src/agent-resume.js) in /home/khaliqgant/Projects/AgentWorkforce/flows-worktrees/agent-resume/packages/sdk/tests/agent-resume.test.ts. Does the file exist? | ||
| ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 3 ⎯⎯⎯⎯⎯⎯⎯ | ||
| CompileError: spec compile failed: | ||
| CompileError: spec compile failed: | ||
| CompileError: spec compile failed: | ||
| Test Files 2 failed (2) | ||
| Tests 3 failed | 46 passed (49) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| $ (cd packages/sdk && npm run typecheck && npm run build && npm run typecheck:tests) | ||
| $ npm run typecheck | ||
| > @relayflows/sdk@2.0.42 typecheck | ||
| > tsc --noEmit && tsc -p tsconfig.type-tests.json | ||
|
|
||
| exit=0 | ||
| $ npm run build | ||
| > tsc && node scripts/make-cli-executable.mjs | ||
|
|
||
| $ npm run typecheck:tests | ||
|
|
||
| > @relayflows/sdk@2.0.42 typecheck:tests | ||
| > tsc -p tsconfig.tests.json |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,15 @@ | ||||||
| # Supersedes the earlier capture, whose output filter (Test Files|Tests|×) hid a collection-time FAIL: the verb-field lint, fixed in aa115352. | ||||||
| # RELAYFLOWD_BIN points at this branch's kernel build (kernel/target/debug/relayflowd); the ambient value named a missing toolchain binary. | ||||||
| $ (cd packages/sdk && RELAYFLOWD_BIN=$PWD/../../kernel/target/debug/relayflowd npx vitest run) | grep -E "FAIL|Test Files|Tests | × " | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: This pipeline exits with Prompt for AI agents
Suggested change
|
||||||
| ✓ built flows CLI against live relayflowd > hn-monitor analyze-story FAILS verification when the CLI omits required schema fields 340ms | ||||||
| FAIL tests/authored-node-runtime.test.ts [ tests/authored-node-runtime.test.ts ] | ||||||
| Test Files 1 failed | 272 passed | 1 skipped (274) | ||||||
| Tests 4278 passed | 20 skipped (4298) | ||||||
|
|
||||||
| # The one FAIL is environmental: the test pins bun 1.4.0 and this host has 1.4.2. | ||||||
| FAIL tests/authored-node-runtime.test.ts [ tests/authored-node-runtime.test.ts ] | ||||||
| AssertionError: expected '1.4.2' to be '1.4.0' // Object.is equality | ||||||
|
|
||||||
| Expected: "1.4.0" | ||||||
| Received: "1.4.2" | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| $ (cd packages/sdk && npx vitest run tests/agent-resume.test.ts tests/spec-parity.test.ts) | ||
| Test Files 2 passed (2) | ||
| Tests 75 passed (75) | ||
| $ (cd kernel && cargo test -p relayflowd-core) | ||
| test result: ok. 86 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.71s | ||
| test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s | ||
| test result: ok. 21 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s | ||
| test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s | ||
| $ node scripts/generate-json-schema.mjs && git diff --stat -- packages/schema | ||
| Generated packages/schema/flows.schema.json (74 definitions) | ||
| packages/schema/flows.schema.json | 10 ++++++++++ | ||
| 1 file changed, 10 insertions(+) | ||
| $ (cd packages/schema && bun run test) | ||
| 86 pass | ||
| 0 fail |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Missing session, real Claude CLI (2.x on this host): | ||
| $ claude -p --resume 00000000-0000-4000-8000-0000000000aa "hi" --output-format json | ||
| No conversation found with session ID: 00000000-0000-4000-8000-0000000000aa | ||
| exit=1 | ||
|
|
||
| # Resume from a different directory than the session was created in: | ||
| $ (cd A && claude -p "Remember the code word PELICAN-42. Reply only with OK." --output-format json) | ||
| A session: 1908508f-989e-4159-82b0-6a676c3d74d3 result: OK | ||
| $ (cd B && claude -p --resume 1908508f-989e-4159-82b0-6a676c3d74d3 "What was the code word? Reply with just it." --output-format json) | ||
| B session: 1908508f-989e-4159-82b0-6a676c3d74d3 result: 'PELICAN-42' error: False |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1453,6 +1453,11 @@ | |
| "description": "Directory the declared CLI is spawned in, as a path relative to the run\nroot — the flow-runner's working directory, which is also where the CLI\nruns when this is absent. Absolute paths, `.`, `..` and empty components\nare refused lexically by `flows check` and by the kernel; the worker that\nspawns the CLI additionally requires the symlink-free directory to exist\ninside the symlink-free run root. A declaration, not a sandbox: nothing\nstops a CLI from writing outside it. Not supported with\n`transport: 'relay'`, where the agent runs on a host this process cannot\nresolve. See docs/SURFACE.md.", | ||
| "type": "string" | ||
| }, | ||
| "resume": { | ||
| "title": "resume", | ||
| "description": "A CLI session id to continue: the `AgentResult.sessionId` an earlier step\nreported. Claude and Codex resume it in place of starting a new session;\nany other CLI refuses the step. 1-200 of A-Z a-z 0-9 . _ : -, starting\nwith a letter or digit. Not supported with `transport: 'relay'`, where the\nagent runs on a host whose session store this worker cannot see.", | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: This schema accepts any string even though its description specifies a 1–200-character session ID, so schema-based editors accept values that Prompt for AI agents |
||
| "type": "string" | ||
| }, | ||
| "transport": { | ||
| "title": "transport", | ||
| "description": "Dispatch transport (flows#385). `'direct'` (default) spawns the CLI as\na local subprocess. `'relay'` posts to agent-relay so the agent\nregisters as a first-class workspace participant.", | ||
|
|
@@ -2484,6 +2489,11 @@ | |
| "description": "Run-root-relative directory the attached worker spawns the CLI in. The\nkernel checks the shape and does no I/O: existence and containment are\ndecided by the worker, on the host that shares the agent's filesystem.", | ||
| "type": "string" | ||
| }, | ||
| "resume": { | ||
| "title": "resume", | ||
| "description": "CLI session id the worker resumes; the kernel checks its shape only.", | ||
| "type": "string" | ||
| }, | ||
| "transport": { | ||
| "title": "transport", | ||
| "description": "Dispatch transport (flows#385). Kernel passes through untouched;\nthe SDK worker selects between direct-spawn and agent-relay routing.", | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -13,6 +13,7 @@ const MODEL_PROBE_PROMPT = 'Reply with exactly RELAYFLOWS_MODEL_READY and nothin | |||||
| * inline shape in `cli-adapter.ts` — only the packaging changed. */ | ||||||
| export const codexAdapter: HeadlessAdapter = { | ||||||
| kind: 'codex', | ||||||
| resumable: true, | ||||||
|
|
||||||
| buildIdentification(): CliAdapterIdentification { | ||||||
| return { invocation: { args: ['login', 'status', '--help'], timeoutMs: 10_000 } }; | ||||||
|
|
@@ -36,22 +37,24 @@ export const codexAdapter: HeadlessAdapter = { | |||||
| return providerUsageLimited(output) ? { cause: 'provider_usage_limited' } : undefined; | ||||||
| }, | ||||||
|
|
||||||
| buildAgentInvocation(instruction: string, model?: string): CliInvocation { | ||||||
| buildAgentInvocation(instruction: string, model?: string, resume?: string): CliInvocation { | ||||||
| return { | ||||||
| args: [ | ||||||
| // Real steps must retain Codex's native session under CODEX_HOME (or | ||||||
| // ~/.codex). Hosted Relayflow teardown captures that provider history | ||||||
| // and uploads it to Relayhistory; --ephemeral silently leaves nothing | ||||||
| // for the bounded flush to capture. Readiness probes above stay | ||||||
| // ephemeral because they are diagnostics, not workflow steps. | ||||||
| 'exec', '--skip-git-repo-check', | ||||||
| // `exec resume <id>` continues a recorded thread with the same flags. | ||||||
| ...(resume === undefined ? ['exec'] : ['exec', 'resume']), '--skip-git-repo-check', | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Codex resume stays scoped to the current directory, so it cannot find a session created under another step's Prompt for AI agents
Suggested change
|
||||||
| // Agent-mode is where the flow explicitly delegates code changes to | ||||||
| // the CLI. Without this flag codex prompts for approval on every | ||||||
| // write, gets nothing (no TTY), and completes "successfully" without | ||||||
| // touching files — the dogfood no-op failure mode. LLM-mode stays | ||||||
| // read-only and does NOT get the bypass. | ||||||
| '--dangerously-bypass-approvals-and-sandbox', | ||||||
| ...(model === undefined ? [] : ['--model', model]), | ||||||
| ...(resume === undefined ? [] : [resume]), | ||||||
| ...promptOperand(instruction), | ||||||
| ], | ||||||
| timeoutMs: 0, | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2:
first.sessionIdis optional, so this call silently starts a fresh session when the CLI reported no id. Guard the value and fail or skip the follow-up rather than presenting it as resumed.Prompt for AI agents