@agentuity/runtime 0.0.100 → 0.0.102
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/AGENTS.md +34 -212
- package/dist/_metadata.d.ts +107 -0
- package/dist/_metadata.d.ts.map +1 -0
- package/dist/_metadata.js +179 -0
- package/dist/_metadata.js.map +1 -0
- package/dist/_process-protection.d.ts.map +1 -1
- package/dist/_process-protection.js +4 -0
- package/dist/_process-protection.js.map +1 -1
- package/dist/_services.d.ts.map +1 -1
- package/dist/_services.js +18 -17
- package/dist/_services.js.map +1 -1
- package/dist/_standalone.d.ts.map +1 -1
- package/dist/_standalone.js +17 -0
- package/dist/_standalone.js.map +1 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +53 -12
- package/dist/agent.js.map +1 -1
- package/dist/app.d.ts +61 -10
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js.map +1 -1
- package/dist/devmode.d.ts.map +1 -1
- package/dist/devmode.js +13 -5
- package/dist/devmode.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/middleware.d.ts +61 -5
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +192 -25
- package/dist/middleware.js.map +1 -1
- package/dist/services/evalrun/http.d.ts.map +1 -1
- package/dist/services/evalrun/http.js +14 -4
- package/dist/services/evalrun/http.js.map +1 -1
- package/dist/services/local/vector.d.ts +5 -1
- package/dist/services/local/vector.d.ts.map +1 -1
- package/dist/services/local/vector.js +112 -0
- package/dist/services/local/vector.js.map +1 -1
- package/dist/services/session/http.d.ts.map +1 -1
- package/dist/services/session/http.js +7 -0
- package/dist/services/session/http.js.map +1 -1
- package/dist/services/session/local.d.ts +2 -2
- package/dist/services/session/local.d.ts.map +1 -1
- package/dist/services/session/local.js +5 -4
- package/dist/services/session/local.js.map +1 -1
- package/dist/session.d.ts +30 -4
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +90 -13
- package/dist/session.js.map +1 -1
- package/dist/workbench.d.ts.map +1 -1
- package/dist/workbench.js +13 -20
- package/dist/workbench.js.map +1 -1
- package/package.json +5 -5
- package/src/_metadata.ts +307 -0
- package/src/_process-protection.ts +6 -0
- package/src/_services.ts +23 -21
- package/src/_standalone.ts +22 -0
- package/src/agent.ts +63 -12
- package/src/app.ts +65 -9
- package/src/devmode.ts +16 -5
- package/src/index.ts +12 -2
- package/src/middleware.ts +221 -29
- package/src/services/evalrun/http.ts +15 -4
- package/src/services/local/vector.ts +160 -0
- package/src/services/session/http.ts +11 -0
- package/src/services/session/local.ts +9 -4
- package/src/session.ts +142 -13
- package/src/workbench.ts +13 -26
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
type Logger,
|
|
9
9
|
StructuredError,
|
|
10
10
|
} from '@agentuity/core';
|
|
11
|
+
import { internal } from '../../logger/internal';
|
|
11
12
|
|
|
12
13
|
const SessionResponseError = StructuredError('SessionResponseError');
|
|
13
14
|
|
|
@@ -29,6 +30,7 @@ export class HTTPSessionEventProvider implements SessionEventProvider {
|
|
|
29
30
|
* @param event SessionStartEvent
|
|
30
31
|
*/
|
|
31
32
|
async start(event: SessionStartEvent): Promise<void> {
|
|
33
|
+
internal.info('[session-http] sending start event: %s', event.id);
|
|
32
34
|
this.logger.debug('Sending session start event: %s', event.id);
|
|
33
35
|
const resp = await this.apiClient.post(
|
|
34
36
|
'/session/2025-03-17',
|
|
@@ -37,9 +39,11 @@ export class HTTPSessionEventProvider implements SessionEventProvider {
|
|
|
37
39
|
SessionStartEventDelayedSchema
|
|
38
40
|
);
|
|
39
41
|
if (resp.success) {
|
|
42
|
+
internal.info('[session-http] start event sent successfully: %s', event.id);
|
|
40
43
|
this.logger.debug('Session start event sent successfully: %s', event.id);
|
|
41
44
|
return;
|
|
42
45
|
}
|
|
46
|
+
internal.info('[session-http] start event failed: %s - %s', event.id, resp.message);
|
|
43
47
|
throw new SessionResponseError({ message: resp.message });
|
|
44
48
|
}
|
|
45
49
|
|
|
@@ -49,6 +53,11 @@ export class HTTPSessionEventProvider implements SessionEventProvider {
|
|
|
49
53
|
* @param event SessionCompleteEvent
|
|
50
54
|
*/
|
|
51
55
|
async complete(event: SessionCompleteEvent): Promise<void> {
|
|
56
|
+
internal.info(
|
|
57
|
+
'[session-http] sending complete event: %s, userData: %s',
|
|
58
|
+
event.id,
|
|
59
|
+
event.userData ? `${event.userData.length} bytes` : 'none'
|
|
60
|
+
);
|
|
52
61
|
this.logger.debug('Sending session complete event: %s', event.id);
|
|
53
62
|
const resp = await this.apiClient.put(
|
|
54
63
|
'/session/2025-03-17',
|
|
@@ -57,9 +66,11 @@ export class HTTPSessionEventProvider implements SessionEventProvider {
|
|
|
57
66
|
SessionCompleteEventDelayedSchema
|
|
58
67
|
);
|
|
59
68
|
if (resp.success) {
|
|
69
|
+
internal.info('[session-http] complete event sent successfully: %s', event.id);
|
|
60
70
|
this.logger.debug('Session complete event sent successfully: %s', event.id);
|
|
61
71
|
return;
|
|
62
72
|
}
|
|
73
|
+
internal.info('[session-http] complete event failed: %s - %s', event.id, resp.message);
|
|
63
74
|
throw new SessionResponseError({ message: resp.message });
|
|
64
75
|
}
|
|
65
76
|
}
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
type SessionStartEvent,
|
|
4
4
|
type SessionCompleteEvent,
|
|
5
5
|
} from '@agentuity/core';
|
|
6
|
+
import { internal } from '../../logger/internal';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* An implementation of the SessionEventProvider which is no-op
|
|
@@ -13,8 +14,8 @@ export class LocalSessionEventProvider implements SessionEventProvider {
|
|
|
13
14
|
*
|
|
14
15
|
* @param event SessionStartEvent
|
|
15
16
|
*/
|
|
16
|
-
async start(
|
|
17
|
-
|
|
17
|
+
async start(event: SessionStartEvent): Promise<void> {
|
|
18
|
+
internal.info('[session-local] start event (no-op): %s', event.id);
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
/**
|
|
@@ -22,7 +23,11 @@ export class LocalSessionEventProvider implements SessionEventProvider {
|
|
|
22
23
|
*
|
|
23
24
|
* @param event SessionCompleteEvent
|
|
24
25
|
*/
|
|
25
|
-
async complete(
|
|
26
|
-
|
|
26
|
+
async complete(event: SessionCompleteEvent): Promise<void> {
|
|
27
|
+
internal.info(
|
|
28
|
+
'[session-local] complete event (no-op): %s, userData: %s',
|
|
29
|
+
event.id,
|
|
30
|
+
event.userData ? `${event.userData.length} bytes` : 'none'
|
|
31
|
+
);
|
|
27
32
|
}
|
|
28
33
|
}
|
package/src/session.ts
CHANGED
|
@@ -72,6 +72,19 @@ export interface Thread {
|
|
|
72
72
|
*/
|
|
73
73
|
state: Map<string, unknown>;
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Unencrypted metadata for filtering and querying threads.
|
|
77
|
+
* Unlike state, metadata is stored as-is in the database with GIN indexes
|
|
78
|
+
* for efficient filtering. Initialized to empty object, only persisted if non-empty.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* ctx.thread.metadata.userId = 'user123';
|
|
83
|
+
* ctx.thread.metadata.department = 'sales';
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
metadata: Record<string, unknown>;
|
|
87
|
+
|
|
75
88
|
/**
|
|
76
89
|
* Register an event listener for when the thread is destroyed.
|
|
77
90
|
* Thread is destroyed when it expires or is manually destroyed.
|
|
@@ -182,6 +195,19 @@ export interface Session {
|
|
|
182
195
|
*/
|
|
183
196
|
state: Map<string, unknown>;
|
|
184
197
|
|
|
198
|
+
/**
|
|
199
|
+
* Unencrypted metadata for filtering and querying sessions.
|
|
200
|
+
* Unlike state, metadata is stored as-is in the database with GIN indexes
|
|
201
|
+
* for efficient filtering. Initialized to empty object, only persisted if non-empty.
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* ```typescript
|
|
205
|
+
* ctx.session.metadata.userId = 'user123';
|
|
206
|
+
* ctx.session.metadata.requestType = 'chat';
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
209
|
+
metadata: Record<string, unknown>;
|
|
210
|
+
|
|
185
211
|
/**
|
|
186
212
|
* Register an event listener for when the session completes.
|
|
187
213
|
* Fired after the agent handler returns and response is sent.
|
|
@@ -653,13 +679,20 @@ export class DefaultThread implements Thread {
|
|
|
653
679
|
#initialStateJson: string | undefined;
|
|
654
680
|
readonly id: string;
|
|
655
681
|
readonly state: Map<string, unknown>;
|
|
682
|
+
metadata: Record<string, unknown>;
|
|
656
683
|
private provider: ThreadProvider;
|
|
657
684
|
|
|
658
|
-
constructor(
|
|
685
|
+
constructor(
|
|
686
|
+
provider: ThreadProvider,
|
|
687
|
+
id: string,
|
|
688
|
+
initialStateJson?: string,
|
|
689
|
+
metadata?: Record<string, unknown>
|
|
690
|
+
) {
|
|
659
691
|
this.provider = provider;
|
|
660
692
|
this.id = id;
|
|
661
693
|
this.state = new Map();
|
|
662
694
|
this.#initialStateJson = initialStateJson;
|
|
695
|
+
this.metadata = metadata || {};
|
|
663
696
|
}
|
|
664
697
|
|
|
665
698
|
addEventListener(eventName: ThreadEventName, callback: ThreadEventCallback<any>): void {
|
|
@@ -707,10 +740,10 @@ export class DefaultThread implements Thread {
|
|
|
707
740
|
}
|
|
708
741
|
|
|
709
742
|
/**
|
|
710
|
-
* Check if thread has any data
|
|
743
|
+
* Check if thread has any data (state or metadata)
|
|
711
744
|
*/
|
|
712
745
|
empty(): boolean {
|
|
713
|
-
return this.state.size === 0;
|
|
746
|
+
return this.state.size === 0 && Object.keys(this.metadata).length === 0;
|
|
714
747
|
}
|
|
715
748
|
|
|
716
749
|
/**
|
|
@@ -718,7 +751,24 @@ export class DefaultThread implements Thread {
|
|
|
718
751
|
* @internal
|
|
719
752
|
*/
|
|
720
753
|
getSerializedState(): string {
|
|
721
|
-
|
|
754
|
+
const hasState = this.state.size > 0;
|
|
755
|
+
const hasMetadata = Object.keys(this.metadata).length > 0;
|
|
756
|
+
|
|
757
|
+
if (!hasState && !hasMetadata) {
|
|
758
|
+
return '';
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
const data: { state?: Record<string, unknown>; metadata?: Record<string, unknown> } = {};
|
|
762
|
+
|
|
763
|
+
if (hasState) {
|
|
764
|
+
data.state = Object.fromEntries(this.state);
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
if (hasMetadata) {
|
|
768
|
+
data.metadata = this.metadata;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
return JSON.stringify(data);
|
|
722
772
|
}
|
|
723
773
|
}
|
|
724
774
|
|
|
@@ -726,11 +776,13 @@ export class DefaultSession implements Session {
|
|
|
726
776
|
readonly id: string;
|
|
727
777
|
readonly thread: Thread;
|
|
728
778
|
readonly state: Map<string, unknown>;
|
|
779
|
+
metadata: Record<string, unknown>;
|
|
729
780
|
|
|
730
|
-
constructor(thread: Thread, id: string) {
|
|
781
|
+
constructor(thread: Thread, id: string, metadata?: Record<string, unknown>) {
|
|
731
782
|
this.id = id;
|
|
732
783
|
this.thread = thread;
|
|
733
784
|
this.state = new Map();
|
|
785
|
+
this.metadata = metadata || {};
|
|
734
786
|
}
|
|
735
787
|
|
|
736
788
|
addEventListener(eventName: SessionEventName, callback: SessionEventCallback<any>): void {
|
|
@@ -1032,7 +1084,11 @@ export class ThreadWebSocketClient {
|
|
|
1032
1084
|
});
|
|
1033
1085
|
}
|
|
1034
1086
|
|
|
1035
|
-
async save(
|
|
1087
|
+
async save(
|
|
1088
|
+
threadId: string,
|
|
1089
|
+
userData: string,
|
|
1090
|
+
threadMetadata?: Record<string, unknown>
|
|
1091
|
+
): Promise<void> {
|
|
1036
1092
|
// Wait for connection/reconnection if in progress
|
|
1037
1093
|
if (this.wsConnecting) {
|
|
1038
1094
|
await this.wsConnecting;
|
|
@@ -1058,10 +1114,20 @@ export class ThreadWebSocketClient {
|
|
|
1058
1114
|
reject,
|
|
1059
1115
|
});
|
|
1060
1116
|
|
|
1117
|
+
const data: { thread_id: string; user_data: string; metadata?: Record<string, unknown> } =
|
|
1118
|
+
{
|
|
1119
|
+
thread_id: threadId,
|
|
1120
|
+
user_data: userData,
|
|
1121
|
+
};
|
|
1122
|
+
|
|
1123
|
+
if (threadMetadata && Object.keys(threadMetadata).length > 0) {
|
|
1124
|
+
data.metadata = threadMetadata;
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1061
1127
|
const message = {
|
|
1062
1128
|
id: requestId,
|
|
1063
1129
|
action: 'save',
|
|
1064
|
-
data
|
|
1130
|
+
data,
|
|
1065
1131
|
};
|
|
1066
1132
|
|
|
1067
1133
|
this.ws!.send(JSON.stringify(message));
|
|
@@ -1174,26 +1240,59 @@ export class DefaultThreadProvider implements ThreadProvider {
|
|
|
1174
1240
|
async restore(ctx: Context<Env>): Promise<Thread> {
|
|
1175
1241
|
const threadId = await this.threadIDProvider!.getThreadId(this.appState!, ctx);
|
|
1176
1242
|
validateThreadIdOrThrow(threadId);
|
|
1243
|
+
internal.info('[thread] restoring thread %s', threadId);
|
|
1177
1244
|
|
|
1178
1245
|
// Wait for WebSocket connection if still connecting
|
|
1179
1246
|
if (this.wsConnecting) {
|
|
1247
|
+
internal.info('[thread] waiting for WebSocket connection');
|
|
1180
1248
|
await this.wsConnecting;
|
|
1181
1249
|
}
|
|
1182
1250
|
|
|
1183
|
-
// Restore thread state from WebSocket if available
|
|
1251
|
+
// Restore thread state and metadata from WebSocket if available
|
|
1184
1252
|
let initialStateJson: string | undefined;
|
|
1253
|
+
let restoredMetadata: Record<string, unknown> | undefined;
|
|
1185
1254
|
if (this.wsClient) {
|
|
1186
1255
|
try {
|
|
1256
|
+
internal.info('[thread] restoring state from WebSocket');
|
|
1187
1257
|
const restoredData = await this.wsClient.restore(threadId);
|
|
1188
1258
|
if (restoredData) {
|
|
1189
1259
|
initialStateJson = restoredData;
|
|
1260
|
+
internal.info('[thread] restored state: %d bytes', restoredData.length);
|
|
1261
|
+
// Parse to check if it includes metadata
|
|
1262
|
+
try {
|
|
1263
|
+
const parsed = JSON.parse(restoredData);
|
|
1264
|
+
// New format: { state?: {...}, metadata?: {...} }
|
|
1265
|
+
if (
|
|
1266
|
+
parsed &&
|
|
1267
|
+
typeof parsed === 'object' &&
|
|
1268
|
+
('state' in parsed || 'metadata' in parsed)
|
|
1269
|
+
) {
|
|
1270
|
+
if (parsed.metadata) {
|
|
1271
|
+
restoredMetadata = parsed.metadata;
|
|
1272
|
+
}
|
|
1273
|
+
// Update initialStateJson to be just the state part for backwards compatibility
|
|
1274
|
+
if (parsed.state) {
|
|
1275
|
+
initialStateJson = JSON.stringify(parsed.state);
|
|
1276
|
+
} else {
|
|
1277
|
+
initialStateJson = undefined;
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
// else: Old format (just state object), keep as-is
|
|
1281
|
+
} catch {
|
|
1282
|
+
// Keep original if parse fails
|
|
1283
|
+
}
|
|
1284
|
+
} else {
|
|
1285
|
+
internal.info('[thread] no existing state found');
|
|
1190
1286
|
}
|
|
1191
|
-
} catch {
|
|
1287
|
+
} catch (err) {
|
|
1288
|
+
internal.info('[thread] WebSocket restore failed: %s', err);
|
|
1192
1289
|
// Continue with empty state rather than failing
|
|
1193
1290
|
}
|
|
1291
|
+
} else {
|
|
1292
|
+
internal.info('[thread] no WebSocket client available');
|
|
1194
1293
|
}
|
|
1195
1294
|
|
|
1196
|
-
const thread = new DefaultThread(this, threadId, initialStateJson);
|
|
1295
|
+
const thread = new DefaultThread(this, threadId, initialStateJson, restoredMetadata);
|
|
1197
1296
|
|
|
1198
1297
|
// Populate thread state from restored data
|
|
1199
1298
|
if (initialStateJson) {
|
|
@@ -1202,7 +1301,9 @@ export class DefaultThreadProvider implements ThreadProvider {
|
|
|
1202
1301
|
for (const [key, value] of Object.entries(data)) {
|
|
1203
1302
|
thread.state.set(key, value);
|
|
1204
1303
|
}
|
|
1205
|
-
|
|
1304
|
+
internal.info('[thread] populated state with %d keys', thread.state.size);
|
|
1305
|
+
} catch (err) {
|
|
1306
|
+
internal.info('[thread] failed to parse state JSON: %s', err);
|
|
1206
1307
|
// Continue with empty state if parsing fails
|
|
1207
1308
|
}
|
|
1208
1309
|
}
|
|
@@ -1213,8 +1314,16 @@ export class DefaultThreadProvider implements ThreadProvider {
|
|
|
1213
1314
|
|
|
1214
1315
|
async save(thread: Thread): Promise<void> {
|
|
1215
1316
|
if (thread instanceof DefaultThread) {
|
|
1317
|
+
internal.info(
|
|
1318
|
+
'[thread] DefaultThreadProvider.save() - thread %s, isDirty: %s, hasWsClient: %s',
|
|
1319
|
+
thread.id,
|
|
1320
|
+
thread.isDirty(),
|
|
1321
|
+
!!this.wsClient
|
|
1322
|
+
);
|
|
1323
|
+
|
|
1216
1324
|
// Wait for WebSocket connection if still connecting
|
|
1217
1325
|
if (this.wsConnecting) {
|
|
1326
|
+
internal.info('[thread] waiting for WebSocket connection');
|
|
1218
1327
|
await this.wsConnecting;
|
|
1219
1328
|
}
|
|
1220
1329
|
|
|
@@ -1222,10 +1331,20 @@ export class DefaultThreadProvider implements ThreadProvider {
|
|
|
1222
1331
|
if (this.wsClient && thread.isDirty()) {
|
|
1223
1332
|
try {
|
|
1224
1333
|
const serialized = thread.getSerializedState();
|
|
1225
|
-
|
|
1226
|
-
|
|
1334
|
+
internal.info(
|
|
1335
|
+
'[thread] saving to WebSocket, serialized length: %d',
|
|
1336
|
+
serialized.length
|
|
1337
|
+
);
|
|
1338
|
+
const metadata =
|
|
1339
|
+
Object.keys(thread.metadata).length > 0 ? thread.metadata : undefined;
|
|
1340
|
+
await this.wsClient.save(thread.id, serialized, metadata);
|
|
1341
|
+
internal.info('[thread] WebSocket save completed');
|
|
1342
|
+
} catch (err) {
|
|
1343
|
+
internal.info('[thread] WebSocket save failed: %s', err);
|
|
1227
1344
|
// Don't throw - allow request to complete even if save fails
|
|
1228
1345
|
}
|
|
1346
|
+
} else {
|
|
1347
|
+
internal.info('[thread] skipping save - no wsClient or thread not dirty');
|
|
1229
1348
|
}
|
|
1230
1349
|
}
|
|
1231
1350
|
}
|
|
@@ -1269,20 +1388,30 @@ export class DefaultSessionProvider implements SessionProvider {
|
|
|
1269
1388
|
}
|
|
1270
1389
|
|
|
1271
1390
|
async restore(thread: Thread, sessionId: string): Promise<Session> {
|
|
1391
|
+
internal.info('[session] restoring session %s for thread %s', sessionId, thread.id);
|
|
1272
1392
|
let session = this.sessions.get(sessionId);
|
|
1273
1393
|
if (!session) {
|
|
1274
1394
|
session = new DefaultSession(thread, sessionId);
|
|
1275
1395
|
this.sessions.set(sessionId, session);
|
|
1396
|
+
internal.info('[session] created new session, firing session.started');
|
|
1276
1397
|
await fireEvent('session.started', session);
|
|
1398
|
+
} else {
|
|
1399
|
+
internal.info('[session] found existing session');
|
|
1277
1400
|
}
|
|
1278
1401
|
return session;
|
|
1279
1402
|
}
|
|
1280
1403
|
|
|
1281
1404
|
async save(session: Session): Promise<void> {
|
|
1282
1405
|
if (session instanceof DefaultSession) {
|
|
1406
|
+
internal.info(
|
|
1407
|
+
'[session] DefaultSessionProvider.save() - firing completed event for session %s',
|
|
1408
|
+
session.id
|
|
1409
|
+
);
|
|
1283
1410
|
try {
|
|
1284
1411
|
await session.fireEvent('completed');
|
|
1412
|
+
internal.info('[session] session.fireEvent completed, firing app event');
|
|
1285
1413
|
await fireEvent('session.completed', session);
|
|
1414
|
+
internal.info('[session] session.completed app event fired');
|
|
1286
1415
|
} finally {
|
|
1287
1416
|
this.sessions.delete(session.id);
|
|
1288
1417
|
sessionEventListeners.delete(session);
|
package/src/workbench.ts
CHANGED
|
@@ -6,8 +6,7 @@ import { createRouter } from './router';
|
|
|
6
6
|
import type { WebSocketConnection } from './router';
|
|
7
7
|
import { privateContext } from './_server';
|
|
8
8
|
import { getThreadProvider } from './_services';
|
|
9
|
-
import {
|
|
10
|
-
import { join } from 'node:path';
|
|
9
|
+
import { loadBuildMetadata, getAgentMetadataByAgentId, hasMetadata } from './_metadata';
|
|
11
10
|
|
|
12
11
|
export const createWorkbenchExecutionRoute = (): Handler => {
|
|
13
12
|
const authHeader = process.env.AGENTUITY_WORKBENCH_APIKEY
|
|
@@ -49,16 +48,11 @@ export const createWorkbenchExecutionRoute = (): Handler => {
|
|
|
49
48
|
}
|
|
50
49
|
|
|
51
50
|
// Read metadata to find agent name by agentId
|
|
52
|
-
const
|
|
53
|
-
if (!existsSync(metadataPath)) {
|
|
54
|
-
return ctx.json({ error: 'Metadata file not found' }, { status: 500 });
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const fileContent = readFileSync(metadataPath, 'utf-8');
|
|
58
|
-
const metadata = JSON.parse(fileContent);
|
|
59
|
-
const agentMeta = metadata.agents?.find((a: { agentId: string }) => a.agentId === agentId);
|
|
60
|
-
|
|
51
|
+
const agentMeta = getAgentMetadataByAgentId(agentId);
|
|
61
52
|
if (!agentMeta) {
|
|
53
|
+
if (!hasMetadata()) {
|
|
54
|
+
return ctx.json({ error: 'Metadata file not found' }, { status: 500 });
|
|
55
|
+
}
|
|
62
56
|
return ctx.text('Agent not found', { status: 404 });
|
|
63
57
|
}
|
|
64
58
|
|
|
@@ -75,6 +69,8 @@ export const createWorkbenchExecutionRoute = (): Handler => {
|
|
|
75
69
|
const _ctx = privateContext(ctx);
|
|
76
70
|
if (agentObj.metadata?.id) {
|
|
77
71
|
_ctx.var.agentIds.add(agentObj.metadata.id);
|
|
72
|
+
}
|
|
73
|
+
if (agentObj.metadata?.agentId) {
|
|
78
74
|
_ctx.var.agentIds.add(agentObj.metadata.agentId);
|
|
79
75
|
}
|
|
80
76
|
|
|
@@ -295,16 +291,11 @@ export const createWorkbenchSampleRoute = (): Handler => {
|
|
|
295
291
|
}
|
|
296
292
|
|
|
297
293
|
// Read metadata to find agent name by agentId
|
|
298
|
-
const
|
|
299
|
-
if (!existsSync(metadataPath)) {
|
|
300
|
-
return ctx.json({ error: 'Metadata file not found' }, { status: 500 });
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
const fileContent = readFileSync(metadataPath, 'utf-8');
|
|
304
|
-
const metadata = JSON.parse(fileContent);
|
|
305
|
-
const agentMeta = metadata.agents?.find((a: { agentId: string }) => a.agentId === agentId);
|
|
306
|
-
|
|
294
|
+
const agentMeta = getAgentMetadataByAgentId(agentId);
|
|
307
295
|
if (!agentMeta) {
|
|
296
|
+
if (!hasMetadata()) {
|
|
297
|
+
return ctx.json({ error: 'Metadata file not found' }, { status: 500 });
|
|
298
|
+
}
|
|
308
299
|
return ctx.text('Agent not found', { status: 404 });
|
|
309
300
|
}
|
|
310
301
|
|
|
@@ -446,9 +437,8 @@ export const createWorkbenchMetadataRoute = (): Handler => {
|
|
|
446
437
|
}
|
|
447
438
|
|
|
448
439
|
// Read metadata from agentuity.metadata.json file
|
|
449
|
-
const
|
|
450
|
-
|
|
451
|
-
if (!existsSync(metadataPath)) {
|
|
440
|
+
const metadata = loadBuildMetadata();
|
|
441
|
+
if (!metadata) {
|
|
452
442
|
return ctx.json(
|
|
453
443
|
{ error: 'Metadata file not found. Run build to generate metadata.' },
|
|
454
444
|
{ status: 500 }
|
|
@@ -456,9 +446,6 @@ export const createWorkbenchMetadataRoute = (): Handler => {
|
|
|
456
446
|
}
|
|
457
447
|
|
|
458
448
|
try {
|
|
459
|
-
const fileContent = readFileSync(metadataPath, 'utf-8');
|
|
460
|
-
const metadata = JSON.parse(fileContent);
|
|
461
|
-
|
|
462
449
|
// Get runtime agents for JSON schema generation
|
|
463
450
|
const agents = getAgents();
|
|
464
451
|
const agentsByName = new Map();
|