Skip to content

Add automation disable conditions for run limits and end dates - #461

Merged
Ben Villalobos (benvillalobos) merged 8 commits into
mainfrom
benvillalobos-automation-run-limits-investigation
Sep 24, 2026
Merged

Ben Villalobos (benvillalobos) merged 8 commits into
mainfrom
benvillalobos-automation-run-limits-investigation

Conversation

@benvillalobos

@benvillalobos Ben Villalobos (benvillalobos) commented Sep 22, 2026 •

Copy link
Copy Markdown
Member

Summary

Adds optional automation disable conditions for a scheduled-run cap (afterRuns), a deadline (afterDate), or both, plus a durable host-owned scheduled-run usage counter. Conditions combine with logical OR: the first condition met disables automatic scheduling.

Protocol surface

  • AutomationDisableConditionKind defines AfterRuns = 'afterRuns' and AfterDate = 'afterDate'.
  • AutomationDisableCondition is the discriminated union of AutomationAfterRunsCondition (kind: AutomationDisableConditionKind.AfterRuns, max: number, a positive integer) and AutomationAfterDateCondition (kind: AutomationDisableConditionKind.AfterDate, date: string, an ISO 8601 timestamp).
  • AutomationDefinition.disableConditions?: AutomationDisableCondition[] contains { kind: "afterRuns", max } and/or { kind: "afterDate", date }. Each kind may appear at most once. An absent field or [] means no automatic disable conditions.
  • AutomationDefinitionPatch.disableConditions?: AutomationDisableCondition[] uses the existing automation/updateRequested action. Omission leaves conditions unchanged, a supplied array replaces all conditions, and [] clears them. No dedicated set/clear action or sentinel value is needed.
  • AutomationEntry.runCount?: number is authoritative usage for the current afterRuns allowance, not a lifetime total. Clients never maintain their own counter or reconstruct it from the bounded run-history window.
  • No disable-reason field or run-limit-specific capability flag is added.

Behavior

  • Meeting either condition sets enabled to false and retains the definition and its conditions. Manual runs neither consume the allowance nor become blocked by these conditions.
  • The host counts scheduled runs atomically on admission; cancellation or failure does not refund a consumed run.
  • Adding afterRuns when absent, or transitioning from disabled to enabled with an afterRuns condition, starts a fresh allowance. Editing an existing cap, changing only the afterDate condition, or reordering conditions preserves usage. Removing afterRuns removes the count.
  • Clearing conditions does not itself re-enable an automation. An expired afterDate condition remains in the definition, so clients should warn before re-enabling.
  • Hosts must reject duplicate condition kinds without changing state. Generated JSON Schemas enforce uniqueness by discriminant, including duplicates with different values, and require a positive-integer run cap.

Implementation

  • Registers the condition union in the hand-written .NET, Go, Kotlin, Rust, and Swift generators and regenerates all six client mirrors plus schemas and reference docs.
  • Preserves the distinction between omitted and explicitly empty arrays in Go so [] reliably clears conditions.
  • Extends shared wire and reducer fixtures for single and combined conditions, omitted edits, explicit clearing, and authoritative state replacement.
  • Updates the automations guide and adds a changelog fragment for the spec and all clients.

Compatibility

The new definition, patch, and entry fields are optional. PROTOCOL_VERSION remains 0.9.0. Existing update requests and authoritative automation/set broadcasts carry the change; no new ActionType or reducer behavior is required. This supersedes the earlier unmerged scheduledRunLimit / set-or-clear patch design in this draft.

Validation

  • npm run generate regenerated all six client mirrors, schemas, and reference docs.
  • Root npm test: 466 passing; includes typecheck, lint, schema checks, generated-output verification, changelog-fragment verification, and 100% reducer coverage. Schema tests also reject the superseded condition discriminants and payload names.
  • Documentation: npx vitepress build docs passed.
  • TypeScript: client typecheck and wire round-trip corpus passed.
  • Go: go test ./ahptypes ./ahp -count=1 passed.
  • Rust: library tests and the shared wire round-trip corpus passed.
  • Kotlin: FixtureDrivenReducerTest and RoundTripCorpusTest passed with JDK 17.
  • .NET: 550 passing tests.
  • Swift sources were regenerated and generated-output verification passed; native compilation/tests were not run because a Swift toolchain is unavailable locally.

