@redtuma/core 0.1.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/LICENSE +202 -0
- package/dist/agent/index.d.ts +87 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +145 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +11 -0
- package/dist/llm/index.d.ts +22 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +46 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/logger.d.ts +17 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +38 -0
- package/dist/logger.js.map +1 -0
- package/dist/message-list.d.ts +37 -0
- package/dist/message-list.d.ts.map +1 -0
- package/dist/message-list.js +61 -0
- package/dist/message-list.js.map +1 -0
- package/dist/redtuma.d.ts +35 -0
- package/dist/redtuma.d.ts.map +1 -0
- package/dist/redtuma.js +65 -0
- package/dist/redtuma.js.map +1 -0
- package/dist/store/index.d.ts +57 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +53 -0
- package/dist/store/index.js.map +1 -0
- package/dist/tools/index.d.ts +39 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +36 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types.d.ts +26 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +21 -0
- package/dist/types.js.map +1 -0
- package/dist/workflows/index.d.ts +114 -0
- package/dist/workflows/index.d.ts.map +1 -0
- package/dist/workflows/index.js +199 -0
- package/dist/workflows/index.js.map +1 -0
- package/package.json +80 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { CoreMessage } from "ai";
|
|
2
|
+
|
|
3
|
+
//#region src/message-list.d.ts
|
|
4
|
+
type MessageRole = 'system' | 'user' | 'assistant' | 'tool';
|
|
5
|
+
/** Canonical persisted message shape. */
|
|
6
|
+
interface RedtumaMessage {
|
|
7
|
+
id: string;
|
|
8
|
+
role: MessageRole;
|
|
9
|
+
content: CoreMessage['content'];
|
|
10
|
+
createdAt: Date;
|
|
11
|
+
threadId?: string;
|
|
12
|
+
resourceId?: string;
|
|
13
|
+
}
|
|
14
|
+
type MessageInput = string | CoreMessage | CoreMessage[] | RedtumaMessage | RedtumaMessage[];
|
|
15
|
+
/**
|
|
16
|
+
* Normalizes heterogeneous message inputs (strings, AI SDK CoreMessages,
|
|
17
|
+
* persisted RedtumaMessages) into a single ordered list and converts back to
|
|
18
|
+
* the AI SDK `CoreMessage[]` shape for model calls.
|
|
19
|
+
*/
|
|
20
|
+
declare class MessageList {
|
|
21
|
+
private readonly meta;
|
|
22
|
+
private messages;
|
|
23
|
+
constructor(meta?: {
|
|
24
|
+
threadId?: string;
|
|
25
|
+
resourceId?: string;
|
|
26
|
+
});
|
|
27
|
+
add(input: MessageInput, role?: MessageRole): this;
|
|
28
|
+
private coerce;
|
|
29
|
+
private wrap;
|
|
30
|
+
all(): RedtumaMessage[];
|
|
31
|
+
/** Convert to AI SDK CoreMessage[] (drops redtuma-only metadata). */
|
|
32
|
+
toCore(): CoreMessage[];
|
|
33
|
+
get length(): number;
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { MessageInput, MessageList, MessageRole, RedtumaMessage };
|
|
37
|
+
//# sourceMappingURL=message-list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-list.d.ts","names":[],"sources":["../src/message-list.ts"],"sourcesContent":[],"mappings":";;;KAEY,WAAA;;AAAA,UAGK,cAAA,CAHM;EAGN,EAAA,EAAA,MAAA;EAET,IAAA,EAAA,WAAA;EACG,OAAA,EAAA,WAAA,CAAA,SAAA,CAAA;EACE,SAAA,EAAA,IAAA;EAAI,QAAA,CAAA,EAAA,MAAA;EAKL,UAAA,CAAA,EAAA,MAAY;;AAGpB,KAHQ,YAAA,GAGR,MAAA,GADA,WACA,GAAA,WAAA,EAAA,GACA,cADA,GAEA,cAFA,EAAA;;;;AAmBJ;;AAOiC,cAPpB,WAAA,CAOoB;EA4BxB,iBAAA,IAAA;EAKG,QAAA,QAAA;EAAW,WAAA,CAAA,KAAA,EAAA;;;;aAjCV,qBAAoB;;;SA4BxB;;YAKG"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
//#region src/message-list.ts
|
|
2
|
+
let counter = 0;
|
|
3
|
+
function genId() {
|
|
4
|
+
counter += 1;
|
|
5
|
+
return `msg_${Date.now().toString(36)}_${counter.toString(36)}`;
|
|
6
|
+
}
|
|
7
|
+
function isRedtumaMessage(m) {
|
|
8
|
+
return !!m && typeof m === "object" && "createdAt" in m && "id" in m && "role" in m;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Normalizes heterogeneous message inputs (strings, AI SDK CoreMessages,
|
|
12
|
+
* persisted RedtumaMessages) into a single ordered list and converts back to
|
|
13
|
+
* the AI SDK `CoreMessage[]` shape for model calls.
|
|
14
|
+
*/
|
|
15
|
+
var MessageList = class {
|
|
16
|
+
messages = [];
|
|
17
|
+
constructor(meta = {}) {
|
|
18
|
+
this.meta = meta;
|
|
19
|
+
}
|
|
20
|
+
add(input, role = "user") {
|
|
21
|
+
for (const m of this.coerce(input, role)) this.messages.push(m);
|
|
22
|
+
return this;
|
|
23
|
+
}
|
|
24
|
+
coerce(input, role) {
|
|
25
|
+
if (typeof input === "string") return [this.wrap({
|
|
26
|
+
role,
|
|
27
|
+
content: input
|
|
28
|
+
})];
|
|
29
|
+
return (Array.isArray(input) ? input : [input]).map((m) => isRedtumaMessage(m) ? m : this.wrap({
|
|
30
|
+
role: m.role,
|
|
31
|
+
content: m.content
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
wrap(m) {
|
|
35
|
+
return {
|
|
36
|
+
id: genId(),
|
|
37
|
+
role: m.role,
|
|
38
|
+
content: m.content,
|
|
39
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
40
|
+
threadId: this.meta.threadId,
|
|
41
|
+
resourceId: this.meta.resourceId
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
all() {
|
|
45
|
+
return [...this.messages];
|
|
46
|
+
}
|
|
47
|
+
/** Convert to AI SDK CoreMessage[] (drops redtuma-only metadata). */
|
|
48
|
+
toCore() {
|
|
49
|
+
return this.messages.map((m) => ({
|
|
50
|
+
role: m.role,
|
|
51
|
+
content: m.content
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
54
|
+
get length() {
|
|
55
|
+
return this.messages.length;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
//#endregion
|
|
60
|
+
export { MessageList };
|
|
61
|
+
//# sourceMappingURL=message-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-list.js","names":["meta: { threadId?: string; resourceId?: string }"],"sources":["../src/message-list.ts"],"sourcesContent":["import type { CoreMessage } from 'ai'\n\nexport type MessageRole = 'system' | 'user' | 'assistant' | 'tool'\n\n/** Canonical persisted message shape. */\nexport interface RedtumaMessage {\n id: string\n role: MessageRole\n content: CoreMessage['content']\n createdAt: Date\n threadId?: string\n resourceId?: string\n}\n\nexport type MessageInput =\n | string\n | CoreMessage\n | CoreMessage[]\n | RedtumaMessage\n | RedtumaMessage[]\n\nlet counter = 0\nfunction genId(): string {\n counter += 1\n return `msg_${Date.now().toString(36)}_${counter.toString(36)}`\n}\n\nfunction isRedtumaMessage(m: unknown): m is RedtumaMessage {\n return !!m && typeof m === 'object' && 'createdAt' in m && 'id' in m && 'role' in m\n}\n\n/**\n * Normalizes heterogeneous message inputs (strings, AI SDK CoreMessages,\n * persisted RedtumaMessages) into a single ordered list and converts back to\n * the AI SDK `CoreMessage[]` shape for model calls.\n */\nexport class MessageList {\n private messages: RedtumaMessage[] = []\n\n constructor(\n private readonly meta: { threadId?: string; resourceId?: string } = {},\n ) {}\n\n add(input: MessageInput, role: MessageRole = 'user'): this {\n for (const m of this.coerce(input, role)) this.messages.push(m)\n return this\n }\n\n private coerce(input: MessageInput, role: MessageRole): RedtumaMessage[] {\n if (typeof input === 'string') {\n return [this.wrap({ role, content: input })]\n }\n const arr = Array.isArray(input) ? input : [input]\n return arr.map((m) =>\n isRedtumaMessage(m)\n ? m\n : this.wrap({ role: m.role as MessageRole, content: m.content }),\n )\n }\n\n private wrap(m: { role: MessageRole; content: CoreMessage['content'] }): RedtumaMessage {\n return {\n id: genId(),\n role: m.role,\n content: m.content,\n createdAt: new Date(),\n threadId: this.meta.threadId,\n resourceId: this.meta.resourceId,\n }\n }\n\n all(): RedtumaMessage[] {\n return [...this.messages]\n }\n\n /** Convert to AI SDK CoreMessage[] (drops redtuma-only metadata). */\n toCore(): CoreMessage[] {\n return this.messages.map(\n (m) => ({ role: m.role, content: m.content }) as CoreMessage,\n )\n }\n\n get length(): number {\n return this.messages.length\n }\n}\n"],"mappings":";AAqBA,IAAI,UAAU;AACd,SAAS,QAAgB;AACvB,YAAW;AACX,QAAO,OAAO,KAAK,KAAK,CAAC,SAAS,GAAG,CAAC,GAAG,QAAQ,SAAS,GAAG;;AAG/D,SAAS,iBAAiB,GAAiC;AACzD,QAAO,CAAC,CAAC,KAAK,OAAO,MAAM,YAAY,eAAe,KAAK,QAAQ,KAAK,UAAU;;;;;;;AAQpF,IAAa,cAAb,MAAyB;CACvB,AAAQ,WAA6B,EAAE;CAEvC,YACE,AAAiBA,OAAmD,EAAE,EACtE;EADiB;;CAGnB,IAAI,OAAqB,OAAoB,QAAc;AACzD,OAAK,MAAM,KAAK,KAAK,OAAO,OAAO,KAAK,CAAE,MAAK,SAAS,KAAK,EAAE;AAC/D,SAAO;;CAGT,AAAQ,OAAO,OAAqB,MAAqC;AACvE,MAAI,OAAO,UAAU,SACnB,QAAO,CAAC,KAAK,KAAK;GAAE;GAAM,SAAS;GAAO,CAAC,CAAC;AAG9C,UADY,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,MAAM,EACvC,KAAK,MACd,iBAAiB,EAAE,GACf,IACA,KAAK,KAAK;GAAE,MAAM,EAAE;GAAqB,SAAS,EAAE;GAAS,CAAC,CACnE;;CAGH,AAAQ,KAAK,GAA2E;AACtF,SAAO;GACL,IAAI,OAAO;GACX,MAAM,EAAE;GACR,SAAS,EAAE;GACX,2BAAW,IAAI,MAAM;GACrB,UAAU,KAAK,KAAK;GACpB,YAAY,KAAK,KAAK;GACvB;;CAGH,MAAwB;AACtB,SAAO,CAAC,GAAG,KAAK,SAAS;;;CAI3B,SAAwB;AACtB,SAAO,KAAK,SAAS,KAClB,OAAO;GAAE,MAAM,EAAE;GAAM,SAAS,EAAE;GAAS,EAC7C;;CAGH,IAAI,SAAiB;AACnB,SAAO,KAAK,SAAS"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Logger } from "./types.js";
|
|
2
|
+
import { AnyToolAction } from "./tools/index.js";
|
|
3
|
+
import { Agent, AgentMemory } from "./agent/index.js";
|
|
4
|
+
import { Workflow } from "./workflows/index.js";
|
|
5
|
+
import { Store } from "./store/index.js";
|
|
6
|
+
|
|
7
|
+
//#region src/redtuma.d.ts
|
|
8
|
+
interface RedtumaConfig {
|
|
9
|
+
agents?: Record<string, Agent>;
|
|
10
|
+
workflows?: Record<string, Workflow>;
|
|
11
|
+
tools?: Record<string, AnyToolAction>;
|
|
12
|
+
storage?: Store;
|
|
13
|
+
memory?: AgentMemory;
|
|
14
|
+
logger?: Logger;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Central registry and orchestrator. Wires shared dependencies (logger, memory,
|
|
18
|
+
* storage) into every registered component.
|
|
19
|
+
*/
|
|
20
|
+
declare class Redtuma {
|
|
21
|
+
#private;
|
|
22
|
+
constructor(config?: RedtumaConfig);
|
|
23
|
+
getAgent(key: string): Agent;
|
|
24
|
+
/** Look up an agent by its `id` property (may differ from the registry key). */
|
|
25
|
+
getAgentById(id: string): Agent;
|
|
26
|
+
getAgents(): Record<string, Agent>;
|
|
27
|
+
getWorkflow(key: string): Workflow;
|
|
28
|
+
getWorkflows(): Record<string, Workflow>;
|
|
29
|
+
getTool(key: string): AnyToolAction;
|
|
30
|
+
getStorage(): Store | undefined;
|
|
31
|
+
getLogger(): Logger;
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { Redtuma, RedtumaConfig };
|
|
35
|
+
//# sourceMappingURL=redtuma.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redtuma.d.ts","names":[],"sources":["../src/redtuma.ts"],"sourcesContent":[],"mappings":";;;;;;;UAOiB,aAAA;WACN,eAAe;EADT,SAAA,CAAA,EAEH,MAFgB,CAAA,MAAA,EAED,QAFC,CAAA;EACJ,KAAA,CAAA,EAEhB,MAFgB,CAAA,MAAA,EAED,aAFC,CAAA;EAAf,OAAA,CAAA,EAGC,KAHD;EACkB,MAAA,CAAA,EAGlB,WAHkB;EAAf,MAAA,CAAA,EAIH,MAJG;;;;;;AAIG,cAOJ,OAAA,CAPI;EAOJ,CAAA,OAAA;EAQS,WAAA,CAAA,MAAA,CAAA,EAAA,aAAA;EAgBG,QAAA,CAAA,GAAA,EAAA,MAAA,CAAA,EAAA,KAAA;EAOG;EAME,YAAA,CAAA,EAAA,EAAA,MAAA,CAAA,EANF,KAME;EAAf,SAAA,CAAA,CAAA,EAAA,MAAA,CAAA,MAAA,EAAe,KAAf,CAAA;EAIa,WAAA,CAAA,GAAA,EAAA,MAAA,CAAA,EAAA,QAAA;EAMK,YAAA,CAAA,CAAA,EAAf,MAAe,CAAA,MAAA,EAAA,QAAA,CAAA;EAAf,OAAA,CAAA,GAAA,EAAA,MAAA,CAAA,EAIM,aAJN;EAIM,UAAA,CAAA,CAAA,EAMR,KANQ,GAAA,SAAA;EAMR,SAAA,CAAA,CAAA,EAID,MAJC"}
|
package/dist/redtuma.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { ConsoleLogger } from "./logger.js";
|
|
2
|
+
|
|
3
|
+
//#region src/redtuma.ts
|
|
4
|
+
/**
|
|
5
|
+
* Central registry and orchestrator. Wires shared dependencies (logger, memory,
|
|
6
|
+
* storage) into every registered component.
|
|
7
|
+
*/
|
|
8
|
+
var Redtuma = class {
|
|
9
|
+
#agents;
|
|
10
|
+
#workflows;
|
|
11
|
+
#tools;
|
|
12
|
+
#storage;
|
|
13
|
+
#memory;
|
|
14
|
+
#logger;
|
|
15
|
+
constructor(config = {}) {
|
|
16
|
+
this.#agents = config.agents ?? {};
|
|
17
|
+
this.#workflows = config.workflows ?? {};
|
|
18
|
+
this.#tools = config.tools ?? {};
|
|
19
|
+
this.#storage = config.storage;
|
|
20
|
+
this.#memory = config.memory;
|
|
21
|
+
this.#logger = config.logger ?? new ConsoleLogger("info");
|
|
22
|
+
for (const agent of Object.values(this.#agents)) agent.__register({
|
|
23
|
+
logger: this.#logger,
|
|
24
|
+
memory: this.#memory
|
|
25
|
+
});
|
|
26
|
+
for (const wf of Object.values(this.#workflows)) wf.logger = this.#logger;
|
|
27
|
+
}
|
|
28
|
+
getAgent(key) {
|
|
29
|
+
const agent = this.#agents[key];
|
|
30
|
+
if (!agent) throw new Error(`Agent "${key}" is not registered.`);
|
|
31
|
+
return agent;
|
|
32
|
+
}
|
|
33
|
+
/** Look up an agent by its `id` property (may differ from the registry key). */
|
|
34
|
+
getAgentById(id) {
|
|
35
|
+
const found = Object.values(this.#agents).find((a) => a.id === id);
|
|
36
|
+
if (!found) throw new Error(`Agent with id "${id}" is not registered.`);
|
|
37
|
+
return found;
|
|
38
|
+
}
|
|
39
|
+
getAgents() {
|
|
40
|
+
return { ...this.#agents };
|
|
41
|
+
}
|
|
42
|
+
getWorkflow(key) {
|
|
43
|
+
const wf = this.#workflows[key];
|
|
44
|
+
if (!wf) throw new Error(`Workflow "${key}" is not registered.`);
|
|
45
|
+
return wf;
|
|
46
|
+
}
|
|
47
|
+
getWorkflows() {
|
|
48
|
+
return { ...this.#workflows };
|
|
49
|
+
}
|
|
50
|
+
getTool(key) {
|
|
51
|
+
const tool = this.#tools[key];
|
|
52
|
+
if (!tool) throw new Error(`Tool "${key}" is not registered.`);
|
|
53
|
+
return tool;
|
|
54
|
+
}
|
|
55
|
+
getStorage() {
|
|
56
|
+
return this.#storage;
|
|
57
|
+
}
|
|
58
|
+
getLogger() {
|
|
59
|
+
return this.#logger;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
//#endregion
|
|
64
|
+
export { Redtuma };
|
|
65
|
+
//# sourceMappingURL=redtuma.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redtuma.js","names":["#agents","#workflows","#tools","#storage","#memory","#logger"],"sources":["../src/redtuma.ts"],"sourcesContent":["import { Agent, type AgentMemory } from './agent'\nimport type { Workflow } from './workflows'\nimport type { AnyToolAction } from './tools'\nimport type { Store } from './store'\nimport { ConsoleLogger } from './logger'\nimport type { Logger } from './types'\n\nexport interface RedtumaConfig {\n agents?: Record<string, Agent>\n workflows?: Record<string, Workflow>\n tools?: Record<string, AnyToolAction>\n storage?: Store\n memory?: AgentMemory\n logger?: Logger\n}\n\n/**\n * Central registry and orchestrator. Wires shared dependencies (logger, memory,\n * storage) into every registered component.\n */\nexport class Redtuma {\n #agents: Record<string, Agent>\n #workflows: Record<string, Workflow>\n #tools: Record<string, AnyToolAction>\n #storage?: Store\n #memory?: AgentMemory\n #logger: Logger\n\n constructor(config: RedtumaConfig = {}) {\n this.#agents = config.agents ?? {}\n this.#workflows = config.workflows ?? {}\n this.#tools = config.tools ?? {}\n this.#storage = config.storage\n this.#memory = config.memory\n this.#logger = config.logger ?? new ConsoleLogger('info')\n\n for (const agent of Object.values(this.#agents)) {\n agent.__register({ logger: this.#logger, memory: this.#memory })\n }\n for (const wf of Object.values(this.#workflows)) {\n wf.logger = this.#logger\n }\n }\n\n getAgent(key: string): Agent {\n const agent = this.#agents[key]\n if (!agent) throw new Error(`Agent \"${key}\" is not registered.`)\n return agent\n }\n\n /** Look up an agent by its `id` property (may differ from the registry key). */\n getAgentById(id: string): Agent {\n const found = Object.values(this.#agents).find((a) => a.id === id)\n if (!found) throw new Error(`Agent with id \"${id}\" is not registered.`)\n return found\n }\n\n getAgents(): Record<string, Agent> {\n return { ...this.#agents }\n }\n\n getWorkflow(key: string): Workflow {\n const wf = this.#workflows[key]\n if (!wf) throw new Error(`Workflow \"${key}\" is not registered.`)\n return wf\n }\n\n getWorkflows(): Record<string, Workflow> {\n return { ...this.#workflows }\n }\n\n getTool(key: string): AnyToolAction {\n const tool = this.#tools[key]\n if (!tool) throw new Error(`Tool \"${key}\" is not registered.`)\n return tool\n }\n\n getStorage(): Store | undefined {\n return this.#storage\n }\n\n getLogger(): Logger {\n return this.#logger\n }\n}\n"],"mappings":";;;;;;;AAoBA,IAAa,UAAb,MAAqB;CACnB;CACA;CACA;CACA;CACA;CACA;CAEA,YAAY,SAAwB,EAAE,EAAE;AACtC,QAAKA,SAAU,OAAO,UAAU,EAAE;AAClC,QAAKC,YAAa,OAAO,aAAa,EAAE;AACxC,QAAKC,QAAS,OAAO,SAAS,EAAE;AAChC,QAAKC,UAAW,OAAO;AACvB,QAAKC,SAAU,OAAO;AACtB,QAAKC,SAAU,OAAO,UAAU,IAAI,cAAc,OAAO;AAEzD,OAAK,MAAM,SAAS,OAAO,OAAO,MAAKL,OAAQ,CAC7C,OAAM,WAAW;GAAE,QAAQ,MAAKK;GAAS,QAAQ,MAAKD;GAAS,CAAC;AAElE,OAAK,MAAM,MAAM,OAAO,OAAO,MAAKH,UAAW,CAC7C,IAAG,SAAS,MAAKI;;CAIrB,SAAS,KAAoB;EAC3B,MAAM,QAAQ,MAAKL,OAAQ;AAC3B,MAAI,CAAC,MAAO,OAAM,IAAI,MAAM,UAAU,IAAI,sBAAsB;AAChE,SAAO;;;CAIT,aAAa,IAAmB;EAC9B,MAAM,QAAQ,OAAO,OAAO,MAAKA,OAAQ,CAAC,MAAM,MAAM,EAAE,OAAO,GAAG;AAClE,MAAI,CAAC,MAAO,OAAM,IAAI,MAAM,kBAAkB,GAAG,sBAAsB;AACvE,SAAO;;CAGT,YAAmC;AACjC,SAAO,EAAE,GAAG,MAAKA,QAAS;;CAG5B,YAAY,KAAuB;EACjC,MAAM,KAAK,MAAKC,UAAW;AAC3B,MAAI,CAAC,GAAI,OAAM,IAAI,MAAM,aAAa,IAAI,sBAAsB;AAChE,SAAO;;CAGT,eAAyC;AACvC,SAAO,EAAE,GAAG,MAAKA,WAAY;;CAG/B,QAAQ,KAA4B;EAClC,MAAM,OAAO,MAAKC,MAAO;AACzB,MAAI,CAAC,KAAM,OAAM,IAAI,MAAM,SAAS,IAAI,sBAAsB;AAC9D,SAAO;;CAGT,aAAgC;AAC9B,SAAO,MAAKC;;CAGd,YAAoB;AAClB,SAAO,MAAKE"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { RedtumaMessage } from "../message-list.js";
|
|
2
|
+
|
|
3
|
+
//#region src/store/index.d.ts
|
|
4
|
+
interface Thread {
|
|
5
|
+
id: string;
|
|
6
|
+
resourceId: string;
|
|
7
|
+
title?: string;
|
|
8
|
+
metadata?: Record<string, unknown>;
|
|
9
|
+
createdAt: Date;
|
|
10
|
+
updatedAt: Date;
|
|
11
|
+
}
|
|
12
|
+
interface Resource {
|
|
13
|
+
id: string;
|
|
14
|
+
workingMemory?: string;
|
|
15
|
+
metadata?: Record<string, unknown>;
|
|
16
|
+
}
|
|
17
|
+
interface GetMessagesArgs {
|
|
18
|
+
threadId: string;
|
|
19
|
+
/** Return only the most recent N messages. */
|
|
20
|
+
last?: number;
|
|
21
|
+
}
|
|
22
|
+
/** Persistence interface shared by all store adapters. */
|
|
23
|
+
interface Store {
|
|
24
|
+
saveThread(thread: Thread): Promise<Thread>;
|
|
25
|
+
getThread(id: string): Promise<Thread | null>;
|
|
26
|
+
getThreadsByResourceId(resourceId: string): Promise<Thread[]>;
|
|
27
|
+
deleteThread(id: string): Promise<void>;
|
|
28
|
+
saveMessages(messages: RedtumaMessage[]): Promise<RedtumaMessage[]>;
|
|
29
|
+
getMessages(args: GetMessagesArgs): Promise<RedtumaMessage[]>;
|
|
30
|
+
getResource(id: string): Promise<Resource | null>;
|
|
31
|
+
saveResource(resource: Resource): Promise<Resource>;
|
|
32
|
+
persistSnapshot(key: string, value: unknown): Promise<void>;
|
|
33
|
+
loadSnapshot<T = unknown>(key: string): Promise<T | null>;
|
|
34
|
+
}
|
|
35
|
+
/** Default ephemeral store. Useful for tests and quick starts. */
|
|
36
|
+
declare class InMemoryStore implements Store {
|
|
37
|
+
private threads;
|
|
38
|
+
private messages;
|
|
39
|
+
private resources;
|
|
40
|
+
private snapshots;
|
|
41
|
+
saveThread(thread: Thread): Promise<Thread>;
|
|
42
|
+
getThread(id: string): Promise<Thread | null>;
|
|
43
|
+
getThreadsByResourceId(resourceId: string): Promise<Thread[]>;
|
|
44
|
+
deleteThread(id: string): Promise<void>;
|
|
45
|
+
saveMessages(messages: RedtumaMessage[]): Promise<RedtumaMessage[]>;
|
|
46
|
+
getMessages({
|
|
47
|
+
threadId,
|
|
48
|
+
last
|
|
49
|
+
}: GetMessagesArgs): Promise<RedtumaMessage[]>;
|
|
50
|
+
getResource(id: string): Promise<Resource | null>;
|
|
51
|
+
saveResource(resource: Resource): Promise<Resource>;
|
|
52
|
+
persistSnapshot(key: string, value: unknown): Promise<void>;
|
|
53
|
+
loadSnapshot<T = unknown>(key: string): Promise<T | null>;
|
|
54
|
+
}
|
|
55
|
+
//#endregion
|
|
56
|
+
export { GetMessagesArgs, InMemoryStore, Resource, Store, Thread };
|
|
57
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/store/index.ts"],"sourcesContent":[],"mappings":";;;UAEiB,MAAA;;EAAA,UAAM,EAAA,MAAA;EAIV,KAAA,CAAA,EAAA,MAAA;EACA,QAAA,CAAA,EADA,MACA,CAAA,MAAA,EAAA,OAAA,CAAA;EACA,SAAA,EADA,IACA;EAAI,SAAA,EAAJ,IAAI;AAGjB;AAMiB,UANA,QAAA,CAMe;EAOf,EAAA,EAAA,MAAK;EAED,aAAA,CAAA,EAAA,MAAA;EAAiB,QAAA,CAAA,EAZzB,MAYyB,CAAA,MAAA,EAAA,OAAA,CAAA;;AACL,UAVhB,eAAA,CAUgB;EAAR,QAAA,EAAA,MAAA;EAC6B;EAAR,IAAA,CAAA,EAAA,MAAA;;;AAGM,UAPnC,KAAA,CAOmC;EAAR,UAAA,CAAA,MAAA,EALvB,MAKuB,CAAA,EALd,OAKc,CALN,MAKM,CAAA;EACxB,SAAA,CAAA,EAAA,EAAA,MAAA,CAAA,EALK,OAKL,CALa,MAKb,GAAA,IAAA,CAAA;EAA0B,sBAAA,CAAA,UAAA,EAAA,MAAA,CAAA,EAJA,OAIA,CAJQ,MAIR,EAAA,CAAA;EAAR,YAAA,CAAA,EAAA,EAAA,MAAA,CAAA,EAHV,OAGU,CAAA,IAAA,CAAA;EAEH,YAAA,CAAA,QAAA,EAHV,cAGU,EAAA,CAAA,EAHS,OAGT,CAHiB,cAGjB,EAAA,CAAA;EAAR,WAAA,CAAA,IAAA,EAFP,eAEO,CAAA,EAFW,OAEX,CAFmB,cAEnB,EAAA,CAAA;EACF,WAAA,CAAA,EAAA,EAAA,MAAA,CAAA,EADE,OACF,CADU,QACV,GAAA,IAAA,CAAA;EAAmB,YAAA,CAAA,QAAA,EAAnB,QAAmB,CAAA,EAAR,OAAQ,CAAA,QAAA,CAAA;EAAR,eAAA,CAAA,GAAA,EAAA,MAAA,EAAA,KAAA,EAAA,OAAA,CAAA,EAEY,OAFZ,CAAA,IAAA,CAAA;EAEY,YAAA,CAAA,IAAA,OAAA,CAAA,CAAA,GAAA,EAAA,MAAA,CAAA,EACN,OADM,CACE,CADF,GAAA,IAAA,CAAA;;;AACC,cAIpC,aAAA,YAAyB,KAJW,CAAA;EAIpC,QAAA,OAAA;EAMc,QAAA,QAAA;EAAiB,QAAA,SAAA;EAAR,QAAA,SAAA;EAKG,UAAA,CAAA,MAAA,EALZ,MAKY,CAAA,EALH,OAKG,CALK,MAKL,CAAA;EAAR,SAAA,CAAA,EAAA,EAAA,MAAA,CAAA,EAAA,OAAA,CAAQ,MAAR,GAAA,IAAA,CAAA;EAG6B,sBAAA,CAAA,UAAA,EAAA,MAAA,CAAA,EAAR,OAAQ,CAAA,MAAA,EAAA,CAAA;EAAR,YAAA,CAAA,EAAA,EAAA,MAAA,CAAA,EAGlB,OAHkB,CAAA,IAAA,CAAA;EAGlB,YAAA,CAAA,QAAA,EAKH,cALG,EAAA,CAAA,EAKgB,OALhB,CAKwB,cALxB,EAAA,CAAA;EAKH,WAAA,CAAA;IAAA,QAAA;IAAA;EAAA,CAAA,EASS,eATT,CAAA,EAS2B,OAT3B,CASmC,cATnC,EAAA,CAAA;EAA2B,WAAA,CAAA,EAAA,EAAA,MAAA,CAAA,EAczB,OAdyB,CAcjB,QAdiB,GAAA,IAAA,CAAA;EAAR,YAAA,CAAA,QAAA,EAiBnB,QAjBmB,CAAA,EAiBR,OAjBQ,CAiBA,QAjBA,CAAA;EAS5B,eAAA,CAAA,GAAA,EAAA,MAAA,EAAA,KAAA,EAAA,OAAA,CAAA,EAagC,OAbhC,CAAA,IAAA,CAAA;EAAU,YAAA,CAAA,IAAA,OAAA,CAAA,CAAA,GAAA,EAAA,MAAA,CAAA,EAgBgB,OAhBhB,CAgBwB,CAhBxB,GAAA,IAAA,CAAA"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
//#region src/store/index.ts
|
|
2
|
+
/** Default ephemeral store. Useful for tests and quick starts. */
|
|
3
|
+
var InMemoryStore = class {
|
|
4
|
+
threads = /* @__PURE__ */ new Map();
|
|
5
|
+
messages = /* @__PURE__ */ new Map();
|
|
6
|
+
resources = /* @__PURE__ */ new Map();
|
|
7
|
+
snapshots = /* @__PURE__ */ new Map();
|
|
8
|
+
async saveThread(thread) {
|
|
9
|
+
this.threads.set(thread.id, thread);
|
|
10
|
+
if (!this.messages.has(thread.id)) this.messages.set(thread.id, []);
|
|
11
|
+
return thread;
|
|
12
|
+
}
|
|
13
|
+
async getThread(id) {
|
|
14
|
+
return this.threads.get(id) ?? null;
|
|
15
|
+
}
|
|
16
|
+
async getThreadsByResourceId(resourceId) {
|
|
17
|
+
return [...this.threads.values()].filter((t) => t.resourceId === resourceId);
|
|
18
|
+
}
|
|
19
|
+
async deleteThread(id) {
|
|
20
|
+
this.threads.delete(id);
|
|
21
|
+
this.messages.delete(id);
|
|
22
|
+
}
|
|
23
|
+
async saveMessages(messages) {
|
|
24
|
+
for (const m of messages) {
|
|
25
|
+
if (!m.threadId) continue;
|
|
26
|
+
const list = this.messages.get(m.threadId) ?? [];
|
|
27
|
+
list.push(m);
|
|
28
|
+
this.messages.set(m.threadId, list);
|
|
29
|
+
}
|
|
30
|
+
return messages;
|
|
31
|
+
}
|
|
32
|
+
async getMessages({ threadId, last }) {
|
|
33
|
+
const list = this.messages.get(threadId) ?? [];
|
|
34
|
+
return typeof last === "number" ? list.slice(-last) : [...list];
|
|
35
|
+
}
|
|
36
|
+
async getResource(id) {
|
|
37
|
+
return this.resources.get(id) ?? null;
|
|
38
|
+
}
|
|
39
|
+
async saveResource(resource) {
|
|
40
|
+
this.resources.set(resource.id, resource);
|
|
41
|
+
return resource;
|
|
42
|
+
}
|
|
43
|
+
async persistSnapshot(key, value) {
|
|
44
|
+
this.snapshots.set(key, value);
|
|
45
|
+
}
|
|
46
|
+
async loadSnapshot(key) {
|
|
47
|
+
return this.snapshots.get(key) ?? null;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
//#endregion
|
|
52
|
+
export { InMemoryStore };
|
|
53
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/store/index.ts"],"sourcesContent":["import type { RedtumaMessage } from '../message-list'\n\nexport interface Thread {\n id: string\n resourceId: string\n title?: string\n metadata?: Record<string, unknown>\n createdAt: Date\n updatedAt: Date\n}\n\nexport interface Resource {\n id: string\n workingMemory?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface GetMessagesArgs {\n threadId: string\n /** Return only the most recent N messages. */\n last?: number\n}\n\n/** Persistence interface shared by all store adapters. */\nexport interface Store {\n // threads\n saveThread(thread: Thread): Promise<Thread>\n getThread(id: string): Promise<Thread | null>\n getThreadsByResourceId(resourceId: string): Promise<Thread[]>\n deleteThread(id: string): Promise<void>\n // messages\n saveMessages(messages: RedtumaMessage[]): Promise<RedtumaMessage[]>\n getMessages(args: GetMessagesArgs): Promise<RedtumaMessage[]>\n // working memory / resources\n getResource(id: string): Promise<Resource | null>\n saveResource(resource: Resource): Promise<Resource>\n // generic kv for workflow snapshots etc.\n persistSnapshot(key: string, value: unknown): Promise<void>\n loadSnapshot<T = unknown>(key: string): Promise<T | null>\n}\n\n/** Default ephemeral store. Useful for tests and quick starts. */\nexport class InMemoryStore implements Store {\n private threads = new Map<string, Thread>()\n private messages = new Map<string, RedtumaMessage[]>()\n private resources = new Map<string, Resource>()\n private snapshots = new Map<string, unknown>()\n\n async saveThread(thread: Thread): Promise<Thread> {\n this.threads.set(thread.id, thread)\n if (!this.messages.has(thread.id)) this.messages.set(thread.id, [])\n return thread\n }\n async getThread(id: string): Promise<Thread | null> {\n return this.threads.get(id) ?? null\n }\n async getThreadsByResourceId(resourceId: string): Promise<Thread[]> {\n return [...this.threads.values()].filter((t) => t.resourceId === resourceId)\n }\n async deleteThread(id: string): Promise<void> {\n this.threads.delete(id)\n this.messages.delete(id)\n }\n\n async saveMessages(messages: RedtumaMessage[]): Promise<RedtumaMessage[]> {\n for (const m of messages) {\n if (!m.threadId) continue\n const list = this.messages.get(m.threadId) ?? []\n list.push(m)\n this.messages.set(m.threadId, list)\n }\n return messages\n }\n async getMessages({ threadId, last }: GetMessagesArgs): Promise<RedtumaMessage[]> {\n const list = this.messages.get(threadId) ?? []\n return typeof last === 'number' ? list.slice(-last) : [...list]\n }\n\n async getResource(id: string): Promise<Resource | null> {\n return this.resources.get(id) ?? null\n }\n async saveResource(resource: Resource): Promise<Resource> {\n this.resources.set(resource.id, resource)\n return resource\n }\n\n async persistSnapshot(key: string, value: unknown): Promise<void> {\n this.snapshots.set(key, value)\n }\n async loadSnapshot<T = unknown>(key: string): Promise<T | null> {\n return (this.snapshots.get(key) as T) ?? null\n }\n}\n"],"mappings":";;AA0CA,IAAa,gBAAb,MAA4C;CAC1C,AAAQ,0BAAU,IAAI,KAAqB;CAC3C,AAAQ,2BAAW,IAAI,KAA+B;CACtD,AAAQ,4BAAY,IAAI,KAAuB;CAC/C,AAAQ,4BAAY,IAAI,KAAsB;CAE9C,MAAM,WAAW,QAAiC;AAChD,OAAK,QAAQ,IAAI,OAAO,IAAI,OAAO;AACnC,MAAI,CAAC,KAAK,SAAS,IAAI,OAAO,GAAG,CAAE,MAAK,SAAS,IAAI,OAAO,IAAI,EAAE,CAAC;AACnE,SAAO;;CAET,MAAM,UAAU,IAAoC;AAClD,SAAO,KAAK,QAAQ,IAAI,GAAG,IAAI;;CAEjC,MAAM,uBAAuB,YAAuC;AAClE,SAAO,CAAC,GAAG,KAAK,QAAQ,QAAQ,CAAC,CAAC,QAAQ,MAAM,EAAE,eAAe,WAAW;;CAE9E,MAAM,aAAa,IAA2B;AAC5C,OAAK,QAAQ,OAAO,GAAG;AACvB,OAAK,SAAS,OAAO,GAAG;;CAG1B,MAAM,aAAa,UAAuD;AACxE,OAAK,MAAM,KAAK,UAAU;AACxB,OAAI,CAAC,EAAE,SAAU;GACjB,MAAM,OAAO,KAAK,SAAS,IAAI,EAAE,SAAS,IAAI,EAAE;AAChD,QAAK,KAAK,EAAE;AACZ,QAAK,SAAS,IAAI,EAAE,UAAU,KAAK;;AAErC,SAAO;;CAET,MAAM,YAAY,EAAE,UAAU,QAAoD;EAChF,MAAM,OAAO,KAAK,SAAS,IAAI,SAAS,IAAI,EAAE;AAC9C,SAAO,OAAO,SAAS,WAAW,KAAK,MAAM,CAAC,KAAK,GAAG,CAAC,GAAG,KAAK;;CAGjE,MAAM,YAAY,IAAsC;AACtD,SAAO,KAAK,UAAU,IAAI,GAAG,IAAI;;CAEnC,MAAM,aAAa,UAAuC;AACxD,OAAK,UAAU,IAAI,SAAS,IAAI,SAAS;AACzC,SAAO;;CAGT,MAAM,gBAAgB,KAAa,OAA+B;AAChE,OAAK,UAAU,IAAI,KAAK,MAAM;;CAEhC,MAAM,aAA0B,KAAgC;AAC9D,SAAQ,KAAK,UAAU,IAAI,IAAI,IAAU"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { RuntimeContext } from "../types.js";
|
|
2
|
+
import { Tool } from "ai";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
//#region src/tools/index.d.ts
|
|
6
|
+
interface ToolExecuteContext<TInput> {
|
|
7
|
+
/** Validated tool input. */
|
|
8
|
+
context: TInput;
|
|
9
|
+
runtimeContext: RuntimeContext;
|
|
10
|
+
abortSignal?: AbortSignal;
|
|
11
|
+
}
|
|
12
|
+
interface ToolAction<TInputSchema extends z.ZodTypeAny = z.ZodTypeAny, TOutputSchema extends z.ZodTypeAny = z.ZodTypeAny> {
|
|
13
|
+
id: string;
|
|
14
|
+
description: string;
|
|
15
|
+
inputSchema: TInputSchema;
|
|
16
|
+
outputSchema?: TOutputSchema;
|
|
17
|
+
execute: (ctx: ToolExecuteContext<z.infer<TInputSchema>>) => Promise<unknown> | unknown;
|
|
18
|
+
}
|
|
19
|
+
/** Define a Redtuma tool. The id is used as the tool name presented to the model. */
|
|
20
|
+
declare function createTool<TInputSchema extends z.ZodTypeAny, TOutputSchema extends z.ZodTypeAny = z.ZodTypeAny>(config: {
|
|
21
|
+
id: string;
|
|
22
|
+
description: string;
|
|
23
|
+
inputSchema: TInputSchema;
|
|
24
|
+
outputSchema?: TOutputSchema;
|
|
25
|
+
execute: (ctx: ToolExecuteContext<z.infer<TInputSchema>>) => Promise<unknown> | unknown;
|
|
26
|
+
}): ToolAction<TInputSchema, TOutputSchema>;
|
|
27
|
+
/** A tool with its schema generics erased; use for heterogeneous collections. */
|
|
28
|
+
type AnyToolAction = ToolAction<any, any>;
|
|
29
|
+
declare function isToolAction(value: unknown): value is ToolAction;
|
|
30
|
+
/** Adapt a {@link ToolAction} into the AI SDK `tool()` shape. */
|
|
31
|
+
declare function toAISDKTool(toolAction: ToolAction, runtimeContext: RuntimeContext): Tool;
|
|
32
|
+
/**
|
|
33
|
+
* Build the AI SDK tool map from a record of Redtuma tools and/or raw AI SDK
|
|
34
|
+
* tools. Redtuma `ToolAction`s are adapted; anything else is passed through.
|
|
35
|
+
*/
|
|
36
|
+
declare function buildToolset(tools: Record<string, AnyToolAction | Tool> | undefined, runtimeContext: RuntimeContext): Record<string, Tool> | undefined;
|
|
37
|
+
//#endregion
|
|
38
|
+
export { AnyToolAction, ToolAction, ToolExecuteContext, buildToolset, createTool, isToolAction, toAISDKTool };
|
|
39
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/tools/index.ts"],"sourcesContent":[],"mappings":";;;;;UAIiB;;EAAA,OAAA,EAEN,MAFM;EAEN,cAAA,EACO,cADP;EACO,WAAA,CAAA,EACF,WADE;;AACS,UAGV,UAHU,CAAA,qBAIJ,CAAA,CAAE,UAJE,GAIW,CAAA,CAAE,UAJb,EAAA,sBAKH,CAAA,CAAE,UALC,GAKY,CAAA,CAAE,UALd,CAAA,CAAA;EAGV,EAAA,EAAA,MAAA;EACQ,WAAA,EAAA,MAAA;EAAe,WAAA,EAKzB,YALyB;EACd,YAAA,CAAA,EAKT,aALS;EAAe,OAAA,EAAA,CAAA,GAAA,EAMxB,kBANwB,CAML,CAAA,CAAE,KANG,CAMG,YANH,CAAA,CAAA,EAAA,GAMsB,OANtB,CAAA,OAAA,CAAA,GAAA,OAAA;;;AAMG,iBAI5B,UAJ4B,CAAA,qBAKrB,CAAA,CAAE,UALmB,EAAA,sBAMpB,CAAA,CAAE,UANkB,GAML,CAAA,CAAE,UANG,CAAA,CAAA,MAAA,EAAA;EAAN,EAAA,EAAA,MAAA;EAArB,WAAA,EAAA,MAAA;EAA8C,WAAA,EAUhD,YAVgD;EAAO,YAAA,CAAA,EAWrD,aAXqD;EAItD,OAAA,EAAA,CAAA,GAAU,EAQT,kBARS,CAQU,CAAA,CAAE,KARZ,CAQkB,YARlB,CAAA,CAAA,EAAA,GAQqC,OARrC,CAAA,OAAA,CAAA,GAAA,OAAA;CACH,CAAA,EAQnB,UARqB,CAQV,YARU,EAQI,aARJ,CAAA;;AACgB,KAa7B,aAAA,GAAgB,UAba,CAAA,GAAA,EAAA,GAAA,CAAA;AAI1B,iBAWC,YAAA,CAXD,KAAA,EAAA,OAAA,CAAA,EAAA,KAAA,IAWwC,UAXxC;;AAE6B,iBAoB5B,WAAA,CApB4B,UAAA,EAqB9B,UArB8B,EAAA,cAAA,EAsB1B,cAtB0B,CAAA,EAuBzC,IAvByC;;;;;AACf,iBAmCb,YAAA,CAnCa,KAAA,EAoCpB,MApCoB,CAAA,MAAA,EAoCL,aApCK,GAoCW,IApCX,CAAA,GAAA,SAAA,EAAA,cAAA,EAqCX,cArCW,CAAA,EAsC1B,MAtC0B,CAAA,MAAA,EAsCX,IAtCW,CAAA,GAAA,SAAA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { tool } from "ai";
|
|
2
|
+
|
|
3
|
+
//#region src/tools/index.ts
|
|
4
|
+
/** Define a Redtuma tool. The id is used as the tool name presented to the model. */
|
|
5
|
+
function createTool(config) {
|
|
6
|
+
return { ...config };
|
|
7
|
+
}
|
|
8
|
+
function isToolAction(value) {
|
|
9
|
+
return !!value && typeof value === "object" && typeof value.execute === "function" && "inputSchema" in value && "description" in value;
|
|
10
|
+
}
|
|
11
|
+
/** Adapt a {@link ToolAction} into the AI SDK `tool()` shape. */
|
|
12
|
+
function toAISDKTool(toolAction, runtimeContext) {
|
|
13
|
+
return tool({
|
|
14
|
+
description: toolAction.description,
|
|
15
|
+
parameters: toolAction.inputSchema,
|
|
16
|
+
execute: async (args, { abortSignal }) => toolAction.execute({
|
|
17
|
+
context: args,
|
|
18
|
+
runtimeContext,
|
|
19
|
+
abortSignal
|
|
20
|
+
})
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Build the AI SDK tool map from a record of Redtuma tools and/or raw AI SDK
|
|
25
|
+
* tools. Redtuma `ToolAction`s are adapted; anything else is passed through.
|
|
26
|
+
*/
|
|
27
|
+
function buildToolset(tools, runtimeContext) {
|
|
28
|
+
if (!tools) return void 0;
|
|
29
|
+
const out = {};
|
|
30
|
+
for (const [name, t] of Object.entries(tools)) out[name] = isToolAction(t) ? toAISDKTool(t, runtimeContext) : t;
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
export { buildToolset, createTool, isToolAction, toAISDKTool };
|
|
36
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["aiTool","out: Record<string, AiTool>"],"sources":["../../src/tools/index.ts"],"sourcesContent":["import { tool as aiTool, type Tool as AiTool } from 'ai'\nimport type { z } from 'zod'\nimport { RuntimeContext } from '../types'\n\nexport interface ToolExecuteContext<TInput> {\n /** Validated tool input. */\n context: TInput\n runtimeContext: RuntimeContext\n abortSignal?: AbortSignal\n}\n\nexport interface ToolAction<\n TInputSchema extends z.ZodTypeAny = z.ZodTypeAny,\n TOutputSchema extends z.ZodTypeAny = z.ZodTypeAny,\n> {\n id: string\n description: string\n inputSchema: TInputSchema\n outputSchema?: TOutputSchema\n execute: (ctx: ToolExecuteContext<z.infer<TInputSchema>>) => Promise<unknown> | unknown\n}\n\n/** Define a Redtuma tool. The id is used as the tool name presented to the model. */\nexport function createTool<\n TInputSchema extends z.ZodTypeAny,\n TOutputSchema extends z.ZodTypeAny = z.ZodTypeAny,\n>(config: {\n id: string\n description: string\n inputSchema: TInputSchema\n outputSchema?: TOutputSchema\n execute: (ctx: ToolExecuteContext<z.infer<TInputSchema>>) => Promise<unknown> | unknown\n}): ToolAction<TInputSchema, TOutputSchema> {\n return { ...config }\n}\n\n/** A tool with its schema generics erased; use for heterogeneous collections. */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyToolAction = ToolAction<any, any>\n\nexport function isToolAction(value: unknown): value is ToolAction {\n return (\n !!value &&\n typeof value === 'object' &&\n typeof (value as ToolAction).execute === 'function' &&\n 'inputSchema' in value &&\n 'description' in value\n )\n}\n\n/** Adapt a {@link ToolAction} into the AI SDK `tool()` shape. */\nexport function toAISDKTool(\n toolAction: ToolAction,\n runtimeContext: RuntimeContext,\n): AiTool {\n return aiTool({\n description: toolAction.description,\n parameters: toolAction.inputSchema,\n execute: async (args, { abortSignal }) =>\n toolAction.execute({ context: args, runtimeContext, abortSignal }),\n })\n}\n\n/**\n * Build the AI SDK tool map from a record of Redtuma tools and/or raw AI SDK\n * tools. Redtuma `ToolAction`s are adapted; anything else is passed through.\n */\nexport function buildToolset(\n tools: Record<string, AnyToolAction | AiTool> | undefined,\n runtimeContext: RuntimeContext,\n): Record<string, AiTool> | undefined {\n if (!tools) return undefined\n const out: Record<string, AiTool> = {}\n for (const [name, t] of Object.entries(tools)) {\n out[name] = isToolAction(t) ? toAISDKTool(t, runtimeContext) : (t as AiTool)\n }\n return out\n}\n"],"mappings":";;;;AAuBA,SAAgB,WAGd,QAM0C;AAC1C,QAAO,EAAE,GAAG,QAAQ;;AAOtB,SAAgB,aAAa,OAAqC;AAChE,QACE,CAAC,CAAC,SACF,OAAO,UAAU,YACjB,OAAQ,MAAqB,YAAY,cACzC,iBAAiB,SACjB,iBAAiB;;;AAKrB,SAAgB,YACd,YACA,gBACQ;AACR,QAAOA,KAAO;EACZ,aAAa,WAAW;EACxB,YAAY,WAAW;EACvB,SAAS,OAAO,MAAM,EAAE,kBACtB,WAAW,QAAQ;GAAE,SAAS;GAAM;GAAgB;GAAa,CAAC;EACrE,CAAC;;;;;;AAOJ,SAAgB,aACd,OACA,gBACoC;AACpC,KAAI,CAAC,MAAO,QAAO;CACnB,MAAMC,MAA8B,EAAE;AACtC,MAAK,MAAM,CAAC,MAAM,MAAM,OAAO,QAAQ,MAAM,CAC3C,KAAI,QAAQ,aAAa,EAAE,GAAG,YAAY,GAAG,eAAe,GAAI;AAElE,QAAO"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { CoreMessage as CoreMessage$1, LanguageModel } from "ai";
|
|
2
|
+
|
|
3
|
+
//#region src/types.d.ts
|
|
4
|
+
/** A model is either a `'provider/model'` string or a concrete AI SDK model. */
|
|
5
|
+
type ModelConfig = string | LanguageModel;
|
|
6
|
+
/** A value that may be provided directly or computed from a runtime context. */
|
|
7
|
+
type DynamicArgument<T> = T | ((ctx: {
|
|
8
|
+
runtimeContext: RuntimeContext;
|
|
9
|
+
}) => T | Promise<T>);
|
|
10
|
+
/** Arbitrary per-invocation key/value context passed through to tools/instructions. */
|
|
11
|
+
declare class RuntimeContext<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
12
|
+
private readonly map;
|
|
13
|
+
constructor(initial?: T);
|
|
14
|
+
get<K extends keyof T & string>(key: K): T[K] | undefined;
|
|
15
|
+
set<K extends keyof T & string>(key: K, value: T[K]): void;
|
|
16
|
+
has(key: string): boolean;
|
|
17
|
+
}
|
|
18
|
+
interface Logger {
|
|
19
|
+
debug(msg: string, meta?: unknown): void;
|
|
20
|
+
info(msg: string, meta?: unknown): void;
|
|
21
|
+
warn(msg: string, meta?: unknown): void;
|
|
22
|
+
error(msg: string, meta?: unknown): void;
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { type CoreMessage$1 as CoreMessage, DynamicArgument, Logger, ModelConfig, RuntimeContext };
|
|
26
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../src/types.ts"],"sourcesContent":[],"mappings":";;;;KAGY,WAAA,YAAuB;AAAnC;AAGY,KAAA,eAAe,CAAA,CAAA,CAAA,GACvB,CADuB,GAAA,CAAA,CAAA,GAAA,EAAA;EACvB,cAAA,EACyB,cADzB;CACyB,EAAA,GAAqB,CAArB,GAAyB,OAAzB,CAAiC,CAAjC,CAAA,CAAA;;AAAiC,cAGjD,cAHiD,CAAA,UAGxB,MAHwB,CAAA,MAAA,EAAA,OAAA,CAAA,GAGE,MAHF,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA,CAAA;EAAR,iBAAA,GAAA;EAAO,WAAA,CAAA,OAAA,CAAA,EAMrC,CANqC;EAGhD,GAAA,CAAA,UAAA,MASS,CATK,GAAA,MAAA,CAAA,CAAA,GAAA,EASY,CATZ,CAAA,EASgB,CAThB,CASkB,CATlB,CAAA,GAAA,SAAA;EAAW,GAAA,CAAA,UAAA,MAahB,CAbgB,GAAA,MAAA,CAAA,CAAA,GAAA,EAaC,CAbD,EAAA,KAAA,EAaW,CAbX,CAaa,CAbb,CAAA,CAAA,EAAA,IAAA;EAA0B,GAAA,CAAA,GAAA,EAAA,MAAA,CAAA,EAAA,OAAA;;AAS1C,UAaL,MAAA,CAbK;EAAiB,KAAA,CAAA,GAAA,EAAA,MAAA,EAAA,IAAA,CAAA,EAAA,OAAA,CAAA,EAAA,IAAA;EAAI,IAAA,CAAA,GAAA,EAAA,MAAA,EAAA,IAAA,CAAA,EAAA,OAAA,CAAA,EAAA,IAAA;EAAE,IAAA,CAAA,GAAA,EAAA,MAAA,EAAA,IAAA,CAAA,EAAA,OAAA,CAAA,EAAA,IAAA;EAIvB,KAAA,CAAA,GAAA,EAAA,MAAA,EAAA,IAAA,CAAA,EAAA,OAAA,CAAA,EAAA,IAAA"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/types.ts
|
|
2
|
+
/** Arbitrary per-invocation key/value context passed through to tools/instructions. */
|
|
3
|
+
var RuntimeContext = class {
|
|
4
|
+
map = /* @__PURE__ */ new Map();
|
|
5
|
+
constructor(initial) {
|
|
6
|
+
if (initial) for (const [k, v] of Object.entries(initial)) this.map.set(k, v);
|
|
7
|
+
}
|
|
8
|
+
get(key) {
|
|
9
|
+
return this.map.get(key);
|
|
10
|
+
}
|
|
11
|
+
set(key, value) {
|
|
12
|
+
this.map.set(key, value);
|
|
13
|
+
}
|
|
14
|
+
has(key) {
|
|
15
|
+
return this.map.has(key);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
//#endregion
|
|
20
|
+
export { RuntimeContext };
|
|
21
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../src/types.ts"],"sourcesContent":["import type { CoreMessage, LanguageModel } from 'ai'\n\n/** A model is either a `'provider/model'` string or a concrete AI SDK model. */\nexport type ModelConfig = string | LanguageModel\n\n/** A value that may be provided directly or computed from a runtime context. */\nexport type DynamicArgument<T> =\n | T\n | ((ctx: { runtimeContext: RuntimeContext }) => T | Promise<T>)\n\n/** Arbitrary per-invocation key/value context passed through to tools/instructions. */\nexport class RuntimeContext<T extends Record<string, unknown> = Record<string, unknown>> {\n private readonly map = new Map<string, unknown>()\n\n constructor(initial?: T) {\n if (initial) {\n for (const [k, v] of Object.entries(initial)) this.map.set(k, v)\n }\n }\n\n get<K extends keyof T & string>(key: K): T[K] | undefined {\n return this.map.get(key) as T[K] | undefined\n }\n\n set<K extends keyof T & string>(key: K, value: T[K]): void {\n this.map.set(key, value)\n }\n\n has(key: string): boolean {\n return this.map.has(key)\n }\n}\n\nexport interface Logger {\n debug(msg: string, meta?: unknown): void\n info(msg: string, meta?: unknown): void\n warn(msg: string, meta?: unknown): void\n error(msg: string, meta?: unknown): void\n}\n\n/** Shared dependencies injected into components when registered on a Redtuma instance. */\nexport interface SharedDeps {\n logger?: Logger\n storage?: unknown\n memory?: unknown\n telemetry?: unknown\n}\n\nexport type { CoreMessage }\n"],"mappings":";;AAWA,IAAa,iBAAb,MAAyF;CACvF,AAAiB,sBAAM,IAAI,KAAsB;CAEjD,YAAY,SAAa;AACvB,MAAI,QACF,MAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,QAAQ,CAAE,MAAK,IAAI,IAAI,GAAG,EAAE;;CAIpE,IAAgC,KAA0B;AACxD,SAAO,KAAK,IAAI,IAAI,IAAI;;CAG1B,IAAgC,KAAQ,OAAmB;AACzD,OAAK,IAAI,IAAI,KAAK,MAAM;;CAG1B,IAAI,KAAsB;AACxB,SAAO,KAAK,IAAI,IAAI,IAAI"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { Logger, RuntimeContext } from "../types.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
//#region src/workflows/index.d.ts
|
|
5
|
+
interface StepExecuteContext<TInput = unknown, TResume = unknown> {
|
|
6
|
+
inputData: TInput;
|
|
7
|
+
runtimeContext: RuntimeContext;
|
|
8
|
+
/** Result of a previously completed step by id. */
|
|
9
|
+
getStepResult: (stepId: string) => unknown;
|
|
10
|
+
/** Data passed to `run.resume()` when resuming a suspended step. */
|
|
11
|
+
resumeData?: TResume;
|
|
12
|
+
/** Suspend the workflow for human-in-the-loop; throws to halt execution. */
|
|
13
|
+
suspend: (payload?: unknown) => never;
|
|
14
|
+
}
|
|
15
|
+
interface Step<TInputSchema extends z.ZodTypeAny = z.ZodTypeAny, TOutputSchema extends z.ZodTypeAny = z.ZodTypeAny> {
|
|
16
|
+
id: string;
|
|
17
|
+
inputSchema?: TInputSchema;
|
|
18
|
+
outputSchema?: TOutputSchema;
|
|
19
|
+
resumeSchema?: z.ZodTypeAny;
|
|
20
|
+
suspendSchema?: z.ZodTypeAny;
|
|
21
|
+
execute: (ctx: StepExecuteContext) => Promise<unknown> | unknown;
|
|
22
|
+
}
|
|
23
|
+
declare function createStep<TInputSchema extends z.ZodTypeAny = z.ZodTypeAny, TOutputSchema extends z.ZodTypeAny = z.ZodTypeAny>(config: {
|
|
24
|
+
id: string;
|
|
25
|
+
inputSchema?: TInputSchema;
|
|
26
|
+
outputSchema?: TOutputSchema;
|
|
27
|
+
resumeSchema?: z.ZodTypeAny;
|
|
28
|
+
suspendSchema?: z.ZodTypeAny;
|
|
29
|
+
execute: (ctx: StepExecuteContext) => Promise<unknown> | unknown;
|
|
30
|
+
}): Step<TInputSchema, TOutputSchema>;
|
|
31
|
+
type Condition = (args: {
|
|
32
|
+
inputData: unknown;
|
|
33
|
+
runtimeContext: RuntimeContext;
|
|
34
|
+
}) => boolean | Promise<boolean>;
|
|
35
|
+
type Node = {
|
|
36
|
+
kind: 'step';
|
|
37
|
+
step: Step;
|
|
38
|
+
} | {
|
|
39
|
+
kind: 'parallel';
|
|
40
|
+
steps: Step[];
|
|
41
|
+
} | {
|
|
42
|
+
kind: 'branch';
|
|
43
|
+
branches: [Condition, Step][];
|
|
44
|
+
} | {
|
|
45
|
+
kind: 'dountil';
|
|
46
|
+
step: Step;
|
|
47
|
+
condition: Condition;
|
|
48
|
+
} | {
|
|
49
|
+
kind: 'foreach';
|
|
50
|
+
step: Step;
|
|
51
|
+
} | {
|
|
52
|
+
kind: 'map';
|
|
53
|
+
fn: (input: unknown) => unknown;
|
|
54
|
+
};
|
|
55
|
+
type RunStatus = 'success' | 'suspended' | 'failed';
|
|
56
|
+
interface RunResult {
|
|
57
|
+
status: RunStatus;
|
|
58
|
+
result?: unknown;
|
|
59
|
+
error?: Error;
|
|
60
|
+
suspended?: {
|
|
61
|
+
stepId: string;
|
|
62
|
+
payload: unknown;
|
|
63
|
+
};
|
|
64
|
+
steps: Record<string, unknown>;
|
|
65
|
+
}
|
|
66
|
+
declare class Workflow {
|
|
67
|
+
config: {
|
|
68
|
+
id: string;
|
|
69
|
+
inputSchema?: z.ZodTypeAny;
|
|
70
|
+
outputSchema?: z.ZodTypeAny;
|
|
71
|
+
};
|
|
72
|
+
readonly id: string;
|
|
73
|
+
private nodes;
|
|
74
|
+
private committed;
|
|
75
|
+
logger: Logger;
|
|
76
|
+
constructor(config: {
|
|
77
|
+
id: string;
|
|
78
|
+
inputSchema?: z.ZodTypeAny;
|
|
79
|
+
outputSchema?: z.ZodTypeAny;
|
|
80
|
+
});
|
|
81
|
+
then(step: Step): this;
|
|
82
|
+
parallel(steps: Step[]): this;
|
|
83
|
+
branch(branches: [Condition, Step][]): this;
|
|
84
|
+
dountil(step: Step, condition: Condition): this;
|
|
85
|
+
foreach(step: Step): this;
|
|
86
|
+
map(fn: (input: unknown) => unknown): this;
|
|
87
|
+
commit(): this;
|
|
88
|
+
createRun(): Run;
|
|
89
|
+
}
|
|
90
|
+
declare class Run {
|
|
91
|
+
readonly workflowId: string;
|
|
92
|
+
private readonly nodes;
|
|
93
|
+
private snapshot;
|
|
94
|
+
constructor(workflowId: string, nodes: Node[]);
|
|
95
|
+
start(args: {
|
|
96
|
+
inputData: unknown;
|
|
97
|
+
runtimeContext?: RuntimeContext;
|
|
98
|
+
}): Promise<RunResult>;
|
|
99
|
+
resume(args: {
|
|
100
|
+
step: string;
|
|
101
|
+
resumeData?: unknown;
|
|
102
|
+
runtimeContext?: RuntimeContext;
|
|
103
|
+
}): Promise<RunResult>;
|
|
104
|
+
private execute;
|
|
105
|
+
private runStep;
|
|
106
|
+
}
|
|
107
|
+
declare function createWorkflow(config: {
|
|
108
|
+
id: string;
|
|
109
|
+
inputSchema?: z.ZodTypeAny;
|
|
110
|
+
outputSchema?: z.ZodTypeAny;
|
|
111
|
+
}): Workflow;
|
|
112
|
+
//#endregion
|
|
113
|
+
export { Run, RunResult, RunStatus, Step, StepExecuteContext, Workflow, createStep, createWorkflow };
|
|
114
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/workflows/index.ts"],"sourcesContent":[],"mappings":";;;;UAIiB;aACJ;EADI,cAAA,EAEC,cAFiB;EACtB;EACK,aAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,GAAA,OAAA;EAIH;EAAO,UAAA,CAAA,EAAP,OAAO;EAKL;EACQ,OAAA,EAAA,CAAA,OAAA,CAAA,EAAA,OAAA,EAAA,GAAA,KAAA;;AACC,UAFT,IAES,CAAA,qBADH,CAAA,CAAE,UACC,GADY,CAAA,CAAE,UACd,EAAA,sBAAF,CAAA,CAAE,UAAA,GAAa,CAAA,CAAE,UAAf,CAAA,CAAA;EAAe,EAAA,EAAA,MAAA;EAGzB,WAAA,CAAA,EAAA,YAAA;EACC,YAAA,CAAA,EAAA,aAAA;EACE,YAAA,CAAA,EAAF,CAAA,CAAE,UAAA;EACC,aAAA,CAAA,EAAF,CAAA,CAAE,UAAA;EACH,OAAA,EAAA,CAAA,GAAA,EAAA,kBAAA,EAAA,GAAuB,OAAvB,CAAA,OAAA,CAAA,GAAA,OAAA;;AAA8B,iBAG/B,UAH+B,CAAA,qBAIxB,CAAA,CAAE,UAJsB,GAIT,CAAA,CAAE,UAJO,EAAA,sBAKvB,CAAA,CAAE,UALqB,GAKR,CAAA,CAAE,UALM,CAAA,CAAA,MAAA,EAAA;EAG/B,EAAA,EAAA,MAAA;EACS,WAAA,CAAA,EAIT,YAJS;EAAe,YAAA,CAAA,EAKvB,aALuB;EACd,YAAA,CAAA,EAKT,CAAA,CAAE,UALO;EAAe,aAAA,CAAA,EAMvB,CAAA,CAAE,UANqB;EAGzB,OAAA,EAAA,CAAA,GAAA,EAIC,kBAJD,EAAA,GAIwB,OAJxB,CAAA,OAAA,CAAA,GAAA,OAAA;CACC,CAAA,EAIb,IAJa,CAIR,YAJQ,EAIM,aAJN,CAAA;KAeZ,SAAA,GAdc,CAAA,IAAA,EAAA;EACC,SAAA,EAAA,OAAA;EACH,cAAA,EAY6C,cAZ7C;CAAuB,EAAA,GAAA,OAAA,GAYqD,OAZrD,CAAA,OAAA,CAAA;KAcnC,IAAA,GAbI;EAAc,IAAA,EAAA,MAAA;EAAnB,IAAA,EAcsB,IAdtB;CAAI,GAAA;EAWH,IAAA,EAAA,UAAS;EAET,KAAA,EAE0B,IAFtB,EAAA;CACiB,GAAA;EACK,IAAA,EAAA,QAAA;EACE,QAAA,EAAA,CAAA,SAAA,EAAW,IAAX,CAAA,EAAA;CAAW,GAAA;EACf,IAAA,EAAA,SAAA;EAAiB,IAAA,EAAjB,IAAiB;EACjB,SAAA,EADiB,SACjB;CAAI,GAAA;EAGrB,IAAA,EAAA,SAAS;EAEJ,IAAA,EALY,IAKZ;CACP,GAAA;EAEA,IAAA,EAAA,KAAA;EAED,EAAA,EAAA,CAAA,KAAA,EAAA,OAAA,EAAA,GAAA,OAAA;CAAM;AAUF,KAjBD,SAAA,GAiBS,SAAA,GAAA,WAAA,GAAA,QAAA;AAMsC,UArB1C,SAAA,CAqB0C;EAA6B,MAAA,EApB9E,SAoB8E;EAF9E,MAAA,CAAA,EAAA,OAAA;EAEiD,KAAA,CAAA,EAlBjD,KAkBiD;EAA6B,SAAA,CAAA,EAAA;IAI3E,MAAA,EAAA,MAAA;IAIK,OAAA,EAAA,OAAA;EAIE,CAAA;EAAW,KAAA,EA5BtB,MA4BsB,CAAA,MAAA,EAAA,OAAA,CAAA;;AAIE,cAtBpB,QAAA,CAsBoB;EAIjB,MAAA,EAAA;IAaD,EAAA,EAAA,MAAA;IAAG,WAAA,CAAA,EAjCuC,CAAA,CAAE,UAiCzC;IAQL,YAAG,CAAA,EAzCsE,CAAA,CAAE,UAyCxE;EAKY,CAAA;EAG+B,SAAA,EAAA,EAAA,MAAA;EAA2B,QAAA,KAAA;EAAR,QAAA,SAAA;EAQzD,MAAA,EA3DX,MA2DW;EACP,WAAA,CAAA,MAAA,EAAA;IAAR,EAAA,EAAA,MAAA;IAAO,WAAA,CAAA,EA1D4C,CAAA,CAAE,UA0D9C;IA8GG,YAAA,CAAc,EAxKwD,CAAA,CAAE,UAwK1D;EAEZ,CAAA;EACC,IAAA,CAAA,IAAA,EAvKN,IAuKM,CAAA,EAAA,IAAA;EACf,QAAA,CAAA,KAAA,EApKc,IAoKd,EAAA,CAAA,EAAA,IAAA;EAAQ,MAAA,CAAA,QAAA,EAAA,CAhKQ,SAgKR,EAhKmB,IAgKnB,CAAA,EAAA,CAAA,EAAA,IAAA;gBA5JI,iBAAiB;gBAIjB;;;eAaD;;cAQF,GAAA;;;;yCAKe;;;qBAG+B;MAAmB,QAAQ;;;;qBAQjE;MACf,QAAQ;;;;iBA8GE,cAAA;;gBAEA,CAAA,CAAE;iBACD,CAAA,CAAE;IACf"}
|