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.
@@ -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":[]}');
@@ -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 readdirSync(actionsDirectory, { withFileTypes: true })) {
167
- if (!entry.isDirectory()) {
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.name}" is missing a valid index.json.`, { cause: error });
173
+ throw new Error(`Action "${agentName}/${entry}" is missing a valid index.json.`, { cause: error });
177
174
  }
178
- validateEnabled(`Action "${agentName}/${entry.name}"`, configuration?.enabled);
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.name}" requires name and description.`);
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.name}" has an invalid model-facing name.`);
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.name}" uses reserved name "${configuration.name}".`);
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.name}" has invalid execution "${configuration.execution}".`);
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.name}" requires a parameters JSON Schema.`);
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.name}" has an invalid outputSchema.`);
206
+ throw new Error(`Action "${agentName}/${entry}" has an invalid outputSchema.`);
210
207
  }
211
- validateNumber(`${agentName}/${entry.name}`, "timeoutMs", configuration.timeoutMs, { integer: true, minimum: 1, maximum: 120_000 });
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.name}" permissions.env must be an array.`);
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.name}" permissions.network must be an array.`);
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.name}" has an invalid permission.`);
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.name, actionsDirectory, actionRuntime, target)
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.name,
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) => entry.isDirectory() && !entry.name.startsWith("."))
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
- return Promise.all(entries
61
- .filter((entry) => entry.isDirectory() && !entry.name.startsWith("."))
62
- .sort((left, right) => left.name.localeCompare(right.name))
63
- .map(async (entry) => {
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`);
@@ -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
- return content;
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 (0, import_fs.readdirSync)(actionsDirectory, { withFileTypes: true })) {
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.name,
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.name}" is missing a valid index.json.`,
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.name}"`,
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.name}" requires name and description.`
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.name}" has an invalid model-facing name.`
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.name}" uses reserved name "${configuration.name}".`
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.name}" has invalid execution "${configuration.execution}".`
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.name}" requires a parameters JSON Schema.`
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.name}" has an invalid outputSchema.`
275
+ `Action "${agentName}/${entry}" has an invalid outputSchema.`
279
276
  );
280
277
  }
281
278
  validateNumber(
282
- `${agentName}/${entry.name}`,
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.name}" permissions.env must be an array.`
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.name}" permissions.network must be an array.`
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.name}" has an invalid permission.`
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.name,
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.name,
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((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name).sort();
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
- entries.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).sort((left, right) => left.name.localeCompare(right.name)).map(async (entry) => {
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
- return content;
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 = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orchajs",
3
- "version": "0.22.0",
3
+ "version": "0.23.1",
4
4
  "description": "A filesystem-convention, stateful agent framework for JavaScript.",
5
5
  "license": "MIT",
6
6
  "repository": {