Adds AutomationDefinition.scheduledRunLimit (optional cap on scheduled runs),
AutomationEntry.scheduledRunCount (host-owned usage), an
AutomationScheduledRunLimitPatch discriminated union (set/clear/omit) on the
definition patch, and an AutomationCapabilities.scheduledRunLimits presence
capability. Additive and optional; PROTOCOL_VERSION unchanged. Union registered
in all five generators; all six clients + schema regenerated.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d158af7a-b861-4b5a-9f66-a0501b92312a
Comment thread types/channels-automation/actions.ts Outdated
Comment thread types/channels-automation/state.ts Outdated
Comment thread types/common/commands.ts Outdated
@jackfreemanceo-dotcom

jackfreemanceo-dotcom commented Sep 23, 2026 via email

Copy link
Copy Markdown

@jackfreemanceo-dotcom

jackfreemanceo-dotcom commented Sep 23, 2026 via email

Copy link
Copy Markdown

Replace the scheduled-run cap patch union with disableConditions arrays, enforce unique condition kinds in schemas, preserve empty-array clearing across clients, and update documentation and conformance fixtures.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d158af7a-b861-4b5a-9f66-a0501b92312a
@benvillalobos Ben Villalobos (benvillalobos) changed the title Add scheduled run limits to the automation channel Add automation disable conditions for run limits and end dates Sep 23, 2026
Use MaxRuns/maxRuns for the enum and wire discriminant, rename AutomationMaxRunsCondition consistently, and refresh generated clients, schemas, documentation, and fixtures.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d158af7a-b861-4b5a-9f66-a0501b92312a
Comment thread types/channels-automation/state.ts Outdated
Comment thread types/channels-automation/state.ts Outdated
Comment thread types/channels-automation/state.ts
Comment thread types/channels-automation/state.ts Outdated
Use afterRuns/max, afterDate/date, and runCount consistently across the protocol, generated clients, fixtures, and documentation. Preserve the existing allowance and disable-condition semantics.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread types/channels-automation/state.ts Outdated
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@benvillalobos
Ben Villalobos (benvillalobos) merged commit 296b25e into main Sep 24, 2026
9 checks passed
@benvillalobos
Ben Villalobos (benvillalobos) deleted the benvillalobos-automation-run-limits-investigation branch September 24, 2026 21:08
Sukanth Gunda (sukanth) added a commit to sukanth/agent-host-protocol that referenced this pull request Sep 25, 2026
Upstream landed microsoft#461 (scheduled automation run limits), which again touches
`scripts/generate-csharp.ts` and adds round-trip fixtures numbered 045-050.
The merge itself is clean, and regeneration shows the two generator changes
still compose: upstream's new `AutomationAfterRunsCondition` /
`AutomationAfterDateCondition` records pick up this branch's pinned
discriminator automatically, so types added after that fix do not
reintroduce the zero-value defect.

Last tick this branch renumbered its fixtures to dodge a collision with
microsoft#450. That turns out to be a treadmill worth stepping off: `upstream/main`
already carries nine duplicate numeric prefixes (019, 030, 031, 041, and
045-049), several created by microsoft#461 and microsoft#450 colliding with each other. Prefixes
are assigned per-branch, so any parallel PR can take a number, and chasing
that costs a rename plus a full CI run every time.

Rather than renumber again, this makes the references stable: the corpus doc
and the fixture cross-references now name fixtures by filename instead of
"fixture NNN", with a note recording why. The fixture files themselves are
left alone, matching how the repository already tolerates shared prefixes.

Verified on the merged tree: root suite 471 pass, .NET 0 failed, plus Rust,
Go, TypeScript, Kotlin, and Swift green.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants