opc-agent 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -188,9 +188,21 @@ program
188
188
  fs.mkdirSync(dir, { recursive: true });
189
189
  fs.mkdirSync(path.join(dir, 'src', 'skills'), { recursive: true });
190
190
  fs.mkdirSync(path.join(dir, 'data'), { recursive: true });
191
+ fs.mkdirSync(path.join(dir, 'brain-seeds'), { recursive: true });
191
192
  // Get system prompt content
192
193
  const systemPromptContent = roleData.files['system-prompt.md'] || roleData.files['prompts/system.md'] || '';
193
- // agent.yaml with role system prompt
194
+ // Generate brain-seeds/ files from role data
195
+ const brainSeedContent = roleData.files['brain-seed.md'] || '';
196
+ const industryMatch = brainSeedContent ? brainSeedContent.match(/# Industry Knowledge[\s\S]*?(?=# Job Knowledge|# Workstation Knowledge|$)/i) : null;
197
+ const jobMatch = brainSeedContent ? brainSeedContent.match(/# Job Knowledge[\s\S]*?(?=# Industry Knowledge|# Workstation Knowledge|$)/i) : null;
198
+ const workstationMatch = brainSeedContent ? brainSeedContent.match(/# Workstation Knowledge[\s\S]*?(?=# Industry Knowledge|# Job Knowledge|$)/i) : null;
199
+ fs.writeFileSync(path.join(dir, 'brain-seeds', 'industry.md'), industryMatch?.[0]?.trim() || `# Industry Knowledge\n\n## Overview\n\nAdd industry-specific knowledge for your domain.\n`);
200
+ fs.writeFileSync(path.join(dir, 'brain-seeds', 'job.md'), jobMatch?.[0]?.trim() || `# Job Knowledge\n\n## Core Skills\n\nAdd role-specific knowledge for ${roleDisplayName}.\n`);
201
+ // workstation.md: public workstation knowledge (tools, workflows, best practices)
202
+ // Company-specific knowledge belongs to Desk (closed-source), not here.
203
+ const workstationSeedFromRole = workstationMatch?.[0]?.trim() || '';
204
+ fs.writeFileSync(path.join(dir, 'brain-seeds', 'workstation.md'), workstationSeedFromRole || `# Workstation Knowledge\n\n## Tools & Environment\n\nCommon tools and setup for this workstation role.\n\n## Workflows\n\nStandard operating procedures and workflows.\n\n## Best Practices\n\nIndustry best practices for this role.\n`);
205
+ // agent.yaml with role system prompt and brain seeds
194
206
  const firstLine = systemPromptContent.split('\n').find((l) => l.trim() && !l.startsWith('#'))?.trim() || 'You are a helpful AI assistant.';
195
207
  fs.writeFileSync(path.join(dir, 'agent.yaml'), `apiVersion: opc/v1
196
208
  kind: Agent
@@ -212,6 +224,15 @@ spec:
212
224
  longTerm:
213
225
  provider: deepbrain
214
226
  database: ./data/brain.db
227
+ brain:
228
+ seeds:
229
+ - brain-seeds/industry.md
230
+ - brain-seeds/job.md
231
+ - brain-seeds/workstation.md
232
+ autoSeed: true
233
+ evolve:
234
+ enabled: true
235
+ direction: bottom-up
215
236
  skills: []
216
237
  `);
217
238
  // SOUL.md from system-prompt.md
@@ -292,8 +313,12 @@ export class EchoSkill extends BaseSkill {
292
313
  console.log(` ${icon.file} agent.yaml - Agent definition with role system prompt`);
293
314
  console.log(` ${icon.file} SOUL.md - Role personality (${systemPromptContent.split('\n').length} lines)`);
294
315
  console.log(` ${icon.file} CONTEXT.md - Role context & documentation`);
316
+ console.log(` ${icon.file} brain-seeds/ - 3-tier brain seed knowledge`);
317
+ console.log(` ${color.dim('├')} industry.md - Industry knowledge`);
318
+ console.log(` ${color.dim('├')} job.md - Job/role knowledge`);
319
+ console.log(` ${color.dim('└')} workstation.md - Workstation knowledge`);
295
320
  if (roleData.files['brain-seed.md']) {
296
- console.log(` ${icon.file} data/brain-seed.md - Role brain seed knowledge`);
321
+ console.log(` ${icon.file} data/brain-seed.md - Role brain seed knowledge (legacy)`);
297
322
  }
298
323
  console.log(` ${icon.file} src/index.ts - Entry point`);
299
324
  console.log(` ${icon.file} package.json - Dependencies`);
@@ -1403,9 +1428,12 @@ program
1403
1428
  }
1404
1429
  });
1405
1430
  // ── Brain command ────────────────────────────────────────────
1406
- program
1431
+ const brainCmd = program
1407
1432
  .command('brain')
1408
- .description('Show agent memory/brain status from DeepBrain')
1433
+ .description('Manage agent brain (memory, seeds, evolve)');
1434
+ brainCmd
1435
+ .command('status')
1436
+ .description('Show brain stats (pages, tiers, last evolve)')
1409
1437
  .option('--url <url>', 'DeepBrain server URL', 'http://localhost:3333')
1410
1438
  .action(async (opts) => {
1411
1439
  console.log(`\n${icon.gear} ${color.bold('DeepBrain Status')} — ${color.dim(opts.url)}\n`);
@@ -1438,6 +1466,86 @@ program
1438
1466
  }
1439
1467
  }
1440
1468
  });
