Repository navigation
feat: AGENTS.md prompt support (closes #732) - #1161
Cedric Vidal (cedricvidal) wants to merge 14 commits into
Conversation
…rage Foundation for AGENTS.md prompt support (#732): typed task prompts ('task' | 'agents.md') with content-hash ids, size-based body storage (small bodies inline, large bodies uploaded to blob and referenced via contentBlobUrl), a prompt client/resolver, typed prompt-feature extraction, and request schema fields (agentsMd, agentsMdParentIds, agentsMdPromptId). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ature routes Wire AGENTS.md support into the API (#732): create-request accepts agentsMd (raw text) and findOrCreates an 'agents.md'-typed prompt, storing agentsMdPromptId and agentsMdParentIds; task-prompt and prompt-feature routes become type-aware and expose a prompt content endpoint that resolves inline or blob-backed bodies. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The shared queue processor resolves the agentsMdPromptId body (downloading from blob storage when needed) and writes <workspace>/AGENTS.md once before the first turn. Fails the run loudly if the prompt id is set but cannot be resolved, rather than silently running the baseline (#732). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ture commands Add CLI parity for AGENTS.md support (#732): 'run submit --agents-md <text|@file>' submits a run with an AGENTS.md prompt, and the task-prompt and prompt-feature commands gain a --type option to manage 'agents.md' prompts alongside task prompts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add portal surfaces for AGENTS.md support (#732): an AGENTS.md field on the Submit Run page, AGENTS.md display on Run Detail, and type-aware task-prompt and prompt-feature views/pickers for 'agents.md' prompts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…h API/CLI snapshots Document the AGENTS.md delivery flow and size-based prompt storage (PROMPT_INLINE_MAX_BYTES) in app-design.md and ENV_VARIABLES.md, and regenerate the OpenAPI and CLI command snapshots to reflect the agentsMd fields and --agents-md/--type options (#732). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
task-prompt.ts and prompt-feature.ts imported each other (task-prompt
needs PromptFeatureResultSchema; prompt-feature needs PromptTypeSchema),
forming a cycle. At ESM runtime the schemas barrel evaluates
prompt-feature first, so task-prompt's `z.array(PromptFeatureResultSchema)`
ran while the binding was still in the temporal dead zone, crashing the
API on boot with a ReferenceError. tsc and vitest tolerated the cycle, so
it only surfaced under the API's tsx runtime; under vitest the unresolved
binding also silently emitted an empty OpenAPI `features.items: {}`.
Extract PromptTypeSchema into its own neutral prompt-type.ts that both
modules depend on, removing the back-edge from prompt-feature to
task-prompt. task-prompt re-exports PromptTypeSchema so the barrel surface
and existing consumers are unchanged. Regenerate the OpenAPI snapshot,
which now correctly refs PromptFeatureResult.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…New Run The AGENTS.md input was always rendered as a prominent 6-row textarea even when unused. Make it discreet behind an "Add AGENTS.md" trigger that unveils a bordered card, mirroring the existing Codebase disclosure. Inside the card, add a TaskPromptPicker(type="agents.md") so an existing agents.md prompt can be looked up from the prompt library, just like the Task and gate prompts; selecting one fills the editor and the API dedups it by content on submit. Also restore AGENTS.md when prefilling from a recent run (resolve agentsMdPromptId to text) and surface an "AGENTS.md" chip in the settings summary. TaskPromptPicker previously imported the gates-only PromptType and indexed GATE_METADATA[type] for its placeholder, which has no agents.md entry. Switch to the broad PromptType from @/types and use promptTypeLabel(type) so the non-gate type renders safely; identical output for gate types. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Runs submitted with an AGENTS.md create an 'agents.md' task prompt, but the Prompt Library hid it: TaskPromptStore.getAll excludes NON_GATE_PROMPT_TYPES from the default (unfiltered) list. That guard is right for the report-template trigger picker, so instead of flipping the default this adds an opt-in 'includeNonGate' flag that the Prompt Library uses to list agents.md prompts alongside task/gate prompts. The library also gains an AGENTS.md type filter and create option; the CLI 'task-prompt list' gets a matching --include-non-gate flag. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The left-nav Library entry for /task-prompts pointed at the Prompt Library but was labeled 'Tasks', which read as a task list. Rename it to 'Prompts' to match the page title and the fact that it now manages task, gate, and AGENTS.md prompts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The task-prompt list previously hid non-gate types (agents.md) from the default unfiltered list, requiring an opt-in flag to surface them. Remove that exclusion entirely so the Prompt Library, report-template pickers, API, and CLI always return every prompt type. Drops the includeNonGate option/flag/query param across the store, API route, portal client, and CLI, and regenerates the OpenAPI and CLI snapshots accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The detail page hard-coded "Task Prompt" / "Task Text", which is wrong for non-gate prompts such as AGENTS.md. Render the identity card title from the prompt type (e.g. "AGENTS.md Prompt", "Select Prompt") and rename the body card to the generic "Prompt Text". Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds focused unit tests for the portal changes in the AGENTS.md feature
that previously had no coverage:
- Layout: the Library nav item is labelled 'Prompts' and links to
/task-prompts (renamed from 'Tasks').
- TaskPromptDetail: the heading adapts to the prompt type
('AGENTS.md Prompt' / 'Select Prompt', legacy untyped falls back to
'Select Prompt') and the body card is the generic 'Prompt Text'.
- TaskPromptPicker: the AGENTS.md library lookup scopes the query to
type=agents.md, fills the field with the selected prompt text, and
shows an empty state when there are no matches.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Address review feedback: the GET /task-prompts/:id/content endpoint returns any prompt body by ID with no authorization check, consistent with the API's current no-auth/no-tenancy model. Since prompts are globally content-addressed and deduplicated via findOrCreate, document that this assumes a trusted-network, single-tenant deployment and must be revisited if auth/multi-tenancy lands. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Original author: @github-actions[bot] Test Results (Node.js 22)test: Run #2036
🎉 All tests passed! |
|
Original author: @github-actions[bot] Test Results (Node.js 22)test: Run #2043
🎉 All tests passed! |
|
Original author: @github-actions[bot] Test Results (Node.js 22)test: Run #2044
🎉 All tests passed! |
|
Original author: @github-actions[bot] Test Results (Node.js 22)test: Run #2045
🎉 All tests passed! |
|
Original author: @github-actions[bot] Test Results (Node.js 22)test: Run #2046
🎉 All tests passed! |
|
Original author: @github-actions[bot] Test Results (Node.js 22)test: Run #2051
🎉 All tests passed! |
|
Original author: Wassim Chegham (@manekinekko) LGTM. |
|
Original author: Cedric Vidal (@cedricvidal) Original review: COMMENTED |
|
Original author: Wassim Chegham (@manekinekko) Worth a note here: this |
|
Original author: Cedric Vidal (@cedricvidal) Good call. Added a comment on the route in 61bf19e4 spelling out the trusted-network / single-tenant assumption and flagging that the content-addressed dedup store is not tenant-safe, so this must be revisited if auth/multi-tenancy ever lands. Agreed it's not a regression given the API has no auth model today. |
Original author: Cedric Vidal (@cedricvidal)
Why
Benchmark runs had no way to seed a project-level
AGENTS.mdinstruction file into the agent's workspace. Issue #732 asks for first-class support so a run can carry anAGENTS.mdthat the worker writes to the workspace root before the agent starts, and so those instruction files can be managed and feature-extracted like other prompts.This PR is the AGENTS.md slice extracted from the larger GEPA optimizer PR (#1031). It deliberately contains only the AGENTS.md feature and the size-based blob storage that underpins it.
experimentId, experiment grouping, the experiment migration, and thegepa-optimizerapp stay in #1031.Video walkthrough
agents-md-walkthrough.mp4
What changed
Typed task-prompt model +
agents.mdtype (shared). Task prompts now carry atype(PromptType = GateId | "agents.md"). AGENTS.md content is stored as anagents.md-typed task prompt, deduplicated by content viafindOrCreate, so reusing the same body reuses the same prompt. Prompt-feature extraction is type-scoped (task prompts get task features; AGENTS.md prompts getagents.mdfeatures).Size-based blob storage (shared). Prompt bodies above
PROMPT_INLINE_MAX_BYTESare offloaded to blob storage with acontentBlobUrl, and resolved transparently through a/contentendpoint. This is the foundation for large AGENTS.md bodies; small bodies stay inline as before.Worker delivery. Before a run starts, the worker writes the resolved AGENTS.md to
<workspace>/AGENTS.md.Surfaces. API request handling (
agentsMdresolves to anagents.mdprompt) plus typed task-prompt and prompt-feature routes; CLI--agents-mdrun flag and type-awaretask-prompt/prompt-featurecommands; portal support to submit an AGENTS.md with a run, view it on a run, and manageagents.mdprompts.New Run UX. The AGENTS.md field is now discreet: hidden behind an "Add AGENTS.md" trigger that unveils a card (mirroring the existing Codebase disclosure), and it can look up an existing
agents.mdprompt from the library via the same picker used for task and gate prompts.Worth a careful look
fix(shared): break task-prompt/prompt-feature schema import cycle(ccfce549).task-prompt.tsandprompt-feature.tsimported each other, which threw a temporal-dead-zoneReferenceErrorunder the API'stsxruntime on boot (tsc and vitest tolerated the cycle, so it passed CI but crashed the running API). The fix extractsPromptTypeSchemainto a neutralprompt-type.tsthat both modules depend on, removing the back-edge. The cycle had also silently emitted an emptyfeatures.items: {}in the OpenAPI spec; it now correctly refsPromptFeatureResult(regenerated snapshot).openapi-snapshot,cli-commands) were regenerated, not hand-edited.Verification
pnpm -r buildclean.apps+packages(excluding snapshots): noexperimentId/gepa/GEPA.Closes #732