@hanphone/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 +196 -0
- package/README.zh.md +195 -0
- package/cordis.patch.yml +11 -0
- package/lib/client.js +166 -0
- package/lib/index.js +2073 -0
- package/lib/tsconfig.client.tsbuildinfo +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/lib/types/api.d.ts +41 -0
- package/lib/types/api.d.ts.map +1 -0
- package/lib/types/api.js +86 -0
- package/lib/types/api.js.map +1 -0
- package/lib/types/client/index.d.ts +35 -0
- package/lib/types/client/index.d.ts.map +1 -0
- package/lib/types/client/index.js +155 -0
- package/lib/types/client/index.js.map +1 -0
- package/lib/types/commands.d.ts +10 -0
- package/lib/types/commands.d.ts.map +1 -0
- package/lib/types/commands.js +93 -0
- package/lib/types/commands.js.map +1 -0
- package/lib/types/events.d.ts +74 -0
- package/lib/types/events.d.ts.map +1 -0
- package/lib/types/events.js +10 -0
- package/lib/types/events.js.map +1 -0
- package/lib/types/index.d.ts +54 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +296 -0
- package/lib/types/index.js.map +1 -0
- package/lib/types/jsonrpc.d.ts +20 -0
- package/lib/types/jsonrpc.d.ts.map +1 -0
- package/lib/types/jsonrpc.js +48 -0
- package/lib/types/jsonrpc.js.map +1 -0
- package/lib/types/outbound/calls.d.ts +37 -0
- package/lib/types/outbound/calls.d.ts.map +1 -0
- package/lib/types/outbound/calls.js +120 -0
- package/lib/types/outbound/calls.js.map +1 -0
- package/lib/types/outbound/registry.d.ts +102 -0
- package/lib/types/outbound/registry.d.ts.map +1 -0
- package/lib/types/outbound/registry.js +249 -0
- package/lib/types/outbound/registry.js.map +1 -0
- package/lib/types/outbound/tools.d.ts +30 -0
- package/lib/types/outbound/tools.d.ts.map +1 -0
- package/lib/types/outbound/tools.js +86 -0
- package/lib/types/outbound/tools.js.map +1 -0
- package/lib/types/protocol.d.ts +194 -0
- package/lib/types/protocol.d.ts.map +1 -0
- package/lib/types/protocol.js +78 -0
- package/lib/types/protocol.js.map +1 -0
- package/lib/types/server/a2a-server.d.ts +98 -0
- package/lib/types/server/a2a-server.d.ts.map +1 -0
- package/lib/types/server/a2a-server.js +397 -0
- package/lib/types/server/a2a-server.js.map +1 -0
- package/lib/types/server/card.d.ts +48 -0
- package/lib/types/server/card.d.ts.map +1 -0
- package/lib/types/server/card.js +75 -0
- package/lib/types/server/card.js.map +1 -0
- package/lib/types/server/exec/agent-runtime.d.ts +126 -0
- package/lib/types/server/exec/agent-runtime.d.ts.map +1 -0
- package/lib/types/server/exec/agent-runtime.js +138 -0
- package/lib/types/server/exec/agent-runtime.js.map +1 -0
- package/lib/types/server/exec/session.d.ts +11 -0
- package/lib/types/server/exec/session.d.ts.map +1 -0
- package/lib/types/server/exec/session.js +22 -0
- package/lib/types/server/exec/session.js.map +1 -0
- package/lib/types/server/exec/subagent.d.ts +39 -0
- package/lib/types/server/exec/subagent.d.ts.map +1 -0
- package/lib/types/server/exec/subagent.js +44 -0
- package/lib/types/server/exec/subagent.js.map +1 -0
- package/lib/types/server/executor.d.ts +63 -0
- package/lib/types/server/executor.d.ts.map +1 -0
- package/lib/types/server/executor.js +38 -0
- package/lib/types/server/executor.js.map +1 -0
- package/lib/types/server/routes.d.ts +32 -0
- package/lib/types/server/routes.d.ts.map +1 -0
- package/lib/types/server/routes.js +131 -0
- package/lib/types/server/routes.js.map +1 -0
- package/lib/types/server/store.d.ts +157 -0
- package/lib/types/server/store.d.ts.map +1 -0
- package/lib/types/server/store.js +239 -0
- package/lib/types/server/store.js.map +1 -0
- package/lib/types/service.d.ts +49 -0
- package/lib/types/service.d.ts.map +1 -0
- package/lib/types/service.js +46 -0
- package/lib/types/service.js.map +1 -0
- package/package.json +82 -0
- package/src/api.ts +115 -0
- package/src/client/index.ts +293 -0
- package/src/commands.ts +92 -0
- package/src/events.ts +58 -0
- package/src/index.ts +353 -0
- package/src/jsonrpc.ts +61 -0
- package/src/outbound/calls.ts +145 -0
- package/src/outbound/registry.ts +290 -0
- package/src/outbound/tools.ts +118 -0
- package/src/protocol.ts +212 -0
- package/src/server/a2a-server.ts +455 -0
- package/src/server/card.ts +106 -0
- package/src/server/exec/agent-runtime.ts +197 -0
- package/src/server/exec/session.ts +25 -0
- package/src/server/exec/subagent.ts +67 -0
- package/src/server/executor.ts +73 -0
- package/src/server/routes.ts +156 -0
- package/src/server/store.ts +320 -0
- package/src/service.ts +78 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable task storage for the inbound half: one `a2a` domain over the routed
|
|
3
|
+
* storage backend (the deployment picks the medium, normally SQLite). Records
|
|
4
|
+
* are serialized JSON so the domain tables stay plain kv rows; the domain
|
|
5
|
+
* SCHEMA_VERSION guards format evolution. A memory store keeps unit tests and
|
|
6
|
+
* minimal embeddings free of a backend.
|
|
7
|
+
* @module dsh-a2a/server/store
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { z } from 'zod'
|
|
11
|
+
import {
|
|
12
|
+
defineDomain,
|
|
13
|
+
domainTable,
|
|
14
|
+
type Domain,
|
|
15
|
+
type DomainFacility,
|
|
16
|
+
type KvTable,
|
|
17
|
+
} from '@deepseek-ai/dsh-storage-domain'
|
|
18
|
+
import { TaskState, type Part } from '../protocol.ts'
|
|
19
|
+
|
|
20
|
+
/** One durable inbound/outbound task record. */
|
|
21
|
+
export interface TaskRecord {
|
|
22
|
+
readonly taskId: string
|
|
23
|
+
readonly contextId: string
|
|
24
|
+
readonly skill: string
|
|
25
|
+
readonly state: TaskState
|
|
26
|
+
readonly createdAt: string
|
|
27
|
+
readonly updatedAt: string
|
|
28
|
+
readonly sessionId: string | null
|
|
29
|
+
readonly remotePeerId: string | null
|
|
30
|
+
readonly parts: readonly Part[]
|
|
31
|
+
readonly artifacts: readonly { readonly artifactId: string; readonly name?: string; readonly parts: readonly Part[] }[]
|
|
32
|
+
readonly executor: 'session' | 'subagent'
|
|
33
|
+
readonly summary: string | null
|
|
34
|
+
readonly error?: { readonly code: string; readonly message: string }
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** One durable context→session binding (inbound conversation ↔ DSH session). */
|
|
38
|
+
export interface ContextBinding {
|
|
39
|
+
readonly sessionId: string
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** One durable outbound agent record (client registry persistence). */
|
|
43
|
+
export interface OutboundAgentRecord {
|
|
44
|
+
readonly id: string
|
|
45
|
+
readonly name: string
|
|
46
|
+
readonly agentCardUrl: string
|
|
47
|
+
readonly bearerTokenEnv?: string
|
|
48
|
+
readonly enabled: boolean
|
|
49
|
+
readonly timeoutMs: number
|
|
50
|
+
readonly lastCardAt: string | null
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** JSON-encoded record schema shared by every `a2a` table. */
|
|
54
|
+
const json = z.string()
|
|
55
|
+
|
|
56
|
+
/** The `a2a` storage domain: JSON-encoded records, one table per record kind. */
|
|
57
|
+
export const a2aDomainSpec = defineDomain({
|
|
58
|
+
name: 'a2a',
|
|
59
|
+
version: 1,
|
|
60
|
+
tables: {
|
|
61
|
+
tasks: domainTable<string, string>(json),
|
|
62
|
+
contexts: domainTable<string, string>(json),
|
|
63
|
+
agents: domainTable<string, string>(json),
|
|
64
|
+
},
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
export type A2aDomainSpec = typeof a2aDomainSpec
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Serialize/deserialize helpers for the domain tables. Plain JSON round-trip
|
|
71
|
+
* with shape assertions; `decodeRecord` returns undefined on any mismatch.
|
|
72
|
+
*/
|
|
73
|
+
export function encodeRecord(value: unknown): string {
|
|
74
|
+
return JSON.stringify(value)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function decodeRecord<T>(raw: string): T | undefined {
|
|
78
|
+
try {
|
|
79
|
+
return JSON.parse(raw) as T
|
|
80
|
+
} catch {
|
|
81
|
+
return undefined
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Open the `a2a` domain on the mounted storage-domain facility and expose
|
|
87
|
+
* its tables. The caller owns the returned handle and closes it on teardown.
|
|
88
|
+
*/
|
|
89
|
+
export async function openDomain(domain: DomainFacility): Promise<A2aDomain> {
|
|
90
|
+
const handle = await domain.open(a2aDomainSpec)
|
|
91
|
+
return new A2aDomain(handle)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** A2a domain facade: typed JSON tables over the routed backend. */
|
|
95
|
+
export class A2aDomain {
|
|
96
|
+
constructor(readonly handle: Domain<A2aDomainSpec>) {}
|
|
97
|
+
|
|
98
|
+
get tasks(): KvTable<string, string> {
|
|
99
|
+
return this.handle.table('tasks')
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
get contexts(): KvTable<string, string> {
|
|
103
|
+
return this.handle.table('contexts')
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
get agents(): KvTable<string, string> {
|
|
107
|
+
return this.handle.table('agents')
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async close(): Promise<void> {
|
|
111
|
+
await this.handle.close()
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Task-store contract shared by the domain-backed and memory stores. */
|
|
116
|
+
export interface TaskStore {
|
|
117
|
+
create(input: { contextId: string; skill: string; parts: readonly Part[]; remotePeerId: string | null }): TaskRecord
|
|
118
|
+
get(taskId: string): TaskRecord | undefined
|
|
119
|
+
list(): TaskRecord[]
|
|
120
|
+
setState(taskId: string, state: TaskState, message?: { code: string; text: string }): TaskRecord
|
|
121
|
+
appendArtifact(taskId: string, artifact: { artifactId: string; name?: string; parts: readonly Part[]; lastChunk?: boolean }): TaskRecord
|
|
122
|
+
setContextSession(contextId: string, sessionId: string): Promise<void>
|
|
123
|
+
getContextSession(contextId: string): Promise<string | undefined>
|
|
124
|
+
close(): Promise<void>
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function now(): string {
|
|
128
|
+
return new Date().toISOString()
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function recordKey(taskId: string): string {
|
|
132
|
+
return `task:${taskId}`
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function contextKey(contextId: string): string {
|
|
136
|
+
return `ctx:${contextId}`
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** In-memory TaskStore (unit tests, minimal embeddings). */
|
|
140
|
+
export class MemoryTaskStore implements TaskStore {
|
|
141
|
+
private tasks = new Map<string, TaskRecord>()
|
|
142
|
+
private contexts = new Map<string, string>()
|
|
143
|
+
|
|
144
|
+
create(input: { contextId: string; skill: string; parts: readonly Part[]; remotePeerId: string | null }): TaskRecord {
|
|
145
|
+
const record: TaskRecord = {
|
|
146
|
+
taskId: `a2a-${crypto.randomUUID()}`,
|
|
147
|
+
contextId: input.contextId,
|
|
148
|
+
skill: input.skill,
|
|
149
|
+
state: TaskState.SUBMITTED,
|
|
150
|
+
createdAt: now(),
|
|
151
|
+
updatedAt: now(),
|
|
152
|
+
sessionId: null,
|
|
153
|
+
remotePeerId: input.remotePeerId,
|
|
154
|
+
parts: input.parts,
|
|
155
|
+
artifacts: [],
|
|
156
|
+
executor: 'session',
|
|
157
|
+
summary: null,
|
|
158
|
+
}
|
|
159
|
+
this.tasks.set(record.taskId, record)
|
|
160
|
+
return record
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
get(taskId: string): TaskRecord | undefined {
|
|
164
|
+
return this.tasks.get(taskId)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
list(): TaskRecord[] {
|
|
168
|
+
return [...this.tasks.values()]
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
setState(taskId: string, state: TaskState, message?: { code: string; text: string }): TaskRecord {
|
|
172
|
+
const current = this.tasks.get(taskId)
|
|
173
|
+
if (current === undefined) throw new Error(`task ${taskId} not found`)
|
|
174
|
+
const next: TaskRecord = {
|
|
175
|
+
...current,
|
|
176
|
+
state,
|
|
177
|
+
updatedAt: now(),
|
|
178
|
+
...(message ? { error: { code: message.code, message: message.text } } : current.error ? { error: current.error } : {}),
|
|
179
|
+
}
|
|
180
|
+
this.tasks.set(taskId, next)
|
|
181
|
+
return next
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
appendArtifact(taskId: string, artifact: { artifactId: string; name?: string; parts: readonly Part[]; lastChunk?: boolean }): TaskRecord {
|
|
185
|
+
const current = this.tasks.get(taskId)
|
|
186
|
+
if (current === undefined) throw new Error(`task ${taskId} not found`)
|
|
187
|
+
const next: TaskRecord = {
|
|
188
|
+
...current,
|
|
189
|
+
updatedAt: now(),
|
|
190
|
+
artifacts: appendArtifactRecord(current.artifacts, artifact),
|
|
191
|
+
}
|
|
192
|
+
this.tasks.set(taskId, next)
|
|
193
|
+
return next
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
async setContextSession(contextId: string, sessionId: string): Promise<void> {
|
|
197
|
+
this.contexts.set(contextId, sessionId)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
async getContextSession(contextId: string): Promise<string | undefined> {
|
|
201
|
+
return this.contexts.get(contextId)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
async close(): Promise<void> {}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function appendArtifactRecord(
|
|
208
|
+
artifacts: TaskRecord['artifacts'],
|
|
209
|
+
artifact: { artifactId: string; name?: string; parts: readonly Part[] },
|
|
210
|
+
): TaskRecord['artifacts'] {
|
|
211
|
+
const existing = artifacts.find((a) => a.artifactId === artifact.artifactId)
|
|
212
|
+
if (existing) {
|
|
213
|
+
return artifacts.map((a) => (a.artifactId === artifact.artifactId ? { ...a, parts: [...a.parts, ...artifact.parts] } : a))
|
|
214
|
+
}
|
|
215
|
+
return [...artifacts, { artifactId: artifact.artifactId, ...(artifact.name !== undefined ? { name: artifact.name } : {}), parts: artifact.parts }]
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/** Domain-backed TaskStore (persistent; the composition path). */
|
|
219
|
+
export class DomainTaskStore implements TaskStore {
|
|
220
|
+
// The real `KvTable.put` queues on the domain's write chain: durability
|
|
221
|
+
// first, then the in-memory table updates. TaskStore's synchronous readers
|
|
222
|
+
// must see their own writes immediately, so this store keeps the live view
|
|
223
|
+
// in memory, seeds it from the domain's opened tables (already loaded from
|
|
224
|
+
// the medium), updates it before each queued write, and never reads the
|
|
225
|
+
// table back for its own writes.
|
|
226
|
+
private readonly records = new Map<string, TaskRecord>()
|
|
227
|
+
private readonly bindings = new Map<string, string>()
|
|
228
|
+
|
|
229
|
+
constructor(private readonly domain: A2aDomain) {
|
|
230
|
+
for (const [key, raw] of domain.tasks.entries()) {
|
|
231
|
+
if (!key.startsWith('task:')) continue
|
|
232
|
+
const record = decodeRecord<TaskRecord>(raw)
|
|
233
|
+
if (record !== undefined) this.records.set(record.taskId, record)
|
|
234
|
+
}
|
|
235
|
+
for (const [key, raw] of domain.contexts.entries()) {
|
|
236
|
+
if (!key.startsWith('ctx:')) continue
|
|
237
|
+
const binding = decodeRecord<ContextBinding>(raw)
|
|
238
|
+
if (binding !== undefined) this.bindings.set(key.slice('ctx:'.length), binding.sessionId)
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
create(input: { contextId: string; skill: string; parts: readonly Part[]; remotePeerId: string | null }): TaskRecord {
|
|
243
|
+
const record: TaskRecord = {
|
|
244
|
+
taskId: `a2a-${crypto.randomUUID()}`,
|
|
245
|
+
contextId: input.contextId,
|
|
246
|
+
skill: input.skill,
|
|
247
|
+
state: TaskState.SUBMITTED,
|
|
248
|
+
createdAt: now(),
|
|
249
|
+
updatedAt: now(),
|
|
250
|
+
sessionId: null,
|
|
251
|
+
remotePeerId: input.remotePeerId,
|
|
252
|
+
parts: input.parts,
|
|
253
|
+
artifacts: [],
|
|
254
|
+
executor: 'session',
|
|
255
|
+
summary: null,
|
|
256
|
+
}
|
|
257
|
+
this.records.set(record.taskId, record)
|
|
258
|
+
// Persist eagerly; a failed write must fail the task, not silently lose it.
|
|
259
|
+
void this.domain.tasks.put(recordKey(record.taskId), encodeRecord(record)).catch((err: unknown) => {
|
|
260
|
+
throw new Error(`a2a: task persistence failed: ${String(err)}`)
|
|
261
|
+
})
|
|
262
|
+
return record
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
get(taskId: string): TaskRecord | undefined {
|
|
266
|
+
return this.records.get(taskId)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
list(): TaskRecord[] {
|
|
270
|
+
return [...this.records.values()]
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
setState(taskId: string, state: TaskState, message?: { code: string; text: string }): TaskRecord {
|
|
274
|
+
const current = this.records.get(taskId)
|
|
275
|
+
if (current === undefined) throw new Error(`task ${taskId} not found`)
|
|
276
|
+
const next: TaskRecord = withState(current, state, message, now())
|
|
277
|
+
this.records.set(taskId, next)
|
|
278
|
+
void this.domain.tasks.put(recordKey(taskId), encodeRecord(next)).catch((err: unknown) => {
|
|
279
|
+
throw new Error(`a2a: task persistence failed: ${String(err)}`)
|
|
280
|
+
})
|
|
281
|
+
return next
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
appendArtifact(taskId: string, artifact: { artifactId: string; name?: string; parts: readonly Part[]; lastChunk?: boolean }): TaskRecord {
|
|
285
|
+
const current = this.records.get(taskId)
|
|
286
|
+
if (current === undefined) throw new Error(`task ${taskId} not found`)
|
|
287
|
+
const next: TaskRecord = { ...current, updatedAt: now(), artifacts: appendArtifactRecord(current.artifacts, artifact) }
|
|
288
|
+
this.records.set(taskId, next)
|
|
289
|
+
void this.domain.tasks.put(recordKey(taskId), encodeRecord(next)).catch((err: unknown) => {
|
|
290
|
+
throw new Error(`a2a: task persistence failed: ${String(err)}`)
|
|
291
|
+
})
|
|
292
|
+
return next
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
async setContextSession(contextId: string, sessionId: string): Promise<void> {
|
|
296
|
+
const binding: ContextBinding = { sessionId }
|
|
297
|
+
this.bindings.set(contextId, sessionId)
|
|
298
|
+
await this.domain.contexts.put(contextKey(contextId), encodeRecord(binding))
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
async getContextSession(contextId: string): Promise<string | undefined> {
|
|
302
|
+
return this.bindings.get(contextId)
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
async close(): Promise<void> {}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function withState(
|
|
309
|
+
current: TaskRecord,
|
|
310
|
+
state: TaskState,
|
|
311
|
+
message: { code: string; text: string } | undefined,
|
|
312
|
+
timestamp: string,
|
|
313
|
+
): TaskRecord {
|
|
314
|
+
return {
|
|
315
|
+
...current,
|
|
316
|
+
state,
|
|
317
|
+
updatedAt: timestamp,
|
|
318
|
+
...(message ? { error: { code: message.code, message: message.text } } : {}),
|
|
319
|
+
}
|
|
320
|
+
}
|
package/src/service.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `ctx.a2a` service facade: the thin read/control surface commands and
|
|
3
|
+
* other plugins use. Registered as a Cordis Service so the key disappears
|
|
4
|
+
* with the plugin fiber.
|
|
5
|
+
* @module dsh-a2a/service
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Service, type Context } from '@deepseek-ai/cordis'
|
|
9
|
+
|
|
10
|
+
/** A result with a user-facing message. */
|
|
11
|
+
export interface OpResult {
|
|
12
|
+
readonly ok: boolean
|
|
13
|
+
readonly message: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** The implementation the facade delegates to (owned by the plugin assembly). */
|
|
17
|
+
export interface A2AServiceImpl {
|
|
18
|
+
status(): unknown
|
|
19
|
+
enableServer(enable: boolean): Promise<OpResult>
|
|
20
|
+
getTask(taskId: string): unknown
|
|
21
|
+
listTasks(): unknown
|
|
22
|
+
cancelTask(taskId: string): Promise<OpResult>
|
|
23
|
+
agents(): unknown
|
|
24
|
+
addAgent(spec: { readonly name: string; readonly agentCardUrl: string; readonly bearerTokenEnv?: string }): Promise<OpResult>
|
|
25
|
+
removeAgent(id: string): Promise<OpResult>
|
|
26
|
+
setAgentEnabled(id: string, enabled: boolean): Promise<OpResult>
|
|
27
|
+
refreshAgentCard(id: string): Promise<OpResult>
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** The service other plugins read as `ctx.a2a`. */
|
|
31
|
+
export class A2AService extends Service {
|
|
32
|
+
constructor(
|
|
33
|
+
ctx: Context,
|
|
34
|
+
private readonly impl: A2AServiceImpl,
|
|
35
|
+
) {
|
|
36
|
+
super(ctx, 'a2a')
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
status(): unknown {
|
|
40
|
+
return this.impl.status()
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async enableServer(enable: boolean): Promise<OpResult> {
|
|
44
|
+
return this.impl.enableServer(enable)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
getTask(taskId: string): unknown {
|
|
48
|
+
return this.impl.getTask(taskId)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
listTasks(): unknown {
|
|
52
|
+
return this.impl.listTasks()
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async cancelTask(taskId: string): Promise<OpResult> {
|
|
56
|
+
return this.impl.cancelTask(taskId)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
agents(): unknown {
|
|
60
|
+
return this.impl.agents()
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async addAgent(spec: { readonly name: string; readonly agentCardUrl: string; readonly bearerTokenEnv?: string }): Promise<OpResult> {
|
|
64
|
+
return this.impl.addAgent(spec)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async removeAgent(id: string): Promise<OpResult> {
|
|
68
|
+
return this.impl.removeAgent(id)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async setAgentEnabled(id: string, enabled: boolean): Promise<OpResult> {
|
|
72
|
+
return this.impl.setAgentEnabled(id, enabled)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async refreshAgentCard(id: string): Promise<OpResult> {
|
|
76
|
+
return this.impl.refreshAgentCard(id)
|
|
77
|
+
}
|
|
78
|
+
}
|