zouroboros-core 2.0.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.
@@ -0,0 +1,406 @@
1
+ /**
2
+ * Core types for Zouroboros
3
+ *
4
+ * This file defines all shared types used across the Zouroboros ecosystem.
5
+ */
6
+ export type UUID = string;
7
+ export type Timestamp = string;
8
+ export type DecayClass = 'permanent' | 'long' | 'medium' | 'short';
9
+ export interface ZouroborosConfig {
10
+ version: string;
11
+ createdAt: Timestamp;
12
+ updatedAt: Timestamp;
13
+ core: CoreConfig;
14
+ memory: MemoryConfig;
15
+ swarm: SwarmConfig;
16
+ personas: PersonasConfig;
17
+ selfheal: SelfHealConfig;
18
+ }
19
+ export interface CoreConfig {
20
+ workspaceRoot: string;
21
+ dataDir: string;
22
+ logLevel: 'debug' | 'info' | 'warn' | 'error';
23
+ defaultTimezone: string;
24
+ }
25
+ export interface MemoryConfig {
26
+ enabled: boolean;
27
+ dbPath: string;
28
+ vectorEnabled: boolean;
29
+ ollamaUrl: string;
30
+ ollamaModel: string;
31
+ autoCapture: boolean;
32
+ captureIntervalMinutes: number;
33
+ graphBoost: boolean;
34
+ hydeExpansion: boolean;
35
+ decayConfig: {
36
+ permanent: number;
37
+ long: number;
38
+ medium: number;
39
+ short: number;
40
+ };
41
+ }
42
+ export interface SwarmConfig {
43
+ enabled: boolean;
44
+ defaultCombo: string;
45
+ maxConcurrency: number;
46
+ localConcurrency: number;
47
+ circuitBreaker: {
48
+ enabled: boolean;
49
+ failureThreshold: number;
50
+ resetTimeoutMs: number;
51
+ };
52
+ retryConfig: {
53
+ maxRetries: number;
54
+ backoffMultiplier: number;
55
+ maxBackoffMs: number;
56
+ };
57
+ registryPath: string;
58
+ }
59
+ export interface PersonasConfig {
60
+ enabled: boolean;
61
+ identityDir: string;
62
+ defaultSoulPath: string;
63
+ autoCreateHeartbeat: boolean;
64
+ }
65
+ export interface SelfHealConfig {
66
+ enabled: boolean;
67
+ introspectionInterval: string;
68
+ autoPrescribe: boolean;
69
+ governorEnabled: boolean;
70
+ minHealthScore: number;
71
+ metrics: Record<string, MetricThreshold>;
72
+ }
73
+ export interface MetricThreshold {
74
+ target: number;
75
+ weight: number;
76
+ warningThreshold: number;
77
+ criticalThreshold: number;
78
+ }
79
+ export interface MemoryEntry {
80
+ id: UUID;
81
+ entity: string;
82
+ key: string | null;
83
+ value: string;
84
+ decay: DecayClass;
85
+ createdAt: Timestamp;
86
+ updatedAt: Timestamp;
87
+ embedding?: number[];
88
+ tags?: string[];
89
+ }
90
+ export interface EpisodicMemory {
91
+ id: UUID;
92
+ conversationId: string;
93
+ summary: string;
94
+ outcome: 'success' | 'failure' | 'partial' | 'resolved' | 'ongoing';
95
+ entities: string[];
96
+ tags: string[];
97
+ createdAt: Timestamp;
98
+ tokenCount?: number;
99
+ }
100
+ export interface TemporalQuery {
101
+ since?: string;
102
+ until?: string;
103
+ outcome?: string;
104
+ limit?: number;
105
+ }
106
+ export interface ProceduralMemory {
107
+ id: UUID;
108
+ name: string;
109
+ description: string;
110
+ steps: string[];
111
+ successRate: number;
112
+ lastExecuted?: Timestamp;
113
+ executionCount: number;
114
+ }
115
+ export interface CognitiveProfile {
116
+ entity: string;
117
+ traits: Record<string, number>;
118
+ preferences: Record<string, string>;
119
+ interactionHistory: InteractionRecord[];
120
+ lastUpdated: Timestamp;
121
+ }
122
+ export interface InteractionRecord {
123
+ timestamp: Timestamp;
124
+ type: 'query' | 'store' | 'search';
125
+ success: boolean;
126
+ latencyMs: number;
127
+ }
128
+ export interface MemorySearchResult {
129
+ entry: MemoryEntry;
130
+ score: number;
131
+ matchType: 'exact' | 'semantic' | 'graph' | 'hybrid';
132
+ }
133
+ export interface GraphNode {
134
+ id: string;
135
+ type: 'entity' | 'concept' | 'fact';
136
+ label: string;
137
+ properties: Record<string, unknown>;
138
+ }
139
+ export interface GraphEdge {
140
+ source: string;
141
+ target: string;
142
+ relation: string;
143
+ weight: number;
144
+ }
145
+ export interface SwarmCampaign {
146
+ id: UUID;
147
+ name: string;
148
+ description: string;
149
+ tasks: SwarmTask[];
150
+ status: 'pending' | 'running' | 'completed' | 'failed';
151
+ createdAt: Timestamp;
152
+ startedAt?: Timestamp;
153
+ completedAt?: Timestamp;
154
+ }
155
+ export interface SwarmTask {
156
+ id: UUID;
157
+ name: string;
158
+ description: string;
159
+ dependencies: string[];
160
+ executor: 'local';
161
+ localExecutor?: string;
162
+ prompt: string;
163
+ status: 'pending' | 'running' | 'completed' | 'failed';
164
+ output?: string;
165
+ error?: string;
166
+ startedAt?: Timestamp;
167
+ completedAt?: Timestamp;
168
+ tokenUsage?: TokenUsage;
169
+ }
170
+ export interface TokenUsage {
171
+ promptTokens: number;
172
+ completionTokens: number;
173
+ totalTokens: number;
174
+ costUsd: number;
175
+ }
176
+ export interface ExecutorBridge {
177
+ name: string;
178
+ type: 'local' | 'remote';
179
+ command: string;
180
+ healthCheck: string;
181
+ envVars: string[];
182
+ supportedModels?: string[];
183
+ }
184
+ export interface ExecutorRegistry {
185
+ version: string;
186
+ updatedAt: Timestamp;
187
+ executors: Record<string, ExecutorConfig>;
188
+ }
189
+ export interface ExecutorConfig {
190
+ name: string;
191
+ bridge: string;
192
+ healthCheck: string;
193
+ timeoutSeconds: number;
194
+ envVars: Record<string, string>;
195
+ }
196
+ export interface ComboRecommendation {
197
+ complexity: ComplexityAnalysis;
198
+ recommendedCombo: ModelCombo;
199
+ alternatives: ComboAlternative[];
200
+ resolvedCombo: string;
201
+ }
202
+ export interface ComplexityAnalysis {
203
+ tier: 'trivial' | 'simple' | 'moderate' | 'complex';
204
+ score: number;
205
+ signals: ComplexitySignals;
206
+ inferredTaskType: TaskType;
207
+ staticCombo: string;
208
+ }
209
+ export interface ComplexitySignals {
210
+ wordCount: number;
211
+ fileCount: number;
212
+ hasMultiStep: boolean;
213
+ hasTool: boolean;
214
+ hasAnalysis: boolean;
215
+ }
216
+ export type TaskType = 'coding' | 'review' | 'planning' | 'analysis' | 'debugging' | 'documentation' | 'general';
217
+ export interface ModelCombo {
218
+ id: string;
219
+ name: string;
220
+ description: string;
221
+ models: ModelConfig[];
222
+ estimatedCostPer1M: number;
223
+ traits: string[];
224
+ }
225
+ export interface ModelConfig {
226
+ provider: string;
227
+ model: string;
228
+ inputCostPer1M: number;
229
+ outputCostPer1M: number;
230
+ }
231
+ export interface ComboAlternative {
232
+ name: string;
233
+ score: number;
234
+ isFree: boolean;
235
+ }
236
+ export interface SeedSpec {
237
+ id: string;
238
+ createdAt: Timestamp;
239
+ goal: string;
240
+ constraints: string[];
241
+ acceptanceCriteria: string[];
242
+ ontology: OntologyDef;
243
+ evaluationPrinciples: EvaluationPrinciple[];
244
+ exitConditions: ExitCondition[];
245
+ ambiguityScore: number;
246
+ }
247
+ export interface OntologyDef {
248
+ name: string;
249
+ description: string;
250
+ fields: OntologyField[];
251
+ }
252
+ export interface OntologyField {
253
+ name: string;
254
+ type: string;
255
+ description: string;
256
+ }
257
+ export interface EvaluationPrinciple {
258
+ name: string;
259
+ description: string;
260
+ weight: number;
261
+ }
262
+ export interface ExitCondition {
263
+ name: string;
264
+ description: string;
265
+ criteria: string;
266
+ }
267
+ export interface EvaluationReport {
268
+ id: string;
269
+ seedId: string;
270
+ timestamp: Timestamp;
271
+ stages: {
272
+ mechanical: MechanicalStage;
273
+ semantic: SemanticStage;
274
+ consensus?: ConsensusStage;
275
+ };
276
+ decision: 'APPROVED' | 'NEEDS_WORK' | 'REJECTED';
277
+ recommendations: string[];
278
+ }
279
+ export interface MechanicalStage {
280
+ passed: boolean;
281
+ checks: MechanicalCheck[];
282
+ }
283
+ export interface MechanicalCheck {
284
+ name: string;
285
+ passed: boolean;
286
+ detail?: string;
287
+ }
288
+ export interface SemanticStage {
289
+ passed: boolean;
290
+ score: number;
291
+ acCompliance: number;
292
+ drift: number;
293
+ criteria: CriterionResult[];
294
+ }
295
+ export interface CriterionResult {
296
+ name: string;
297
+ met: boolean;
298
+ evidence?: string;
299
+ }
300
+ export interface ConsensusStage {
301
+ perspectives: Perspective[];
302
+ finalDecision: 'APPROVE' | 'REJECT';
303
+ reasoning: string;
304
+ }
305
+ export interface Perspective {
306
+ role: 'proposer' | 'devils_advocate' | 'synthesizer';
307
+ decision: 'APPROVE' | 'REJECT';
308
+ reasoning: string;
309
+ }
310
+ export type UnstuckPersona = 'hacker' | 'researcher' | 'simplifier' | 'architect' | 'contrarian';
311
+ export interface Persona {
312
+ id: UUID;
313
+ name: string;
314
+ description: string;
315
+ prompt: string;
316
+ safetyRules: SafetyRule[];
317
+ skills: string[];
318
+ mcpServers: string[];
319
+ identityFiles?: {
320
+ soul?: string;
321
+ identity?: string;
322
+ user?: string;
323
+ heartbeat?: string;
324
+ };
325
+ createdAt: Timestamp;
326
+ updatedAt: Timestamp;
327
+ }
328
+ export interface SafetyRule {
329
+ id: string;
330
+ condition: string;
331
+ instruction: string;
332
+ priority: 'critical' | 'high' | 'medium' | 'low';
333
+ }
334
+ export interface IdentityFile {
335
+ type: 'soul' | 'identity' | 'user' | 'heartbeat';
336
+ path: string;
337
+ content: string;
338
+ lastUpdated: Timestamp;
339
+ }
340
+ export interface IntrospectionScorecard {
341
+ id: string;
342
+ timestamp: Timestamp;
343
+ compositeScore: number;
344
+ metrics: MetricScore[];
345
+ status: 'HEALTHY' | 'WARNING' | 'CRITICAL';
346
+ weakestSubsystem: string;
347
+ opportunities: ImprovementOpportunity[];
348
+ }
349
+ export interface MetricScore {
350
+ name: string;
351
+ score: number;
352
+ target: number;
353
+ weight: number;
354
+ trend: 'improving' | 'stable' | 'declining';
355
+ status: 'HEALTHY' | 'WARNING' | 'CRITICAL';
356
+ }
357
+ export interface ImprovementOpportunity {
358
+ rank: number;
359
+ metric: string;
360
+ currentScore: number;
361
+ potentialImprovement: number;
362
+ recommendedAction: string;
363
+ }
364
+ export interface Prescription {
365
+ id: string;
366
+ scorecardId: string;
367
+ targetMetric: string;
368
+ seed: SeedSpec;
369
+ program?: AutoloopProgram;
370
+ governorFlags: GovernorFlag[];
371
+ approved: boolean;
372
+ createdAt: Timestamp;
373
+ }
374
+ export interface GovernorFlag {
375
+ type: 'schema_migration' | 'multi_file' | 'executor_change' | 'high_ambiguity' | 'no_baseline';
376
+ severity: 'warning' | 'block';
377
+ description: string;
378
+ }
379
+ export interface AutoloopProgram {
380
+ name: string;
381
+ metric: string;
382
+ targetFile: string;
383
+ runCommand: string;
384
+ extractCommand: string;
385
+ maxExperiments: number;
386
+ maxDurationHours: number;
387
+ maxCostUsd: number;
388
+ }
389
+ export interface EvolutionResult {
390
+ id: string;
391
+ prescriptionId: string;
392
+ status: 'success' | 'failure' | 'reverted';
393
+ baselineValue: number;
394
+ finalValue: number;
395
+ improvement: number;
396
+ experiments: ExperimentRecord[];
397
+ startedAt: Timestamp;
398
+ completedAt?: Timestamp;
399
+ }
400
+ export interface ExperimentRecord {
401
+ id: number;
402
+ change: string;
403
+ value: number;
404
+ improved: boolean;
405
+ committed: boolean;
406
+ }
package/dist/types.js ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Core types for Zouroboros
3
+ *
4
+ * This file defines all shared types used across the Zouroboros ecosystem.
5
+ */
6
+ export {};
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Utility functions for Zouroboros
3
+ */
4
+ /**
5
+ * Generate a UUID v4
6
+ */
7
+ export declare function generateUUID(): string;
8
+ /**
9
+ * Get current timestamp in ISO format
10
+ */
11
+ export declare function now(): string;
12
+ /**
13
+ * Deep clone an object
14
+ */
15
+ export declare function deepClone<T>(obj: T): T;
16
+ /**
17
+ * Sleep for a given number of milliseconds
18
+ */
19
+ export declare function sleep(ms: number): Promise<void>;
20
+ /**
21
+ * Retry a function with exponential backoff
22
+ */
23
+ export declare function retry<T>(fn: () => Promise<T>, options?: {
24
+ maxRetries?: number;
25
+ backoffMultiplier?: number;
26
+ maxBackoffMs?: number;
27
+ onRetry?: (error: Error, attempt: number) => void;
28
+ }): Promise<T>;
29
+ /**
30
+ * Format bytes to human readable string
31
+ */
32
+ export declare function formatBytes(bytes: number): string;
33
+ /**
34
+ * Format milliseconds to human readable duration
35
+ */
36
+ export declare function formatDuration(ms: number): string;
37
+ /**
38
+ * Truncate a string to a maximum length
39
+ */
40
+ export declare function truncate(str: string, maxLength: number, suffix?: string): string;
41
+ /**
42
+ * Parse a cron expression (simplified - only supports basic patterns)
43
+ */
44
+ export declare function parseCron(expression: string): {
45
+ minute: number;
46
+ hour: number;
47
+ };
48
+ /**
49
+ * Check if a value is a plain object
50
+ */
51
+ export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
52
+ /**
53
+ * Merge two objects deeply
54
+ */
55
+ export declare function deepMerge<T extends Record<string, unknown>>(target: T, source: Partial<T>): T;
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Utility functions for Zouroboros
3
+ */
4
+ import { randomUUID } from 'crypto';
5
+ /**
6
+ * Generate a UUID v4
7
+ */
8
+ export function generateUUID() {
9
+ return randomUUID();
10
+ }
11
+ /**
12
+ * Get current timestamp in ISO format
13
+ */
14
+ export function now() {
15
+ return new Date().toISOString();
16
+ }
17
+ /**
18
+ * Deep clone an object
19
+ */
20
+ export function deepClone(obj) {
21
+ return JSON.parse(JSON.stringify(obj));
22
+ }
23
+ /**
24
+ * Sleep for a given number of milliseconds
25
+ */
26
+ export function sleep(ms) {
27
+ return new Promise(resolve => setTimeout(resolve, ms));
28
+ }
29
+ /**
30
+ * Retry a function with exponential backoff
31
+ */
32
+ export async function retry(fn, options = {}) {
33
+ const { maxRetries = 3, backoffMultiplier = 2, maxBackoffMs = 30000, onRetry } = options;
34
+ let lastError = new Error('No attempts made');
35
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
36
+ try {
37
+ return await fn();
38
+ }
39
+ catch (error) {
40
+ lastError = error instanceof Error ? error : new Error(String(error));
41
+ if (attempt === maxRetries) {
42
+ throw lastError;
43
+ }
44
+ if (onRetry) {
45
+ onRetry(lastError, attempt + 1);
46
+ }
47
+ const backoffMs = Math.min(1000 * Math.pow(backoffMultiplier, attempt), maxBackoffMs);
48
+ await sleep(backoffMs);
49
+ }
50
+ }
51
+ throw lastError;
52
+ }
53
+ /**
54
+ * Format bytes to human readable string
55
+ */
56
+ export function formatBytes(bytes) {
57
+ const units = ['B', 'KB', 'MB', 'GB', 'TB'];
58
+ let size = bytes;
59
+ let unitIndex = 0;
60
+ while (size >= 1024 && unitIndex < units.length - 1) {
61
+ size /= 1024;
62
+ unitIndex++;
63
+ }
64
+ return `${size.toFixed(2)} ${units[unitIndex]}`;
65
+ }
66
+ /**
67
+ * Format milliseconds to human readable duration
68
+ */
69
+ export function formatDuration(ms) {
70
+ if (ms < 1000) {
71
+ return `${ms}ms`;
72
+ }
73
+ const seconds = Math.floor(ms / 1000);
74
+ if (seconds < 60) {
75
+ return `${seconds}s`;
76
+ }
77
+ const minutes = Math.floor(seconds / 60);
78
+ const remainingSeconds = seconds % 60;
79
+ if (minutes < 60) {
80
+ return `${minutes}m ${remainingSeconds}s`;
81
+ }
82
+ const hours = Math.floor(minutes / 60);
83
+ const remainingMinutes = minutes % 60;
84
+ return `${hours}h ${remainingMinutes}m`;
85
+ }
86
+ /**
87
+ * Truncate a string to a maximum length
88
+ */
89
+ export function truncate(str, maxLength, suffix = '...') {
90
+ if (str.length <= maxLength) {
91
+ return str;
92
+ }
93
+ return str.slice(0, maxLength - suffix.length) + suffix;
94
+ }
95
+ /**
96
+ * Parse a cron expression (simplified - only supports basic patterns)
97
+ */
98
+ export function parseCron(expression) {
99
+ const parts = expression.split(' ');
100
+ if (parts.length < 2) {
101
+ throw new Error('Invalid cron expression');
102
+ }
103
+ const minute = parts[0] === '*' ? 0 : parseInt(parts[0], 10);
104
+ const hour = parts[1] === '*' ? 0 : parseInt(parts[1], 10);
105
+ if (isNaN(minute) || isNaN(hour)) {
106
+ throw new Error('Invalid cron expression');
107
+ }
108
+ return { minute, hour };
109
+ }
110
+ /**
111
+ * Check if a value is a plain object
112
+ */
113
+ export function isPlainObject(value) {
114
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
115
+ }
116
+ /**
117
+ * Merge two objects deeply
118
+ */
119
+ export function deepMerge(target, source) {
120
+ const result = { ...target };
121
+ for (const key in source) {
122
+ if (source[key] !== undefined) {
123
+ if (isPlainObject(result[key]) && isPlainObject(source[key])) {
124
+ result[key] = deepMerge(result[key], source[key]);
125
+ }
126
+ else {
127
+ result[key] = source[key];
128
+ }
129
+ }
130
+ }
131
+ return result;
132
+ }
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "zouroboros-core",
3
+ "version": "2.0.0",
4
+ "description": "Core types, configuration, and utilities for Zouroboros",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ },
13
+ "./config": {
14
+ "import": "./dist/config/loader.js",
15
+ "types": "./dist/config/loader.d.ts"
16
+ }
17
+ },
18
+ "dependencies": {
19
+ "zod": "^3.22.4"
20
+ },
21
+ "devDependencies": {
22
+ "@types/node": "^20.11.0",
23
+ "typescript": "^5.3.3"
24
+ },
25
+ "files": [
26
+ "dist/",
27
+ "README.md"
28
+ ],
29
+ "keywords": [
30
+ "zouroboros",
31
+ "core",
32
+ "config",
33
+ "types"
34
+ ],
35
+ "license": "MIT",
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "https://github.com/marlandoj/zouroboros.git",
39
+ "directory": "packages/core"
40
+ },
41
+ "scripts": {
42
+ "build": "tsc",
43
+ "dev": "tsc --watch",
44
+ "typecheck": "tsc --noEmit",
45
+ "test": "bun test src/",
46
+ "test:coverage": "bun test --coverage src/",
47
+ "lint": "eslint src --ext .ts",
48
+ "clean": "rm -rf dist"
49
+ }
50
+ }