@alveus-ai/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.
File without changes
@@ -0,0 +1,28 @@
1
+
2
+ Serialized handler source: async(event2,ctx)=>{const result2=await ctx.db.save(event2.data);return{saved:result2}}
3
+ Mock DB: Saving hello from POC
4
+ ✅ POC Success! Result: { saved: 'saved:hello from POC' }
5
+ ✅ Arrow function test passed: { count: 6 }
6
+ Mock fetch: https://api.example.com/v2?retries=3
7
+ ✅ Configuration passing test passed: response from https://api.example.com/v2?retries=3
8
+ ✅ Complex context test passed: { saveId: 'save-id-456', response: 'AI generated response' }
9
+ Logs: [
10
+ 'INFO: Processing request for user user-789',
11
+ "db.query: SELECT * FROM users WHERE id = 'user-789'",
12
+ 'openai.complete: Summarize this document',
13
+ 'db.save: {"userId":"user-789","response":"AI generated response"}'
14
+ ]
15
+ ▶ Capability Injection POC
16
+ ✔ should inject capabilities into a deserialized function (1.540707ms)
17
+ ✔ should work with arrow functions (0.255949ms)
18
+ ✔ should pass configuration via event/state, not outer scope (0.253008ms)
19
+ ✔ should handle complex context with multiple capabilities (0.437631ms)
20
+ ✔ Capability Injection POC (3.096825ms)
21
+ ℹ tests 4
22
+ ℹ suites 1
23
+ ℹ pass 4
24
+ ℹ fail 0
25
+ ℹ cancelled 0
26
+ ℹ skipped 0
27
+ ℹ todo 0
28
+ ℹ duration_ms 1464.19065
@@ -0,0 +1,4 @@
1
+ import type { Agent, AgentHandler, AgentOptions } from './types.js';
2
+ export declare function agent$<TState = any, TEvent = any, TContext = any, TResult = any>(handler: AgentHandler<TState, TEvent, TContext, TResult>, options?: AgentOptions): Agent<TState, TEvent, TContext, TResult>;
3
+ export declare function serializeHandler(handler: (...args: unknown[]) => unknown): string;
4
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAmB,MAAM,YAAY,CAAC;AAgBrF,wBAAgB,MAAM,CAAC,MAAM,GAAG,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,QAAQ,GAAG,GAAG,EAAE,OAAO,GAAG,GAAG,EAC9E,OAAO,EAAE,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,EACxD,OAAO,CAAC,EAAE,YAAY,GACrB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAwB1C;AAYD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,GAAG,MAAM,CAEjF"}
package/dist/agent.js ADDED
@@ -0,0 +1,30 @@
1
+ import crypto from 'node:crypto';
2
+ export function agent$(handler, options) {
3
+ const handlerSource = handler.toString();
4
+ const hash = computeHash(handlerSource);
5
+ const definition = {
6
+ hash,
7
+ inputs: {
8
+ state: 'any',
9
+ event: 'any',
10
+ context: 'any',
11
+ },
12
+ metadata: {
13
+ name: options?.name,
14
+ version: options?.version,
15
+ description: options?.description,
16
+ },
17
+ };
18
+ return {
19
+ definition,
20
+ handler,
21
+ options,
22
+ };
23
+ }
24
+ function computeHash(source) {
25
+ return crypto.createHash('sha256').update(source).digest('hex');
26
+ }
27
+ export function serializeHandler(handler) {
28
+ return handler.toString();
29
+ }
30
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAiBjC,MAAM,UAAU,MAAM,CACpB,OAAwD,EACxD,OAAsB;IAGtB,MAAM,aAAa,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IACzC,MAAM,IAAI,GAAG,WAAW,CAAC,aAAa,CAAC,CAAC;IAExC,MAAM,UAAU,GAA8C;QAC5D,IAAI;QACJ,MAAM,EAAE;YACN,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,KAAK;YACZ,OAAO,EAAE,KAAK;SACf;QACD,QAAQ,EAAE;YACR,IAAI,EAAE,OAAO,EAAE,IAAI;YACnB,OAAO,EAAE,OAAO,EAAE,OAAO;YACzB,WAAW,EAAE,OAAO,EAAE,WAAW;SAClC;KACF,CAAC;IAEF,OAAO;QACL,UAAU;QACV,OAAO;QACP,OAAO;KACR,CAAC;AACJ,CAAC;AAKD,SAAS,WAAW,CAAC,MAAc;IACjC,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAClE,CAAC;AAKD,MAAM,UAAU,gBAAgB,CAAC,OAAwC;IACvE,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { agent$, serializeHandler } from './agent.js';
2
+ export type { Agent, AgentDefinition, AgentHandler, AgentOptions, ExecutionContext, VirtualAgent, } from './types.js';
3
+ export { isVirtualAgent } from './types.js';
4
+ export { isDurableContext, withDurableContext } from './runtime.js';
5
+ export type { DurableExecutionContext, ExecutionRequest, ExecutionResult, ExecutionStatus, Registry, Runtime, RuntimeConfig, SimpleRuntimeConfig, DurableRuntimeConfig, ChatMessage, ChatOptions, LLMCapability, StorageCapability, BlobStore, AlveusEvent, EventCapability, LoggerCapability, } from './runtime.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGtD,YAAY,EACV,KAAK,EACL,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,YAAY,GACb,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAG5C,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEpE,YAAY,EAEV,uBAAuB,EACvB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,QAAQ,EACR,OAAO,EACP,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EAEpB,WAAW,EACX,WAAW,EACX,aAAa,EAEb,iBAAiB,EACjB,SAAS,EAET,WAAW,EACX,eAAe,EAEf,gBAAgB,GACjB,MAAM,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { agent$, serializeHandler } from './agent.js';
2
+ export { isVirtualAgent } from './types.js';
3
+ export { isDurableContext, withDurableContext } from './runtime.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAatD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAG5C,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,121 @@
1
+ import type { ExecutionContext } from './types.js';
2
+ export interface AlveusEvent {
3
+ id: string;
4
+ topic: string;
5
+ data: any;
6
+ source?: string;
7
+ timestamp: number;
8
+ targetWorkflowId?: string;
9
+ }
10
+ export interface EventCapability {
11
+ emit(topic: string, data: any): Promise<void>;
12
+ waitFor(topic: string, timeoutMs?: number): Promise<AlveusEvent>;
13
+ }
14
+ export interface SecretsCapability {
15
+ get(key: string): string | undefined;
16
+ has(key: string): boolean;
17
+ keys(): string[];
18
+ }
19
+ export interface LoggerCapability {
20
+ info(message: string, attrs?: Record<string, any>): void;
21
+ warn(message: string, attrs?: Record<string, any>): void;
22
+ error(message: string, attrs?: Record<string, any>): void;
23
+ debug(message: string, attrs?: Record<string, any>): void;
24
+ }
25
+ export interface ChatMessage {
26
+ role: 'system' | 'user' | 'assistant';
27
+ content: string;
28
+ }
29
+ export interface ChatOptions {
30
+ provider?: 'openai' | 'anthropic' | 'ollama' | 'mock';
31
+ model?: string;
32
+ temperature?: number;
33
+ jsonMode?: boolean;
34
+ maxTokens?: number;
35
+ streamId?: string;
36
+ }
37
+ export interface LLMCapability {
38
+ chat(messages: ChatMessage[], options?: ChatOptions): Promise<string>;
39
+ }
40
+ export interface StorageCapability {
41
+ put(data: string | Buffer): Promise<string>;
42
+ get(key: string): Promise<string | null>;
43
+ }
44
+ export interface BlobStore {
45
+ put(data: string | Buffer): Promise<string>;
46
+ get(key: string): Promise<string | null>;
47
+ exists(key: string): Promise<boolean>;
48
+ delete?(key: string): Promise<void>;
49
+ list?(): Promise<string[]>;
50
+ }
51
+ export interface DurableExecutionContext extends ExecutionContext {
52
+ sleep(duration: number | string): Promise<void>;
53
+ sleepUntil(timestamp: string | Date): Promise<void>;
54
+ getExecutionId(): string;
55
+ getAttempt(): number;
56
+ log: {
57
+ info(message: string, ...args: any[]): void;
58
+ warn(message: string, ...args: any[]): void;
59
+ error(message: string, ...args: any[]): void;
60
+ debug(message: string, ...args: any[]): void;
61
+ };
62
+ }
63
+ export interface ExecutionRequest<TState = any, TEvent = any> {
64
+ hash: string;
65
+ state: TState;
66
+ event: TEvent;
67
+ executionId?: string;
68
+ parentExecutionId?: string;
69
+ }
70
+ export interface ExecutionResult<TResult = any> {
71
+ success: boolean;
72
+ result?: TResult;
73
+ error?: string;
74
+ metadata: {
75
+ hash: string;
76
+ executionId: string;
77
+ duration: number;
78
+ timestamp: string;
79
+ attempts?: number;
80
+ };
81
+ }
82
+ export interface Registry {
83
+ store(hash: string, content: string): Promise<void>;
84
+ retrieve(hash: string): Promise<string | null>;
85
+ list(): Promise<string[]>;
86
+ exists(hash: string): Promise<boolean>;
87
+ }
88
+ export interface Runtime {
89
+ readonly name: string;
90
+ start(): Promise<void>;
91
+ stop(): Promise<void>;
92
+ execute<TState = any, TEvent = any, TResult = any>(request: ExecutionRequest<TState, TEvent>): Promise<ExecutionResult<TResult>>;
93
+ getExecutionStatus(executionId: string): Promise<ExecutionStatus>;
94
+ cancelExecution(executionId: string): Promise<void>;
95
+ }
96
+ export interface ExecutionStatus {
97
+ executionId: string;
98
+ hash: string;
99
+ status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
100
+ startedAt?: string;
101
+ completedAt?: string;
102
+ error?: string;
103
+ result?: any;
104
+ }
105
+ export interface RuntimeConfig {
106
+ registry: Registry;
107
+ capabilities?: Record<string, any>;
108
+ }
109
+ export interface DurableRuntimeConfig extends RuntimeConfig {
110
+ address: string;
111
+ namespace: string;
112
+ taskQueue: string;
113
+ identity?: string;
114
+ }
115
+ export interface SimpleRuntimeConfig extends RuntimeConfig {
116
+ port?: number;
117
+ host?: string;
118
+ }
119
+ export declare function isDurableContext(ctx: ExecutionContext): ctx is DurableExecutionContext;
120
+ export declare function withDurableContext<TState, TEvent, TResult>(handler: (state: TState, event: TEvent, ctx: DurableExecutionContext) => Promise<TResult>): (state: TState, event: TEvent, ctx: ExecutionContext) => Promise<TResult>;
121
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ export function isDurableContext(ctx) {
2
+ return 'sleep' in ctx && typeof ctx.sleep === 'function';
3
+ }
4
+ export function withDurableContext(handler) {
5
+ return async (state, event, ctx) => {
6
+ const durableCtx = isDurableContext(ctx)
7
+ ? ctx
8
+ : {
9
+ ...ctx,
10
+ sleep: async (duration) => {
11
+ const ms = typeof duration === 'number' ? duration : parseDuration(duration);
12
+ return new Promise((resolve) => setTimeout(resolve, ms));
13
+ },
14
+ sleepUntil: async (timestamp) => {
15
+ const target = typeof timestamp === 'string' ? new Date(timestamp) : timestamp;
16
+ const now = Date.now();
17
+ const delay = target.getTime() - now;
18
+ if (delay > 0) {
19
+ await new Promise((resolve) => setTimeout(resolve, delay));
20
+ }
21
+ },
22
+ getExecutionId: () => `simple-${Date.now()}-${Math.random().toString(36).slice(2)}`,
23
+ getAttempt: () => 1,
24
+ log: {
25
+ info: (msg, ...args) => console.log(`[INFO] ${msg}`, ...args),
26
+ warn: (msg, ...args) => console.warn(`[WARN] ${msg}`, ...args),
27
+ error: (msg, ...args) => console.error(`[ERROR] ${msg}`, ...args),
28
+ debug: (msg, ...args) => console.debug(`[DEBUG] ${msg}`, ...args),
29
+ },
30
+ };
31
+ return handler(state, event, durableCtx);
32
+ };
33
+ }
34
+ function parseDuration(duration) {
35
+ const match = duration.match(/^P(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d+)?)S)?)?$/);
36
+ if (!match) {
37
+ throw new Error(`Invalid duration format: ${duration}`);
38
+ }
39
+ const [, days, hours, minutes, seconds] = match;
40
+ let ms = 0;
41
+ if (days)
42
+ ms += parseInt(days, 10) * 24 * 60 * 60 * 1000;
43
+ if (hours)
44
+ ms += parseInt(hours, 10) * 60 * 60 * 1000;
45
+ if (minutes)
46
+ ms += parseInt(minutes, 10) * 60 * 1000;
47
+ if (seconds)
48
+ ms += parseFloat(seconds) * 1000;
49
+ return ms;
50
+ }
51
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAkfA,MAAM,UAAU,gBAAgB,CAAC,GAAqB;IACpD,OAAO,OAAO,IAAI,GAAG,IAAI,OAAQ,GAAW,CAAC,KAAK,KAAK,UAAU,CAAC;AACpE,CAAC;AAqBD,MAAM,UAAU,kBAAkB,CAChC,OAAyF;IAEzF,OAAO,KAAK,EAAE,KAAa,EAAE,KAAa,EAAE,GAAqB,EAAE,EAAE;QAEnE,MAAM,UAAU,GAA4B,gBAAgB,CAAC,GAAG,CAAC;YAC/D,CAAC,CAAC,GAAG;YACL,CAAC,CAAC;gBACE,GAAG,GAAG;gBACN,KAAK,EAAE,KAAK,EAAE,QAAyB,EAAE,EAAE;oBACzC,MAAM,EAAE,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;oBAC7E,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;gBAC3D,CAAC;gBACD,UAAU,EAAE,KAAK,EAAE,SAAwB,EAAE,EAAE;oBAC7C,MAAM,MAAM,GAAG,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;oBAC/E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;oBACvB,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC;oBACrC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;wBACd,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;oBAC7D,CAAC;gBACH,CAAC;gBACD,cAAc,EAAE,GAAG,EAAE,CAAC,UAAU,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;gBACnF,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;gBACnB,GAAG,EAAE;oBACH,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC;oBAC7D,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC;oBAC9D,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC;oBACjE,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC;iBAClE;aACF,CAAC;QAEN,OAAO,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;IAC3C,CAAC,CAAC;AACJ,CAAC;AAMD,SAAS,aAAa,CAAC,QAAgB;IACrC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAC;IAChG,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC;IAChD,IAAI,EAAE,GAAG,CAAC,CAAC;IAEX,IAAI,IAAI;QAAE,EAAE,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IACzD,IAAI,KAAK;QAAE,EAAE,IAAI,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IACtD,IAAI,OAAO;QAAE,EAAE,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;IACrD,IAAI,OAAO;QAAE,EAAE,IAAI,UAAU,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IAE9C,OAAO,EAAE,CAAC;AACZ,CAAC"}
@@ -0,0 +1,47 @@
1
+ export interface AgentDefinition<TState = any, TEvent = any, TContext = any> {
2
+ hash: string;
3
+ inputs: {
4
+ state: string;
5
+ event: string;
6
+ context: string;
7
+ };
8
+ metadata?: {
9
+ name?: string;
10
+ version?: string;
11
+ description?: string;
12
+ };
13
+ __types?: {
14
+ state: TState;
15
+ event: TEvent;
16
+ context: TContext;
17
+ };
18
+ }
19
+ export type AgentHandler<TState = any, TEvent = any, TContext = any, TResult = any> = (state: TState, event: TEvent, context: TContext) => Promise<TResult> | TResult;
20
+ export interface AgentOptions {
21
+ name?: string;
22
+ description?: string;
23
+ version?: string;
24
+ }
25
+ export interface Agent<TState = any, TEvent = any, TContext = any, TResult = any> {
26
+ definition: AgentDefinition<TState, TEvent, TContext>;
27
+ handler: AgentHandler<TState, TEvent, TContext, TResult>;
28
+ options?: AgentOptions;
29
+ }
30
+ export interface VirtualAgent<TInput = any> {
31
+ definition: Agent;
32
+ defaultInput: Partial<TInput>;
33
+ }
34
+ export declare function isVirtualAgent(agent: any): agent is VirtualAgent;
35
+ export interface ExecutionContext {
36
+ workflowId: string;
37
+ call<TInput = any, TOutput = any>(agent: Agent<any, TInput, any, TOutput> | string, input: TInput): Promise<TOutput>;
38
+ sleep(duration: number): Promise<void>;
39
+ getState<T = any>(key: string): Promise<T | null>;
40
+ setState(key: string, value: any): Promise<void>;
41
+ llm: import('./runtime.js').LLMCapability;
42
+ storage: import('./runtime.js').StorageCapability;
43
+ events: import('./runtime.js').EventCapability;
44
+ logger: import('./runtime.js').LoggerCapability;
45
+ secrets: import('./runtime.js').SecretsCapability;
46
+ }
47
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,eAAe,CAAC,MAAM,GAAG,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,QAAQ,GAAG,GAAG;IAEzE,IAAI,EAAE,MAAM,CAAC;IAGb,MAAM,EAAE;QACN,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IAGF,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IAGF,OAAO,CAAC,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,QAAQ,CAAC;KACnB,CAAC;CACH;AAKD,MAAM,MAAM,YAAY,CAAC,MAAM,GAAG,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,QAAQ,GAAG,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,CACpF,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,QAAQ,KACd,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;AAKhC,MAAM,WAAW,YAAY;IAE3B,IAAI,CAAC,EAAE,MAAM,CAAC;IAGd,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAKD,MAAM,WAAW,KAAK,CAAC,MAAM,GAAG,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,QAAQ,GAAG,GAAG,EAAE,OAAO,GAAG,GAAG;IAE9E,UAAU,EAAE,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAGtD,OAAO,EAAE,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAGzD,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB;AAaD,MAAM,WAAW,YAAY,CAAC,MAAM,GAAG,GAAG;IAExC,UAAU,EAAE,KAAK,CAAC;IAGlB,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;CAC/B;AAKD,wBAAgB,cAAc,CAAC,KAAK,EAAE,GAAG,GAAG,KAAK,IAAI,YAAY,CAShE;AAQD,MAAM,WAAW,gBAAgB;IAE/B,UAAU,EAAE,MAAM,CAAC;IAGnB,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,OAAO,GAAG,GAAG,EAC9B,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,MAAM,EAChD,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,OAAO,CAAC,CAAC;IAMpB,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAGvC,QAAQ,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAGlD,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAGjD,GAAG,EAAE,OAAO,cAAc,EAAE,aAAa,CAAC;IAG1C,OAAO,EAAE,OAAO,cAAc,EAAE,iBAAiB,CAAC;IAGlD,MAAM,EAAE,OAAO,cAAc,EAAE,eAAe,CAAC;IAG/C,MAAM,EAAE,OAAO,cAAc,EAAE,gBAAgB,CAAC;IAGhD,OAAO,EAAE,OAAO,cAAc,EAAE,iBAAiB,CAAC;CACnD"}
package/dist/types.js ADDED
@@ -0,0 +1,9 @@
1
+ export function isVirtualAgent(agent) {
2
+ return (agent !== null &&
3
+ typeof agent === 'object' &&
4
+ 'definition' in agent &&
5
+ 'defaultInput' in agent &&
6
+ typeof agent.definition === 'object' &&
7
+ 'definition' in agent.definition);
8
+ }
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AA4FA,MAAM,UAAU,cAAc,CAAC,KAAU;IACvC,OAAO,CACL,KAAK,KAAK,IAAI;QACd,OAAO,KAAK,KAAK,QAAQ;QACzB,YAAY,IAAI,KAAK;QACrB,cAAc,IAAI,KAAK;QACvB,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ;QACpC,YAAY,IAAI,KAAK,CAAC,UAAU,CACjC,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@alveus-ai/core",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "main": "dist/index.js",
9
+ "types": "dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js"
14
+ }
15
+ },
16
+ "scripts": {
17
+ "build": "tsc",
18
+ "dev": "tsc --watch",
19
+ "test": "node --import tsx --test test/**/*.test.ts",
20
+ "type-check": "tsc --noEmit"
21
+ },
22
+ "devDependencies": {
23
+ "@types/node": "^22.10.1",
24
+ "tsx": "^4.19.2",
25
+ "typescript": "^5.7.2"
26
+ }
27
+ }
package/src/agent.ts ADDED
@@ -0,0 +1,59 @@
1
+ import crypto from 'node:crypto';
2
+ import type { Agent, AgentHandler, AgentOptions, AgentDefinition } from './types.js';
3
+
4
+ /**
5
+ * Define an Alveus agent.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * const myAgent = agent$(
10
+ * async (state, event, ctx) => {
11
+ * const reply = await ctx.llm.chat([{ role: 'user', content: event.message }]);
12
+ * return { reply };
13
+ * },
14
+ * { name: 'my-agent' }
15
+ * );
16
+ * ```
17
+ */
18
+ export function agent$<TState = any, TEvent = any, TContext = any, TResult = any>(
19
+ handler: AgentHandler<TState, TEvent, TContext, TResult>,
20
+ options?: AgentOptions,
21
+ ): Agent<TState, TEvent, TContext, TResult> {
22
+ // In development mode, we compute the hash of the handler source
23
+ const handlerSource = handler.toString();
24
+ const hash = computeHash(handlerSource);
25
+
26
+ const definition: AgentDefinition<TState, TEvent, TContext> = {
27
+ hash,
28
+ inputs: {
29
+ state: 'any',
30
+ event: 'any',
31
+ context: 'any',
32
+ },
33
+ metadata: {
34
+ name: options?.name,
35
+ version: options?.version,
36
+ description: options?.description,
37
+ },
38
+ };
39
+
40
+ return {
41
+ definition,
42
+ handler,
43
+ options,
44
+ };
45
+ }
46
+
47
+ /**
48
+ * Compute SHA-256 hash of a string
49
+ */
50
+ function computeHash(source: string): string {
51
+ return crypto.createHash('sha256').update(source).digest('hex');
52
+ }
53
+
54
+ /**
55
+ * Serialize an agent handler to its source string representation.
56
+ */
57
+ export function serializeHandler(handler: (...args: unknown[]) => unknown): string {
58
+ return handler.toString();
59
+ }
package/src/index.ts ADDED
@@ -0,0 +1,49 @@
1
+ /**
2
+ * @alveus-ai/core - The runtime SDK for Alveus agents
3
+ *
4
+ * This package provides the core primitives for defining and executing agents.
5
+ */
6
+
7
+ // Agent definition and serialization
8
+ export { agent$, serializeHandler } from './agent.js';
9
+
10
+ // Core types
11
+ export type {
12
+ Agent,
13
+ AgentDefinition,
14
+ AgentHandler,
15
+ AgentOptions,
16
+ ExecutionContext,
17
+ VirtualAgent,
18
+ } from './types.js';
19
+
20
+ // Virtual Agent support
21
+ export { isVirtualAgent } from './types.js';
22
+
23
+ // Runtime abstraction layer
24
+ export { isDurableContext, withDurableContext } from './runtime.js';
25
+
26
+ export type {
27
+ // Runtime interfaces
28
+ DurableExecutionContext,
29
+ ExecutionRequest,
30
+ ExecutionResult,
31
+ ExecutionStatus,
32
+ Registry,
33
+ Runtime,
34
+ RuntimeConfig,
35
+ SimpleRuntimeConfig,
36
+ DurableRuntimeConfig,
37
+ // LLM capability
38
+ ChatMessage,
39
+ ChatOptions,
40
+ LLMCapability,
41
+ // Storage capability
42
+ StorageCapability,
43
+ BlobStore,
44
+ // Event capability
45
+ AlveusEvent,
46
+ EventCapability,
47
+ // Logger capability
48
+ LoggerCapability,
49
+ } from './runtime.js';
package/src/runtime.ts ADDED
@@ -0,0 +1,576 @@
1
+ /**
2
+ * Runtime Abstraction Layer
3
+ *
4
+ * This module defines the interfaces that allow Alveus to run on different
5
+ * execution backends.
6
+ *
7
+ * Key concepts:
8
+ * - ExecutionContext: What agents see (call, sleep, emit, etc.)
9
+ * - Runtime: The execution environment that provides the context
10
+ * - LLMCapability: Model-agnostic AI generation
11
+ * - StorageCapability: Large payload handling via content-addressed references
12
+ * - EventCapability: Reactive event system for external triggers
13
+ */
14
+
15
+ import type { ExecutionContext } from './types.js';
16
+
17
+ // ============================================================================
18
+ // Event Capability
19
+ // ============================================================================
20
+
21
+ /**
22
+ * AlveusEvent - A durable event in the system
23
+ */
24
+ export interface AlveusEvent {
25
+ /** Unique event ID */
26
+ id: string;
27
+
28
+ /** Topic/channel for routing (e.g., "market.btc.price", "user.approval") */
29
+ topic: string;
30
+
31
+ /** Event payload - any JSON-serializable data */
32
+ data: any;
33
+
34
+ /** Source identifier (e.g., workflow ID, external system) */
35
+ source?: string;
36
+
37
+ /** Unix timestamp in milliseconds */
38
+ timestamp: number;
39
+
40
+ /** Optional target workflow ID for direct routing */
41
+ targetWorkflowId?: string;
42
+ }
43
+
44
+ /**
45
+ * EventCapability - Reactive event system for agents
46
+ *
47
+ * Enables agents to:
48
+ * 1. Publish events to the global event bus
49
+ * 2. Pause execution and wait for specific events (durable wait)
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * // Publish an event
54
+ * await ctx.events.emit('order.completed', { orderId: '123', total: 99.99 });
55
+ *
56
+ * // Wait for an external event (durable - survives restarts)
57
+ * const approval = await ctx.events.waitFor('human.approval', 60000);
58
+ * if (approval.data.approved) {
59
+ * // Continue with approved action
60
+ * }
61
+ * ```
62
+ */
63
+ export interface EventCapability {
64
+ /**
65
+ * Publish an event to the global event bus
66
+ *
67
+ * @param topic - Event topic for routing (e.g., "user.signup", "order.paid")
68
+ * @param data - Event payload (must be JSON-serializable)
69
+ */
70
+ emit(topic: string, data: any): Promise<void>;
71
+
72
+ /**
73
+ * Pause execution and wait for a specific event topic
74
+ *
75
+ * This is a DURABLE wait - the workflow will resume even after:
76
+ * - Worker restarts
77
+ * - System failures
78
+ * - Long delays (hours, days)
79
+ *
80
+ * @param topic - Event topic to wait for
81
+ * @param timeoutMs - Optional timeout in milliseconds
82
+ * @returns The event that matched the topic
83
+ * @throws TimeoutError if timeout is reached without receiving event
84
+ */
85
+ waitFor(topic: string, timeoutMs?: number): Promise<AlveusEvent>;
86
+ }
87
+
88
+ // ============================================================================
89
+ // Secrets Capability
90
+ // ============================================================================
91
+
92
+ /**
93
+ * SecretsCapability - Secure runtime secrets for agents
94
+ *
95
+ * Provides access to secrets that are securely injected into the
96
+ * agent's execution context at runtime.
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * // Get a secret
101
+ * const apiKey = ctx.secrets.get('OPENAI_API_KEY');
102
+ * if (!apiKey) throw new Error('OPENAI_API_KEY secret not configured');
103
+ *
104
+ * // Check if a secret exists
105
+ * if (ctx.secrets.has('DATABASE_URL')) {
106
+ * // Connect to database
107
+ * }
108
+ *
109
+ * // List available secrets (for debugging - shows keys only)
110
+ * console.log('Available secrets:', ctx.secrets.keys());
111
+ * ```
112
+ */
113
+ export interface SecretsCapability {
114
+ /**
115
+ * Get a secret value by key
116
+ *
117
+ * @param key - Secret key (e.g., "OPENAI_API_KEY")
118
+ * @returns The secret value or undefined if not set
119
+ */
120
+ get(key: string): string | undefined;
121
+
122
+ /**
123
+ * Check if a secret exists
124
+ *
125
+ * @param key - Secret key to check
126
+ */
127
+ has(key: string): boolean;
128
+
129
+ /**
130
+ * Get all available secret keys (not values - for debugging)
131
+ *
132
+ * @returns Array of secret key names
133
+ */
134
+ keys(): string[];
135
+ }
136
+
137
+ // ============================================================================
138
+ // Logger Capability
139
+ // ============================================================================
140
+
141
+ /**
142
+ * LoggerCapability - Deterministic logging for agents
143
+ *
144
+ * Provides a consistent logging interface that is safe for use in all
145
+ * execution environments, including replay-safe durable runtimes.
146
+ *
147
+ * @example
148
+ * ```ts
149
+ * ctx.logger.info('Processing order', { orderId: '123' });
150
+ * ctx.logger.warn('Retrying operation', { attempt: 2 });
151
+ * ctx.logger.error('Failed to process', { error: err.message });
152
+ * ```
153
+ */
154
+ export interface LoggerCapability {
155
+ /** Log informational message */
156
+ info(message: string, attrs?: Record<string, any>): void;
157
+
158
+ /** Log warning message */
159
+ warn(message: string, attrs?: Record<string, any>): void;
160
+
161
+ /** Log error message */
162
+ error(message: string, attrs?: Record<string, any>): void;
163
+
164
+ /** Log debug message */
165
+ debug(message: string, attrs?: Record<string, any>): void;
166
+ }
167
+
168
+ // ============================================================================
169
+ // LLM Capability
170
+ // ============================================================================
171
+
172
+ /**
173
+ * Chat message format - provider-agnostic
174
+ */
175
+ export interface ChatMessage {
176
+ role: 'system' | 'user' | 'assistant';
177
+ content: string;
178
+ }
179
+
180
+ /**
181
+ * Options for LLM generation
182
+ */
183
+ export interface ChatOptions {
184
+ /** Provider to use. Default: process.env.DEFAULT_LLM_PROVIDER or 'openai' */
185
+ provider?: 'openai' | 'anthropic' | 'ollama' | 'mock';
186
+
187
+ /** Model identifier (e.g., 'gpt-4o', 'claude-3-opus', 'llama2') */
188
+ model?: string;
189
+
190
+ /** Temperature for generation. Default: 0.7 */
191
+ temperature?: number;
192
+
193
+ /** Enforce JSON output format */
194
+ jsonMode?: boolean;
195
+
196
+ /** Maximum tokens to generate */
197
+ maxTokens?: number;
198
+
199
+ /** Stream ID for real-time token delivery. */
200
+ streamId?: string;
201
+ }
202
+
203
+ /**
204
+ * LLM Capability - Model-agnostic AI generation
205
+ *
206
+ * Allows agents to use any LLM provider without coupling to specific SDKs.
207
+ * The implementation handles provider routing, retries, and rate limits.
208
+ *
209
+ * @example
210
+ * ```ts
211
+ * const response = await ctx.llm.chat([
212
+ * { role: 'system', content: 'You are a helpful assistant.' },
213
+ * { role: 'user', content: 'What is 2+2?' }
214
+ * ], { provider: 'openai', model: 'gpt-4o' });
215
+ * ```
216
+ */
217
+ export interface LLMCapability {
218
+ /**
219
+ * Generate a chat completion
220
+ *
221
+ * @param messages - Array of chat messages
222
+ * @param options - Provider and model options
223
+ * @returns The assistant's response content
224
+ */
225
+ chat(messages: ChatMessage[], options?: ChatOptions): Promise<string>;
226
+ }
227
+
228
+ // ============================================================================
229
+ // Storage Capability
230
+ // ============================================================================
231
+
232
+ /**
233
+ * Storage Capability - Large payload handling via content-addressed references
234
+ *
235
+ * Solves payload size limits by offloading large data to external storage.
236
+ * Agents can pass massive context using small reference keys.
237
+ *
238
+ * @example
239
+ * ```ts
240
+ * // Store large context
241
+ * const key = await ctx.storage.put(JSON.stringify(largeHistory));
242
+ *
243
+ * // Pass key to child agent (small payload)
244
+ * await ctx.call(childAgent, { historyRef: key });
245
+ *
246
+ * // Child retrieves the data
247
+ * const history = JSON.parse(await ctx.storage.get(key));
248
+ * ```
249
+ */
250
+ export interface StorageCapability {
251
+ /**
252
+ * Store data and get a reference key
253
+ *
254
+ * @param data - String or Buffer to store
255
+ * @returns Content-addressed key (e.g., "blob:sha256hash")
256
+ */
257
+ put(data: string | Buffer): Promise<string>;
258
+
259
+ /**
260
+ * Retrieve data by key
261
+ *
262
+ * @param key - The reference key from put()
263
+ * @returns The stored data, or null if not found
264
+ */
265
+ get(key: string): Promise<string | null>;
266
+ }
267
+
268
+ /**
269
+ * BlobStore Interface - Provider-agnostic blob storage abstraction
270
+ */
271
+ export interface BlobStore {
272
+ /**
273
+ * Store data and return content-addressed key
274
+ */
275
+ put(data: string | Buffer): Promise<string>;
276
+
277
+ /**
278
+ * Retrieve data by key
279
+ */
280
+ get(key: string): Promise<string | null>;
281
+
282
+ /**
283
+ * Check if a blob exists
284
+ */
285
+ exists(key: string): Promise<boolean>;
286
+
287
+ /**
288
+ * Delete a blob (optional - for cleanup)
289
+ */
290
+ delete?(key: string): Promise<void>;
291
+
292
+ /**
293
+ * List all blob keys (optional - for admin/debug)
294
+ */
295
+ list?(): Promise<string[]>;
296
+ }
297
+
298
+ /**
299
+ * Extended ExecutionContext with durable execution primitives
300
+ *
301
+ * This extends the base ExecutionContext with methods needed for
302
+ * durable execution (sleep, scheduleAt, etc.)
303
+ */
304
+ export interface DurableExecutionContext extends ExecutionContext {
305
+ /**
306
+ * Sleep for a duration (durable — survives process restarts)
307
+ *
308
+ * @param duration - Duration in milliseconds, or ISO 8601 duration string
309
+ * @example
310
+ * await ctx.sleep(5000); // Sleep for 5 seconds
311
+ * await ctx.sleep('PT1H'); // Sleep for 1 hour (ISO 8601)
312
+ * await ctx.sleep('P1D'); // Sleep for 1 day
313
+ */
314
+ sleep(duration: number | string): Promise<void>;
315
+
316
+ /**
317
+ * Schedule execution to resume at a specific time
318
+ *
319
+ * @param timestamp - ISO 8601 timestamp or Date object
320
+ * @example
321
+ * await ctx.sleepUntil('2024-12-25T00:00:00Z');
322
+ * await ctx.sleepUntil(new Date('2024-12-25'));
323
+ */
324
+ sleepUntil(timestamp: string | Date): Promise<void>;
325
+
326
+ /**
327
+ * Get the current workflow/execution ID
328
+ * Useful for correlation and debugging
329
+ */
330
+ getExecutionId(): string;
331
+
332
+ /**
333
+ * Get the current attempt number (for retries)
334
+ */
335
+ getAttempt(): number;
336
+
337
+ /** Deterministic logger (safe for durable execution replay) */
338
+ log: {
339
+ info(message: string, ...args: any[]): void;
340
+ warn(message: string, ...args: any[]): void;
341
+ error(message: string, ...args: any[]): void;
342
+ debug(message: string, ...args: any[]): void;
343
+ };
344
+ }
345
+
346
+ /**
347
+ * Execution Request - Input to execute an agent
348
+ */
349
+ export interface ExecutionRequest<TState = any, TEvent = any> {
350
+ /** The content hash of the agent to execute */
351
+ hash: string;
352
+
353
+ /** The state to pass to the agent */
354
+ state: TState;
355
+
356
+ /** The event/input to pass to the agent */
357
+ event: TEvent;
358
+
359
+ /** Optional execution ID (generated if not provided) */
360
+ executionId?: string;
361
+
362
+ /** Optional parent execution ID (for tracing) */
363
+ parentExecutionId?: string;
364
+ }
365
+
366
+ /**
367
+ * Execution Result - Output from agent execution
368
+ */
369
+ export interface ExecutionResult<TResult = any> {
370
+ /** Whether execution succeeded */
371
+ success: boolean;
372
+
373
+ /** The result if successful */
374
+ result?: TResult;
375
+
376
+ /** Error message if failed */
377
+ error?: string;
378
+
379
+ /** Execution metadata */
380
+ metadata: {
381
+ hash: string;
382
+ executionId: string;
383
+ duration: number;
384
+ timestamp: string;
385
+ attempts?: number;
386
+ };
387
+ }
388
+
389
+ /**
390
+ * Registry Interface - Abstraction for blob storage
391
+ */
392
+ export interface Registry {
393
+ /** Store a blob and return its hash */
394
+ store(hash: string, content: string): Promise<void>;
395
+
396
+ /** Retrieve a blob by hash */
397
+ retrieve(hash: string): Promise<string | null>;
398
+
399
+ /** List all stored hashes */
400
+ list(): Promise<string[]>;
401
+
402
+ /** Check if a hash exists */
403
+ exists(hash: string): Promise<boolean>;
404
+ }
405
+
406
+ /**
407
+ * Runtime Interface - The execution environment abstraction
408
+ */
409
+ export interface Runtime {
410
+ /** Runtime name for debugging */
411
+ readonly name: string;
412
+
413
+ /** Start the runtime (connect to services, etc.) */
414
+ start(): Promise<void>;
415
+
416
+ /** Stop the runtime gracefully */
417
+ stop(): Promise<void>;
418
+
419
+ /**
420
+ * Execute an agent by hash
421
+ *
422
+ * @param request - The execution request
423
+ * @returns The execution result
424
+ */
425
+ execute<TState = any, TEvent = any, TResult = any>(
426
+ request: ExecutionRequest<TState, TEvent>,
427
+ ): Promise<ExecutionResult<TResult>>;
428
+
429
+ /**
430
+ * Get the status of an execution
431
+ *
432
+ * @param executionId - The execution ID to check
433
+ */
434
+ getExecutionStatus(executionId: string): Promise<ExecutionStatus>;
435
+
436
+ /**
437
+ * Cancel a running execution
438
+ *
439
+ * @param executionId - The execution ID to cancel
440
+ */
441
+ cancelExecution(executionId: string): Promise<void>;
442
+ }
443
+
444
+ /**
445
+ * Execution Status - Current state of an execution
446
+ */
447
+ export interface ExecutionStatus {
448
+ executionId: string;
449
+ hash: string;
450
+ status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
451
+ startedAt?: string;
452
+ completedAt?: string;
453
+ error?: string;
454
+ result?: any;
455
+ }
456
+
457
+ /**
458
+ * Runtime Configuration
459
+ */
460
+ export interface RuntimeConfig {
461
+ /** Registry for blob storage */
462
+ registry: Registry;
463
+
464
+ /** Custom capability providers */
465
+ capabilities?: Record<string, any>;
466
+ }
467
+
468
+ /**
469
+ * Durable runtime configuration
470
+ */
471
+ export interface DurableRuntimeConfig extends RuntimeConfig {
472
+ /** Server address */
473
+ address: string;
474
+
475
+ /** Namespace */
476
+ namespace: string;
477
+
478
+ /** Task queue name */
479
+ taskQueue: string;
480
+
481
+ /** Worker identity */
482
+ identity?: string;
483
+ }
484
+
485
+ /**
486
+ * Simple runtime configuration
487
+ */
488
+ export interface SimpleRuntimeConfig extends RuntimeConfig {
489
+ /** Port to listen on */
490
+ port?: number;
491
+
492
+ /** Host to bind to */
493
+ host?: string;
494
+ }
495
+
496
+ /**
497
+ * Type guard for checking if context supports durable execution
498
+ */
499
+ export function isDurableContext(ctx: ExecutionContext): ctx is DurableExecutionContext {
500
+ return 'sleep' in ctx && typeof (ctx as any).sleep === 'function';
501
+ }
502
+
503
+ /**
504
+ * Helper to create a runtime-agnostic agent handler
505
+ *
506
+ * This wrapper ensures agents can run on any runtime by:
507
+ * 1. Providing safe defaults for non-durable contexts
508
+ * 2. Adding type safety for durable operations
509
+ *
510
+ * @example
511
+ * ```ts
512
+ * const myAgent = agent$(
513
+ * withDurableContext(async (state, event, ctx) => {
514
+ * // ctx is now typed as DurableExecutionContext
515
+ * await ctx.sleep(5000);
516
+ * const result = await ctx.call(otherAgent, { data: 'hello' });
517
+ * return { processed: true };
518
+ * })
519
+ * );
520
+ * ```
521
+ */
522
+ export function withDurableContext<TState, TEvent, TResult>(
523
+ handler: (state: TState, event: TEvent, ctx: DurableExecutionContext) => Promise<TResult>,
524
+ ): (state: TState, event: TEvent, ctx: ExecutionContext) => Promise<TResult> {
525
+ return async (state: TState, event: TEvent, ctx: ExecutionContext) => {
526
+ // If not a durable context, provide fallback implementations
527
+ const durableCtx: DurableExecutionContext = isDurableContext(ctx)
528
+ ? ctx
529
+ : {
530
+ ...ctx,
531
+ sleep: async (duration: number | string) => {
532
+ const ms = typeof duration === 'number' ? duration : parseDuration(duration);
533
+ return new Promise((resolve) => setTimeout(resolve, ms));
534
+ },
535
+ sleepUntil: async (timestamp: string | Date) => {
536
+ const target = typeof timestamp === 'string' ? new Date(timestamp) : timestamp;
537
+ const now = Date.now();
538
+ const delay = target.getTime() - now;
539
+ if (delay > 0) {
540
+ await new Promise((resolve) => setTimeout(resolve, delay));
541
+ }
542
+ },
543
+ getExecutionId: () => `simple-${Date.now()}-${Math.random().toString(36).slice(2)}`,
544
+ getAttempt: () => 1,
545
+ log: {
546
+ info: (msg, ...args) => console.log(`[INFO] ${msg}`, ...args),
547
+ warn: (msg, ...args) => console.warn(`[WARN] ${msg}`, ...args),
548
+ error: (msg, ...args) => console.error(`[ERROR] ${msg}`, ...args),
549
+ debug: (msg, ...args) => console.debug(`[DEBUG] ${msg}`, ...args),
550
+ },
551
+ };
552
+
553
+ return handler(state, event, durableCtx);
554
+ };
555
+ }
556
+
557
+ /**
558
+ * Parse ISO 8601 duration string to milliseconds
559
+ * Supports: PT#H, PT#M, PT#S, P#D formats
560
+ */
561
+ function parseDuration(duration: string): number {
562
+ const match = duration.match(/^P(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d+)?)S)?)?$/);
563
+ if (!match) {
564
+ throw new Error(`Invalid duration format: ${duration}`);
565
+ }
566
+
567
+ const [, days, hours, minutes, seconds] = match;
568
+ let ms = 0;
569
+
570
+ if (days) ms += parseInt(days, 10) * 24 * 60 * 60 * 1000;
571
+ if (hours) ms += parseInt(hours, 10) * 60 * 60 * 1000;
572
+ if (minutes) ms += parseInt(minutes, 10) * 60 * 1000;
573
+ if (seconds) ms += parseFloat(seconds) * 1000;
574
+
575
+ return ms;
576
+ }
package/src/types.ts ADDED
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Core type definitions for Alveus agents
3
+ */
4
+
5
+ /**
6
+ * Agent Definition - The immutable representation of an agent
7
+ */
8
+ export interface AgentDefinition<TState = any, TEvent = any, TContext = any> {
9
+ /** Content-addressed hash of the agent code */
10
+ hash: string;
11
+
12
+ /** Input schema definition */
13
+ inputs: {
14
+ state: string;
15
+ event: string;
16
+ context: string;
17
+ };
18
+
19
+ /** Metadata about the agent */
20
+ metadata?: {
21
+ name?: string;
22
+ version?: string;
23
+ description?: string;
24
+ };
25
+
26
+ /** Phantom properties for type safety (not present at runtime) */
27
+ __types?: {
28
+ state: TState;
29
+ event: TEvent;
30
+ context: TContext;
31
+ };
32
+ }
33
+
34
+ /**
35
+ * Agent Handler Function - The actual executable code
36
+ */
37
+ export type AgentHandler<TState = any, TEvent = any, TContext = any, TResult = any> = (
38
+ state: TState,
39
+ event: TEvent,
40
+ context: TContext,
41
+ ) => Promise<TResult> | TResult;
42
+
43
+ /**
44
+ * Agent Configuration Options
45
+ */
46
+ export interface AgentOptions {
47
+ /** Optional name for debugging/logging */
48
+ name?: string;
49
+
50
+ /** Optional description */
51
+ description?: string;
52
+
53
+ /** Optional version identifier */
54
+ version?: string;
55
+ }
56
+
57
+ /**
58
+ * Agent - The result of calling agent$()
59
+ */
60
+ export interface Agent<TState = any, TEvent = any, TContext = any, TResult = any> {
61
+ /** The agent definition (with hash) */
62
+ definition: AgentDefinition<TState, TEvent, TContext>;
63
+
64
+ /** The handler function (only available at compile time) */
65
+ handler: AgentHandler<TState, TEvent, TContext, TResult>;
66
+
67
+ /** Optional configuration */
68
+ options?: AgentOptions;
69
+ }
70
+
71
+ /**
72
+ * Virtual Agent - A configuration wrapper around a compiled agent.
73
+ *
74
+ * Allows creating pre-configured variants of an agent without
75
+ * generating new code.
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * const myAgent = createReActAgent({ systemPrompt: '...', tools: {...} });
80
+ * ```
81
+ */
82
+ export interface VirtualAgent<TInput = any> {
83
+ /** The underlying agent definition */
84
+ definition: Agent;
85
+
86
+ /** Pre-filled input that gets merged with runtime input */
87
+ defaultInput: Partial<TInput>;
88
+ }
89
+
90
+ /**
91
+ * Type guard to check if something is a VirtualAgent
92
+ */
93
+ export function isVirtualAgent(agent: any): agent is VirtualAgent {
94
+ return (
95
+ agent !== null &&
96
+ typeof agent === 'object' &&
97
+ 'definition' in agent &&
98
+ 'defaultInput' in agent &&
99
+ typeof agent.definition === 'object' &&
100
+ 'definition' in agent.definition // Has nested Agent structure
101
+ );
102
+ }
103
+
104
+ /**
105
+ * Execution Context - Injected capabilities and utilities
106
+ *
107
+ * This is the base context available to all agents. For durable execution
108
+ * features (sleep, sleepUntil, etc.), see DurableExecutionContext in runtime.ts.
109
+ */
110
+ export interface ExecutionContext {
111
+ /** Unique identifier for this execution */
112
+ workflowId: string;
113
+
114
+ /** Call another agent (RPC-style) */
115
+ call<TInput = any, TOutput = any>(
116
+ agent: Agent<any, TInput, any, TOutput> | string,
117
+ input: TInput,
118
+ ): Promise<TOutput>;
119
+
120
+ /**
121
+ * Sleep for a duration
122
+ * @param duration - Duration in milliseconds
123
+ */
124
+ sleep(duration: number): Promise<void>;
125
+
126
+ /** Get a value from state storage */
127
+ getState<T = any>(key: string): Promise<T | null>;
128
+
129
+ /** Set a value in state storage */
130
+ setState(key: string, value: any): Promise<void>;
131
+
132
+ /** LLM capability - model-agnostic AI generation */
133
+ llm: import('./runtime.js').LLMCapability;
134
+
135
+ /** Storage capability - large payload handling */
136
+ storage: import('./runtime.js').StorageCapability;
137
+
138
+ /** Event capability - publish events and wait for external triggers */
139
+ events: import('./runtime.js').EventCapability;
140
+
141
+ /** Logger capability - deterministic, replay-safe logging */
142
+ logger: import('./runtime.js').LoggerCapability;
143
+
144
+ /** Secrets capability - secure runtime secrets */
145
+ secrets: import('./runtime.js').SecretsCapability;
146
+ }
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Capability Injection Test
3
+ *
4
+ * Validates the "Data-Only Closures" + "Capabilities" pattern:
5
+ * agent handlers receive all external dependencies via the context
6
+ * parameter, never via captured outer scope.
7
+ */
8
+
9
+ import { describe, test } from 'node:test';
10
+ import assert from 'node:assert';
11
+
12
+ describe('Capability Injection', () => {
13
+ test('should inject capabilities into a handler via context', async () => {
14
+ const handler = async (
15
+ event: { data: string },
16
+ ctx: { db: { save: (data: string) => Promise<string> } },
17
+ ) => {
18
+ const result = await ctx.db.save(event.data);
19
+ return { saved: result };
20
+ };
21
+
22
+ const mockContext = {
23
+ db: {
24
+ save: async (data: string) => `saved:${data}`,
25
+ },
26
+ };
27
+
28
+ const result = await handler({ data: 'hello' }, mockContext);
29
+ assert.deepStrictEqual(result, { saved: 'saved:hello' });
30
+ });
31
+
32
+ test('should pass configuration via event/state, not outer scope', async () => {
33
+ const handler = async (
34
+ event: { url: string; config: { apiVersion: string; maxRetries: number } },
35
+ ctx: { fetch: (url: string) => Promise<string> },
36
+ ) => {
37
+ const fullUrl = `${event.url}/${event.config.apiVersion}?retries=${event.config.maxRetries}`;
38
+ return ctx.fetch(fullUrl);
39
+ };
40
+
41
+ const mockContext = {
42
+ fetch: async (url: string) => `response from ${url}`,
43
+ };
44
+
45
+ const result = await handler(
46
+ { url: 'https://api.example.com', config: { apiVersion: 'v2', maxRetries: 3 } },
47
+ mockContext,
48
+ );
49
+
50
+ assert.ok(result.includes('v2'));
51
+ assert.ok(result.includes('retries=3'));
52
+ });
53
+
54
+ test('should handle complex context with multiple capabilities', async () => {
55
+ interface Context {
56
+ db: {
57
+ query: (sql: string) => Promise<any[]>;
58
+ save: (data: any) => Promise<string>;
59
+ };
60
+ llm: {
61
+ complete: (prompt: string) => Promise<string>;
62
+ };
63
+ logger: {
64
+ info: (msg: string) => void;
65
+ };
66
+ }
67
+
68
+ const handler = async (event: { userId: string; prompt: string }, ctx: Context) => {
69
+ ctx.logger.info(`Processing request for user ${event.userId}`);
70
+ await ctx.db.query(`SELECT * FROM users WHERE id = '${event.userId}'`);
71
+ const aiResponse = await ctx.llm.complete(event.prompt);
72
+ const saveId = await ctx.db.save({ userId: event.userId, response: aiResponse });
73
+ return { saveId, response: aiResponse };
74
+ };
75
+
76
+ const logs: string[] = [];
77
+ const mockContext: Context = {
78
+ db: {
79
+ query: async () => [{ id: '123', name: 'Test User' }],
80
+ save: async () => 'save-id-456',
81
+ },
82
+ llm: {
83
+ complete: async () => 'AI generated response',
84
+ },
85
+ logger: {
86
+ info: (msg) => logs.push(msg),
87
+ },
88
+ };
89
+
90
+ const result = await handler(
91
+ { userId: 'user-789', prompt: 'Summarize this document' },
92
+ mockContext,
93
+ );
94
+
95
+ assert.strictEqual(result.saveId, 'save-id-456');
96
+ assert.strictEqual(result.response, 'AI generated response');
97
+ assert.ok(logs.length > 0);
98
+ });
99
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "rootDir": "./src"
6
+ },
7
+ "include": ["src/**/*"],
8
+ "exclude": ["node_modules", "dist", "**/*.test.ts"]
9
+ }