orchajs 0.20.2 → 0.21.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 +129 -0
- 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-agents-template.d.ts +1 -1
- package/dist/cli-agents-template.js +22 -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/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 +8 -5
- package/dist/runtime/compiler-hook.d.ts +5 -0
- package/dist/runtime/compiler-hook.js +8 -0
- package/dist/runtime/create-orcha.d.ts +2 -1
- package/dist/runtime/create-orcha.js +15 -19
- 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 +3 -1
- package/dist-cjs/browser.js +48 -0
- package/dist-cjs/cli-agents-template.js +22 -0
- package/dist-cjs/compiler/build-project.js +97 -8
- package/dist-cjs/compiler/compile.js +17 -9
- 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 +8 -6
- package/dist-cjs/runtime/compiler-hook.js +37 -0
- package/dist-cjs/runtime/create-orcha.js +18 -21
- 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/orcha.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
|
-
import { compileRegistry } from "./compiler/compile.js";
|
|
4
3
|
import { generateProviderResponse } from "./providers/index.js";
|
|
5
|
-
import { setSandboxRuntimeLoader } from "./runtime/actions/execute.js";
|
|
4
|
+
import { setNativeRuntimeLoader, setSandboxRuntimeLoader, } from "./runtime/actions/execute.js";
|
|
5
|
+
import { executeNativeAction } from "./runtime/actions/native.js";
|
|
6
|
+
import { getRegistryCompiler } from "./runtime/compiler-hook.js";
|
|
6
7
|
import { createOrcha } from "./runtime/create-orcha.js";
|
|
8
|
+
import { nodeRuntimePlatform } from "./runtime/platform-node.js";
|
|
9
|
+
setNativeRuntimeLoader(async () => ({ executeNativeAction }));
|
|
7
10
|
setSandboxRuntimeLoader(async () => {
|
|
8
11
|
const modulePath = "./runtime/actions/sandbox.js";
|
|
9
12
|
return import(modulePath);
|
|
@@ -12,13 +15,16 @@ export const orcha = createOrcha((configuration) => {
|
|
|
12
15
|
const projectRoot = resolve(configuration.root ??
|
|
13
16
|
process.env.ORCHA_PROJECT_ROOT ??
|
|
14
17
|
process.cwd());
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
const compiler = getRegistryCompiler();
|
|
19
|
+
if (process.env.ORCHA_COMPILING === "1" && compiler) {
|
|
20
|
+
return compiler(configuration, projectRoot);
|
|
21
|
+
}
|
|
22
|
+
if (isPrecompiledRuntime() ||
|
|
23
|
+
existsSync(compiledManifestPath(projectRoot))) {
|
|
17
24
|
return loadCompiledManifest(projectRoot, configuration);
|
|
18
25
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}, generateProviderResponse);
|
|
26
|
+
throw new Error('Orcha agents must be compiled before runtime initialization. Run "npx orcha dev" during development or "npx orcha build" before starting the application.');
|
|
27
|
+
}, generateProviderResponse, nodeRuntimePlatform);
|
|
22
28
|
function isPrecompiledRuntime() {
|
|
23
29
|
return (process.env.ORCHA_USE_BUILD === "1" ||
|
|
24
30
|
process.env.NODE_ENV === "production" ||
|
|
@@ -26,7 +32,7 @@ function isPrecompiledRuntime() {
|
|
|
26
32
|
process.env.AWS_EXECUTION_ENV?.startsWith("AWS_Lambda_") === true);
|
|
27
33
|
}
|
|
28
34
|
function loadCompiledManifest(projectRoot, configuration) {
|
|
29
|
-
const manifestPath =
|
|
35
|
+
const manifestPath = compiledManifestPath(projectRoot);
|
|
30
36
|
if (!existsSync(manifestPath)) {
|
|
31
37
|
throw new Error(`ORCHA_PRODUCTION_BUNDLE_MISSING: "${manifestPath}" was not found. Run "npx orcha build" before packaging, include ".orcha/dist" in the deployment, or configure the Orcha build integration.`);
|
|
32
38
|
}
|
|
@@ -56,3 +62,6 @@ function loadCompiledManifest(projectRoot, configuration) {
|
|
|
56
62
|
}
|
|
57
63
|
return bundle;
|
|
58
64
|
}
|
|
65
|
+
function compiledManifestPath(projectRoot) {
|
|
66
|
+
return resolve(projectRoot, ".orcha/dist/manifest.json");
|
|
67
|
+
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { randomBytes } from "node:crypto";
|
|
3
3
|
import { existsSync } from "node:fs";
|
|
4
|
-
import { readFile } from "node:fs/promises";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { copyFile, mkdir, readFile, writeFile, } from "node:fs/promises";
|
|
5
|
+
import { createRequire } from "node:module";
|
|
6
|
+
import { extname, isAbsolute, relative, resolve } from "node:path";
|
|
7
7
|
import { createServer, } from "node:http";
|
|
8
8
|
import { watch } from "chokidar";
|
|
9
|
+
import { build } from "esbuild";
|
|
9
10
|
import { orcha } from "../orcha.js";
|
|
10
11
|
import { loadProject } from "../project-loader.js";
|
|
11
12
|
import { listTests, runTests } from "../testing.js";
|
|
@@ -20,6 +21,7 @@ export async function startPlayground(options = {}) {
|
|
|
20
21
|
const mutationToken = randomBytes(32).toString("base64url");
|
|
21
22
|
const allowedHosts = playgroundHosts(host, port);
|
|
22
23
|
await loadProject(projectRoot);
|
|
24
|
+
const publicRoot = await buildPlaygroundAssets(projectRoot);
|
|
23
25
|
const projectClients = new Set();
|
|
24
26
|
const server = createServer(async (request, response) => {
|
|
25
27
|
try {
|
|
@@ -32,6 +34,7 @@ export async function startPlayground(options = {}) {
|
|
|
32
34
|
projectClients,
|
|
33
35
|
mutationToken,
|
|
34
36
|
allowedHosts,
|
|
37
|
+
publicRoot,
|
|
35
38
|
});
|
|
36
39
|
}
|
|
37
40
|
catch (error) {
|
|
@@ -312,7 +315,7 @@ async function routeRequest(context) {
|
|
|
312
315
|
return;
|
|
313
316
|
}
|
|
314
317
|
if (method === "GET") {
|
|
315
|
-
await serveAsset(response, url.pathname);
|
|
318
|
+
await serveAsset(response, url.pathname, context.publicRoot);
|
|
316
319
|
return;
|
|
317
320
|
}
|
|
318
321
|
sendJson(response, 404, { error: "Not found." });
|
|
@@ -444,8 +447,7 @@ async function readAllEventPages(read) {
|
|
|
444
447
|
}
|
|
445
448
|
return pages.flat();
|
|
446
449
|
}
|
|
447
|
-
async function serveAsset(response, pathname) {
|
|
448
|
-
const publicRoot = resolve(dirname(fileURLToPath(import.meta.url)), "public");
|
|
450
|
+
async function serveAsset(response, pathname, publicRoot) {
|
|
449
451
|
const requested = pathname === "/" ? "index.html" : pathname.slice(1);
|
|
450
452
|
const path = resolve(publicRoot, requested);
|
|
451
453
|
const relativePath = relative(publicRoot, path);
|
|
@@ -455,7 +457,7 @@ async function serveAsset(response, pathname) {
|
|
|
455
457
|
const indexPath = resolve(publicRoot, "index.html");
|
|
456
458
|
if (!existsSync(indexPath)) {
|
|
457
459
|
sendJson(response, 503, {
|
|
458
|
-
error: "Playground assets are missing.
|
|
460
|
+
error: "Playground assets are missing. Restart the Orcha playground.",
|
|
459
461
|
});
|
|
460
462
|
return;
|
|
461
463
|
}
|
|
@@ -472,6 +474,54 @@ async function serveAsset(response, pathname) {
|
|
|
472
474
|
});
|
|
473
475
|
response.end(await readFile(path));
|
|
474
476
|
}
|
|
477
|
+
async function buildPlaygroundAssets(projectRoot) {
|
|
478
|
+
const require = createRequire(import.meta.url);
|
|
479
|
+
let entryPath;
|
|
480
|
+
let logoPath;
|
|
481
|
+
try {
|
|
482
|
+
entryPath = require.resolve("@orchajs/playground-ui/mount");
|
|
483
|
+
logoPath = require.resolve("@orchajs/playground-ui/orcha-logo.svg");
|
|
484
|
+
}
|
|
485
|
+
catch (error) {
|
|
486
|
+
throw new Error('The playground requires the optional "@orchajs/playground-ui" package. Install it as a development dependency.', { cause: error });
|
|
487
|
+
}
|
|
488
|
+
const publicRoot = resolve(projectRoot, ".orcha/playground");
|
|
489
|
+
await mkdir(publicRoot, { recursive: true });
|
|
490
|
+
await Promise.all([
|
|
491
|
+
build({
|
|
492
|
+
entryPoints: [entryPath],
|
|
493
|
+
outfile: resolve(publicRoot, "app.js"),
|
|
494
|
+
bundle: true,
|
|
495
|
+
format: "esm",
|
|
496
|
+
platform: "browser",
|
|
497
|
+
target: ["chrome110", "firefox110", "safari16"],
|
|
498
|
+
minify: true,
|
|
499
|
+
sourcemap: false,
|
|
500
|
+
legalComments: "none",
|
|
501
|
+
define: {
|
|
502
|
+
"process.env.NODE_ENV": JSON.stringify("production"),
|
|
503
|
+
},
|
|
504
|
+
}),
|
|
505
|
+
copyFile(logoPath, resolve(publicRoot, "orcha-logo.svg")),
|
|
506
|
+
writeFile(resolve(publicRoot, "index.html"), `<!doctype html>
|
|
507
|
+
<html lang="en">
|
|
508
|
+
<head>
|
|
509
|
+
<meta charset="UTF-8" />
|
|
510
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
511
|
+
<meta name="color-scheme" content="light" />
|
|
512
|
+
<link rel="icon" href="/orcha-logo.svg" type="image/svg+xml" />
|
|
513
|
+
<title>Orcha Playground</title>
|
|
514
|
+
<link rel="stylesheet" href="/app.css" />
|
|
515
|
+
</head>
|
|
516
|
+
<body>
|
|
517
|
+
<div id="root"></div>
|
|
518
|
+
<script type="module" src="/app.js"></script>
|
|
519
|
+
</body>
|
|
520
|
+
</html>
|
|
521
|
+
`, "utf8"),
|
|
522
|
+
]);
|
|
523
|
+
return publicRoot;
|
|
524
|
+
}
|
|
475
525
|
function contentType(path) {
|
|
476
526
|
switch (extname(path)) {
|
|
477
527
|
case ".html":
|
package/dist/project-loader.js
CHANGED
|
@@ -3,9 +3,12 @@ import { mkdir, rm } from "node:fs/promises";
|
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
import { pathToFileURL } from "node:url";
|
|
5
5
|
import { build as bundleEntry } from "esbuild";
|
|
6
|
+
import { compileRegistry } from "./compiler/compile.js";
|
|
6
7
|
import { loadProjectEnvironment } from "./env.js";
|
|
7
8
|
import { orcha } from "./orcha.js";
|
|
9
|
+
import { setRegistryCompiler } from "./runtime/compiler-hook.js";
|
|
8
10
|
export async function loadProject(projectRoot) {
|
|
11
|
+
setRegistryCompiler((configuration, compilerProjectRoot) => compileRegistry(configuration.agents, resolve(compilerProjectRoot, "orcha"), configuration.actions?.runtime ?? "native", "node"));
|
|
9
12
|
loadProjectEnvironment(projectRoot);
|
|
10
13
|
const registryPath = resolve(projectRoot, "orcha/index.ts");
|
|
11
14
|
if (!existsSync(registryPath)) {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { OrchaError } from "../errors.js";
|
|
2
|
+
const loadedProviders = new Map();
|
|
3
|
+
const loaders = {
|
|
4
|
+
anthropic: () => import("./anthropic.js").then((module) => module.anthropicProvider),
|
|
5
|
+
deepseek: () => import("./deepseek.js").then((module) => module.deepSeekProvider),
|
|
6
|
+
googlegenai: () => import("./google-genai.js").then((module) => module.googleGenAIProvider),
|
|
7
|
+
openai: () => import("./openai.js").then((module) => module.openAIProvider),
|
|
8
|
+
};
|
|
9
|
+
export const generateBrowserProviderResponse = async (name, configuration, request) => {
|
|
10
|
+
const loader = loaders[name];
|
|
11
|
+
if (!loader) {
|
|
12
|
+
throw new OrchaError("provider_error", `Provider "${name}" is not available in browser or React Native runtimes.`);
|
|
13
|
+
}
|
|
14
|
+
let provider = loadedProviders.get(name);
|
|
15
|
+
if (!provider) {
|
|
16
|
+
provider = loader();
|
|
17
|
+
loadedProviders.set(name, provider);
|
|
18
|
+
}
|
|
19
|
+
return (await provider).generate(configuration, request);
|
|
20
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { generateBrowserProviderResponse } from "./providers/browser.js";
|
|
2
|
+
import { setNativeRuntimeLoader } from "./runtime/actions/execute.js";
|
|
3
|
+
import { createOrcha } from "./runtime/create-orcha.js";
|
|
4
|
+
import { reactNativeRuntimePlatform } from "./runtime/platform-react-native.js";
|
|
5
|
+
setNativeRuntimeLoader(async () => {
|
|
6
|
+
const modulePath = "./runtime/actions/browser-native.js";
|
|
7
|
+
return import(modulePath);
|
|
8
|
+
});
|
|
9
|
+
export const orcha = createOrcha(() => {
|
|
10
|
+
throw new Error("The React Native runtime requires a precompiled Orcha bundle. Configure the Orcha Metro integration.");
|
|
11
|
+
}, generateBrowserProviderResponse, reactNativeRuntimePlatform);
|
|
12
|
+
export * from "./runtime-entry.js";
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { CompiledActionManifest } from "../../types.js";
|
|
2
|
+
import type { LocalActionContext } from "./context.js";
|
|
3
|
+
export declare function executeNativeAction(action: CompiledActionManifest, parameters: Record<string, unknown>, context: LocalActionContext): Promise<unknown>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export async function executeNativeAction(action, parameters, context) {
|
|
2
|
+
if (!action.source) {
|
|
3
|
+
throw new Error(`Action "${action.name}" has no compiled source.`);
|
|
4
|
+
}
|
|
5
|
+
if (/\brequire\s*\(/.test(action.source)) {
|
|
6
|
+
throw new Error(`Browser action "${action.name}" contains a Node.js require() call. Rebuild it for the browser target.`);
|
|
7
|
+
}
|
|
8
|
+
const loadAction = new Function(`"use strict";\n${action.source}\nreturn __orchaActionModule.default;`);
|
|
9
|
+
const executable = loadAction();
|
|
10
|
+
if (typeof executable !== "function") {
|
|
11
|
+
throw new Error(`Action "${action.name}" index.js must export a default function.`);
|
|
12
|
+
}
|
|
13
|
+
const timeoutMs = action.timeoutMs ?? 10_000;
|
|
14
|
+
let timeout;
|
|
15
|
+
try {
|
|
16
|
+
return await Promise.race([
|
|
17
|
+
Promise.resolve(executable(parameters, context)),
|
|
18
|
+
new Promise((_resolve, reject) => {
|
|
19
|
+
timeout = setTimeout(() => reject(new Error(`Action timed out after ${timeoutMs}ms.`)), timeoutMs);
|
|
20
|
+
}),
|
|
21
|
+
]);
|
|
22
|
+
}
|
|
23
|
+
finally {
|
|
24
|
+
if (timeout) {
|
|
25
|
+
clearTimeout(timeout);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import type { CompiledActionManifest, LocalActionRuntimeConfiguration, SessionMetadata } from "../../types.js";
|
|
2
|
+
import { type LocalActionContext } from "./context.js";
|
|
2
3
|
type SandboxRuntime = typeof import("./sandbox.js");
|
|
3
4
|
type SandboxRuntimeLoader = () => Promise<SandboxRuntime>;
|
|
5
|
+
interface NativeRuntime {
|
|
6
|
+
executeNativeAction(action: CompiledActionManifest, parameters: Record<string, unknown>, context: LocalActionContext): Promise<unknown>;
|
|
7
|
+
}
|
|
8
|
+
type NativeRuntimeLoader = () => Promise<NativeRuntime>;
|
|
4
9
|
/** @internal Supplies the statically bundled sandbox in production builds. */
|
|
5
10
|
export declare function setSandboxRuntimeLoader(loader: SandboxRuntimeLoader): void;
|
|
11
|
+
/** @internal Supplies the platform-specific native action executor. */
|
|
12
|
+
export declare function setNativeRuntimeLoader(loader: NativeRuntimeLoader): void;
|
|
6
13
|
export declare function executeLocalAction(options: {
|
|
7
14
|
action: CompiledActionManifest;
|
|
8
15
|
parameters: Record<string, unknown>;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { createLocalActionContext } from "./context.js";
|
|
2
|
-
|
|
1
|
+
import { createLocalActionContext, } from "./context.js";
|
|
2
|
+
let loadConfiguredNativeRuntime = async () => {
|
|
3
|
+
throw new Error("The native action runtime was not included in this Orcha build.");
|
|
4
|
+
};
|
|
3
5
|
let loadConfiguredSandboxRuntime = async () => {
|
|
4
6
|
throw new Error("The QuickJS sandbox runtime was not included in this Orcha build.");
|
|
5
7
|
};
|
|
@@ -7,9 +9,14 @@ let loadConfiguredSandboxRuntime = async () => {
|
|
|
7
9
|
export function setSandboxRuntimeLoader(loader) {
|
|
8
10
|
loadConfiguredSandboxRuntime = loader;
|
|
9
11
|
}
|
|
12
|
+
/** @internal Supplies the platform-specific native action executor. */
|
|
13
|
+
export function setNativeRuntimeLoader(loader) {
|
|
14
|
+
loadConfiguredNativeRuntime = loader;
|
|
15
|
+
}
|
|
10
16
|
export async function executeLocalAction(options) {
|
|
11
17
|
const context = createLocalActionContext(options);
|
|
12
18
|
if (options.configuration.runtime === "native") {
|
|
19
|
+
const { executeNativeAction } = await loadConfiguredNativeRuntime();
|
|
13
20
|
return executeNativeAction(options.action, options.parameters, context);
|
|
14
21
|
}
|
|
15
22
|
if (process.env.ORCHA_INCLUDE_SANDBOX !== "0") {
|
package/dist/runtime/agent.d.ts
CHANGED
package/dist/runtime/agent.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { randomUUID } from "node:crypto";
|
|
2
1
|
import { OrchaError } from "../errors.js";
|
|
3
2
|
import { normalizeLocalFile, normalizeUrlContent, } from "../file-content.js";
|
|
4
3
|
import { messagesFromEvents, normalizePersistedToolResults, SessionEventWriter, } from "./session-events.js";
|
|
5
4
|
import { validateStructuredValue } from "./structured-output.js";
|
|
6
5
|
import { executeLocalAction } from "./actions/execute.js";
|
|
7
6
|
import { createExecution, } from "./execution.js";
|
|
7
|
+
import { portableRandomUUID } from "./random-id.js";
|
|
8
8
|
const LOAD_SKILL_TOOL_NAME = "load_skill";
|
|
9
9
|
const RUN_AGENT_TOOL_NAME = "run_agent";
|
|
10
10
|
const RESUME_AGENT_TOOL_NAME = "resume_agent";
|
|
@@ -27,6 +27,7 @@ export class RuntimeAgent {
|
|
|
27
27
|
#agentKey;
|
|
28
28
|
#sessionIdPrefix;
|
|
29
29
|
#projectRoot;
|
|
30
|
+
#randomUUID;
|
|
30
31
|
#evaluationTasks = new Map();
|
|
31
32
|
#sessionIdleWaiters = new Map();
|
|
32
33
|
constructor(options) {
|
|
@@ -40,7 +41,8 @@ export class RuntimeAgent {
|
|
|
40
41
|
this.#delegatedOnly = options.delegatedOnly ?? false;
|
|
41
42
|
this.#agentKey = options.manifest.key ?? options.manifest.name;
|
|
42
43
|
this.#sessionIdPrefix = options.sessionIdPrefix ?? "ses_";
|
|
43
|
-
this.#projectRoot = options.projectRoot ??
|
|
44
|
+
this.#projectRoot = options.projectRoot ?? ".";
|
|
45
|
+
this.#randomUUID = options.randomUUID ?? portableRandomUUID;
|
|
44
46
|
}
|
|
45
47
|
get agent() {
|
|
46
48
|
return this.#agentKey;
|
|
@@ -65,7 +67,7 @@ export class RuntimeAgent {
|
|
|
65
67
|
return this.#run(input);
|
|
66
68
|
}
|
|
67
69
|
createDelegatedSessionId() {
|
|
68
|
-
return createSessionId(this.#sessionIdPrefix);
|
|
70
|
+
return createSessionId(this.#sessionIdPrefix, this.#randomUUID);
|
|
69
71
|
}
|
|
70
72
|
runAsChild(sessionId, input, lineage) {
|
|
71
73
|
const normalized = typeof input === "string" ? { content: input } : input;
|
|
@@ -76,7 +78,8 @@ export class RuntimeAgent {
|
|
|
76
78
|
}
|
|
77
79
|
#run(input, lineage, requestedSessionId) {
|
|
78
80
|
const normalized = typeof input === "string" ? { content: input } : input;
|
|
79
|
-
const sessionId = requestedSessionId ??
|
|
81
|
+
const sessionId = requestedSessionId ??
|
|
82
|
+
createSessionId(this.#sessionIdPrefix, this.#randomUUID);
|
|
80
83
|
if (typeof normalized === "object" &&
|
|
81
84
|
normalized !== null &&
|
|
82
85
|
"sessionId" in normalized) {
|
|
@@ -1836,7 +1839,7 @@ function normalizeMetadata(metadata) {
|
|
|
1836
1839
|
}
|
|
1837
1840
|
return normalized;
|
|
1838
1841
|
}
|
|
1839
|
-
function createSessionId(prefix) {
|
|
1842
|
+
function createSessionId(prefix, randomUUID) {
|
|
1840
1843
|
const utcTimestamp = new Date()
|
|
1841
1844
|
.toISOString()
|
|
1842
1845
|
.replace(/\.\d{3}Z$/, "")
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { CompiledBundle, OrchaInitConfiguration } from "../types.js";
|
|
2
|
+
export type RegistryCompiler = (configuration: OrchaInitConfiguration, projectRoot: string) => CompiledBundle;
|
|
3
|
+
/** @internal Installed by Node development tooling, never by runtime bundles. */
|
|
4
|
+
export declare function setRegistryCompiler(compiler: RegistryCompiler): void;
|
|
5
|
+
export declare function getRegistryCompiler(): RegistryCompiler | undefined;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ProviderResponseGenerator } from "../providers/types.js";
|
|
2
|
+
import type { RuntimePlatform } from "./platform.js";
|
|
2
3
|
import type { AgentRuntime, CompiledBundle, OrchaInitConfiguration } from "../types.js";
|
|
3
4
|
export interface Orcha {
|
|
4
5
|
init(configuration: OrchaInitConfiguration): OrchaClient;
|
|
@@ -8,4 +9,4 @@ export interface Orcha {
|
|
|
8
9
|
}
|
|
9
10
|
export type OrchaClient = Orcha & Record<string, AgentRuntime>;
|
|
10
11
|
export type BundleResolver = (configuration: OrchaInitConfiguration) => CompiledBundle;
|
|
11
|
-
export declare function createOrcha(resolveBundle: BundleResolver, generateProviderResponse: ProviderResponseGenerator): OrchaClient;
|
|
12
|
+
export declare function createOrcha(resolveBundle: BundleResolver, generateProviderResponse: ProviderResponseGenerator, platform: RuntimePlatform): OrchaClient;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import { resolve } from "node:path";
|
|
2
1
|
import { RuntimeAgent } from "./agent.js";
|
|
3
|
-
import { createSessionStore } from "../storage/create-store.js";
|
|
4
|
-
import { syncAmarsiaProject } from "../amarsia/sync.js";
|
|
5
2
|
import { setOrchaRuntimeContext } from "./context.js";
|
|
6
3
|
class OrchaRuntimeCore {
|
|
7
4
|
#agents = new Map();
|
|
@@ -11,22 +8,21 @@ class OrchaRuntimeCore {
|
|
|
11
8
|
#sessionControls = new Map();
|
|
12
9
|
#resolveBundle;
|
|
13
10
|
#generateProviderResponse;
|
|
14
|
-
|
|
11
|
+
#platform;
|
|
12
|
+
constructor(resolveBundle, generateProviderResponse, platform) {
|
|
15
13
|
this.#resolveBundle = resolveBundle;
|
|
16
14
|
this.#generateProviderResponse = generateProviderResponse;
|
|
15
|
+
this.#platform = platform;
|
|
17
16
|
}
|
|
18
17
|
attachClient(client) {
|
|
19
18
|
this.#client = client;
|
|
20
19
|
}
|
|
21
20
|
init(configuration) {
|
|
22
|
-
const projectRoot =
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
syncAmarsiaProject({
|
|
28
|
-
key: configuration.amarsia.key,
|
|
29
|
-
endpoint: configuration.amarsia.endpoint,
|
|
21
|
+
const projectRoot = this.#platform.projectRoot(configuration);
|
|
22
|
+
const bundle = configuration.bundle ?? this.#resolveBundle(configuration);
|
|
23
|
+
if (configuration.amarsia?.key && this.#platform.syncProject) {
|
|
24
|
+
this.#platform.syncProject({
|
|
25
|
+
configuration,
|
|
30
26
|
bundle,
|
|
31
27
|
projectRoot,
|
|
32
28
|
});
|
|
@@ -46,12 +42,10 @@ class OrchaRuntimeCore {
|
|
|
46
42
|
runtimeConfiguration.actions?.runtime !== bundle.actionRuntime) {
|
|
47
43
|
throw new Error(`Production bundle expects local action runtime "${bundle.actionRuntime}".`);
|
|
48
44
|
}
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
strategy: configuration.storage?.strategy,
|
|
52
|
-
directory: storageDirectory,
|
|
45
|
+
const createStore = (manifest) => this.#platform.createSessionStore({
|
|
46
|
+
configuration,
|
|
53
47
|
projectRoot,
|
|
54
|
-
|
|
48
|
+
manifest,
|
|
55
49
|
});
|
|
56
50
|
const agents = new Map();
|
|
57
51
|
for (const [name, manifest] of Object.entries(bundle.agents)) {
|
|
@@ -66,6 +60,7 @@ class OrchaRuntimeCore {
|
|
|
66
60
|
generateProviderResponse: this.#generateProviderResponse,
|
|
67
61
|
delegatedOnly: true,
|
|
68
62
|
projectRoot,
|
|
63
|
+
randomUUID: this.#platform.randomUUID,
|
|
69
64
|
}),
|
|
70
65
|
]));
|
|
71
66
|
agents.set(name, new RuntimeAgent({
|
|
@@ -77,6 +72,7 @@ class OrchaRuntimeCore {
|
|
|
77
72
|
generateProviderResponse: this.#generateProviderResponse,
|
|
78
73
|
subagents,
|
|
79
74
|
projectRoot,
|
|
75
|
+
randomUUID: this.#platform.randomUUID,
|
|
80
76
|
}));
|
|
81
77
|
}
|
|
82
78
|
this.#bundle = bundle;
|
|
@@ -103,8 +99,8 @@ class OrchaRuntimeCore {
|
|
|
103
99
|
return this.#agents.get(name);
|
|
104
100
|
}
|
|
105
101
|
}
|
|
106
|
-
export function createOrcha(resolveBundle, generateProviderResponse) {
|
|
107
|
-
const core = new OrchaRuntimeCore(resolveBundle, generateProviderResponse);
|
|
102
|
+
export function createOrcha(resolveBundle, generateProviderResponse, platform) {
|
|
103
|
+
const core = new OrchaRuntimeCore(resolveBundle, generateProviderResponse, platform);
|
|
108
104
|
const client = new Proxy(core, {
|
|
109
105
|
get(target, property) {
|
|
110
106
|
if (typeof property === "string") {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BrowserIndexedDbSessionStore } from "../storage/browser-indexeddb.js";
|
|
2
|
+
import { portableRandomUUID } from "./random-id.js";
|
|
3
|
+
export const browserRuntimePlatform = {
|
|
4
|
+
randomUUID: portableRandomUUID,
|
|
5
|
+
projectRoot(configuration) {
|
|
6
|
+
return configuration.root ?? "/";
|
|
7
|
+
},
|
|
8
|
+
createSessionStore({ configuration, manifest }) {
|
|
9
|
+
const strategy = configuration.storage?.strategy ?? "indexeddb";
|
|
10
|
+
if (strategy !== "indexeddb") {
|
|
11
|
+
throw new Error(`Browser runtimes require storage strategy "indexeddb", received "${strategy}".`);
|
|
12
|
+
}
|
|
13
|
+
return new BrowserIndexedDbSessionStore(manifest.key ?? manifest.name, configuration.storage?.directory ?? "orchajs");
|
|
14
|
+
},
|
|
15
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { syncAmarsiaProject } from "../amarsia/sync.js";
|
|
4
|
+
import { createSessionStore } from "../storage/create-store.js";
|
|
5
|
+
export const nodeRuntimePlatform = {
|
|
6
|
+
randomUUID,
|
|
7
|
+
projectRoot(configuration) {
|
|
8
|
+
return resolve(configuration.root ??
|
|
9
|
+
process.env.ORCHA_PROJECT_ROOT ??
|
|
10
|
+
process.cwd());
|
|
11
|
+
},
|
|
12
|
+
createSessionStore({ configuration, projectRoot, manifest }) {
|
|
13
|
+
return createSessionStore({
|
|
14
|
+
strategy: configuration.storage?.strategy,
|
|
15
|
+
directory: configuration.storage?.directory,
|
|
16
|
+
projectRoot,
|
|
17
|
+
agentName: manifest.key ?? manifest.name,
|
|
18
|
+
});
|
|
19
|
+
},
|
|
20
|
+
syncProject({ configuration, bundle, projectRoot }) {
|
|
21
|
+
if (!configuration.amarsia?.key) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
syncAmarsiaProject({
|
|
25
|
+
key: configuration.amarsia.key,
|
|
26
|
+
endpoint: configuration.amarsia.endpoint,
|
|
27
|
+
bundle,
|
|
28
|
+
projectRoot,
|
|
29
|
+
});
|
|
30
|
+
},
|
|
31
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ReactNativeJsonlSessionStore } from "../storage/react-native-jsonl.js";
|
|
2
|
+
import { portableRandomUUID } from "./random-id.js";
|
|
3
|
+
export const reactNativeRuntimePlatform = {
|
|
4
|
+
randomUUID: portableRandomUUID,
|
|
5
|
+
projectRoot(configuration) {
|
|
6
|
+
return configuration.root ?? "/";
|
|
7
|
+
},
|
|
8
|
+
createSessionStore({ configuration, manifest }) {
|
|
9
|
+
const strategy = configuration.storage?.strategy ?? "react-native";
|
|
10
|
+
if (strategy !== "react-native") {
|
|
11
|
+
throw new Error(`React Native requires storage strategy "react-native", received "${strategy}".`);
|
|
12
|
+
}
|
|
13
|
+
return new ReactNativeJsonlSessionStore(manifest.key ?? manifest.name);
|
|
14
|
+
},
|
|
15
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CompiledAgentManifest, CompiledBundle, OrchaInitConfiguration, SessionStore } from "../types.js";
|
|
2
|
+
export interface RuntimePlatform {
|
|
3
|
+
randomUUID(): string;
|
|
4
|
+
projectRoot(configuration: OrchaInitConfiguration): string;
|
|
5
|
+
createSessionStore(options: {
|
|
6
|
+
configuration: OrchaInitConfiguration;
|
|
7
|
+
projectRoot: string;
|
|
8
|
+
manifest: CompiledAgentManifest;
|
|
9
|
+
}): SessionStore;
|
|
10
|
+
syncProject?(options: {
|
|
11
|
+
configuration: OrchaInitConfiguration;
|
|
12
|
+
bundle: CompiledBundle;
|
|
13
|
+
projectRoot: string;
|
|
14
|
+
}): void;
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function portableRandomUUID(): string;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
let fallbackSequence = 0;
|
|
2
|
+
export function portableRandomUUID() {
|
|
3
|
+
const crypto = globalThis.crypto;
|
|
4
|
+
if (typeof crypto?.randomUUID === "function") {
|
|
5
|
+
return crypto.randomUUID();
|
|
6
|
+
}
|
|
7
|
+
if (typeof crypto?.getRandomValues === "function") {
|
|
8
|
+
return formatUuid(crypto.getRandomValues(new Uint8Array(16)));
|
|
9
|
+
}
|
|
10
|
+
fallbackSequence = (fallbackSequence + 1) >>> 0;
|
|
11
|
+
const bytes = new Uint8Array(16);
|
|
12
|
+
let state = Date.now() ^
|
|
13
|
+
fallbackSequence ^
|
|
14
|
+
Math.floor(Math.random() * 0x1_0000_0000);
|
|
15
|
+
for (let index = 0; index < bytes.length; index += 1) {
|
|
16
|
+
state = (Math.imul(state, 1_664_525) + 1_013_904_223) >>> 0;
|
|
17
|
+
bytes[index] = state >>> 24;
|
|
18
|
+
}
|
|
19
|
+
return formatUuid(bytes);
|
|
20
|
+
}
|
|
21
|
+
function formatUuid(bytes) {
|
|
22
|
+
bytes[6] = (bytes[6] & 0x0f) | 0x40;
|
|
23
|
+
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
|
24
|
+
const value = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
25
|
+
return `${value.slice(0, 8)}-${value.slice(8, 12)}-${value.slice(12, 16)}-${value.slice(16, 20)}-${value.slice(20)}`;
|
|
26
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { OrchaError } from "./errors.js";
|
|
2
|
+
export type { Orcha, OrchaClient, } from "./runtime/create-orcha.js";
|
|
3
|
+
export { exportSessionJsonl, migrateSessionStore, } from "./storage/migrate.js";
|
|
4
|
+
export type { SessionStoreMigrationResult, } from "./storage/migrate.js";
|
|
5
|
+
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";
|
|
@@ -1,20 +1,11 @@
|
|
|
1
1
|
import type { SessionEvent, SessionStore } from "../types.js";
|
|
2
|
-
/**
|
|
3
|
-
* Future browser storage strategy.
|
|
4
|
-
*
|
|
5
|
-
* It will persist the same ordered SessionEvent records used by the JSONL
|
|
6
|
-
* strategy in IndexedDB. Import and export will preserve the canonical JSONL
|
|
7
|
-
* representation so a session can move between browser, Node, and remote
|
|
8
|
-
* stores without changing the runtime or replay engine.
|
|
9
|
-
*
|
|
10
|
-
* Required before implementation:
|
|
11
|
-
* - transactional sequence allocation;
|
|
12
|
-
* - multi-tab writer coordination;
|
|
13
|
-
* - quota and eviction handling;
|
|
14
|
-
* - schema migrations and JSONL import/export.
|
|
15
|
-
*/
|
|
16
2
|
export declare class BrowserIndexedDbSessionStore implements SessionStore {
|
|
17
|
-
|
|
18
|
-
|
|
3
|
+
#private;
|
|
4
|
+
constructor(namespace: string, databaseName?: string);
|
|
5
|
+
read(sessionId: string): Promise<SessionEvent[]>;
|
|
6
|
+
append(sessionId: string, events: SessionEvent[]): Promise<void>;
|
|
19
7
|
listSessionIds(): Promise<string[]>;
|
|
8
|
+
subscribe(sessionId: string, listener: (events: SessionEvent[]) => void): () => void;
|
|
9
|
+
subscribeAll(listener: (sessionId: string, events: SessionEvent[]) => void): () => void;
|
|
10
|
+
describeLocation(sessionId: string): Promise<string>;
|
|
20
11
|
}
|