principles-disciple 1.6.0 → 1.7.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 (67) hide show
  1. package/dist/commands/context.js +7 -3
  2. package/dist/commands/evolution-status.d.ts +4 -0
  3. package/dist/commands/evolution-status.js +138 -0
  4. package/dist/commands/export.d.ts +2 -0
  5. package/dist/commands/export.js +45 -0
  6. package/dist/commands/focus.js +9 -6
  7. package/dist/commands/pain.js +8 -0
  8. package/dist/commands/principle-rollback.d.ts +4 -0
  9. package/dist/commands/principle-rollback.js +22 -0
  10. package/dist/commands/samples.d.ts +2 -0
  11. package/dist/commands/samples.js +55 -0
  12. package/dist/core/config.d.ts +5 -0
  13. package/dist/core/control-ui-db.d.ts +68 -0
  14. package/dist/core/control-ui-db.js +274 -0
  15. package/dist/core/detection-funnel.d.ts +1 -1
  16. package/dist/core/detection-funnel.js +4 -0
  17. package/dist/core/dictionary.d.ts +2 -0
  18. package/dist/core/dictionary.js +13 -0
  19. package/dist/core/event-log.d.ts +2 -1
  20. package/dist/core/event-log.js +3 -0
  21. package/dist/core/evolution-engine.d.ts +5 -5
  22. package/dist/core/evolution-engine.js +18 -18
  23. package/dist/core/evolution-migration.d.ts +5 -0
  24. package/dist/core/evolution-migration.js +65 -0
  25. package/dist/core/evolution-reducer.d.ts +69 -0
  26. package/dist/core/evolution-reducer.js +369 -0
  27. package/dist/core/evolution-types.d.ts +103 -0
  28. package/dist/core/path-resolver.js +75 -36
  29. package/dist/core/paths.d.ts +7 -8
  30. package/dist/core/paths.js +48 -40
  31. package/dist/core/profile.js +1 -1
  32. package/dist/core/session-tracker.d.ts +4 -0
  33. package/dist/core/session-tracker.js +15 -0
  34. package/dist/core/thinking-models.d.ts +38 -0
  35. package/dist/core/thinking-models.js +170 -0
  36. package/dist/core/trajectory.d.ts +184 -0
  37. package/dist/core/trajectory.js +817 -0
  38. package/dist/core/trust-engine.d.ts +2 -0
  39. package/dist/core/trust-engine.js +30 -4
  40. package/dist/core/workspace-context.d.ts +13 -0
  41. package/dist/core/workspace-context.js +50 -7
  42. package/dist/hooks/gate.js +117 -48
  43. package/dist/hooks/llm.js +114 -69
  44. package/dist/hooks/pain.js +105 -5
  45. package/dist/hooks/prompt.d.ts +11 -14
  46. package/dist/hooks/prompt.js +283 -57
  47. package/dist/hooks/subagent.js +27 -1
  48. package/dist/http/principles-console-route.d.ts +2 -0
  49. package/dist/http/principles-console-route.js +257 -0
  50. package/dist/i18n/commands.js +16 -0
  51. package/dist/index.js +83 -4
  52. package/dist/service/control-ui-query-service.d.ts +217 -0
  53. package/dist/service/control-ui-query-service.js +537 -0
  54. package/dist/service/evolution-worker.d.ts +9 -0
  55. package/dist/service/evolution-worker.js +152 -22
  56. package/dist/service/trajectory-service.d.ts +2 -0
  57. package/dist/service/trajectory-service.js +15 -0
  58. package/dist/tools/agent-spawn.d.ts +27 -6
  59. package/dist/tools/agent-spawn.js +339 -87
  60. package/dist/tools/deep-reflect.d.ts +27 -7
  61. package/dist/tools/deep-reflect.js +210 -121
  62. package/dist/types/event-types.d.ts +9 -2
  63. package/dist/types.d.ts +10 -0
  64. package/dist/types.js +5 -0
  65. package/openclaw.plugin.json +43 -11
  66. package/package.json +14 -4
  67. package/templates/langs/zh/skills/pd-daily/SKILL.md +97 -13
@@ -1,5 +1,6 @@
1
1
  import * as fs from 'fs';
2
2
  import * as path from 'path';
3
+ import { defaultContextConfig } from '../types.js';
3
4
  import { loadContextInjectionConfig } from '../hooks/prompt.js';
