Commit Graph

6 Commits

Author SHA1 Message Date
99bb64ddf3 feat(molecule_agent): add strip_a2a_boundary() for OFFSEC-003 trust-boundary markers
Some checks failed
Test / test (3.11) (pull_request) Failing after 2s
Test / test (3.12) (pull_request) Failing after 1s
Test / test (3.13) (pull_request) Failing after 1s
Platform now wraps peer A2A responses in [A2A_RESULT_FROM_PEER]...
[/A2A_RESULT_FROM_PEER] markers (OFFSEC-003) to mark them as untrusted
third-party content. This change adds:

- strip_a2a_boundary(text): strips the wrapper and returns the interior
  content. Safe on pre-OFFSEC-003 responses (returns input unchanged when
  markers absent or malformed) and on None/empty.

Exported from molecule_agent/__init__.py and added to __all__.

README updated with a dedicated OFFSEC-003 section and call_peer() table
note pointing to strip_a2a_boundary().

8 new tests: basic, whitespace edges, no-markers passthrough, only-start,
only-end, empty/None, end-before-start edge case, multiline content.
305 total tests pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 16:25:59 +00:00
a3bba8a3f3 feat(molecule_agent): add org_id and origin kwargs to RemoteAgentClient
Some checks failed
Test / test (3.13) (pull_request) Failing after 1s
Test / test (3.12) (pull_request) Failing after 3s
Test / test (3.11) (pull_request) Failing after 4s
Adds optional org_id and origin constructor kwargs that inject
X-Molecule-Org-Id and Origin headers on every request, enabling
SDK use against multi-tenant SaaS deployments (*.moleculesai.app)
without needing a pre-configured requests.Session.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 13:33:17 +00:00
db69916699 feat(sdk): add peer_id and before_ts filter params to fetch_inbound()
Some checks failed
Test / test (3.11) (pull_request) Failing after 2s
Test / test (3.13) (pull_request) Failing after 2s
Test / test (3.12) (pull_request) Failing after 5s
Exposes the two platform-supported filter parameters on
RemoteAgentClient.fetch_inbound():
- peer_id: narrow inbound events to a specific peer workspace UUID
- before_ts: RFC3339 cutoff timestamp for historical backlog replay

Also marks the corresponding README limitation as resolved (was documented as
"does not expose peer_id or before_ts filters" — both are now wired up).

New tests:
- test_fetch_inbound_peer_id_filter
- test_fetch_inbound_before_ts_filter
- test_fetch_inbound_combined_filters

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 13:01:43 +00:00
a206dae28b docs(readme): document channel envelope, auth headers, runtime split
Some checks failed
Test / test (3.11) (pull_request) Failing after 3s
Test / test (3.13) (pull_request) Failing after 2s
Test / test (3.12) (pull_request) Failing after 11s
Adds the docs gaps that were left when several CP changes landed without
SDK-side coverage:

- "What this is / what this isn't" callout — distinguishes molecule_agent
  (outside-workspace client SDK) from molecule-ai-workspace-runtime
  (in-workspace runtime), with strong forward-pointer to the runtime docs
- Channel envelope (wire format) — including the three enrichment fields
  added 2026-05-02 (peer_name, peer_role, agent_card_url)
- A2A reply transport table — explicit /notify vs /a2a routing per source
- Limitations & roadmap — names the SDK gaps so follow-up issues/PRs
  are trivial to file:
    * fetch_inbound() missing peer_id + before_ts filters (CP PRs #2472, #2476)
    * InboundMessage missing typed peer_name/peer_role/agent_card_url
    * RemoteAgentClient does not auto-inject X-Molecule-Org-Id + Origin
      (with a session-based workaround)

Docs-only — no Python code touched. Code work for the named gaps is
deferred to follow-up PRs so reviewers can land docs first.
2026-05-01 20:06:13 -07:00
70d66cd814 feat: poll-mode inbound delivery + molecule connect CLI (Phase 30.8c)
External agents that can't expose a public HTTP endpoint (laptops behind
NAT, ephemeral CI runners, hermes self-hosted, codex et al) had to reverse-
engineer the activity-poll loop from molecule-mcp-claude-channel/server.ts
because the SDK only shipped the push-mode `A2AServer` (Phase 30.8b).

This adds the complementary path:

- `RemoteAgentClient.fetch_inbound(since_id=…)` — one-shot GET against
  `/workspaces/:id/activity?type=a2a_receive&since_id=…`. Cursor-loss (410)
  surfaces as `CursorLostError`; caller resets and re-polls.
- `RemoteAgentClient.reply(msg, text)` — smart-routes to `/notify` for
  canvas users, `/a2a` (JSON-RPC envelope + X-Source-Workspace-Id) for peer
  agents. Hides the reply-path bifurcation from connector authors.
- `PollDelivery` / `PushDelivery` / `InboundDelivery` protocol — same
  `MessageHandler` callback works for both transports.
- `RemoteAgentClient.run_agent_loop(handler, delivery=None)` — combined
  heartbeat + state-poll + inbound dispatch. Defaults to `PollDelivery`.
  Async handlers detected and `asyncio.run`'d (matches A2AServer pattern).
  Sleep cadence = min(heartbeat_interval, delivery.interval).
- `python -m molecule_agent connect` CLI — one-line bootstrap. Loads a
  user's `module:function` via importlib, registers, runs the loop until
  pause/delete or SIGTERM. All flags also read from environment variables.

Tests: 50 new (test_inbound.py, test_cli_connect.py) covering every prod
branch — source normalization, cursor advancement, 410 reset, async/sync
handler dispatch, handler exception → log+continue+advance, smart-reply
routing for canvas vs peer vs unknown sources, run_agent_loop terminal
states, sleep-interval selection, CLI handler resolution failures.

Resolves #17.
2026-04-30 13:03:44 -07:00
Hongming Wang
fefcc38e11 feat: initial Python SDK (extracted from molecule-monorepo/sdk/python)
Workspace, org, channel, memory, delegation client for Molecule AI.
Package renamed to molecule-ai-sdk for PyPI.
2026-04-16 03:15:38 -07:00