orchajs 0.22.0 → 0.23.1
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/dist/amarsia/analytics.js +60 -0
- package/dist/compiler/compile.js +21 -21
- package/dist/playground/source.js +12 -5
- package/dist/runtime/agent.js +10 -1
- package/dist/types.d.ts +27 -0
- package/dist-cjs/amarsia/analytics.js +46 -0
- package/dist-cjs/compiler/compile.js +19 -20
- package/dist-cjs/playground/source.js +9 -1
- package/dist-cjs/runtime/agent.js +10 -1
- package/package.json +1 -1
|
@@ -270,6 +270,7 @@ function projectRunFact(manifest, sessionId, run, projection) {
|
|
|
270
270
|
const failedActions = runEvents.filter((event) => event.type === "action.failed");
|
|
271
271
|
const evaluations = runEvents.filter((event) => event.type === "evaluation.completed" ||
|
|
272
272
|
event.type === "evaluation.failed");
|
|
273
|
+
const evaluationMetrics = evaluations.flatMap((event) => Array.isArray(event.data.metrics) ? event.data.metrics : []);
|
|
273
274
|
const error = asRecord(terminal?.data.error);
|
|
274
275
|
const lastAssistant = assistants.at(-1);
|
|
275
276
|
const status = terminal?.type === "run.completed"
|
|
@@ -324,6 +325,12 @@ function projectRunFact(manifest, sessionId, run, projection) {
|
|
|
324
325
|
evaluation_count: evaluations.length,
|
|
325
326
|
evaluation_pass_count: evaluations.filter((event) => event.type === "evaluation.completed" &&
|
|
326
327
|
event.data.status === "passed").length,
|
|
328
|
+
evaluation_failure_count: evaluations.filter((event) => event.type === "evaluation.completed" &&
|
|
329
|
+
event.data.status === "failed").length,
|
|
330
|
+
evaluation_error_count: evaluations.filter((event) => event.type === "evaluation.failed").length,
|
|
331
|
+
evaluation_metric_count: evaluationMetrics.length,
|
|
332
|
+
evaluation_metric_pass_count: evaluationMetrics.filter((metric) => asRecord(metric)?.passed === true).length,
|
|
333
|
+
evaluations: projectEvaluationLogs(evaluations),
|
|
327
334
|
...(typeof error?.code === "string" ? { error_code: error.code } : {}),
|
|
328
335
|
...(typeof error?.message === "string"
|
|
329
336
|
? { error_message: sanitizeErrorMessage(error.message) }
|
|
@@ -405,6 +412,59 @@ function projectActionLogs(events) {
|
|
|
405
412
|
};
|
|
406
413
|
});
|
|
407
414
|
}
|
|
415
|
+
function projectEvaluationLogs(events) {
|
|
416
|
+
return events.slice(0, 50).map((event) => {
|
|
417
|
+
const usage = asRecord(event.data.usage);
|
|
418
|
+
const error = asRecord(event.data.error);
|
|
419
|
+
const metrics = Array.isArray(event.data.metrics)
|
|
420
|
+
? event.data.metrics
|
|
421
|
+
.map(asRecord)
|
|
422
|
+
.filter((metric) => metric !== undefined)
|
|
423
|
+
.slice(0, 50)
|
|
424
|
+
.map((metric) => ({
|
|
425
|
+
name: typeof metric.name === "string" ? metric.name : "unknown_metric",
|
|
426
|
+
score: numberValue(metric.score),
|
|
427
|
+
threshold: numberValue(metric.threshold),
|
|
428
|
+
passed: metric.passed === true,
|
|
429
|
+
reasoning: typeof metric.reasoning === "string"
|
|
430
|
+
? sanitizeErrorMessage(metric.reasoning)
|
|
431
|
+
: "",
|
|
432
|
+
evidence: Array.isArray(metric.evidence)
|
|
433
|
+
? metric.evidence
|
|
434
|
+
.filter((item) => typeof item === "string")
|
|
435
|
+
.slice(0, 20)
|
|
436
|
+
.map(sanitizeErrorMessage)
|
|
437
|
+
: [],
|
|
438
|
+
}))
|
|
439
|
+
: [];
|
|
440
|
+
return {
|
|
441
|
+
name: typeof event.data.name === "string"
|
|
442
|
+
? event.data.name
|
|
443
|
+
: "unknown_evaluation",
|
|
444
|
+
status: event.type === "evaluation.failed"
|
|
445
|
+
? "error"
|
|
446
|
+
: event.data.status === "passed"
|
|
447
|
+
? "passed"
|
|
448
|
+
: "failed",
|
|
449
|
+
...(typeof event.data.provider === "string"
|
|
450
|
+
? { provider: event.data.provider }
|
|
451
|
+
: {}),
|
|
452
|
+
...(typeof event.data.model === "string"
|
|
453
|
+
? { model: event.data.model }
|
|
454
|
+
: {}),
|
|
455
|
+
duration_ms: numberValue(event.data.durationMs),
|
|
456
|
+
input_tokens: numberValue(usage?.inputTokens),
|
|
457
|
+
output_tokens: numberValue(usage?.outputTokens),
|
|
458
|
+
reasoning_tokens: numberValue(usage?.reasoningTokens),
|
|
459
|
+
cache_read_tokens: numberValue(usage?.cacheReadTokens),
|
|
460
|
+
cache_write_tokens: numberValue(usage?.cacheWriteTokens),
|
|
461
|
+
metrics,
|
|
462
|
+
...(typeof error?.message === "string"
|
|
463
|
+
? { error_message: sanitizeErrorMessage(error.message) }
|
|
464
|
+
: {}),
|
|
465
|
+
};
|
|
466
|
+
});
|
|
467
|
+
}
|
|
408
468
|
function takeBatch(queue) {
|
|
409
469
|
const batch = [];
|
|
410
470
|
let bytes = utf8ByteLength('{"schema_version":1,"runs":[]}');
|
package/dist/compiler/compile.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
2
|
+
import { existsSync, readFileSync, readdirSync, statSync, } from "node:fs";
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
import { buildSync } from "esbuild";
|
|
5
5
|
import { isBuiltInProvider } from "../providers/catalog.js";
|
|
@@ -163,27 +163,24 @@ function compileActions(agentName, sourceDirectory, actionRuntime, target) {
|
|
|
163
163
|
return {};
|
|
164
164
|
}
|
|
165
165
|
const actions = {};
|
|
166
|
-
for (const entry of
|
|
167
|
-
|
|
168
|
-
continue;
|
|
169
|
-
}
|
|
170
|
-
const configurationPath = resolve(actionsDirectory, entry.name, "index.json");
|
|
166
|
+
for (const entry of discoverDirectories(actionsDirectory)) {
|
|
167
|
+
const configurationPath = resolve(actionsDirectory, entry, "index.json");
|
|
171
168
|
let configuration;
|
|
172
169
|
try {
|
|
173
170
|
configuration = JSON.parse(readFileSync(configurationPath, "utf8"));
|
|
174
171
|
}
|
|
175
172
|
catch (error) {
|
|
176
|
-
throw new Error(`Action "${agentName}/${entry
|
|
173
|
+
throw new Error(`Action "${agentName}/${entry}" is missing a valid index.json.`, { cause: error });
|
|
177
174
|
}
|
|
178
|
-
validateEnabled(`Action "${agentName}/${entry
|
|
175
|
+
validateEnabled(`Action "${agentName}/${entry}"`, configuration?.enabled);
|
|
179
176
|
if (configuration?.enabled === false) {
|
|
180
177
|
continue;
|
|
181
178
|
}
|
|
182
179
|
if (!configuration.name?.trim() || !configuration.description?.trim()) {
|
|
183
|
-
throw new Error(`Action "${agentName}/${entry
|
|
180
|
+
throw new Error(`Action "${agentName}/${entry}" requires name and description.`);
|
|
184
181
|
}
|
|
185
182
|
if (!/^[a-zA-Z0-9_-]{1,64}$/.test(configuration.name)) {
|
|
186
|
-
throw new Error(`Action "${agentName}/${entry
|
|
183
|
+
throw new Error(`Action "${agentName}/${entry}" has an invalid model-facing name.`);
|
|
187
184
|
}
|
|
188
185
|
if ([
|
|
189
186
|
"load_skill",
|
|
@@ -191,50 +188,50 @@ function compileActions(agentName, sourceDirectory, actionRuntime, target) {
|
|
|
191
188
|
"resume_agent",
|
|
192
189
|
"inspect_agent",
|
|
193
190
|
].includes(configuration.name)) {
|
|
194
|
-
throw new Error(`Action "${agentName}/${entry
|
|
191
|
+
throw new Error(`Action "${agentName}/${entry}" uses reserved name "${configuration.name}".`);
|
|
195
192
|
}
|
|
196
193
|
const execution = configuration.execution ?? "local";
|
|
197
194
|
if (!["client", "local"].includes(execution)) {
|
|
198
|
-
throw new Error(`Action "${agentName}/${entry
|
|
195
|
+
throw new Error(`Action "${agentName}/${entry}" has invalid execution "${configuration.execution}".`);
|
|
199
196
|
}
|
|
200
197
|
if (!configuration.parameters ||
|
|
201
198
|
typeof configuration.parameters !== "object" ||
|
|
202
199
|
Array.isArray(configuration.parameters)) {
|
|
203
|
-
throw new Error(`Action "${agentName}/${entry
|
|
200
|
+
throw new Error(`Action "${agentName}/${entry}" requires a parameters JSON Schema.`);
|
|
204
201
|
}
|
|
205
202
|
if (configuration.outputSchema !== undefined &&
|
|
206
203
|
(typeof configuration.outputSchema !== "object" ||
|
|
207
204
|
configuration.outputSchema === null ||
|
|
208
205
|
Array.isArray(configuration.outputSchema))) {
|
|
209
|
-
throw new Error(`Action "${agentName}/${entry
|
|
206
|
+
throw new Error(`Action "${agentName}/${entry}" has an invalid outputSchema.`);
|
|
210
207
|
}
|
|
211
|
-
validateNumber(`${agentName}/${entry
|
|
208
|
+
validateNumber(`${agentName}/${entry}`, "timeoutMs", configuration.timeoutMs, { integer: true, minimum: 1, maximum: 120_000 });
|
|
212
209
|
if (configuration.permissions?.env !== undefined &&
|
|
213
210
|
!Array.isArray(configuration.permissions.env)) {
|
|
214
|
-
throw new Error(`Action "${agentName}/${entry
|
|
211
|
+
throw new Error(`Action "${agentName}/${entry}" permissions.env must be an array.`);
|
|
215
212
|
}
|
|
216
213
|
if (configuration.permissions?.network !== undefined &&
|
|
217
214
|
!Array.isArray(configuration.permissions.network)) {
|
|
218
|
-
throw new Error(`Action "${agentName}/${entry
|
|
215
|
+
throw new Error(`Action "${agentName}/${entry}" permissions.network must be an array.`);
|
|
219
216
|
}
|
|
220
217
|
for (const permission of [
|
|
221
218
|
...(configuration.permissions?.env ?? []),
|
|
222
219
|
...(configuration.permissions?.network ?? []),
|
|
223
220
|
]) {
|
|
224
221
|
if (typeof permission !== "string" || !permission.trim()) {
|
|
225
|
-
throw new Error(`Action "${agentName}/${entry
|
|
222
|
+
throw new Error(`Action "${agentName}/${entry}" has an invalid permission.`);
|
|
226
223
|
}
|
|
227
224
|
}
|
|
228
225
|
if (actions[configuration.name]) {
|
|
229
226
|
throw new Error(`Agent "${agentName}" has duplicate action name "${configuration.name}".`);
|
|
230
227
|
}
|
|
231
228
|
const compiledSource = execution === "local"
|
|
232
|
-
? compileLocalAction(agentName, entry
|
|
229
|
+
? compileLocalAction(agentName, entry, actionsDirectory, actionRuntime, target)
|
|
233
230
|
: undefined;
|
|
234
231
|
actions[configuration.name] = Object.freeze({
|
|
235
232
|
...configuration,
|
|
236
233
|
execution,
|
|
237
|
-
directoryName: entry
|
|
234
|
+
directoryName: entry,
|
|
238
235
|
...compiledSource,
|
|
239
236
|
});
|
|
240
237
|
}
|
|
@@ -321,7 +318,10 @@ function compileEvaluations(agentName, sourceDirectory) {
|
|
|
321
318
|
}
|
|
322
319
|
function discoverDirectories(directory) {
|
|
323
320
|
return readdirSync(directory, { withFileTypes: true })
|
|
324
|
-
.filter((entry) =>
|
|
321
|
+
.filter((entry) => !entry.name.startsWith(".") &&
|
|
322
|
+
(entry.isDirectory() ||
|
|
323
|
+
(entry.isSymbolicLink() &&
|
|
324
|
+
statSync(resolve(directory, entry.name)).isDirectory())))
|
|
325
325
|
.map((entry) => entry.name)
|
|
326
326
|
.sort();
|
|
327
327
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readFile, readdir } from "node:fs/promises";
|
|
1
|
+
import { readFile, readdir, stat } from "node:fs/promises";
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import { getOrchaRuntimeContext } from "../runtime/context.js";
|
|
4
4
|
export async function readPlaygroundAgentSource(orcha, agentKey) {
|
|
@@ -57,10 +57,17 @@ async function readCollectionItems(agentDirectory, collection, manifests, includ
|
|
|
57
57
|
manifest.directoryName,
|
|
58
58
|
{ key, manifest },
|
|
59
59
|
]));
|
|
60
|
-
|
|
61
|
-
.filter((entry) =>
|
|
62
|
-
.
|
|
63
|
-
|
|
60
|
+
const directories = (await Promise.all(entries
|
|
61
|
+
.filter((entry) => !entry.name.startsWith("."))
|
|
62
|
+
.map(async (entry) => ({
|
|
63
|
+
entry,
|
|
64
|
+
isDirectory: entry.isDirectory() ||
|
|
65
|
+
(entry.isSymbolicLink() &&
|
|
66
|
+
(await stat(resolve(root, entry.name))).isDirectory()),
|
|
67
|
+
})))).filter(({ isDirectory }) => isDirectory);
|
|
68
|
+
return Promise.all(directories
|
|
69
|
+
.sort((left, right) => left.entry.name.localeCompare(right.entry.name))
|
|
70
|
+
.map(async ({ entry }) => {
|
|
64
71
|
const directory = resolve(root, entry.name);
|
|
65
72
|
const rawConfiguration = await readRequired(resolve(directory, "index.json"));
|
|
66
73
|
const configuration = parseObject(rawConfiguration, `${collection}/${entry.name}/index.json`);
|
package/dist/runtime/agent.js
CHANGED
|
@@ -1740,7 +1740,16 @@ function normalizeDelegatedInput(input, projectRoot) {
|
|
|
1740
1740
|
if (!content) {
|
|
1741
1741
|
throw new Error("run_agent input must contain at least one valid content item.");
|
|
1742
1742
|
}
|
|
1743
|
-
|
|
1743
|
+
if (content.some((item) => item.type === "text")) {
|
|
1744
|
+
return content;
|
|
1745
|
+
}
|
|
1746
|
+
return [
|
|
1747
|
+
{
|
|
1748
|
+
type: "text",
|
|
1749
|
+
text: "Process the attached content according to your agent instructions.",
|
|
1750
|
+
},
|
|
1751
|
+
...content,
|
|
1752
|
+
];
|
|
1744
1753
|
}
|
|
1745
1754
|
function agentContentInputSchema() {
|
|
1746
1755
|
const textItem = {
|
package/dist/types.d.ts
CHANGED
|
@@ -97,6 +97,11 @@ export interface AmarsiaTelemetryRunV1 {
|
|
|
97
97
|
actions: AmarsiaTelemetryActionV1[];
|
|
98
98
|
evaluation_count: number;
|
|
99
99
|
evaluation_pass_count: number;
|
|
100
|
+
evaluation_failure_count: number;
|
|
101
|
+
evaluation_error_count: number;
|
|
102
|
+
evaluation_metric_count: number;
|
|
103
|
+
evaluation_metric_pass_count: number;
|
|
104
|
+
evaluations: AmarsiaTelemetryEvaluationV1[];
|
|
100
105
|
error_code?: string;
|
|
101
106
|
error_message?: string;
|
|
102
107
|
error_retryable?: boolean;
|
|
@@ -111,6 +116,28 @@ export interface AmarsiaTelemetryActionV1 {
|
|
|
111
116
|
error_code?: string;
|
|
112
117
|
error_message?: string;
|
|
113
118
|
}
|
|
119
|
+
export interface AmarsiaTelemetryEvaluationMetricV1 {
|
|
120
|
+
name: string;
|
|
121
|
+
score: number;
|
|
122
|
+
threshold: number;
|
|
123
|
+
passed: boolean;
|
|
124
|
+
reasoning: string;
|
|
125
|
+
evidence: string[];
|
|
126
|
+
}
|
|
127
|
+
export interface AmarsiaTelemetryEvaluationV1 {
|
|
128
|
+
name: string;
|
|
129
|
+
status: "passed" | "failed" | "error";
|
|
130
|
+
provider?: string;
|
|
131
|
+
model?: string;
|
|
132
|
+
duration_ms: number;
|
|
133
|
+
input_tokens: number;
|
|
134
|
+
output_tokens: number;
|
|
135
|
+
reasoning_tokens: number;
|
|
136
|
+
cache_read_tokens: number;
|
|
137
|
+
cache_write_tokens: number;
|
|
138
|
+
metrics: AmarsiaTelemetryEvaluationMetricV1[];
|
|
139
|
+
error_message?: string;
|
|
140
|
+
}
|
|
114
141
|
export interface AmarsiaTelemetryBatchV1 {
|
|
115
142
|
schema_version: 1;
|
|
116
143
|
runs: AmarsiaTelemetryRunV1[];
|
|
@@ -289,6 +289,9 @@ function projectRunFact(manifest, sessionId, run, projection) {
|
|
|
289
289
|
const evaluations = runEvents.filter(
|
|
290
290
|
(event) => event.type === "evaluation.completed" || event.type === "evaluation.failed"
|
|
291
291
|
);
|
|
292
|
+
const evaluationMetrics = evaluations.flatMap(
|
|
293
|
+
(event) => Array.isArray(event.data.metrics) ? event.data.metrics : []
|
|
294
|
+
);
|
|
292
295
|
const error = asRecord(terminal?.data.error);
|
|
293
296
|
const lastAssistant = assistants.at(-1);
|
|
294
297
|
const status = terminal?.type === "run.completed" ? "completed" : terminal?.type === "run.failed" ? "failed" : terminal?.type === "run.paused" ? "paused" : "running";
|
|
@@ -331,6 +334,17 @@ function projectRunFact(manifest, sessionId, run, projection) {
|
|
|
331
334
|
evaluation_pass_count: evaluations.filter(
|
|
332
335
|
(event) => event.type === "evaluation.completed" && event.data.status === "passed"
|
|
333
336
|
).length,
|
|
337
|
+
evaluation_failure_count: evaluations.filter(
|
|
338
|
+
(event) => event.type === "evaluation.completed" && event.data.status === "failed"
|
|
339
|
+
).length,
|
|
340
|
+
evaluation_error_count: evaluations.filter(
|
|
341
|
+
(event) => event.type === "evaluation.failed"
|
|
342
|
+
).length,
|
|
343
|
+
evaluation_metric_count: evaluationMetrics.length,
|
|
344
|
+
evaluation_metric_pass_count: evaluationMetrics.filter(
|
|
345
|
+
(metric) => asRecord(metric)?.passed === true
|
|
346
|
+
).length,
|
|
347
|
+
evaluations: projectEvaluationLogs(evaluations),
|
|
334
348
|
...typeof error?.code === "string" ? { error_code: error.code } : {},
|
|
335
349
|
...typeof error?.message === "string" ? { error_message: sanitizeErrorMessage(error.message) } : {},
|
|
336
350
|
...typeof error?.retryable === "boolean" ? { error_retryable: error.retryable } : {}
|
|
@@ -396,6 +410,38 @@ function projectActionLogs(events) {
|
|
|
396
410
|
};
|
|
397
411
|
});
|
|
398
412
|
}
|
|
413
|
+
function projectEvaluationLogs(events) {
|
|
414
|
+
return events.slice(0, 50).map((event) => {
|
|
415
|
+
const usage = asRecord(event.data.usage);
|
|
416
|
+
const error = asRecord(event.data.error);
|
|
417
|
+
const metrics = Array.isArray(event.data.metrics) ? event.data.metrics.map(asRecord).filter(
|
|
418
|
+
(metric) => metric !== void 0
|
|
419
|
+
).slice(0, 50).map((metric) => ({
|
|
420
|
+
name: typeof metric.name === "string" ? metric.name : "unknown_metric",
|
|
421
|
+
score: numberValue(metric.score),
|
|
422
|
+
threshold: numberValue(metric.threshold),
|
|
423
|
+
passed: metric.passed === true,
|
|
424
|
+
reasoning: typeof metric.reasoning === "string" ? sanitizeErrorMessage(metric.reasoning) : "",
|
|
425
|
+
evidence: Array.isArray(metric.evidence) ? metric.evidence.filter(
|
|
426
|
+
(item) => typeof item === "string"
|
|
427
|
+
).slice(0, 20).map(sanitizeErrorMessage) : []
|
|
428
|
+
})) : [];
|
|
429
|
+
return {
|
|
430
|
+
name: typeof event.data.name === "string" ? event.data.name : "unknown_evaluation",
|
|
431
|
+
status: event.type === "evaluation.failed" ? "error" : event.data.status === "passed" ? "passed" : "failed",
|
|
432
|
+
...typeof event.data.provider === "string" ? { provider: event.data.provider } : {},
|
|
433
|
+
...typeof event.data.model === "string" ? { model: event.data.model } : {},
|
|
434
|
+
duration_ms: numberValue(event.data.durationMs),
|
|
435
|
+
input_tokens: numberValue(usage?.inputTokens),
|
|
436
|
+
output_tokens: numberValue(usage?.outputTokens),
|
|
437
|
+
reasoning_tokens: numberValue(usage?.reasoningTokens),
|
|
438
|
+
cache_read_tokens: numberValue(usage?.cacheReadTokens),
|
|
439
|
+
cache_write_tokens: numberValue(usage?.cacheWriteTokens),
|
|
440
|
+
metrics,
|
|
441
|
+
...typeof error?.message === "string" ? { error_message: sanitizeErrorMessage(error.message) } : {}
|
|
442
|
+
};
|
|
443
|
+
});
|
|
444
|
+
}
|
|
399
445
|
function takeBatch(queue) {
|
|
400
446
|
const batch = [];
|
|
401
447
|
let bytes = utf8ByteLength('{"schema_version":1,"runs":[]}');
|
|
@@ -215,13 +215,10 @@ function compileActions(agentName, sourceDirectory, actionRuntime, target) {
|
|
|
215
215
|
return {};
|
|
216
216
|
}
|
|
217
217
|
const actions = {};
|
|
218
|
-
for (const entry of (
|
|
219
|
-
if (!entry.isDirectory()) {
|
|
220
|
-
continue;
|
|
221
|
-
}
|
|
218
|
+
for (const entry of discoverDirectories(actionsDirectory)) {
|
|
222
219
|
const configurationPath = (0, import_path.resolve)(
|
|
223
220
|
actionsDirectory,
|
|
224
|
-
entry
|
|
221
|
+
entry,
|
|
225
222
|
"index.json"
|
|
226
223
|
);
|
|
227
224
|
let configuration;
|
|
@@ -231,12 +228,12 @@ function compileActions(agentName, sourceDirectory, actionRuntime, target) {
|
|
|
231
228
|
);
|
|
232
229
|
} catch (error) {
|
|
233
230
|
throw new Error(
|
|
234
|
-
`Action "${agentName}/${entry
|
|
231
|
+
`Action "${agentName}/${entry}" is missing a valid index.json.`,
|
|
235
232
|
{ cause: error }
|
|
236
233
|
);
|
|
237
234
|
}
|
|
238
235
|
validateEnabled(
|
|
239
|
-
`Action "${agentName}/${entry
|
|
236
|
+
`Action "${agentName}/${entry}"`,
|
|
240
237
|
configuration?.enabled
|
|
241
238
|
);
|
|
242
239
|
if (configuration?.enabled === false) {
|
|
@@ -244,12 +241,12 @@ function compileActions(agentName, sourceDirectory, actionRuntime, target) {
|
|
|
244
241
|
}
|
|
245
242
|
if (!configuration.name?.trim() || !configuration.description?.trim()) {
|
|
246
243
|
throw new Error(
|
|
247
|
-
`Action "${agentName}/${entry
|
|
244
|
+
`Action "${agentName}/${entry}" requires name and description.`
|
|
248
245
|
);
|
|
249
246
|
}
|
|
250
247
|
if (!/^[a-zA-Z0-9_-]{1,64}$/.test(configuration.name)) {
|
|
251
248
|
throw new Error(
|
|
252
|
-
`Action "${agentName}/${entry
|
|
249
|
+
`Action "${agentName}/${entry}" has an invalid model-facing name.`
|
|
253
250
|
);
|
|
254
251
|
}
|
|
255
252
|
if ([
|
|
@@ -259,39 +256,39 @@ function compileActions(agentName, sourceDirectory, actionRuntime, target) {
|
|
|
259
256
|
"inspect_agent"
|
|
260
257
|
].includes(configuration.name)) {
|
|
261
258
|
throw new Error(
|
|
262
|
-
`Action "${agentName}/${entry
|
|
259
|
+
`Action "${agentName}/${entry}" uses reserved name "${configuration.name}".`
|
|
263
260
|
);
|
|
264
261
|
}
|
|
265
262
|
const execution = configuration.execution ?? "local";
|
|
266
263
|
if (!["client", "local"].includes(execution)) {
|
|
267
264
|
throw new Error(
|
|
268
|
-
`Action "${agentName}/${entry
|
|
265
|
+
`Action "${agentName}/${entry}" has invalid execution "${configuration.execution}".`
|
|
269
266
|
);
|
|
270
267
|
}
|
|
271
268
|
if (!configuration.parameters || typeof configuration.parameters !== "object" || Array.isArray(configuration.parameters)) {
|
|
272
269
|
throw new Error(
|
|
273
|
-
`Action "${agentName}/${entry
|
|
270
|
+
`Action "${agentName}/${entry}" requires a parameters JSON Schema.`
|
|
274
271
|
);
|
|
275
272
|
}
|
|
276
273
|
if (configuration.outputSchema !== void 0 && (typeof configuration.outputSchema !== "object" || configuration.outputSchema === null || Array.isArray(configuration.outputSchema))) {
|
|
277
274
|
throw new Error(
|
|
278
|
-
`Action "${agentName}/${entry
|
|
275
|
+
`Action "${agentName}/${entry}" has an invalid outputSchema.`
|
|
279
276
|
);
|
|
280
277
|
}
|
|
281
278
|
validateNumber(
|
|
282
|
-
`${agentName}/${entry
|
|
279
|
+
`${agentName}/${entry}`,
|
|
283
280
|
"timeoutMs",
|
|
284
281
|
configuration.timeoutMs,
|
|
285
282
|
{ integer: true, minimum: 1, maximum: 12e4 }
|
|
286
283
|
);
|
|
287
284
|
if (configuration.permissions?.env !== void 0 && !Array.isArray(configuration.permissions.env)) {
|
|
288
285
|
throw new Error(
|
|
289
|
-
`Action "${agentName}/${entry
|
|
286
|
+
`Action "${agentName}/${entry}" permissions.env must be an array.`
|
|
290
287
|
);
|
|
291
288
|
}
|
|
292
289
|
if (configuration.permissions?.network !== void 0 && !Array.isArray(configuration.permissions.network)) {
|
|
293
290
|
throw new Error(
|
|
294
|
-
`Action "${agentName}/${entry
|
|
291
|
+
`Action "${agentName}/${entry}" permissions.network must be an array.`
|
|
295
292
|
);
|
|
296
293
|
}
|
|
297
294
|
for (const permission of [
|
|
@@ -300,7 +297,7 @@ function compileActions(agentName, sourceDirectory, actionRuntime, target) {
|
|
|
300
297
|
]) {
|
|
301
298
|
if (typeof permission !== "string" || !permission.trim()) {
|
|
302
299
|
throw new Error(
|
|
303
|
-
`Action "${agentName}/${entry
|
|
300
|
+
`Action "${agentName}/${entry}" has an invalid permission.`
|
|
304
301
|
);
|
|
305
302
|
}
|
|
306
303
|
}
|
|
@@ -311,7 +308,7 @@ function compileActions(agentName, sourceDirectory, actionRuntime, target) {
|
|
|
311
308
|
}
|
|
312
309
|
const compiledSource = execution === "local" ? compileLocalAction(
|
|
313
310
|
agentName,
|
|
314
|
-
entry
|
|
311
|
+
entry,
|
|
315
312
|
actionsDirectory,
|
|
316
313
|
actionRuntime,
|
|
317
314
|
target
|
|
@@ -319,7 +316,7 @@ function compileActions(agentName, sourceDirectory, actionRuntime, target) {
|
|
|
319
316
|
actions[configuration.name] = Object.freeze({
|
|
320
317
|
...configuration,
|
|
321
318
|
execution,
|
|
322
|
-
directoryName: entry
|
|
319
|
+
directoryName: entry,
|
|
323
320
|
...compiledSource
|
|
324
321
|
});
|
|
325
322
|
}
|
|
@@ -426,7 +423,9 @@ function compileEvaluations(agentName, sourceDirectory) {
|
|
|
426
423
|
return Object.freeze(evaluations);
|
|
427
424
|
}
|
|
428
425
|
function discoverDirectories(directory) {
|
|
429
|
-
return (0, import_fs.readdirSync)(directory, { withFileTypes: true }).filter(
|
|
426
|
+
return (0, import_fs.readdirSync)(directory, { withFileTypes: true }).filter(
|
|
427
|
+
(entry) => !entry.name.startsWith(".") && (entry.isDirectory() || entry.isSymbolicLink() && (0, import_fs.statSync)((0, import_path.resolve)(directory, entry.name)).isDirectory())
|
|
428
|
+
).map((entry) => entry.name).sort();
|
|
430
429
|
}
|
|
431
430
|
function rejectLegacyRegistry(agentName, directory, collection) {
|
|
432
431
|
if ((0, import_fs.existsSync)((0, import_path.resolve)(directory, "index.js"))) {
|
|
@@ -102,8 +102,16 @@ async function readCollectionItems(agentDirectory, collection, manifests, includ
|
|
|
102
102
|
{ key, manifest }
|
|
103
103
|
])
|
|
104
104
|
);
|
|
105
|
+
const directories = (await Promise.all(
|
|
106
|
+
entries.filter((entry) => !entry.name.startsWith(".")).map(async (entry) => ({
|
|
107
|
+
entry,
|
|
108
|
+
isDirectory: entry.isDirectory() || entry.isSymbolicLink() && (await (0, import_promises.stat)((0, import_path.resolve)(root, entry.name))).isDirectory()
|
|
109
|
+
}))
|
|
110
|
+
)).filter(({ isDirectory }) => isDirectory);
|
|
105
111
|
return Promise.all(
|
|
106
|
-
|
|
112
|
+
directories.sort(
|
|
113
|
+
(left, right) => left.entry.name.localeCompare(right.entry.name)
|
|
114
|
+
).map(async ({ entry }) => {
|
|
107
115
|
const directory = (0, import_path.resolve)(root, entry.name);
|
|
108
116
|
const rawConfiguration = await readRequired(
|
|
109
117
|
(0, import_path.resolve)(directory, "index.json")
|
|
@@ -2024,7 +2024,16 @@ function normalizeDelegatedInput(input, projectRoot) {
|
|
|
2024
2024
|
"run_agent input must contain at least one valid content item."
|
|
2025
2025
|
);
|
|
2026
2026
|
}
|
|
2027
|
-
|
|
2027
|
+
if (content.some((item) => item.type === "text")) {
|
|
2028
|
+
return content;
|
|
2029
|
+
}
|
|
2030
|
+
return [
|
|
2031
|
+
{
|
|
2032
|
+
type: "text",
|
|
2033
|
+
text: "Process the attached content according to your agent instructions."
|
|
2034
|
+
},
|
|
2035
|
+
...content
|
|
2036
|
+
];
|
|
2028
2037
|
}
|
|
2029
2038
|
function agentContentInputSchema() {
|
|
2030
2039
|
const textItem = {
|