@radaros/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.
Files changed (48) hide show
  1. package/dist/index.d.ts +887 -0
  2. package/dist/index.js +3462 -0
  3. package/package.json +64 -0
  4. package/src/agent/agent.ts +314 -0
  5. package/src/agent/llm-loop.ts +263 -0
  6. package/src/agent/run-context.ts +35 -0
  7. package/src/agent/types.ts +77 -0
  8. package/src/events/event-bus.ts +45 -0
  9. package/src/events/types.ts +16 -0
  10. package/src/guardrails/types.ts +5 -0
  11. package/src/hooks/types.ts +6 -0
  12. package/src/index.ts +111 -0
  13. package/src/knowledge/knowledge-base.ts +146 -0
  14. package/src/logger/logger.ts +232 -0
  15. package/src/memory/memory.ts +87 -0
  16. package/src/memory/types.ts +13 -0
  17. package/src/models/provider.ts +22 -0
  18. package/src/models/providers/anthropic.ts +330 -0
  19. package/src/models/providers/google.ts +361 -0
  20. package/src/models/providers/ollama.ts +211 -0
  21. package/src/models/providers/openai.ts +323 -0
  22. package/src/models/registry.ts +90 -0
  23. package/src/models/types.ts +112 -0
  24. package/src/session/session-manager.ts +75 -0
  25. package/src/session/types.ts +10 -0
  26. package/src/storage/driver.ts +10 -0
  27. package/src/storage/in-memory.ts +44 -0
  28. package/src/storage/mongodb.ts +70 -0
  29. package/src/storage/postgres.ts +81 -0
  30. package/src/storage/sqlite.ts +81 -0
  31. package/src/team/modes.ts +1 -0
  32. package/src/team/team.ts +323 -0
  33. package/src/team/types.ts +26 -0
  34. package/src/tools/define-tool.ts +20 -0
  35. package/src/tools/tool-executor.ts +131 -0
  36. package/src/tools/types.ts +27 -0
  37. package/src/vector/base.ts +44 -0
  38. package/src/vector/embeddings/google.ts +64 -0
  39. package/src/vector/embeddings/openai.ts +66 -0
  40. package/src/vector/in-memory.ts +115 -0
  41. package/src/vector/mongodb.ts +241 -0
  42. package/src/vector/pgvector.ts +169 -0
  43. package/src/vector/qdrant.ts +203 -0
  44. package/src/vector/types.ts +55 -0
  45. package/src/workflow/step-runner.ts +303 -0
  46. package/src/workflow/types.ts +55 -0
  47. package/src/workflow/workflow.ts +68 -0
  48. package/tsconfig.json +8 -0
