agentconnect-cli 0.1.0a1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. agentconnect/__init__.py +3 -0
  2. agentconnect/a2a_adapter/__init__.py +6 -0
  3. agentconnect/a2a_adapter/adapter.py +565 -0
  4. agentconnect/a2a_adapter/cards.py +149 -0
  5. agentconnect/a2a_adapter/convert.py +157 -0
  6. agentconnect/a2a_adapter/facade.py +560 -0
  7. agentconnect/a2a_adapter/seen.py +49 -0
  8. agentconnect/a2a_adapter/serve.py +67 -0
  9. agentconnect/adapter.py +319 -0
  10. agentconnect/adapters.py +52 -0
  11. agentconnect/apiclient.py +51 -0
  12. agentconnect/backoff.py +42 -0
  13. agentconnect/callback.py +314 -0
  14. agentconnect/cli.py +2324 -0
  15. agentconnect/cli_json.py +470 -0
  16. agentconnect/cli_support.py +444 -0
  17. agentconnect/clock.py +161 -0
  18. agentconnect/config.py +1213 -0
  19. agentconnect/daemon/__init__.py +41 -0
  20. agentconnect/deliveries.py +295 -0
  21. agentconnect/directory_client.py +255 -0
  22. agentconnect/failpoints.py +99 -0
  23. agentconnect/identity.py +111 -0
  24. agentconnect/isolation.py +345 -0
  25. agentconnect/keystore.py +279 -0
  26. agentconnect/limits.py +457 -0
  27. agentconnect/log.py +143 -0
  28. agentconnect/mcp/__init__.py +30 -0
  29. agentconnect/mcp/backend.py +405 -0
  30. agentconnect/mcp/server.py +382 -0
  31. agentconnect/mcp/session.py +373 -0
  32. agentconnect/mcp/tools.py +583 -0
  33. agentconnect/ownerfile.py +238 -0
  34. agentconnect/payloads.py +109 -0
  35. agentconnect/policy.py +1066 -0
  36. agentconnect/provision.py +239 -0
  37. agentconnect/py.typed +0 -0
  38. agentconnect/relay.py +405 -0
  39. agentconnect/runtime/__init__.py +46 -0
  40. agentconnect/runtime/agent.py +225 -0
  41. agentconnect/runtime/api.py +2043 -0
  42. agentconnect/runtime/engine.py +5359 -0
  43. agentconnect/runtime/errors.py +47 -0
  44. agentconnect/runtime/floor.py +649 -0
  45. agentconnect/runtime/groups.py +1351 -0
  46. agentconnect/runtime/knocks.py +1422 -0
  47. agentconnect/runtime/ledger.py +94 -0
  48. agentconnect/runtime/listing.py +1307 -0
  49. agentconnect/runtime/registry.py +53 -0
  50. agentconnect/runtime/runtime.py +158 -0
  51. agentconnect/runtime/sas.py +1002 -0
  52. agentconnect/sas_emoji.py +83 -0
  53. agentconnect/schemas.py +381 -0
  54. agentconnect/shapes.py +56 -0
  55. agentconnect/sockets.py +86 -0
  56. agentconnect/sse.py +234 -0
  57. agentconnect/store.py +3282 -0
  58. agentconnect/tasks.py +35 -0
  59. agentconnect/tokens.py +63 -0
  60. agentconnect/webhook.py +199 -0
  61. agentconnect_cli-0.1.0a1.dist-info/METADATA +103 -0
  62. agentconnect_cli-0.1.0a1.dist-info/RECORD +64 -0
  63. agentconnect_cli-0.1.0a1.dist-info/WHEEL +4 -0
  64. agentconnect_cli-0.1.0a1.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,94 @@
