aibroker 0.54.0 → 0.55.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 +3 -0
- package/dist/a2a/agentish-extension.d.ts +111 -0
- package/dist/a2a/agentish-extension.d.ts.map +1 -0
- package/dist/a2a/agentish-extension.js +124 -0
- package/dist/a2a/agentish-extension.js.map +1 -0
- package/dist/a2a/client.d.ts +45 -0
- package/dist/a2a/client.d.ts.map +1 -0
- package/dist/a2a/client.js +112 -0
- package/dist/a2a/client.js.map +1 -0
- package/dist/a2a/exposure.d.ts +24 -0
- package/dist/a2a/exposure.d.ts.map +1 -0
- package/dist/a2a/exposure.js +70 -0
- package/dist/a2a/exposure.js.map +1 -0
- package/dist/a2a/schema/types.d.ts +153 -0
- package/dist/a2a/schema/types.d.ts.map +1 -0
- package/dist/a2a/schema/types.js +28 -0
- package/dist/a2a/schema/types.js.map +1 -0
- package/dist/a2a/schema/validate.d.ts +27 -0
- package/dist/a2a/schema/validate.d.ts.map +1 -0
- package/dist/a2a/schema/validate.js +190 -0
- package/dist/a2a/schema/validate.js.map +1 -0
- package/dist/a2a/server.d.ts +73 -0
- package/dist/a2a/server.d.ts.map +1 -0
- package/dist/a2a/server.js +325 -0
- package/dist/a2a/server.js.map +1 -0
- package/dist/a2a/tasks.d.ts +81 -0
- package/dist/a2a/tasks.d.ts.map +1 -0
- package/dist/a2a/tasks.js +148 -0
- package/dist/a2a/tasks.js.map +1 -0
- package/dist/agentish/index.d.ts +80 -0
- package/dist/agentish/index.d.ts.map +1 -0
- package/dist/agentish/index.js +263 -0
- package/dist/agentish/index.js.map +1 -0
- package/dist/daemon/a2a-cli.d.ts +46 -0
- package/dist/daemon/a2a-cli.d.ts.map +1 -0
- package/dist/daemon/a2a-cli.js +385 -0
- package/dist/daemon/a2a-cli.js.map +1 -0
- package/dist/daemon/agentish-cli.d.ts +17 -0
- package/dist/daemon/agentish-cli.d.ts.map +1 -0
- package/dist/daemon/agentish-cli.js +137 -0
- package/dist/daemon/agentish-cli.js.map +1 -0
- package/dist/daemon/agentish-stats.d.ts +65 -0
- package/dist/daemon/agentish-stats.d.ts.map +1 -0
- package/dist/daemon/agentish-stats.js +125 -0
- package/dist/daemon/agentish-stats.js.map +1 -0
- package/dist/daemon/agentish.d.ts +13 -0
- package/dist/daemon/agentish.d.ts.map +1 -0
- package/dist/daemon/agentish.js +13 -0
- package/dist/daemon/agentish.js.map +1 -0
- package/dist/daemon/cli.js +12 -1
- package/dist/daemon/cli.js.map +1 -1
- package/dist/daemon/core-handlers.d.ts.map +1 -1
- package/dist/daemon/core-handlers.js +38 -0
- package/dist/daemon/core-handlers.js.map +1 -1
- package/dist/daemon/manage.d.ts.map +1 -1
- package/dist/daemon/manage.js +10 -1
- package/dist/daemon/manage.js.map +1 -1
- package/dist/daemon/todoist-webhook.d.ts +25 -2
- package/dist/daemon/todoist-webhook.d.ts.map +1 -1
- package/dist/daemon/todoist-webhook.js +136 -17
- package/dist/daemon/todoist-webhook.js.map +1 -1
- package/dist/mcp/index.js +41 -1
- package/dist/mcp/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -475,6 +475,9 @@ Addressing is explicit: `hub:machine-b/session:abc` routes through the bridge to
|
|
|
475
475
|
| [routing.md](docs/routing.md) | Message routing logic and channel system |
|
|
476
476
|
| [sessions.md](docs/sessions.md) | Session management and lifecycle |
|
|
477
477
|
| [commands.md](docs/commands.md) | Slash command reference |
|
|
478
|
+
| [agentish.md](docs/agentish.md) | AG2: the wire format sessions use to talk to each other |
|
|
479
|
+
| [a2a-agentish-extension.md](docs/a2a-agentish-extension.md) | AG2 declared as an A2A protocol extension (definition + helpers, no transport) |
|
|
480
|
+
| [a2a.md](docs/a2a.md) | A2A v0.3.0 transport: expose sessions as skills for outside agents to task, and task outside agents from a session |
|
|
478
481
|
| [mcp-tools.md](docs/mcp-tools.md) | All 42 MCP tools with parameters |
|
|
479
482
|
| [adapters.md](docs/adapters.md) | Adapter development guide |
|
|
480
483
|
| [pailot.md](docs/pailot.md) | PAILot iOS app integration |
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* a2a/agentish-extension.ts — Agentish v2 (AG2) declared as an A2A protocol
|
|
3
|
+
* extension.
|
|
4
|
+
*
|
|
5
|
+
* A2A already carries a Message built of typed Parts (spec 4.1.4/4.1.6 in
|
|
6
|
+
* the current draft; 6.4/6.5 in the stable v0.3.0 JSON-RPC spec) — it does
|
|
7
|
+
* not say what the words inside a text part mean. AG2 is a wire format for
|
|
8
|
+
* what agents tell each other about a job: a kind line plus k=v lines
|
|
9
|
+
* instead of prose. Declaring it as an A2A extension (spec 4.6 "Extensions",
|
|
10
|
+
* 5.5.2.1 "AgentExtension Object" in v0.3.0) means any A2A agent can say "I
|
|
11
|
+
* understand AG2" in its AgentCard, and any other A2A agent can check that
|
|
12
|
+
* declaration before sending AG2 text — without AG2 needing its own
|
|
13
|
+
* transport, auth, or discovery story. A2A already has those.
|
|
14
|
+
*
|
|
15
|
+
* This module defines the extension: its URI, its AgentCard fragment, and
|
|
16
|
+
* helpers to mark and validate a Part as carrying AG2 text. It does not run
|
|
17
|
+
* an A2A server — see docs/a2a-agentish-extension.md for what that would
|
|
18
|
+
* still take.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Extension identifier (A2A spec 5.5.2.1: AgentExtension.uri — "The unique
|
|
22
|
+
* URI identifying the extension"). One URN, one definition — this is an
|
|
23
|
+
* alias of `AGENTISH_URI` from agentish/index.ts, not a second constant
|
|
24
|
+
* that could drift from it. A2A does not require the URI to resolve, so it
|
|
25
|
+
* is a `urn:`, not an `https:` URL pointing at a domain nobody has
|
|
26
|
+
* registered or serves. `AGENTISH_SPEC_URL` below is the resolvable
|
|
27
|
+
* pointer, for callers that want one.
|
|
28
|
+
*/
|
|
29
|
+
export declare const AGENTISH_EXTENSION_URI = "urn:aibroker:a2a:ext:agentish:2";
|
|
30
|
+
/**
|
|
31
|
+
* Where to find the AG2 spec this extension declares. Not a network
|
|
32
|
+
* location — an aibroker installation ships this file at this path, so it
|
|
33
|
+
* resolves against the aibroker package or repository you installed from
|
|
34
|
+
* (npm package root, or a checkout of the source repository).
|
|
35
|
+
*/
|
|
36
|
+
export declare const AGENTISH_SPEC_URL = "docs/agentish.md";
|
|
37
|
+
/** Media type an AG2-carrying Part may advertise instead of (or in addition
|
|
38
|
+
* to) the `metadata.agentish` tag — see isAg2Part(). Matches the emerging
|
|
39
|
+
* A2A draft's per-part `mediaType` field (not yet in the stable v0.3.0
|
|
40
|
+
* TextPart shape); ag2Part() does not emit it today, but isAg2Part()
|
|
41
|
+
* already recognizes it so a differently-built AG2 part is not missed. */
|
|
42
|
+
export declare const AGENTISH_MEDIA_TYPE = "text/x-agentish";
|
|
43
|
+
/** Shape of one `AgentCard.capabilities.extensions[]` entry (A2A spec
|
|
44
|
+
* 5.5.2.1, AgentExtension Object: uri, description, required, params). */
|
|
45
|
+
export interface AgentishExtensionDeclaration {
|
|
46
|
+
uri: string;
|
|
47
|
+
description: string;
|
|
48
|
+
required: boolean;
|
|
49
|
+
params: {
|
|
50
|
+
version: string;
|
|
51
|
+
spec: string;
|
|
52
|
+
spec_url: string;
|
|
53
|
+
extensions: string;
|
|
54
|
+
validator: string;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Build the `AgentCard.capabilities.extensions[]` entry that declares AG2
|
|
59
|
+
* support. `required: false` — an agent that does not understand AG2 can
|
|
60
|
+
* still exchange plain-text Messages with this one; AG2 is additive, never
|
|
61
|
+
* load-bearing for the base protocol.
|
|
62
|
+
*/
|
|
63
|
+
export declare function agentCardExtension(): AgentishExtensionDeclaration;
|
|
64
|
+
/**
|
|
65
|
+
* Minimal shape this module needs from A2A's TextPart (spec 6.5.1, stable
|
|
66
|
+
* v0.3.0: `{ kind: "text", text, metadata? }`), declared locally so this
|
|
67
|
+
* module carries no dependency on an A2A SDK.
|
|
68
|
+
*/
|
|
69
|
+
export interface A2ATextPart {
|
|
70
|
+
readonly kind: "text";
|
|
71
|
+
text: string;
|
|
72
|
+
metadata?: Record<string, unknown>;
|
|
73
|
+
/** Not part of the stable v0.3.0 TextPart shape — carried here only so
|
|
74
|
+
* isAg2Part() can also recognize a part tagged this way instead of via
|
|
75
|
+
* metadata. See AGENTISH_MEDIA_TYPE. */
|
|
76
|
+
mediaType?: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Build a TextPart carrying AG2 text, tagged via `metadata.agentish: "2"`
|
|
80
|
+
* so a receiver can recognize it as AG2 before parsing the text itself.
|
|
81
|
+
* Metadata is the extension point A2A defines for exactly this purpose
|
|
82
|
+
* (spec 4.6.2 "Extension Points": Message/Part metadata keyed by the
|
|
83
|
+
* extension's concern).
|
|
84
|
+
*/
|
|
85
|
+
export declare function ag2Part(text: string): A2ATextPart;
|
|
86
|
+
/**
|
|
87
|
+
* True if `part` is a TextPart tagged as AG2, either by ag2Part()'s
|
|
88
|
+
* `metadata.agentish === "2"` convention or by a `mediaType`/`mimeType` of
|
|
89
|
+
* `text/x-agentish` (AGENTISH_MEDIA_TYPE) — some other sender may tag a
|
|
90
|
+
* part that way instead. Either is sufficient; neither is required to be
|
|
91
|
+
* absent. Does not validate the text itself — use validateAg2Part() for
|
|
92
|
+
* that.
|
|
93
|
+
*/
|
|
94
|
+
export declare function isAg2Part(part: unknown): part is A2ATextPart;
|
|
95
|
+
export interface Ag2PartValidation {
|
|
96
|
+
ok: boolean;
|
|
97
|
+
errors: string[];
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Validate an AG2-tagged Part's text against the AG2 grammar. Delegates to
|
|
101
|
+
* daemon/agentish.ts's `check()` — this module owns only the A2A wrapping,
|
|
102
|
+
* not the grammar itself. `earlier` is the thread's prior AG2 message texts,
|
|
103
|
+
* passed through unchanged so `@n=path` symbols they declared stay in scope
|
|
104
|
+
* (same contract as `check()`).
|
|
105
|
+
*
|
|
106
|
+
* Returns `ok: false` with one synthetic error if `part` is not an AG2 part
|
|
107
|
+
* at all, so a caller that skipped `isAg2Part()` still gets a usable result
|
|
108
|
+
* instead of a thrown error.
|
|
109
|
+
*/
|
|
110
|
+
export declare function validateAg2Part(part: unknown, earlier?: string[]): Ag2PartValidation;
|
|
111
|
+
//# sourceMappingURL=agentish-extension.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentish-extension.d.ts","sourceRoot":"","sources":["../../src/a2a/agentish-extension.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,oCAAe,CAAC;AAEnD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,qBAAqB,CAAC;AAEpD;;;;2EAI2E;AAC3E,eAAO,MAAM,mBAAmB,oBAAoB,CAAC;AAErD;2EAC2E;AAC3E,MAAM,WAAW,4BAA4B;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,4BAA4B,CAgBjE;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC;;6CAEyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAMjD;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,WAAW,CAe5D;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,GAAE,MAAM,EAAO,GAAG,iBAAiB,CASxF"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* a2a/agentish-extension.ts — Agentish v2 (AG2) declared as an A2A protocol
|
|
3
|
+
* extension.
|
|
4
|
+
*
|
|
5
|
+
* A2A already carries a Message built of typed Parts (spec 4.1.4/4.1.6 in
|
|
6
|
+
* the current draft; 6.4/6.5 in the stable v0.3.0 JSON-RPC spec) — it does
|
|
7
|
+
* not say what the words inside a text part mean. AG2 is a wire format for
|
|
8
|
+
* what agents tell each other about a job: a kind line plus k=v lines
|
|
9
|
+
* instead of prose. Declaring it as an A2A extension (spec 4.6 "Extensions",
|
|
10
|
+
* 5.5.2.1 "AgentExtension Object" in v0.3.0) means any A2A agent can say "I
|
|
11
|
+
* understand AG2" in its AgentCard, and any other A2A agent can check that
|
|
12
|
+
* declaration before sending AG2 text — without AG2 needing its own
|
|
13
|
+
* transport, auth, or discovery story. A2A already has those.
|
|
14
|
+
*
|
|
15
|
+
* This module defines the extension: its URI, its AgentCard fragment, and
|
|
16
|
+
* helpers to mark and validate a Part as carrying AG2 text. It does not run
|
|
17
|
+
* an A2A server — see docs/a2a-agentish-extension.md for what that would
|
|
18
|
+
* still take.
|
|
19
|
+
*/
|
|
20
|
+
import { AG2_SPEC, AG2_EXTENSIONS, AGENTISH_URI, check } from "../agentish/index.js";
|
|
21
|
+
/**
|
|
22
|
+
* Extension identifier (A2A spec 5.5.2.1: AgentExtension.uri — "The unique
|
|
23
|
+
* URI identifying the extension"). One URN, one definition — this is an
|
|
24
|
+
* alias of `AGENTISH_URI` from agentish/index.ts, not a second constant
|
|
25
|
+
* that could drift from it. A2A does not require the URI to resolve, so it
|
|
26
|
+
* is a `urn:`, not an `https:` URL pointing at a domain nobody has
|
|
27
|
+
* registered or serves. `AGENTISH_SPEC_URL` below is the resolvable
|
|
28
|
+
* pointer, for callers that want one.
|
|
29
|
+
*/
|
|
30
|
+
export const AGENTISH_EXTENSION_URI = AGENTISH_URI;
|
|
31
|
+
/**
|
|
32
|
+
* Where to find the AG2 spec this extension declares. Not a network
|
|
33
|
+
* location — an aibroker installation ships this file at this path, so it
|
|
34
|
+
* resolves against the aibroker package or repository you installed from
|
|
35
|
+
* (npm package root, or a checkout of the source repository).
|
|
36
|
+
*/
|
|
37
|
+
export const AGENTISH_SPEC_URL = "docs/agentish.md";
|
|
38
|
+
/** Media type an AG2-carrying Part may advertise instead of (or in addition
|
|
39
|
+
* to) the `metadata.agentish` tag — see isAg2Part(). Matches the emerging
|
|
40
|
+
* A2A draft's per-part `mediaType` field (not yet in the stable v0.3.0
|
|
41
|
+
* TextPart shape); ag2Part() does not emit it today, but isAg2Part()
|
|
42
|
+
* already recognizes it so a differently-built AG2 part is not missed. */
|
|
43
|
+
export const AGENTISH_MEDIA_TYPE = "text/x-agentish";
|
|
44
|
+
/**
|
|
45
|
+
* Build the `AgentCard.capabilities.extensions[]` entry that declares AG2
|
|
46
|
+
* support. `required: false` — an agent that does not understand AG2 can
|
|
47
|
+
* still exchange plain-text Messages with this one; AG2 is additive, never
|
|
48
|
+
* load-bearing for the base protocol.
|
|
49
|
+
*/
|
|
50
|
+
export function agentCardExtension() {
|
|
51
|
+
return {
|
|
52
|
+
uri: AGENTISH_EXTENSION_URI,
|
|
53
|
+
description: "Agentish v2 (AG2): a compact kind+k=v wire format for agent-to-agent " +
|
|
54
|
+
"task reports. params.spec carries the format; params.validator names " +
|
|
55
|
+
"the CLI that checks a message against it.",
|
|
56
|
+
required: false,
|
|
57
|
+
params: {
|
|
58
|
+
version: "2",
|
|
59
|
+
spec: AG2_SPEC,
|
|
60
|
+
spec_url: AGENTISH_SPEC_URL,
|
|
61
|
+
extensions: AG2_EXTENSIONS,
|
|
62
|
+
validator: "aibroker agentish check",
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Build a TextPart carrying AG2 text, tagged via `metadata.agentish: "2"`
|
|
68
|
+
* so a receiver can recognize it as AG2 before parsing the text itself.
|
|
69
|
+
* Metadata is the extension point A2A defines for exactly this purpose
|
|
70
|
+
* (spec 4.6.2 "Extension Points": Message/Part metadata keyed by the
|
|
71
|
+
* extension's concern).
|
|
72
|
+
*/
|
|
73
|
+
export function ag2Part(text) {
|
|
74
|
+
return {
|
|
75
|
+
kind: "text",
|
|
76
|
+
text,
|
|
77
|
+
metadata: { agentish: "2" },
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* True if `part` is a TextPart tagged as AG2, either by ag2Part()'s
|
|
82
|
+
* `metadata.agentish === "2"` convention or by a `mediaType`/`mimeType` of
|
|
83
|
+
* `text/x-agentish` (AGENTISH_MEDIA_TYPE) — some other sender may tag a
|
|
84
|
+
* part that way instead. Either is sufficient; neither is required to be
|
|
85
|
+
* absent. Does not validate the text itself — use validateAg2Part() for
|
|
86
|
+
* that.
|
|
87
|
+
*/
|
|
88
|
+
export function isAg2Part(part) {
|
|
89
|
+
if (typeof part !== "object" || part === null)
|
|
90
|
+
return false;
|
|
91
|
+
const p = part;
|
|
92
|
+
if (p.kind !== "text")
|
|
93
|
+
return false;
|
|
94
|
+
if (typeof p.text !== "string")
|
|
95
|
+
return false;
|
|
96
|
+
const metadata = p.metadata;
|
|
97
|
+
const taggedByMetadata = typeof metadata === "object" &&
|
|
98
|
+
metadata !== null &&
|
|
99
|
+
metadata.agentish === "2";
|
|
100
|
+
const taggedByMediaType = p.mediaType === AGENTISH_MEDIA_TYPE || p.mimeType === AGENTISH_MEDIA_TYPE;
|
|
101
|
+
return taggedByMetadata || taggedByMediaType;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Validate an AG2-tagged Part's text against the AG2 grammar. Delegates to
|
|
105
|
+
* daemon/agentish.ts's `check()` — this module owns only the A2A wrapping,
|
|
106
|
+
* not the grammar itself. `earlier` is the thread's prior AG2 message texts,
|
|
107
|
+
* passed through unchanged so `@n=path` symbols they declared stay in scope
|
|
108
|
+
* (same contract as `check()`).
|
|
109
|
+
*
|
|
110
|
+
* Returns `ok: false` with one synthetic error if `part` is not an AG2 part
|
|
111
|
+
* at all, so a caller that skipped `isAg2Part()` still gets a usable result
|
|
112
|
+
* instead of a thrown error.
|
|
113
|
+
*/
|
|
114
|
+
export function validateAg2Part(part, earlier = []) {
|
|
115
|
+
if (!isAg2Part(part)) {
|
|
116
|
+
return {
|
|
117
|
+
ok: false,
|
|
118
|
+
errors: ["not an AG2 part: missing kind:\"text\" or metadata.agentish:\"2\""],
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
const result = check(part.text, earlier);
|
|
122
|
+
return { ok: result.errors.length === 0, errors: result.errors };
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=agentish-extension.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentish-extension.js","sourceRoot":"","sources":["../../src/a2a/agentish-extension.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAErF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,YAAY,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,kBAAkB,CAAC;AAEpD;;;;2EAI2E;AAC3E,MAAM,CAAC,MAAM,mBAAmB,GAAG,iBAAiB,CAAC;AAiBrD;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO;QACL,GAAG,EAAE,sBAAsB;QAC3B,WAAW,EACT,uEAAuE;YACvE,uEAAuE;YACvE,2CAA2C;QAC7C,QAAQ,EAAE,KAAK;QACf,MAAM,EAAE;YACN,OAAO,EAAE,GAAG;YACZ,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,iBAAiB;YAC3B,UAAU,EAAE,cAAc;YAC1B,SAAS,EAAE,yBAAyB;SACrC;KACF,CAAC;AACJ,CAAC;AAiBD;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,IAAI;QACJ,QAAQ,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE;KAC5B,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CAAC,IAAa;IACrC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC5D,MAAM,CAAC,GAAG,IAA+B,CAAC;IAC1C,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IACpC,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAE7C,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC;IAC5B,MAAM,gBAAgB,GACpB,OAAO,QAAQ,KAAK,QAAQ;QAC5B,QAAQ,KAAK,IAAI;QAChB,QAAoC,CAAC,QAAQ,KAAK,GAAG,CAAC;IAEzD,MAAM,iBAAiB,GAAG,CAAC,CAAC,SAAS,KAAK,mBAAmB,IAAI,CAAC,CAAC,QAAQ,KAAK,mBAAmB,CAAC;IAEpG,OAAO,gBAAgB,IAAI,iBAAiB,CAAC;AAC/C,CAAC;AAOD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAAC,IAAa,EAAE,UAAoB,EAAE;IACnE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,CAAC,mEAAmE,CAAC;SAC9E,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACzC,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;AACnE,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* a2a/client.ts — AIBroker as an A2A client: task an OUTSIDE agent's
|
|
3
|
+
* exposed skill and poll for its answer.
|
|
4
|
+
*
|
|
5
|
+
* Fetch-only, no dependencies, works against any A2A v0.3.0 server —
|
|
6
|
+
* that is the point of `aibroker a2a check` in a2a-cli.ts, which runs
|
|
7
|
+
* this client against an arbitrary remote agent and reports pass/fail per
|
|
8
|
+
* step rather than assuming aibroker's own server is the only target.
|
|
9
|
+
*/
|
|
10
|
+
import type { AgentCard, Task } from "./schema/types.js";
|
|
11
|
+
export interface FetchAgentCardResult {
|
|
12
|
+
ok: boolean;
|
|
13
|
+
card?: AgentCard;
|
|
14
|
+
errors: string[];
|
|
15
|
+
}
|
|
16
|
+
/** GET <base>/.well-known/agent-card.json, validated against the vendored schema. */
|
|
17
|
+
export declare function fetchAgentCard(baseUrl: string): Promise<FetchAgentCardResult>;
|
|
18
|
+
export interface SendMessageResult {
|
|
19
|
+
ok: boolean;
|
|
20
|
+
task?: Task;
|
|
21
|
+
error?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface SendMessageOptions {
|
|
24
|
+
/** Which exposed skill/session to target. Optional because a generic A2A
|
|
25
|
+
* agent — the target of `aibroker a2a check` — need not have this concept
|
|
26
|
+
* at all; aibroker's own server requires it (or message.metadata.session). */
|
|
27
|
+
skillId?: string;
|
|
28
|
+
text: string;
|
|
29
|
+
/** Tag the text part as an AG2 (Agentish v2) message per the extension. */
|
|
30
|
+
ag2?: boolean;
|
|
31
|
+
token?: string;
|
|
32
|
+
contextId?: string;
|
|
33
|
+
agentName?: string;
|
|
34
|
+
}
|
|
35
|
+
export declare function sendMessage(a2aUrl: string, opts: SendMessageOptions): Promise<SendMessageResult>;
|
|
36
|
+
export declare function getTask(a2aUrl: string, taskId: string, token?: string): Promise<SendMessageResult>;
|
|
37
|
+
export declare function cancelTask(a2aUrl: string, taskId: string, token?: string): Promise<SendMessageResult>;
|
|
38
|
+
export interface PollOptions {
|
|
39
|
+
intervalMs?: number;
|
|
40
|
+
timeoutMs?: number;
|
|
41
|
+
token?: string;
|
|
42
|
+
}
|
|
43
|
+
/** Poll tasks/get until the task reaches a terminal state or the timeout elapses. */
|
|
44
|
+
export declare function pollUntilDone(a2aUrl: string, taskId: string, opts?: PollOptions): Promise<SendMessageResult>;
|
|
45
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/a2a/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAa,MAAM,mBAAmB,CAAC;AAGpE,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,qFAAqF;AACrF,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAiBnF;AA+BD,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC;;mFAE+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CActG;AAED,wBAAsB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAMxG;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAI3G;AAID,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qFAAqF;AACrF,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAUtH"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* a2a/client.ts — AIBroker as an A2A client: task an OUTSIDE agent's
|
|
3
|
+
* exposed skill and poll for its answer.
|
|
4
|
+
*
|
|
5
|
+
* Fetch-only, no dependencies, works against any A2A v0.3.0 server —
|
|
6
|
+
* that is the point of `aibroker a2a check` in a2a-cli.ts, which runs
|
|
7
|
+
* this client against an arbitrary remote agent and reports pass/fail per
|
|
8
|
+
* step rather than assuming aibroker's own server is the only target.
|
|
9
|
+
*/
|
|
10
|
+
import { validateAgentCard, validateTask } from "./schema/validate.js";
|
|
11
|
+
import { ag2Part } from "./agentish-extension.js";
|
|
12
|
+
/** GET <base>/.well-known/agent-card.json, validated against the vendored schema. */
|
|
13
|
+
export async function fetchAgentCard(baseUrl) {
|
|
14
|
+
const url = new URL("/.well-known/agent-card.json", baseUrl).toString();
|
|
15
|
+
let res;
|
|
16
|
+
try {
|
|
17
|
+
res = await fetch(url);
|
|
18
|
+
}
|
|
19
|
+
catch (e) {
|
|
20
|
+
return { ok: false, errors: [`fetch failed: ${e instanceof Error ? e.message : String(e)}`] };
|
|
21
|
+
}
|
|
22
|
+
if (!res.ok)
|
|
23
|
+
return { ok: false, errors: [`HTTP ${res.status} fetching ${url}`] };
|
|
24
|
+
let body;
|
|
25
|
+
try {
|
|
26
|
+
body = await res.json();
|
|
27
|
+
}
|
|
28
|
+
catch (e) {
|
|
29
|
+
return { ok: false, errors: [`response is not JSON: ${e instanceof Error ? e.message : String(e)}`] };
|
|
30
|
+
}
|
|
31
|
+
const v = validateAgentCard(body);
|
|
32
|
+
return { ok: v.ok, card: v.ok ? body : undefined, errors: v.errors };
|
|
33
|
+
}
|
|
34
|
+
let seq = 0;
|
|
35
|
+
function nextId() { seq += 1; return `aibroker-client-${Date.now().toString(36)}-${seq}`; }
|
|
36
|
+
function nextMessageId() { return `msg-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`; }
|
|
37
|
+
async function rpc(a2aUrl, method, params, token) {
|
|
38
|
+
const headers = { "content-type": "application/json" };
|
|
39
|
+
if (token)
|
|
40
|
+
headers.authorization = `Bearer ${token}`;
|
|
41
|
+
let res;
|
|
42
|
+
try {
|
|
43
|
+
res = await fetch(a2aUrl, {
|
|
44
|
+
method: "POST", headers,
|
|
45
|
+
body: JSON.stringify({ jsonrpc: "2.0", id: nextId(), method, params }),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
return { ok: false, error: `fetch failed: ${e instanceof Error ? e.message : String(e)}` };
|
|
50
|
+
}
|
|
51
|
+
if (!res.ok)
|
|
52
|
+
return { ok: false, error: `HTTP ${res.status}` };
|
|
53
|
+
let body;
|
|
54
|
+
try {
|
|
55
|
+
body = await res.json();
|
|
56
|
+
}
|
|
57
|
+
catch (e) {
|
|
58
|
+
return { ok: false, error: `response is not JSON: ${e instanceof Error ? e.message : String(e)}` };
|
|
59
|
+
}
|
|
60
|
+
if (body.error)
|
|
61
|
+
return { ok: false, error: `[${body.error.code}] ${body.error.message}` };
|
|
62
|
+
return { ok: true, result: body.result };
|
|
63
|
+
}
|
|
64
|
+
export async function sendMessage(a2aUrl, opts) {
|
|
65
|
+
const part = opts.ag2 ? ag2Part(opts.text) : { kind: "text", text: opts.text };
|
|
66
|
+
const r = await rpc(a2aUrl, "message/send", {
|
|
67
|
+
skillId: opts.skillId,
|
|
68
|
+
agentName: opts.agentName,
|
|
69
|
+
message: {
|
|
70
|
+
kind: "message", role: "user", messageId: nextMessageId(),
|
|
71
|
+
contextId: opts.contextId, parts: [part],
|
|
72
|
+
},
|
|
73
|
+
}, opts.token);
|
|
74
|
+
if (!r.ok)
|
|
75
|
+
return { ok: false, error: r.error };
|
|
76
|
+
const v = validateTask(r.result);
|
|
77
|
+
if (!v.ok)
|
|
78
|
+
return { ok: false, error: `server returned an invalid Task: ${v.errors.join("; ")}` };
|
|
79
|
+
return { ok: true, task: r.result };
|
|
80
|
+
}
|
|
81
|
+
export async function getTask(a2aUrl, taskId, token) {
|
|
82
|
+
const r = await rpc(a2aUrl, "tasks/get", { id: taskId }, token);
|
|
83
|
+
if (!r.ok)
|
|
84
|
+
return { ok: false, error: r.error };
|
|
85
|
+
const v = validateTask(r.result);
|
|
86
|
+
if (!v.ok)
|
|
87
|
+
return { ok: false, error: `server returned an invalid Task: ${v.errors.join("; ")}` };
|
|
88
|
+
return { ok: true, task: r.result };
|
|
89
|
+
}
|
|
90
|
+
export async function cancelTask(a2aUrl, taskId, token) {
|
|
91
|
+
const r = await rpc(a2aUrl, "tasks/cancel", { id: taskId }, token);
|
|
92
|
+
if (!r.ok)
|
|
93
|
+
return { ok: false, error: r.error };
|
|
94
|
+
return { ok: true, task: r.result };
|
|
95
|
+
}
|
|
96
|
+
const TERMINAL = new Set(["completed", "canceled", "failed", "rejected"]);
|
|
97
|
+
/** Poll tasks/get until the task reaches a terminal state or the timeout elapses. */
|
|
98
|
+
export async function pollUntilDone(a2aUrl, taskId, opts = {}) {
|
|
99
|
+
const interval = opts.intervalMs ?? 2000;
|
|
100
|
+
const deadline = Date.now() + (opts.timeoutMs ?? 60_000);
|
|
101
|
+
for (;;) {
|
|
102
|
+
const r = await getTask(a2aUrl, taskId, opts.token);
|
|
103
|
+
if (!r.ok)
|
|
104
|
+
return r;
|
|
105
|
+
if (r.task && TERMINAL.has(r.task.status.state))
|
|
106
|
+
return r;
|
|
107
|
+
if (Date.now() >= deadline)
|
|
108
|
+
return { ok: false, error: "timed out waiting for a terminal state", task: r.task };
|
|
109
|
+
await new Promise((resolve) => setTimeout(resolve, interval));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/a2a/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* a2a/exposure.ts — which sessions the operator has chosen to publish as
|
|
3
|
+
* A2A skills.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors inbound.ts's rule: "a route names its session; the payload never
|
|
6
|
+
* does." The AgentCard is a directory a stranger reads before ever
|
|
7
|
+
* proving anything — the first thing a stranger does with a directory is
|
|
8
|
+
* enumerate it — so the card must never list more than the operator
|
|
9
|
+
* explicitly chose. Every persistent session name would be the wrong
|
|
10
|
+
* default: it turns a card fetch into a roster of every project this
|
|
11
|
+
* machine works on. Default is empty; nothing is exposed until the
|
|
12
|
+
* operator runs `aibroker a2a expose <session>`.
|
|
13
|
+
*/
|
|
14
|
+
export interface ExposedSession {
|
|
15
|
+
name: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function listExposed(file?: string): ExposedSession[];
|
|
19
|
+
/** Case-insensitive, matching how session names are matched elsewhere. */
|
|
20
|
+
export declare function findExposed(name: string, file?: string): ExposedSession | undefined;
|
|
21
|
+
export declare function isExposed(name: string, file?: string): boolean;
|
|
22
|
+
export declare function expose(name: string, description: string | undefined, file?: string): ExposedSession;
|
|
23
|
+
export declare function unexpose(name: string, file?: string): boolean;
|
|
24
|
+
//# sourceMappingURL=exposure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exposure.d.ts","sourceRoot":"","sources":["../../src/a2a/exposure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAiBD,wBAAgB,WAAW,CAAC,IAAI,GAAE,MAAsB,GAAG,cAAc,EAAE,CAE1E;AAED,0EAA0E;AAC1E,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAsB,GAAG,cAAc,GAAG,SAAS,CAGlG;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAsB,GAAG,OAAO,CAE7E;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,GAAE,MAAsB,GAAG,cAAc,CAalH;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAsB,GAAG,OAAO,CAS5E"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* a2a/exposure.ts — which sessions the operator has chosen to publish as
|
|
3
|
+
* A2A skills.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors inbound.ts's rule: "a route names its session; the payload never
|
|
6
|
+
* does." The AgentCard is a directory a stranger reads before ever
|
|
7
|
+
* proving anything — the first thing a stranger does with a directory is
|
|
8
|
+
* enumerate it — so the card must never list more than the operator
|
|
9
|
+
* explicitly chose. Every persistent session name would be the wrong
|
|
10
|
+
* default: it turns a card fetch into a roster of every project this
|
|
11
|
+
* machine works on. Default is empty; nothing is exposed until the
|
|
12
|
+
* operator runs `aibroker a2a expose <session>`.
|
|
13
|
+
*/
|
|
14
|
+
import { join } from "node:path";
|
|
15
|
+
import { homedir } from "node:os";
|
|
16
|
+
import { loadJson, saveJson } from "../core/json-store.js";
|
|
17
|
+
import { log } from "../core/log.js";
|
|
18
|
+
import { audit } from "../daemon/audit.js";
|
|
19
|
+
function defaultFile() {
|
|
20
|
+
return join(homedir(), ".aibroker", "a2a-exposed.json");
|
|
21
|
+
}
|
|
22
|
+
function read(file) {
|
|
23
|
+
const r = loadJson(file);
|
|
24
|
+
if (r.status === "ok" && Array.isArray(r.data?.sessions))
|
|
25
|
+
return r.data;
|
|
26
|
+
if (r.status === "unreadable") {
|
|
27
|
+
log(`a2a-exposure: ${file} is unreadable — treating as nothing exposed until it is fixed`);
|
|
28
|
+
}
|
|
29
|
+
return { sessions: [] };
|
|
30
|
+
}
|
|
31
|
+
export function listExposed(file = defaultFile()) {
|
|
32
|
+
return read(file).sessions;
|
|
33
|
+
}
|
|
34
|
+
/** Case-insensitive, matching how session names are matched elsewhere. */
|
|
35
|
+
export function findExposed(name, file = defaultFile()) {
|
|
36
|
+
const want = name.trim().toLowerCase();
|
|
37
|
+
return read(file).sessions.find((s) => s.name.toLowerCase() === want);
|
|
38
|
+
}
|
|
39
|
+
export function isExposed(name, file = defaultFile()) {
|
|
40
|
+
return findExposed(name, file) !== undefined;
|
|
41
|
+
}
|
|
42
|
+
export function expose(name, description, file = defaultFile()) {
|
|
43
|
+
const clean = name.trim();
|
|
44
|
+
if (!clean)
|
|
45
|
+
throw new Error("session name must not be empty");
|
|
46
|
+
const s = read(file);
|
|
47
|
+
const existing = s.sessions.find((e) => e.name.toLowerCase() === clean.toLowerCase());
|
|
48
|
+
const entry = existing ?? { name: clean };
|
|
49
|
+
entry.name = clean;
|
|
50
|
+
if (description !== undefined)
|
|
51
|
+
entry.description = description;
|
|
52
|
+
if (!existing)
|
|
53
|
+
s.sessions.push(entry);
|
|
54
|
+
saveJson(file, s);
|
|
55
|
+
audit({ action: "a2a-expose", actor: "aibroker", target: `session:${clean}`, outcome: existing ? "updated" : "exposed" });
|
|
56
|
+
log(`a2a: ${clean} is ${existing ? "still" : "now"} exposed as an A2A skill${entry.description ? ` ("${entry.description}")` : ""}`);
|
|
57
|
+
return entry;
|
|
58
|
+
}
|
|
59
|
+
export function unexpose(name, file = defaultFile()) {
|
|
60
|
+
const s = read(file);
|
|
61
|
+
const before = s.sessions.length;
|
|
62
|
+
s.sessions = s.sessions.filter((e) => e.name.toLowerCase() !== name.trim().toLowerCase());
|
|
63
|
+
if (s.sessions.length === before)
|
|
64
|
+
return false;
|
|
65
|
+
saveJson(file, s);
|
|
66
|
+
audit({ action: "a2a-expose", actor: "aibroker", target: `session:${name}`, outcome: "unexposed" });
|
|
67
|
+
log(`a2a: ${name} is no longer exposed as an A2A skill`);
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=exposure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exposure.js","sourceRoot":"","sources":["../../src/a2a/exposure.ts"],"names":[],"mappings":"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"}
|