molecule-sdk-python/molecule_agent/__init__.py
Molecule AI SDK-Dev 99bb64ddf3
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
feat(molecule_agent): add strip_a2a_boundary() for OFFSEC-003 trust-boundary markers
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

79 lines
2.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Molecule AI remote-agent SDK — build agents that run outside the platform
network and register as first-class workspaces.
This is the Phase 30.8 companion to ``molecule_plugin`` (for plugin authors).
Where ``molecule_plugin`` helps you ship installable behavior for workspaces
that already exist, ``molecule_agent`` helps you *be* a workspace from the
other side of the wire: register, authenticate, pull secrets, heartbeat,
and detect pause/resume/delete — all via the Phase 30.130.5 HTTP contract.
Intended usage::
from molecule_agent import RemoteAgentClient
client = RemoteAgentClient(
workspace_id="550e8400-e29b-41d4-a716-446655440000",
platform_url="https://your-platform.example.com",
agent_card={"name": "my-remote-agent", "skills": []},
)
client.register() # mints + persists the auth token
env = client.pull_secrets() # decrypted secrets dict
client.run_heartbeat_loop() # background heartbeat + state-poll
See ``sdk/python/examples/remote-agent/`` for a runnable demo.
Design notes:
* **No async.** The SDK uses blocking ``requests`` so a remote agent author
can embed it in any event loop / thread / script without forcing anyio.
* **Token cached on disk** at ``~/.molecule/<workspace_id>/.auth_token``
with 0600 permissions, so a restart of the agent doesn't re-issue a
token (the platform refuses to issue a second token when one is on file).
* **Pause/delete detection is polling-based** because remote agents usually
can't expose an inbound WebSocket reachable from the platform.
"""
from __future__ import annotations
from .a2a_server import A2AServer
from .client import (
PeerInfo,
RemoteAgentClient,
WorkspaceState,
strip_a2a_boundary,
verify_plugin_sha256,
)
from .inbound import (
CursorLostError,
DEFAULT_POLL_INTERVAL,
InboundDelivery,
InboundMessage,
InboundSource,
MessageHandler,
PollDelivery,
PushDelivery,
)
# compute_plugin_sha256 lives in __main__ (the CLI entry point).
# Import it here so `from molecule_agent import compute_plugin_sha256` works.
from .__main__ import compute_plugin_sha256
__all__ = [
"A2AServer",
"RemoteAgentClient",
"WorkspaceState",
"PeerInfo",
"InboundMessage",
"InboundSource",
"InboundDelivery",
"PollDelivery",
"PushDelivery",
"MessageHandler",
"CursorLostError",
"DEFAULT_POLL_INTERVAL",
"compute_plugin_sha256",
"verify_plugin_sha256",
"strip_a2a_boundary",
"__version__",
]
__version__ = "0.1.0"