@kortyx/runtime 0.2.2 → 0.4.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/CHANGELOG.md +20 -0
- package/README.md +20 -0
- package/dist/checkpointer.d.ts +2 -2
- package/dist/checkpointer.d.ts.map +1 -1
- package/dist/checkpointer.js +11 -5
- package/dist/config/load-kortyx-config.js +5 -5
- package/dist/framework/adapter.d.ts +21 -0
- package/dist/framework/adapter.d.ts.map +1 -0
- package/dist/framework/adapter.js +74 -0
- package/dist/framework/in-memory-checkpointer.d.ts +9 -0
- package/dist/framework/in-memory-checkpointer.d.ts.map +1 -0
- package/dist/framework/in-memory-checkpointer.js +134 -0
- package/dist/framework/pending-requests.d.ts +33 -0
- package/dist/framework/pending-requests.d.ts.map +1 -0
- package/dist/framework/pending-requests.js +32 -0
- package/dist/framework/redis/pending-request-store.d.ts +8 -0
- package/dist/framework/redis/pending-request-store.d.ts.map +1 -0
- package/dist/framework/redis/pending-request-store.js +30 -0
- package/dist/framework/redis/redis-checkpointer.d.ts +13 -0
- package/dist/framework/redis/redis-checkpointer.d.ts.map +1 -0
- package/dist/framework/redis/redis-checkpointer.js +159 -0
- package/dist/framework/redis/redis-client.d.ts +13 -0
- package/dist/framework/redis/redis-client.d.ts.map +1 -0
- package/dist/framework/redis/redis-client.js +181 -0
- package/dist/framework/redis/redis-store.d.ts +20 -0
- package/dist/framework/redis/redis-store.d.ts.map +1 -0
- package/dist/framework/redis/redis-store.js +107 -0
- package/dist/graph/create-langgraph.d.ts +4 -2
- package/dist/graph/create-langgraph.d.ts.map +1 -1
- package/dist/graph/create-langgraph.js +56 -34
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/node-loader.d.ts +7 -0
- package/dist/node-loader.d.ts.map +1 -0
- package/dist/node-loader.js +58 -0
- package/dist/node-registry.d.ts +7 -0
- package/dist/node-registry.d.ts.map +1 -0
- package/dist/node-registry.js +27 -0
- package/dist/registry/file-registry.d.ts.map +1 -1
- package/dist/registry/file-registry.js +25 -2
- package/dist/registry/in-memory-registry.d.ts +6 -0
- package/dist/registry/in-memory-registry.d.ts.map +1 -0
- package/dist/registry/in-memory-registry.js +25 -0
- package/dist/registry/interface.d.ts +2 -2
- package/dist/registry/interface.d.ts.map +1 -1
- package/dist/state/build-initial-state.d.ts +1 -1
- package/dist/state/build-initial-state.d.ts.map +1 -1
- package/dist/state/build-initial-state.js +6 -2
- package/package.json +40 -18
- package/src/checkpointer.ts +0 -13
- package/src/config/load-kortyx-config.ts +0 -46
- package/src/graph/create-langgraph.ts +0 -437
- package/src/index.ts +0 -8
- package/src/interrupt/tokens.ts +0 -9
- package/src/registry/file-registry.ts +0 -124
- package/src/registry/interface.ts +0 -13
- package/src/state/build-initial-state.ts +0 -30
- package/tsconfig.build.json +0 -25
- package/tsconfig.build.tsbuildinfo +0 -1
- package/tsconfig.json +0 -29
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerNode = registerNode;
|
|
4
|
+
exports.getRegisteredNode = getRegisteredNode;
|
|
5
|
+
exports.listRegisteredNodes = listRegisteredNodes;
|
|
6
|
+
exports.clearRegisteredNodes = clearRegisteredNodes;
|
|
7
|
+
exports.resolveNode = resolveNode;
|
|
8
|
+
const registry = new Map();
|
|
9
|
+
function registerNode(id, fn) {
|
|
10
|
+
registry.set(id, fn);
|
|
11
|
+
}
|
|
12
|
+
function getRegisteredNode(id) {
|
|
13
|
+
return registry.get(id) ?? null;
|
|
14
|
+
}
|
|
15
|
+
function listRegisteredNodes() {
|
|
16
|
+
return [...registry.keys()].sort();
|
|
17
|
+
}
|
|
18
|
+
function clearRegisteredNodes() {
|
|
19
|
+
registry.clear();
|
|
20
|
+
}
|
|
21
|
+
function resolveNode(id) {
|
|
22
|
+
const fn = registry.get(id);
|
|
23
|
+
if (!fn) {
|
|
24
|
+
throw new Error(`Node '${id}' is not registered. Call registerNode('${id}', fn) before running workflows that reference it.`);
|
|
25
|
+
}
|
|
26
|
+
return fn;
|
|
27
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-registry.d.ts","sourceRoot":"","sources":["../../src/registry/file-registry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"file-registry.d.ts","sourceRoot":"","sources":["../../src/registry/file-registry.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,WAAW,2BAA2B;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AA0BD,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,2BAA2B,GACnC,gBAAgB,CAgHlB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createFileWorkflowRegistry = createFileWorkflowRegistry;
|
|
4
|
+
const core_1 = require("@kortyx/core");
|
|
4
5
|
const promises_1 = require("fs/promises");
|
|
5
6
|
const path_1 = require("path");
|
|
6
7
|
const DEFAULT_EXTENSIONS = [
|
|
@@ -8,10 +9,18 @@ const DEFAULT_EXTENSIONS = [
|
|
|
8
9
|
".workflow.mts",
|
|
9
10
|
".workflow.js",
|
|
10
11
|
".workflow.mjs",
|
|
12
|
+
".workflow.json",
|
|
13
|
+
".workflow.yml",
|
|
14
|
+
".workflow.yaml",
|
|
11
15
|
];
|
|
12
16
|
function isWorkflowFile(name, extensions) {
|
|
13
17
|
return extensions.some((ext) => name.endsWith(ext));
|
|
14
18
|
}
|
|
19
|
+
function isDeclarativeWorkflowFile(name) {
|
|
20
|
+
return (name.endsWith(".workflow.json") ||
|
|
21
|
+
name.endsWith(".workflow.yml") ||
|
|
22
|
+
name.endsWith(".workflow.yaml"));
|
|
23
|
+
}
|
|
15
24
|
function createFileWorkflowRegistry(options) {
|
|
16
25
|
const workflowsDir = options.workflowsDir;
|
|
17
26
|
const fallbackId = options.fallbackId ?? "general-chat";
|
|
@@ -30,18 +39,32 @@ function createFileWorkflowRegistry(options) {
|
|
|
30
39
|
for (const file of workflowFiles) {
|
|
31
40
|
try {
|
|
32
41
|
const modulePath = (0, path_1.join)(workflowsDir, file);
|
|
42
|
+
if (isDeclarativeWorkflowFile(file)) {
|
|
43
|
+
const raw = await (0, promises_1.readFile)(modulePath, "utf8");
|
|
44
|
+
const workflow = (0, core_1.loadWorkflow)(raw);
|
|
45
|
+
workflow.metadata = {
|
|
46
|
+
...(workflow.metadata ?? {}),
|
|
47
|
+
__filePath: modulePath,
|
|
48
|
+
};
|
|
49
|
+
workflows[workflow.id] = workflow;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
33
52
|
const module = await import(modulePath);
|
|
34
53
|
const workflowExport = Object.values(module).find((exp) => {
|
|
35
54
|
const obj = exp;
|
|
36
55
|
return (exp !== null &&
|
|
37
56
|
typeof exp === "object" &&
|
|
38
|
-
typeof obj.
|
|
57
|
+
typeof obj.id === "string" &&
|
|
39
58
|
typeof obj.nodes === "object" &&
|
|
40
59
|
obj.nodes !== null &&
|
|
41
60
|
Array.isArray(obj.edges));
|
|
42
61
|
});
|
|
43
62
|
if (workflowExport) {
|
|
44
|
-
|
|
63
|
+
workflowExport.metadata = {
|
|
64
|
+
...(workflowExport.metadata ?? {}),
|
|
65
|
+
__filePath: modulePath,
|
|
66
|
+
};
|
|
67
|
+
workflows[workflowExport.id] = workflowExport;
|
|
45
68
|
}
|
|
46
69
|
}
|
|
47
70
|
catch (error) {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { WorkflowDefinition } from "@kortyx/core";
|
|
2
|
+
import type { WorkflowRegistry } from "./interface";
|
|
3
|
+
export declare function createInMemoryWorkflowRegistry(workflows: WorkflowDefinition[], options?: {
|
|
4
|
+
fallbackId?: string;
|
|
5
|
+
}): WorkflowRegistry;
|
|
6
|
+
//# sourceMappingURL=in-memory-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory-registry.d.ts","sourceRoot":"","sources":["../../src/registry/in-memory-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,kBAAkB,EAAE,EAC/B,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAChC,gBAAgB,CAwBlB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createInMemoryWorkflowRegistry = createInMemoryWorkflowRegistry;
|
|
4
|
+
function createInMemoryWorkflowRegistry(workflows, options) {
|
|
5
|
+
const byId = new Map();
|
|
6
|
+
for (const wf of workflows)
|
|
7
|
+
byId.set(wf.id, wf);
|
|
8
|
+
const fallbackId = options?.fallbackId ?? "general-chat";
|
|
9
|
+
return {
|
|
10
|
+
async list() {
|
|
11
|
+
return Array.from(byId.values());
|
|
12
|
+
},
|
|
13
|
+
async get(id) {
|
|
14
|
+
return byId.get(id) ?? null;
|
|
15
|
+
},
|
|
16
|
+
async select(id, selectOptions) {
|
|
17
|
+
const fallback = selectOptions?.fallbackId ?? fallbackId;
|
|
18
|
+
const wf = byId.get(id) ?? (fallback ? byId.get(fallback) : undefined);
|
|
19
|
+
if (!wf) {
|
|
20
|
+
throw new Error(`Workflow "${id}" not found${fallback ? ` (fallback "${fallback}" missing too)` : ""}.`);
|
|
21
|
+
}
|
|
22
|
+
return wf;
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
type AnyWorkflow = WorkflowDefinition
|
|
1
|
+
import type { WorkflowDefinition } from "@kortyx/core";
|
|
2
|
+
type AnyWorkflow = WorkflowDefinition;
|
|
3
3
|
export interface WorkflowRegistry {
|
|
4
4
|
list: () => Promise<AnyWorkflow[]>;
|
|
5
5
|
get: (id: string) => Promise<AnyWorkflow | null>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/registry/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/registry/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,KAAK,WAAW,GAAG,kBAAkB,CAAC;AAEtC,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACnC,GAAG,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACjD,MAAM,EAAE,CACN,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,KAC9B,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-initial-state.d.ts","sourceRoot":"","sources":["../../src/state/build-initial-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAM/D,MAAM,WAAW,gBAAgB,CAAC,MAAM,GAAG,OAAO;IAChD,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"build-initial-state.d.ts","sourceRoot":"","sources":["../../src/state/build-initial-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAM/D,MAAM,WAAW,gBAAgB,CAAC,MAAM,GAAG,OAAO;IAChD,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAsB,sBAAsB,CAAC,MAAM,EAAE,EACnD,KAAK,EACL,MAAM,EACN,MAAM,EACN,iBAAiB,GAClB,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAkBhD"}
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.buildInitialGraphState = buildInitialGraphState;
|
|
4
|
-
async function buildInitialGraphState({ input, memory, config, defaultWorkflowId
|
|
4
|
+
async function buildInitialGraphState({ input, memory, config, defaultWorkflowId, }) {
|
|
5
|
+
const currentWorkflow = memory.currentWorkflow || defaultWorkflowId;
|
|
6
|
+
if (!currentWorkflow) {
|
|
7
|
+
throw new Error("No workflow selected. Provide defaultWorkflowId (or set memory.currentWorkflow) before starting the graph.");
|
|
8
|
+
}
|
|
5
9
|
return {
|
|
6
10
|
input,
|
|
7
11
|
lastNode: "__start__",
|
|
8
12
|
memory,
|
|
9
13
|
config: config,
|
|
10
14
|
conversationHistory: [],
|
|
11
|
-
currentWorkflow
|
|
15
|
+
currentWorkflow,
|
|
12
16
|
awaitingHumanInput: false,
|
|
13
17
|
};
|
|
14
18
|
}
|
package/package.json
CHANGED
|
@@ -1,25 +1,54 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kortyx/runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"private": false,
|
|
5
|
+
"description": "Runtime/orchestration wiring for Kortyx.",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"ai",
|
|
8
|
+
"agent",
|
|
9
|
+
"agents",
|
|
10
|
+
"orchestration",
|
|
11
|
+
"framework",
|
|
12
|
+
"runtime",
|
|
13
|
+
"kortyx"
|
|
14
|
+
],
|
|
15
|
+
"license": "Apache-2.0",
|
|
16
|
+
"homepage": "https://github.com/kortyx-io/kortyx/tree/main/packages/runtime#readme",
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/kortyx-io/kortyx/issues"
|
|
19
|
+
},
|
|
20
|
+
"author": "Kortyx (https://github.com/kortyx-io)",
|
|
5
21
|
"main": "./dist/index.js",
|
|
6
|
-
"types": "./
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
7
23
|
"exports": {
|
|
8
24
|
".": {
|
|
9
|
-
"types": "./
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
10
26
|
"default": "./dist/index.js"
|
|
11
27
|
}
|
|
12
28
|
},
|
|
29
|
+
"files": [
|
|
30
|
+
"dist/**",
|
|
31
|
+
"README.md",
|
|
32
|
+
"CHANGELOG.md"
|
|
33
|
+
],
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "tsc -p tsconfig.build.json",
|
|
36
|
+
"dev": "tsc --watch",
|
|
37
|
+
"lint": "biome check src",
|
|
38
|
+
"test": "pnpm -s type-check",
|
|
39
|
+
"type-check": "tsc --noEmit"
|
|
40
|
+
},
|
|
13
41
|
"dependencies": {
|
|
42
|
+
"@kortyx/stream": "workspace:*",
|
|
43
|
+
"@kortyx/core": "workspace:*",
|
|
44
|
+
"@kortyx/hooks": "workspace:*",
|
|
45
|
+
"@kortyx/memory": "workspace:*",
|
|
46
|
+
"@kortyx/providers": "workspace:*",
|
|
47
|
+
"@kortyx/utils": "workspace:*",
|
|
14
48
|
"@langchain/core": "^1.0.1",
|
|
15
49
|
"@langchain/langgraph": "^1.0.1",
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"@kortyx/hooks": "0.2.2",
|
|
19
|
-
"@kortyx/memory": "0.2.2",
|
|
20
|
-
"@kortyx/providers": "0.2.2",
|
|
21
|
-
"@kortyx/utils": "0.2.2",
|
|
22
|
-
"@kortyx/stream": "0.2.2"
|
|
50
|
+
"@langchain/langgraph-checkpoint": "^1.0.0",
|
|
51
|
+
"uuid": "^11.1.0"
|
|
23
52
|
},
|
|
24
53
|
"devDependencies": {
|
|
25
54
|
"turbo": "^2.5.4",
|
|
@@ -30,12 +59,5 @@
|
|
|
30
59
|
"type": "git",
|
|
31
60
|
"url": "https://github.com/kortyx-io/kortyx",
|
|
32
61
|
"directory": "packages/runtime"
|
|
33
|
-
},
|
|
34
|
-
"scripts": {
|
|
35
|
-
"build": "tsc -p tsconfig.build.json",
|
|
36
|
-
"dev": "tsc --watch",
|
|
37
|
-
"lint": "echo 'Linting @kortyx/runtime...' && echo 'Lint passed!'",
|
|
38
|
-
"test": "echo 'Testing @kortyx/runtime...' && echo 'All tests passed!'",
|
|
39
|
-
"type-check": "tsc --noEmit"
|
|
40
62
|
}
|
|
41
|
-
}
|
|
63
|
+
}
|
package/src/checkpointer.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { MemorySaver } from "@langchain/langgraph";
|
|
2
|
-
|
|
3
|
-
const map = new Map<string, MemorySaver>();
|
|
4
|
-
|
|
5
|
-
export function getCheckpointer(key: string): MemorySaver {
|
|
6
|
-
const k = key || "__default__";
|
|
7
|
-
let saver = map.get(k);
|
|
8
|
-
if (!saver) {
|
|
9
|
-
saver = new MemorySaver();
|
|
10
|
-
map.set(k, saver);
|
|
11
|
-
}
|
|
12
|
-
return saver;
|
|
13
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { stat } from "fs/promises";
|
|
2
|
-
import { resolve } from "path";
|
|
3
|
-
import { pathToFileURL } from "url";
|
|
4
|
-
|
|
5
|
-
export interface KortyxConfig {
|
|
6
|
-
workflowsDir?: string;
|
|
7
|
-
fallbackWorkflowId?: string;
|
|
8
|
-
registry?: {
|
|
9
|
-
cache?: boolean;
|
|
10
|
-
extensions?: string[];
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface LoadKortyxConfigOptions {
|
|
15
|
-
cwd?: string;
|
|
16
|
-
configPath?: string;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
async function exists(filePath: string): Promise<boolean> {
|
|
20
|
-
try {
|
|
21
|
-
const info = await stat(filePath);
|
|
22
|
-
return info.isFile();
|
|
23
|
-
} catch {
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export async function loadKortyxConfig(
|
|
29
|
-
options: LoadKortyxConfigOptions = {},
|
|
30
|
-
): Promise<KortyxConfig | null> {
|
|
31
|
-
const cwd = options.cwd ?? process.cwd();
|
|
32
|
-
const configPath = options.configPath ?? "kortyx.config.mjs";
|
|
33
|
-
const resolvedPath = resolve(cwd, configPath);
|
|
34
|
-
|
|
35
|
-
if (!(await exists(resolvedPath))) return null;
|
|
36
|
-
|
|
37
|
-
try {
|
|
38
|
-
const mod = await import(pathToFileURL(resolvedPath).href);
|
|
39
|
-
const config = (mod?.default ?? mod?.kortyx ?? mod) as KortyxConfig | null;
|
|
40
|
-
if (!config || typeof config !== "object") return null;
|
|
41
|
-
return config;
|
|
42
|
-
} catch (error) {
|
|
43
|
-
const message = error instanceof Error ? error.message : "Unknown error";
|
|
44
|
-
throw new Error(`Failed to load ${configPath}: ${message}`);
|
|
45
|
-
}
|
|
46
|
-
}
|