1469
+ brainCmd
1470
+ .command('seed')
1471
+ .description('Import brain seed files into memory')
1472
+ .option('-f, --file <file>', 'OAD file', 'agent.yaml')
1473
+ .option('--status', 'Check if seeds have been imported')
1474
+ .option('--reset', 'Re-import seeds (clear marker and re-seed)')
1475
+ .action(async (opts) => {
1476
+ const { BrainSeedLoader } = require('./memory/seed-loader');
1477
+ let config = {};
1478
+ try {
1479
+ config = yaml.load(fs.readFileSync(opts.file, 'utf-8'));
1480
+ }
1481
+ catch { /* ignore */ }
1482
+ const brainConfig = config?.spec?.brain;
1483
+ if (!brainConfig?.seeds?.length) {
1484
+ console.log(`${icon.info} No brain seeds configured in ${opts.file}.`);
1485
+ console.log(` Add spec.brain.seeds to your agent.yaml.`);
1486
+ return;
1487
+ }
1488
+ const loader = new BrainSeedLoader(process.cwd(), {
1489
+ seeds: brainConfig.seeds,
1490
+ autoSeed: brainConfig.autoSeed !== false,
1491
+ });
1492
+ if (opts.status) {
1493
+ const seeded = await loader.isSeeded();
1494
+ console.log(`\n Brain seed status: ${seeded ? color.green('seeded ✔') : color.yellow('not seeded')}`);
1495
+ console.log(` Seeds configured: ${brainConfig.seeds.map((s) => color.cyan(s)).join(', ')}\n`);
1496
+ return;
1497
+ }
1498
+ if (opts.reset) {
1499
+ const markerPath = path.resolve(process.cwd(), '.brain-seeded');
1500
+ if (fs.existsSync(markerPath)) {
1501
+ fs.unlinkSync(markerPath);
1502
+ console.log(` ${icon.success} Cleared seed marker.`);
1503
+ }
1504
+ }
1505
+ if (await loader.isSeeded() && !opts.reset) {
1506
+ console.log(`${icon.info} Brain already seeded. Use --reset to re-import.`);
1507
+ return;
1508
+ }
1509
+ console.log(`\n${icon.gear} Importing brain seeds...\n`);
1510
+ // Use a simple mock brain that logs imports (real usage would connect to DeepBrain)
1511
+ const pages = [];
1512
+ const mockBrain = {
1513
+ learn: async (content, meta) => { pages.push(meta?.slug || 'unknown'); },
1514
+ };
1515
+ const result = await loader.seedBrain(mockBrain);
1516
+ await loader.markSeeded();
1517
+ console.log(` ${icon.success} Imported ${color.bold(String(result.imported))} pages from ${brainConfig.seeds.length} seed files.`);
1518
+ for (const p of result.pages) {
1519
+ console.log(` ${color.dim('•')} ${p}`);
1520
+ }
1521
+ console.log();
1522
+ });
1523
+ brainCmd
1524
+ .command('evolve')
1525
+ .description('Trigger manual knowledge evolution cycle')
1526
+ .option('--dry-run', 'Show what would be promoted without doing it')
1527
+ .action(async (opts) => {
1528
+ const { KnowledgeEvolver } = require('./memory/seed-loader');
1529
+ const evolver = new KnowledgeEvolver();
1530
+ console.log(`\n${icon.gear} ${color.bold('Knowledge Evolution')}\n`);
1531
+ console.log(` ${icon.info} Checking for promotion candidates...`);
1532
+ // Would connect to real brain in production
1533
+ const result = await evolver.checkPromotion(null);
1534
+ if (result.candidates.length === 0) {
1535
+ console.log(` ${icon.info} No knowledge ready for promotion yet.\n`);
1536
+ }
1537
+ else {
1538
+ for (const c of result.candidates) {
1539
+ console.log(` ${color.cyan(c.slug)} → ${c.fromTier} → ${c.toTier} (confidence: ${(c.confidence * 100).toFixed(0)}%)`);
1540
+ }
1541
+ if (opts.dryRun) {
1542
+ console.log(`\n ${icon.info} Dry run — no changes made.\n`);
1543
+ }
1544
+ else {
1545
+ console.log(`\n ${icon.success} Promoted ${result.promoted} knowledge entries.\n`);
1546
+ }
1547
+ }
1548
+ });
1441
1549
  // ── Logs command ─────────────────────────────────────────────