1
+ """The owner's replay ledgers: one for invite JoinRequests (SPEC 6.2
2
+ "Replays"), one for knocks (SPEC 6.6.3 step 6).
3
+
4
+ Neither request carries freshness of its own and the relay sees both, so
5
+ every request that passed the owner's checks is remembered by its id and
6
+ its KeyPackageRef, whatever happens to it next, until no copy can pass the
7
+ checks again: a knock until ``ts + 3900``, a JoinRequest until its invite's
8
+ ``expires_at`` plus the core's ``LEDGER_GRACE_SECS``. A remembered request
9
+ is dropped silently.
10
+
11
+ The core's bounded ``ReplayLedger`` answers "seen?"; its entries are
12
+ persisted in a table of the encrypted store, written in the transaction that
13
+ records what the request led to. The in-memory ledger has no remove, so a
14
+ transaction that rolls back is followed by :func:`load`. When the ledger is
15
+ full, new requests are refused (``busy``) and nothing live is evicted. Each
16
+ invite also has a share of the join ledger (:func:`join_quota`), and an
17
+ invite's entries are forgotten once it is revoked or has expired. Purges
18
+ run on the clock's current time on every pass and keep nothing from
19
+ earlier passes; loading purges nothing.
20
+ """
21
+
22
+ from __future__ import annotations
23
+
24
+ from collections.abc import Callable
25
+
26
+ import agentconnect_core as ac
27
+ from agentconnect.config import MIN_JOIN_LEDGER_PER_INVITE
28
+ from agentconnect.relay import b64, unb64
29
+ from agentconnect.store import Ledger, Store
30
+
31
+ KNOCK_ID_LEN = 16
32
+
33
+ #: What a request the ledger refuses is dropped as, by its error kind.
34
+ REASONS: dict[Ledger, dict[str, str]] = {
35
+ "knock": {"replay": "knock_replay", "busy": "knock_ledger_full"},
36
+ "join": {"replay": "join_replay", "busy": "join_ledger_full"},
37
+ }
38
+
39
+
40
+ def load(store: Store, ledger: Ledger, capacity: int) -> ac.ReplayLedger:
41
+ """The ledger from the database, every row of it, even past a lowered
42
+ capacity: a request seen before a restart must never pass after it.
43
+ Loading purges nothing. A clock that is ahead at start and put right
44
+ before the next pass would otherwise forget live entries; the passes
45
+ purge (for joins right after marking expired invites, at the same now)."""
46
+ rows = store.ledger_rows(0, ledger=ledger)
47
+ core = ac.ReplayLedger(
48
+ max(capacity, len(rows)), id_len=KNOCK_ID_LEN if ledger == "knock" else None
49
+ )
50
+ for entry_id, kp_ref, forget_after in rows:
51
+ core.insert(entry_key(ledger, entry_id), unb64(kp_ref), forget_after)
52
+ return core
53
+
54
+
55
+ def entry_key(ledger: Ledger, entry_id: str) -> bytes:
56
+ """The bytes the core keys an entry by: a knock's raw ``knock_id``, a
57
+ join's request id (the envelope's ``msg_id``) as text."""
58
+ return unb64(entry_id) if ledger == "knock" else entry_id.encode()
59
+
60
+
61
+ def remember( # noqa: PLR0913
62
+ store: Store,
63
+ ledger: Ledger,
64
+ core: ac.ReplayLedger,
65
+ remember_in: Callable[[ac.ReplayLedger], None],
66
+ *,
67
+ entry_id: str,
68
+ kp_ref: bytes,
69
+ forget_after: int,
70
+ invite_id: str | None = None,
71
+ ) -> str | None:
72
+ """Inside the transaction that records the request: ``None`` if it is
73
+ new (now remembered, in memory and in the store), else the reason code
74
+ to drop it with (``*_replay``, ``*_ledger_full``)."""
75
+ try:
76
+ remember_in(core)
77
+ except ac.AgentConnectError as e:
78
+ return REASONS[ledger].get(e.kind, f"{ledger}_check:{e.kind}")
79
+ store.ledger_add(entry_id, b64(kp_ref), forget_after, ledger=ledger, invite_id=invite_id)
80
+ return None
81
+
82
+
83
+ def join_quota(max_uses: int, per_invite: int) -> int:
84
+ """How many entries one invite may hold in the join ledger: 4 times its
85
+ uses, at least ``MIN_JOIN_LEDGER_PER_INVITE``, at most ``per_invite``
86
+ (``policy.join_ledger_per_invite``). A leaked link fills only its own
87
+ share."""
88
+ return min(max(4 * max_uses, MIN_JOIN_LEDGER_PER_INVITE), per_invite)
89
+
90
+
91
+ def purge(store: Store, ledger: Ledger, core: ac.ReplayLedger, now: int) -> None:
92
+ """Forget what expired before ``now``: the clock's current time."""
93
+ store.ledger_purge(now, ledger=ledger)
94
+ core.purge(now)