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
|
@@ -1,25 +1,108 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
* It will persist the same ordered SessionEvent records used by the JSONL
|
|
5
|
-
* strategy in IndexedDB. Import and export will preserve the canonical JSONL
|
|
6
|
-
* representation so a session can move between browser, Node, and remote
|
|
7
|
-
* stores without changing the runtime or replay engine.
|
|
8
|
-
*
|
|
9
|
-
* Required before implementation:
|
|
10
|
-
* - transactional sequence allocation;
|
|
11
|
-
* - multi-tab writer coordination;
|
|
12
|
-
* - quota and eviction handling;
|
|
13
|
-
* - schema migrations and JSONL import/export.
|
|
14
|
-
*/
|
|
1
|
+
const DATABASE_VERSION = 1;
|
|
2
|
+
const EVENT_STORE = "events";
|
|
15
3
|
export class BrowserIndexedDbSessionStore {
|
|
16
|
-
|
|
17
|
-
|
|
4
|
+
#databaseName;
|
|
5
|
+
#namespace;
|
|
6
|
+
#listeners = new Map();
|
|
7
|
+
#allListeners = new Set();
|
|
8
|
+
constructor(namespace, databaseName = "orchajs") {
|
|
9
|
+
this.#namespace = namespace;
|
|
10
|
+
this.#databaseName = databaseName;
|
|
18
11
|
}
|
|
19
|
-
async
|
|
20
|
-
|
|
12
|
+
async read(sessionId) {
|
|
13
|
+
const database = await this.#open();
|
|
14
|
+
const transaction = database.transaction(EVENT_STORE, "readonly");
|
|
15
|
+
const index = transaction.objectStore(EVENT_STORE).index("session");
|
|
16
|
+
const records = await request(index.getAll(IDBKeyRange.only([this.#namespace, sessionId])));
|
|
17
|
+
await transactionComplete(transaction);
|
|
18
|
+
return records
|
|
19
|
+
.sort((left, right) => left.sequence - right.sequence)
|
|
20
|
+
.map((record) => record.event);
|
|
21
|
+
}
|
|
22
|
+
async append(sessionId, events) {
|
|
23
|
+
if (events.length === 0) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const database = await this.#open();
|
|
27
|
+
const transaction = database.transaction(EVENT_STORE, "readwrite");
|
|
28
|
+
const store = transaction.objectStore(EVENT_STORE);
|
|
29
|
+
for (const event of events) {
|
|
30
|
+
store.add({
|
|
31
|
+
id: eventId(this.#namespace, sessionId, event.sequence),
|
|
32
|
+
namespace: this.#namespace,
|
|
33
|
+
sessionId,
|
|
34
|
+
sequence: event.sequence,
|
|
35
|
+
event,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
await transactionComplete(transaction);
|
|
39
|
+
this.#listeners.get(sessionId)?.forEach((listener) => listener(events));
|
|
40
|
+
this.#allListeners.forEach((listener) => listener(sessionId, events));
|
|
21
41
|
}
|
|
22
42
|
async listSessionIds() {
|
|
23
|
-
|
|
43
|
+
const database = await this.#open();
|
|
44
|
+
const transaction = database.transaction(EVENT_STORE, "readonly");
|
|
45
|
+
const index = transaction.objectStore(EVENT_STORE).index("namespace");
|
|
46
|
+
const records = await request(index.getAll(IDBKeyRange.only(this.#namespace)));
|
|
47
|
+
await transactionComplete(transaction);
|
|
48
|
+
return [...new Set(records.map((record) => record.sessionId))].sort();
|
|
49
|
+
}
|
|
50
|
+
subscribe(sessionId, listener) {
|
|
51
|
+
const listeners = this.#listeners.get(sessionId) ?? new Set();
|
|
52
|
+
listeners.add(listener);
|
|
53
|
+
this.#listeners.set(sessionId, listeners);
|
|
54
|
+
return () => {
|
|
55
|
+
listeners.delete(listener);
|
|
56
|
+
if (listeners.size === 0) {
|
|
57
|
+
this.#listeners.delete(sessionId);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
subscribeAll(listener) {
|
|
62
|
+
this.#allListeners.add(listener);
|
|
63
|
+
return () => this.#allListeners.delete(listener);
|
|
64
|
+
}
|
|
65
|
+
async describeLocation(sessionId) {
|
|
66
|
+
return `indexeddb://${this.#databaseName}/${this.#namespace}/${sessionId}`;
|
|
24
67
|
}
|
|
68
|
+
#open() {
|
|
69
|
+
if (typeof indexedDB === "undefined") {
|
|
70
|
+
throw new Error("IndexedDB is unavailable in this runtime.");
|
|
71
|
+
}
|
|
72
|
+
return new Promise((resolve, reject) => {
|
|
73
|
+
const openRequest = indexedDB.open(this.#databaseName, DATABASE_VERSION);
|
|
74
|
+
openRequest.onupgradeneeded = () => {
|
|
75
|
+
const database = openRequest.result;
|
|
76
|
+
if (database.objectStoreNames.contains(EVENT_STORE)) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const store = database.createObjectStore(EVENT_STORE, {
|
|
80
|
+
keyPath: "id",
|
|
81
|
+
});
|
|
82
|
+
store.createIndex("session", ["namespace", "sessionId"]);
|
|
83
|
+
store.createIndex("namespace", "namespace");
|
|
84
|
+
};
|
|
85
|
+
openRequest.onsuccess = () => resolve(openRequest.result);
|
|
86
|
+
openRequest.onerror = () => reject(openRequest.error);
|
|
87
|
+
openRequest.onblocked = () => reject(new Error("Opening the Orcha IndexedDB database was blocked."));
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function eventId(namespace, sessionId, sequence) {
|
|
92
|
+
return `${namespace}\u0000${sessionId}\u0000${sequence
|
|
93
|
+
.toString()
|
|
94
|
+
.padStart(12, "0")}`;
|
|
95
|
+
}
|
|
96
|
+
function request(value) {
|
|
97
|
+
return new Promise((resolve, reject) => {
|
|
98
|
+
value.onsuccess = () => resolve(value.result);
|
|
99
|
+
value.onerror = () => reject(value.error);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
function transactionComplete(transaction) {
|
|
103
|
+
return new Promise((resolve, reject) => {
|
|
104
|
+
transaction.oncomplete = () => resolve();
|
|
105
|
+
transaction.onerror = () => reject(transaction.error);
|
|
106
|
+
transaction.onabort = () => reject(transaction.error ?? new Error("IndexedDB transaction aborted."));
|
|
107
|
+
});
|
|
25
108
|
}
|
|
@@ -1,20 +1,11 @@
|
|
|
1
1
|
import type { SessionEvent, SessionStore } from "../types.js";
|
|
2
|
-
/**
|
|
3
|
-
* Future React Native storage strategy.
|
|
4
|
-
*
|
|
5
|
-
* It will store one JSONL event stream per session inside the application's
|
|
6
|
-
* private documents directory. The implementation must not assume Node's
|
|
7
|
-
* `fs` module: Expo FileSystem and bare React Native filesystem bindings need
|
|
8
|
-
* a small host adapter while retaining the exact SessionStore contract.
|
|
9
|
-
*
|
|
10
|
-
* Required before implementation:
|
|
11
|
-
* - Expo and bare React Native filesystem adapters;
|
|
12
|
-
* - atomic append/recovery behavior on iOS and Android;
|
|
13
|
-
* - app lifecycle interruption handling;
|
|
14
|
-
* - JSONL import/export conformance tests.
|
|
15
|
-
*/
|
|
16
2
|
export declare class ReactNativeJsonlSessionStore implements SessionStore {
|
|
17
|
-
|
|
18
|
-
|
|
3
|
+
#private;
|
|
4
|
+
constructor(namespace: 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
|
}
|
|
@@ -1,25 +1,71 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
* It will store one JSONL event stream per session inside the application's
|
|
5
|
-
* private documents directory. The implementation must not assume Node's
|
|
6
|
-
* `fs` module: Expo FileSystem and bare React Native filesystem bindings need
|
|
7
|
-
* a small host adapter while retaining the exact SessionStore contract.
|
|
8
|
-
*
|
|
9
|
-
* Required before implementation:
|
|
10
|
-
* - Expo and bare React Native filesystem adapters;
|
|
11
|
-
* - atomic append/recovery behavior on iOS and Android;
|
|
12
|
-
* - app lifecycle interruption handling;
|
|
13
|
-
* - JSONL import/export conformance tests.
|
|
14
|
-
*/
|
|
1
|
+
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
2
|
+
const writes = new Map();
|
|
15
3
|
export class ReactNativeJsonlSessionStore {
|
|
16
|
-
|
|
17
|
-
|
|
4
|
+
#namespace;
|
|
5
|
+
#listeners = new Map();
|
|
6
|
+
#allListeners = new Set();
|
|
7
|
+
constructor(namespace) {
|
|
8
|
+
this.#namespace = namespace;
|
|
18
9
|
}
|
|
19
|
-
async
|
|
20
|
-
|
|
10
|
+
async read(sessionId) {
|
|
11
|
+
const contents = await AsyncStorage.getItem(this.#key(sessionId));
|
|
12
|
+
if (!contents) {
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
return contents
|
|
16
|
+
.split("\n")
|
|
17
|
+
.filter(Boolean)
|
|
18
|
+
.map((line) => JSON.parse(line));
|
|
19
|
+
}
|
|
20
|
+
async append(sessionId, events) {
|
|
21
|
+
if (events.length === 0) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const key = this.#key(sessionId);
|
|
25
|
+
const previous = writes.get(key) ?? Promise.resolve();
|
|
26
|
+
const write = previous.then(async () => {
|
|
27
|
+
const existing = await AsyncStorage.getItem(key);
|
|
28
|
+
const appended = events.map((event) => JSON.stringify(event)).join("\n");
|
|
29
|
+
await AsyncStorage.setItem(key, `${existing ? `${existing.replace(/\n*$/, "")}\n` : ""}${appended}\n`);
|
|
30
|
+
});
|
|
31
|
+
writes.set(key, write);
|
|
32
|
+
try {
|
|
33
|
+
await write;
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
if (writes.get(key) === write) {
|
|
37
|
+
writes.delete(key);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
this.#listeners.get(sessionId)?.forEach((listener) => listener(events));
|
|
41
|
+
this.#allListeners.forEach((listener) => listener(sessionId, events));
|
|
21
42
|
}
|
|
22
43
|
async listSessionIds() {
|
|
23
|
-
|
|
44
|
+
const prefix = `@orchajs:${this.#namespace}:`;
|
|
45
|
+
return (await AsyncStorage.getAllKeys())
|
|
46
|
+
.filter((key) => key.startsWith(prefix))
|
|
47
|
+
.map((key) => key.slice(prefix.length))
|
|
48
|
+
.sort();
|
|
49
|
+
}
|
|
50
|
+
subscribe(sessionId, listener) {
|
|
51
|
+
const listeners = this.#listeners.get(sessionId) ?? new Set();
|
|
52
|
+
listeners.add(listener);
|
|
53
|
+
this.#listeners.set(sessionId, listeners);
|
|
54
|
+
return () => {
|
|
55
|
+
listeners.delete(listener);
|
|
56
|
+
if (listeners.size === 0) {
|
|
57
|
+
this.#listeners.delete(sessionId);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
subscribeAll(listener) {
|
|
62
|
+
this.#allListeners.add(listener);
|
|
63
|
+
return () => this.#allListeners.delete(listener);
|
|
64
|
+
}
|
|
65
|
+
async describeLocation(sessionId) {
|
|
66
|
+
return `async-storage://${this.#key(sessionId)}`;
|
|
67
|
+
}
|
|
68
|
+
#key(sessionId) {
|
|
69
|
+
return `@orchajs:${this.#namespace}:${sessionId}`;
|
|
24
70
|
}
|
|
25
71
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -43,7 +43,7 @@ export interface ProjectConfiguration {
|
|
|
43
43
|
providers: ResolvedProviderConfigurations;
|
|
44
44
|
actions?: LocalActionRuntimeConfiguration;
|
|
45
45
|
storage?: {
|
|
46
|
-
strategy?: "node-jsonl" | "sqlite";
|
|
46
|
+
strategy?: "node-jsonl" | "sqlite" | "indexeddb" | "react-native";
|
|
47
47
|
directory?: string;
|
|
48
48
|
};
|
|
49
49
|
}
|
|
@@ -54,6 +54,8 @@ export type AgentRegistration = string | {
|
|
|
54
54
|
export interface OrchaInitConfiguration {
|
|
55
55
|
providers: ProviderInitConfigurations;
|
|
56
56
|
agents: Record<string, AgentRegistration>;
|
|
57
|
+
/** Precompiled registry used by browser, React Native, and custom runtimes. */
|
|
58
|
+
bundle?: CompiledBundle;
|
|
57
59
|
amarsia?: {
|
|
58
60
|
key: string;
|
|
59
61
|
endpoint?: string;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict"; const __orchaImportMetaUrl = require("url").pathToFileURL(__filename).href;
|
|
2
|
+
"use strict";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
20
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
21
|
+
var browser_exports = {};
|
|
22
|
+
__export(browser_exports, {
|
|
23
|
+
orcha: () => orcha
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(browser_exports);
|
|
26
|
+
var import_browser = require("./providers/browser.js");
|
|
27
|
+
var import_execute = require("./runtime/actions/execute.js");
|
|
28
|
+
var import_create_orcha = require("./runtime/create-orcha.js");
|
|
29
|
+
var import_platform_browser = require("./runtime/platform-browser.js");
|
|
30
|
+
__reExport(browser_exports, require("./runtime-entry.js"), module.exports);
|
|
31
|
+
(0, import_execute.setNativeRuntimeLoader)(async () => {
|
|
32
|
+
const modulePath = "./runtime/actions/browser-native.js";
|
|
33
|
+
return import(modulePath);
|
|
34
|
+
});
|
|
35
|
+
const orcha = (0, import_create_orcha.createOrcha)(
|
|
36
|
+
() => {
|
|
37
|
+
throw new Error(
|
|
38
|
+
"The browser runtime requires a precompiled Orcha bundle. Configure the Orcha integration for your application bundler."
|
|
39
|
+
);
|
|
40
|
+
},
|
|
41
|
+
import_browser.generateBrowserProviderResponse,
|
|
42
|
+
import_platform_browser.browserRuntimePlatform
|
|
43
|
+
);
|
|
44
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
45
|
+
0 && (module.exports = {
|
|
46
|
+
orcha,
|
|
47
|
+
...require("./runtime-entry.js")
|
|
48
|
+
});
|
|
@@ -52,6 +52,28 @@ credentials. \`dev\` and \`build\` are offline. Sessions use JSONL by default
|
|
|
52
52
|
under \`.orcha/sessions/<agentName>/\`; opt-in SQLite stores all agents in
|
|
53
53
|
\`.orcha/sessions/orcha-sqlite.db\`.
|
|
54
54
|
|
|
55
|
+
## Production deployment
|
|
56
|
+
|
|
57
|
+
\`orcha build\` writes \`.orcha/dist/bundle.js\` for bundler integrations and
|
|
58
|
+
\`.orcha/dist/manifest.json\` for unbundled production runtimes. If deployment
|
|
59
|
+
uses plain \`tsc\`, \`serverless-plugin-typescript\`, or another packager that
|
|
60
|
+
does not use \`orchajs/esbuild\`, explicitly include \`.orcha/dist/**\` in the
|
|
61
|
+
deployment artifact. AWS Lambda loads the manifest automatically; other
|
|
62
|
+
unbundled environments require \`NODE_ENV=production\` or
|
|
63
|
+
\`ORCHA_USE_BUILD=1\`.
|
|
64
|
+
|
|
65
|
+
For Serverless Framework manual builds:
|
|
66
|
+
|
|
67
|
+
\`\`\`yaml
|
|
68
|
+
package:
|
|
69
|
+
patterns:
|
|
70
|
+
- ".orcha/dist/**"
|
|
71
|
+
\`\`\`
|
|
72
|
+
|
|
73
|
+
Do not assume that a successful \`orcha build\` means the generated files were
|
|
74
|
+
copied by a later packaging tool. Inspect the final ZIP or container image and
|
|
75
|
+
confirm that \`.orcha/dist/manifest.json\` is present.
|
|
76
|
+
|
|
55
77
|
## Registry
|
|
56
78
|
|
|
57
79
|
\`orcha/index.ts\` initializes providers and explicitly registers agents:
|
|
@@ -28,9 +28,21 @@ var import_path = require("path");
|
|
|
28
28
|
var import_url = require("url");
|
|
29
29
|
var import_esbuild = require("esbuild");
|
|
30
30
|
var import_orcha = require("../orcha.js");
|
|
31
|
+
var import_compiler_hook = require("../runtime/compiler-hook.js");
|
|
32
|
+
var import_compile = require("./compile.js");
|
|
31
33
|
var import_catalog = require("../providers/catalog.js");
|
|
34
|
+
let registryImportSequence = 0;
|
|
32
35
|
async function buildProject(options = {}) {
|
|
33
36
|
const projectRoot = (0, import_path.resolve)(options.projectRoot ?? process.cwd());
|
|
37
|
+
const target = options.target ?? "node";
|
|
38
|
+
(0, import_compiler_hook.setRegistryCompiler)(
|
|
39
|
+
(configuration, compilerProjectRoot) => (0, import_compile.compileRegistry)(
|
|
40
|
+
configuration.agents,
|
|
41
|
+
(0, import_path.resolve)(compilerProjectRoot, "orcha"),
|
|
42
|
+
configuration.actions?.runtime ?? "native",
|
|
43
|
+
target
|
|
44
|
+
)
|
|
45
|
+
);
|
|
34
46
|
const registryPath = (0, import_path.resolve)(projectRoot, "orcha/index.ts");
|
|
35
47
|
if (!(0, import_fs.existsSync)(registryPath)) {
|
|
36
48
|
throw new Error('Missing "orcha/index.ts". Run "orcha init" first.');
|
|
@@ -41,7 +53,10 @@ async function buildProject(options = {}) {
|
|
|
41
53
|
temporaryDirectory,
|
|
42
54
|
"production-entry.mjs"
|
|
43
55
|
);
|
|
44
|
-
const outputPath = (0, import_path.resolve)(
|
|
56
|
+
const outputPath = (0, import_path.resolve)(
|
|
57
|
+
projectRoot,
|
|
58
|
+
`.orcha/dist/${bundleFileName(target)}`
|
|
59
|
+
);
|
|
45
60
|
const manifestPath = (0, import_path.resolve)(
|
|
46
61
|
projectRoot,
|
|
47
62
|
".orcha/dist/manifest.json"
|
|
@@ -64,7 +79,7 @@ async function buildProject(options = {}) {
|
|
|
64
79
|
process.env.ORCHA_COMPILING = "1";
|
|
65
80
|
process.env.ORCHA_PROJECT_ROOT = projectRoot;
|
|
66
81
|
try {
|
|
67
|
-
await import(`${(0, import_url.pathToFileURL)(registryBundlePath).href}?
|
|
82
|
+
await import(`${(0, import_url.pathToFileURL)(registryBundlePath).href}?build=${Date.now()}-${registryImportSequence++}`);
|
|
68
83
|
} finally {
|
|
69
84
|
if (previousCompiling === void 0) {
|
|
70
85
|
delete process.env.ORCHA_COMPILING;
|
|
@@ -78,15 +93,30 @@ async function buildProject(options = {}) {
|
|
|
78
93
|
}
|
|
79
94
|
}
|
|
80
95
|
const compiledBundle = import_orcha.orcha.getCompiledBundle();
|
|
96
|
+
if (target !== "node" && compiledBundle.actionRuntime === "sandbox") {
|
|
97
|
+
throw new Error(
|
|
98
|
+
`The ${target} target supports precompiled native actions only. Set actions.runtime to "native".`
|
|
99
|
+
);
|
|
100
|
+
}
|
|
81
101
|
const runtimeFactoryPath = (0, import_path.resolve)(
|
|
82
102
|
(0, import_path.dirname)((0, import_url.fileURLToPath)(__orchaImportMetaUrl)),
|
|
83
103
|
"../runtime/create-orcha.js"
|
|
84
104
|
).replaceAll("\\", "/");
|
|
105
|
+
const runtimePlatformPath = (0, import_path.resolve)(
|
|
106
|
+
(0, import_path.dirname)((0, import_url.fileURLToPath)(__orchaImportMetaUrl)),
|
|
107
|
+
`../runtime/platform-${target}.js`
|
|
108
|
+
).replaceAll("\\", "/");
|
|
109
|
+
const runtimeEntryPath = (0, import_path.resolve)(
|
|
110
|
+
(0, import_path.dirname)((0, import_url.fileURLToPath)(__orchaImportMetaUrl)),
|
|
111
|
+
"../runtime-entry.js"
|
|
112
|
+
).replaceAll("\\", "/");
|
|
85
113
|
const providerDispatcherPath = (0, import_path.resolve)(
|
|
86
114
|
(0, import_path.dirname)((0, import_url.fileURLToPath)(__orchaImportMetaUrl)),
|
|
87
115
|
"../providers/dispatcher.js"
|
|
88
116
|
).replaceAll("\\", "/");
|
|
89
117
|
const sandboxRuntimeSource = compiledBundle.actionRuntime === "sandbox" ? createSandboxRuntimeSource() : "";
|
|
118
|
+
const platformActionRuntimeSource = createPlatformActionRuntimeSource(target);
|
|
119
|
+
const nodeStorageExports = target === "node" ? createNodeStorageExports() : "";
|
|
90
120
|
const includedProviders = [
|
|
91
121
|
...new Set(
|
|
92
122
|
allCompiledAgents(compiledBundle.agents).flatMap(
|
|
@@ -97,18 +127,22 @@ async function buildProject(options = {}) {
|
|
|
97
127
|
)
|
|
98
128
|
)
|
|
99
129
|
];
|
|
100
|
-
const providerRuntimeSource = createProviderRuntimeSource(includedProviders);
|
|
130
|
+
const providerRuntimeSource = createProviderRuntimeSource(includedProviders, target);
|
|
101
131
|
const needsNodeRequire = compiledBundle.actionRuntime === "sandbox" || includedProviders.includes("vertexai") || includedProviders.includes("bedrock");
|
|
102
132
|
await (0, import_promises.writeFile)(
|
|
103
133
|
productionEntryPath,
|
|
104
134
|
[
|
|
105
135
|
`import { createOrcha } from ${JSON.stringify(runtimeFactoryPath)};`,
|
|
136
|
+
`import { ${runtimePlatformExport(target)} as runtimePlatform } from ${JSON.stringify(runtimePlatformPath)};`,
|
|
106
137
|
`import { createProviderResponseGenerator } from ${JSON.stringify(providerDispatcherPath)};`,
|
|
138
|
+
`export * from ${JSON.stringify(runtimeEntryPath)};`,
|
|
139
|
+
nodeStorageExports,
|
|
107
140
|
providerRuntimeSource,
|
|
141
|
+
platformActionRuntimeSource,
|
|
108
142
|
sandboxRuntimeSource,
|
|
109
143
|
`const compiledBundle = ${JSON.stringify(compiledBundle)};`,
|
|
110
144
|
"const generateProviderResponse = createProviderResponseGenerator(includedProviders);",
|
|
111
|
-
"export const orcha = createOrcha(() => compiledBundle, generateProviderResponse);",
|
|
145
|
+
"export const orcha = createOrcha(() => compiledBundle, generateProviderResponse, runtimePlatform);",
|
|
112
146
|
"export default orcha;",
|
|
113
147
|
""
|
|
114
148
|
].join("\n"),
|
|
@@ -119,8 +153,8 @@ async function buildProject(options = {}) {
|
|
|
119
153
|
outfile: outputPath,
|
|
120
154
|
bundle: true,
|
|
121
155
|
format: "esm",
|
|
122
|
-
platform: "node",
|
|
123
|
-
target: "node18",
|
|
156
|
+
platform: target === "node" ? "node" : "browser",
|
|
157
|
+
target: target === "node" ? "node18" : target === "browser" ? ["chrome110", "firefox110", "safari16"] : "es2022",
|
|
124
158
|
minify: true,
|
|
125
159
|
legalComments: "none",
|
|
126
160
|
define: {
|
|
@@ -128,7 +162,7 @@ async function buildProject(options = {}) {
|
|
|
128
162
|
compiledBundle.actionRuntime === "sandbox" ? "1" : "0"
|
|
129
163
|
)
|
|
130
164
|
},
|
|
131
|
-
...needsNodeRequire ? {
|
|
165
|
+
...needsNodeRequire && target === "node" ? {
|
|
132
166
|
banner: {
|
|
133
167
|
js: [
|
|
134
168
|
'import { createRequire as __orchaCreateRequire } from "module";',
|
|
@@ -136,6 +170,11 @@ async function buildProject(options = {}) {
|
|
|
136
170
|
].join("\n")
|
|
137
171
|
}
|
|
138
172
|
} : {},
|
|
173
|
+
...target === "react-native" ? {
|
|
174
|
+
external: [
|
|
175
|
+
"@react-native-async-storage/async-storage"
|
|
176
|
+
]
|
|
177
|
+
} : {},
|
|
139
178
|
logLevel: "silent"
|
|
140
179
|
});
|
|
141
180
|
await (0, import_promises.writeFile)(
|
|
@@ -152,6 +191,18 @@ async function buildProject(options = {}) {
|
|
|
152
191
|
});
|
|
153
192
|
}
|
|
154
193
|
}
|
|
194
|
+
function bundleFileName(target) {
|
|
195
|
+
return target === "node" ? "bundle.js" : `bundle.${target}.js`;
|
|
196
|
+
}
|
|
197
|
+
function runtimePlatformExport(target) {
|
|
198
|
+
if (target === "browser") {
|
|
199
|
+
return "browserRuntimePlatform";
|
|
200
|
+
}
|
|
201
|
+
if (target === "react-native") {
|
|
202
|
+
return "reactNativeRuntimePlatform";
|
|
203
|
+
}
|
|
204
|
+
return "nodeRuntimePlatform";
|
|
205
|
+
}
|
|
155
206
|
function createSandboxRuntimeSource() {
|
|
156
207
|
const runtimeDirectory = (0, import_path.dirname)((0, import_url.fileURLToPath)(__orchaImportMetaUrl));
|
|
157
208
|
const executePath = (0, import_path.resolve)(
|
|
@@ -169,13 +220,46 @@ function createSandboxRuntimeSource() {
|
|
|
169
220
|
""
|
|
170
221
|
].join("\n");
|
|
171
222
|
}
|
|
223
|
+
function createPlatformActionRuntimeSource(target) {
|
|
224
|
+
const runtimeDirectory = (0, import_path.dirname)((0, import_url.fileURLToPath)(__orchaImportMetaUrl));
|
|
225
|
+
const executePath = (0, import_path.resolve)(
|
|
226
|
+
runtimeDirectory,
|
|
227
|
+
"../runtime/actions/execute.js"
|
|
228
|
+
).replaceAll("\\", "/");
|
|
229
|
+
const nativePath = (0, import_path.resolve)(
|
|
230
|
+
runtimeDirectory,
|
|
231
|
+
target === "node" ? "../runtime/actions/native.js" : "../runtime/actions/browser-native.js"
|
|
232
|
+
).replaceAll("\\", "/");
|
|
233
|
+
return [
|
|
234
|
+
`import { setNativeRuntimeLoader } from ${JSON.stringify(executePath)};`,
|
|
235
|
+
`import { executeNativeAction } from ${JSON.stringify(nativePath)};`,
|
|
236
|
+
"setNativeRuntimeLoader(async () => ({ executeNativeAction }));",
|
|
237
|
+
""
|
|
238
|
+
].join("\n");
|
|
239
|
+
}
|
|
240
|
+
function createNodeStorageExports() {
|
|
241
|
+
const sourceRoot = (0, import_path.dirname)((0, import_url.fileURLToPath)(__orchaImportMetaUrl));
|
|
242
|
+
const jsonlPath = (0, import_path.resolve)(
|
|
243
|
+
sourceRoot,
|
|
244
|
+
"../storage/node-jsonl.js"
|
|
245
|
+
).replaceAll("\\", "/");
|
|
246
|
+
const sqlitePath = (0, import_path.resolve)(
|
|
247
|
+
sourceRoot,
|
|
248
|
+
"../storage/node-sqlite.js"
|
|
249
|
+
).replaceAll("\\", "/");
|
|
250
|
+
return [
|
|
251
|
+
`export { NodeJsonlSessionStore } from ${JSON.stringify(jsonlPath)};`,
|
|
252
|
+
`export { NodeSqliteSessionStore } from ${JSON.stringify(sqlitePath)};`,
|
|
253
|
+
""
|
|
254
|
+
].join("\n");
|
|
255
|
+
}
|
|
172
256
|
function allCompiledAgents(agents) {
|
|
173
257
|
return Object.values(agents).flatMap((agent) => [
|
|
174
258
|
agent,
|
|
175
259
|
...Object.values(agent.subagents ?? {})
|
|
176
260
|
]);
|
|
177
261
|
}
|
|
178
|
-
function createProviderRuntimeSource(providerNames) {
|
|
262
|
+
function createProviderRuntimeSource(providerNames, target) {
|
|
179
263
|
const providersDirectory = (0, import_path.resolve)(
|
|
180
264
|
(0, import_path.dirname)((0, import_url.fileURLToPath)(__orchaImportMetaUrl)),
|
|
181
265
|
"../providers"
|
|
@@ -186,6 +270,11 @@ function createProviderRuntimeSource(providerNames) {
|
|
|
186
270
|
if (!(0, import_catalog.isBuiltInProvider)(name)) {
|
|
187
271
|
throw new Error(`Provider "${name}" is not built in.`);
|
|
188
272
|
}
|
|
273
|
+
if (target !== "node" && (name === "bedrock" || name === "vertexai")) {
|
|
274
|
+
throw new Error(
|
|
275
|
+
`Provider "${name}" is not available for the ${target} target.`
|
|
276
|
+
);
|
|
277
|
+
}
|
|
189
278
|
const descriptor = import_catalog.builtInProviderCatalog[name];
|
|
190
279
|
const localName = `provider${index}`;
|
|
191
280
|
imports.push(
|
|
@@ -28,7 +28,7 @@ var import_fs = require("fs");
|
|
|
28
28
|
var import_path = require("path");
|
|
29
29
|
var import_esbuild = require("esbuild");
|
|
30
30
|
var import_catalog = require("../providers/catalog.js");
|
|
31
|
-
function compileRegistry(registrations, registryRoot, actionRuntime = "native") {
|
|
31
|
+
function compileRegistry(registrations, registryRoot, actionRuntime = "native", target = "node") {
|
|
32
32
|
if (!registrations || typeof registrations !== "object" || Array.isArray(registrations)) {
|
|
33
33
|
throw new TypeError(
|
|
34
34
|
'orcha.init() requires an "agents" object of registered folder paths.'
|
|
@@ -51,14 +51,16 @@ function compileRegistry(registrations, registryRoot, actionRuntime = "native")
|
|
|
51
51
|
subagentKey,
|
|
52
52
|
registeredPath,
|
|
53
53
|
registryRoot,
|
|
54
|
-
actionRuntime
|
|
54
|
+
actionRuntime,
|
|
55
|
+
target
|
|
55
56
|
);
|
|
56
57
|
}
|
|
57
58
|
const parent = compileAgent(
|
|
58
59
|
key,
|
|
59
60
|
normalized.path,
|
|
60
61
|
registryRoot,
|
|
61
|
-
actionRuntime
|
|
62
|
+
actionRuntime,
|
|
63
|
+
target
|
|
62
64
|
);
|
|
63
65
|
agents[key] = Object.freeze({
|
|
64
66
|
...parent,
|
|
@@ -108,7 +110,7 @@ function normalizeAgentRegistration(key, registration) {
|
|
|
108
110
|
subagents: registration.subagents ?? {}
|
|
109
111
|
};
|
|
110
112
|
}
|
|
111
|
-
function compileAgent(key, registeredPath, registryRoot, actionRuntime) {
|
|
113
|
+
function compileAgent(key, registeredPath, registryRoot, actionRuntime, target) {
|
|
112
114
|
const name = key;
|
|
113
115
|
const sourceDirectory = (0, import_path.resolve)(registryRoot, registeredPath);
|
|
114
116
|
const configPath = (0, import_path.resolve)(sourceDirectory, "index.json");
|
|
@@ -195,14 +197,19 @@ function compileAgent(key, registeredPath, registryRoot, actionRuntime) {
|
|
|
195
197
|
reasoningLevel: configuration.reasoningLevel,
|
|
196
198
|
outputType: configuration.outputType ?? "text",
|
|
197
199
|
outputSchema: configuration.outputSchema,
|
|
198
|
-
actions: compileActions(
|
|
200
|
+
actions: compileActions(
|
|
201
|
+
name,
|
|
202
|
+
sourceDirectory,
|
|
203
|
+
actionRuntime,
|
|
204
|
+
target
|
|
205
|
+
),
|
|
199
206
|
skills: compileSkills(name, sourceDirectory),
|
|
200
207
|
evaluations: compileEvaluations(name, sourceDirectory),
|
|
201
208
|
subagentPolicy: configuration.subagents ? Object.freeze({ ...configuration.subagents }) : void 0,
|
|
202
209
|
subagents: Object.freeze({})
|
|
203
210
|
});
|
|
204
211
|
}
|
|
205
|
-
function compileActions(agentName, sourceDirectory, actionRuntime) {
|
|
212
|
+
function compileActions(agentName, sourceDirectory, actionRuntime, target) {
|
|
206
213
|
const actionsDirectory = (0, import_path.resolve)(sourceDirectory, "actions");
|
|
207
214
|
if (!(0, import_fs.existsSync)(actionsDirectory)) {
|
|
208
215
|
return {};
|
|
@@ -306,7 +313,8 @@ function compileActions(agentName, sourceDirectory, actionRuntime) {
|
|
|
306
313
|
agentName,
|
|
307
314
|
entry.name,
|
|
308
315
|
actionsDirectory,
|
|
309
|
-
actionRuntime
|
|
316
|
+
actionRuntime,
|
|
317
|
+
target
|
|
310
318
|
) : void 0;
|
|
311
319
|
actions[configuration.name] = Object.freeze({
|
|
312
320
|
...configuration,
|
|
@@ -498,7 +506,7 @@ function validateEvaluationConfiguration(agentName, registrationName, configurat
|
|
|
498
506
|
names.add(metric.name);
|
|
499
507
|
}
|
|
500
508
|
}
|
|
501
|
-
function compileLocalAction(agentName, directoryName, actionsDirectory, actionRuntime) {
|
|
509
|
+
function compileLocalAction(agentName, directoryName, actionsDirectory, actionRuntime, target) {
|
|
502
510
|
const entryPath = (0, import_path.resolve)(actionsDirectory, directoryName, "index.js");
|
|
503
511
|
if (!(0, import_fs.existsSync)(entryPath)) {
|
|
504
512
|
throw new Error(
|
|
@@ -513,7 +521,7 @@ function compileLocalAction(agentName, directoryName, actionsDirectory, actionRu
|
|
|
513
521
|
write: false,
|
|
514
522
|
format: "iife",
|
|
515
523
|
globalName: "__orchaActionModule",
|
|
516
|
-
platform: actionRuntime === "native" ? "node" : "
|
|
524
|
+
platform: actionRuntime === "native" && target === "node" ? "node" : "browser",
|
|
517
525
|
target: "es2022",
|
|
518
526
|
logLevel: "silent"
|
|
519
527
|
});
|