Skip to content

flows: Ctx.agent has no cli/model options in TypeScript — SURFACE §2 rule 6 gap #310

Description

@khaliqgant

Spec citation — SURFACE.md §2 rule 6 (lines 72–96)

- agent: Review this diff for security issues.        # 1. anonymous
agents:
  reviewer: { cli: claude, model: claude-sonnet-4-6 } # 2. named — explicit and reusable

The declarative named-agent schema in this slice is exactly { cli, model }...
Explicit step values win independently: step cli/model → named
declaration → the existing flow/project CLI default. Model has no
flow/project default.
— docs/SURFACE.md:74-92

Current state (2026-09-11, main @ 3c10e99b2accfd51e94dd6d4f90ca16187e4e724)

The declarative (YAML/JSON) side of this rule is fully shipped: AgentStepSpec
has real cli?/model? fields (packages/sdk/src/spec.ts:184,191), and
preflight.ts resolves them in the documented order — step → named agent →
flow → project (packages/sdk/src/preflight.ts:277-280).

The TypeScript authoring surface has none of this:

  • Ctx.agent's options type is { task: string; workspace?: string }
    (packages/surface/src/context.ts:10-13) — no cli, no model.
  • FlowHeader has no agents map and no flow-level cli either
    (packages/surface/src/flow.ts:4-9; the allowlist enforced by
    assertFlowHeader at flow.ts:148-181 is exactly identity, memory,
    budget, tools, workspace).
  • authored-flow-executor.ts's lowerAgent builds the compiled step with
    no cli/model field at all (authored-flow-executor.ts:196-209) and
    says so explicitly in its own comment: "CLI selection goes through the
    project's flows.json default... an authored flow has no way to declare
    one today"
    (authored-flow-executor.ts:169-176).

Net effect: every f.agent call in a TypeScript flow shares one project-wide
CLI (flows.json's cli) with no way to override it per call, and has no
way to pin a model at all — not even the flow/step defaults YAML already has.
Confirmed by writing the Relayflows product docs against real source and
real captured CLI output (agentrelay.com PR #66): the TypeScript example
for "a whole flow" cannot express what the equivalent YAML example expresses
inline on the step (cli: claude, model: claude-sonnet-4-6) — the docs had
to fall back to explaining flows.json's single project default instead.

(Note: #300's "What's shipped" section claims FlowHeader.agents TS types
are already in place — that's not accurate against current source; see my
correction there. This issue is the narrower, prerequisite gap: a single
call's cli/model, with no named-agent map or use: composition
required.)

Scope

  1. Ctx.agent options. Add optional cli?: string and model?: string
    to AgentOptions in packages/surface/src/context.ts, mirroring
    AgentStepSpec's fields exactly.
  2. Lowering. authored-flow-executor.ts's lowerAgent passes
    options.cli/options.model through onto the compiled step spec when
    present, the same way options.workspace is passed through today.
  3. Resolution order. No change needed to preflight.ts — an authored
    step with an explicit cli/model already takes the source: 'step'
    branch (preflight.ts:277); this issue only adds the field an author can
    set to reach it.
  4. Docs/tests. Surface + SDK test coverage mirroring the existing
    AgentStepSpec.cli/.model cases; once shipped, the Relayflows docs'
    TypeScript examples can show the CLI/model inline on the call instead of
    pointing at a project-wide flows.json default.

Non-goal: named-agent maps or use:-based flow composition in TypeScript
(that's #300's scope). This issue is just parity for the single-call
cli/model override YAML already has.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions