@plurnk/plurnk-a2a 1.18.0 → 1.19.0
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.
- package/.env.defaults +12 -8
- package/README.md +16 -13
- package/SPEC.md +155 -37
- package/dist/A2a.d.ts +19 -5
- package/dist/A2a.d.ts.map +1 -1
- package/dist/A2a.js +120 -33
- package/dist/A2a.js.map +1 -1
- package/dist/A2aMessage.d.ts +2 -1
- package/dist/A2aMessage.d.ts.map +1 -1
- package/dist/A2aMessage.js +11 -6
- package/dist/A2aMessage.js.map +1 -1
- package/dist/A2aProjection.d.ts +13 -4
- package/dist/A2aProjection.d.ts.map +1 -1
- package/dist/A2aProjection.js +94 -52
- package/dist/A2aProjection.js.map +1 -1
- package/dist/Functionality.d.ts +6 -3
- package/dist/Functionality.d.ts.map +1 -1
- package/dist/Functionality.js +18 -16
- package/dist/Functionality.js.map +1 -1
- package/dist/Module.d.ts +8 -15
- package/dist/Module.d.ts.map +1 -1
- package/dist/Module.js +75 -40
- package/dist/Module.js.map +1 -1
- package/dist/OutboundModule.d.ts +0 -1
- package/dist/OutboundModule.d.ts.map +1 -1
- package/dist/OutboundModule.js +4 -7
- package/dist/OutboundModule.js.map +1 -1
- package/dist/PlurnkAgentExecutor.d.ts +4 -1
- package/dist/PlurnkAgentExecutor.d.ts.map +1 -1
- package/dist/PlurnkAgentExecutor.js +51 -16
- package/dist/PlurnkAgentExecutor.js.map +1 -1
- package/dist/PlurnkRequestHandler.d.ts +11 -0
- package/dist/PlurnkRequestHandler.d.ts.map +1 -0
- package/dist/PlurnkRequestHandler.js +19 -0
- package/dist/PlurnkRequestHandler.js.map +1 -0
- package/dist/PlurnkTaskStore.d.ts +2 -1
- package/dist/PlurnkTaskStore.d.ts.map +1 -1
- package/dist/PlurnkTaskStore.js +88 -42
- package/dist/PlurnkTaskStore.js.map +1 -1
- package/dist/WorkspaceBinding.d.ts +1 -0
- package/dist/WorkspaceBinding.d.ts.map +1 -1
- package/dist/WorkspaceBinding.js +14 -5
- package/dist/WorkspaceBinding.js.map +1 -1
- package/dist/config.d.ts +5 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +46 -20
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/docs/a2a.md +54 -15
- package/package.json +6 -6
- package/docs/agents.md +0 -42
package/.env.defaults
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# @plurnk/plurnk-a2a — remote agents and optional hosted exposure.
|
|
2
2
|
|
|
3
3
|
# --- Outbound agents ---
|
|
4
|
-
#
|
|
4
|
+
# An empty alias target masks its definition, companions and ENABLED selection.
|
|
5
|
+
# Initially enabled workspace agent aliases, JSON array; [] = none.
|
|
5
6
|
PLURNK_A2A_ENABLED=[]
|
|
6
7
|
# Connection/discovery deadline, positive ms.
|
|
7
8
|
PLURNK_A2A_CONNECT_TIMEOUT=30000
|
|
@@ -15,21 +16,24 @@ PLURNK_A2A_ERROR_DETAIL_LIMIT=512
|
|
|
15
16
|
# PLURNK_A2A_research_BEARER=${A2A_RESEARCH_TOKEN}
|
|
16
17
|
# PLURNK_A2A_research_HEADERS={"X-Tenant":"${A2A_RESEARCH_TENANT}"}
|
|
17
18
|
|
|
18
|
-
# --- Inbound exposure
|
|
19
|
-
# 1 = expose a Plurnk agent; 0 = off. Protocol
|
|
19
|
+
# --- Inbound exposure ---
|
|
20
|
+
# 1 = expose a Plurnk agent on the service listener (PLURNK_HOST:PLURNK_PORT); 0 = off. Protocol
|
|
21
|
+
# capabilities come from the implementation.
|
|
20
22
|
PLURNK_A2A_EXPOSE=0
|
|
21
|
-
#
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
PLURNK_A2A_PORT=4100
|
|
23
|
+
# Bearer required on the endpoint, declared by the card; empty = an unauthenticated exposure, so
|
|
24
|
+
# protect a nonlocal deployment externally. The card at /.well-known/agent-card.json is public.
|
|
25
|
+
PLURNK_A2A_TOKEN=
|
|
25
26
|
# Absolute endpoint URL pathname, without query or fragment.
|
|
26
27
|
PLURNK_A2A_ENDPOINT_PATH=/a2a
|
|
27
|
-
# Public HTTP(S) endpoint advertised in the card; empty = derive from listener.
|
|
28
|
+
# Public HTTP(S) endpoint advertised in the card; empty = derive from the service listener.
|
|
28
29
|
PLURNK_A2A_ENDPOINT_URL=
|
|
29
30
|
# Workspace used for inbound tasks.
|
|
30
31
|
PLURNK_A2A_WORKSPACE=a2a
|
|
31
32
|
# Absolute project root for a new inbound workspace; empty = headless.
|
|
32
33
|
PLURNK_A2A_PROJECT_ROOT=
|
|
34
|
+
# What an inbound task's loop does with a proposal: accept applies it, reject refuses it.
|
|
35
|
+
# A2A carries no review channel, so review is not a choice here.
|
|
36
|
+
PLURNK_A2A_PROPOSALS=reject
|
|
33
37
|
# Agent card name; required when EXPOSE=1.
|
|
34
38
|
PLURNK_A2A_NAME=
|
|
35
39
|
# Agent card description; required when EXPOSE=1.
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ HTTP+JSON v1 binding.
|
|
|
10
10
|
|
|
11
11
|
The module is an exterior client of Core's `ApplicationPort`; it does not add
|
|
12
12
|
an A2A scheduler or Task database. The installed service reads the ordinary
|
|
13
|
-
Plurnk environment cascade. Enable
|
|
13
|
+
Plurnk environment cascade. Enable the exposure and describe its public
|
|
14
14
|
identity in an operator or project `.env`:
|
|
15
15
|
|
|
16
16
|
```dotenv
|
|
@@ -22,11 +22,13 @@ PLURNK_A2A_VERSION=1.0.0
|
|
|
22
22
|
PLURNK_A2A_SKILLS=[{"id":"research","name":"Research","description":"Researches a question and returns a sourced answer","tags":["research"]}]
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
The module
|
|
26
|
-
advertised HTTP+JSON interface at `/a2a
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
The module mounts the Agent Card at `/.well-known/agent-card.json` and the
|
|
26
|
+
advertised HTTP+JSON interface at `/a2a` on the service listener
|
|
27
|
+
(`PLURNK_HOST:PLURNK_PORT`); it opens no socket of its own. With
|
|
28
|
+
`PLURNK_A2A_TOKEN` set, the card declares an HTTP bearer scheme and the
|
|
29
|
+
interface requires that bearer; the card itself stays public. Starting the
|
|
30
|
+
service or reading the card does not create or hydrate the named workspace;
|
|
31
|
+
the first admitted Task does so.
|
|
30
32
|
|
|
31
33
|
## Connect to an agent
|
|
32
34
|
|
|
@@ -45,23 +47,24 @@ PLURNK_A2A_RESEARCH_BEARER=${A2A_RESEARCH_TOKEN}
|
|
|
45
47
|
PLURNK_A2A_ENABLED=["research"]
|
|
46
48
|
```
|
|
47
49
|
|
|
48
|
-
In the service those definitions are the baseline of the workspace `
|
|
50
|
+
In the service those definitions are the baseline of the workspace `a2a`
|
|
49
51
|
Functionality family (`OutboundModule`): every Worker lists, discovers, adds,
|
|
50
52
|
enables, disables, and removes outbound agents through the common
|
|
51
|
-
`workspace.
|
|
53
|
+
`workspace.a2a.*` actions or the generated ```` ```a2a ```` manager, and the
|
|
52
54
|
`a2a://<alias>` scheme resolves an alias against the workspace's enabled
|
|
53
|
-
snapshot. Enabled agents appear in Turn 0 as one `worker:///_plurnk/
|
|
55
|
+
snapshot. Enabled agents appear in Turn 0 as one `worker:///_plurnk/a2a/<alias>.md`
|
|
54
56
|
catalog row each; the exact Agent Card stays pullable with `READ a2a://<alias>`.
|
|
55
57
|
|
|
56
|
-
The package also exports the
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
The package also exports the scheme's live face for embedding: a runtime named
|
|
59
|
+
`a2a` carries it as its `scheme`, and it claims every coordinate that opens
|
|
60
|
+
with an alias. Its resolver maps each URI authority, in the operation's
|
|
61
|
+
workspace, to one client while keeping alias and credential policy outside the
|
|
59
62
|
protocol/resource owner:
|
|
60
63
|
|
|
61
64
|
```ts
|
|
62
65
|
import { A2a, connectHttpJsonAgent } from "@plurnk/plurnk-a2a";
|
|
63
66
|
|
|
64
|
-
const
|
|
67
|
+
const face = new A2a(async (alias, ctx) =>
|
|
65
68
|
alias === "research" && ctx.workspaceId === 1 ? await connectHttpJsonAgent("https://agent.example") : null);
|
|
66
69
|
```
|
|
67
70
|
|
package/SPEC.md
CHANGED
|
@@ -17,10 +17,10 @@ cards are protocol projections, not configuration files.
|
|
|
17
17
|
| Family | Variables | Meaning |
|
|
18
18
|
|---|---|---|
|
|
19
19
|
| Outbound definition | `PLURNK_A2A_<ALIAS>=<absolute HTTP(S) URL>` plus optional `_CARD_PATH`, `_HEADERS`, and `_BEARER` companions | Defines one available remote agent without fetching or enabling it. `_BEARER` contains only a symbolic `${NAME}` reference; secrets remain environment-owned. |
|
|
20
|
-
| Outbound defaults | `PLURNK_A2A_ENABLED` | JSON array selecting the exact aliases enabled by default for the workspace's `
|
|
20
|
+
| Outbound defaults | `PLURNK_A2A_ENABLED` | JSON array selecting the exact aliases enabled by default for the workspace's `a2a` family ({§a2a-functionality}); workspace state may override enabledness. `[]` is the one spelling of none: an absent or empty key is refused by name. |
|
|
21
21
|
| Timeouts | `PLURNK_A2A_CONNECT_TIMEOUT`, `PLURNK_A2A_REQUEST_TIMEOUT` | Positive integer milliseconds owned by the A2A package. |
|
|
22
22
|
| Diagnostics | `PLURNK_A2A_ERROR_DETAIL_LIMIT` | Non-negative character bound for one caught upstream diagnostic admitted to a model-facing A2A Problem; complete causes remain internal. |
|
|
23
|
-
| Inbound
|
|
23
|
+
| Inbound exposure | `PLURNK_A2A_EXPOSE`, `_TOKEN`, `_ENDPOINT_PATH`, `_ENDPOINT_URL` | `EXPOSE=1` mounts one HTTP+JSON exposure on the service listener ({§http-host}); `0` mounts none. `_TOKEN` is the bearer the endpoint requires and the card declares ({§a2a-hosted-bearer}); empty is an unauthenticated exposure. |
|
|
24
24
|
| Inbound workspace | `PLURNK_A2A_WORKSPACE`, `_PROJECT_ROOT` | Names the lazily resolved execution workspace and its creation root. |
|
|
25
25
|
| Hosted identity | `PLURNK_A2A_NAME`, `_DESCRIPTION`, `_VERSION`, optional provider/docs/icon fields, and `_SKILLS` | Supplies identity content for one generated standard Agent Card. `_SKILLS` is a JSON array; omitted per-skill examples and media modes receive the exposure's factual defaults. |
|
|
26
26
|
|
|
@@ -30,6 +30,11 @@ environment references until connection admission. A remote Agent Card remains
|
|
|
30
30
|
the authority for that remote agent; its discovered contents are never copied
|
|
31
31
|
into this environment vocabulary.
|
|
32
32
|
|
|
33
|
+
An explicitly empty outbound target omits that definition, ignores its companion
|
|
34
|
+
values and drops its inherited `ENABLED` selection. It does not remove a
|
|
35
|
+
workspace-owned definition or prohibit adding one. Genuinely undeclared aliases
|
|
36
|
+
and case-fold collisions still fail validation.
|
|
37
|
+
|
|
33
38
|
## §a2a-protocol-witness Protocol witness
|
|
34
39
|
|
|
35
40
|
The integration witness places a discovery-first client and an independent
|
|
@@ -44,8 +49,11 @@ architecture.
|
|
|
44
49
|
|
|
45
50
|
## §a2a-inbound-exposure Inbound exterior exposure
|
|
46
51
|
|
|
47
|
-
The inbound HTTP+JSON
|
|
48
|
-
`ApplicationPort
|
|
52
|
+
The inbound HTTP+JSON exposure is an exterior adapter over
|
|
53
|
+
`ApplicationPort`, mounted on the daemon's one listener ({§http-host}): the
|
|
54
|
+
public Agent Card at the standard well-known path and the interface at
|
|
55
|
+
`PLURNK_A2A_ENDPOINT_PATH`, both on the service address, and it opens no
|
|
56
|
+
socket of its own. The official SDK owns A2A framing and request handling;
|
|
49
57
|
Plurnk Workers, Loops, logs, and terminal results remain the only execution
|
|
50
58
|
state. The SDK `TaskStore` implementation is a projection of that durable
|
|
51
59
|
state, not an independent Task database.
|
|
@@ -60,58 +68,94 @@ flowchart LR
|
|
|
60
68
|
```
|
|
61
69
|
|
|
62
70
|
The SDK generates new Context and Task UUIDs before execution. Those UUIDs
|
|
63
|
-
already satisfy Plurnk's worker-name contract, so their exact values name the
|
|
71
|
+
already satisfy Plurnk's worker-name contract ({§worker-name}), so their exact values name the
|
|
64
72
|
root Context Worker and its Task child. No adapter binding table, synthetic
|
|
65
73
|
actor, or second scheduler exists. Later Tasks fork the Context root and
|
|
66
74
|
therefore receive the parent-visible prior Task evidence under Core's ordinary
|
|
67
75
|
topology contract.
|
|
68
76
|
|
|
69
|
-
Only a child Worker with a durable
|
|
77
|
+
Only a child Worker with a durable message source matching its exact A2A Context,
|
|
70
78
|
Task, and Message identities projects as a Task. A root is reusable as an A2A
|
|
71
79
|
Context only after this adapter created it in the running exposure or one such
|
|
72
80
|
Task proves its durable ownership after restart. Ordinary model Workers in the
|
|
73
|
-
same workspace are neither discoverable nor adoptable through A2A.
|
|
74
|
-
|
|
75
|
-
|
|
81
|
+
same workspace are neither discoverable nor adoptable through A2A. Foreign
|
|
82
|
+
Task identities that cannot name a local Worker are unknown Tasks, not Core
|
|
83
|
+
validation failures. Unsupported Message content and invalid answers to a
|
|
84
|
+
pending interaction are rejected before execution with the standard protocol
|
|
85
|
+
error; they do not create Workers or alter an existing Task. Other executor
|
|
86
|
+
failures follow the SDK's failed-Task behavior.
|
|
76
87
|
|
|
77
88
|
| Durable Plurnk state | A2A projection |
|
|
78
89
|
|---|---|
|
|
79
90
|
| Loop `100` | `SUBMITTED` |
|
|
80
91
|
| Loop `102` or `202` | `WORKING`; parking alone does not claim user input is required |
|
|
81
92
|
| Pending client interaction on the Task Loop | `INPUT_REQUIRED` |
|
|
82
|
-
| Successful terminal result | `COMPLETED`;
|
|
93
|
+
| Successful terminal result | `COMPLETED`; the current Loop's last non-empty delivered reply from message history is the `result` Artifact. The lifecycle result is not a message body. |
|
|
83
94
|
| External cancellation / Loop `499` | `CANCELED` |
|
|
84
95
|
| Other terminal failure | `FAILED` with the exact Problem detail as its status Message |
|
|
85
|
-
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
96
|
+
| Inbox messages carrying the adapter's causal source | Complete admitted user Message history from {§message-envelope-evidence}, including accepted interaction answers; independent of log curation and publication. |
|
|
97
|
+
| Delivered replies answering this Task's A2A messages | Only replies whose `answers` name this Task's A2A messages contribute text or attachments. Native or other-protocol replies do not become A2A Artifacts. |
|
|
98
|
+
| Such replies' attachment receipts | Distinct standard Artifacts holding send-time bytes from {§send-resource-attachments}, independent of later source changes. |
|
|
99
|
+
|
|
100
|
+
The exposure accepts text, data, URL, and raw Message Parts, advertises HTTP+JSON v1
|
|
101
|
+
streaming without push notifications, tenants, or extended cards, declares no
|
|
102
|
+
security beyond the bearer it enforces ({§a2a-hosted-bearer}), and rejects a
|
|
103
|
+
card that claims any security of its own. Those omitted surfaces are not
|
|
104
|
+
silently simulated. The adapter subscribes to live
|
|
91
105
|
application events for streaming and reads durable Worker/Loop/log projections
|
|
92
106
|
for retrieval and restart truth.
|
|
93
107
|
|
|
94
108
|
§a2a-hosted-card The service generates the hosted standard Agent Card from
|
|
95
109
|
normalized environment identity plus actual adapter capabilities. The adapter,
|
|
96
110
|
not configuration, fixes HTTP+JSON protocol `1.0`, streaming, no push
|
|
97
|
-
notifications, no extended card, no tenant,
|
|
98
|
-
and
|
|
111
|
+
notifications, no extended card, no tenant, the security it enforces
|
|
112
|
+
({§a2a-hosted-bearer}), and `*/*` input/output.
|
|
113
|
+
Arbitrary media are resources; native model interpretation still depends on its route.
|
|
114
|
+
Unsupported security claims are structurally absent
|
|
99
115
|
rather than configurable. The official SDK serializes the card served at the
|
|
100
116
|
standard well-known path.
|
|
101
117
|
|
|
102
|
-
§a2a-
|
|
103
|
-
|
|
118
|
+
§a2a-hosted-bearer With `PLURNK_A2A_TOKEN` set, the card declares one `http`
|
|
119
|
+
bearer scheme as its whole security requirement, and the endpoint refuses any
|
|
120
|
+
request without that exact bearer — `401`, `UNAUTHENTICATED`,
|
|
121
|
+
`WWW-Authenticate: Bearer`, in the binding's own error shape — before the SDK
|
|
122
|
+
reads anything. The card at the well-known path is never behind the bearer, so a
|
|
123
|
+
caller can discover the scheme. Empty is an unauthenticated exposure: the panel
|
|
124
|
+
states it, the adapter never infers it.
|
|
125
|
+
|
|
126
|
+
§a2a-hosted-proposals A2A carries no review channel, so an inbound Task's loop
|
|
127
|
+
settles its own proposals: `PLURNK_A2A_PROPOSALS` states `accept` or `reject`,
|
|
128
|
+
and `review` is outside its vocabulary. That one field is all the adapter states
|
|
129
|
+
about the loop's policy; attendance is the daemon's to supply, because a remote
|
|
130
|
+
agent can answer an interaction through `input-required`.
|
|
131
|
+
|
|
132
|
+
§a2a-lazy-workspace Mounting the exposure, Agent Card discovery, Task observations,
|
|
133
|
+
and rejected Task lookups perform no workspace creation, attachment, hydration,
|
|
134
|
+
model selection, or inference. An absent workspace yields an empty Task list or
|
|
135
|
+
the standard Task-not-found result, not implicit creation. The
|
|
104
136
|
first admitted Task resolves the configured workspace name, adopting the one
|
|
105
137
|
existing match or creating it with the configured project root. A configured
|
|
106
138
|
non-null root must match an existing workspace exactly. The resolution is
|
|
107
139
|
shared across concurrent requests and a failed resolution remains retryable.
|
|
108
140
|
|
|
109
|
-
|
|
141
|
+
### §a2a-task-listing Task listing
|
|
110
142
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
143
|
+
`ListTasks` follows the [A2A listing contract](https://a2a-protocol.org/latest/specification/#314-list-tasks),
|
|
144
|
+
not the Worker directory's creation order.
|
|
145
|
+
|
|
146
|
+
| Concern | Projection |
|
|
147
|
+
|---|---|
|
|
148
|
+
| Ordering | Status timestamp descending; equal or absent timestamps use Task ID ascending. Absent timestamps sort last. |
|
|
149
|
+
| Pagination | Opaque cursor after the last returned timestamp/ID, not an offset. Newer Tasks do not shift subsequent pages. This is a live listing, not a frozen snapshot. |
|
|
150
|
+
| Filtering | Context, state, and inclusive status timestamp bound apply before paging; `totalSize` counts the filtered Tasks. |
|
|
151
|
+
| Content | Artifacts are omitted unless requested; the SDK applies the requested history limit. |
|
|
152
|
+
| Invalid cursor | Standard `RequestMalformedError`; never silently restart at the first page. |
|
|
153
|
+
|
|
154
|
+
## §a2a-functionality Outbound agents as workspace Functionality
|
|
155
|
+
|
|
156
|
+
The package registers, through `OutboundModule`, one workspace Functionality
|
|
157
|
+
family named `a2a` ({§functionality-adapter} in core): the package, its keys,
|
|
158
|
+
the family and the scheme share one name. Its definition
|
|
115
159
|
is the `A2aAgentDefinition` contract — local alias `name`, remote `url`,
|
|
116
160
|
optional `cardPath`, `headers`, and symbolic bearer `authorization` —
|
|
117
161
|
exactly the environment's `PLURNK_A2A_<ALIAS>*` projection.
|
|
@@ -132,9 +176,10 @@ Agent Card at the definition's URL (`card-unreachable`), and connects only
|
|
|
132
176
|
through an advertised HTTP+JSON `1.0` interface (`interface-unsupported`),
|
|
133
177
|
reusing an unchanged attachment across publications. The outcome detail carries
|
|
134
178
|
the card's name, version, description, skill identifiers, and streaming
|
|
135
|
-
capability. The family publishes no runtimes; its snapshot is the
|
|
136
|
-
`alias → client` map, and
|
|
137
|
-
Functionality of the operation's workspace
|
|
179
|
+
capability. The family publishes no runtimes of its own; its snapshot is the
|
|
180
|
+
workspace's `alias → client` map, and its scheme face ({§a2a-scheme-face})
|
|
181
|
+
resolves an authority against the Functionality of the operation's workspace
|
|
182
|
+
(`ctx.workspaceId`):
|
|
138
183
|
an unknown or disabled alias is 404 `agent-not-configured`, an unavailable
|
|
139
184
|
alias carries its one exact preparation Problem. Every worker in a workspace
|
|
140
185
|
resolves the same alias definition; independent workspaces may differ.
|
|
@@ -145,12 +190,12 @@ prose. A decision-relevant caught configuration, discovery, or interface
|
|
|
145
190
|
diagnostic is admitted only through `PLURNK_A2A_ERROR_DETAIL_LIMIT`; the exact
|
|
146
191
|
cause remains attached for daemon diagnostics.
|
|
147
192
|
|
|
148
|
-
§a2a-
|
|
149
|
-
publishes one `worker:///_plurnk/
|
|
193
|
+
§a2a-catalog **Turn 0 shows enabled agents concisely.** Preparation
|
|
194
|
+
publishes one `worker:///_plurnk/a2a/<alias>.md` document per active
|
|
150
195
|
alias — an H1 alias, an H2 `Summary` whose one line is
|
|
151
196
|
`a2a://<alias> — <card name> v<version>: <description>`, and the invocation
|
|
152
197
|
form — and nothing for disabled or unavailable aliases. Core's seventh turn-0
|
|
153
|
-
survey (```` ```FIND (worker:///_plurnk/
|
|
198
|
+
survey (```` ```FIND (worker:///_plurnk/a2a/*.md) <1,-1> ````,
|
|
154
199
|
{§actor-boundary-catalog-preview}) therefore presents every effective agent as
|
|
155
200
|
one summary row. The document embeds neither the card nor its skills; both stay
|
|
156
201
|
pullable exactly through `READ a2a://<alias>` ({§a2a-outbound-definition}).
|
|
@@ -163,8 +208,21 @@ and subscription contracts. Its URI authority is the configured remote-agent
|
|
|
163
208
|
alias. The adapter is not a Worker producer, scheduler, Task store, or alternate
|
|
164
209
|
operation runtime.
|
|
165
210
|
|
|
211
|
+
§a2a-scheme-face **The scheme is the live half of the family's own runtime.**
|
|
212
|
+
Every executor tag is a scheme of the same name, so the `a2a` manager and the
|
|
213
|
+
`a2a://` resources are one scheme with two halves ({§runtime-resource-binding}
|
|
214
|
+
in core). The manager's stored executions keep `a2a:///<loop>/<turn>/<sequence>`,
|
|
215
|
+
numeric throughout; the package's face claims every other coordinate — one that
|
|
216
|
+
opens with an agent alias, or with `contexts` for a hosted message — and owns
|
|
217
|
+
READ, FIND preparation and SEND there; KILL of a live Task is the ordinary
|
|
218
|
+
stream control. The face declares its own representation — resource authority,
|
|
219
|
+
`#body` and `#json` — so a resource keeps the one address `a2a://planner/tasks/7`
|
|
220
|
+
in what the model writes, in its log, and in the wake that concludes a Task.
|
|
221
|
+
The family states the `web` trait, so a capability policy that selects on it
|
|
222
|
+
covers the manager and every resource alike.
|
|
223
|
+
|
|
166
224
|
§a2a-outbound-definition An enabled outbound alias resolves through its
|
|
167
|
-
workspace's `
|
|
225
|
+
workspace's `a2a` Functionality snapshot ({§a2a-functionality}), whose
|
|
168
226
|
preparation discovered and validated the remote standard Agent Card and
|
|
169
227
|
selected only an advertised HTTP+JSON `1.0` interface. The local alias,
|
|
170
228
|
target, optional card path, symbolic authentication, and provenance are local
|
|
@@ -180,11 +238,11 @@ interfaces remain remote protocol authority.
|
|
|
180
238
|
| READ | Exact Task resource | Materialize the remote Task's current canonical snapshot. |
|
|
181
239
|
| READ | Stored Artifact resource | Read the workspace's retained bytes without requiring an active agent connection. |
|
|
182
240
|
|
|
183
|
-
§a2a-outbound-turn-rhythm SEND delivers a Message;
|
|
184
|
-
the local Loop's
|
|
185
|
-
creates an ordinary live obligation.
|
|
186
|
-
|
|
187
|
-
same Loop with its terminal READ, and
|
|
241
|
+
§a2a-outbound-turn-rhythm SEND delivers a Message; lifecycle verbs independently
|
|
242
|
+
declare the local Loop's intent under {§turn-disposition}. A Task-backed SEND
|
|
243
|
+
creates an ordinary live obligation. Ordinary operations continue work;
|
|
244
|
+
WAIT joins that obligation. Subscription settlement wakes the
|
|
245
|
+
same Loop with its terminal READ, and an answered, observed and settled loop concludes
|
|
188
246
|
under {§wait-obligation-matrix}. KILL cancels through that same subscription.
|
|
189
247
|
No adapter-authored turn or alternate disposition path fills any step.
|
|
190
248
|
|
|
@@ -193,6 +251,14 @@ entry, opens one subscription, returns its exact address with `102`, and closes
|
|
|
193
251
|
that subscription with the remote Task result. Core alone owns parking, waking,
|
|
194
252
|
the terminal next-turn READ, and cancellation propagation.
|
|
195
253
|
|
|
254
|
+
Reaching a remote agent is a host effect, so the SEND proposes first
|
|
255
|
+
({§http-outbound-proposes}) and the seeding above happens on the settlement. The
|
|
256
|
+
`102` is then what the applied operation returns to the settlement, not what the
|
|
257
|
+
model reads: an accepted proposal answers `200` ({§proposal-accept-applies}), so
|
|
258
|
+
the Task's first snapshot arrives by ordinary observation of the resource rather
|
|
259
|
+
than on the SEND row. The model sees the same canonical entry either way, one
|
|
260
|
+
turn later; a rejected proposal reaches no agent at all.
|
|
261
|
+
|
|
196
262
|
§a2a-outbound-replay A card or resource READ and connection discovery are
|
|
197
263
|
replay-safe observations. A SEND is not: once dispatch begins, a transport or
|
|
198
264
|
stream-protocol failure cannot prove that the remote agent rejected the
|
|
@@ -202,6 +268,41 @@ automatic identical replay that could duplicate remote work.
|
|
|
202
268
|
|
|
203
269
|
## §a2a-resource-projection Resource projection
|
|
204
270
|
|
|
271
|
+
§a2a-hosted-message-resources Hosted input uses the ordinary inbox and
|
|
272
|
+
{§send-resource-attachments}, not the outbound alias resolver. An incoming
|
|
273
|
+
caller needs neither an Agent Card nor a configured remote alias.
|
|
274
|
+
|
|
275
|
+
| Input Part | Model-facing arrival |
|
|
276
|
+
|---|---|
|
|
277
|
+
| Text | Authored text. |
|
|
278
|
+
| Data | Pretty-printed JSON. |
|
|
279
|
+
| URL | Literal supplied URL; no arrival-time fetch. |
|
|
280
|
+
| Raw | Link to `worker://<task>/attachments/<eight-character-id>/<name>`, with ordinary typed bytes; unnamed/colliding names use {§resource-publication-names}. |
|
|
281
|
+
|
|
282
|
+
The complete admitted SDK SendMessageRequest envelope preserves configuration,
|
|
283
|
+
request metadata, and its inner Message's Part order, media types, filenames,
|
|
284
|
+
metadata, and assigned Task/Context identity. Accepted interaction
|
|
285
|
+
answers enter that same evidence path before the operation resumes; invalid
|
|
286
|
+
answers do not. Task history selects the envelope's inner Message, including
|
|
287
|
+
those awaiting log publication. Derived status Messages describe the current
|
|
288
|
+
pending interaction or terminal Problem; they are not additional inbox arrivals.
|
|
289
|
+
Task retrieval reconstructs these facts after adapter/daemon restart.
|
|
290
|
+
|
|
291
|
+
§a2a-response-preferences Nonempty `configuration.acceptedOutputModes` appears
|
|
292
|
+
as labeled response preferences beside the model-facing arrival, for normal
|
|
293
|
+
requests and accepted interaction answers. Omitted or empty preferences add
|
|
294
|
+
nothing. This projection neither edits the protocol Message nor changes
|
|
295
|
+
interaction validation. Other request configuration remains adapter-owned;
|
|
296
|
+
opaque request metadata is evidence, not additional instructions. Preferences
|
|
297
|
+
do not relabel source bytes or promise an unavailable output representation.
|
|
298
|
+
|
|
299
|
+
Explicit resource selections in a hosted worker's targetless SEND become
|
|
300
|
+
standard raw-Part Artifacts, one per selected resource in order. Artifact IDs
|
|
301
|
+
are stable within the Task. The ordinary final textual result retains its
|
|
302
|
+
`result` Artifact. A directed A2A SEND instead transmits its selected resources
|
|
303
|
+
as raw Parts of that user Message. Resource creation and READ never export;
|
|
304
|
+
the selected send-time snapshot survives both source mutation and log curation.
|
|
305
|
+
|
|
205
306
|
Every retained Agent Card, Message, Task, and Artifact has a model-oriented
|
|
206
307
|
Markdown `#body` and an exact protocol `#json` channel serialized by the pinned
|
|
207
308
|
official SDK. A Task's Artifact identities remain distinct URI descendants and
|
|
@@ -209,3 +310,20 @@ materialize independently; the adapter never flattens multiple Artifacts into
|
|
|
209
310
|
one fabricated result. Projection wording is presentation rather than protocol
|
|
210
311
|
identity: tests assert lifecycle state, content, media type, and addressability,
|
|
211
312
|
not a prose template.
|
|
313
|
+
|
|
314
|
+
§a2a-part-resources Received raw Parts are ordinary typed resources, not base64
|
|
315
|
+
placeholders. Their parent Message or Artifact links to them in Part order;
|
|
316
|
+
the exact protocol JSON remains independently readable.
|
|
317
|
+
|
|
318
|
+
| Part | Ordinary resource projection |
|
|
319
|
+
|---|---|
|
|
320
|
+
| Text / structured data | Text / pretty JSON in the parent body. |
|
|
321
|
+
| URL | The supplied URL; arrival does not fetch it or bypass its scheme's acquisition policy. |
|
|
322
|
+
| Raw bytes | `<parent>/resources/<name>` with exact bytes and media type (or `application/octet-stream` if absent). Supplied names and stable eight-character fallback names use {§resource-publication-names}. |
|
|
323
|
+
|
|
324
|
+
A received Task snapshot retains its Artifacts and Messages with their Part
|
|
325
|
+
resources before publishing links or settling its subscription. Retained
|
|
326
|
+
Message, Artifact, and Part READs need no active remote connection. READ alone
|
|
327
|
+
controls native attachment delivery through {§packet-attachment-parts}; listing
|
|
328
|
+
a resource does not inject its bytes into model context. Log curation does not
|
|
329
|
+
delete the retained source.
|
package/dist/A2a.d.ts
CHANGED
|
@@ -1,12 +1,26 @@
|
|
|
1
1
|
import type { Client } from "@a2a-js/sdk/client";
|
|
2
|
-
import { type PassthroughResult, type RepresentationPreparationRequest, type RepresentationPreparationResult, type SchemeCtx, type
|
|
2
|
+
import { type PassthroughResult, type ProposalResult, type ProposalApplyRequest, type ProposalApplyResult, type RepresentationPreparationRequest, type RepresentationPreparationResult, type SchemeCtx, type SchemeResult, type SendStatement, type FindStatement } from "@plurnk/plurnk-schemes";
|
|
3
3
|
export type A2aClientResolver = (authority: string, ctx: SchemeCtx) => Client | null | Promise<Client | null>;
|
|
4
|
-
/**
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* {§a2a-scheme-face} Outbound A2A v1 resources and Task obligations: the live half of the `a2a`
|
|
6
|
+
* runtime's scheme. The family manager's stored executions keep `a2a:///<loop>/<turn>/<sequence>`;
|
|
7
|
+
* every other coordinate opens with an agent alias, or with `contexts` for a hosted message.
|
|
8
|
+
*/
|
|
9
|
+
export default class A2a {
|
|
6
10
|
#private;
|
|
7
|
-
|
|
11
|
+
readonly manifest: {
|
|
12
|
+
readonly authority: "resource";
|
|
13
|
+
readonly channels: {
|
|
14
|
+
readonly body: "text/markdown";
|
|
15
|
+
readonly json: "application/json";
|
|
16
|
+
};
|
|
17
|
+
readonly defaultChannel: "body";
|
|
18
|
+
};
|
|
19
|
+
claims(pathname: string): boolean;
|
|
20
|
+
prepareFind(_statement: FindStatement, ctx: SchemeCtx): Promise<SchemeResult>;
|
|
8
21
|
constructor(resolveClient: A2aClientResolver);
|
|
9
22
|
prepareRepresentation(request: RepresentationPreparationRequest, ctx: SchemeCtx): Promise<RepresentationPreparationResult>;
|
|
10
|
-
send(statement: SendStatement, ctx: SchemeCtx): Promise<PassthroughResult>;
|
|
23
|
+
send(statement: SendStatement, ctx: SchemeCtx): Promise<PassthroughResult | ProposalResult>;
|
|
24
|
+
applyResolution(request: ProposalApplyRequest, ctx: SchemeCtx): Promise<ProposalApplyResult>;
|
|
11
25
|
}
|
|
12
26
|
//# sourceMappingURL=A2a.d.ts.map
|
package/dist/A2a.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"A2a.d.ts","sourceRoot":"","sources":["../src/A2a.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"A2a.d.ts","sourceRoot":"","sources":["../src/A2a.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAMH,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,gCAAgC,EACrC,KAAK,+BAA+B,EACpC,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,aAAa,EAGlB,KAAK,aAAa,EACrB,MAAM,wBAAwB,CAAC;AAQhC,MAAM,MAAM,iBAAiB,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,KAAK,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AAe9G;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,GAAG;;IAEpB,QAAQ,CAAC,QAAQ;iBACb,SAAS,EAAE,UAAU;iBACrB,QAAQ;qBAAI,IAAI,EAAE,eAAe;qBAAE,IAAI,EAAE,kBAAkB;;iBAC3D,cAAc,EAAE,MAAM;MACf;IASX,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEhC;IAEK,WAAW,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,CAElF;IAID,YAAY,aAAa,EAAE,iBAAiB,EAE3C;IAEK,qBAAqB,CACvB,OAAO,EAAE,gCAAgC,EACzC,GAAG,EAAE,SAAS,GACf,OAAO,CAAC,+BAA+B,CAAC,CA0E1C;IAMK,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,iBAAiB,GAAG,cAAc,CAAC,CA8BhG;IAEK,eAAe,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAmBjG;CAuVJ"}
|