4
5
  /**
5
6
  * Get workspace directory from context
@@ -185,7 +186,8 @@ function applyPreset(workspaceDir, preset, isZh) {
185
186
  thinkingOs: false,
186
187
  trustScore: true,
187
188
  reflectionLog: false,
188
- projectFocus: 'off'
189
+ projectFocus: 'off',
190
+ evolutionContext: { ...defaultContextConfig.evolutionContext }
189
191
  };
190
192
  break;
191
193
  case 'standard':
@@ -193,7 +195,8 @@ function applyPreset(workspaceDir, preset, isZh) {
193
195
  thinkingOs: true,
194
196
  trustScore: true,
195
197
  reflectionLog: false,
196
- projectFocus: 'off'
198
+ projectFocus: 'off',
199
+ evolutionContext: { ...defaultContextConfig.evolutionContext }
197
200
  };
198
201
  break;
199
202
  case 'full':
@@ -201,7 +204,8 @@ function applyPreset(workspaceDir, preset, isZh) {
201
204
  thinkingOs: true,
202
205
  trustScore: true,
203
206
  reflectionLog: true,
204
- projectFocus: 'summary'
207
+ projectFocus: 'summary',
208
+ evolutionContext: { ...defaultContextConfig.evolutionContext }
205
209
  };
206
210
  break;
207
211
  }
@@ -0,0 +1,4 @@
1
+ import type { PluginCommandContext } from '../openclaw-sdk.js';
2
+ export declare function handleEvolutionStatusCommand(ctx: PluginCommandContext): {
3
+ text: string;
4
+ };
@@ -0,0 +1,138 @@
1
+ import { EvolutionReducerImpl } from '../core/evolution-reducer.js';
2
+ import { normalizeLanguage } from '../i18n/commands.js';
3
+ import { getAgentScorecard } from '../core/trust-engine.js';
4
+ import { EventLogService } from '../core/event-log.js';
5
+ import * as fs from 'fs';
6
+ import * as path from 'path';
7
+ function getQueueStats(workspaceDir) {
8
+ const stateDir = path.join(workspaceDir, '.state', 'principles');
9
+ const queuePath = path.join(stateDir, 'evolution_queue.json');
10
+ let pending = 0;
11
+ let completed = 0;
12
+ let inProgress = 0;
13
+ try {
14
+ if (fs.existsSync(queuePath)) {
15
+ const queue = JSON.parse(fs.readFileSync(queuePath, 'utf-8'));
16
+ for (const item of queue) {
17
+ if (item.status === 'completed') {
18
+ completed++;
19
+ }
20
+ else if (item.status === 'in_progress') {
21
+ inProgress++;
22
+ }
23
+ else {
24
+ pending++;
25
+ }
26
+ }
27
+ }
28
+ }
29
+ catch {
30
+ // Ignore errors, return zeros
31
+ }
32
+ return { pending, completed, inProgress };
33
+ }
34
+ function getCurrentPain(workspaceDir) {
35
+ const stateDir = path.join(workspaceDir, '.state', 'principles');
36
+ const painFlagPath = path.join(stateDir, '.pain_flag');
37
+ try {
38
+ if (fs.existsSync(painFlagPath)) {
39
+ const data = JSON.parse(fs.readFileSync(painFlagPath, 'utf-8'));
40
+ return {
41
+ painScore: data.score || 0,
42
+ painSource: data.source || 'none'
43
+ };
44
+ }
45
+ }
46
+ catch {
47
+ // Ignore errors
48
+ }
49
+ return { painScore: 0, painSource: 'none' };
50
+ }
51
+ export function handleEvolutionStatusCommand(ctx) {
52
+ const workspaceDir = ctx.config?.workspaceDir || process.cwd();
53
+ const reducer = new EvolutionReducerImpl({ workspaceDir });
54
+ const stats = reducer.getStats();
55
+ // Get Trust Score
56
+ let trustScore = 0;
57
+ let trustStage = 1;
58
+ try {
59
+ const scorecard = getAgentScorecard(workspaceDir);
60
+ trustScore = scorecard.trust_score ?? 0;
61
+ trustStage = trustScore >= 80 ? 4 : trustScore >= 60 ? 3 : trustScore >= 30 ? 2 : 1;
62
+ }
63
+ catch {
64
+ // Ignore errors, use defaults
65
+ }
66
+ // Get EventLog for GFI and Pain stats
67
+ let gfiPeak = 0;
68
+ let painSignals = 0;
69
+ try {
70
+ const stateDir = path.join(workspaceDir, '.state', 'principles');
71
+ const eventLog = EventLogService.get(stateDir);
72
+ const today = new Date().toISOString().split('T')[0];
73
+ const dailyStats = eventLog.getDailyStats(today);
74
+ gfiPeak = dailyStats.gfi?.peak ?? 0;
75
+ painSignals = dailyStats.pain?.signalsDetected ?? 0;
76
+ }
77
+ catch {
78
+ // Ignore errors, use defaults
79
+ }
80
+ // Get Queue Stats
81
+ const queueStats = getQueueStats(workspaceDir);
82
+ // Get Current Pain
83
+ const currentPain = getCurrentPain(workspaceDir);
84
+ // Determine language - handle both 'zh' and 'zh-CN' formats
85
+ const rawLang = ctx.config?.language || 'en';
86
+ const lang = normalizeLanguage(rawLang);
87
+ if (lang === 'zh') {
88
+ const lines = [
89
+ '📈 Evolution 状态',
90
+ '━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
91
+ '',
92
+ `🛡️ Trust Score: ${trustScore}/100 (Stage ${trustStage})`,
93
+ `😴 GFI Peak: ${gfiPeak.toFixed(1)}`,
94
+ `⚡ Current Pain: ${currentPain.painScore} pts (${currentPain.painSource})`,
95
+ `📈 Pain Signals Today: ${painSignals}`,
96
+ '',
97
+ '📊 Evolution Rules',
98
+ '━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
99
+ `- 候选原则: ${stats.candidateCount}`,
100
+ `- 观察期原则: ${stats.probationCount}`,
101
+ `- 生效原则: ${stats.activeCount}`,
102
+ `- 已废弃原则: ${stats.deprecatedCount}`,
103
+ `- 最近晋升时间: ${stats.lastPromotedAt ?? '无'}`,
104
+ '',
105
+ '📋 Evolution Queue',
106
+ '━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
107
+ `- 待处理: ${queueStats.pending} 项`,
108
+ `- 进行中: ${queueStats.inProgress} 项`,
109
+ `- 已完成: ${queueStats.completed} 项`,
110
+ ];
111
+ return { text: lines.join('\n') };
112
+ }
113
+ // English
114
+ const lines = [
115
+ '📈 Evolution Status',
116
+ '━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
117
+ '',
118
+ `🛡️ Trust Score: ${trustScore}/100 (Stage ${trustStage})`,
119
+ `😴 GFI Peak: ${gfiPeak.toFixed(1)}`,
120
+ `⚡ Current Pain: ${currentPain.painScore} pts (${currentPain.painSource})`,
121
+ `📈 Pain Signals Today: ${painSignals}`,
122
+ '',
123
+ '📊 Evolution Rules',
124
+ '━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
125
+ `- candidate principles: ${stats.candidateCount}`,
126
+ `- probation principles: ${stats.probationCount}`,
127
+ `- active principles: ${stats.activeCount}`,
128
+ `- deprecated principles: ${stats.deprecatedCount}`,
129
+ `- last promoted: ${stats.lastPromotedAt ?? 'none'}`,
130
+ '',
131
+ '📋 Evolution Queue',
132
+ '━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
133
+ `- Pending: ${queueStats.pending}`,
134
+ `- In Progress: ${queueStats.inProgress}`,
135
+ `- Completed: ${queueStats.completed}`,
136
+ ];
137
+ return { text: lines.join('\n') };
138
+ }
@@ -0,0 +1,2 @@
1
+ import type { PluginCommandContext, PluginCommandResult } from '../openclaw-sdk.js';
2
+ export declare function handleExportCommand(ctx: PluginCommandContext): PluginCommandResult;
@@ -0,0 +1,45 @@
1
+ import { WorkspaceContext } from '../core/workspace-context.js';
2
+ function isZh(ctx) {
3
+ return String(ctx.config?.language || 'en').startsWith('zh');
4
+ }
5
+ export function handleExportCommand(ctx) {
6
+ const workspaceDir = ctx.config?.workspaceDir || process.cwd();
7
+ const zh = isZh(ctx);
8
+ const args = (ctx.args || '').trim();
9
+ const [subcommand = 'corrections'] = args.split(/\s+/).filter(Boolean);
10
+ const wctx = WorkspaceContext.fromHookContext({ workspaceDir, ...ctx.config });
11
+ if (subcommand !== 'analytics' && subcommand !== 'corrections') {
12
+ return {
13
+ text: zh
14
+ ? '无效的导出类型。请使用 `analytics` 或 `corrections [--redacted]`。'
15
+ : 'Invalid export target. Use `analytics` or `corrections [--redacted]`.',
16
+ };
17
+ }
18
+ try {
19
+ if (subcommand === 'analytics') {
20
+ const result = wctx.trajectory.exportAnalytics();
21
+ return {
22
+ text: zh
23
+ ? `已导出 analytics 快照到 ${result.filePath},共 ${result.count} 条聚合记录。`
24
+ : `Exported analytics snapshot to ${result.filePath} (${result.count} aggregated rows).`,
25
+ };
26
+ }
27
+ const redacted = args.includes('--redacted');
28
+ const result = wctx.trajectory.exportCorrections({
29
+ mode: redacted ? 'redacted' : 'raw',
30
+ approvedOnly: true,
31
+ });
32
+ return {
33
+ text: zh
34
+ ? `已导出纠错样本到 ${result.filePath},模式 ${result.mode},共 ${result.count} 条。`
35
+ : `Exported correction samples to ${result.filePath} (mode=${result.mode}, count=${result.count}).`,
36
+ };
37
+ }
38
+ catch {
39
+ return {
40
+ text: zh
41
+ ? '导出失败,请检查日志。'
42
+ : 'Export failed. Check logs.',
43
+ };
44
+ }
45
+ }
@@ -9,9 +9,10 @@
9
9
  */
10
10
  import * as fs from 'fs';
11
11
  import * as path from 'path';
12
+ import { randomUUID } from 'node:crypto';
12
13
  import { WorkspaceContext } from '../core/workspace-context.js';
13
14
  import { getHistoryDir, backupToHistory, cleanupHistory, extractVersion, extractDate, } from '../core/focus-history.js';
14
- import { agentSpawnTool } from '../tools/agent-spawn.js';
15
+ import { createAgentSpawnTool } from '../tools/agent-spawn.js';
15
16
  /**
16
17
  * 清理 Markdown 代码块围栏
17
18
  * 移除开头的 ```lang 和结尾的 ```
@@ -329,14 +330,16 @@ If no milestones to record, leave ===MEMORY=== section empty.`;
329
330
  let memoryUpdated = false;
330
331
  try {
331
332
  // 调用子智能体进行压缩
332
- const result = await agentSpawnTool.execute({
333
+ const tool = createAgentSpawnTool(api);
334
+ const result = await tool.execute(`focus-compress-${randomUUID()}`, {
333
335
  agentType: 'reporter', // 使用 reporter 类型,适合总结和压缩
334
336
  task: compressPrompt,
335
- }, api);
337
+ });
336
338
  // 解析输出,提取 MEMORY 和 COMPRESSED 部分
337
- if (result && result.trim()) {
338
- const memoryMatch = result.match(/===MEMORY===([\s\S]*?)===COMPRESSED===/);
339
- const compressedMatch = result.match(/===COMPRESSED===([\s\S]*?)$/);
339
+ const resultText = result?.content?.[0]?.text || '';
340
+ if (resultText.trim()) {
341
+ const memoryMatch = resultText.match(/===MEMORY===([\s\S]*?)===COMPRESSED===/);
342
+ const compressedMatch = resultText.match(/===COMPRESSED===([\s\S]*?)$/);
340
343
  if (compressedMatch && compressedMatch[1].trim()) {
341
344
  // 清理 Markdown 代码块围栏
342
345
  compressedContent = stripMarkdownFence(compressedMatch[1]);
@@ -93,6 +93,14 @@ export function handlePainCommand(ctx) {
93
93
  const newScore = wctx.trust.getScore();
94
94
  return { text: isZh ? `✅ 智能体信任分已重置为初始值 (${newScore})。` : `✅ Agent trust score has been reset to initial value (${newScore}).` };
95
95
  }
96
+ if (args === 'data') {
97
+ const stats = wctx.trajectory.getDataStats();
98
+ return {
99
+ text: isZh
100
+ ? `轨迹数据状态\n- 数据库: ${stats.dbPath}\n- 助手轮次: ${stats.assistantTurns}\n- 用户轮次: ${stats.userTurns}\n- 工具调用: ${stats.toolCalls}\n- 痛感事件: ${stats.painEvents}\n- 待审核样本: ${stats.pendingSamples}\n- 已通过样本: ${stats.approvedSamples}\n- Blob 字节数: ${stats.blobBytes}\n- 最近写入: ${stats.lastIngestAt ?? 'none'}`
101
+ : `Trajectory Data Status\n- DB: ${stats.dbPath}\n- assistant turns: ${stats.assistantTurns}\n- user turns: ${stats.userTurns}\n- tool calls: ${stats.toolCalls}\n- pain events: ${stats.painEvents}\n- pending samples: ${stats.pendingSamples}\n- approved samples: ${stats.approvedSamples}\n- blob bytes: ${stats.blobBytes}\n- last ingest: ${stats.lastIngestAt ?? 'none'}`
102
+ };
103
+ }
96
104
  // Default: Show status
97
105
  const session = sessionId ? getSession(sessionId) : undefined;
98
106
  const gfi = session ? session.currentGfi : 0;
@@ -0,0 +1,4 @@
1
+ import type { PluginCommandContext } from '../openclaw-sdk.js';
2
+ export declare function handlePrincipleRollbackCommand(ctx: PluginCommandContext): {
3
+ text: string;
4
+ };
@@ -0,0 +1,22 @@
1
+ import { EvolutionReducerImpl } from '../core/evolution-reducer.js';
2
+ export function handlePrincipleRollbackCommand(ctx) {
3
+ const workspaceDir = ctx.config?.workspaceDir || process.cwd();
4
+ const argText = (ctx.args || '').trim();
5
+ const [principleId = '', ...reasonParts] = argText.split(/\s+/);
6
+ const reason = (reasonParts.join(' ') || 'manual rollback').trim();
7
+ const isZh = ctx.config?.language?.startsWith('zh');
8
+ if (!principleId) {
9
+ return { text: isZh ? '用法: /pd-principle-rollback <principleId> [reason]' : 'Usage: /pd-principle-rollback <principleId> [reason]' };
10
+ }
11
+ const reducer = new EvolutionReducerImpl({ workspaceDir });
12
+ const principle = reducer.getPrincipleById(principleId);
13
+ if (!principle) {
14
+ return { text: isZh ? `未找到原则: ${principleId}` : `Principle not found: ${principleId}` };
15
+ }
16
+ reducer.rollbackPrinciple(principleId, reason);
17
+ return {
18
+ text: isZh
19
+ ? `✅ 已回滚原则 ${principleId}\n原因: ${reason}`
20
+ : `✅ Rolled back principle ${principleId}\nReason: ${reason}`,
21
+ };
22
+ }
@@ -0,0 +1,2 @@
1
+ import type { PluginCommandContext, PluginCommandResult } from '../openclaw-sdk.js';
2
+ export declare function handleSamplesCommand(ctx: PluginCommandContext): PluginCommandResult;
@@ -0,0 +1,55 @@
1
+ import { WorkspaceContext } from '../core/workspace-context.js';
2
+ function isZh(ctx) {
3
+ return String(ctx.config?.language || 'en').startsWith('zh');
4
+ }
5
+ export function handleSamplesCommand(ctx) {
6
+ const workspaceDir = ctx.config?.workspaceDir || process.cwd();
7
+ const zh = isZh(ctx);
8
+ const args = (ctx.args || '').trim();
9
+ const wctx = WorkspaceContext.fromHookContext({ workspaceDir, ...ctx.config });
10
+ if (args.startsWith('review ')) {
11
+ const [, decision = '', sampleId = '', ...noteParts] = args.split(/\s+/);
12
+ if (decision !== 'approve' && decision !== 'reject') {
13
+ return {
14
+ text: zh
15
+ ? '无效的审核动作。请使用 `review approve <sample-id> [note]` 或 `review reject <sample-id> [note]`。'
16
+ : 'Invalid review action. Use `review approve <sample-id> [note]` or `review reject <sample-id> [note]`.',
17
+ };
18
+ }
19
+ if (!sampleId) {
20
+ return {
21
+ text: zh
22
+ ? '缺少 sample-id。'
23
+ : 'Missing sample-id.',
24
+ };
25
+ }
26
+ const normalizedDecision = decision === 'approve' ? 'approved' : 'rejected';
27
+ const note = noteParts.join(' ').trim();
28
+ let record;
29
+ try {
30
+ record = wctx.trajectory.reviewCorrectionSample(sampleId, normalizedDecision, note);
31
+ }
32
+ catch (error) {
33
+ return {
34
+ text: zh
35
+ ? `审核样本失败:${sampleId}`
36
+ : `Failed to review sample: ${sampleId}`,
37
+ };
38
+ }
39
+ return {
40
+ text: zh
41
+ ? `样本 ${record.sampleId} 已标记为 ${record.reviewStatus}。`
42
+ : `Sample ${record.sampleId} marked as ${record.reviewStatus}.`,
43
+ };
44
+ }
45
+ const samples = wctx.trajectory.listCorrectionSamples('pending');
46
+ if (samples.length === 0) {
47
+ return { text: zh ? '当前没有待审核纠错样本。' : 'No pending correction samples.' };
48
+ }
49
+ const lines = samples.map((sample) => `- ${sample.sampleId} | session=${sample.sessionId} | score=${sample.qualityScore}`);
50
+ return {
51
+ text: zh
52
+ ? `待审核纠错样本:\n${lines.join('\n')}`
53
+ : `Pending correction samples:\n${lines.join('\n')}`,
54
+ };
55
+ }
@@ -65,6 +65,11 @@ export interface TrustSettings {
65
65
  }
66
66
  export interface PainSettings {
67
67
  language: 'en' | 'zh';
68
+ trajectory?: {
69
+ blob_inline_threshold_bytes?: number;
70
+ busy_timeout_ms?: number;
71
+ orphan_blob_grace_days?: number;
72
+ };
68
73
  thresholds: {
69
74
  pain_trigger: number;
70
75
  cognitive_paralysis_input: number;
@@ -0,0 +1,68 @@
1
+ export interface ThinkingModelEventInput {
2
+ sessionId: string;
3
+ runId: string;
4
+ assistantTurnId: number;
5
+ modelId: string;
6
+ matchedPattern: string;
7
+ scenarioJson: unknown;
8
+ toolContextJson: unknown;
9
+ painContextJson: unknown;
10
+ principleContextJson: unknown;
11
+ triggerExcerpt: string;
12
+ createdAt: string;
13
+ }
14
+ export interface ControlUiDatabaseOptions {
15
+ workspaceDir: string;
16
+ busyTimeoutMs?: number;
17
+ }
18
+ export interface RecentThinkingContext {
19
+ toolCalls: Array<{
20
+ id: number;
21
+ toolName: string;
22
+ outcome: 'success' | 'failure' | 'blocked';
23
+ errorType: string | null;
24
+ errorMessage: string | null;
25
+ createdAt: string;
26
+ }>;
27
+ painEvents: Array<{
28
+ id: number;
29
+ source: string;
30
+ score: number;
31
+ reason: string | null;
32
+ createdAt: string;
33
+ }>;
34
+ gateBlocks: Array<{
35
+ id: number;
36
+ toolName: string;
37
+ reason: string;
38
+ filePath: string | null;
39
+ createdAt: string;
40
+ }>;
41
+ userCorrections: Array<{
42
+ id: number;
43
+ correctionCue: string | null;
44
+ rawExcerpt: string | null;
45
+ createdAt: string;
46
+ }>;
47
+ principleEvents: Array<{
48
+ id: number;
49
+ principleId: string | null;
50
+ eventType: string;
51
+ createdAt: string;
52
+ }>;
53
+ }
54
+ export declare class ControlUiDatabase {
55
+ private readonly workspaceDir;
56
+ private readonly dbPath;
57
+ private readonly blobDir;
58
+ private readonly db;
59
+ constructor(opts: ControlUiDatabaseOptions);
60
+ dispose(): void;
61
+ recordThinkingModelEvent(input: ThinkingModelEventInput): number;
62
+ getRecentThinkingContext(sessionId: string, beforeCreatedAt: string, limit?: number): RecentThinkingContext;
63
+ all<T>(sql: string, ...params: unknown[]): T[];
64
+ get<T>(sql: string, ...params: unknown[]): T | undefined;
65
+ restoreRawText(inlineText?: string | null, blobRef?: string | null): string;
66
+ private initSchema;
67
+ private withWrite;
68
+ }