@aramisfa/openclaw-a2a-outbound 0.2.2 → 2.0.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/README.md +355 -33
- package/dist/capability-diagnostics.d.ts +13 -0
- package/dist/capability-diagnostics.d.ts.map +1 -0
- package/dist/capability-diagnostics.js +131 -0
- package/dist/capability-diagnostics.js.map +1 -0
- package/dist/errors.d.ts +1 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +1 -0
- package/dist/errors.js.map +1 -1
- package/dist/request-normalization.d.ts +4 -10
- package/dist/request-normalization.d.ts.map +1 -1
- package/dist/request-normalization.js +83 -47
- package/dist/request-normalization.js.map +1 -1
- package/dist/result-shape.d.ts +58 -15
- package/dist/result-shape.d.ts.map +1 -1
- package/dist/result-shape.js +324 -85
- package/dist/result-shape.js.map +1 -1
- package/dist/schemas.d.ts +28 -5
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +128 -21
- package/dist/schemas.js.map +1 -1
- package/dist/sdk-client-pool.d.ts +0 -2
- package/dist/sdk-client-pool.d.ts.map +1 -1
- package/dist/sdk-client-pool.js +2 -22
- package/dist/sdk-client-pool.js.map +1 -1
- package/dist/service.d.ts +4 -2
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +333 -80
- package/dist/service.js.map +1 -1
- package/dist/target-catalog.d.ts +27 -5
- package/dist/target-catalog.d.ts.map +1 -1
- package/dist/target-catalog.js +164 -58
- package/dist/target-catalog.js.map +1 -1
- package/dist/task-handle-registry.d.ts +3 -2
- package/dist/task-handle-registry.d.ts.map +1 -1
- package/dist/task-handle-registry.js +7 -0
- package/dist/task-handle-registry.js.map +1 -1
- package/openclaw.plugin.json +42 -12
- package/package.json +10 -10
- package/skills/remote-agent/SKILL.md +74 -8
- package/dist/plugin-config.d.ts +0 -5
- package/dist/plugin-config.d.ts.map +0 -1
- package/dist/plugin-config.js +0 -89
- package/dist/plugin-config.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aramisfa/openclaw-a2a-outbound",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Outbound A2A delegation plugin for OpenClaw agents",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -41,14 +41,6 @@
|
|
|
41
41
|
"./dist/index.js"
|
|
42
42
|
]
|
|
43
43
|
},
|
|
44
|
-
"scripts": {
|
|
45
|
-
"build": "tsc -b",
|
|
46
|
-
"typecheck:src": "tsc -b --pretty false",
|
|
47
|
-
"typecheck:tests": "tsc -p tsconfig.tests.json --pretty false",
|
|
48
|
-
"typecheck": "corepack pnpm run typecheck:src && corepack pnpm run typecheck:tests",
|
|
49
|
-
"test": "corepack pnpm run build && node --import tsx --test tests/*.test.ts",
|
|
50
|
-
"clean": "rm -rf dist"
|
|
51
|
-
},
|
|
52
44
|
"dependencies": {
|
|
53
45
|
"@a2a-js/sdk": "^0.3.10",
|
|
54
46
|
"ajv": "^8.18.0",
|
|
@@ -67,5 +59,13 @@
|
|
|
67
59
|
},
|
|
68
60
|
"publishConfig": {
|
|
69
61
|
"access": "public"
|
|
62
|
+
},
|
|
63
|
+
"scripts": {
|
|
64
|
+
"build": "tsc -b",
|
|
65
|
+
"typecheck:src": "tsc -b --pretty false",
|
|
66
|
+
"typecheck:tests": "tsc -p tsconfig.tests.json --pretty false",
|
|
67
|
+
"typecheck": "corepack pnpm run typecheck:src && corepack pnpm run typecheck:tests",
|
|
68
|
+
"test": "corepack pnpm run build && node --import tsx --test tests/*.test.ts",
|
|
69
|
+
"clean": "rm -rf dist"
|
|
70
70
|
}
|
|
71
|
-
}
|
|
71
|
+
}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: remote-agent
|
|
3
3
|
description: Delegate work to external A2A agents using the remote_agent tool.
|
|
4
|
-
metadata: {"openclaw": {"requires": {"config": ["plugins.entries.openclaw-a2a-outbound.enabled"]}}}
|
|
4
|
+
metadata: {"openclaw": {"requires": {"config": ["plugins.entries.openclaw-a2a-outbound.enabled", "plugins.entries.openclaw-a2a-outbound.config.enabled"]}}}
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Remote Agent Delegation
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
If the plugin is not installed or configured yet, use the `a2a-delegation-setup` skill first.
|
|
10
|
+
|
|
11
|
+
Use the `remote_agent` tool to delegate work to external A2A-compatible agents and manage delegated tasks. `send` is the only action to start a new remote turn or continue an existing one.
|
|
10
12
|
|
|
11
13
|
## When to delegate
|
|
12
14
|
|
|
@@ -38,21 +40,85 @@ Discover configured targets.
|
|
|
38
40
|
|
|
39
41
|
### send
|
|
40
42
|
|
|
41
|
-
Send a request to a remote agent.
|
|
43
|
+
Send a request to a remote agent. Use it for:
|
|
44
|
+
|
|
45
|
+
- a brand-new remote task
|
|
46
|
+
- a follow-up turn on an existing remote task
|
|
47
|
+
- a related new task that references prior work
|
|
48
|
+
- a new task inside an existing remote conversation
|
|
42
49
|
|
|
43
50
|
```json
|
|
44
51
|
{
|
|
45
52
|
"action": "send",
|
|
46
53
|
"target_alias": "my-agent",
|
|
47
|
-
"
|
|
54
|
+
"parts": [
|
|
55
|
+
{
|
|
56
|
+
"kind": "text",
|
|
57
|
+
"text": "Summarize the latest quarterly report."
|
|
58
|
+
}
|
|
59
|
+
],
|
|
48
60
|
"follow_updates": true
|
|
49
61
|
}
|
|
50
62
|
```
|
|
51
63
|
|
|
52
|
-
- `
|
|
64
|
+
- `parts` (required): non-empty array of `text`, `file`, or `data` parts.
|
|
53
65
|
- `target_alias`: configured target name. Omit when a default target exists.
|
|
54
|
-
- `
|
|
55
|
-
- `
|
|
66
|
+
- `task_handle`: preferred continuation key for `send`, `watch`, `status`, and `cancel`.
|
|
67
|
+
- `task_id`: optional continuation id for `send`; for follow-up actions it identifies the remote task when no `task_handle` is available. `task_id` continues an existing task.
|
|
68
|
+
- `context_id`: optional conversation continuation id for `send`. Use it with `task_id`, or by itself to start a new task in the same conversation.
|
|
69
|
+
- `reference_task_ids`: optional related task ids for `send`. `reference_task_ids` references prior tasks without continuing them.
|
|
70
|
+
- `task_requirement`: optional durability contract. `task_requirement="required"` forces explicit task creation or fails fast.
|
|
71
|
+
- `follow_updates`: when `true`, streams updates and returns the full event log. `follow_updates=true` means “stream the initial send”; it does not guarantee task creation unless `task_requirement="required"`.
|
|
72
|
+
- `blocking`: only for non-stream `send`; do not combine it with `follow_updates=true`.
|
|
73
|
+
|
|
74
|
+
Preferred continuation forms:
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{ "action": "send", "task_handle": "rah_abc123", "parts": [{ "kind": "text", "text": "Approved. Continue." }] }
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{ "action": "send", "target_alias": "my-agent", "task_id": "task-123", "parts": [{ "kind": "text", "text": "Continue the task." }] }
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{ "action": "send", "target_alias": "my-agent", "context_id": "ctx-123", "parts": [{ "kind": "text", "text": "Start a new task in the same conversation." }] }
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{ "action": "send", "target_alias": "my-agent", "context_id": "ctx-123", "reference_task_ids": ["task-1", "task-2"], "parts": [{ "kind": "text", "text": "Start related work without continuing those tasks." }] }
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Continuation safety
|
|
93
|
+
|
|
94
|
+
Interpret follow-up capability from `result.summary.continuation`, not from prompt text, message text, or other inferred context.
|
|
95
|
+
|
|
96
|
+
- `response_kind` is descriptive only. Keep follow-up logic anchored to `summary.continuation`.
|
|
97
|
+
- `summary.continuation.task`: trackable task continuity. Use it for follow-up `send`, `watch`, `status`, and `cancel`.
|
|
98
|
+
- `summary.continuation.conversation`: conversation continuity only. Use it only with `send` to start a new task in the same conversation.
|
|
99
|
+
- Branch on `summary.continuation.task` vs `summary.continuation.conversation` before choosing the next action.
|
|
100
|
+
- Never infer or synthesize `summary.continuation.task` from `summary.continuation.conversation`, session ids, run ids, prior prompts, or summary text.
|
|
101
|
+
- Do not call `watch`, `status`, or `cancel` from a result that has only `summary.continuation.conversation`.
|
|
102
|
+
- If lifecycle tracking is required, fail fast when the peer returns only `summary.continuation.conversation`.
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
const task = result.summary.continuation?.task
|
|
106
|
+
const conversation = result.summary.continuation?.conversation
|
|
107
|
+
|
|
108
|
+
if (task) {
|
|
109
|
+
// Trackable task lifecycle.
|
|
110
|
+
} else if (conversation) {
|
|
111
|
+
// Send-only conversation continuity.
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Invalid follow-up example:
|
|
116
|
+
|
|
117
|
+
```json
|
|
118
|
+
{ "action": "status", "context_id": "ctx-123" }
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
That is invalid because `status`, `watch`, and `cancel` require task continuity, not just conversation continuity.
|
|
56
122
|
|
|
57
123
|
### status
|
|
58
124
|
|
|
@@ -80,7 +146,7 @@ Cancel a running task.
|
|
|
80
146
|
|
|
81
147
|
## Task handles
|
|
82
148
|
|
|
83
|
-
After a successful `send`, the result includes
|
|
149
|
+
After a successful `send`, the result usually includes `summary.continuation.task.task_handle` (prefixed `rah_`) when the remote peer exposes task continuity. `task_handle` is returned only when the peer actually created a task. Always prefer `summary.continuation.task.task_handle` over `target_alias + summary.continuation.task.task_id` for follow-up `send`/`watch`/`status`/`cancel` actions. Handles are process-local and expire after restart or TTL. If a handle expires, fall back to `target_alias` + `summary.continuation.task.task_id`. Treat `send.task_id` as a continuation id for the remote peer, not as a replacement for `summary.continuation.task.task_handle`. If the result includes only `summary.continuation.conversation`, there is no task lifecycle to poll, watch, or cancel.
|
|
84
150
|
|
|
85
151
|
## watch vs status
|
|
86
152
|
|
package/dist/plugin-config.d.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { OpenClawPluginConfigSchema } from "openclaw/plugin-sdk";
|
|
2
|
-
import { type A2AOutboundPluginConfig } from "./constants.js";
|
|
3
|
-
export declare function parseA2AOutboundPluginConfig(input: unknown): A2AOutboundPluginConfig;
|
|
4
|
-
export declare const A2AOutboundPluginConfigSchema: OpenClawPluginConfigSchema;
|
|
5
|
-
//# sourceMappingURL=plugin-config.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-config.d.ts","sourceRoot":"","sources":["../src/plugin-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAGL,KAAK,uBAAuB,EAE7B,MAAM,gBAAgB,CAAC;AAuFxB,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,OAAO,GACb,uBAAuB,CA4CzB;AAED,eAAO,MAAM,6BAA6B,EAAE,0BAI3C,CAAC"}
|
package/dist/plugin-config.js
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { ALL_TRANSPORTS, DEFAULTS, } from "./constants.js";
|
|
2
|
-
function cloneConfig(config) {
|
|
3
|
-
return {
|
|
4
|
-
enabled: config.enabled,
|
|
5
|
-
defaults: {
|
|
6
|
-
timeoutMs: config.defaults.timeoutMs,
|
|
7
|
-
cardPath: config.defaults.cardPath,
|
|
8
|
-
preferredTransports: [...config.defaults.preferredTransports],
|
|
9
|
-
serviceParameters: { ...config.defaults.serviceParameters },
|
|
10
|
-
},
|
|
11
|
-
policy: {
|
|
12
|
-
acceptedOutputModes: [...config.policy.acceptedOutputModes],
|
|
13
|
-
normalizeBaseUrl: config.policy.normalizeBaseUrl,
|
|
14
|
-
enforceSupportedTransports: config.policy.enforceSupportedTransports,
|
|
15
|
-
},
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
function isPlainObject(value) {
|
|
19
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20
|
-
}
|
|
21
|
-
function normalizeStringArray(value, fallback = []) {
|
|
22
|
-
if (!Array.isArray(value)) {
|
|
23
|
-
return [...fallback];
|
|
24
|
-
}
|
|
25
|
-
const normalized = [];
|
|
26
|
-
for (const entry of value) {
|
|
27
|
-
if (typeof entry !== "string" || entry.trim() === "") {
|
|
28
|
-
continue;
|
|
29
|
-
}
|
|
30
|
-
if (!normalized.includes(entry)) {
|
|
31
|
-
normalized.push(entry);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
return normalized;
|
|
35
|
-
}
|
|
36
|
-
function normalizeTransports(value, fallback) {
|
|
37
|
-
const normalized = normalizeStringArray(value).filter((entry) => ALL_TRANSPORTS.includes(entry));
|
|
38
|
-
return normalized.length > 0 ? normalized : [...fallback];
|
|
39
|
-
}
|
|
40
|
-
function normalizeStringMap(value, fallback = {}) {
|
|
41
|
-
if (!isPlainObject(value)) {
|
|
42
|
-
return { ...fallback };
|
|
43
|
-
}
|
|
44
|
-
const normalized = {};
|
|
45
|
-
for (const [key, entry] of Object.entries(value)) {
|
|
46
|
-
if (typeof entry === "string") {
|
|
47
|
-
normalized[key] = entry;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return normalized;
|
|
51
|
-
}
|
|
52
|
-
function readBoolean(value, fallback) {
|
|
53
|
-
return typeof value === "boolean" ? value : fallback;
|
|
54
|
-
}
|
|
55
|
-
function readPositiveInteger(value, fallback) {
|
|
56
|
-
return Number.isInteger(value) && value > 0
|
|
57
|
-
? value
|
|
58
|
-
: fallback;
|
|
59
|
-
}
|
|
60
|
-
export function parseA2AOutboundPluginConfig(input) {
|
|
61
|
-
if (!isPlainObject(input)) {
|
|
62
|
-
return cloneConfig(DEFAULTS);
|
|
63
|
-
}
|
|
64
|
-
const rawDefaults = isPlainObject(input.defaults) ? input.defaults : {};
|
|
65
|
-
const rawPolicy = isPlainObject(input.policy) ? input.policy : {};
|
|
66
|
-
return {
|
|
67
|
-
enabled: readBoolean(input.enabled, DEFAULTS.enabled),
|
|
68
|
-
defaults: {
|
|
69
|
-
timeoutMs: readPositiveInteger(rawDefaults.timeoutMs, DEFAULTS.defaults.timeoutMs),
|
|
70
|
-
cardPath: typeof rawDefaults.cardPath === "string" &&
|
|
71
|
-
rawDefaults.cardPath.trim() !== ""
|
|
72
|
-
? rawDefaults.cardPath
|
|
73
|
-
: DEFAULTS.defaults.cardPath,
|
|
74
|
-
preferredTransports: normalizeTransports(rawDefaults.preferredTransports, DEFAULTS.defaults.preferredTransports),
|
|
75
|
-
serviceParameters: normalizeStringMap(rawDefaults.serviceParameters, DEFAULTS.defaults.serviceParameters),
|
|
76
|
-
},
|
|
77
|
-
policy: {
|
|
78
|
-
acceptedOutputModes: normalizeStringArray(rawPolicy.acceptedOutputModes, DEFAULTS.policy.acceptedOutputModes),
|
|
79
|
-
normalizeBaseUrl: readBoolean(rawPolicy.normalizeBaseUrl, DEFAULTS.policy.normalizeBaseUrl),
|
|
80
|
-
enforceSupportedTransports: readBoolean(rawPolicy.enforceSupportedTransports, DEFAULTS.policy.enforceSupportedTransports),
|
|
81
|
-
},
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
export const A2AOutboundPluginConfigSchema = {
|
|
85
|
-
parse(value) {
|
|
86
|
-
return parseA2AOutboundPluginConfig(value);
|
|
87
|
-
},
|
|
88
|
-
};
|
|
89
|
-
//# sourceMappingURL=plugin-config.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-config.js","sourceRoot":"","sources":["../src/plugin-config.ts"],"names":[],"mappings":"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"}
|