Skip to content

feat: doubleagent-sdk shared Python library#14

Closed
zozo123 wants to merge 1 commit intomainfrom
feat/sdk-library
Closed

feat: doubleagent-sdk shared Python library#14
zozo123 wants to merge 1 commit intomainfrom
feat/sdk-library

Conversation

@zozo123
Copy link
Contributor

@zozo123 zozo123 commented Feb 15, 2026

Summary

Foundation library for building DoubleAgent fake services. Every fake service imports this SDK instead of reinventing state management, snapshot loading, PII redaction, and webhook delivery.

12 modules, 4,475 lines, 22 tests:

State management

  • state_overlay.py — Copy-on-write state: immutable snapshot baseline + mutable overlay + tombstones. reset() returns to baseline in O(1).
  • namespace.py — Per-agent isolation. Multiple AI agents share one baseline but get independent overlays via X-DoubleAgent-Namespace header.

Snapshot infrastructure

  • snapshot.py — Disk storage at ~/.doubleagent/snapshots/<service>/<profile>/. Manifest + per-type JSON files. Incremental merge support.
  • connector.py — Abstract SnapshotConnector interface for pulling real SaaS data.
  • airbyte_adapter.py — Docker-based Airbyte source connector integration (666 lines, handles discover/read/state).
  • airbyte_pull.py — CLI entry point for doubleagent snapshot pull when using Airbyte connectors. Dual backend: PyAirbyte (default, no Docker) or Docker.
  • pyairbyte_backend.py — PyAirbyte wrapper (ab.get_source() + get_records()). No Docker required.
  • smart_filter.py — Breadth-first relational graph traversal for smart seeding (e.g., 3 projects → follow to issues → follow to comments, with per-parent limits).

Data safety

  • redactor.py — Deterministic PII anonymization. Same email always maps to same user-N@doubleagent.local, preserving referential integrity across resources.
  • http_readonly.py — GET/HEAD-only HTTP client with SSRF protection. Ensures connectors never accidentally mutate production data.

Extras

  • webhook_simulator.py — Delivery with retry + exponential backoff, HMAC-SHA256 signatures, localhost-only allowlist, queryable audit log.
  • dual_target.py — Fake-vs-real contract comparison. When DOUBLEAGENT_DUAL_TARGET=1, @readonly tests run against both targets and diff responses.
  • generic_server.py — Zero-code FastAPI snapshot explorer. Any Airbyte-backed service can use this as its server with no custom code.

Test plan

  • 22 unit tests pass (uv run pytest -v)
  • Import as dependency from Descope/Jira/Salesforce services

🤖 Generated with Claude Code

Foundation library for building DoubleAgent fake services. 12 modules:

State management:
- StateOverlay: copy-on-write state (immutable baseline + mutable overlay + tombstones)
- NamespaceRouter: per-agent isolation via X-DoubleAgent-Namespace header

Snapshot infrastructure:
- snapshot.py: disk storage (manifest + per-type JSON files)
- connector.py: abstract SnapshotConnector interface for pulling real SaaS data
- airbyte_adapter.py: Docker-based Airbyte source connector integration
- airbyte_pull.py: CLI entry point for Airbyte pulls (PyAirbyte + Docker backends)
- pyairbyte_backend.py: PyAirbyte wrapper (no Docker required)
- smart_filter.py: relational graph traversal for smart seeding

Data safety:
- redactor.py: deterministic PII anonymization preserving referential integrity
- http_readonly.py: GET/HEAD-only HTTP client with SSRF protection

Extras:
- webhook_simulator.py: delivery with retry, HMAC signatures, audit log
- dual_target.py: fake-vs-real contract comparison helpers
- generic_server.py: zero-code snapshot explorer (FastAPI)

22 tests across 8 test files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@tomerezer
Copy link
Contributor

@zozo123 this is something i decided to avoid for now - i don't want to make agents to learn our SDK for implementation - they can just do it however they like (its not a lot of code to reimplement)

@zozo123
Copy link
Contributor Author

zozo123 commented Feb 16, 2026

Closing per Tomer's feedback — services should be self-contained without a shared SDK. Descope (PR #15) has been decoupled and rebased onto main. Jira/Salesforce (PR #16) will be decoupled separately.

@zozo123 zozo123 closed this Feb 16, 2026
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