@ryubyte/dsh-a2a 0.1.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/LICENSE +21 -0
- package/README.md +224 -0
- package/README.zh-CN.md +196 -0
- package/cordis.patch.yml +12 -0
- package/lib/client.js +574 -0
- package/lib/index.js +1896 -0
- package/lib/types/a2a-config.d.ts +107 -0
- package/lib/types/a2a-config.d.ts.map +1 -0
- package/lib/types/card.d.ts +40 -0
- package/lib/types/card.d.ts.map +1 -0
- package/lib/types/client/index.d.ts +22 -0
- package/lib/types/client/index.d.ts.map +1 -0
- package/lib/types/client.d.ts +52 -0
- package/lib/types/client.d.ts.map +1 -0
- package/lib/types/dashboard.d.ts +144 -0
- package/lib/types/dashboard.d.ts.map +1 -0
- package/lib/types/errors.d.ts +24 -0
- package/lib/types/errors.d.ts.map +1 -0
- package/lib/types/index.d.ts +89 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/jsonrpc.d.ts +40 -0
- package/lib/types/jsonrpc.d.ts.map +1 -0
- package/lib/types/outbound.d.ts +45 -0
- package/lib/types/outbound.d.ts.map +1 -0
- package/lib/types/protocol.d.ts +330 -0
- package/lib/types/protocol.d.ts.map +1 -0
- package/lib/types/server.d.ts +142 -0
- package/lib/types/server.d.ts.map +1 -0
- package/package.json +89 -0
- package/src/a2a-config.ts +201 -0
- package/src/card.ts +143 -0
- package/src/client/index.ts +613 -0
- package/src/client.ts +141 -0
- package/src/dashboard.ts +350 -0
- package/src/errors.ts +39 -0
- package/src/index.ts +659 -0
- package/src/jsonrpc.ts +185 -0
- package/src/outbound.ts +186 -0
- package/src/protocol.ts +308 -0
- package/src/server.ts +467 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-a2a — persisted configuration (`a2a.json`).
|
|
3
|
+
*
|
|
4
|
+
* Runtime-editable configuration lives in a per-profile `a2a.json`, so the
|
|
5
|
+
* plugin's UI changes survive restarts without touching the composition
|
|
6
|
+
* (`cordis.patch.yml` / `package.json` stay pure entry points).
|
|
7
|
+
*
|
|
8
|
+
* File resolution order:
|
|
9
|
+
* 1. `process.cwd()/a2a.json` — profile dir when launched via `dsh --profile <x>`
|
|
10
|
+
* 2. `~/.dsh/profiles/<cwd-basename>/a2a.json` — fallback when cwd is not the profile dir
|
|
11
|
+
* 3. `$DSH_HOME/a2a.json` — last-resort global location
|
|
12
|
+
*
|
|
13
|
+
* Shape (all fields optional):
|
|
14
|
+
* {
|
|
15
|
+
* "mode": "both", // client | server | both (default both)
|
|
16
|
+
* "timeoutMs": 8000, // client global default (ms)
|
|
17
|
+
* "mapSkills": true, // per-skill tools vs one agent-wide tool
|
|
18
|
+
* "agents": [{ "name", "agentCardUrl", "bearerToken?", "timeoutMs?", "mapSkills?", "enabled?" }],
|
|
19
|
+
* "server": { "baseUrl"?, "agentName"?, "agentDescription"?, "agentVersion"?,
|
|
20
|
+
* "endpointPath"?, "skills"?: [{ "id","name","description"?, "tags"? }] },
|
|
21
|
+
* "dashboard": true
|
|
22
|
+
* }
|
|
23
|
+
*/
|
|
24
|
+
import type { A2APluginConfig } from './index.js';
|
|
25
|
+
export declare const A2A_CONFIG_FILENAME = "a2a.json";
|
|
26
|
+
export interface PersistedAgentConfig {
|
|
27
|
+
name: string;
|
|
28
|
+
agentCardUrl: string;
|
|
29
|
+
bearerToken?: string;
|
|
30
|
+
timeoutMs?: number;
|
|
31
|
+
mapSkills?: boolean;
|
|
32
|
+
/** False disables the connection without removing the entry (default true). */
|
|
33
|
+
enabled?: boolean;
|
|
34
|
+
}
|
|
35
|
+
export interface PersistedServerConfig {
|
|
36
|
+
/** Explicitly enable the inbound server (default off). */
|
|
37
|
+
enabled?: boolean;
|
|
38
|
+
baseUrl?: string;
|
|
39
|
+
agentName?: string;
|
|
40
|
+
agentDescription?: string;
|
|
41
|
+
agentVersion?: string;
|
|
42
|
+
endpointPath?: string;
|
|
43
|
+
skills?: Array<{
|
|
44
|
+
id: string;
|
|
45
|
+
name: string;
|
|
46
|
+
description: string;
|
|
47
|
+
tags?: string[];
|
|
48
|
+
examples?: string[];
|
|
49
|
+
}>;
|
|
50
|
+
}
|
|
51
|
+
export interface PersistedA2AConfig {
|
|
52
|
+
mode?: 'client' | 'server' | 'both';
|
|
53
|
+
timeoutMs?: number;
|
|
54
|
+
mapSkills?: boolean;
|
|
55
|
+
agents?: PersistedAgentConfig[];
|
|
56
|
+
server?: PersistedServerConfig;
|
|
57
|
+
dashboard?: boolean;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Parse `--profile <name>` (or `--profile=<name>`) from the process argv.
|
|
61
|
+
*
|
|
62
|
+
* dsh keeps its launcher flags in the process command line (`node …/dsh
|
|
63
|
+
* --profile a2a-test --port 3083`), so the active profile name is directly
|
|
64
|
+
* observable no matter which directory the process was started from. This is
|
|
65
|
+
* the most reliable way to locate the per-profile config — far better than
|
|
66
|
+
* guessing from cwd's basename.
|
|
67
|
+
*/
|
|
68
|
+
export declare function profileNameFromArgv(): string | undefined;
|
|
69
|
+
/**
|
|
70
|
+
* Resolve the a2a.json path for the current process, without depending on
|
|
71
|
+
* the launch directory. The plugin must work no matter where `dsh` was
|
|
72
|
+
* started from (dsh does NOT chdir into the profile directory), so this
|
|
73
|
+
* prefers the profile named in argv (`--profile <name>`), then walks
|
|
74
|
+
* outward from cwd, then falls back to the profile dir that matches cwd's
|
|
75
|
+
* basename, then the harness home.
|
|
76
|
+
*
|
|
77
|
+
* Order:
|
|
78
|
+
* 0. `$DSH_HOME/profiles/<argv --profile>/a2a.json` — the active profile
|
|
79
|
+
* as named on the command line (most authoritative; works from ANY cwd)
|
|
80
|
+
* 1. `cwd/a2a.json` — explicit when launched inside a profile dir
|
|
81
|
+
* 2. outward from cwd: the nearest ancestor holding `a2a.json` — covers
|
|
82
|
+
* launching from e.g. a repo checkout whose parent chain includes the
|
|
83
|
+
* profile, or any subdir of the profile
|
|
84
|
+
* 3. `$DSH_HOME/profiles/<cwd-basename>/a2a.json` — started from the
|
|
85
|
+
* profile's *parent* (e.g. `~/.dsh/profiles`) or when the profile dir
|
|
86
|
+
* is cwd but the file hasn't been created yet
|
|
87
|
+
* 4. `$DSH_HOME/a2a.json` — last-resort global location
|
|
88
|
+
*
|
|
89
|
+
* Writes always go to the *resolved* path (the one we read), so a config
|
|
90
|
+
* loaded from any step is saved back to the same place, never re-resolved
|
|
91
|
+
* to cwd.
|
|
92
|
+
*/
|
|
93
|
+
export declare function resolveConfigPath(): string;
|
|
94
|
+
/** Read the persisted config (empty object when absent or unreadable). */
|
|
95
|
+
export declare function loadConfig(): PersistedA2AConfig;
|
|
96
|
+
/** Atomically write the persisted config (creates the directory when needed). */
|
|
97
|
+
export declare function saveConfig(config: PersistedA2AConfig): {
|
|
98
|
+
ok: boolean;
|
|
99
|
+
path: string;
|
|
100
|
+
message?: string;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Merge persisted config on top of the in-composition config, so the file
|
|
104
|
+
* (UI-editable, survives restart) wins over static defaults.
|
|
105
|
+
*/
|
|
106
|
+
export declare function mergePersisted(base: A2APluginConfig, persisted: PersistedA2AConfig): A2APluginConfig;
|
|
107
|
+
//# sourceMappingURL=a2a-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"a2a-config.d.ts","sourceRoot":"","sources":["../../src/a2a-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,eAAO,MAAM,mBAAmB,aAAa,CAAC;AAE9C,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,0DAA0D;IAC1D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CACzG;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,oBAAoB,EAAE,CAAC;IAChC,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,SAAS,CAaxD;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAqC1C;AAED,0EAA0E;AAC1E,wBAAgB,UAAU,IAAI,kBAAkB,CAW/C;AAED,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,MAAM,EAAE,kBAAkB,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAatG;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,kBAAkB,GAAG,eAAe,CAkBpG"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A2A (Agent2Agent) Protocol v1.0 — AgentCard discovery and validation.
|
|
3
|
+
*
|
|
4
|
+
* Reproduces the protocol's discovery contract: fetch the manifest at
|
|
5
|
+
* `/.well-known/agent-card.json` (or a configured URL). Per the spec, when a
|
|
6
|
+
* path is configured without a well-known segment the client SHOULD probe the
|
|
7
|
+
* well-known location first, then fall back to the configured path.
|
|
8
|
+
*/
|
|
9
|
+
import type { AgentCard, AgentInterface } from './protocol.js';
|
|
10
|
+
export interface AgentCardOptions {
|
|
11
|
+
/** How long a single fetch may take (ms). Default 15000. */
|
|
12
|
+
timeoutMs?: number;
|
|
13
|
+
/** Optional bearer token sent as `Authorization: Bearer <token>`. */
|
|
14
|
+
bearerToken?: string;
|
|
15
|
+
/** Optional custom fetch implementation (for tests). */
|
|
16
|
+
fetchImpl?: typeof fetch;
|
|
17
|
+
}
|
|
18
|
+
export declare function isAgentCard(value: unknown): value is AgentCard;
|
|
19
|
+
/**
|
|
20
|
+
* Fetch and validate an agent's AgentCard.
|
|
21
|
+
*
|
|
22
|
+
* Discovery order (per spec §AgentCard discovery):
|
|
23
|
+
* 1. Probe `GET {origin}/.well-known/agent-card.json` first.
|
|
24
|
+
* 2. Fall back to the exact configured URL.
|
|
25
|
+
* A configured URL that already ends in `agent-card.json` is used directly.
|
|
26
|
+
*/
|
|
27
|
+
export declare function fetchAgentCard(baseUrl: string, options?: AgentCardOptions): Promise<AgentCard>;
|
|
28
|
+
/**
|
|
29
|
+
* Pick the best interface to talk to an agent from its AgentCard.
|
|
30
|
+
*
|
|
31
|
+
* Preference order: a JSONRPC interface first, then gRPC, then any other
|
|
32
|
+
* binding; the card's own ordering ("first entry is preferred") is respected
|
|
33
|
+
* within each binding class. Returns the interface and a normalized base URL
|
|
34
|
+
* to post JSON-RPC requests to.
|
|
35
|
+
*/
|
|
36
|
+
export declare function pickInterface(card: AgentCard, preferred?: string): {
|
|
37
|
+
iface: AgentInterface;
|
|
38
|
+
url: string;
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=card.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card.d.ts","sourceRoot":"","sources":["../../src/card.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/D,MAAM,WAAW,gBAAgB;IAC/B,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAc9D;AAQD;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,SAAS,CAAC,CA0DpB;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,SAAS,EACf,SAAS,CAAC,EAAE,MAAM,GACjB;IAAE,KAAK,EAAE,cAAc,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAiBxC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-a2a — browser half.
|
|
3
|
+
*
|
|
4
|
+
* Contributes the "A2A 连接" settings section: a dashboard showing who is
|
|
5
|
+
* connected TO this DSH (inbound peers) and who this DSH is connected TO
|
|
6
|
+
* (outbound agents), with reconnect / close controls per connection.
|
|
7
|
+
*
|
|
8
|
+
* The data and the controls live behind the host's `/a2a/api` routes
|
|
9
|
+
* (served by the node half on the same webserver); the browser half is a
|
|
10
|
+
* thin read/write client with no protocol knowledge.
|
|
11
|
+
*/
|
|
12
|
+
import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
|
|
13
|
+
import type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
14
|
+
import { type ReactElement } from 'react';
|
|
15
|
+
/** Services this plugin needs from the client runtime. */
|
|
16
|
+
export declare const inject: string[];
|
|
17
|
+
export declare function apply(ctx: ClientContext): void;
|
|
18
|
+
type SectionProps = PropsRuntime<'settings.section'>;
|
|
19
|
+
/** The A2A connection dashboard settings section. */
|
|
20
|
+
export declare function DashboardSection(_props: SectionProps): ReactElement;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAE5E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAsC,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAE9E,0DAA0D;AAC1D,eAAO,MAAM,MAAM,UAAY,CAAC;AAEhC,wBAAgB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAmB9C;AA6DD,KAAK,YAAY,GAAG,YAAY,CAAC,kBAAkB,CAAC,CAAC;AAErD,qDAAqD;AACrD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CAqTnE"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A2A (Agent2Agent) Protocol v1.0 — outbound client.
|
|
3
|
+
*
|
|
4
|
+
* A thin client that discovers an agent via its AgentCard and speaks the
|
|
5
|
+
* JSONRPC binding: SendMessage (sync/async), SendStreamingMessage,
|
|
6
|
+
* GetTask, CancelTask, ListTasks.
|
|
7
|
+
*/
|
|
8
|
+
import type { AgentCard, Message, SendMessageConfiguration, SendMessageResponse, StreamResponse, Task } from './protocol.js';
|
|
9
|
+
import { TaskState } from './protocol.js';
|
|
10
|
+
import { type JsonRpcClientOptions, type JsonRpcCallOptions } from './jsonrpc.js';
|
|
11
|
+
export interface A2AClientOptions extends JsonRpcClientOptions {
|
|
12
|
+
/** Prefer a specific protocol binding. Default 'JSONRPC'. */
|
|
13
|
+
preferredBinding?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface WaitForTaskOptions {
|
|
16
|
+
/** Poll interval in ms. Default 500. */
|
|
17
|
+
intervalMs?: number;
|
|
18
|
+
signal?: AbortSignal;
|
|
19
|
+
}
|
|
20
|
+
/** A2A client bound to one remote agent. */
|
|
21
|
+
export declare class A2AClient {
|
|
22
|
+
readonly card: AgentCard;
|
|
23
|
+
private readonly rpc;
|
|
24
|
+
readonly endpointUrl: string;
|
|
25
|
+
readonly tenant?: string;
|
|
26
|
+
static connect(agentCardUrlOrBase: string, options?: A2AClientOptions): Promise<A2AClient>;
|
|
27
|
+
constructor(card: AgentCard, options?: A2AClientOptions);
|
|
28
|
+
/** Send a message; returns a Task or Message per the server's choice. */
|
|
29
|
+
sendMessage(message: Message, configuration?: SendMessageConfiguration, options?: JsonRpcCallOptions): Promise<SendMessageResponse>;
|
|
30
|
+
/** Send a message over a stream, yielding all StreamResponse events. */
|
|
31
|
+
streamMessage(message: Message, configuration?: SendMessageConfiguration, options?: JsonRpcCallOptions): AsyncGenerator<StreamResponse>;
|
|
32
|
+
getTask(id: string, historyLength?: number, options?: JsonRpcCallOptions): Promise<Task>;
|
|
33
|
+
listTasks(params?: {
|
|
34
|
+
contextId?: string;
|
|
35
|
+
status?: TaskState;
|
|
36
|
+
pageSize?: number;
|
|
37
|
+
pageToken?: string;
|
|
38
|
+
includeArtifacts?: boolean;
|
|
39
|
+
}, options?: JsonRpcCallOptions): Promise<{
|
|
40
|
+
tasks: Task[];
|
|
41
|
+
nextPageToken: string;
|
|
42
|
+
pageSize: number;
|
|
43
|
+
totalSize: number;
|
|
44
|
+
}>;
|
|
45
|
+
cancelTask(id: string, options?: JsonRpcCallOptions): Promise<Task>;
|
|
46
|
+
/**
|
|
47
|
+
* Send a message and wait (polling) until the created task reaches a
|
|
48
|
+
* terminal state. Errors if the task fails or is rejected.
|
|
49
|
+
*/
|
|
50
|
+
sendAndWait(message: Message, configuration?: SendMessageConfiguration, options?: JsonRpcCallOptions & WaitForTaskOptions): Promise<Task>;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC7H,OAAO,EAAE,SAAS,EAAc,MAAM,eAAe,CAAC;AACtD,OAAO,EAAiB,KAAK,oBAAoB,EAAE,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGjG,MAAM,WAAW,gBAAiB,SAAQ,oBAAoB;IAC5D,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAkB;IACjC,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,4CAA4C;AAC5C,qBAAa,SAAS;IACpB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAgB;IACpC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;WAEZ,OAAO,CAClB,kBAAkB,EAAE,MAAM,EAC1B,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,SAAS,CAAC;gBAKT,IAAI,EAAE,SAAS,EAAE,OAAO,GAAE,gBAAqB;IAQ3D,yEAAyE;IACnE,WAAW,CACf,OAAO,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,wBAAwB,EACxC,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,mBAAmB,CAAC;IAQ/B,wEAAwE;IACxE,aAAa,CACX,OAAO,EAAE,OAAO,EAChB,aAAa,GAAE,wBAA6B,EAC5C,OAAO,GAAE,kBAAuB,GAC/B,cAAc,CAAC,cAAc,CAAC;IAQ3B,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ5F,SAAS,CAAC,MAAM,GAAE;QACtB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,SAAS,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;KACvB,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC;QACjD,KAAK,EAAE,IAAI,EAAE,CAAC;QACd,aAAa,EAAE,MAAM,CAAC;QACtB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IAII,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAO7E;;;OAGG;IACG,WAAW,CACf,OAAO,EAAE,OAAO,EAChB,aAAa,GAAE,wBAA6B,EAC5C,OAAO,GAAE,kBAAkB,GAAG,kBAAuB,GACpD,OAAO,CAAC,IAAI,CAAC;CA4BjB"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-a2a — connection dashboard.
|
|
3
|
+
*
|
|
4
|
+
* Tracks both directions of A2A connectivity so the operator (and the
|
|
5
|
+
* settings dashboard) can see:
|
|
6
|
+
*
|
|
7
|
+
* - **inbound** — which remote peers are talking to THIS DSH's A2A server
|
|
8
|
+
* (peer label, source address, last activity, live tasks).
|
|
9
|
+
* - **outbound** — which remote agents THIS DSH is connected to via the
|
|
10
|
+
* client mode (agent name, AgentCard URL, skill count,
|
|
11
|
+
* connection state) with reconnect/close controls.
|
|
12
|
+
*
|
|
13
|
+
* The registry is process-local and purely observational: entries never
|
|
14
|
+
* affect protocol behavior by themselves. Control operations
|
|
15
|
+
* (`reconnectPeer`, `closePeer`, `reconnectAgent`, `closeAgent`) are wired
|
|
16
|
+
* by the plugin entry to the real connection owners.
|
|
17
|
+
*/
|
|
18
|
+
import type { A2AClient } from './client.js';
|
|
19
|
+
export interface InboundPeer {
|
|
20
|
+
/** Stable per-process id (random). */
|
|
21
|
+
id: string;
|
|
22
|
+
/** Short display label derived from the request. */
|
|
23
|
+
label: string;
|
|
24
|
+
/** Source socket address, when visible ("127.0.0.1:54321"). */
|
|
25
|
+
source?: string;
|
|
26
|
+
/** First-seen ISO timestamp. */
|
|
27
|
+
firstSeen: string;
|
|
28
|
+
/** Last-activity ISO timestamp. */
|
|
29
|
+
lastSeen: string;
|
|
30
|
+
/** Number of tasks this peer has created/continued. */
|
|
31
|
+
taskCount: number;
|
|
32
|
+
/** Ids of tasks still running for this peer. */
|
|
33
|
+
activeTaskIds: string[];
|
|
34
|
+
/** True while at least one streaming (SSE) connection is open. */
|
|
35
|
+
streaming: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface OutboundAgent {
|
|
38
|
+
/** Stable per-process id. */
|
|
39
|
+
id: string;
|
|
40
|
+
/** Namespace used for tool names ("research" → a2a__research__<skill>). */
|
|
41
|
+
name: string;
|
|
42
|
+
/** AgentCard URL the client was connected to. */
|
|
43
|
+
agentCardUrl: string;
|
|
44
|
+
/** Remote agent display name (from the AgentCard). */
|
|
45
|
+
agentName?: string;
|
|
46
|
+
/** Number of skills mapped to tools. */
|
|
47
|
+
skillCount: number;
|
|
48
|
+
/** Number of tools registered for this agent. */
|
|
49
|
+
toolCount: number;
|
|
50
|
+
/** Connection state. */
|
|
51
|
+
state: 'connected' | 'disconnected' | 'reconnecting';
|
|
52
|
+
/** False when this agent is configured but disabled in a2a.json (no live connection). */
|
|
53
|
+
enabled?: boolean;
|
|
54
|
+
/** Last-activity ISO timestamp. */
|
|
55
|
+
lastSeen: string;
|
|
56
|
+
/** Per-process connection id assigned by the outbound registry. */
|
|
57
|
+
connectionId?: string;
|
|
58
|
+
/** True when this connection came from the profile config (vs runtime-added). */
|
|
59
|
+
configured?: boolean;
|
|
60
|
+
/** Skills advertised by the remote AgentCard (for the detail view). */
|
|
61
|
+
skills?: Array<{
|
|
62
|
+
id: string;
|
|
63
|
+
name: string;
|
|
64
|
+
description?: string;
|
|
65
|
+
tags?: string[];
|
|
66
|
+
}>;
|
|
67
|
+
}
|
|
68
|
+
export interface DashboardSnapshot {
|
|
69
|
+
inbound: InboundPeer[];
|
|
70
|
+
outbound: OutboundAgent[];
|
|
71
|
+
/** Epoch ms of the snapshot. */
|
|
72
|
+
at: number;
|
|
73
|
+
}
|
|
74
|
+
export interface ControlResult {
|
|
75
|
+
ok: boolean;
|
|
76
|
+
message: string;
|
|
77
|
+
}
|
|
78
|
+
/** How the plugin entry wires control operations to connection owners. */
|
|
79
|
+
export interface DashboardControlHooks {
|
|
80
|
+
/** Reconnect an outbound agent by its connection id. */
|
|
81
|
+
reconnectAgent?: (connectionId: string) => Promise<ControlResult>;
|
|
82
|
+
/** Disable (disconnect + persist enabled:false) an outbound agent without removing it. */
|
|
83
|
+
disableAgent?: (connectionId: string) => Promise<ControlResult>;
|
|
84
|
+
/** Enable a disabled outbound agent (persist enabled:true and reconnect). */
|
|
85
|
+
enableAgent?: (connectionId: string) => Promise<ControlResult>;
|
|
86
|
+
/** Close an outbound agent by its connection id. */
|
|
87
|
+
closeAgent?: (connectionId: string) => Promise<ControlResult>;
|
|
88
|
+
/** Close (sever) an inbound peer by its id. */
|
|
89
|
+
closePeer?: (peerId: string) => Promise<ControlResult>;
|
|
90
|
+
/** Reconnect is not meaningful for an inbound peer — rejects unless overridden. */
|
|
91
|
+
reconnectPeer?: (peerId: string) => Promise<ControlResult>;
|
|
92
|
+
/** Runtime-add an outbound agent (visual config). Returns the new connection id. */
|
|
93
|
+
addAgent?: (name: string, agentCardUrl: string) => Promise<ControlResult>;
|
|
94
|
+
/** Discover an Agent Card without connecting (for the import preview). */
|
|
95
|
+
discoverAgent?: (agentCardUrl: string) => Promise<ControlResult>;
|
|
96
|
+
/** Enable/disable the inbound A2A server (serve routes) at runtime. */
|
|
97
|
+
setServerEnabled?: (enabled: boolean) => Promise<ControlResult>;
|
|
98
|
+
/** Read current inbound server status (for the serve panel). */
|
|
99
|
+
serverStatus?: () => ControlResult;
|
|
100
|
+
/** Runtime-remove an outbound agent by its connection id. */
|
|
101
|
+
removeAgent?: (connectionId: string) => Promise<ControlResult>;
|
|
102
|
+
}
|
|
103
|
+
/** Registry of live A2A connections, both directions. */
|
|
104
|
+
export declare class DashboardRegistry {
|
|
105
|
+
private peers;
|
|
106
|
+
private agents;
|
|
107
|
+
private hooks;
|
|
108
|
+
private seq;
|
|
109
|
+
setHooks(hooks: DashboardControlHooks): void;
|
|
110
|
+
/** Record one inbound request (or stream open). Returns the peer id. */
|
|
111
|
+
touchInbound(req: {
|
|
112
|
+
headers?: Record<string, string>;
|
|
113
|
+
source?: string;
|
|
114
|
+
}, taskIds?: string[]): string;
|
|
115
|
+
/** Mark a task finished for a peer (drops it from the active list). */
|
|
116
|
+
finishTask(peerId: string, taskId: string): void;
|
|
117
|
+
/** Mark a peer's streaming flag. */
|
|
118
|
+
setStreaming(peerId: string, streaming: boolean): void;
|
|
119
|
+
/** Remove an inbound peer (the "关闭" action severs tracking). */
|
|
120
|
+
removePeer(id: string): void;
|
|
121
|
+
/** Register or refresh an outbound agent connection. */
|
|
122
|
+
upsertAgent(agent: Omit<OutboundAgent, 'id' | 'lastSeen'>): string;
|
|
123
|
+
/** Remove an outbound agent by id or connectionId. */
|
|
124
|
+
removeAgent(connectionId: string): boolean;
|
|
125
|
+
/** Update one agent's state. */
|
|
126
|
+
setAgentState(connectionId: string, state: OutboundAgent['state']): void;
|
|
127
|
+
/** Touch one agent's last activity. */
|
|
128
|
+
touchAgent(connectionId: string): void;
|
|
129
|
+
snapshot(): DashboardSnapshot;
|
|
130
|
+
control(action: string, target: string, payload?: Record<string, unknown>): Promise<ControlResult>;
|
|
131
|
+
private closePeerLocal;
|
|
132
|
+
}
|
|
133
|
+
/** A client owned by the plugin entry, tracked for the dashboard. */
|
|
134
|
+
export interface TrackedClient {
|
|
135
|
+
client: A2AClient;
|
|
136
|
+
connectionId: string;
|
|
137
|
+
name: string;
|
|
138
|
+
agentCardUrl: string;
|
|
139
|
+
}
|
|
140
|
+
/** Get the process-wide dashboard registry (creating it on first use). */
|
|
141
|
+
export declare function getSharedRegistry(): DashboardRegistry;
|
|
142
|
+
/** Test hook: reset the shared registry (and any hooks). */
|
|
143
|
+
export declare function resetSharedRegistry(): void;
|
|
144
|
+
//# sourceMappingURL=dashboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/dashboard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A2A (Agent2Agent) Protocol v1.0 — errors.
|
|
3
|
+
*/
|
|
4
|
+
/** An error produced by a remote A2A agent (JSON-RPC error object). */
|
|
5
|
+
export interface A2ARemoteErrorInfo {
|
|
6
|
+
code: number;
|
|
7
|
+
message: string;
|
|
8
|
+
data?: unknown;
|
|
9
|
+
}
|
|
10
|
+
/** Error class for A2A protocol failures, mirroring JSON-RPC error semantics. */
|
|
11
|
+
export declare class A2AError extends Error {
|
|
12
|
+
readonly code: number;
|
|
13
|
+
readonly data?: unknown;
|
|
14
|
+
/** True when this error came from a remote agent over the wire. */
|
|
15
|
+
readonly remote: boolean;
|
|
16
|
+
constructor(code: number, message: string, data?: unknown, remote?: boolean);
|
|
17
|
+
toJsonRpc(): {
|
|
18
|
+
code: number;
|
|
19
|
+
message: string;
|
|
20
|
+
data?: unknown;
|
|
21
|
+
};
|
|
22
|
+
static fromJsonRpc(err: A2ARemoteErrorInfo): A2AError;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,uEAAuE;AACvE,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,iFAAiF;AACjF,qBAAa,QAAS,SAAQ,KAAK;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,mEAAmE;IACnE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;gBAEb,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,UAAQ;IAQzE,SAAS,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE;IAS9D,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,kBAAkB,GAAG,QAAQ;CAGtD"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-a2a — Cordis plugin entry point for DeepSeek Harness.
|
|
3
|
+
*
|
|
4
|
+
* Mounts the A2A plugin inside a DSH composition. The plugin is
|
|
5
|
+
* configuration-driven and opportunistically consumes DSH services:
|
|
6
|
+
*
|
|
7
|
+
* mode: 'client' — fetch a remote AgentCard, register each skill as a
|
|
8
|
+
* model tool on `ctx.tools` (name `a2a__<name>__<skill>`).
|
|
9
|
+
* mode: 'server' — expose this DSH as an A2A agent: AgentCard +
|
|
10
|
+
* JSON-RPC endpoint on `ctx.webServer` (when mounted).
|
|
11
|
+
*
|
|
12
|
+
* Both modes feed a connection dashboard (see `dashboard.ts`) exposed at
|
|
13
|
+
* `/a2a/api` (state snapshot + reconnect/close controls), so the settings
|
|
14
|
+
* panel can show "who is connected to us" (inbound) and "who we are
|
|
15
|
+
* connected to" (outbound).
|
|
16
|
+
*
|
|
17
|
+
* Service access follows the native DSH pattern: services are declared via
|
|
18
|
+
* module augmentation and read as context properties inside `ctx.effect(...)`,
|
|
19
|
+
* so Cordis waits for availability and disposes registrations with the fiber.
|
|
20
|
+
* The plugin stays mounted in compositions that lack a service (it logs and
|
|
21
|
+
* idles); it never hard-depends on one.
|
|
22
|
+
*/
|
|
23
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
24
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
25
|
+
import { type ServerOptions } from './server.js';
|
|
26
|
+
export interface A2APluginConfig {
|
|
27
|
+
mode?: 'client' | 'server' | 'both';
|
|
28
|
+
name?: string;
|
|
29
|
+
agentCardUrl?: string;
|
|
30
|
+
bearerToken?: string;
|
|
31
|
+
timeoutMs?: number;
|
|
32
|
+
mapSkills?: boolean;
|
|
33
|
+
/** Explicitly enable the inbound A2A server (default off). */
|
|
34
|
+
serverEnabled?: boolean;
|
|
35
|
+
baseUrl?: string;
|
|
36
|
+
agentName?: string;
|
|
37
|
+
agentDescription?: string;
|
|
38
|
+
agentVersion?: string;
|
|
39
|
+
skills?: ServerOptions['skills'];
|
|
40
|
+
endpointPath?: string;
|
|
41
|
+
execute?: ServerOptions['execute'];
|
|
42
|
+
/** Serve the dashboard API on the webserver (default true). */
|
|
43
|
+
dashboard?: boolean;
|
|
44
|
+
}
|
|
45
|
+
export { A2AClient } from './client.js';
|
|
46
|
+
export * from './protocol.js';
|
|
47
|
+
export * from './errors.js';
|
|
48
|
+
export { fetchAgentCard } from './card.js';
|
|
49
|
+
export { A2AServer, TaskStore, defaultExecutor, defaultSkills } from './server.js';
|
|
50
|
+
export { registerAgentTools } from './outbound.js';
|
|
51
|
+
export { DashboardRegistry, getSharedRegistry } from './dashboard.js';
|
|
52
|
+
export type { DashboardSnapshot, InboundPeer, OutboundAgent, ControlResult, } from './dashboard.js';
|
|
53
|
+
/**
|
|
54
|
+
* Service shapes consumed from the DSH composition. Declared structurally so
|
|
55
|
+
* this package builds against `@deepseek-ai/cordis` alone (peer dependency);
|
|
56
|
+
* the runtime shapes are owned by `@deepseek-ai/dsh-host-webserver` and
|
|
57
|
+
* `@deepseek-ai/dsh-tools` respectively.
|
|
58
|
+
*/
|
|
59
|
+
export interface WebServerService {
|
|
60
|
+
/** The OS-assigned (or configured) listen port. */
|
|
61
|
+
readonly port: number;
|
|
62
|
+
/** The configured bind host literal ('127.0.0.1' | '0.0.0.0'). */
|
|
63
|
+
readonly host: string;
|
|
64
|
+
register(route: {
|
|
65
|
+
kind: 'exact' | 'prefix';
|
|
66
|
+
path: string;
|
|
67
|
+
handler: (req: IncomingMessage, res: ServerResponse) => void | Promise<void>;
|
|
68
|
+
}): () => void;
|
|
69
|
+
}
|
|
70
|
+
declare module '@deepseek-ai/cordis' {
|
|
71
|
+
interface Context {
|
|
72
|
+
/** Provided by @deepseek-ai/dsh-host-webserver. */
|
|
73
|
+
webServer: WebServerService;
|
|
74
|
+
/** Provided by @deepseek-ai/dsh-tools. */
|
|
75
|
+
tools: {
|
|
76
|
+
register(def: unknown): () => void;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
export declare const name = "a2a";
|
|
81
|
+
/**
|
|
82
|
+
* Services this plugin may read as context properties. Declared so property
|
|
83
|
+
* reads inside `apply` never trip Cordis's "without inject" guard. The
|
|
84
|
+
* mode-specific wiring runs inside `ctx.inject(...)` for the single service it
|
|
85
|
+
* needs, so a composition lacking the other one simply idles that half.
|
|
86
|
+
*/
|
|
87
|
+
export declare const inject: readonly ["webServer", "tools"];
|
|
88
|
+
export declare function apply(ctx: Context, config?: A2APluginConfig): void;
|
|
89
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGjE,OAAO,EAAa,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAW5D,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;IAEpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IAEnC,+DAA+D;IAC/D,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACtE,YAAY,EACV,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,aAAa,GACd,MAAM,gBAAgB,CAAC;AAExB;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE;QACd,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;QACzB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KAC9E,GAAG,MAAM,IAAI,CAAC;CAChB;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,mDAAmD;QACnD,SAAS,EAAE,gBAAgB,CAAC;QAC5B,0CAA0C;QAC1C,KAAK,EAAE;YAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,IAAI,CAAA;SAAE,CAAC;KAC/C;CACF;AAQD,eAAO,MAAM,IAAI,QAAQ,CAAC;AAE1B;;;;;GAKG;AACH,eAAO,MAAM,MAAM,iCAAkC,CAAC;AAEtD,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,GAAE,eAAoB,QA8e/D"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A2A (Agent2Agent) Protocol v1.0 — JSON-RPC 2.0 transport client.
|
|
3
|
+
*
|
|
4
|
+
* Implements the JSONRPC protocol binding of A2A v1.0: a thin JSON-RPC 2.0
|
|
5
|
+
* client for unary calls plus an SSE reader for `SendStreamingMessage`.
|
|
6
|
+
*/
|
|
7
|
+
import type { StreamResponse } from './protocol.js';
|
|
8
|
+
export interface JsonRpcClientOptions {
|
|
9
|
+
/** Timeout (ms) for a single unary call. Default 60000. */
|
|
10
|
+
timeoutMs?: number;
|
|
11
|
+
/** Optional bearer token. */
|
|
12
|
+
bearerToken?: string;
|
|
13
|
+
/** Custom fetch (tests). */
|
|
14
|
+
fetchImpl?: typeof fetch;
|
|
15
|
+
}
|
|
16
|
+
export interface JsonRpcCallOptions {
|
|
17
|
+
signal?: AbortSignal;
|
|
18
|
+
timeoutMs?: number;
|
|
19
|
+
}
|
|
20
|
+
export declare class JsonRpcClient {
|
|
21
|
+
readonly url: string;
|
|
22
|
+
private readonly timeoutMs;
|
|
23
|
+
private readonly bearerToken?;
|
|
24
|
+
private readonly fetchImpl;
|
|
25
|
+
private seq;
|
|
26
|
+
constructor(url: string, options?: JsonRpcClientOptions);
|
|
27
|
+
private headers;
|
|
28
|
+
/** Perform a unary JSON-RPC call. */
|
|
29
|
+
call<T>(method: string, params: unknown, options?: JsonRpcCallOptions): Promise<T>;
|
|
30
|
+
/**
|
|
31
|
+
* Open a streaming JSON-RPC call (`SendStreamingMessage`) over SSE and
|
|
32
|
+
* yield the `StreamResponse` events as they arrive. The connection is
|
|
33
|
+
* closed when the returned async iterator is broken or the request is
|
|
34
|
+
* cancelled. Events are decoded from SSE `data:` lines (JSON-RPC result
|
|
35
|
+
* frames); per A2A v1.0 the JSON structure uses member names to
|
|
36
|
+
* discriminate `task` / `message` / `statusUpdate` / `artifactUpdate`.
|
|
37
|
+
*/
|
|
38
|
+
stream<T = StreamResponse>(method: string, params: unknown, options?: JsonRpcCallOptions): AsyncGenerator<T>;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=jsonrpc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonrpc.d.ts","sourceRoot":"","sources":["../../src/jsonrpc.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAmD,cAAc,EAAE,MAAM,eAAe,CAAC;AAGrG,MAAM,WAAW,oBAAoB;IACnC,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,aAAa;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,GAAG,CAAK;gBAEJ,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,oBAAyB;IAO3D,OAAO,CAAC,OAAO;IAUf,qCAAqC;IAC/B,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,CAAC,CAAC;IA6C5F;;;;;;;OAOG;IACI,MAAM,CAAC,CAAC,GAAG,cAAc,EAC9B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,EACf,OAAO,GAAE,kBAAuB,GAC/B,cAAc,CAAC,CAAC,CAAC;CA8ErB"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-a2a — outbound half: bridge remote A2A agent skills into DSH's tool
|
|
3
|
+
* registry (`ctx.tools`).
|
|
4
|
+
*
|
|
5
|
+
* Each skill on a remote AgentCard becomes a model-facing tool named
|
|
6
|
+
* `a2a__<agentName>__<skillId>` (normalized to the DSH function-name
|
|
7
|
+
* contract: `[A-Za-z0-9_-]`, ≤64 chars; on collision a deterministic hash is
|
|
8
|
+
* appended, mirroring dsh-mcp-client's naming rule).
|
|
9
|
+
*/
|
|
10
|
+
import type { AgentCard } from './protocol.js';
|
|
11
|
+
export interface ToolLike {
|
|
12
|
+
register?(definition: unknown): (() => void) | void;
|
|
13
|
+
}
|
|
14
|
+
export interface OutboundOptions {
|
|
15
|
+
/** Namespace prefix for tool names (lowercase, unique across instances). */
|
|
16
|
+
name: string;
|
|
17
|
+
agentCardUrl: string;
|
|
18
|
+
bearerToken?: string;
|
|
19
|
+
/** Per-call timeout in ms. Default 60000. */
|
|
20
|
+
timeoutMs?: number;
|
|
21
|
+
/** Register one generic tool per skill (default true). */
|
|
22
|
+
mapSkills?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Optional connection-lifecycle observation: called once the AgentCard is
|
|
25
|
+
* fetched and the connection is usable. `connectionId` is the stable id the
|
|
26
|
+
* dashboard tracks this connection under.
|
|
27
|
+
*/
|
|
28
|
+
onReady?: (info: {
|
|
29
|
+
connectionId: string;
|
|
30
|
+
card: AgentCard;
|
|
31
|
+
}) => void;
|
|
32
|
+
/** Called when the connection (and its tools) are torn down. */
|
|
33
|
+
onDispose?: (connectionId: string) => void;
|
|
34
|
+
}
|
|
35
|
+
export interface RegisteredTool {
|
|
36
|
+
name: string;
|
|
37
|
+
/** Stable id of the client connection this tool belongs to. */
|
|
38
|
+
connectionId?: string;
|
|
39
|
+
dispose: () => void;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Register all skills of a remote agent on `ctx.tools` and return disposers.
|
|
43
|
+
*/
|
|
44
|
+
export declare function registerAgentTools(tools: ToolLike, options: OutboundOptions): Promise<RegisteredTool[]>;
|
|
45
|
+
//# sourceMappingURL=outbound.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outbound.d.ts","sourceRoot":"","sources":["../../src/outbound.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAA6B,MAAM,eAAe,CAAC;AAK1E,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,CAAC,UAAU,EAAE,OAAO,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;CACrD;AAED,MAAM,WAAW,eAAe;IAC9B,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,SAAS,CAAA;KAAE,KAAK,IAAI,CAAC;IACpE,gEAAgE;IAChE,SAAS,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5C;AAmCD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,EAAE,CAAC,CAsC3B"}
|