orchajs 0.20.3 → 0.22.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/README.md +103 -0
- package/dist/amarsia/analytics.d.ts +21 -0
- package/dist/amarsia/analytics.js +457 -0
- package/dist/amarsia/endpoint.d.ts +1 -0
- package/dist/amarsia/endpoint.js +8 -0
- package/dist/amarsia/sync.js +1 -4
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +13 -0
- package/dist/browser.d.ts +2 -0
- package/dist/browser.js +12 -0
- package/dist/cli.js +35 -9
- package/dist/compiler/build-project.d.ts +1 -0
- package/dist/compiler/build-project.js +75 -8
- package/dist/compiler/compile.d.ts +1 -1
- package/dist/compiler/compile.js +11 -9
- package/dist/errors.d.ts +5 -0
- package/dist/errors.js +102 -0
- package/dist/file-content.js +42 -6
- package/dist/index.d.ts +1 -5
- package/dist/index.js +1 -2
- package/dist/integrations/esbuild.js +5 -2
- package/dist/integrations/expo.d.ts +1 -0
- package/dist/integrations/expo.js +1 -0
- package/dist/integrations/metro.d.ts +15 -0
- package/dist/integrations/metro.js +25 -0
- package/dist/integrations/next.d.ts +23 -0
- package/dist/integrations/next.js +53 -0
- package/dist/integrations/runtime-build.d.ts +4 -0
- package/dist/integrations/runtime-build.js +32 -0
- package/dist/integrations/vite.d.ts +23 -0
- package/dist/integrations/vite.js +32 -0
- package/dist/integrations/webpack.d.ts +24 -0
- package/dist/integrations/webpack.js +21 -0
- package/dist/orcha.js +17 -8
- package/dist/playground/server.js +57 -7
- package/dist/project-loader.js +3 -0
- package/dist/providers/browser.d.ts +2 -0
- package/dist/providers/browser.js +20 -0
- package/dist/react-native.d.ts +2 -0
- package/dist/react-native.js +12 -0
- package/dist/runtime/actions/browser-native.d.ts +3 -0
- package/dist/runtime/actions/browser-native.js +28 -0
- package/dist/runtime/actions/execute.d.ts +7 -0
- package/dist/runtime/actions/execute.js +9 -2
- package/dist/runtime/agent.d.ts +1 -0
- package/dist/runtime/agent.js +38 -10
- package/dist/runtime/compiler-hook.d.ts +5 -0
- package/dist/runtime/compiler-hook.js +8 -0
- package/dist/runtime/create-orcha.d.ts +6 -1
- package/dist/runtime/create-orcha.js +35 -21
- package/dist/runtime/platform-browser.d.ts +2 -0
- package/dist/runtime/platform-browser.js +15 -0
- package/dist/runtime/platform-node.d.ts +2 -0
- package/dist/runtime/platform-node.js +31 -0
- package/dist/runtime/platform-react-native.d.ts +2 -0
- package/dist/runtime/platform-react-native.js +15 -0
- package/dist/runtime/platform.d.ts +15 -0
- package/dist/runtime/platform.js +1 -0
- package/dist/runtime/random-id.d.ts +1 -0
- package/dist/runtime/random-id.js +26 -0
- package/dist/runtime-entry.d.ts +5 -0
- package/dist/runtime-entry.js +2 -0
- package/dist/storage/browser-indexeddb.d.ts +7 -16
- package/dist/storage/browser-indexeddb.js +102 -19
- package/dist/storage/react-native-jsonl.d.ts +7 -16
- package/dist/storage/react-native-jsonl.js +65 -19
- package/dist/types.d.ts +54 -1
- package/dist-cjs/amarsia/analytics.js +447 -0
- package/dist-cjs/amarsia/endpoint.js +32 -0
- package/dist-cjs/amarsia/sync.js +2 -5
- package/dist-cjs/browser.js +48 -0
- package/dist-cjs/compiler/build-project.js +97 -8
- package/dist-cjs/compiler/compile.js +17 -9
- package/dist-cjs/errors.js +92 -2
- package/dist-cjs/file-content.js +42 -7
- package/dist-cjs/index.js +4 -9
- package/dist-cjs/integrations/esbuild.js +6 -2
- package/dist-cjs/integrations/expo.js +29 -0
- package/dist-cjs/integrations/metro.js +51 -0
- package/dist-cjs/integrations/next.js +75 -0
- package/dist-cjs/integrations/runtime-build.js +70 -0
- package/dist-cjs/integrations/vite.js +57 -0
- package/dist-cjs/integrations/webpack.js +51 -0
- package/dist-cjs/orcha.js +17 -12
- package/dist-cjs/playground/server.js +62 -9
- package/dist-cjs/project-loader.js +10 -0
- package/dist-cjs/providers/browser.js +61 -0
- package/dist-cjs/react-native.js +48 -0
- package/dist-cjs/runtime/actions/browser-native.js +68 -0
- package/dist-cjs/runtime/actions/execute.js +12 -2
- package/dist-cjs/runtime/agent.js +37 -14
- package/dist-cjs/runtime/compiler-hook.js +37 -0
- package/dist-cjs/runtime/create-orcha.js +34 -23
- package/dist-cjs/runtime/platform-browser.js +48 -0
- package/dist-cjs/runtime/platform-node.js +59 -0
- package/dist-cjs/runtime/platform-react-native.js +45 -0
- package/dist-cjs/runtime/platform.js +17 -0
- package/dist-cjs/runtime/random-id.js +55 -0
- package/dist-cjs/runtime-entry.js +34 -0
- package/dist-cjs/storage/browser-indexeddb.js +102 -5
- package/dist-cjs/storage/react-native-jsonl.js +73 -5
- package/dist-cjs/types/react-native-async-storage.d.js +2 -0
- package/package.json +69 -9
- package/dist/playground/public/app.css +0 -1
- package/dist/playground/public/app.js +0 -31
- package/dist/playground/public/index.html +0 -15
- package/dist/playground/public/orcha-logo.svg +0 -4
package/dist/cli.js
CHANGED
|
@@ -24,8 +24,7 @@ try {
|
|
|
24
24
|
await initializeProject(projectRoot);
|
|
25
25
|
break;
|
|
26
26
|
case "dev":
|
|
27
|
-
|
|
28
|
-
await watchProject(projectRoot);
|
|
27
|
+
await watchProject(projectRoot, parseDevTargets(commandArguments));
|
|
29
28
|
break;
|
|
30
29
|
case "run":
|
|
31
30
|
await runAgent(projectRoot, commandArguments);
|
|
@@ -43,9 +42,13 @@ try {
|
|
|
43
42
|
await exportSession(projectRoot, commandArguments);
|
|
44
43
|
break;
|
|
45
44
|
case "build": {
|
|
46
|
-
|
|
45
|
+
const parsed = parseArguments(commandArguments, new Set(["--target"]), new Set());
|
|
46
|
+
if (parsed.positionals.length > 0) {
|
|
47
|
+
throw new Error("Usage: orcha build [--target node|browser|react-native]");
|
|
48
|
+
}
|
|
49
|
+
const target = parseBuildTarget(parsed.values.get("--target"));
|
|
47
50
|
loadProjectEnvironment(projectRoot);
|
|
48
|
-
const outputPath = await buildProject({ projectRoot });
|
|
51
|
+
const outputPath = await buildProject({ projectRoot, target });
|
|
49
52
|
console.log(`Built ${relative(projectRoot, outputPath)}`);
|
|
50
53
|
break;
|
|
51
54
|
}
|
|
@@ -112,11 +115,12 @@ async function initializeProject(projectRoot) {
|
|
|
112
115
|
await ensureGitignore(projectRoot);
|
|
113
116
|
console.log('\nRun "orcha dev" to validate changes or "orcha run exampleAgent --input \\"Hello\\"" to execute the agent.');
|
|
114
117
|
}
|
|
115
|
-
async function watchProject(projectRoot) {
|
|
118
|
+
async function watchProject(projectRoot, targets) {
|
|
116
119
|
const registryDirectory = resolve(projectRoot, "orcha");
|
|
117
120
|
if (!existsSync(registryDirectory)) {
|
|
118
121
|
throw new Error('Missing "orcha/". Run "orcha init" first.');
|
|
119
122
|
}
|
|
123
|
+
loadProjectEnvironment(projectRoot);
|
|
120
124
|
let validating = false;
|
|
121
125
|
let validateAgain = false;
|
|
122
126
|
let timer;
|
|
@@ -127,7 +131,9 @@ async function watchProject(projectRoot) {
|
|
|
127
131
|
}
|
|
128
132
|
validating = true;
|
|
129
133
|
try {
|
|
130
|
-
|
|
134
|
+
for (const target of targets) {
|
|
135
|
+
await buildProject({ projectRoot, target });
|
|
136
|
+
}
|
|
131
137
|
const agents = Object.keys(orcha.getCompiledBundle().agents);
|
|
132
138
|
console.log(`[orcha] valid — ${agents.length} agent${agents.length === 1 ? "" : "s"}: ${agents.join(", ") || "none"}`);
|
|
133
139
|
}
|
|
@@ -143,7 +149,7 @@ async function watchProject(projectRoot) {
|
|
|
143
149
|
}
|
|
144
150
|
};
|
|
145
151
|
await validate();
|
|
146
|
-
console.log(
|
|
152
|
+
console.log(`[orcha] watching orcha/** for ${targets.join(", ")}`);
|
|
147
153
|
const watcher = watch(registryDirectory, { ignoreInitial: true }).on("all", () => {
|
|
148
154
|
clearTimeout(timer);
|
|
149
155
|
timer = setTimeout(() => void validate(), 75);
|
|
@@ -344,6 +350,26 @@ function allAgentManifests(agents) {
|
|
|
344
350
|
}
|
|
345
351
|
return [...manifests.values()];
|
|
346
352
|
}
|
|
353
|
+
function parseDevTargets(arguments_) {
|
|
354
|
+
const parsed = parseArguments(arguments_, new Set(["--target"]), new Set());
|
|
355
|
+
if (parsed.positionals.length > 0) {
|
|
356
|
+
throw new Error("Usage: orcha dev [--target node|browser|react-native|all]");
|
|
357
|
+
}
|
|
358
|
+
const target = parsed.values.get("--target") ?? "node";
|
|
359
|
+
if (target === "all") {
|
|
360
|
+
return ["browser", "react-native", "node"];
|
|
361
|
+
}
|
|
362
|
+
return [parseBuildTarget(target)];
|
|
363
|
+
}
|
|
364
|
+
function parseBuildTarget(value) {
|
|
365
|
+
if (value === undefined ||
|
|
366
|
+
value === "node" ||
|
|
367
|
+
value === "browser" ||
|
|
368
|
+
value === "react-native") {
|
|
369
|
+
return value ?? "node";
|
|
370
|
+
}
|
|
371
|
+
throw new Error(`Unknown build target "${value}". Expected node, browser, or react-native.`);
|
|
372
|
+
}
|
|
347
373
|
function parseArguments(arguments_, valueOptions, flagOptions = new Set(["--json"])) {
|
|
348
374
|
const parsed = {
|
|
349
375
|
positionals: [],
|
|
@@ -605,13 +631,13 @@ function printUsage() {
|
|
|
605
631
|
"",
|
|
606
632
|
"Commands:",
|
|
607
633
|
" init Add Orcha to the current project",
|
|
608
|
-
" dev
|
|
634
|
+
" dev [--target <runtime>] Build and watch orcha/**",
|
|
609
635
|
" run <agent> [options] Execute or resume an agent",
|
|
610
636
|
" test [agent | agent/test] Run agent tests",
|
|
611
637
|
" playground [options] Open the local agent playground",
|
|
612
638
|
" migrate-storage --to <type> Copy sessions between JSONL and SQLite",
|
|
613
639
|
" export-session <agent> <id> Export one session as JSONL",
|
|
614
|
-
" build
|
|
640
|
+
" build [--target <runtime>] Build for node, browser, or react-native",
|
|
615
641
|
"",
|
|
616
642
|
"Run and test support --json for machine-readable output.",
|
|
617
643
|
].join("\n"));
|
|
@@ -4,9 +4,14 @@ import { dirname, resolve } from "node:path";
|
|
|
4
4
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
5
|
import { build as bundleEntry } from "esbuild";
|
|
6
6
|
import { orcha } from "../orcha.js";
|
|
7
|
+
import { setRegistryCompiler } from "../runtime/compiler-hook.js";
|
|
8
|
+
import { compileRegistry } from "./compile.js";
|
|
7
9
|
import { builtInProviderCatalog, isBuiltInProvider, } from "../providers/catalog.js";
|
|
10
|
+
let registryImportSequence = 0;
|
|
8
11
|
export async function buildProject(options = {}) {
|
|
9
12
|
const projectRoot = resolve(options.projectRoot ?? process.cwd());
|
|
13
|
+
const target = options.target ?? "node";
|
|
14
|
+
setRegistryCompiler((configuration, compilerProjectRoot) => compileRegistry(configuration.agents, resolve(compilerProjectRoot, "orcha"), configuration.actions?.runtime ?? "native", target));
|
|
10
15
|
const registryPath = resolve(projectRoot, "orcha/index.ts");
|
|
11
16
|
if (!existsSync(registryPath)) {
|
|
12
17
|
throw new Error('Missing "orcha/index.ts". Run "orcha init" first.');
|
|
@@ -14,7 +19,7 @@ export async function buildProject(options = {}) {
|
|
|
14
19
|
const temporaryDirectory = resolve(projectRoot, ".orcha/.build");
|
|
15
20
|
const registryBundlePath = resolve(temporaryDirectory, "registry.mjs");
|
|
16
21
|
const productionEntryPath = resolve(temporaryDirectory, "production-entry.mjs");
|
|
17
|
-
const outputPath = resolve(projectRoot,
|
|
22
|
+
const outputPath = resolve(projectRoot, `.orcha/dist/${bundleFileName(target)}`);
|
|
18
23
|
const manifestPath = resolve(projectRoot, ".orcha/dist/manifest.json");
|
|
19
24
|
await mkdir(temporaryDirectory, { recursive: true });
|
|
20
25
|
await mkdir(dirname(outputPath), { recursive: true });
|
|
@@ -34,7 +39,7 @@ export async function buildProject(options = {}) {
|
|
|
34
39
|
process.env.ORCHA_COMPILING = "1";
|
|
35
40
|
process.env.ORCHA_PROJECT_ROOT = projectRoot;
|
|
36
41
|
try {
|
|
37
|
-
await import(`${pathToFileURL(registryBundlePath).href}?
|
|
42
|
+
await import(`${pathToFileURL(registryBundlePath).href}?build=${Date.now()}-${registryImportSequence++}`);
|
|
38
43
|
}
|
|
39
44
|
finally {
|
|
40
45
|
if (previousCompiling === undefined) {
|
|
@@ -51,11 +56,19 @@ export async function buildProject(options = {}) {
|
|
|
51
56
|
}
|
|
52
57
|
}
|
|
53
58
|
const compiledBundle = orcha.getCompiledBundle();
|
|
59
|
+
if (target !== "node" &&
|
|
60
|
+
compiledBundle.actionRuntime === "sandbox") {
|
|
61
|
+
throw new Error(`The ${target} target supports precompiled native actions only. Set actions.runtime to "native".`);
|
|
62
|
+
}
|
|
54
63
|
const runtimeFactoryPath = resolve(dirname(fileURLToPath(import.meta.url)), "../runtime/create-orcha.js").replaceAll("\\", "/");
|
|
64
|
+
const runtimePlatformPath = resolve(dirname(fileURLToPath(import.meta.url)), `../runtime/platform-${target}.js`).replaceAll("\\", "/");
|
|
65
|
+
const runtimeEntryPath = resolve(dirname(fileURLToPath(import.meta.url)), "../runtime-entry.js").replaceAll("\\", "/");
|
|
55
66
|
const providerDispatcherPath = resolve(dirname(fileURLToPath(import.meta.url)), "../providers/dispatcher.js").replaceAll("\\", "/");
|
|
56
67
|
const sandboxRuntimeSource = compiledBundle.actionRuntime === "sandbox"
|
|
57
68
|
? createSandboxRuntimeSource()
|
|
58
69
|
: "";
|
|
70
|
+
const platformActionRuntimeSource = createPlatformActionRuntimeSource(target);
|
|
71
|
+
const nodeStorageExports = target === "node" ? createNodeStorageExports() : "";
|
|
59
72
|
const includedProviders = [
|
|
60
73
|
...new Set(allCompiledAgents(compiledBundle.agents).flatMap((agent) => [
|
|
61
74
|
agent.provider,
|
|
@@ -64,18 +77,22 @@ export async function buildProject(options = {}) {
|
|
|
64
77
|
.map((evaluation) => evaluation.provider),
|
|
65
78
|
])),
|
|
66
79
|
];
|
|
67
|
-
const providerRuntimeSource = createProviderRuntimeSource(includedProviders);
|
|
80
|
+
const providerRuntimeSource = createProviderRuntimeSource(includedProviders, target);
|
|
68
81
|
const needsNodeRequire = compiledBundle.actionRuntime === "sandbox" ||
|
|
69
82
|
includedProviders.includes("vertexai") ||
|
|
70
83
|
includedProviders.includes("bedrock");
|
|
71
84
|
await writeFile(productionEntryPath, [
|
|
72
85
|
`import { createOrcha } from ${JSON.stringify(runtimeFactoryPath)};`,
|
|
86
|
+
`import { ${runtimePlatformExport(target)} as runtimePlatform } from ${JSON.stringify(runtimePlatformPath)};`,
|
|
73
87
|
`import { createProviderResponseGenerator } from ${JSON.stringify(providerDispatcherPath)};`,
|
|
88
|
+
`export * from ${JSON.stringify(runtimeEntryPath)};`,
|
|
89
|
+
nodeStorageExports,
|
|
74
90
|
providerRuntimeSource,
|
|
91
|
+
platformActionRuntimeSource,
|
|
75
92
|
sandboxRuntimeSource,
|
|
76
93
|
`const compiledBundle = ${JSON.stringify(compiledBundle)};`,
|
|
77
94
|
"const generateProviderResponse = createProviderResponseGenerator(includedProviders);",
|
|
78
|
-
"export const orcha = createOrcha(() => compiledBundle, generateProviderResponse);",
|
|
95
|
+
"export const orcha = createOrcha(() => compiledBundle, generateProviderResponse, runtimePlatform);",
|
|
79
96
|
"export default orcha;",
|
|
80
97
|
"",
|
|
81
98
|
].join("\n"), "utf8");
|
|
@@ -84,14 +101,18 @@ export async function buildProject(options = {}) {
|
|
|
84
101
|
outfile: outputPath,
|
|
85
102
|
bundle: true,
|
|
86
103
|
format: "esm",
|
|
87
|
-
platform: "node",
|
|
88
|
-
target: "
|
|
104
|
+
platform: target === "node" ? "node" : "browser",
|
|
105
|
+
target: target === "node"
|
|
106
|
+
? "node18"
|
|
107
|
+
: target === "browser"
|
|
108
|
+
? ["chrome110", "firefox110", "safari16"]
|
|
109
|
+
: "es2022",
|
|
89
110
|
minify: true,
|
|
90
111
|
legalComments: "none",
|
|
91
112
|
define: {
|
|
92
113
|
"process.env.ORCHA_INCLUDE_SANDBOX": JSON.stringify(compiledBundle.actionRuntime === "sandbox" ? "1" : "0"),
|
|
93
114
|
},
|
|
94
|
-
...(needsNodeRequire
|
|
115
|
+
...(needsNodeRequire && target === "node"
|
|
95
116
|
? {
|
|
96
117
|
banner: {
|
|
97
118
|
js: [
|
|
@@ -101,6 +122,13 @@ export async function buildProject(options = {}) {
|
|
|
101
122
|
},
|
|
102
123
|
}
|
|
103
124
|
: {}),
|
|
125
|
+
...(target === "react-native"
|
|
126
|
+
? {
|
|
127
|
+
external: [
|
|
128
|
+
"@react-native-async-storage/async-storage",
|
|
129
|
+
],
|
|
130
|
+
}
|
|
131
|
+
: {}),
|
|
104
132
|
logLevel: "silent",
|
|
105
133
|
});
|
|
106
134
|
await writeFile(manifestPath, `${JSON.stringify(compiledBundle)}\n`, "utf8");
|
|
@@ -113,6 +141,18 @@ export async function buildProject(options = {}) {
|
|
|
113
141
|
});
|
|
114
142
|
}
|
|
115
143
|
}
|
|
144
|
+
function bundleFileName(target) {
|
|
145
|
+
return target === "node" ? "bundle.js" : `bundle.${target}.js`;
|
|
146
|
+
}
|
|
147
|
+
function runtimePlatformExport(target) {
|
|
148
|
+
if (target === "browser") {
|
|
149
|
+
return "browserRuntimePlatform";
|
|
150
|
+
}
|
|
151
|
+
if (target === "react-native") {
|
|
152
|
+
return "reactNativeRuntimePlatform";
|
|
153
|
+
}
|
|
154
|
+
return "nodeRuntimePlatform";
|
|
155
|
+
}
|
|
116
156
|
function createSandboxRuntimeSource() {
|
|
117
157
|
const runtimeDirectory = dirname(fileURLToPath(import.meta.url));
|
|
118
158
|
const executePath = resolve(runtimeDirectory, "../runtime/actions/execute.js").replaceAll("\\", "/");
|
|
@@ -124,13 +164,36 @@ function createSandboxRuntimeSource() {
|
|
|
124
164
|
"",
|
|
125
165
|
].join("\n");
|
|
126
166
|
}
|
|
167
|
+
function createPlatformActionRuntimeSource(target) {
|
|
168
|
+
const runtimeDirectory = dirname(fileURLToPath(import.meta.url));
|
|
169
|
+
const executePath = resolve(runtimeDirectory, "../runtime/actions/execute.js").replaceAll("\\", "/");
|
|
170
|
+
const nativePath = resolve(runtimeDirectory, target === "node"
|
|
171
|
+
? "../runtime/actions/native.js"
|
|
172
|
+
: "../runtime/actions/browser-native.js").replaceAll("\\", "/");
|
|
173
|
+
return [
|
|
174
|
+
`import { setNativeRuntimeLoader } from ${JSON.stringify(executePath)};`,
|
|
175
|
+
`import { executeNativeAction } from ${JSON.stringify(nativePath)};`,
|
|
176
|
+
"setNativeRuntimeLoader(async () => ({ executeNativeAction }));",
|
|
177
|
+
"",
|
|
178
|
+
].join("\n");
|
|
179
|
+
}
|
|
180
|
+
function createNodeStorageExports() {
|
|
181
|
+
const sourceRoot = dirname(fileURLToPath(import.meta.url));
|
|
182
|
+
const jsonlPath = resolve(sourceRoot, "../storage/node-jsonl.js").replaceAll("\\", "/");
|
|
183
|
+
const sqlitePath = resolve(sourceRoot, "../storage/node-sqlite.js").replaceAll("\\", "/");
|
|
184
|
+
return [
|
|
185
|
+
`export { NodeJsonlSessionStore } from ${JSON.stringify(jsonlPath)};`,
|
|
186
|
+
`export { NodeSqliteSessionStore } from ${JSON.stringify(sqlitePath)};`,
|
|
187
|
+
"",
|
|
188
|
+
].join("\n");
|
|
189
|
+
}
|
|
127
190
|
function allCompiledAgents(agents) {
|
|
128
191
|
return Object.values(agents).flatMap((agent) => [
|
|
129
192
|
agent,
|
|
130
193
|
...Object.values(agent.subagents ?? {}),
|
|
131
194
|
]);
|
|
132
195
|
}
|
|
133
|
-
function createProviderRuntimeSource(providerNames) {
|
|
196
|
+
function createProviderRuntimeSource(providerNames, target) {
|
|
134
197
|
const providersDirectory = resolve(dirname(fileURLToPath(import.meta.url)), "../providers");
|
|
135
198
|
const imports = [];
|
|
136
199
|
const entries = [];
|
|
@@ -138,6 +201,10 @@ function createProviderRuntimeSource(providerNames) {
|
|
|
138
201
|
if (!isBuiltInProvider(name)) {
|
|
139
202
|
throw new Error(`Provider "${name}" is not built in.`);
|
|
140
203
|
}
|
|
204
|
+
if (target !== "node" &&
|
|
205
|
+
(name === "bedrock" || name === "vertexai")) {
|
|
206
|
+
throw new Error(`Provider "${name}" is not available for the ${target} target.`);
|
|
207
|
+
}
|
|
141
208
|
const descriptor = builtInProviderCatalog[name];
|
|
142
209
|
const localName = `provider${index}`;
|
|
143
210
|
imports.push(`import { ${descriptor.exportName} as ${localName} } from ${JSON.stringify(resolve(providersDirectory, descriptor.moduleFile))};`);
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { AgentRegistration, CompiledBundle } from "../types.js";
|
|
2
|
-
export declare function compileRegistry(registrations: Record<string, AgentRegistration>, registryRoot: string, actionRuntime?: "native" | "sandbox"): CompiledBundle;
|
|
2
|
+
export declare function compileRegistry(registrations: Record<string, AgentRegistration>, registryRoot: string, actionRuntime?: "native" | "sandbox", target?: "node" | "browser" | "react-native"): CompiledBundle;
|
|
3
3
|
export declare function serializeBundle(bundle: CompiledBundle): string;
|
package/dist/compiler/compile.js
CHANGED
|
@@ -3,7 +3,7 @@ import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
import { buildSync } from "esbuild";
|
|
5
5
|
import { isBuiltInProvider } from "../providers/catalog.js";
|
|
6
|
-
export function compileRegistry(registrations, registryRoot, actionRuntime = "native") {
|
|
6
|
+
export function compileRegistry(registrations, registryRoot, actionRuntime = "native", target = "node") {
|
|
7
7
|
if (!registrations ||
|
|
8
8
|
typeof registrations !== "object" ||
|
|
9
9
|
Array.isArray(registrations)) {
|
|
@@ -20,9 +20,9 @@ export function compileRegistry(registrations, registryRoot, actionRuntime = "na
|
|
|
20
20
|
if (!subagentKey.trim()) {
|
|
21
21
|
throw new Error(`Agent "${key}" has an empty subagent name.`);
|
|
22
22
|
}
|
|
23
|
-
subagents[subagentKey] = compileAgent(subagentKey, registeredPath, registryRoot, actionRuntime);
|
|
23
|
+
subagents[subagentKey] = compileAgent(subagentKey, registeredPath, registryRoot, actionRuntime, target);
|
|
24
24
|
}
|
|
25
|
-
const parent = compileAgent(key, normalized.path, registryRoot, actionRuntime);
|
|
25
|
+
const parent = compileAgent(key, normalized.path, registryRoot, actionRuntime, target);
|
|
26
26
|
agents[key] = Object.freeze({
|
|
27
27
|
...parent,
|
|
28
28
|
subagentPolicy: Object.keys(subagents).length > 0
|
|
@@ -72,7 +72,7 @@ function normalizeAgentRegistration(key, registration) {
|
|
|
72
72
|
subagents: registration.subagents ?? {},
|
|
73
73
|
};
|
|
74
74
|
}
|
|
75
|
-
function compileAgent(key, registeredPath, registryRoot, actionRuntime) {
|
|
75
|
+
function compileAgent(key, registeredPath, registryRoot, actionRuntime, target) {
|
|
76
76
|
const name = key;
|
|
77
77
|
const sourceDirectory = resolve(registryRoot, registeredPath);
|
|
78
78
|
const configPath = resolve(sourceDirectory, "index.json");
|
|
@@ -148,7 +148,7 @@ function compileAgent(key, registeredPath, registryRoot, actionRuntime) {
|
|
|
148
148
|
reasoningLevel: configuration.reasoningLevel,
|
|
149
149
|
outputType: configuration.outputType ?? "text",
|
|
150
150
|
outputSchema: configuration.outputSchema,
|
|
151
|
-
actions: compileActions(name, sourceDirectory, actionRuntime),
|
|
151
|
+
actions: compileActions(name, sourceDirectory, actionRuntime, target),
|
|
152
152
|
skills: compileSkills(name, sourceDirectory),
|
|
153
153
|
evaluations: compileEvaluations(name, sourceDirectory),
|
|
154
154
|
subagentPolicy: configuration.subagents
|
|
@@ -157,7 +157,7 @@ function compileAgent(key, registeredPath, registryRoot, actionRuntime) {
|
|
|
157
157
|
subagents: Object.freeze({}),
|
|
158
158
|
});
|
|
159
159
|
}
|
|
160
|
-
function compileActions(agentName, sourceDirectory, actionRuntime) {
|
|
160
|
+
function compileActions(agentName, sourceDirectory, actionRuntime, target) {
|
|
161
161
|
const actionsDirectory = resolve(sourceDirectory, "actions");
|
|
162
162
|
if (!existsSync(actionsDirectory)) {
|
|
163
163
|
return {};
|
|
@@ -229,7 +229,7 @@ function compileActions(agentName, sourceDirectory, actionRuntime) {
|
|
|
229
229
|
throw new Error(`Agent "${agentName}" has duplicate action name "${configuration.name}".`);
|
|
230
230
|
}
|
|
231
231
|
const compiledSource = execution === "local"
|
|
232
|
-
? compileLocalAction(agentName, entry.name, actionsDirectory, actionRuntime)
|
|
232
|
+
? compileLocalAction(agentName, entry.name, actionsDirectory, actionRuntime, target)
|
|
233
233
|
: undefined;
|
|
234
234
|
actions[configuration.name] = Object.freeze({
|
|
235
235
|
...configuration,
|
|
@@ -413,7 +413,7 @@ function validateEvaluationConfiguration(agentName, registrationName, configurat
|
|
|
413
413
|
names.add(metric.name);
|
|
414
414
|
}
|
|
415
415
|
}
|
|
416
|
-
function compileLocalAction(agentName, directoryName, actionsDirectory, actionRuntime) {
|
|
416
|
+
function compileLocalAction(agentName, directoryName, actionsDirectory, actionRuntime, target) {
|
|
417
417
|
const entryPath = resolve(actionsDirectory, directoryName, "index.js");
|
|
418
418
|
if (!existsSync(entryPath)) {
|
|
419
419
|
throw new Error(`Local action "${agentName}/${directoryName}" requires index.js.`);
|
|
@@ -426,7 +426,9 @@ function compileLocalAction(agentName, directoryName, actionsDirectory, actionRu
|
|
|
426
426
|
write: false,
|
|
427
427
|
format: "iife",
|
|
428
428
|
globalName: "__orchaActionModule",
|
|
429
|
-
platform: actionRuntime === "native"
|
|
429
|
+
platform: actionRuntime === "native" && target === "node"
|
|
430
|
+
? "node"
|
|
431
|
+
: "browser",
|
|
430
432
|
target: "es2022",
|
|
431
433
|
logLevel: "silent",
|
|
432
434
|
});
|
package/dist/errors.d.ts
CHANGED
|
@@ -9,3 +9,8 @@ export declare class OrchaError extends Error {
|
|
|
9
9
|
cause?: unknown;
|
|
10
10
|
});
|
|
11
11
|
}
|
|
12
|
+
export declare function describeProviderError(error: unknown): {
|
|
13
|
+
message: string;
|
|
14
|
+
details?: Record<string, unknown>;
|
|
15
|
+
};
|
|
16
|
+
export declare function isRetryableProviderConnectionError(error: unknown): boolean;
|
package/dist/errors.js
CHANGED
|
@@ -10,3 +10,105 @@ export class OrchaError extends Error {
|
|
|
10
10
|
this.details = options.details;
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
|
+
export function describeProviderError(error) {
|
|
14
|
+
const rootMessage = errorMessage(error);
|
|
15
|
+
const cause = deepestUsefulCause(error);
|
|
16
|
+
if (!cause) {
|
|
17
|
+
return { message: rootMessage };
|
|
18
|
+
}
|
|
19
|
+
const causeMessage = errorMessage(cause);
|
|
20
|
+
const causeCode = stringOrNumberField(cause, "code");
|
|
21
|
+
const syscall = stringField(cause, "syscall");
|
|
22
|
+
const hostname = stringField(cause, "hostname");
|
|
23
|
+
const explanation = causeMessage !== rootMessage
|
|
24
|
+
? causeMessage
|
|
25
|
+
: causeCode
|
|
26
|
+
? String(causeCode)
|
|
27
|
+
: undefined;
|
|
28
|
+
const details = {
|
|
29
|
+
...(causeCode !== undefined ? { causeCode } : {}),
|
|
30
|
+
...(syscall ? { syscall } : {}),
|
|
31
|
+
...(hostname ? { hostname } : {}),
|
|
32
|
+
...(explanation ? { causeMessage: explanation } : {}),
|
|
33
|
+
};
|
|
34
|
+
return {
|
|
35
|
+
message: explanation ? `${rootMessage}: ${explanation}` : rootMessage,
|
|
36
|
+
...(Object.keys(details).length > 0 ? { details } : {}),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export function isRetryableProviderConnectionError(error) {
|
|
40
|
+
const retryableCodes = new Set([
|
|
41
|
+
"UND_ERR_CONNECT_TIMEOUT",
|
|
42
|
+
"EAI_AGAIN",
|
|
43
|
+
"ENETUNREACH",
|
|
44
|
+
"EHOSTUNREACH",
|
|
45
|
+
"ECONNREFUSED",
|
|
46
|
+
]);
|
|
47
|
+
const pending = [error];
|
|
48
|
+
const visited = new Set();
|
|
49
|
+
while (pending.length > 0 && visited.size < 8) {
|
|
50
|
+
const current = pending.shift();
|
|
51
|
+
if (typeof current !== "object" ||
|
|
52
|
+
current === null ||
|
|
53
|
+
visited.has(current)) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
visited.add(current);
|
|
57
|
+
const record = current;
|
|
58
|
+
if (typeof record.code === "string" &&
|
|
59
|
+
retryableCodes.has(record.code)) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
if (record.cause !== undefined)
|
|
63
|
+
pending.push(record.cause);
|
|
64
|
+
if (Array.isArray(record.errors))
|
|
65
|
+
pending.push(...record.errors);
|
|
66
|
+
}
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
function deepestUsefulCause(error) {
|
|
70
|
+
let current = error;
|
|
71
|
+
let useful;
|
|
72
|
+
const visited = new Set();
|
|
73
|
+
for (let depth = 0; depth < 5; depth += 1) {
|
|
74
|
+
if ((typeof current !== "object" || current === null) ||
|
|
75
|
+
visited.has(current)) {
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
visited.add(current);
|
|
79
|
+
const record = current;
|
|
80
|
+
const next = record.cause ??
|
|
81
|
+
(Array.isArray(record.errors) ? record.errors[0] : undefined);
|
|
82
|
+
if (next === undefined)
|
|
83
|
+
break;
|
|
84
|
+
useful = next;
|
|
85
|
+
current = next;
|
|
86
|
+
}
|
|
87
|
+
return useful;
|
|
88
|
+
}
|
|
89
|
+
function errorMessage(error) {
|
|
90
|
+
if (error instanceof Error && error.message.trim()) {
|
|
91
|
+
return error.message.trim();
|
|
92
|
+
}
|
|
93
|
+
if (typeof error === "object" && error !== null) {
|
|
94
|
+
const message = error.message;
|
|
95
|
+
if (typeof message === "string" && message.trim()) {
|
|
96
|
+
return message.trim();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return String(error);
|
|
100
|
+
}
|
|
101
|
+
function stringField(value, key) {
|
|
102
|
+
if (typeof value !== "object" || value === null)
|
|
103
|
+
return undefined;
|
|
104
|
+
const field = value[key];
|
|
105
|
+
return typeof field === "string" && field.trim() ? field : undefined;
|
|
106
|
+
}
|
|
107
|
+
function stringOrNumberField(value, key) {
|
|
108
|
+
if (typeof value !== "object" || value === null)
|
|
109
|
+
return undefined;
|
|
110
|
+
const field = value[key];
|
|
111
|
+
return typeof field === "string" || typeof field === "number"
|
|
112
|
+
? field
|
|
113
|
+
: undefined;
|
|
114
|
+
}
|
package/dist/file-content.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
|
-
import { basename, extname, resolve } from "node:path";
|
|
3
1
|
const MIME_TYPES = {
|
|
4
2
|
".csv": "text/csv",
|
|
5
3
|
".doc": "application/msword",
|
|
@@ -21,8 +19,8 @@ const MIME_TYPES = {
|
|
|
21
19
|
".xls": "application/vnd.ms-excel",
|
|
22
20
|
".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
23
21
|
};
|
|
24
|
-
export function normalizeLocalFile(filePath, mimeType, projectRoot =
|
|
25
|
-
const absolutePath =
|
|
22
|
+
export function normalizeLocalFile(filePath, mimeType, projectRoot = ".") {
|
|
23
|
+
const absolutePath = resolvePortablePath(projectRoot, filePath);
|
|
26
24
|
return {
|
|
27
25
|
type: "file",
|
|
28
26
|
filePath: absolutePath,
|
|
@@ -47,22 +45,60 @@ export function normalizeUrlContent(url, mimeType) {
|
|
|
47
45
|
};
|
|
48
46
|
}
|
|
49
47
|
export async function readLocalFileContent(content) {
|
|
48
|
+
const fsModule = "node:fs/promises";
|
|
49
|
+
const { readFile } = await import(fsModule);
|
|
50
50
|
const bytes = await readFile(content.filePath);
|
|
51
51
|
const base64 = bytes.toString("base64");
|
|
52
52
|
return {
|
|
53
53
|
bytes,
|
|
54
54
|
base64,
|
|
55
55
|
dataUri: `data:${content.mimeType};base64,${base64}`,
|
|
56
|
-
fileName:
|
|
56
|
+
fileName: portableBasename(content.filePath),
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
59
|
function normalizeMimeType(mimeType, source) {
|
|
60
60
|
if (mimeType?.trim()) {
|
|
61
61
|
return mimeType.trim().toLowerCase();
|
|
62
62
|
}
|
|
63
|
-
const inferred = MIME_TYPES[
|
|
63
|
+
const inferred = MIME_TYPES[portableExtension(source).toLowerCase()];
|
|
64
64
|
if (!inferred) {
|
|
65
65
|
throw new Error(`Could not infer a MIME type for "${source}". Provide mimeType explicitly.`);
|
|
66
66
|
}
|
|
67
67
|
return inferred;
|
|
68
68
|
}
|
|
69
|
+
function resolvePortablePath(root, filePath) {
|
|
70
|
+
if (/^(?:\/|[a-zA-Z]:[\\/])/.test(filePath)) {
|
|
71
|
+
return normalizePath(filePath);
|
|
72
|
+
}
|
|
73
|
+
return normalizePath(`${root.replace(/[\\/]+$/, "")}/${filePath}`);
|
|
74
|
+
}
|
|
75
|
+
function normalizePath(path) {
|
|
76
|
+
const separator = path.includes("\\") ? "\\" : "/";
|
|
77
|
+
const prefix = path.match(/^(?:[a-zA-Z]:)?[\\/]/)?.[0] ?? "";
|
|
78
|
+
const source = prefix ? path.slice(prefix.length) : path;
|
|
79
|
+
const parts = [];
|
|
80
|
+
for (const part of source.split(/[\\/]+/)) {
|
|
81
|
+
if (!part || part === ".") {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (part === "..") {
|
|
85
|
+
if (parts.length > 0 && parts.at(-1) !== "..") {
|
|
86
|
+
parts.pop();
|
|
87
|
+
}
|
|
88
|
+
else if (!prefix) {
|
|
89
|
+
parts.push(part);
|
|
90
|
+
}
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
parts.push(part);
|
|
94
|
+
}
|
|
95
|
+
return `${prefix}${parts.join(separator)}` || ".";
|
|
96
|
+
}
|
|
97
|
+
function portableBasename(path) {
|
|
98
|
+
return path.split(/[\\/]/).at(-1) ?? path;
|
|
99
|
+
}
|
|
100
|
+
function portableExtension(path) {
|
|
101
|
+
const name = portableBasename(path);
|
|
102
|
+
const index = name.lastIndexOf(".");
|
|
103
|
+
return index > 0 ? name.slice(index) : "";
|
|
104
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
export { orcha } from "./orcha.js";
|
|
2
|
-
export
|
|
3
|
-
export type { Orcha, OrchaClient } from "./orcha.js";
|
|
2
|
+
export * from "./runtime-entry.js";
|
|
4
3
|
export { NodeJsonlSessionStore } from "./storage/node-jsonl.js";
|
|
5
4
|
export { NodeSqliteSessionStore } from "./storage/node-sqlite.js";
|
|
6
|
-
export { exportSessionJsonl, migrateSessionStore, } from "./storage/migrate.js";
|
|
7
|
-
export type { SessionStoreMigrationResult, } from "./storage/migrate.js";
|
|
8
|
-
export type { ActionConfiguration, AgentTestActionConfiguration, AgentTestActionExpectation, AgentTestActionResponse, AgentTestAssertionResult, AgentTestCaseConfiguration, AgentTestCaseReport, AgentTestCaseSummary, AgentTestExpectation, AgentTestReport, AgentTestTextExpectation, AgentTestValueExpectation, AgentTestWarning, ApiKeyProviderConfiguration, AwsCredentials, AgentContinueInput, AgentConfiguration, AgentContentInput, AgentInput, AgentRegistration, AgentRuntime, ClientCapability, ClientToolCall, CompletedRunResult, CompiledActionManifest, CompiledAgentManifest, CompiledBundle, CompiledEvaluationManifest, CompiledSkillManifest, EvaluationConfiguration, EvaluationMetricConfiguration, EvaluationMetricResult, EvaluationResult, Execution, ExecutionSnapshot, FailedRunResult, FileContent, FilePathContentInput, LocalFileContent, LocalActionRuntimeConfiguration, MessageContent, MessageContentInput, MetadataValue, OrchaErrorCode, OrchaInitConfiguration, PausedRunResult, PaginationOptions, ProjectConfiguration, ProviderConfiguration, ProviderInitConfigurations, ProviderName, BedrockProviderConfiguration, RunError, RunStatus, RunTestsOptions, ResumeInput, RunResult, SessionEvent, SessionEventListOptions, SessionEvents, SessionEventType, SessionHistory, SessionHistoryItem, SessionList, SessionListOptions, SessionMetadata, SessionSnapshot, SessionStatus, SessionStore, SkillConfiguration, SessionUpdate, StreamingRunSnapshot, SubagentConfiguration, TextContent, ToolResult, ToolResumeInput, UrlContentInput, Usage, VertexAIProviderConfiguration, GoogleServiceAccountCredentials, WaitingRunResult, WaitingForSubagentSnapshot, } from "./types.js";
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export { orcha } from "./orcha.js";
|
|
2
|
-
export
|
|
2
|
+
export * from "./runtime-entry.js";
|
|
3
3
|
export { NodeJsonlSessionStore } from "./storage/node-jsonl.js";
|
|
4
4
|
export { NodeSqliteSessionStore } from "./storage/node-sqlite.js";
|
|
5
|
-
export { exportSessionJsonl, migrateSessionStore, } from "./storage/migrate.js";
|
|
@@ -6,12 +6,15 @@ import { buildProject } from "../compiler/build-project.js";
|
|
|
6
6
|
*/
|
|
7
7
|
export function orchaPlugin(options = {}) {
|
|
8
8
|
const projectRoot = resolve(options.projectRoot ?? process.cwd());
|
|
9
|
-
const generatedBundle = resolve(projectRoot, ".orcha/dist/bundle.js");
|
|
10
9
|
return {
|
|
11
10
|
name: "orchajs",
|
|
12
11
|
setup(builder) {
|
|
12
|
+
const target = builder.initialOptions.platform === "browser"
|
|
13
|
+
? "browser"
|
|
14
|
+
: "node";
|
|
15
|
+
const generatedBundle = resolve(projectRoot, `.orcha/dist/${target === "node" ? "bundle.js" : "bundle.browser.js"}`);
|
|
13
16
|
builder.onStart(async () => {
|
|
14
|
-
await buildProject({ projectRoot });
|
|
17
|
+
await buildProject({ projectRoot, target });
|
|
15
18
|
});
|
|
16
19
|
builder.onResolve({ filter: /^orchajs$/ }, () => ({
|
|
17
20
|
path: generatedBundle,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { withOrchaMetro as withOrchaExpo, type OrchaMetroOptions as OrchaExpoOptions, } from "./metro.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { withOrchaMetro as withOrchaExpo, } from "./metro.js";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface OrchaMetroOptions {
|
|
2
|
+
projectRoot?: string;
|
|
3
|
+
}
|
|
4
|
+
interface MetroResolverContext {
|
|
5
|
+
resolveRequest(context: MetroResolverContext, moduleName: string, platform: string | null): unknown;
|
|
6
|
+
}
|
|
7
|
+
interface MetroConfiguration {
|
|
8
|
+
resolver?: {
|
|
9
|
+
resolveRequest?: MetroResolverContext["resolveRequest"];
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
};
|
|
12
|
+
[key: string]: unknown;
|
|
13
|
+
}
|
|
14
|
+
export declare function withOrchaMetro<T extends MetroConfiguration>(configuration: T, options?: OrchaMetroOptions): Promise<T>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { generatedBundlePath, queueRuntimeBuild, watchRuntimeTargets, } from "./runtime-build.js";
|
|
3
|
+
export async function withOrchaMetro(configuration, options = {}) {
|
|
4
|
+
const projectRoot = resolve(options.projectRoot ?? process.cwd());
|
|
5
|
+
await queueRuntimeBuild(projectRoot, "react-native");
|
|
6
|
+
if (process.env.NODE_ENV !== "production") {
|
|
7
|
+
watchRuntimeTargets(projectRoot, ["react-native"]);
|
|
8
|
+
}
|
|
9
|
+
const existingResolver = configuration.resolver?.resolveRequest;
|
|
10
|
+
return {
|
|
11
|
+
...configuration,
|
|
12
|
+
resolver: {
|
|
13
|
+
...configuration.resolver,
|
|
14
|
+
resolveRequest(context, moduleName, platform) {
|
|
15
|
+
const requestedModule = moduleName === "orchajs"
|
|
16
|
+
? generatedBundlePath(projectRoot, "react-native")
|
|
17
|
+
: moduleName;
|
|
18
|
+
if (existingResolver) {
|
|
19
|
+
return existingResolver(context, requestedModule, platform);
|
|
20
|
+
}
|
|
21
|
+
return context.resolveRequest(context, requestedModule, platform);
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|