Skip to content

feat(push): label assistant versions with the pusher, commit and changed fields - #79

Merged
dhruva-vapi merged 2 commits into
mainfrom
dr/assistant-version-labels
Oct 12, 2026
Merged

dhruva-vapi merged 2 commits into
mainfrom
dr/assistant-version-labels

Conversation

@dhruva-vapi

@dhruva-vapi dhruva-vapi commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Value

V.A.L.U.E. tier: small. It is a behavior change: push sends one extra PATCH per published assistant version. Linear: PRISM-2038.

  • Problem: On an org with assistant versioning, each gitops push publishes a new assistant version. The platform records no author on a version written with a private API key (createdBy is null), and the audit log only covers dashboard users. So nobody can tell who published a version, from which commit, or what changed.
  • Who it affects: Teams that manage production assistants with gitops and need to trace a live version back to a person and a change. This matters most during a traffic split, when several versions take calls at once.
  • What changes:
    • After a push publishes a new assistant version, push sends PATCH /assistant/:id/versions/:version with:
      • versionName: gitops <commit>[+dirty] by <actor>
      • versionDescription: the actor, the commit, and the dotted paths of the changed fields (model.messages, voice.voiceId), within the API's 80 and 500 character limits
    • Actor: VAPI_GITOPS_ACTOR, else github:$GITHUB_ACTOR, else git config user.email. It is self-reported.
    • Changed fields: the diff of the dashboard payload fetched before the PATCH (the drift check's GET, reused) against the PATCH response. Server-managed keys are ignored.
    • Skips: dry runs, and pushes the platform deduplicated (latestVersion did not move). A failed label logs a warning and never fails the push.
    • Docs: docs/learnings/sync-behavior.md gets an "Assistant version labels" section.
  • Definition of done: a push that edits an assistant's prompt shows a version in the dashboard history named gitops <sha> by <email>, described with Changed: model.messages. It fails if a push errors because of the label, or if a no-op push labels anything.
  • Out of scope:
    • Squads: the API has no squad version metadata endpoint.
    • Authenticated attribution: storing the API key id on version rows is a platform change in VapiAI/vapi.

Small edit since first push: rebased onto current main, preserving both reference validation and version labeling, and sorted the imports.

Evidence of value

  • 10 new unit tests in tests/version-metadata.test.ts cover the field diff, the server-key filter, truncation within the API limits, and the actor resolution order.
  • Live run on a dev org (2026-10-06), using a throwaway assistant that was deleted afterwards:
    • create → v1 named gitops 6eeae32+dirty by …, described Created by gitops.
    • prompt and first-message edit → v2 described Changed: firstMessage, model.messages
    • a second push with no edits published no v3
    • createdBy was null on both versions, which confirms the gap this PR fills

Testing plan

  • npm test: 546 pass, 0 fail (10 new)
  • npx tsc --noEmit: clean
  • Live: npm run push -- <sandbox-org> after editing one assistant prompt, on a versioning-enabled org. Confirm the new version's name and description in GET /assistant/:id/versions/:version, and that a second push with no edits adds no label.

…ged fields

A push that publishes an assistant version now sets its versionName and
versionDescription to the pusher, the commit, and the dotted paths of the
fields that changed. API-key writes record no author on the version, so
this is the only trace of who published it.
@dhruva-vapi
dhruva-vapi force-pushed the dr/assistant-version-labels branch from 6eeae32 to b1ce995 Compare October 12, 2026 20:24
@dhruva-vapi
dhruva-vapi marked this pull request as ready for review October 12, 2026 20:24

Copy link
Copy Markdown
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@scott-lowe-vapi scott-lowe-vapi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Tests pass (10/10) and tsc --noEmit is clean. The labeling trigger is safe: it only labels when latestVersion changes, so deduplicated pushes and orgs without versioning are skipped. Reusing the drift check's GET for the "before" payload is a nice touch.

Non-blocking suggestions:

  1. Memoize versionActorResolve. It spawns 3–5 git subprocesses per assistant, but the actor and commit can't change mid-push.
  2. Possible noisy diffs. changedFieldPaths compares a GET payload with a PATCH response via JSON.stringify. If key order or returned fields differ between the endpoints, it will report changes that didn't happen. A sorted-key stringify would cover the ordering case.
  3. Silent skip when the GET fails. If platformPayloadForSnapshot stays undefined, the version gets no label at all. Labeling it with "fields unknown" would keep the audit trail complete.
  4. Double space in changedFieldsLine. When even the first path doesn't fit (e.g. a long actor name), the output is Changed: (+N more).
  5. Email visibility. The local fallback to git config user.email puts emails in version metadata that the whole org can see. Consider trying user.name first.
  6. Nits. The { ...metadata } spread is unnecessary, and the countAuthoredAssistantRefs reformat is unrelated to this PR.

dhruva-vapi commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor Author

Merge activity

  • Oct 12, 8:57 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Oct 12, 8:57 PM UTC: @dhruva-vapi merged this pull request with Graphite.

@dhruva-vapi
dhruva-vapi merged commit 28966fe into main Oct 12, 2026
7 checks passed
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.

2 participants