confused-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.
Files changed (114) hide show
  1. package/FEATURES.md +169 -0
  2. package/package.json +119 -0
  3. package/src/agent.ts +187 -0
  4. package/src/agentic/index.ts +87 -0
  5. package/src/agentic/runner.ts +386 -0
  6. package/src/agentic/types.ts +91 -0
  7. package/src/artifacts/artifact.ts +417 -0
  8. package/src/artifacts/index.ts +42 -0
  9. package/src/artifacts/media.ts +304 -0
  10. package/src/cli/index.ts +122 -0
  11. package/src/core/base-agent.ts +151 -0
  12. package/src/core/context-builder.ts +106 -0
  13. package/src/core/index.ts +8 -0
  14. package/src/core/schemas.ts +17 -0
  15. package/src/core/types.ts +158 -0
  16. package/src/create-agent.ts +309 -0
  17. package/src/debug-logger.ts +188 -0
  18. package/src/dx/agent.ts +88 -0
  19. package/src/dx/define-agent.ts +183 -0
  20. package/src/dx/dev-logger.ts +57 -0
  21. package/src/dx/index.ts +11 -0
  22. package/src/errors.ts +175 -0
  23. package/src/execution/engine.ts +522 -0
  24. package/src/execution/graph-builder.ts +362 -0
  25. package/src/execution/index.ts +8 -0
  26. package/src/execution/types.ts +257 -0
  27. package/src/execution/worker-pool.ts +308 -0
  28. package/src/extensions/index.ts +123 -0
  29. package/src/guardrails/allowlist.ts +155 -0
  30. package/src/guardrails/index.ts +17 -0
  31. package/src/guardrails/types.ts +159 -0
  32. package/src/guardrails/validator.ts +265 -0
  33. package/src/index.ts +74 -0
  34. package/src/knowledge/index.ts +5 -0
  35. package/src/knowledge/types.ts +52 -0
  36. package/src/learning/in-memory-store.ts +72 -0
  37. package/src/learning/index.ts +6 -0
  38. package/src/learning/types.ts +42 -0
  39. package/src/llm/cache.ts +300 -0
  40. package/src/llm/index.ts +22 -0
  41. package/src/llm/model-resolver.ts +81 -0
  42. package/src/llm/openai-provider.ts +313 -0
  43. package/src/llm/openrouter-provider.ts +29 -0
  44. package/src/llm/types.ts +131 -0
  45. package/src/memory/in-memory-store.ts +255 -0
  46. package/src/memory/index.ts +7 -0
  47. package/src/memory/types.ts +193 -0
  48. package/src/memory/vector-store.ts +251 -0
  49. package/src/observability/console-logger.ts +123 -0
  50. package/src/observability/index.ts +12 -0
  51. package/src/observability/metrics.ts +85 -0
  52. package/src/observability/otlp-exporter.ts +417 -0
  53. package/src/observability/tracer.ts +105 -0
  54. package/src/observability/types.ts +341 -0
  55. package/src/orchestration/agent-adapter.ts +33 -0
  56. package/src/orchestration/index.ts +34 -0
  57. package/src/orchestration/load-balancer.ts +151 -0
  58. package/src/orchestration/mcp-types.ts +59 -0
  59. package/src/orchestration/message-bus.ts +192 -0
  60. package/src/orchestration/orchestrator.ts +349 -0
  61. package/src/orchestration/pipeline.ts +66 -0
  62. package/src/orchestration/supervisor.ts +107 -0
  63. package/src/orchestration/swarm.ts +1099 -0
  64. package/src/orchestration/toolkit.ts +47 -0
  65. package/src/orchestration/types.ts +339 -0
  66. package/src/planner/classical-planner.ts +383 -0
  67. package/src/planner/index.ts +8 -0
  68. package/src/planner/llm-planner.ts +353 -0
  69. package/src/planner/types.ts +227 -0
  70. package/src/planner/validator.ts +297 -0
  71. package/src/production/circuit-breaker.ts +290 -0
  72. package/src/production/graceful-shutdown.ts +251 -0
  73. package/src/production/health.ts +333 -0
  74. package/src/production/index.ts +57 -0
  75. package/src/production/latency-eval.ts +62 -0
  76. package/src/production/rate-limiter.ts +287 -0
  77. package/src/production/resumable-stream.ts +289 -0
  78. package/src/production/types.ts +81 -0
  79. package/src/sdk/index.ts +374 -0
  80. package/src/session/db-driver.ts +50 -0
  81. package/src/session/in-memory-store.ts +235 -0
  82. package/src/session/index.ts +12 -0
  83. package/src/session/sql-store.ts +315 -0
  84. package/src/session/sqlite-store.ts +61 -0
  85. package/src/session/types.ts +153 -0
  86. package/src/tools/base-tool.ts +223 -0
  87. package/src/tools/browser-tool.ts +123 -0
  88. package/src/tools/calculator-tool.ts +265 -0
  89. package/src/tools/file-tools.ts +394 -0
  90. package/src/tools/github-tool.ts +432 -0
  91. package/src/tools/hackernews-tool.ts +187 -0
  92. package/src/tools/http-tool.ts +118 -0
  93. package/src/tools/index.ts +99 -0
  94. package/src/tools/jira-tool.ts +373 -0
  95. package/src/tools/notion-tool.ts +322 -0
  96. package/src/tools/openai-tool.ts +236 -0
  97. package/src/tools/registry.ts +131 -0
  98. package/src/tools/serpapi-tool.ts +234 -0
  99. package/src/tools/shell-tool.ts +118 -0
  100. package/src/tools/slack-tool.ts +327 -0
  101. package/src/tools/telegram-tool.ts +127 -0
  102. package/src/tools/types.ts +229 -0
  103. package/src/tools/websearch-tool.ts +335 -0
  104. package/src/tools/wikipedia-tool.ts +177 -0
  105. package/src/tools/yfinance-tool.ts +33 -0
  106. package/src/voice/index.ts +17 -0
  107. package/src/voice/voice-provider.ts +228 -0
  108. package/tests/artifact.test.ts +241 -0
  109. package/tests/circuit-breaker.test.ts +171 -0
  110. package/tests/health.test.ts +192 -0
  111. package/tests/llm-cache.test.ts +186 -0
  112. package/tests/rate-limiter.test.ts +161 -0
  113. package/tsconfig.json +29 -0
  114. package/vitest.config.ts +47 -0
@@ -0,0 +1,304 @@
1
+ /**
2
+ * Media Artifacts - Agno-Style Image, Audio, Video Support
3
+ *
4
+ * Production-grade media handling:
5
+ * - Image generation and storage
6
+ * - Audio transcription and synthesis artifacts
7
+ * - Video processing artifacts
8
+ * - URL and base64 support
9
+ */
10
+
11
+ import type { ArtifactStorage, BinaryArtifact, ArtifactMetadata } from './artifact.js';
12
+
13
+ /** Image generation result */
14
+ export interface ImageArtifact extends Omit<BinaryArtifact, 'type'> {
15
+ type: 'image';
16
+ /** Image width in pixels */
17
+ readonly width?: number;
18
+ /** Image height in pixels */
19
+ readonly height?: number;
20
+ /** Generation prompt (if AI-generated) */
21
+ readonly prompt?: string;
22
+ /** Negative prompt (if applicable) */
23
+ readonly negativePrompt?: string;
24
+ /** Model used for generation */
25
+ readonly model?: string;
26
+ /** Seed for reproducibility */
27
+ readonly seed?: number;
28
+ }
29
+
30
+ /** Audio artifact */
31
+ export interface AudioArtifact extends Omit<BinaryArtifact, 'type'> {
32
+ type: 'audio';
33
+ /** Duration in seconds */
34
+ readonly durationSeconds?: number;
35
+ /** Sample rate in Hz */
36
+ readonly sampleRate?: number;
37
+ /** Number of channels */
38
+ readonly channels?: number;
39
+ /** Transcript (if available) */
40
+ readonly transcript?: string;
41
+ /** Voice ID (for TTS) */
42
+ readonly voiceId?: string;
43
+ }
44
+
45
+ /** Video artifact */
46
+ export interface VideoArtifact extends Omit<BinaryArtifact, 'type'> {
47
+ type: 'video';
48
+ /** Duration in seconds */
49
+ readonly durationSeconds?: number;
50
+ /** Width in pixels */
51
+ readonly width?: number;
52
+ /** Height in pixels */
53
+ readonly height?: number;
54
+ /** Frame rate */
55
+ readonly fps?: number;
56
+ /** Thumbnail URL */
57
+ readonly thumbnailUrl?: string;
58
+ }
59
+
60
+ // --- Media Artifact Helpers ---
61
+
62
+ /**
63
+ * Create an image artifact from URL
64
+ */
65
+ export function createImageFromUrl(
66
+ name: string,
67
+ url: string,
68
+ options?: {
69
+ width?: number;
70
+ height?: number;
71
+ prompt?: string;
72
+ model?: string;
73
+ tags?: string[];
74
+ }
75
+ ): Omit<ImageArtifact, 'id' | 'createdAt' | 'updatedAt' | 'version'> {
76
+ return {
77
+ name,
78
+ type: 'image',
79
+ content: url,
80
+ url,
81
+ mimeType: guessImageMimeType(url),
82
+ width: options?.width,
83
+ height: options?.height,
84
+ prompt: options?.prompt,
85
+ model: options?.model,
86
+ tags: options?.tags,
87
+ };
88
+ }
89
+
90
+ /**
91
+ * Create an image artifact from base64
92
+ */
93
+ export function createImageFromBase64(
94
+ name: string,
95
+ base64: string,
96
+ mimeType: string,
97
+ options?: {
98
+ width?: number;
99
+ height?: number;
100
+ prompt?: string;
101
+ model?: string;
102
+ tags?: string[];
103
+ }
104
+ ): Omit<ImageArtifact, 'id' | 'createdAt' | 'updatedAt' | 'version'> {
105
+ return {
106
+ name,
107
+ type: 'image',
108
+ content: base64,
109
+ base64,
110
+ mimeType,
111
+ width: options?.width,
112
+ height: options?.height,
113
+ prompt: options?.prompt,
114
+ model: options?.model,
115
+ tags: options?.tags,
116
+ };
117
+ }
118
+
119
+ /**
120
+ * Create an audio artifact from URL
121
+ */
122
+ export function createAudioFromUrl(
123
+ name: string,
124
+ url: string,
125
+ options?: {
126
+ durationSeconds?: number;
127
+ transcript?: string;
128
+ voiceId?: string;
129
+ tags?: string[];
130
+ }
131
+ ): Omit<AudioArtifact, 'id' | 'createdAt' | 'updatedAt' | 'version'> {
132
+ return {
133
+ name,
134
+ type: 'audio',
135
+ content: url,
136
+ url,
137
+ mimeType: guessAudioMimeType(url),
138
+ durationSeconds: options?.durationSeconds,
139
+ transcript: options?.transcript,
140
+ voiceId: options?.voiceId,
141
+ tags: options?.tags,
142
+ };
143
+ }
144
+
145
+ /**
146
+ * Create a video artifact from URL
147
+ */
148
+ export function createVideoFromUrl(
149
+ name: string,
150
+ url: string,
151
+ options?: {
152
+ durationSeconds?: number;
153
+ width?: number;
154
+ height?: number;
155
+ fps?: number;
156
+ thumbnailUrl?: string;
157
+ tags?: string[];
158
+ }
159
+ ): Omit<VideoArtifact, 'id' | 'createdAt' | 'updatedAt' | 'version'> {
160
+ return {
161
+ name,
162
+ type: 'video',
163
+ content: url,
164
+ url,
165
+ mimeType: guessVideoMimeType(url),
166
+ durationSeconds: options?.durationSeconds,
167
+ width: options?.width,
168
+ height: options?.height,
169
+ fps: options?.fps,
170
+ thumbnailUrl: options?.thumbnailUrl,
171
+ tags: options?.tags,
172
+ };
173
+ }
174
+
175
+ // --- Media Manager ---
176
+
177
+ /**
178
+ * MediaManager - handles media artifact operations
179
+ */
180
+ export class MediaManager {
181
+ constructor(private readonly storage: ArtifactStorage) { }
182
+
183
+ /** Save an image artifact */
184
+ async saveImage(
185
+ name: string,
186
+ source: string | { base64: string; mimeType: string },
187
+ options?: {
188
+ width?: number;
189
+ height?: number;
190
+ prompt?: string;
191
+ model?: string;
192
+ tags?: string[];
193
+ }
194
+ ): Promise<ImageArtifact> {
195
+ const artifact = typeof source === 'string'
196
+ ? createImageFromUrl(name, source, options)
197
+ : createImageFromBase64(name, source.base64, source.mimeType, options);
198
+
199
+ return await this.storage.save(artifact) as ImageArtifact;
200
+ }
201
+
202
+ /** Save an audio artifact */
203
+ async saveAudio(
204
+ name: string,
205
+ url: string,
206
+ options?: {
207
+ durationSeconds?: number;
208
+ transcript?: string;
209
+ voiceId?: string;
210
+ tags?: string[];
211
+ }
212
+ ): Promise<AudioArtifact> {
213
+ const artifact = createAudioFromUrl(name, url, options);
214
+ return await this.storage.save(artifact) as AudioArtifact;
215
+ }
216
+
217
+ /** Save a video artifact */
218
+ async saveVideo(
219
+ name: string,
220
+ url: string,
221
+ options?: {
222
+ durationSeconds?: number;
223
+ width?: number;
224
+ height?: number;
225
+ fps?: number;
226
+ thumbnailUrl?: string;
227
+ tags?: string[];
228
+ }
229
+ ): Promise<VideoArtifact> {
230
+ const artifact = createVideoFromUrl(name, url, options);
231
+ return await this.storage.save(artifact) as VideoArtifact;
232
+ }
233
+
234
+ /** Get an image by ID */
235
+ async getImage(id: string): Promise<ImageArtifact | null> {
236
+ return await this.storage.get<ImageArtifact['content']>(id) as ImageArtifact | null;
237
+ }
238
+
239
+ /** Get an audio by ID */
240
+ async getAudio(id: string): Promise<AudioArtifact | null> {
241
+ return await this.storage.get<AudioArtifact['content']>(id) as AudioArtifact | null;
242
+ }
243
+
244
+ /** Get a video by ID */
245
+ async getVideo(id: string): Promise<VideoArtifact | null> {
246
+ return await this.storage.get<VideoArtifact['content']>(id) as VideoArtifact | null;
247
+ }
248
+
249
+ /** List all images */
250
+ async listImages(limit?: number): Promise<ArtifactMetadata[]> {
251
+ return await this.storage.list({ type: 'image', limit });
252
+ }
253
+
254
+ /** List all audio */
255
+ async listAudio(limit?: number): Promise<ArtifactMetadata[]> {
256
+ return await this.storage.list({ type: 'audio', limit });
257
+ }
258
+
259
+ /** List all videos */
260
+ async listVideos(limit?: number): Promise<ArtifactMetadata[]> {
261
+ return await this.storage.list({ type: 'video', limit });
262
+ }
263
+ }
264
+
265
+ // --- Helpers ---
266
+
267
+ function guessImageMimeType(url: string): string {
268
+ const ext = url.split('.').pop()?.toLowerCase();
269
+ const mimeTypes: Record<string, string> = {
270
+ jpg: 'image/jpeg',
271
+ jpeg: 'image/jpeg',
272
+ png: 'image/png',
273
+ gif: 'image/gif',
274
+ webp: 'image/webp',
275
+ svg: 'image/svg+xml',
276
+ bmp: 'image/bmp',
277
+ };
278
+ return mimeTypes[ext ?? ''] ?? 'image/png';
279
+ }
280
+
281
+ function guessAudioMimeType(url: string): string {
282
+ const ext = url.split('.').pop()?.toLowerCase();
283
+ const mimeTypes: Record<string, string> = {
284
+ mp3: 'audio/mpeg',
285
+ wav: 'audio/wav',
286
+ ogg: 'audio/ogg',
287
+ flac: 'audio/flac',
288
+ aac: 'audio/aac',
289
+ m4a: 'audio/mp4',
290
+ };
291
+ return mimeTypes[ext ?? ''] ?? 'audio/mpeg';
292
+ }
293
+
294
+ function guessVideoMimeType(url: string): string {
295
+ const ext = url.split('.').pop()?.toLowerCase();
296
+ const mimeTypes: Record<string, string> = {
297
+ mp4: 'video/mp4',
298
+ webm: 'video/webm',
299
+ mov: 'video/quicktime',
300
+ avi: 'video/x-msvideo',
301
+ mkv: 'video/x-matroska',
302
+ };
303
+ return mimeTypes[ext ?? ''] ?? 'video/mp4';
304
+ }
@@ -0,0 +1,122 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * CLI entry point for Agent Framework
5
+ */
6
+
7
+ import { Command } from 'commander';
8
+ import { VERSION } from '../index.js';
9
+
10
+ const program = new Command();
11
+
12
+ program
13
+ .name('agent-framework')
14
+ .description('CLI for Agent Framework - A production-grade TypeScript agent framework')
15
+ .version(VERSION);
16
+
17
+ // Create agent command
18
+ program
19
+ .command('create')
20
+ .description('Create a new agent project')
21
+ .argument('<name>', 'Project name')
22
+ .option('-t, --template <template>', 'Project template', 'basic')
23
+ .option('-d, --directory <directory>', 'Target directory')
24
+ .action(async (name, options) => {
25
+ console.log(`Creating new agent project: ${name}`);
26
+ console.log(`Template: ${options.template}`);
27
+ console.log(`Directory: ${options.directory ?? name}`);
28
+ // TODO: Implement project scaffolding
29
+ });
30
+
31
+ // Run agent command
32
+ program
33
+ .command('run')
34
+ .description('Run an agent')
35
+ .argument('<file>', 'Agent file path')
36
+ .option('-i, --input <input>', 'Input prompt')
37
+ .option('-w, --watch', 'Watch for changes', false)
38
+ .action(async (file, options) => {
39
+ console.log(`Running agent: ${file}`);
40
+ if (options.input) {
41
+ console.log(`Input: ${options.input}`);
42
+ }
43
+ // TODO: Implement agent runner
44
+ });
45
+
46
+ // Test command
47
+ program
48
+ .command('test')
49
+ .description('Run agent tests')
50
+ .argument('[pattern]', 'Test file pattern')
51
+ .option('-w, --watch', 'Watch mode', false)
52
+ .option('-c, --coverage', 'Generate coverage report', false)
53
+ .action(async (pattern, _options) => {
54
+ console.log('Running tests...');
55
+ if (pattern) {
56
+ console.log(`Pattern: ${pattern}`);
57
+ }
58
+ // TODO: Implement test runner
59
+ });
60
+
61
+ // Validate command
62
+ program
63
+ .command('validate')
64
+ .description('Validate agent configuration')
65
+ .argument('<file>', 'Configuration file path')
66
+ .action(async (file) => {
67
+ console.log(`Validating: ${file}`);
68
+ // TODO: Implement validation
69
+ });
70
+
71
+ // Plan command
72
+ program
73
+ .command('plan')
74
+ .description('Generate execution plan for a goal')
75
+ .argument('<goal>', 'Goal to plan')
76
+ .option('-p, --planner <planner>', 'Planner type', 'classical')
77
+ .option('-o, --output <output>', 'Output file')
78
+ .action(async (goal, options) => {
79
+ console.log(`Planning: ${goal}`);
80
+ console.log(`Planner: ${options.planner}`);
81
+ // TODO: Implement plan generation
82
+ });
83
+
84
+ // Execute command
85
+ program
86
+ .command('execute')
87
+ .description('Execute a plan')
88
+ .argument('<file>', 'Plan file path')
89
+ .option('-p, --parallel', 'Enable parallel execution', false)
90
+ .option('-c, --concurrency <number>', 'Max concurrency', '4')
91
+ .action(async (file, options) => {
92
+ console.log(`Executing plan: ${file}`);
93
+ console.log(`Parallel: ${options.parallel}`);
94
+ console.log(`Concurrency: ${options.concurrency}`);
95
+ // TODO: Implement plan execution
96
+ });
97
+
98
+ // List templates command
99
+ program
100
+ .command('list-templates')
101
+ .description('List available project templates')
102
+ .action(() => {
103
+ console.log('Available templates:');
104
+ console.log(' - basic: Simple agent with minimal setup');
105
+ console.log(' - advanced: Agent with memory, tools, and planning');
106
+ console.log(' - multi-agent: Multi-agent orchestration setup');
107
+ console.log(' - workflow: Workflow-based agent system');
108
+ });
109
+
110
+ // Doctor command
111
+ program
112
+ .command('doctor')
113
+ .description('Check environment and dependencies')
114
+ .action(() => {
115
+ console.log('Checking environment...');
116
+ console.log(`Node.js version: ${process.version}`);
117
+ console.log(`Platform: ${process.platform}`);
118
+ console.log(`Architecture: ${process.arch}`);
119
+ // TODO: Implement environment checks
120
+ });
121
+
122
+ program.parse();
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Base agent implementation
3
+ */
4
+
5
+ import {
6
+ Agent,
7
+ AgentConfig,
8
+ AgentContext,
9
+ AgentInput,
10
+ AgentOutput,
11
+ AgentState,
12
+ ExecutionMetadata,
13
+ } from './types.js';
14
+ import { DebugLogger, createDebugLogger } from '../debug-logger.js';
15
+
16
+ /**
17
+ * Abstract base class providing common agent functionality
18
+ */
19
+ export abstract class BaseAgent extends Agent {
20
+ protected startTime?: Date;
21
+ protected iterationCount = 0;
22
+ protected logger: DebugLogger;
23
+
24
+ constructor(config: AgentConfig) {
25
+ super(config);
26
+ this.logger = createDebugLogger(`Agent:${this.name}`, config.debug ?? false);
27
+ }
28
+
29
+ /**
30
+ * Main execution method with lifecycle hooks
31
+ */
32
+ async run(input: AgentInput, ctx: AgentContext): Promise<AgentOutput> {
33
+ this.startTime = new Date();
34
+ this.iterationCount = 0;
35
+
36
+ this.logger.logStart('Agent execution', {
37
+ agentId: this.id,
38
+ prompt: input.prompt.slice(0, 100),
39
+ });
40
+
41
+ try {
42
+ // Before execution hook
43
+ if (this.hooks.beforeExecution) {
44
+ this.logger.debug('Running beforeExecution hook');
45
+ await this.hooks.beforeExecution(input, ctx);
46
+ }
47
+
48
+ // Set state to planning
49
+ this.logger.logStateChange('Agent', this.state, AgentState.PLANNING);
50
+ await this.setState(AgentState.PLANNING, ctx);
51
+
52
+ // Execute the agent-specific logic
53
+ this.logger.debug('Executing agent logic');
54
+ const result = await this.execute(input, ctx);
55
+
56
+ // Set state to completed
57
+ this.logger.logStateChange('Agent', this.state, AgentState.COMPLETED);
58
+ await this.setState(AgentState.COMPLETED, ctx);
59
+
60
+ const output = this.createOutput(result, AgentState.COMPLETED);
61
+
62
+ // After execution hook
63
+ if (this.hooks.afterExecution) {
64
+ this.logger.debug('Running afterExecution hook');
65
+ await this.hooks.afterExecution(output, ctx);
66
+ }
67
+
68
+ this.logger.logComplete('Agent execution', output.metadata?.durationMs);
69
+ return output;
70
+ } catch (error) {
71
+ // Set state to failed
72
+ this.logger.logStateChange('Agent', this.state, AgentState.FAILED);
73
+ await this.setState(AgentState.FAILED, ctx);
74
+
75
+ const errorMessage = error instanceof Error ? error.message : String(error);
76
+ this.logger.error('Agent execution failed', undefined, { error: errorMessage });
77
+
78
+ const errorOutput = this.createOutput(errorMessage, AgentState.FAILED);
79
+
80
+ // Error hook
81
+ if (this.hooks.onError) {
82
+ await this.hooks.onError(error instanceof Error ? error : new Error(errorMessage), ctx);
83
+ }
84
+
85
+ return errorOutput;
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Execute the agent's core logic - must be implemented by subclasses
91
+ */
92
+ protected abstract execute(input: AgentInput, ctx: AgentContext): Promise<unknown>;
93
+
94
+ /**
95
+ * Increment iteration counter
96
+ */
97
+ protected incrementIteration(): void {
98
+ this.iterationCount++;
99
+ }
100
+
101
+ /**
102
+ * Check if max iterations reached
103
+ */
104
+ protected isMaxIterationsReached(): boolean {
105
+ if (!this.config.maxIterations) return false;
106
+ return this.iterationCount >= this.config.maxIterations;
107
+ }
108
+
109
+ /**
110
+ * Create an agent output with metadata
111
+ */
112
+ protected createOutput(result: unknown, state: AgentState): AgentOutput {
113
+ const endTime = new Date();
114
+ const startTime = this.startTime ?? endTime;
115
+ const durationMs = endTime.getTime() - startTime.getTime();
116
+
117
+ const metadata: ExecutionMetadata = {
118
+ startTime,
119
+ endTime,
120
+ durationMs,
121
+ iterations: this.iterationCount,
122
+ };
123
+
124
+ return {
125
+ result,
126
+ state,
127
+ metadata,
128
+ };
129
+ }
130
+
131
+ /**
132
+ * Check if agent is currently executing
133
+ */
134
+ isExecuting(): boolean {
135
+ return this.state === AgentState.EXECUTING || this.state === AgentState.PLANNING;
136
+ }
137
+
138
+ /**
139
+ * Check if agent has completed
140
+ */
141
+ isCompleted(): boolean {
142
+ return this.state === AgentState.COMPLETED;
143
+ }
144
+
145
+ /**
146
+ * Check if agent has failed
147
+ */
148
+ hasFailed(): boolean {
149
+ return this.state === AgentState.FAILED;
150
+ }
151
+ }
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Agent context builder for fluent context creation
3
+ */
4
+
5
+ import {
6
+ AgentContext,
7
+ EntityId,
8
+ } from './types.js';
9
+ import type { MemoryStore } from '../memory/types.js';
10
+ import type { ToolRegistry } from '../tools/types.js';
11
+ import type { Planner } from '../planner/types.js';
12
+
13
+ /**
14
+ * Builder for creating AgentContext instances
15
+ */
16
+ export class AgentContextBuilder {
17
+ private agentId: EntityId = `agent-${Date.now()}`;
18
+ private memory?: MemoryStore;
19
+ private tools?: ToolRegistry;
20
+ private planner?: Planner;
21
+ private metadata: Record<string, unknown> = {};
22
+
23
+ /**
24
+ * Set the agent ID
25
+ */
26
+ withAgentId(agentId: EntityId): this {
27
+ this.agentId = agentId;
28
+ return this;
29
+ }
30
+
31
+ /**
32
+ * Set the memory store
33
+ */
34
+ withMemory(memory: MemoryStore): this {
35
+ this.memory = memory;
36
+ return this;
37
+ }
38
+
39
+ /**
40
+ * Set the tool registry
41
+ */
42
+ withTools(tools: ToolRegistry): this {
43
+ this.tools = tools;
44
+ return this;
45
+ }
46
+
47
+ /**
48
+ * Set the planner
49
+ */
50
+ withPlanner(planner: Planner): this {
51
+ this.planner = planner;
52
+ return this;
53
+ }
54
+
55
+ /**
56
+ * Add metadata
57
+ */
58
+ withMetadata(key: string, value: unknown): this {
59
+ this.metadata[key] = value;
60
+ return this;
61
+ }
62
+
63
+ /**
64
+ * Add multiple metadata entries
65
+ */
66
+ withMetadataEntries(entries: Record<string, unknown>): this {
67
+ this.metadata = { ...this.metadata, ...entries };
68
+ return this;
69
+ }
70
+
71
+ /**
72
+ * Build the AgentContext
73
+ */
74
+ build(): AgentContext {
75
+ if (!this.memory) {
76
+ throw new Error('Memory store is required');
77
+ }
78
+ if (!this.tools) {
79
+ throw new Error('Tool registry is required');
80
+ }
81
+ if (!this.planner) {
82
+ throw new Error('Planner is required');
83
+ }
84
+
85
+ return {
86
+ agentId: this.agentId,
87
+ memory: this.memory,
88
+ tools: this.tools,
89
+ planner: this.planner,
90
+ metadata: { ...this.metadata },
91
+ };
92
+ }
93
+
94
+ /**
95
+ * Create a builder from an existing context
96
+ */
97
+ static fromContext(context: AgentContext): AgentContextBuilder {
98
+ const builder = new AgentContextBuilder();
99
+ builder.agentId = context.agentId;
100
+ builder.memory = context.memory;
101
+ builder.tools = context.tools;
102
+ builder.planner = context.planner;
103
+ builder.metadata = { ...context.metadata };
104
+ return builder;
105
+ }
106
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Core module exports
3
+ */
4
+
5
+ export * from './types.js';
6
+ export * from './schemas.js';
7
+ export { BaseAgent } from './base-agent.js';
8
+ export { AgentContextBuilder } from './context-builder.js';
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Type-safe I/O: input_schema and output_schema (Zod) for agent runs.
3
+ */
4
+
5
+ import type { z } from 'zod';
6
+
7
+ /** Input schema for agent run (e.g. prompt + optional structured fields) */
8
+ export type InputSchema<T = unknown> = z.ZodType<T>;
9
+
10
+ /** Output schema for agent run (e.g. structured response) */
11
+ export type OutputSchema<T = unknown> = z.ZodType<T>;
12
+
13
+ /** Parsed input from user when inputSchema is used */
14
+ export type ParsedInput<T> = T;
15
+
16
+ /** Parsed output from agent when outputSchema is used */
17
+ export type ParsedOutput<T> = T;