openyida 2026.5.9 → 2026.5.12
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 +1 -0
- package/bin/yida.js +12 -0
- package/lib/a2a/cmd.js +98 -0
- package/lib/a2a/server.js +370 -0
- package/lib/core/command-manifest.js +5 -0
- package/lib/core/locales/ar.js +2 -0
- package/lib/core/locales/de.js +2 -0
- package/lib/core/locales/en.js +2 -0
- package/lib/core/locales/es.js +2 -0
- package/lib/core/locales/fr.js +2 -0
- package/lib/core/locales/hi.js +2 -0
- package/lib/core/locales/ja.js +2 -0
- package/lib/core/locales/ko.js +2 -0
- package/lib/core/locales/pt.js +2 -0
- package/lib/core/locales/vi.js +2 -0
- package/lib/core/locales/zh-HK.js +2 -0
- package/lib/core/locales/zh.js +2 -0
- package/lib/corp-manager/api.js +311 -0
- package/lib/corp-manager/corp-manager.js +210 -0
- package/package.json +1 -1
- package/scripts/e2e-real/skill-coverage.js +1 -0
- package/yida-skills/SKILL.md +1 -0
- package/yida-skills/skills/yida-corp-manager/SKILL.md +83 -0
package/README.md
CHANGED
|
@@ -296,6 +296,7 @@ Run `openyida --help` or `openyida <command> --help` for detailed usage.
|
|
|
296
296
|
| `openyida task-center <type> [options]` | Query todo, created, processed, CC, or proxy-submitted tasks |
|
|
297
297
|
| `openyida get-permission <appType> <formUuid>` | Query form permission configuration |
|
|
298
298
|
| `openyida save-permission <appType> <formUuid> [options]` | Save form permission configuration |
|
|
299
|
+
| `openyida corp-manager <sub-command>` | Manage platform admins, sub-admins, app admins, and address book visibility |
|
|
299
300
|
| `openyida verify-short-url <appType> <formUuid> <url>` | Verify a short URL |
|
|
300
301
|
| `openyida save-share-config <appType> <formUuid> <url> <isOpen> [openAuth]` | Save public access or sharing configuration |
|
|
301
302
|
| `openyida get-page-config <appType> <formUuid>` | Query public access or sharing configuration |
|
package/bin/yida.js
CHANGED
|
@@ -312,6 +312,12 @@ async function main() {
|
|
|
312
312
|
break;
|
|
313
313
|
}
|
|
314
314
|
|
|
315
|
+
case 'a2a': {
|
|
316
|
+
const { run } = require('../lib/a2a/cmd');
|
|
317
|
+
await run(args);
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
320
|
+
|
|
315
321
|
case 'env': {
|
|
316
322
|
if (shouldUseEnvManagement(args)) {
|
|
317
323
|
const { run } = require('../lib/core/env-cmd');
|
|
@@ -827,6 +833,12 @@ async function main() {
|
|
|
827
833
|
break;
|
|
828
834
|
}
|
|
829
835
|
|
|
836
|
+
case 'corp-manager': {
|
|
837
|
+
const { run: runCorpManager } = require('../lib/corp-manager/corp-manager');
|
|
838
|
+
await runCorpManager(args);
|
|
839
|
+
break;
|
|
840
|
+
}
|
|
841
|
+
|
|
830
842
|
case 'flash-to-prd': {
|
|
831
843
|
const { run: runFlashToPrd } = require('../lib/flash-note/flash-to-prd');
|
|
832
844
|
await runFlashToPrd(args);
|
package/lib/a2a/cmd.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { createA2aHttpServer, DEFAULT_HOST, DEFAULT_PORT, listen } = require('./server');
|
|
4
|
+
|
|
5
|
+
function hasFlag(args, name) {
|
|
6
|
+
return args.includes(name);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function getArgValue(args, name, defaultValue) {
|
|
10
|
+
const index = args.indexOf(name);
|
|
11
|
+
if (index === -1 || !args[index + 1] || args[index + 1].startsWith('--')) {
|
|
12
|
+
return defaultValue;
|
|
13
|
+
}
|
|
14
|
+
return args[index + 1];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function printUsage() {
|
|
18
|
+
console.log(`
|
|
19
|
+
Usage: openyida a2a <serve|agent-card> [options]
|
|
20
|
+
|
|
21
|
+
Commands:
|
|
22
|
+
serve Start a local read-only A2A HTTP adapter
|
|
23
|
+
agent-card Print the A2A Agent Card JSON
|
|
24
|
+
|
|
25
|
+
Options:
|
|
26
|
+
--host <host> Bind host, default: ${DEFAULT_HOST}
|
|
27
|
+
--port <port> Bind port, default: ${DEFAULT_PORT}
|
|
28
|
+
--base-url <url> Public base URL shown in Agent Card
|
|
29
|
+
--json Print machine-readable startup output
|
|
30
|
+
|
|
31
|
+
Examples:
|
|
32
|
+
openyida a2a agent-card
|
|
33
|
+
openyida a2a serve --host 127.0.0.1 --port 8787
|
|
34
|
+
`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function parseServerOptions(args) {
|
|
38
|
+
const host = getArgValue(args, '--host', DEFAULT_HOST);
|
|
39
|
+
const port = Number(getArgValue(args, '--port', DEFAULT_PORT));
|
|
40
|
+
if (!Number.isInteger(port) || port <= 0 || port > 65535) {
|
|
41
|
+
throw new Error(`Invalid --port value: ${port}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
host,
|
|
46
|
+
port,
|
|
47
|
+
baseUrl: getArgValue(args, '--base-url', `http://${host}:${port}`),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function run(args = []) {
|
|
52
|
+
const subCommand = args[0];
|
|
53
|
+
const subArgs = args.slice(1);
|
|
54
|
+
|
|
55
|
+
if (!subCommand || subCommand === '--help' || subCommand === '-h') {
|
|
56
|
+
printUsage();
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (subCommand === 'agent-card') {
|
|
61
|
+
const { createAgentCard } = require('./server');
|
|
62
|
+
const options = parseServerOptions(subArgs);
|
|
63
|
+
console.log(JSON.stringify(createAgentCard(options), null, 2));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (subCommand === 'serve') {
|
|
68
|
+
const options = parseServerOptions(subArgs);
|
|
69
|
+
const server = createA2aHttpServer(options);
|
|
70
|
+
await listen(server, options);
|
|
71
|
+
|
|
72
|
+
const startup = {
|
|
73
|
+
ok: true,
|
|
74
|
+
readonly: true,
|
|
75
|
+
host: options.host,
|
|
76
|
+
port: options.port,
|
|
77
|
+
base_url: options.baseUrl,
|
|
78
|
+
agent_card_url: `${options.baseUrl}/.well-known/agent-card.json`,
|
|
79
|
+
message_send_url: `${options.baseUrl}/message:send`,
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
if (hasFlag(subArgs, '--json')) {
|
|
83
|
+
console.log(JSON.stringify(startup));
|
|
84
|
+
} else {
|
|
85
|
+
console.log(`OpenYida A2A local adapter listening on ${options.baseUrl}`);
|
|
86
|
+
console.log(`Agent Card: ${startup.agent_card_url}`);
|
|
87
|
+
console.log('Mode: read-only preview');
|
|
88
|
+
}
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
throw new Error(`Unknown a2a subcommand: ${subCommand}`);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
module.exports = {
|
|
96
|
+
parseServerOptions,
|
|
97
|
+
run,
|
|
98
|
+
};
|
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const http = require('http');
|
|
4
|
+
const { version } = require('../../package.json');
|
|
5
|
+
const { buildCommandManifest } = require('../core/command-manifest');
|
|
6
|
+
const { t } = require('../core/i18n');
|
|
7
|
+
|
|
8
|
+
const A2A_PROTOCOL_VERSION = '1.0';
|
|
9
|
+
const DEFAULT_HOST = '127.0.0.1';
|
|
10
|
+
const DEFAULT_PORT = 8787;
|
|
11
|
+
const JSON_CONTENT_TYPE = 'application/json; charset=utf-8';
|
|
12
|
+
|
|
13
|
+
function createJsonResponse(statusCode, body, headers = {}) {
|
|
14
|
+
return {
|
|
15
|
+
statusCode,
|
|
16
|
+
headers: {
|
|
17
|
+
'content-type': JSON_CONTENT_TYPE,
|
|
18
|
+
'cache-control': 'no-store',
|
|
19
|
+
...headers,
|
|
20
|
+
},
|
|
21
|
+
body: JSON.stringify(body, null, 2),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function createTextResponse(statusCode, body, headers = {}) {
|
|
26
|
+
return {
|
|
27
|
+
statusCode,
|
|
28
|
+
headers: {
|
|
29
|
+
'content-type': 'text/plain; charset=utf-8',
|
|
30
|
+
'cache-control': 'no-store',
|
|
31
|
+
...headers,
|
|
32
|
+
},
|
|
33
|
+
body,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function createA2aError(code, message, details) {
|
|
38
|
+
return {
|
|
39
|
+
error: {
|
|
40
|
+
code,
|
|
41
|
+
message,
|
|
42
|
+
...(details === undefined ? {} : { details }),
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function createAgentCard(options = {}) {
|
|
48
|
+
const baseUrl = options.baseUrl || `http://${options.host || DEFAULT_HOST}:${options.port || DEFAULT_PORT}`;
|
|
49
|
+
return {
|
|
50
|
+
protocolVersion: A2A_PROTOCOL_VERSION,
|
|
51
|
+
name: 'OpenYida Local Adapter',
|
|
52
|
+
description: 'Local read-only A2A adapter for OpenYida CLI capabilities.',
|
|
53
|
+
url: baseUrl,
|
|
54
|
+
provider: {
|
|
55
|
+
organization: 'OpenYida',
|
|
56
|
+
url: 'https://github.com/openyida/openyida',
|
|
57
|
+
},
|
|
58
|
+
version,
|
|
59
|
+
documentationUrl: 'https://github.com/openyida/openyida',
|
|
60
|
+
capabilities: {
|
|
61
|
+
streaming: false,
|
|
62
|
+
pushNotifications: false,
|
|
63
|
+
stateTransitionHistory: true,
|
|
64
|
+
},
|
|
65
|
+
defaultInputModes: ['text/plain', 'application/json'],
|
|
66
|
+
defaultOutputModes: ['text/plain', 'application/json'],
|
|
67
|
+
skills: [
|
|
68
|
+
{
|
|
69
|
+
id: 'openyida.command_manifest',
|
|
70
|
+
name: 'OpenYida command manifest',
|
|
71
|
+
description: 'Returns the machine-readable OpenYida CLI command manifest.',
|
|
72
|
+
tags: ['openyida', 'cli', 'commands'],
|
|
73
|
+
examples: ['List OpenYida commands', 'Show command manifest'],
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
id: 'openyida.a2a_health',
|
|
77
|
+
name: 'OpenYida A2A health',
|
|
78
|
+
description: 'Reports local A2A adapter health and readonly mode.',
|
|
79
|
+
tags: ['openyida', 'a2a', 'health'],
|
|
80
|
+
examples: ['health', 'status'],
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
securitySchemes: {
|
|
84
|
+
localOnly: {
|
|
85
|
+
type: 'apiKey',
|
|
86
|
+
in: 'header',
|
|
87
|
+
name: 'X-OpenYida-Local-Only',
|
|
88
|
+
description: 'The first preview server binds to localhost by default and does not require credentials.',
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
security: [{ localOnly: [] }],
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function createTaskStore() {
|
|
96
|
+
const tasks = new Map();
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
set(task) {
|
|
100
|
+
tasks.set(task.id, task);
|
|
101
|
+
return task;
|
|
102
|
+
},
|
|
103
|
+
get(taskId) {
|
|
104
|
+
return tasks.get(taskId) || null;
|
|
105
|
+
},
|
|
106
|
+
update(taskId, updater) {
|
|
107
|
+
const currentTask = tasks.get(taskId);
|
|
108
|
+
if (!currentTask) {return null;}
|
|
109
|
+
const nextTask = updater(currentTask);
|
|
110
|
+
tasks.set(taskId, nextTask);
|
|
111
|
+
return nextTask;
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function createTaskId(now = Date.now()) {
|
|
117
|
+
const randomSuffix = Math.random().toString(36).slice(2, 10);
|
|
118
|
+
return `task-${now.toString(36)}-${randomSuffix}`;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function extractTextFromMessage(message) {
|
|
122
|
+
if (!message) {return '';}
|
|
123
|
+
if (typeof message === 'string') {return message;}
|
|
124
|
+
if (typeof message.text === 'string') {return message.text;}
|
|
125
|
+
if (Array.isArray(message.parts)) {
|
|
126
|
+
return message.parts
|
|
127
|
+
.map((part) => {
|
|
128
|
+
if (!part) {return '';}
|
|
129
|
+
if (typeof part === 'string') {return part;}
|
|
130
|
+
if (typeof part.text === 'string') {return part.text;}
|
|
131
|
+
if (part.kind === 'text' && typeof part.content === 'string') {return part.content;}
|
|
132
|
+
return '';
|
|
133
|
+
})
|
|
134
|
+
.filter(Boolean)
|
|
135
|
+
.join('\n');
|
|
136
|
+
}
|
|
137
|
+
return '';
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function createTextPart(text) {
|
|
141
|
+
return {
|
|
142
|
+
kind: 'text',
|
|
143
|
+
text,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function createDataPart(data) {
|
|
148
|
+
return {
|
|
149
|
+
kind: 'data',
|
|
150
|
+
data,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function createAgentMessage(parts) {
|
|
155
|
+
return {
|
|
156
|
+
role: 'agent',
|
|
157
|
+
parts,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function buildCommandManifestResult() {
|
|
162
|
+
const manifest = buildCommandManifest({ t, version });
|
|
163
|
+
return createAgentMessage([
|
|
164
|
+
createTextPart(`OpenYida exposes ${manifest.commands.length} CLI commands. This A2A preview is read-only.`),
|
|
165
|
+
createDataPart({ manifest }),
|
|
166
|
+
]);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function buildHealthResult(options = {}) {
|
|
170
|
+
return createAgentMessage([
|
|
171
|
+
createTextPart('OpenYida A2A local adapter is running in read-only preview mode.'),
|
|
172
|
+
createDataPart({
|
|
173
|
+
ok: true,
|
|
174
|
+
protocolVersion: A2A_PROTOCOL_VERSION,
|
|
175
|
+
version,
|
|
176
|
+
readonly: true,
|
|
177
|
+
host: options.host || DEFAULT_HOST,
|
|
178
|
+
port: options.port || DEFAULT_PORT,
|
|
179
|
+
}),
|
|
180
|
+
]);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function buildFallbackResult(inputText) {
|
|
184
|
+
return createAgentMessage([
|
|
185
|
+
createTextPart([
|
|
186
|
+
'OpenYida A2A preview currently supports read-only discovery commands.',
|
|
187
|
+
'Try: "health", "status", "commands", or "command manifest".',
|
|
188
|
+
inputText ? `Received: ${inputText}` : '',
|
|
189
|
+
].filter(Boolean).join('\n')),
|
|
190
|
+
]);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function runReadonlySkill(inputText, options = {}) {
|
|
194
|
+
const normalizedText = String(inputText || '').trim().toLowerCase();
|
|
195
|
+
if (!normalizedText || /health|status|ping|a2a/.test(normalizedText)) {
|
|
196
|
+
return buildHealthResult(options);
|
|
197
|
+
}
|
|
198
|
+
if (/command|manifest|commands|capabilit|能力|命令/.test(normalizedText)) {
|
|
199
|
+
return buildCommandManifestResult();
|
|
200
|
+
}
|
|
201
|
+
return buildFallbackResult(inputText);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function createCompletedTask(inputMessage, outputMessage, now = new Date()) {
|
|
205
|
+
return {
|
|
206
|
+
id: createTaskId(now.getTime()),
|
|
207
|
+
contextId: inputMessage && (inputMessage.contextId || inputMessage.context_id) || undefined,
|
|
208
|
+
status: {
|
|
209
|
+
state: 'completed',
|
|
210
|
+
timestamp: now.toISOString(),
|
|
211
|
+
},
|
|
212
|
+
history: [
|
|
213
|
+
{
|
|
214
|
+
role: 'user',
|
|
215
|
+
parts: inputMessage && Array.isArray(inputMessage.parts) ? inputMessage.parts : [createTextPart(extractTextFromMessage(inputMessage))],
|
|
216
|
+
},
|
|
217
|
+
outputMessage,
|
|
218
|
+
],
|
|
219
|
+
artifacts: [
|
|
220
|
+
{
|
|
221
|
+
artifactId: 'openyida-readonly-result',
|
|
222
|
+
name: 'OpenYida read-only result',
|
|
223
|
+
parts: outputMessage.parts,
|
|
224
|
+
},
|
|
225
|
+
],
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function parseJsonBody(rawBody) {
|
|
230
|
+
if (!rawBody) {return {};}
|
|
231
|
+
return JSON.parse(rawBody);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function normalizePath(pathname) {
|
|
235
|
+
return pathname.replace(/\/+$/, '') || '/';
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
async function handleA2aRequest(request, rawBody = '', context = {}) {
|
|
239
|
+
const url = new URL(request.url, 'http://localhost');
|
|
240
|
+
const pathname = normalizePath(url.pathname);
|
|
241
|
+
const method = request.method || 'GET';
|
|
242
|
+
const taskStore = context.taskStore || createTaskStore();
|
|
243
|
+
const serverOptions = context.serverOptions || {};
|
|
244
|
+
|
|
245
|
+
if (method === 'OPTIONS') {
|
|
246
|
+
return createTextResponse(204, '', {
|
|
247
|
+
allow: 'GET,POST,OPTIONS',
|
|
248
|
+
'access-control-allow-origin': '*',
|
|
249
|
+
'access-control-allow-methods': 'GET,POST,OPTIONS',
|
|
250
|
+
'access-control-allow-headers': 'content-type,authorization',
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (method === 'GET' && (pathname === '/.well-known/agent-card.json' || pathname === '/agent-card.json')) {
|
|
255
|
+
return createJsonResponse(200, createAgentCard(serverOptions));
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
if (method === 'GET' && (pathname === '/' || pathname === '/health')) {
|
|
259
|
+
return createJsonResponse(200, {
|
|
260
|
+
ok: true,
|
|
261
|
+
name: 'openyida-a2a',
|
|
262
|
+
protocolVersion: A2A_PROTOCOL_VERSION,
|
|
263
|
+
agentCard: '/.well-known/agent-card.json',
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (method === 'POST' && (pathname === '/message:send' || pathname === '/a2a/v1/message:send')) {
|
|
268
|
+
let payload;
|
|
269
|
+
try {
|
|
270
|
+
payload = parseJsonBody(rawBody);
|
|
271
|
+
} catch (err) {
|
|
272
|
+
return createJsonResponse(400, createA2aError('INVALID_JSON', err.message));
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const inputMessage = payload.message || payload;
|
|
276
|
+
const inputText = extractTextFromMessage(inputMessage);
|
|
277
|
+
const outputMessage = runReadonlySkill(inputText, serverOptions);
|
|
278
|
+
const task = taskStore.set(createCompletedTask(inputMessage, outputMessage));
|
|
279
|
+
return createJsonResponse(200, task);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const taskMatch = pathname.match(/^\/(?:a2a\/v1\/)?tasks\/([^/]+)$/);
|
|
283
|
+
if (taskMatch && method === 'GET') {
|
|
284
|
+
const task = taskStore.get(decodeURIComponent(taskMatch[1]));
|
|
285
|
+
if (!task) {
|
|
286
|
+
return createJsonResponse(404, createA2aError('TASK_NOT_FOUND', 'Task not found.'));
|
|
287
|
+
}
|
|
288
|
+
return createJsonResponse(200, task);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const cancelMatch = pathname.match(/^\/(?:a2a\/v1\/)?tasks\/([^/]+):cancel$/);
|
|
292
|
+
if (cancelMatch && method === 'POST') {
|
|
293
|
+
const task = taskStore.update(decodeURIComponent(cancelMatch[1]), (currentTask) => ({
|
|
294
|
+
...currentTask,
|
|
295
|
+
status: {
|
|
296
|
+
state: currentTask.status && currentTask.status.state === 'completed' ? 'completed' : 'canceled',
|
|
297
|
+
timestamp: new Date().toISOString(),
|
|
298
|
+
},
|
|
299
|
+
}));
|
|
300
|
+
if (!task) {
|
|
301
|
+
return createJsonResponse(404, createA2aError('TASK_NOT_FOUND', 'Task not found.'));
|
|
302
|
+
}
|
|
303
|
+
return createJsonResponse(200, task);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (pathname.includes('message:stream') || pathname.includes('push')) {
|
|
307
|
+
return createJsonResponse(501, createA2aError(
|
|
308
|
+
'UNSUPPORTED_CAPABILITY',
|
|
309
|
+
'Streaming and push notifications are not supported by this read-only preview adapter.'
|
|
310
|
+
));
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return createJsonResponse(404, createA2aError('NOT_FOUND', `No A2A route for ${method} ${pathname}.`));
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
function writeNodeResponse(nodeResponse, response) {
|
|
317
|
+
nodeResponse.writeHead(response.statusCode, response.headers);
|
|
318
|
+
nodeResponse.end(response.body);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function readRequestBody(request) {
|
|
322
|
+
return new Promise((resolve, reject) => {
|
|
323
|
+
const chunks = [];
|
|
324
|
+
request.on('data', (chunk) => chunks.push(chunk));
|
|
325
|
+
request.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
|
|
326
|
+
request.on('error', reject);
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function createA2aHttpServer(options = {}) {
|
|
331
|
+
const taskStore = options.taskStore || createTaskStore();
|
|
332
|
+
return http.createServer(async (request, response) => {
|
|
333
|
+
try {
|
|
334
|
+
const rawBody = await readRequestBody(request);
|
|
335
|
+
const result = await handleA2aRequest(request, rawBody, {
|
|
336
|
+
taskStore,
|
|
337
|
+
serverOptions: options,
|
|
338
|
+
});
|
|
339
|
+
writeNodeResponse(response, result);
|
|
340
|
+
} catch (err) {
|
|
341
|
+
writeNodeResponse(response, createJsonResponse(500, createA2aError('INTERNAL_ERROR', err.message)));
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function listen(server, options = {}) {
|
|
347
|
+
const host = options.host || DEFAULT_HOST;
|
|
348
|
+
const port = Number(options.port || DEFAULT_PORT);
|
|
349
|
+
return new Promise((resolve, reject) => {
|
|
350
|
+
server.once('error', reject);
|
|
351
|
+
server.listen(port, host, () => {
|
|
352
|
+
server.off('error', reject);
|
|
353
|
+
resolve({ host, port });
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
module.exports = {
|
|
359
|
+
A2A_PROTOCOL_VERSION,
|
|
360
|
+
DEFAULT_HOST,
|
|
361
|
+
DEFAULT_PORT,
|
|
362
|
+
createA2aError,
|
|
363
|
+
createA2aHttpServer,
|
|
364
|
+
createAgentCard,
|
|
365
|
+
createTaskStore,
|
|
366
|
+
extractTextFromMessage,
|
|
367
|
+
handleA2aRequest,
|
|
368
|
+
listen,
|
|
369
|
+
runReadonlySkill,
|
|
370
|
+
};
|
|
@@ -72,6 +72,7 @@ const COMMAND_GROUPS = [
|
|
|
72
72
|
command('task-center', ['task-center'], 'task-center <type> [options]', 'help.cmd_task_center'),
|
|
73
73
|
command('get-permission', ['get-permission'], 'get-permission <appType> <formUuid>', 'help.cmd_get_permission'),
|
|
74
74
|
command('save-permission', ['save-permission'], 'save-permission <appType> <formUuid> ...', 'help.cmd_save_permission'),
|
|
75
|
+
command('corp-manager', ['corp-manager'], 'corp-manager <search-user|list|add|remove|address-book> ...', 'help.cmd_corp_manager', { output: 'json' }),
|
|
75
76
|
],
|
|
76
77
|
},
|
|
77
78
|
{
|
|
@@ -135,6 +136,10 @@ const COMMAND_GROUPS = [
|
|
|
135
136
|
requiresLogin: false,
|
|
136
137
|
output: 'json',
|
|
137
138
|
}),
|
|
139
|
+
command('a2a', ['a2a'], 'a2a <serve|agent-card> [options]', 'help.cmd_a2a', {
|
|
140
|
+
requiresLogin: false,
|
|
141
|
+
output: 'text|json',
|
|
142
|
+
}),
|
|
138
143
|
command('copy', ['copy'], 'copy [--force]', 'help.cmd_copy', { requiresLogin: false }),
|
|
139
144
|
command('sample', ['sample'], 'sample [--list]', 'help.cmd_sample', { requiresLogin: false }),
|
|
140
145
|
command('doctor', ['doctor'], 'doctor [--fix]', 'help.cmd_doctor', { requiresLogin: false }),
|
package/lib/core/locales/ar.js
CHANGED
|
@@ -38,6 +38,7 @@ module.exports = {
|
|
|
38
38
|
cmd_task_center: 'مركز المهام العالمي (معلق/معالج/نسخة إلخ)',
|
|
39
39
|
cmd_get_permission: 'استعلام إعدادات أذونات النموذج',
|
|
40
40
|
cmd_save_permission: 'حفظ إعدادات أذونات النموذج',
|
|
41
|
+
cmd_corp_manager: 'إدارة أذونات منصة المؤسسة',
|
|
41
42
|
group_process: 'العمليات',
|
|
42
43
|
cmd_configure_process: 'تكوين ونشر قواعد العملية',
|
|
43
44
|
cmd_create_process: 'إنشاء نموذج عملية (متكامل)',
|
|
@@ -69,6 +70,7 @@ module.exports = {
|
|
|
69
70
|
cmd_dws: 'DingTalk CLI (جهات الاتصال/التقويم/المهام/الموافقة إلخ)',
|
|
70
71
|
group_utility: 'الأدوات',
|
|
71
72
|
cmd_commands: 'Output machine-readable command manifest',
|
|
73
|
+
cmd_a2a: 'Start local read-only A2A adapter or print Agent Card',
|
|
72
74
|
cmd_copy: 'نسخ دليل عمل project',
|
|
73
75
|
cmd_sample: 'إخراج أمثلة/قوالب الكود',
|
|
74
76
|
cmd_doctor: 'تشخيص البيئة والإصلاح التلقائي',
|
package/lib/core/locales/de.js
CHANGED
|
@@ -38,6 +38,7 @@ module.exports = {
|
|
|
38
38
|
cmd_task_center: 'Globales Aufgabenzentrum (Aufgaben/Bearbeitet/CC etc.)',
|
|
39
39
|
cmd_get_permission: 'Formularberechtigungen abfragen',
|
|
40
40
|
cmd_save_permission: 'Formularberechtigungen speichern',
|
|
41
|
+
cmd_corp_manager: 'Plattformberechtigungen verwalten',
|
|
41
42
|
group_process: 'Prozesse',
|
|
42
43
|
cmd_configure_process: 'Prozessregeln konfigurieren & veröffentlichen',
|
|
43
44
|
cmd_create_process: 'Prozessformular erstellen (All-in-One)',
|
|
@@ -69,6 +70,7 @@ module.exports = {
|
|
|
69
70
|
cmd_dws: 'DingTalk CLI (Kontakte/Kalender/Aufgaben/Genehmigung etc.)',
|
|
70
71
|
group_utility: 'Werkzeuge',
|
|
71
72
|
cmd_commands: 'Maschinenlesbares Command Manifest ausgeben',
|
|
73
|
+
cmd_a2a: 'Lokalen schreibgeschützten A2A-Adapter starten oder Agent Card ausgeben',
|
|
72
74
|
cmd_copy: 'project-Arbeitsverzeichnis kopieren',
|
|
73
75
|
cmd_sample: 'Codebeispiele/Vorlagen ausgeben',
|
|
74
76
|
cmd_doctor: 'Umgebungsdiagnose & automatische Reparatur',
|
package/lib/core/locales/en.js
CHANGED
|
@@ -41,6 +41,7 @@ module.exports = {
|
|
|
41
41
|
cmd_task_center: 'Global task center (todo/processed/cc etc.)',
|
|
42
42
|
cmd_get_permission: 'Query form permission config',
|
|
43
43
|
cmd_save_permission: 'Save form permission config',
|
|
44
|
+
cmd_corp_manager: 'Manage platform admins and address book permissions',
|
|
44
45
|
group_process: 'Process',
|
|
45
46
|
cmd_configure_process: 'Configure and publish process rules',
|
|
46
47
|
cmd_create_process: 'Create process form (all-in-one)',
|
|
@@ -72,6 +73,7 @@ module.exports = {
|
|
|
72
73
|
cmd_dws: 'DingTalk CLI (contacts/calendar/todo/approval etc.)',
|
|
73
74
|
group_utility: 'Utility',
|
|
74
75
|
cmd_commands: 'Output machine-readable command manifest',
|
|
76
|
+
cmd_a2a: 'Start local read-only A2A adapter or print Agent Card',
|
|
75
77
|
cmd_copy: 'Copy project working directory',
|
|
76
78
|
cmd_sample: 'Output code samples/templates',
|
|
77
79
|
cmd_doctor: 'Environment diagnostics & auto-fix',
|
package/lib/core/locales/es.js
CHANGED
|
@@ -38,6 +38,7 @@ module.exports = {
|
|
|
38
38
|
cmd_task_center: 'Centro de tareas global (pendiente/procesado/CC etc.)',
|
|
39
39
|
cmd_get_permission: 'Consultar configuración de permisos',
|
|
40
40
|
cmd_save_permission: 'Guardar configuración de permisos',
|
|
41
|
+
cmd_corp_manager: 'Gestionar permisos de plataforma',
|
|
41
42
|
group_process: 'Procesos',
|
|
42
43
|
cmd_configure_process: 'Configurar y publicar reglas de proceso',
|
|
43
44
|
cmd_create_process: 'Crear formulario de proceso (todo en uno)',
|
|
@@ -69,6 +70,7 @@ module.exports = {
|
|
|
69
70
|
cmd_dws: 'DingTalk CLI (contactos/calendario/tareas/aprobación etc.)',
|
|
70
71
|
group_utility: 'Utilidades',
|
|
71
72
|
cmd_commands: 'Emitir manifiesto de comandos legible por máquina',
|
|
73
|
+
cmd_a2a: 'Iniciar adaptador A2A local de solo lectura o imprimir Agent Card',
|
|
72
74
|
cmd_copy: 'Copiar directorio de trabajo project',
|
|
73
75
|
cmd_sample: 'Generar ejemplos/plantillas de código',
|
|
74
76
|
cmd_doctor: 'Diagnóstico de entorno y reparación automática',
|
package/lib/core/locales/fr.js
CHANGED
|
@@ -38,6 +38,7 @@ module.exports = {
|
|
|
38
38
|
cmd_task_center: 'Centre de tâches global (à faire/traité/CC etc.)',
|
|
39
39
|
cmd_get_permission: 'Consulter la configuration des permissions',
|
|
40
40
|
cmd_save_permission: 'Enregistrer la configuration des permissions',
|
|
41
|
+
cmd_corp_manager: 'Gérer les permissions de plateforme',
|
|
41
42
|
group_process: 'Processus',
|
|
42
43
|
cmd_configure_process: 'Configurer et publier les règles de processus',
|
|
43
44
|
cmd_create_process: 'Créer un formulaire de processus (tout-en-un)',
|
|
@@ -69,6 +70,7 @@ module.exports = {
|
|
|
69
70
|
cmd_dws: 'DingTalk CLI (contacts/calendrier/tâches/approbation etc.)',
|
|
70
71
|
group_utility: 'Utilitaires',
|
|
71
72
|
cmd_commands: 'Afficher le manifeste des commandes lisible par machine',
|
|
73
|
+
cmd_a2a: 'Démarrer l’adaptateur A2A local en lecture seule ou afficher l’Agent Card',
|
|
72
74
|
cmd_copy: 'Copier le répertoire de travail project',
|
|
73
75
|
cmd_sample: 'Exporter des exemples/modèles de code',
|
|
74
76
|
cmd_doctor: 'Diagnostic d\'environnement et réparation auto',
|
package/lib/core/locales/hi.js
CHANGED
|
@@ -38,6 +38,7 @@ module.exports = {
|
|
|
38
38
|
cmd_task_center: 'वैश्विक कार्य केंद्र (लंबित/संसाधित/CC आदि)',
|
|
39
39
|
cmd_get_permission: 'फॉर्म अनुमति कॉन्फ़िगरेशन पूछें',
|
|
40
40
|
cmd_save_permission: 'फॉर्म अनुमति कॉन्फ़िगरेशन सहेजें',
|
|
41
|
+
cmd_corp_manager: 'प्लेटफ़ॉर्म अनुमतियां प्रबंधित करें',
|
|
41
42
|
group_process: 'प्रक्रिया',
|
|
42
43
|
cmd_configure_process: 'प्रक्रिया नियम कॉन्फ़िगर और प्रकाशित करें',
|
|
43
44
|
cmd_create_process: 'प्रक्रिया फॉर्म बनाएं (एकीकृत)',
|
|
@@ -69,6 +70,7 @@ module.exports = {
|
|
|
69
70
|
cmd_dws: 'DingTalk CLI (संपर्क/कैलेंडर/कार्य/अनुमोदन आदि)',
|
|
70
71
|
group_utility: 'उपकरण',
|
|
71
72
|
cmd_commands: 'Output machine-readable command manifest',
|
|
73
|
+
cmd_a2a: 'Start local read-only A2A adapter or print Agent Card',
|
|
72
74
|
cmd_copy: 'project कार्य निर्देशिका कॉपी करें',
|
|
73
75
|
cmd_sample: 'कोड सैंपल/टेम्पलेट आउटपुट करें',
|
|
74
76
|
cmd_doctor: 'वातावरण निदान और स्वचालित मरम्मत',
|
package/lib/core/locales/ja.js
CHANGED
|
@@ -40,6 +40,7 @@ module.exports = {
|
|
|
40
40
|
cmd_task_center: 'グローバルタスクセンター(未処理/処理済/CC等)',
|
|
41
41
|
cmd_get_permission: 'フォーム権限設定を照会',
|
|
42
42
|
cmd_save_permission: 'フォーム権限設定を保存',
|
|
43
|
+
cmd_corp_manager: 'プラットフォーム権限を管理',
|
|
43
44
|
group_process: 'プロセス',
|
|
44
45
|
cmd_configure_process: 'プロセスルールを設定&公開',
|
|
45
46
|
cmd_create_process: 'プロセスフォームを作成(一体型)',
|
|
@@ -71,6 +72,7 @@ module.exports = {
|
|
|
71
72
|
cmd_dws: 'DingTalk CLI(連絡先/カレンダー/ToDo/承認等)',
|
|
72
73
|
group_utility: 'ユーティリティ',
|
|
73
74
|
cmd_commands: '機械可読コマンド manifest を出力',
|
|
75
|
+
cmd_a2a: 'ローカル読み取り専用 A2A Adapter を起動、または Agent Card を出力',
|
|
74
76
|
cmd_copy: 'project 作業ディレクトリをコピー',
|
|
75
77
|
cmd_sample: 'コードサンプル/テンプレートを出力',
|
|
76
78
|
cmd_doctor: '環境診断と自動修復',
|
package/lib/core/locales/ko.js
CHANGED
|
@@ -38,6 +38,7 @@ module.exports = {
|
|
|
38
38
|
cmd_task_center: '글로벌 작업 센터 (할일/처리됨/참조 등)',
|
|
39
39
|
cmd_get_permission: '양식 권한 설정 조회',
|
|
40
40
|
cmd_save_permission: '양식 권한 설정 저장',
|
|
41
|
+
cmd_corp_manager: '플랫폼 권한 관리',
|
|
41
42
|
group_process: '프로세스',
|
|
42
43
|
cmd_configure_process: '프로세스 규칙 설정 및 게시',
|
|
43
44
|
cmd_create_process: '프로세스 양식 생성 (통합형)',
|
|
@@ -69,6 +70,7 @@ module.exports = {
|
|
|
69
70
|
cmd_dws: 'DingTalk CLI (연락처/캘린더/할일/승인 등)',
|
|
70
71
|
group_utility: '유틸리티',
|
|
71
72
|
cmd_commands: 'Output machine-readable command manifest',
|
|
73
|
+
cmd_a2a: 'Start local read-only A2A adapter or print Agent Card',
|
|
72
74
|
cmd_copy: 'project 작업 디렉토리 복사',
|
|
73
75
|
cmd_sample: '코드 샘플/템플릿 출력',
|
|
74
76
|
cmd_doctor: '환경 진단 및 자동 수정',
|
package/lib/core/locales/pt.js
CHANGED
|
@@ -38,6 +38,7 @@ module.exports = {
|
|
|
38
38
|
cmd_task_center: 'Centro de tarefas global (pendente/processado/CC etc.)',
|
|
39
39
|
cmd_get_permission: 'Consultar configuração de permissões',
|
|
40
40
|
cmd_save_permission: 'Salvar configuração de permissões',
|
|
41
|
+
cmd_corp_manager: 'Gerenciar permissões da plataforma',
|
|
41
42
|
group_process: 'Processos',
|
|
42
43
|
cmd_configure_process: 'Configurar e publicar regras de processo',
|
|
43
44
|
cmd_create_process: 'Criar formulário de processo (tudo-em-um)',
|
|
@@ -69,6 +70,7 @@ module.exports = {
|
|
|
69
70
|
cmd_dws: 'DingTalk CLI (contatos/calendário/tarefas/aprovação etc.)',
|
|
70
71
|
group_utility: 'Utilitários',
|
|
71
72
|
cmd_commands: 'Emitir manifesto de comandos legível por máquina',
|
|
73
|
+
cmd_a2a: 'Iniciar adaptador A2A local somente leitura ou imprimir Agent Card',
|
|
72
74
|
cmd_copy: 'Copiar diretório de trabalho project',
|
|
73
75
|
cmd_sample: 'Gerar exemplos/modelos de código',
|
|
74
76
|
cmd_doctor: 'Diagnóstico de ambiente e reparo automático',
|