nexus-agentd 0.1.8 → 0.2.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 +22 -22
- package/README.md +224 -446
- package/dist/a2a/runtime.d.ts +5 -4
- package/dist/a2a/runtime.js +83 -13
- package/dist/acp/runtime.d.ts +3 -8
- package/dist/acp/runtime.js +63 -79
- package/dist/completion-contract.d.ts +1 -0
- package/dist/completion-contract.js +9 -0
- package/dist/config.js +1 -15
- package/dist/control-plane.d.ts +0 -1
- package/dist/control-plane.js +1 -19
- package/dist/run-store.d.ts +1 -1
- package/dist/server.js +63 -248
- package/dist/session-contract.d.ts +3 -2
- package/dist/session.d.ts +11 -2
- package/dist/session.js +202 -17
- package/dist/types.d.ts +25 -45
- package/dist/webui/app.js +912 -1074
- package/dist/webui/icons.d.ts +0 -1
- package/dist/webui/icons.js +0 -1
- package/dist/webui/index.js +10 -10
- package/dist/webui/markup.js +65 -66
- package/dist/webui/styles.js +256 -268
- package/nexus-agentd.example.json +40 -47
- package/package.json +52 -52
- package/dist/agent-instructions.d.ts +0 -11
- package/dist/agent-instructions.js +0 -44
- package/dist/artifact-store.d.ts +0 -41
- package/dist/artifact-store.js +0 -340
- package/dist/workspace-files.d.ts +0 -48
- package/dist/workspace-files.js +0 -269
package/dist/session.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import {
|
|
2
|
+
import { open, realpath } from 'node:fs/promises';
|
|
3
|
+
import { basename, extname, isAbsolute, relative, resolve, sep } from 'node:path';
|
|
4
|
+
import { AcpProcessRuntime } from './acp/runtime.js';
|
|
3
5
|
import { A2AClientRuntime, probeA2AAgent } from './a2a/runtime.js';
|
|
4
6
|
import { SessionEventLog } from './events.js';
|
|
5
7
|
const MAX_SESSION_ARTIFACTS = 64;
|
|
@@ -9,6 +11,7 @@ const READINESS_CACHE_MS = 20_000;
|
|
|
9
11
|
const MAX_INPUT_ATTACHMENTS = 16;
|
|
10
12
|
const MAX_INPUT_ATTACHMENT_BYTES = 16 * 1024 * 1024;
|
|
11
13
|
const MAX_SESSION_INPUT_BYTES = 32 * 1024 * 1024;
|
|
14
|
+
const MAX_PUBLISHED_FILE_BYTES = 12 * 1024 * 1024;
|
|
12
15
|
export class ManagedSession {
|
|
13
16
|
agentId;
|
|
14
17
|
protocol;
|
|
@@ -17,6 +20,7 @@ export class ManagedSession {
|
|
|
17
20
|
maxOutputChars;
|
|
18
21
|
agentName;
|
|
19
22
|
runStore;
|
|
23
|
+
instanceId;
|
|
20
24
|
id = randomUUID();
|
|
21
25
|
createdAt = Date.now();
|
|
22
26
|
events;
|
|
@@ -27,10 +31,11 @@ export class ManagedSession {
|
|
|
27
31
|
output = '';
|
|
28
32
|
error;
|
|
29
33
|
pendingRequest;
|
|
34
|
+
completion;
|
|
30
35
|
artifacts = [];
|
|
31
36
|
inputAttachments = new Map();
|
|
32
37
|
runtime;
|
|
33
|
-
constructor(agentId, protocol, workspace, ownerKeyId, maxEvents, maxOutputChars, agentName, runStore) {
|
|
38
|
+
constructor(agentId, protocol, workspace, ownerKeyId, maxEvents, maxOutputChars, agentName, runStore, instanceId = randomUUID()) {
|
|
34
39
|
this.agentId = agentId;
|
|
35
40
|
this.protocol = protocol;
|
|
36
41
|
this.workspace = workspace;
|
|
@@ -38,6 +43,7 @@ export class ManagedSession {
|
|
|
38
43
|
this.maxOutputChars = maxOutputChars;
|
|
39
44
|
this.agentName = agentName;
|
|
40
45
|
this.runStore = runStore;
|
|
46
|
+
this.instanceId = instanceId;
|
|
41
47
|
this.events = new SessionEventLog(this.id, maxEvents);
|
|
42
48
|
this.events.append('session_state', { state: this.state, protocol });
|
|
43
49
|
}
|
|
@@ -56,6 +62,8 @@ export class ManagedSession {
|
|
|
56
62
|
setState(state, error) {
|
|
57
63
|
if (this.state === state && this.error === error)
|
|
58
64
|
return;
|
|
65
|
+
if (state !== 'completed')
|
|
66
|
+
this.completion = undefined;
|
|
59
67
|
this.state = state;
|
|
60
68
|
this.error = error;
|
|
61
69
|
this.updatedAt = Date.now();
|
|
@@ -66,15 +74,52 @@ export class ManagedSession {
|
|
|
66
74
|
: state === 'canceled'
|
|
67
75
|
? 'canceled'
|
|
68
76
|
: 'session_state';
|
|
69
|
-
this.events.append(type, {
|
|
77
|
+
this.events.append(type, {
|
|
78
|
+
state,
|
|
79
|
+
...(error ? { error } : {}),
|
|
80
|
+
...(state === 'completed' && this.completion
|
|
81
|
+
? { completion: structuredClone(this.completion) }
|
|
82
|
+
: {})
|
|
83
|
+
});
|
|
70
84
|
const endedAt = isTerminal(state) ? this.updatedAt : undefined;
|
|
71
85
|
this.syncRun({
|
|
72
86
|
state,
|
|
73
87
|
error,
|
|
74
88
|
progress: progressForState(state, error),
|
|
89
|
+
completion: state === 'completed' && this.completion
|
|
90
|
+
? structuredClone(this.completion)
|
|
91
|
+
: undefined,
|
|
75
92
|
...(endedAt ? { endedAt } : {})
|
|
76
93
|
});
|
|
77
94
|
}
|
|
95
|
+
completeTurn(proof) {
|
|
96
|
+
if (this.pendingRequest || isInteractive(this.state)) {
|
|
97
|
+
this.emit('terminal_output', {
|
|
98
|
+
stream: 'system',
|
|
99
|
+
text: `Ignored ${proof.source} completion while the session is waiting for ${this.pendingRequest?.kind || 'input'}.`
|
|
100
|
+
});
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
if (this.state !== 'running')
|
|
104
|
+
return false;
|
|
105
|
+
const outputPresent = this.output.trim().length > 0;
|
|
106
|
+
const artifactCount = this.artifacts.length;
|
|
107
|
+
if (!outputPresent && artifactCount < 1) {
|
|
108
|
+
this.setState('failed', `Agent ended the turn (${proof.stopReason}) without a final response or artifact.`);
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
this.completion = {
|
|
112
|
+
...structuredClone(proof),
|
|
113
|
+
runId: this.currentRunId,
|
|
114
|
+
protocol: this.protocol,
|
|
115
|
+
verified: true,
|
|
116
|
+
outputPresent,
|
|
117
|
+
artifactCount,
|
|
118
|
+
completedAt: Date.now()
|
|
119
|
+
};
|
|
120
|
+
this.setState('completed');
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
78
123
|
appendOutput(text) {
|
|
79
124
|
if (!text)
|
|
80
125
|
return;
|
|
@@ -116,7 +161,72 @@ export class ManagedSession {
|
|
|
116
161
|
artifactCount: this.artifacts.length
|
|
117
162
|
});
|
|
118
163
|
}
|
|
164
|
+
async publishFile(filePath) {
|
|
165
|
+
const requestedPath = String(filePath || '').trim();
|
|
166
|
+
if (!requestedPath) {
|
|
167
|
+
throw new SessionRequestError(400, 'path is required');
|
|
168
|
+
}
|
|
169
|
+
if (!this.workspace) {
|
|
170
|
+
throw new SessionRequestError(400, 'This session does not have a local workspace');
|
|
171
|
+
}
|
|
172
|
+
let handle;
|
|
173
|
+
try {
|
|
174
|
+
const workspaceRoot = await realpath(this.workspace);
|
|
175
|
+
const unresolved = resolve(workspaceRoot, requestedPath);
|
|
176
|
+
const target = await realpath(unresolved);
|
|
177
|
+
assertWorkspacePath(workspaceRoot, target);
|
|
178
|
+
handle = await open(target, 'r');
|
|
179
|
+
// Resolve again after opening so a swapped symlink cannot silently
|
|
180
|
+
// redirect a publish request outside the configured workspace.
|
|
181
|
+
const verifiedTarget = await realpath(unresolved);
|
|
182
|
+
assertWorkspacePath(workspaceRoot, verifiedTarget);
|
|
183
|
+
if (verifiedTarget !== target) {
|
|
184
|
+
throw new SessionRequestError(409, 'Published file changed while it was being opened');
|
|
185
|
+
}
|
|
186
|
+
const stats = await handle.stat();
|
|
187
|
+
if (!stats.isFile()) {
|
|
188
|
+
throw new SessionRequestError(400, 'Only regular files can be published');
|
|
189
|
+
}
|
|
190
|
+
if (stats.size > MAX_PUBLISHED_FILE_BYTES) {
|
|
191
|
+
throw new SessionRequestError(413, `Published file exceeds the ${MAX_PUBLISHED_FILE_BYTES} byte limit`);
|
|
192
|
+
}
|
|
193
|
+
const bytes = await handle.readFile();
|
|
194
|
+
const filename = basename(verifiedTarget);
|
|
195
|
+
const workspacePath = relative(workspaceRoot, verifiedTarget).split(sep).join('/');
|
|
196
|
+
const artifact = {
|
|
197
|
+
id: `published:${randomUUID()}`,
|
|
198
|
+
name: filename,
|
|
199
|
+
filename,
|
|
200
|
+
mediaType: mediaTypeForPath(filename),
|
|
201
|
+
bytesBase64: bytes.toString('base64'),
|
|
202
|
+
metadata: {
|
|
203
|
+
source: 'workspace_publish',
|
|
204
|
+
path: workspacePath,
|
|
205
|
+
size: bytes.length
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
this.addArtifact(artifact);
|
|
209
|
+
this.emit('artifact', runArtifact(artifact));
|
|
210
|
+
return artifact;
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
if (error instanceof SessionRequestError)
|
|
214
|
+
throw error;
|
|
215
|
+
const code = error?.code;
|
|
216
|
+
if (code === 'ENOENT') {
|
|
217
|
+
throw new SessionRequestError(404, 'Published file was not found');
|
|
218
|
+
}
|
|
219
|
+
if (code === 'EACCES' || code === 'EPERM') {
|
|
220
|
+
throw new SessionRequestError(403, 'Published file cannot be read');
|
|
221
|
+
}
|
|
222
|
+
throw error;
|
|
223
|
+
}
|
|
224
|
+
finally {
|
|
225
|
+
await handle?.close();
|
|
226
|
+
}
|
|
227
|
+
}
|
|
119
228
|
setPending(request) {
|
|
229
|
+
this.completion = undefined;
|
|
120
230
|
this.pendingRequest = structuredClone(request);
|
|
121
231
|
this.state = request.kind === 'permission' ? 'permission_required' : 'input_required';
|
|
122
232
|
this.updatedAt = Date.now();
|
|
@@ -167,18 +277,10 @@ export class ManagedSession {
|
|
|
167
277
|
throw new SessionRequestError(409, 'Agent runtime is unavailable');
|
|
168
278
|
const attachments = this.inputAttachmentsFor(attachmentIds);
|
|
169
279
|
if (this.pendingRequest) {
|
|
170
|
-
this.
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
await this.runtime.respondPending(message, attachments);
|
|
175
|
-
}
|
|
176
|
-
catch (error) {
|
|
177
|
-
if (error instanceof InvalidPermissionAnswerError) {
|
|
178
|
-
throw new SessionRequestError(400, error.message);
|
|
179
|
-
}
|
|
180
|
-
throw error;
|
|
181
|
-
}
|
|
280
|
+
await this.resolvePending({
|
|
281
|
+
requestId: this.pendingRequest.id,
|
|
282
|
+
message
|
|
283
|
+
}, attachmentIds);
|
|
182
284
|
return;
|
|
183
285
|
}
|
|
184
286
|
if (this.state === 'running') {
|
|
@@ -186,6 +288,7 @@ export class ManagedSession {
|
|
|
186
288
|
}
|
|
187
289
|
this.output = '';
|
|
188
290
|
this.artifacts = [];
|
|
291
|
+
this.completion = undefined;
|
|
189
292
|
this.error = undefined;
|
|
190
293
|
this.updatedAt = Date.now();
|
|
191
294
|
this.currentRunId = this.runStore?.create({
|
|
@@ -204,6 +307,23 @@ export class ManagedSession {
|
|
|
204
307
|
this.setState('failed', errorMessage(error));
|
|
205
308
|
});
|
|
206
309
|
}
|
|
310
|
+
async resolvePending(response, attachmentIds = []) {
|
|
311
|
+
if (!this.runtime) {
|
|
312
|
+
throw new SessionRequestError(409, 'Agent runtime is unavailable');
|
|
313
|
+
}
|
|
314
|
+
const pending = this.pendingRequest;
|
|
315
|
+
if (!pending) {
|
|
316
|
+
throw new SessionRequestError(409, 'Session is not waiting for input');
|
|
317
|
+
}
|
|
318
|
+
if (pending.id !== response.requestId) {
|
|
319
|
+
throw new SessionRequestError(409, `Pending request no longer matches: ${response.requestId}`);
|
|
320
|
+
}
|
|
321
|
+
const attachments = this.inputAttachmentsFor(attachmentIds);
|
|
322
|
+
this.syncRun({
|
|
323
|
+
progress: { phase: '继续执行', message: '已提交补充信息' }
|
|
324
|
+
});
|
|
325
|
+
await this.runtime.respondPending(response, attachments);
|
|
326
|
+
}
|
|
207
327
|
async cancel() {
|
|
208
328
|
await this.runtime?.cancel();
|
|
209
329
|
}
|
|
@@ -214,6 +334,7 @@ export class ManagedSession {
|
|
|
214
334
|
snapshot() {
|
|
215
335
|
return {
|
|
216
336
|
id: this.id,
|
|
337
|
+
instanceId: this.instanceId,
|
|
217
338
|
runId: this.currentRunId,
|
|
218
339
|
protocol: this.protocol,
|
|
219
340
|
protocolSessionId: this.protocolSessionId,
|
|
@@ -228,6 +349,9 @@ export class ManagedSession {
|
|
|
228
349
|
pendingRequest: this.pendingRequest
|
|
229
350
|
? structuredClone(this.pendingRequest)
|
|
230
351
|
: undefined,
|
|
352
|
+
completion: this.completion
|
|
353
|
+
? structuredClone(this.completion)
|
|
354
|
+
: undefined,
|
|
231
355
|
lastEventId: this.events.lastId,
|
|
232
356
|
createdAt: this.createdAt,
|
|
233
357
|
updatedAt: this.updatedAt
|
|
@@ -247,6 +371,9 @@ export class ManagedSession {
|
|
|
247
371
|
output: this.output || undefined,
|
|
248
372
|
artifacts: this.artifacts.map(runArtifact),
|
|
249
373
|
artifactCount: this.artifacts.length,
|
|
374
|
+
completion: this.completion
|
|
375
|
+
? structuredClone(this.completion)
|
|
376
|
+
: undefined,
|
|
250
377
|
updatedAt: this.updatedAt,
|
|
251
378
|
...patch
|
|
252
379
|
});
|
|
@@ -265,6 +392,7 @@ export class SessionManager {
|
|
|
265
392
|
workspacePolicy;
|
|
266
393
|
drivers;
|
|
267
394
|
runStore;
|
|
395
|
+
instanceId = randomUUID();
|
|
268
396
|
sessions = new Map();
|
|
269
397
|
cleanupTimer;
|
|
270
398
|
readinessCache;
|
|
@@ -379,10 +507,10 @@ export class SessionManager {
|
|
|
379
507
|
}
|
|
380
508
|
workspace = await this.workspacePolicy.resolve(requestedWorkspace);
|
|
381
509
|
}
|
|
382
|
-
const session = new ManagedSession(agentId, config.protocol === 'a2a' ? 'a2a' : 'acp', workspace, ownerKeyId, this.config.maxEventsPerSession, this.config.maxOutputChars, config.name || agentId, this.runStore);
|
|
510
|
+
const session = new ManagedSession(agentId, config.protocol === 'a2a' ? 'a2a' : 'acp', workspace, ownerKeyId, this.config.maxEventsPerSession, this.config.maxOutputChars, config.name || agentId, this.runStore, this.instanceId);
|
|
383
511
|
const runtime = config.protocol === 'a2a'
|
|
384
512
|
? new A2AClientRuntime(config, session, this.config.promptTimeoutMs || 30 * 60_000)
|
|
385
|
-
: new AcpProcessRuntime(driver, session, this.config.maxOutputChars, this.config.promptTimeoutMs || 30 * 60_000
|
|
513
|
+
: new AcpProcessRuntime(driver, session, this.config.maxOutputChars, this.config.promptTimeoutMs || 30 * 60_000);
|
|
386
514
|
this.sessions.set(session.id, session);
|
|
387
515
|
session.attach(runtime);
|
|
388
516
|
try {
|
|
@@ -422,15 +550,34 @@ export class SessionManager {
|
|
|
422
550
|
await session.message(text, attachmentIds);
|
|
423
551
|
return session.snapshot();
|
|
424
552
|
}
|
|
553
|
+
async resolvePending(id, response, attachmentIds = []) {
|
|
554
|
+
const session = this.require(id);
|
|
555
|
+
await session.resolvePending(response, attachmentIds);
|
|
556
|
+
return session.snapshot();
|
|
557
|
+
}
|
|
425
558
|
addInputAttachment(id, name, mediaType, bytes) {
|
|
426
559
|
const session = this.require(id);
|
|
427
560
|
return session.addInputAttachment(name, mediaType, bytes);
|
|
428
561
|
}
|
|
562
|
+
async publishFile(id, path) {
|
|
563
|
+
const session = this.require(id);
|
|
564
|
+
await session.publishFile(path);
|
|
565
|
+
return session.snapshot();
|
|
566
|
+
}
|
|
429
567
|
async cancel(id) {
|
|
430
568
|
const session = this.require(id);
|
|
431
569
|
await session.cancel();
|
|
432
570
|
return session.snapshot();
|
|
433
571
|
}
|
|
572
|
+
async close(id) {
|
|
573
|
+
const session = this.require(id);
|
|
574
|
+
if (isActive(session.state))
|
|
575
|
+
await session.cancel();
|
|
576
|
+
const snapshot = session.snapshot();
|
|
577
|
+
await session.dispose();
|
|
578
|
+
this.sessions.delete(id);
|
|
579
|
+
return snapshot;
|
|
580
|
+
}
|
|
434
581
|
eventsAfter(id, after) {
|
|
435
582
|
return this.require(id).events.after(after);
|
|
436
583
|
}
|
|
@@ -542,6 +689,41 @@ function runArtifact(artifact) {
|
|
|
542
689
|
metadata: artifact.metadata ? structuredClone(artifact.metadata) : undefined
|
|
543
690
|
};
|
|
544
691
|
}
|
|
692
|
+
function assertWorkspacePath(workspaceRoot, target) {
|
|
693
|
+
const child = relative(workspaceRoot, target);
|
|
694
|
+
if (child === '..' || child.startsWith(`..${sep}`) || isAbsolute(child)) {
|
|
695
|
+
throw new SessionRequestError(403, 'Published files must stay inside the session workspace');
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
function mediaTypeForPath(path) {
|
|
699
|
+
switch (extname(path).toLowerCase()) {
|
|
700
|
+
case '.txt':
|
|
701
|
+
case '.log':
|
|
702
|
+
case '.md':
|
|
703
|
+
return 'text/plain';
|
|
704
|
+
case '.json':
|
|
705
|
+
return 'application/json';
|
|
706
|
+
case '.pdf':
|
|
707
|
+
return 'application/pdf';
|
|
708
|
+
case '.png':
|
|
709
|
+
return 'image/png';
|
|
710
|
+
case '.jpg':
|
|
711
|
+
case '.jpeg':
|
|
712
|
+
return 'image/jpeg';
|
|
713
|
+
case '.gif':
|
|
714
|
+
return 'image/gif';
|
|
715
|
+
case '.webp':
|
|
716
|
+
return 'image/webp';
|
|
717
|
+
case '.svg':
|
|
718
|
+
return 'image/svg+xml';
|
|
719
|
+
case '.csv':
|
|
720
|
+
return 'text/csv';
|
|
721
|
+
case '.zip':
|
|
722
|
+
return 'application/zip';
|
|
723
|
+
default:
|
|
724
|
+
return 'application/octet-stream';
|
|
725
|
+
}
|
|
726
|
+
}
|
|
545
727
|
function firstString(...values) {
|
|
546
728
|
for (const value of values) {
|
|
547
729
|
if (typeof value === 'string' && value.trim())
|
|
@@ -594,6 +776,9 @@ function isTerminal(state) {
|
|
|
594
776
|
function isActive(state) {
|
|
595
777
|
return state === 'running' || state === 'input_required' || state === 'permission_required';
|
|
596
778
|
}
|
|
779
|
+
function isInteractive(state) {
|
|
780
|
+
return state === 'input_required' || state === 'permission_required';
|
|
781
|
+
}
|
|
597
782
|
function errorMessage(error) {
|
|
598
783
|
return error instanceof Error ? error.message : String(error);
|
|
599
784
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
export type AgentdSessionState = 'created' | 'running' | 'input_required' | 'permission_required' | 'completed' | 'failed' | 'canceled';
|
|
2
2
|
export type AgentdProtocol = 'acp' | 'a2a';
|
|
3
|
-
export type PermissionPolicy = 'ask' | '
|
|
3
|
+
export type PermissionPolicy = 'ask' | 'deny';
|
|
4
|
+
export type AgentdTurnCompletionSource = 'acp_prompt_response' | 'a2a_task_status' | 'a2a_message_stream';
|
|
5
|
+
export interface AgentdTurnCompletionProof {
|
|
6
|
+
source: AgentdTurnCompletionSource;
|
|
7
|
+
stopReason: string;
|
|
8
|
+
}
|
|
9
|
+
export interface AgentdTurnCompletion extends AgentdTurnCompletionProof {
|
|
10
|
+
runId?: string;
|
|
11
|
+
protocol: AgentdProtocol;
|
|
12
|
+
verified: true;
|
|
13
|
+
outputPresent: boolean;
|
|
14
|
+
artifactCount: number;
|
|
15
|
+
completedAt: number;
|
|
16
|
+
}
|
|
4
17
|
export declare const agentdDriverKinds: readonly ["opencode", "claude", "codex", "pi", "openclaw", "hermes"];
|
|
5
18
|
export type AgentdDriverKind = (typeof agentdDriverKinds)[number];
|
|
6
19
|
export interface AgentdDriverConfig {
|
|
@@ -14,8 +27,6 @@ export interface AgentdDriverConfig {
|
|
|
14
27
|
args?: string[];
|
|
15
28
|
inheritEnv?: string[];
|
|
16
29
|
env?: Record<string, string>;
|
|
17
|
-
/** Optional extra instructions appended to the built-in Agent Nexus guidance. */
|
|
18
|
-
instructions?: string;
|
|
19
30
|
permissionPolicy?: PermissionPolicy;
|
|
20
31
|
permissionTimeoutMs?: number;
|
|
21
32
|
}
|
|
@@ -25,8 +36,6 @@ export interface AgentdA2AConfig {
|
|
|
25
36
|
protocol: 'a2a';
|
|
26
37
|
name?: string;
|
|
27
38
|
description?: string;
|
|
28
|
-
/** Optional extra instructions sent with the first A2A user message. */
|
|
29
|
-
instructions?: string;
|
|
30
39
|
enabled?: boolean;
|
|
31
40
|
/** Full Agent Card JSON URL. Preferred for new configurations. */
|
|
32
41
|
agentCardUrl?: string;
|
|
@@ -67,18 +76,6 @@ export interface AgentdConfig {
|
|
|
67
76
|
workspaceRoots: string[];
|
|
68
77
|
maxRequestBytes: number;
|
|
69
78
|
maxAttachmentBytes?: number;
|
|
70
|
-
/** Gateway-owned directory for temporary, anonymously downloadable artifacts. */
|
|
71
|
-
artifactStoragePath?: string;
|
|
72
|
-
/** Maximum size of one published artifact. */
|
|
73
|
-
maxArtifactBytes?: number;
|
|
74
|
-
/** Maximum combined size of all retained published artifacts. */
|
|
75
|
-
maxArtifactStorageBytes?: number;
|
|
76
|
-
/** Maximum number of retained published artifacts. */
|
|
77
|
-
maxPublishedArtifacts?: number;
|
|
78
|
-
/** Maximum number of simultaneous artifact copies. */
|
|
79
|
-
maxConcurrentArtifactPublishes?: number;
|
|
80
|
-
/** Lifetime of a published artifact URL. */
|
|
81
|
-
artifactTtlMs?: number;
|
|
82
79
|
maxEventsPerSession: number;
|
|
83
80
|
maxOutputChars: number;
|
|
84
81
|
sessionTtlMs: number;
|
|
@@ -92,27 +89,6 @@ export interface AgentdConfig {
|
|
|
92
89
|
secureAdminCookies?: boolean;
|
|
93
90
|
agents: Record<string, AgentdAgentConfig>;
|
|
94
91
|
}
|
|
95
|
-
export interface AgentdFileRootView {
|
|
96
|
-
id: string;
|
|
97
|
-
name: string;
|
|
98
|
-
path: string;
|
|
99
|
-
}
|
|
100
|
-
export interface AgentdFileEntryView {
|
|
101
|
-
name: string;
|
|
102
|
-
path: string;
|
|
103
|
-
type: 'file' | 'directory' | 'symlink' | 'other';
|
|
104
|
-
size?: number;
|
|
105
|
-
modifiedAt: number;
|
|
106
|
-
}
|
|
107
|
-
export interface AgentdPublishedFile {
|
|
108
|
-
id: string;
|
|
109
|
-
name: string;
|
|
110
|
-
url: string;
|
|
111
|
-
size: number;
|
|
112
|
-
mediaType: string;
|
|
113
|
-
sha256: string;
|
|
114
|
-
expiresAt: number;
|
|
115
|
-
}
|
|
116
92
|
export interface AgentdAgentView {
|
|
117
93
|
id: string;
|
|
118
94
|
name: string;
|
|
@@ -132,7 +108,6 @@ export interface AgentdAgentConfigView {
|
|
|
132
108
|
protocol: AgentdProtocol;
|
|
133
109
|
name: string;
|
|
134
110
|
description?: string;
|
|
135
|
-
instructions?: string;
|
|
136
111
|
enabled: boolean;
|
|
137
112
|
driver?: AgentdDriverKind;
|
|
138
113
|
workspace?: string;
|
|
@@ -186,17 +161,17 @@ export interface AgentdPendingRequest {
|
|
|
186
161
|
id: string;
|
|
187
162
|
kind: 'permission' | 'input';
|
|
188
163
|
prompt: string;
|
|
189
|
-
/** Optional business-facing step, for example `payment` or `pickup_time`. */
|
|
190
|
-
step?: string;
|
|
191
|
-
/** Optional hint for clients rendering the pending interaction. */
|
|
192
|
-
inputType?: 'text' | 'choice' | 'confirmation' | 'payment' | 'unknown';
|
|
193
164
|
options?: Array<{
|
|
194
165
|
id: string;
|
|
195
166
|
name: string;
|
|
196
167
|
kind?: string;
|
|
197
168
|
}>;
|
|
198
|
-
|
|
199
|
-
|
|
169
|
+
}
|
|
170
|
+
export interface AgentdPendingResponse {
|
|
171
|
+
requestId: string;
|
|
172
|
+
message?: string;
|
|
173
|
+
optionId?: string;
|
|
174
|
+
action?: 'accept' | 'decline' | 'cancel';
|
|
200
175
|
}
|
|
201
176
|
export interface AgentdArtifact {
|
|
202
177
|
id?: string;
|
|
@@ -212,6 +187,8 @@ export interface AgentdArtifact {
|
|
|
212
187
|
}
|
|
213
188
|
export interface AgentdSessionView {
|
|
214
189
|
id: string;
|
|
190
|
+
/** Identifies the Gateway process that owns this in-memory session. */
|
|
191
|
+
instanceId?: string;
|
|
215
192
|
runId?: string;
|
|
216
193
|
protocol: AgentdProtocol;
|
|
217
194
|
protocolSessionId?: string;
|
|
@@ -225,6 +202,8 @@ export interface AgentdSessionView {
|
|
|
225
202
|
artifacts: AgentdArtifact[];
|
|
226
203
|
inputAttachments?: AgentdInputAttachmentView[];
|
|
227
204
|
pendingRequest?: AgentdPendingRequest;
|
|
205
|
+
/** Structural proof that the current protocol turn reached a valid terminal boundary. */
|
|
206
|
+
completion?: AgentdTurnCompletion;
|
|
228
207
|
lastEventId?: string;
|
|
229
208
|
createdAt: number;
|
|
230
209
|
updatedAt: number;
|
|
@@ -259,6 +238,7 @@ export interface AgentdRunView {
|
|
|
259
238
|
error?: string;
|
|
260
239
|
artifactCount: number;
|
|
261
240
|
inputAttachmentCount?: number;
|
|
241
|
+
completion?: AgentdTurnCompletion;
|
|
262
242
|
startedAt: number;
|
|
263
243
|
updatedAt: number;
|
|
264
244
|
endedAt?: number;
|