feat(agent): replace + delete endpoints for agent-tier sources - #69
Merged
Conversation
…ow with audit + SourceRemoved event
…atory Idempotency-Key
…_not_found" This reverts commit b17bdf1.
…404 on PUT/DELETE
This was referenced Jul 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What it delivers
Two new agent-tier endpoints on
/api/v1/agent/sources/{source_id}, both gated byX-Agent-Tokenwith scopeagent.sources:ingestand a mandatoryIdempotency-Key:PUT— replaces a document in place by stable id. Delegates to the existingReplaceSourceCommand->IntakeService.replacepath (same as the user-tier PUT): the intake pipeline re-runs against the new bytes and the chunks + dense vectors are replaced under the samesource_id.content_base64is required (URL fetch not supported, mirroring the user-tier PUT). Returns the updatedSourceRecord(200); unknown ids within the tenant/workspace scope return 404.DELETE— removes a source via a new minimal removal path (RemoveSourceCommand->IntakeService.remove): purges the BM25 rows + dense vectors (IndexService.remove_for_source), deletes the chunk rows and the source row within the tenant/workspace scope, records asource.removedaudit entry, and publishes aSourceRemovedEDA event consistent withSourceIngested/SourceReplaced. Returns 204; unknown ids return 404. Object-store originals are not touched, and no user-tier DELETE is exposed.Both routes replay-cache their responses under route-specific dedup scopes (
agent.sources:replace/agent.sources:delete), so retries return the original response without re-dispatching — a retried DELETE does not surface a spurious 404.Also included: regenerated OpenAPI snapshot, CHANGELOG entries under Unreleased, and unit tests covering happy paths, missing-key rejection, replay short-circuit, scope refusal, 404s, and the purge ordering (vectors are deleted before the chunk rows so external stores cannot leak embeddings).
Benefit
An external control-plane can now keep its work items fully synchronized in flycanon at the agent tier: documents can be updated in place (citations follow the new content instead of orphaning) and removed cleanly (no stale chunks or dangling vectors in the index), with safe retry semantics end to end.
Design notes
IndexService.remove_for_sourceresolves the chunk ids through the chunk repository; the ordering is pinned by a test.