automations: feat: add shared automations protocol - #393
automations: feat: add shared automations protocol#393Ulugbek Abdullaev (ulugbekna) wants to merge 8 commits into
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 935e37c8-2b68-40b1-9273-f195cb3af9a0
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 935e37c8-2b68-40b1-9273-f195cb3af9a0
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 935e37c8-2b68-40b1-9273-f195cb3af9a0
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1131c2f6-bcd0-4012-9265-fdb2685179e7
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1131c2f6-bcd0-4012-9265-fdb2685179e7
isClientDispatchable did not accept automation or automation-run actions, so servers could not use it to reject server-only actions arriving on the new automation channels. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1131c2f6-bcd0-4012-9265-fdb2685179e7
Collapse recurring schedules to the specified five-field AHP cron format, document the automation and run protocol surfaces, expand the guide, and regenerate every client and schema. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1131c2f6-bcd0-4012-9265-fdb2685179e7
| /** Optional host-resolved execution context. */ | ||
| runtime?: AutomationRuntimeState; | ||
| /** Operations currently permitted for this automation. */ | ||
| operations: AutomationOperation[]; |
There was a problem hiding this comment.
AI Review: operations is documented as authoritative and able to change over time, but this channel has no action/reducer path that updates it. A subscribed client can therefore retain stale permissions when run state changes whether update/dispose/run is allowed. Please add an observable replacement action (and consider runtime if it is also live), or define another synchronization mechanism.
| 'invokeChangesetOperation': { params: InvokeChangesetOperationParams; result: InvokeChangesetOperationResult }; | ||
| 'listAutomations': { params: ListAutomationsParams; result: ListAutomationsResult }; | ||
| 'listAutomationTriggerDefinitions': { params: ListAutomationTriggerDefinitionsParams; result: ListAutomationTriggerDefinitionsResult }; | ||
| 'createAutomation': { params: CreateAutomationParams; result: null }; |
There was a problem hiding this comment.
AI Review: An import retry with the same AutomationImportIdentity may resolve to a previously imported automation independently of the newly requested URI, but this command returns null. The caller cannot discover the canonical existing resource in that case. Could createAutomation return the resolved automation URI?
| if (action.nextCursor === undefined) { | ||
| delete next.runsNextCursor; | ||
| } else { | ||
| next.runsNextCursor = action.nextCursor; |
There was a problem hiding this comment.
AI Review: automation/runsLoaded does not identify the cursor it consumed, yet it unconditionally replaces runsNextCursor. If requests for C1 and C2 overlap and their broadcast actions arrive out of order, a late C1→C2 page can overwrite C2→C3 and move pagination backwards. Please carry the consumed cursor and advance only on a match, or explicitly require serialized loads.
| protocolVersion: shared.protocolVersion, | ||
| serverSeq: shared.serverSeq, | ||
| defaultDirectory: shared.defaultDirectory, | ||
| automations: shared.automations, |
There was a problem hiding this comment.
AI Review: snapshotHandle exposes shared.automations by reference while the API says snapshots should be treated as immutable. readonly automations only prevents replacing the property; a consumer can mutate nested capability fields and thereby alter later snapshots/runtime-owned state. Please clone this small capability graph when constructing the snapshot.
| view: { turns: 30 }, | ||
| }); | ||
|
|
||
| test('root automation catalogue notifications reach subscriptions', async () => { |
There was a problem hiding this comment.
AI Review: This test is declared inside an already-running async test and its returned promise is not awaited. The parent can finish and cancel/skip these assertions, so the intended notification coverage is unreliable. Please move it to top level (or make it an explicitly awaited subtest).
| }); | ||
|
|
||
| it('inherits request metadata from BaseParams', () => { | ||
| it('preserves automation schedule restrictions', () => { |
There was a problem hiding this comment.
AI Review: This replaces the existing BaseParams._meta inheritance regression test rather than adding schedule coverage alongside it. The new automation assertion should not remove unrelated schema-generator coverage; please restore the _meta test as a separate case.
| export interface AutomationTriggeredRunCause { | ||
| kind: AutomationRunCauseKind.Trigger; | ||
| /** Matches the stable {@link AutomationTrigger.id} in the definition. */ | ||
| triggerId: string; |
There was a problem hiding this comment.
AI Review: Is triggerId alone sufficient immutable provenance after the owning definition is revised? A trigger can be removed or its ID reused with different semantics, leaving historical runs ambiguous. Consider recording the automation definition revision (or an immutable trigger snapshot) in the cause.
| } | ||
| ``` | ||
|
|
||
| `requestId` is durable. Retrying with the same automation and request id |
There was a problem hiding this comment.
AI Review: What retention guarantee does “durable� impose on the (automation, requestId) → run mapping? Run history is explicitly bounded, so if the mapping is pruned with the run, a sufficiently late retry can create a duplicate. Please define whether idempotency survives history pruning and, if not indefinitely, its minimum retention window.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1131c2f6-bcd0-4012-9265-fdb2685179e7
Summary
Add shared, host-owned Automations to Agent Host Protocol.
The protocol now represents:
AHP documentation standard.
This lets multiple AHP clients connected to the same authority share one
definition, scheduler, run claim, and run history instead of independently
scheduling duplicate sessions.
Protocol model
The change introduces two state channels:
ahp-automation:Owns the durable recipe:
Definitions use optimistic revisions.
updateAutomation.expectedRevisionrejects stale writes rather than overwriting a newer client.
ahp-automation-run:Owns one task-level invocation:
Runs may contain multiple sessions, supporting retries or workers without
encoding the current one-session local implementation into the protocol.
Ordinary session/chat channels remain authoritative for transcripts, tools,
confirmations, and file changes.
Triggers
Definitions contain a trigger collection:
IANA time zone;
steps, and Unix day-of-month/day-of-week matching;
schema-defined config.
Hosts describe dynamic event triggers through
listAutomationTriggerDefinitions. This allows a managed authority such asMission Control to expose repository events without hard-coding
GitHub-specific trigger enums into AHP.
Capabilities and commands
initialize.automationsadvertises execution lifetime, creation, schedulesupport and an optional minimum interval, cancellation, schedule preview, and
retained history limits.
Execution lifetime describes availability:
hostLifetime: scheduling runs while this host process is alive;managed: scheduling continues independently as a managed service.The change adds:
listAutomations;listAutomationTriggerDefinitions;createAutomation;updateAutomation;disposeAutomation;runAutomation;fetchAutomationRuns;previewAutomationSchedule;runAutomation.requestIdis a durable idempotency key, so repeating the samemanual request returns the same run URI.
Capability fields such as
create?: {}andrunCancellation?: {}arepresence markers. Objects are used instead of booleans so optional detail can
be added later without changing the wire type.
Generated surfaces
The source contract is propagated through:
The automation state, action, command, capability, notification, run, and
session-provenance types now carry detailed normative docblocks. The expanded
guide covers authority, cron semantics, event discovery, revisions, migration,
run lifecycle, cancellation, retention, multi-client reconciliation, and
security.
The branch is rebased onto current main. Regeneration also incorporates the
current optional
BaseParams._metafield into automation command types andschemas.
Deliberate boundaries
replicate independent hosts.
managed/cloud execution can be represented by separate authorities.
Validation
npm run generatenpm testnpm run docs:buildCompanion implementation
A companion draft VS Code PR implements the local Agent Host scheduler,
persistence, transport integration, Agents-window projection, and automatic
migration from the retired renderer-owned automation stores.
Companion VS Code draft PR: microsoft/vscode#330463