1442
1550
  program
1443
1551
  .command('logs')
@@ -6,6 +6,7 @@ import type { MCPTool } from '../tools/mcp';
6
6
  import { MCPToolRegistry } from '../tools/mcp';
7
7
  import { type SubAgentConfig, type SubAgentResult } from './subagent';
8
8
  import { Tracer } from '../telemetry';
9
+ import { type BrainSeedConfig } from '../memory/seed-loader';
9
10
  export declare class BaseAgent extends EventEmitter implements IAgent {
10
11
  readonly name: string;
11
12
  private _state;
@@ -23,6 +24,8 @@ export declare class BaseAgent extends EventEmitter implements IAgent {
23
24
  private longTermMemory?;
24
25
  private longTermMemoryConfig;
25
26
  private tracer?;
27
+ private brainSeedConfig?;
28
+ private agentDir;
26
29
  constructor(options: {
27
30
  name: string;
28
31
  systemPrompt?: string;
@@ -38,6 +41,8 @@ export declare class BaseAgent extends EventEmitter implements IAgent {
38
41
  };
39
42
  maxToolRounds?: number;
40
43
  tracer?: Tracer;
44
+ agentDir?: string;
45
+ brainSeedConfig?: BrainSeedConfig;
41
46
  });
42
47
  setLongTermMemory(brain: any, config?: {
43
48
  autoLearn?: boolean;
@@ -7,6 +7,7 @@ const providers_1 = require("../providers");
7
7
  const auto_learn_1 = require("../skills/auto-learn");
8
8
  const mcp_1 = require("../tools/mcp");
9
9
  const subagent_1 = require("./subagent");
10
+ const seed_loader_1 = require("../memory/seed-loader");
10
11
  class BaseAgent extends events_1.EventEmitter {
11
12
  name;
12
13
  _state = 'init';
@@ -24,6 +25,8 @@ class BaseAgent extends events_1.EventEmitter {
24
25
  longTermMemory;
25
26
  longTermMemoryConfig = { autoLearn: true, autoRecall: true };
26
27
  tracer;
28
+ brainSeedConfig;
29
+ agentDir;
27
30
  constructor(options) {
28
31
  super();
29
32
  this.name = options.name;
@@ -41,6 +44,8 @@ class BaseAgent extends events_1.EventEmitter {
41
44
  this.skillLearner = new auto_learn_1.SkillLearner(options.skillsDir);
42
45
  }
43
46
  this.tracer = options.tracer;
47
+ this.agentDir = options.agentDir ?? process.cwd();
48
+ this.brainSeedConfig = options.brainSeedConfig;
44
49
  }
45
50
  setLongTermMemory(brain, config) {
46
51
  this.longTermMemory = brain;
@@ -93,6 +98,15 @@ class BaseAgent extends events_1.EventEmitter {
93
98
  if (this.skillLearner) {
94
99
  await this.skillLearner.loadLearnedSkills();
95
100
  }
101
+ // Auto-seed brain if configured
102
+ if (this.brainSeedConfig?.autoSeed && this.longTermMemory) {
103
+ const loader = new seed_loader_1.BrainSeedLoader(this.agentDir, this.brainSeedConfig);
104
+ if (!await loader.isSeeded()) {
105
+ const result = await loader.seedBrain(this.longTermMemory);
106
+ this.emit('brain:seeded', result);
107
+ await loader.markSeeded();
108
+ }
109
+ }
96
110
  this.transition('ready');
97
111
  }
98
112
  async start() {
package/dist/index.d.ts CHANGED
@@ -104,6 +104,8 @@ export { TraceCollector, ConsoleExporter as TraceConsoleExporter, DeepBrainExpor
104
104
  export type { Span as TraceSpan, SpanEvent as TraceSpanEvent, TraceExporter as ITraceExporter } from './traces';
105
105
  export { Tracer, ConsoleExporter, FileExporter, OTLPHttpExporter, generateTraceId, generateSpanId } from './telemetry';
106
106
  export type { Span, SpanEvent, Metric, TraceExporter } from './telemetry';
107
+ export { SubAgentManager } from './core/subagent';
108
+ export type { SubAgentConfig, SubAgentResult } from './core/subagent';
107
109
  export { Scheduler, parseCron, cronMatches } from './core/scheduler';
108
110
  export type { CronJob, JobHandler } from './core/scheduler';
109
111
  export { getBuiltinTools, getBuiltinToolsByName } from './tools/builtin';
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.compose = exports.AgentPipeline = exports.Orchestrator = exports.getActiveSessions = exports.createAuthMiddleware = exports.deployToHermes = exports.KnowledgeBase = exports.addMessages = exports.detectLocale = exports.getLocale = exports.setLocale = exports.t = exports.LazyLoader = exports.RequestBatcher = exports.ConnectionPool = exports.VersionManager = exports.WebhookChannel = exports.VoiceChannel = exports.HITLManager = exports.AgentCardRegistry = exports.AgentRegistry = exports.parseOADWorkflow = exports.WorkflowBuilder = exports.GraphWorkflowEngine = exports.WorkflowEngine = exports.Analytics = exports.KeyManager = exports.ApprovalManager = exports.Sandbox = exports.PluginManager = exports.createMCPTool = exports.MCPToolRegistry = exports.Room = exports.SUPPORTED_PROVIDERS = exports.createProvider = exports.DeepBrainMemoryStore = exports.InMemoryStore = exports.SkillRegistry = exports.BaseSkill = exports.WebSocketChannel = exports.TelegramChannel = exports.WebChannel = exports.BaseChannel = exports.OADSchema = exports.validateOAD = exports.loadOAD = exports.Logger = exports.truncateOutput = exports.AgentRuntime = exports.BaseAgent = void 0;
4
4
  exports.DiscordChannel = exports.FeishuChannel = exports.createContentFilterPlugin = exports.contentFilterPlugin = exports.createEnhancedRateLimiterPlugin = exports.rateLimiterPlugin = exports.loggerPlugin = exports.createRateLimitPlugin = exports.createAnalyticsPlugin = exports.createLoggingPlugin = exports.inputValidation = exports.APIKeyManager = exports.corsMiddleware = exports.securityHeaders = exports.detectInjection = exports.sanitizeInput = exports.formatErrorForUser = exports.wrapError = exports.TimeoutError = exports.SecurityError = exports.RateLimitError = exports.PluginError = exports.ChannelError = exports.ConfigError = exports.ValidationError = exports.ProviderError = exports.OPCError = exports.createTeacherConfig = exports.createDataAnalystConfig = exports.getSupportedLocales = exports.LLMCache = exports.RateLimiter = exports.AnalyticsEngine = exports.formatReport = exports.loadTestCases = exports.runTests = exports.parseSkillMarkdown = exports.skillToMarkdown = exports.SkillLearner = exports.DocumentSkill = exports.SchedulerSkill = exports.WebhookTriggerSkill = exports.HttpSkill = exports.TextAnalysisTool = exports.JsonTransformTool = exports.DateTimeTool = exports.CalculatorTool = exports.WeChatChannel = exports.SlackChannel = exports.EmailChannel = void 0;
5
- exports.isValidEventType = exports.AGUI_EVENT_TYPES = exports.AGUIClient = exports.AGUIEventEmitter = exports.AGUIServer = exports.AgentEvaluator = exports.agentToMCPResources = exports.agentToMCPTools = exports.MCPServer = exports.JSON_RPC_ERRORS = exports.oadToAgentCard = exports.A2AClient = exports.A2AServer = exports.StudioServer = exports.AgentInstaller = exports.AgentPublisher = exports.AgentPackager = exports.MCPClient = exports.getBuiltinToolsByName = exports.getBuiltinTools = exports.cronMatches = exports.parseCron = exports.Scheduler = exports.generateSpanId = exports.generateTraceId = exports.OTLPHttpExporter = exports.FileExporter = exports.ConsoleExporter = exports.Tracer = exports.DeepBrainExporter = exports.TraceConsoleExporter = exports.TraceCollector = exports.StreamableResponse = exports.StreamingManager = exports.ToolGateway = exports.ProcessWatcher = void 0;
5
+ exports.isValidEventType = exports.AGUI_EVENT_TYPES = exports.AGUIClient = exports.AGUIEventEmitter = exports.AGUIServer = exports.AgentEvaluator = exports.agentToMCPResources = exports.agentToMCPTools = exports.MCPServer = exports.JSON_RPC_ERRORS = exports.oadToAgentCard = exports.A2AClient = exports.A2AServer = exports.StudioServer = exports.AgentInstaller = exports.AgentPublisher = exports.AgentPackager = exports.MCPClient = exports.getBuiltinToolsByName = exports.getBuiltinTools = exports.cronMatches = exports.parseCron = exports.Scheduler = exports.SubAgentManager = exports.generateSpanId = exports.generateTraceId = exports.OTLPHttpExporter = exports.FileExporter = exports.ConsoleExporter = exports.Tracer = exports.DeepBrainExporter = exports.TraceConsoleExporter = exports.TraceCollector = exports.StreamableResponse = exports.StreamingManager = exports.ToolGateway = exports.ProcessWatcher = void 0;
6
6
  // OPC Agent — Open Agent Framework
7
7
  var agent_1 = require("./core/agent");
8
8
  Object.defineProperty(exports, "BaseAgent", { enumerable: true, get: function () { return agent_1.BaseAgent; } });
@@ -195,6 +195,9 @@ Object.defineProperty(exports, "FileExporter", { enumerable: true, get: function
195
195
  Object.defineProperty(exports, "OTLPHttpExporter", { enumerable: true, get: function () { return telemetry_1.OTLPHttpExporter; } });
196
196
  Object.defineProperty(exports, "generateTraceId", { enumerable: true, get: function () { return telemetry_1.generateTraceId; } });
197
197
  Object.defineProperty(exports, "generateSpanId", { enumerable: true, get: function () { return telemetry_1.generateSpanId; } });
198
+ // v1.3.1 — Sub-agent management
199
+ var subagent_1 = require("./core/subagent");
200
+ Object.defineProperty(exports, "SubAgentManager", { enumerable: true, get: function () { return subagent_1.SubAgentManager; } });
198
201
  // v1.4.0 modules
199
202
  var scheduler_2 = require("./core/scheduler");
200
203
  Object.defineProperty(exports, "Scheduler", { enumerable: true, get: function () { return scheduler_2.Scheduler; } });
@@ -1,4 +1,6 @@
1
1
  import type { Message, MemoryStore } from '../core/types';
2
+ export { BrainSeedLoader, KnowledgeEvolver } from './seed-loader';
3
+ export type { BrainSeedConfig, SeedPage, SeedResult, PromotionResult, PromotionCandidate } from './seed-loader';
2
4
  export declare class InMemoryStore implements MemoryStore {
3
5
  private store;
4
6
  private conversations;
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.InMemoryStore = void 0;
3
+ exports.InMemoryStore = exports.KnowledgeEvolver = exports.BrainSeedLoader = void 0;
4
+ var seed_loader_1 = require("./seed-loader");
5
+ Object.defineProperty(exports, "BrainSeedLoader", { enumerable: true, get: function () { return seed_loader_1.BrainSeedLoader; } });
6
+ Object.defineProperty(exports, "KnowledgeEvolver", { enumerable: true, get: function () { return seed_loader_1.KnowledgeEvolver; } });
4
7
  class InMemoryStore {
5
8
  store = new Map();
6
9
  conversations = new Map();
@@ -0,0 +1,51 @@
1
+ export interface BrainSeedConfig {
2
+ seeds: string[];
3
+ autoSeed: boolean;
4
+ seedMarkerFile?: string;
5
+ evolve?: {
6
+ enabled: boolean;
7
+ direction: 'bottom-up' | 'top-down';
8
+ };
9
+ }
10
+ export interface SeedPage {
11
+ slug: string;
12
+ content: string;
13
+ tier: string;
14
+ }
15
+ export interface SeedResult {
16
+ imported: number;
17
+ pages: string[];
18
+ }
19
+ export interface PromotionCandidate {
20
+ slug: string;
21
+ content: string;
22
+ fromTier: string;
23
+ toTier: string;
24
+ confidence: number;
25
+ }
26
+ export interface PromotionResult {
27
+ candidates: PromotionCandidate[];
28
+ promoted: number;
29
+ }
30
+ export declare class BrainSeedLoader {
31
+ private agentDir;
32
+ private config;
33
+ private markerFile;
34
+ constructor(agentDir: string, config: BrainSeedConfig);
35
+ isSeeded(): Promise<boolean>;
36
+ seedBrain(brain: any): Promise<SeedResult>;
37
+ markSeeded(): Promise<void>;
38
+ parseSeedFile(filePath: string, tier: string): SeedPage[];
39
+ private inferTier;
40
+ private slugify;
41
+ }
42
+ export declare class KnowledgeEvolver {
43
+ private tierOrder;
44
+ checkPromotion(brain: any, options?: {
45
+ minInteractions?: number;
46
+ confidenceThreshold?: number;
47
+ }): Promise<PromotionResult>;
48
+ promoteToJob(brain: any, knowledge: string, jobSlug: string): Promise<void>;
49
+ promoteToIndustry(brain: any, knowledge: string, industrySlug: string): Promise<void>;
50
+ }
51
+ //# sourceMappingURL=seed-loader.d.ts.map
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.KnowledgeEvolver = exports.BrainSeedLoader = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ class BrainSeedLoader {
40
+ agentDir;
41
+ config;
42
+ markerFile;
43
+ constructor(agentDir, config) {
44
+ this.agentDir = agentDir;
45
+ this.config = config;
46
+ this.markerFile = config.seedMarkerFile
47
+ ? path.resolve(agentDir, config.seedMarkerFile)
48
+ : path.resolve(agentDir, '.brain-seeded');
49
+ }
50
+ async isSeeded() {
51
+ return fs.existsSync(this.markerFile);
52
+ }
53
+ async seedBrain(brain) {
54
+ const allPages = [];
55
+ for (const seedPath of this.config.seeds) {
56
+ const fullPath = path.resolve(this.agentDir, seedPath);
57
+ if (!fs.existsSync(fullPath))
58
+ continue;
59
+ const tier = this.inferTier(seedPath);
60
+ const pages = this.parseSeedFile(fullPath, tier);
61
+ allPages.push(...pages);
62
+ }
63
+ const importedSlugs = [];
64
+ for (const page of allPages) {
65
+ if (brain && typeof brain.store === 'function') {
66
+ await brain.store('brain-seeds', page.slug, page.content, {
67
+ tier: page.tier,
68
+ source: 'brain-seed',
69
+ });
70
+ }
71
+ else if (brain && typeof brain.learn === 'function') {
72
+ await brain.learn(page.content, {
73
+ tags: ['brain-seed', page.tier],
74
+ slug: page.slug,
75
+ });
76
+ }
77
+ importedSlugs.push(page.slug);
78
+ }
79
+ return { imported: importedSlugs.length, pages: importedSlugs };
80
+ }
81
+ async markSeeded() {
82
+ const dir = path.dirname(this.markerFile);
83
+ if (!fs.existsSync(dir))
84
+ fs.mkdirSync(dir, { recursive: true });
85
+ fs.writeFileSync(this.markerFile, JSON.stringify({
86
+ seededAt: new Date().toISOString(),
87
+ seeds: this.config.seeds,
88
+ }, null, 2));
89
+ }
90
+ parseSeedFile(filePath, tier) {
91
+ const content = fs.readFileSync(filePath, 'utf-8');
92
+ const pages = [];
93
+ const sections = content.split(/^## /m);
94
+ for (const section of sections) {
95
+ const trimmed = section.trim();
96
+ if (!trimmed)
97
+ continue;
98
+ const newlineIdx = trimmed.indexOf('\n');
99
+ if (newlineIdx === -1 && sections.indexOf(section) === 0 && !content.trimStart().startsWith('## ')) {
100
+ // This is preamble before any ## heading — skip or treat as intro
101
+ continue;
102
+ }
103
+ let title;
104
+ let body;
105
+ if (sections.indexOf(section) === 0 && !content.trimStart().startsWith('## ')) {
106
+ // Preamble (before first ##)
107
+ continue;
108
+ }
109
+ if (newlineIdx === -1) {
110
+ title = trimmed;
111
+ body = '';
112
+ }
113
+ else {
114
+ title = trimmed.slice(0, newlineIdx).trim();
115
+ body = trimmed.slice(newlineIdx + 1).trim();
116
+ }
117
+ const slug = `seed/${tier}/${this.slugify(title)}`;
118
+ pages.push({ slug, content: `## ${title}\n\n${body}`, tier });
119
+ }
120
+ return pages;
121
+ }
122
+ inferTier(seedPath) {
123
+ const basename = path.basename(seedPath, path.extname(seedPath)).toLowerCase();
124
+ if (basename.includes('industry'))
125
+ return 'industry';
126
+ if (basename.includes('job'))
127
+ return 'job';
128
+ if (basename.includes('workstation'))
129
+ return 'workstation';
130
+ return 'workstation';
131
+ }
132
+ slugify(text) {
133
+ return text
134
+ .toLowerCase()
135
+ .replace(/[^a-z0-9\u4e00-\u9fff]+/g, '-')
136
+ .replace(/^-|-$/g, '');
137
+ }
138
+ }
139
+ exports.BrainSeedLoader = BrainSeedLoader;
140
+ class KnowledgeEvolver {
141
+ tierOrder = ['workstation', 'job', 'industry'];
142
+ async checkPromotion(brain, options = {}) {
143
+ const minInteractions = options.minInteractions ?? 50;
144
+ const confidenceThreshold = options.confidenceThreshold ?? 0.8;
145
+ const result = { candidates: [], promoted: 0 };
146
+ // Search for frequently referenced seed knowledge
147
+ if (!brain || typeof brain.search !== 'function')
148
+ return result;
149
+ try {
150
+ const seedPages = await brain.search('brain-seeds', 'seed/', 100);
151
+ if (!Array.isArray(seedPages))
152
+ return result;
153
+ for (const page of seedPages) {
154
+ const meta = page.metadata || {};
155
+ const usageCount = meta.usageCount ?? 0;
156
+ const tier = meta.tier || 'workstation';
157
+ if (usageCount < minInteractions)
158
+ continue;
159
+ const confidence = Math.min(usageCount / (minInteractions * 2), 1.0);
160
+ if (confidence < confidenceThreshold)
161
+ continue;
162
+ const tierIdx = this.tierOrder.indexOf(tier);
163
+ if (tierIdx <= 0)
164
+ continue; // already at highest tier or unknown
165
+ const toTier = this.tierOrder[tierIdx - 1];
166
+ result.candidates.push({
167
+ slug: page.id || page.slug,
168
+ content: page.content,
169
+ fromTier: tier,
170
+ toTier,
171
+ confidence,
172
+ });
173
+ }
174
+ }
175
+ catch {
176
+ // Silent fail
177
+ }
178
+ return result;
179
+ }
180
+ async promoteToJob(brain, knowledge, jobSlug) {
181
+ if (brain && typeof brain.store === 'function') {
182
+ await brain.store('brain-seeds', jobSlug, knowledge, {
183
+ tier: 'job',
184
+ source: 'promotion',
185
+ promotedAt: new Date().toISOString(),
186
+ });
187
+ }
188
+ }
189
+ async promoteToIndustry(brain, knowledge, industrySlug) {
190
+ if (brain && typeof brain.store === 'function') {
191
+ await brain.store('brain-seeds', industrySlug, knowledge, {
192
+ tier: 'industry',
193
+ source: 'promotion',
194
+ promotedAt: new Date().toISOString(),
195
+ });
196
+ }
197
+ }
198
+ }
199
+ exports.KnowledgeEvolver = KnowledgeEvolver;
200
+ //# sourceMappingURL=seed-loader.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opc-agent",
3
- "version": "2.0.1",
3
+ "version": "2.1.0",
4
4
  "description": "Open Agent Framework — Build, test, and run AI Agents for business workstations",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",