@@ -0,0 +1,303 @@
1
+ import type { RunContext } from "../agent/run-context.js";
2
+ import type {
3
+ StepDef,
4
+ StepResult,
5
+ AgentStep,
6
+ FunctionStep,
7
+ ConditionStep,
8
+ ParallelStep,
9
+ } from "./types.js";
10
+
11
+ function isAgentStep<T>(step: StepDef<T>): step is AgentStep<T> {
12
+ return "agent" in step;
13
+ }
14
+
15
+ function isFunctionStep<T>(step: StepDef<T>): step is FunctionStep<T> {
16
+ return "run" in step;
17
+ }
18
+
19
+ function isConditionStep<T>(step: StepDef<T>): step is ConditionStep<T> {
20
+ return "condition" in step;
21
+ }
22
+
23
+ function isParallelStep<T>(step: StepDef<T>): step is ParallelStep<T> {
24
+ return "parallel" in step;
25
+ }
26
+
27
+ export class StepRunner<TState extends Record<string, unknown>> {
28
+ private retryPolicy?: { maxRetries: number; backoffMs: number };
29
+
30
+ constructor(retryPolicy?: { maxRetries: number; backoffMs: number }) {
31
+ this.retryPolicy = retryPolicy;
32
+ }
33
+
34
+ async executeSteps(
35
+ steps: StepDef<TState>[],
36
+ state: TState,
37
+ ctx: RunContext
38
+ ): Promise<{ state: TState; results: StepResult[] }> {
39
+ let currentState = { ...state };
40
+ const allResults: StepResult[] = [];
41
+
42
+ for (const step of steps) {
43
+ const { state: newState, results } = await this.executeStep(
44
+ step,
45
+ currentState,
46
+ ctx
47
+ );
48
+ currentState = newState;
49
+ allResults.push(...results);
50
+ }
51
+
52
+ return { state: currentState, results: allResults };
53
+ }
54
+
55
+ private async executeStep(
56
+ step: StepDef<TState>,
57
+ state: TState,
58
+ ctx: RunContext
59
+ ): Promise<{ state: TState; results: StepResult[] }> {
60
+ if (isConditionStep(step)) {
61
+ return this.executeConditionStep(step, state, ctx);
62
+ }
63
+
64
+ if (isParallelStep(step)) {
65
+ return this.executeParallelStep(step, state, ctx);
66
+ }
67
+
68
+ if (isAgentStep(step)) {
69
+ return this.executeAgentStep(step, state, ctx);
70
+ }
71
+
72
+ if (isFunctionStep(step)) {
73
+ return this.executeFunctionStep(step, state, ctx);
74
+ }
75
+
76
+ return { state, results: [] };
77
+ }
78
+
79
+ private async executeAgentStep(
80
+ step: AgentStep<TState>,
81
+ state: TState,
82
+ ctx: RunContext
83
+ ): Promise<{ state: TState; results: StepResult[] }> {
84
+ const startTime = Date.now();
85
+
86
+ ctx.eventBus.emit("workflow.step", {
87
+ runId: ctx.runId,
88
+ stepName: step.name,
89
+ status: "start",
90
+ });
91
+
92
+ const execute = async (): Promise<StepResult> => {
93
+ const input = step.inputFrom
94
+ ? step.inputFrom(state)
95
+ : JSON.stringify(state);
96
+
97
+ const output = await step.agent.run(input, {
98
+ sessionId: ctx.sessionId,
99
+ });
100
+
101
+ const newState = {
102
+ ...state,
103
+ [`${step.name}_output`]: output.text,
104
+ } as TState;
105
+
106
+ Object.assign(state, newState);
107
+
108
+ return {
109
+ stepName: step.name,
110
+ status: "done",
111
+ durationMs: Date.now() - startTime,
112
+ };
113
+ };
114
+
115
+ const result = await this.withRetry(step.name, execute, ctx);
116
+ return { state, results: [result] };
117
+ }
118
+
119
+ private async executeFunctionStep(
120
+ step: FunctionStep<TState>,
121
+ state: TState,
122
+ ctx: RunContext
123
+ ): Promise<{ state: TState; results: StepResult[] }> {
124
+ const startTime = Date.now();
125
+
126
+ ctx.eventBus.emit("workflow.step", {
127
+ runId: ctx.runId,
128
+ stepName: step.name,
129
+ status: "start",
130
+ });
131
+
132
+ const execute = async (): Promise<StepResult> => {
133
+ const patch = await step.run(state, ctx);
134
+ Object.assign(state, patch);
135
+
136
+ return {
137
+ stepName: step.name,
138
+ status: "done",
139
+ durationMs: Date.now() - startTime,
140
+ };
141
+ };
142
+
143
+ const result = await this.withRetry(step.name, execute, ctx);
144
+ return { state, results: [result] };
145
+ }
146
+
147
+ private async executeConditionStep(
148
+ step: ConditionStep<TState>,
149
+ state: TState,
150
+ ctx: RunContext
151
+ ): Promise<{ state: TState; results: StepResult[] }> {
152
+ const startTime = Date.now();
153
+
154
+ ctx.eventBus.emit("workflow.step", {
155
+ runId: ctx.runId,
156
+ stepName: step.name,
157
+ status: "start",
158
+ });
159
+
160
+ if (step.condition(state)) {
161
+ const { state: newState, results } = await this.executeSteps(
162
+ step.steps,
163
+ state,
164
+ ctx
165
+ );
166
+
167
+ ctx.eventBus.emit("workflow.step", {
168
+ runId: ctx.runId,
169
+ stepName: step.name,
170
+ status: "done",
171
+ });
172
+
173
+ return {
174
+ state: newState,
175
+ results: [
176
+ {
177
+ stepName: step.name,
178
+ status: "done",
179
+ durationMs: Date.now() - startTime,
180
+ },
181
+ ...results,
182
+ ],
183
+ };
184
+ }
185
+
186
+ ctx.eventBus.emit("workflow.step", {
187
+ runId: ctx.runId,
188
+ stepName: step.name,
189
+ status: "done",
190
+ });
191
+
192
+ return {
193
+ state,
194
+ results: [
195
+ {
196
+ stepName: step.name,
197
+ status: "skipped",
198
+ durationMs: Date.now() - startTime,
199
+ },
200
+ ],
201
+ };
202
+ }
203
+
204
+ private async executeParallelStep(
205
+ step: ParallelStep<TState>,
206
+ state: TState,
207
+ ctx: RunContext
208
+ ): Promise<{ state: TState; results: StepResult[] }> {
209
+ const startTime = Date.now();
210
+
211
+ ctx.eventBus.emit("workflow.step", {
212
+ runId: ctx.runId,
213
+ stepName: step.name,
214
+ status: "start",
215
+ });
216
+
217
+ const settled = await Promise.allSettled(
218
+ step.parallel.map((s) => this.executeStep(s, { ...state }, ctx))
219
+ );
220
+
221
+ const allResults: StepResult[] = [];
222
+ let mergedState = { ...state };
223
+
224
+ for (const result of settled) {
225
+ if (result.status === "fulfilled") {
226
+ Object.assign(mergedState, result.value.state);
227
+ allResults.push(...result.value.results);
228
+ } else {
229
+ allResults.push({
230
+ stepName: step.name,
231
+ status: "error",
232
+ error: result.reason?.message ?? "Unknown error",
233
+ durationMs: Date.now() - startTime,
234
+ });
235
+ }
236
+ }
237
+
238
+ ctx.eventBus.emit("workflow.step", {
239
+ runId: ctx.runId,
240
+ stepName: step.name,
241
+ status: "done",
242
+ });
243
+
244
+ return {
245
+ state: mergedState,
246
+ results: [
247
+ {
248
+ stepName: step.name,
249
+ status: "done",
250
+ durationMs: Date.now() - startTime,
251
+ },
252
+ ...allResults,
253
+ ],
254
+ };
255
+ }
256
+
257
+ private async withRetry(
258
+ stepName: string,
259
+ fn: () => Promise<StepResult>,
260
+ ctx: RunContext
261
+ ): Promise<StepResult> {
262
+ const maxRetries = this.retryPolicy?.maxRetries ?? 0;
263
+ const backoffMs = this.retryPolicy?.backoffMs ?? 1000;
264
+
265
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
266
+ try {
267
+ const result = await fn();
268
+
269
+ ctx.eventBus.emit("workflow.step", {
270
+ runId: ctx.runId,
271
+ stepName,
272
+ status: "done",
273
+ });
274
+
275
+ return result;
276
+ } catch (error) {
277
+ if (attempt === maxRetries) {
278
+ const err =
279
+ error instanceof Error ? error : new Error(String(error));
280
+
281
+ ctx.eventBus.emit("workflow.step", {
282
+ runId: ctx.runId,
283
+ stepName,
284
+ status: "error",
285
+ });
286
+
287
+ return {
288
+ stepName,
289
+ status: "error",
290
+ error: err.message,
291
+ durationMs: 0,
292
+ };
293
+ }
294
+
295
+ await new Promise((resolve) =>
296
+ setTimeout(resolve, backoffMs * Math.pow(2, attempt))
297
+ );
298
+ }
299
+ }
300
+
301
+ return { stepName, status: "error", error: "Exhausted retries", durationMs: 0 };
302
+ }
303
+ }
@@ -0,0 +1,55 @@
1
+ import type { Agent } from "../agent/agent.js";
2
+ import type { RunContext } from "../agent/run-context.js";
3
+ import type { StorageDriver } from "../storage/driver.js";
4
+ import type { EventBus } from "../events/event-bus.js";
5
+
6
+ export type StepDef<TState> =
7
+ | AgentStep<TState>
8
+ | FunctionStep<TState>
9
+ | ConditionStep<TState>
10
+ | ParallelStep<TState>;
11
+
12
+ export interface AgentStep<TState> {
13
+ name: string;
14
+ agent: Agent;
15
+ inputFrom?: (state: TState) => string;
16
+ }
17
+
18
+ export interface FunctionStep<TState> {
19
+ name: string;
20
+ run: (state: TState, ctx: RunContext) => Promise<Partial<TState>>;
21
+ }
22
+
23
+ export interface ConditionStep<TState> {
24
+ name: string;
25
+ condition: (state: TState) => boolean;
26
+ steps: StepDef<TState>[];
27
+ }
28
+
29
+ export interface ParallelStep<TState> {
30
+ name: string;
31
+ parallel: StepDef<TState>[];
32
+ }
33
+
34
+ export interface WorkflowConfig<
35
+ TState extends Record<string, unknown> = Record<string, unknown>,
36
+ > {
37
+ name: string;
38
+ initialState: TState;
39
+ steps: StepDef<TState>[];
40
+ storage?: StorageDriver;
41
+ retryPolicy?: { maxRetries: number; backoffMs: number };
42
+ eventBus?: EventBus;
43
+ }
44
+
45
+ export interface WorkflowResult<TState> {
46
+ state: TState;
47
+ stepResults: StepResult[];
48
+ }
49
+
50
+ export interface StepResult {
51
+ stepName: string;
52
+ status: "done" | "error" | "skipped";
53
+ error?: string;
54
+ durationMs: number;
55
+ }
@@ -0,0 +1,68 @@
1
+ import { v4 as uuidv4 } from "uuid";
2
+ import { EventBus } from "../events/event-bus.js";
3
+ import { RunContext } from "../agent/run-context.js";
4
+ import { StepRunner } from "./step-runner.js";
5
+ import type { WorkflowConfig, WorkflowResult } from "./types.js";
6
+
7
+ export class Workflow<
8
+ TState extends Record<string, unknown> = Record<string, unknown>,
9
+ > {
10
+ readonly name: string;
11
+ readonly eventBus: EventBus;
12
+
13
+ private config: WorkflowConfig<TState>;
14
+ private stepRunner: StepRunner<TState>;
15
+
16
+ constructor(config: WorkflowConfig<TState>) {
17
+ this.config = config;
18
+ this.name = config.name;
19
+ this.eventBus = config.eventBus ?? new EventBus();
20
+ this.stepRunner = new StepRunner<TState>(config.retryPolicy);
21
+ }
22
+
23
+ async run(opts?: {
24
+ sessionId?: string;
25
+ userId?: string;
26
+ }): Promise<WorkflowResult<TState>> {
27
+ const ctx = new RunContext({
28
+ sessionId: opts?.sessionId ?? uuidv4(),
29
+ userId: opts?.userId,
30
+ eventBus: this.eventBus,
31
+ sessionState: {},
32
+ });
33
+
34
+ this.eventBus.emit("run.start", {
35
+ runId: ctx.runId,
36
+ agentName: `workflow:${this.name}`,
37
+ input: JSON.stringify(this.config.initialState),
38
+ });
39
+
40
+ try {
41
+ const { state, results } = await this.stepRunner.executeSteps(
42
+ this.config.steps,
43
+ { ...this.config.initialState },
44
+ ctx
45
+ );
46
+
47
+ const workflowResult: WorkflowResult<TState> = {
48
+ state,
49
+ stepResults: results,
50
+ };
51
+
52
+ this.eventBus.emit("run.complete", {
53
+ runId: ctx.runId,
54
+ output: {
55
+ text: JSON.stringify(state),
56
+ toolCalls: [],
57
+ usage: { promptTokens: 0, completionTokens: 0, totalTokens: 0 },
58
+ },
59
+ });
60
+
61
+ return workflowResult;
62
+ } catch (error) {
63
+ const err = error instanceof Error ? error : new Error(String(error));
64
+ this.eventBus.emit("run.error", { runId: ctx.runId, error: err });
65
+ throw err;
66
+ }
67
+ }
68
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "rootDir": "./src"
6
+ },
7
+ "include": ["src"]
8
+ }