tracelattice 1.2.5
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/LICENSE +24 -0
- package/README.md +112 -0
- package/dist/ServerConfig.d.ts +229 -0
- package/dist/ServerConfig.d.ts.map +1 -0
- package/dist/ServerConfig.js +121 -0
- package/dist/ServerConfig.js.map +1 -0
- package/dist/__tests__/base-registry.test.d.ts +2 -0
- package/dist/__tests__/base-registry.test.d.ts.map +1 -0
- package/dist/__tests__/base-transport-cov.test.d.ts +2 -0
- package/dist/__tests__/base-transport-cov.test.d.ts.map +1 -0
- package/dist/__tests__/base-transport.test.d.ts +2 -0
- package/dist/__tests__/base-transport.test.d.ts.map +1 -0
- package/dist/__tests__/config-loader.test.d.ts +2 -0
- package/dist/__tests__/config-loader.test.d.ts.map +1 -0
- package/dist/__tests__/connection-pool-cov.test.d.ts +2 -0
- package/dist/__tests__/connection-pool-cov.test.d.ts.map +1 -0
- package/dist/__tests__/connection-pool.test.d.ts +2 -0
- package/dist/__tests__/connection-pool.test.d.ts.map +1 -0
- package/dist/__tests__/container.test.d.ts +2 -0
- package/dist/__tests__/container.test.d.ts.map +1 -0
- package/dist/__tests__/crud.test.d.ts +2 -0
- package/dist/__tests__/crud.test.d.ts.map +1 -0
- package/dist/__tests__/discovery-cache.test.d.ts +2 -0
- package/dist/__tests__/discovery-cache.test.d.ts.map +1 -0
- package/dist/__tests__/errors.test.d.ts +2 -0
- package/dist/__tests__/errors.test.d.ts.map +1 -0
- package/dist/__tests__/factories.test.d.ts +2 -0
- package/dist/__tests__/factories.test.d.ts.map +1 -0
- package/dist/__tests__/health-checker-cov.test.d.ts +2 -0
- package/dist/__tests__/health-checker-cov.test.d.ts.map +1 -0
- package/dist/__tests__/health-checker.test.d.ts +2 -0
- package/dist/__tests__/health-checker.test.d.ts.map +1 -0
- package/dist/__tests__/helpers/factories.d.ts +36 -0
- package/dist/__tests__/helpers/factories.d.ts.map +1 -0
- package/dist/__tests__/helpers/index.d.ts +3 -0
- package/dist/__tests__/helpers/index.d.ts.map +1 -0
- package/dist/__tests__/helpers/timers.d.ts +4 -0
- package/dist/__tests__/helpers/timers.d.ts.map +1 -0
- package/dist/__tests__/history-manager.test.d.ts +2 -0
- package/dist/__tests__/history-manager.test.d.ts.map +1 -0
- package/dist/__tests__/http-helpers-cov.test.d.ts +2 -0
- package/dist/__tests__/http-helpers-cov.test.d.ts.map +1 -0
- package/dist/__tests__/http-transport-cov.test.d.ts +2 -0
- package/dist/__tests__/http-transport-cov.test.d.ts.map +1 -0
- package/dist/__tests__/http-transport.test.d.ts +2 -0
- package/dist/__tests__/http-transport.test.d.ts.map +1 -0
- package/dist/__tests__/input-normalizer.test.d.ts +8 -0
- package/dist/__tests__/input-normalizer.test.d.ts.map +1 -0
- package/dist/__tests__/integration.test.d.ts +2 -0
- package/dist/__tests__/integration.test.d.ts.map +1 -0
- package/dist/__tests__/lib-server.test.d.ts +2 -0
- package/dist/__tests__/lib-server.test.d.ts.map +1 -0
- package/dist/__tests__/memory-persistence.test.d.ts +2 -0
- package/dist/__tests__/memory-persistence.test.d.ts.map +1 -0
- package/dist/__tests__/metrics-integration.test.d.ts +2 -0
- package/dist/__tests__/metrics-integration.test.d.ts.map +1 -0
- package/dist/__tests__/persistence.test.d.ts +2 -0
- package/dist/__tests__/persistence.test.d.ts.map +1 -0
- package/dist/__tests__/reasoning-integration.test.d.ts +11 -0
- package/dist/__tests__/reasoning-integration.test.d.ts.map +1 -0
- package/dist/__tests__/reasoning-types.test.d.ts +2 -0
- package/dist/__tests__/reasoning-types.test.d.ts.map +1 -0
- package/dist/__tests__/request-context.test.d.ts +2 -0
- package/dist/__tests__/request-context.test.d.ts.map +1 -0
- package/dist/__tests__/sanitize.test.d.ts +2 -0
- package/dist/__tests__/sanitize.test.d.ts.map +1 -0
- package/dist/__tests__/schema.test.d.ts +2 -0
- package/dist/__tests__/schema.test.d.ts.map +1 -0
- package/dist/__tests__/sequentialthinking-tools.test.d.ts +2 -0
- package/dist/__tests__/sequentialthinking-tools.test.d.ts.map +1 -0
- package/dist/__tests__/server-config.test.d.ts +2 -0
- package/dist/__tests__/server-config.test.d.ts.map +1 -0
- package/dist/__tests__/skill-discovery.test.d.ts +2 -0
- package/dist/__tests__/skill-discovery.test.d.ts.map +1 -0
- package/dist/__tests__/skill-registry.test.d.ts +2 -0
- package/dist/__tests__/skill-registry.test.d.ts.map +1 -0
- package/dist/__tests__/skill-watcher.test.d.ts +2 -0
- package/dist/__tests__/skill-watcher.test.d.ts.map +1 -0
- package/dist/__tests__/sqlite-persistence.test.d.ts +2 -0
- package/dist/__tests__/sqlite-persistence.test.d.ts.map +1 -0
- package/dist/__tests__/sse-transport-cov.test.d.ts +2 -0
- package/dist/__tests__/sse-transport-cov.test.d.ts.map +1 -0
- package/dist/__tests__/sse-transport.test.d.ts +2 -0
- package/dist/__tests__/sse-transport.test.d.ts.map +1 -0
- package/dist/__tests__/streamable-http-cov.test.d.ts +2 -0
- package/dist/__tests__/streamable-http-cov.test.d.ts.map +1 -0
- package/dist/__tests__/streamable-http-transport.test.d.ts +2 -0
- package/dist/__tests__/streamable-http-transport.test.d.ts.map +1 -0
- package/dist/__tests__/structured-logger.test.d.ts +2 -0
- package/dist/__tests__/structured-logger.test.d.ts.map +1 -0
- package/dist/__tests__/thought-evaluator.test.d.ts +2 -0
- package/dist/__tests__/thought-evaluator.test.d.ts.map +1 -0
- package/dist/__tests__/thought-formatter.test.d.ts +2 -0
- package/dist/__tests__/thought-formatter.test.d.ts.map +1 -0
- package/dist/__tests__/thought-processor.test.d.ts +8 -0
- package/dist/__tests__/thought-processor.test.d.ts.map +1 -0
- package/dist/__tests__/tool-registry-cov.test.d.ts +2 -0
- package/dist/__tests__/tool-registry-cov.test.d.ts.map +1 -0
- package/dist/__tests__/tool-registry.test.d.ts +2 -0
- package/dist/__tests__/tool-registry.test.d.ts.map +1 -0
- package/dist/__tests__/tool-watcher.test.d.ts +2 -0
- package/dist/__tests__/tool-watcher.test.d.ts.map +1 -0
- package/dist/__tests__/worker-manager-cov.test.d.ts +2 -0
- package/dist/__tests__/worker-manager-cov.test.d.ts.map +1 -0
- package/dist/__tests__/worker-manager.test.d.ts +2 -0
- package/dist/__tests__/worker-manager.test.d.ts.map +1 -0
- package/dist/cache/DiscoveryCache.d.ts +269 -0
- package/dist/cache/DiscoveryCache.d.ts.map +1 -0
- package/dist/cache/DiscoveryCache.js +100 -0
- package/dist/cache/DiscoveryCache.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +114 -0
- package/dist/cli.js.map +1 -0
- package/dist/cluster/WorkerManager.d.ts +166 -0
- package/dist/cluster/WorkerManager.d.ts.map +1 -0
- package/dist/cluster/WorkerManager.js +202 -0
- package/dist/cluster/WorkerManager.js.map +1 -0
- package/dist/cluster/worker.d.ts +11 -0
- package/dist/cluster/worker.d.ts.map +1 -0
- package/dist/cluster/worker.js +36 -0
- package/dist/cluster/worker.js.map +1 -0
- package/dist/config/ConfigLoader.d.ts +224 -0
- package/dist/config/ConfigLoader.d.ts.map +1 -0
- package/dist/config/ConfigLoader.js +85 -0
- package/dist/config/ConfigLoader.js.map +1 -0
- package/dist/context/RequestContext.d.ts +61 -0
- package/dist/context/RequestContext.d.ts.map +1 -0
- package/dist/context/RequestContext.js +17 -0
- package/dist/context/RequestContext.js.map +1 -0
- package/dist/contracts/index.d.ts +10 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +1 -0
- package/dist/contracts/interfaces.d.ts +107 -0
- package/dist/contracts/interfaces.d.ts.map +1 -0
- package/dist/contracts/interfaces.js +1 -0
- package/dist/core/HistoryManager.d.ts +514 -0
- package/dist/core/HistoryManager.d.ts.map +1 -0
- package/dist/core/HistoryManager.js +331 -0
- package/dist/core/HistoryManager.js.map +1 -0
- package/dist/core/IHistoryManager.d.ts +100 -0
- package/dist/core/IHistoryManager.d.ts.map +1 -0
- package/dist/core/IHistoryManager.js +1 -0
- package/dist/core/InputNormalizer.d.ts +139 -0
- package/dist/core/InputNormalizer.d.ts.map +1 -0
- package/dist/core/InputNormalizer.js +101 -0
- package/dist/core/InputNormalizer.js.map +1 -0
- package/dist/core/ThoughtEvaluator.d.ts +127 -0
- package/dist/core/ThoughtEvaluator.d.ts.map +1 -0
- package/dist/core/ThoughtEvaluator.js +346 -0
- package/dist/core/ThoughtEvaluator.js.map +1 -0
- package/dist/core/ThoughtFormatter.d.ts +133 -0
- package/dist/core/ThoughtFormatter.d.ts.map +1 -0
- package/dist/core/ThoughtFormatter.js +70 -0
- package/dist/core/ThoughtFormatter.js.map +1 -0
- package/dist/core/ThoughtProcessor.d.ts +218 -0
- package/dist/core/ThoughtProcessor.d.ts.map +1 -0
- package/dist/core/ThoughtProcessor.js +205 -0
- package/dist/core/ThoughtProcessor.js.map +1 -0
- package/dist/core/reasoning.d.ts +169 -0
- package/dist/core/reasoning.d.ts.map +1 -0
- package/dist/core/reasoning.js +1 -0
- package/dist/core/step.d.ts +45 -0
- package/dist/core/step.d.ts.map +1 -0
- package/dist/core/step.js +1 -0
- package/dist/core/thought.d.ts +190 -0
- package/dist/core/thought.d.ts.map +1 -0
- package/dist/core/thought.js +1 -0
- package/dist/di/Container.d.ts +226 -0
- package/dist/di/Container.d.ts.map +1 -0
- package/dist/di/Container.js +96 -0
- package/dist/di/Container.js.map +1 -0
- package/dist/di/ServiceRegistry.d.ts +32 -0
- package/dist/di/ServiceRegistry.d.ts.map +1 -0
- package/dist/di/ServiceRegistry.js +1 -0
- package/dist/errors.d.ts +482 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +108 -0
- package/dist/errors.js.map +1 -0
- package/dist/health/HealthChecker.d.ts +73 -0
- package/dist/health/HealthChecker.d.ts.map +1 -0
- package/dist/health/HealthChecker.js +69 -0
- package/dist/health/HealthChecker.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/dist/lib.d.ts +205 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +219 -0
- package/dist/lib.js.map +1 -0
- package/dist/logger/NullLogger.d.ts +154 -0
- package/dist/logger/NullLogger.d.ts.map +1 -0
- package/dist/logger/NullLogger.js +24 -0
- package/dist/logger/NullLogger.js.map +1 -0
- package/dist/logger/StructuredLogger.d.ts +327 -0
- package/dist/logger/StructuredLogger.d.ts.map +1 -0
- package/dist/logger/StructuredLogger.js +72 -0
- package/dist/logger/StructuredLogger.js.map +1 -0
- package/dist/metrics/__tests__/metrics.test.d.ts +2 -0
- package/dist/metrics/__tests__/metrics.test.d.ts.map +1 -0
- package/dist/metrics/metrics.impl.d.ts +252 -0
- package/dist/metrics/metrics.impl.d.ts.map +1 -0
- package/dist/metrics/metrics.impl.js +197 -0
- package/dist/metrics/metrics.impl.js.map +1 -0
- package/dist/persistence/FilePersistence.d.ts +66 -0
- package/dist/persistence/FilePersistence.d.ts.map +1 -0
- package/dist/persistence/FilePersistence.js +132 -0
- package/dist/persistence/FilePersistence.js.map +1 -0
- package/dist/persistence/MemoryPersistence.d.ts +68 -0
- package/dist/persistence/MemoryPersistence.d.ts.map +1 -0
- package/dist/persistence/MemoryPersistence.js +51 -0
- package/dist/persistence/MemoryPersistence.js.map +1 -0
- package/dist/persistence/PersistenceBackend.d.ts +69 -0
- package/dist/persistence/PersistenceBackend.d.ts.map +1 -0
- package/dist/persistence/PersistenceBackend.js +1 -0
- package/dist/persistence/PersistenceFactory.d.ts +21 -0
- package/dist/persistence/PersistenceFactory.d.ts.map +1 -0
- package/dist/persistence/PersistenceFactory.js +25 -0
- package/dist/persistence/PersistenceFactory.js.map +1 -0
- package/dist/persistence/SqlitePersistence.d.ts +60 -0
- package/dist/persistence/SqlitePersistence.d.ts.map +1 -0
- package/dist/persistence/SqlitePersistence.js +136 -0
- package/dist/persistence/SqlitePersistence.js.map +1 -0
- package/dist/pool/ConnectionPool.d.ts +215 -0
- package/dist/pool/ConnectionPool.d.ts.map +1 -0
- package/dist/pool/ConnectionPool.js +187 -0
- package/dist/pool/ConnectionPool.js.map +1 -0
- package/dist/registry/BaseRegistry.d.ts +203 -0
- package/dist/registry/BaseRegistry.d.ts.map +1 -0
- package/dist/registry/BaseRegistry.js +165 -0
- package/dist/registry/BaseRegistry.js.map +1 -0
- package/dist/registry/SkillRegistry.d.ts +69 -0
- package/dist/registry/SkillRegistry.d.ts.map +1 -0
- package/dist/registry/SkillRegistry.js +88 -0
- package/dist/registry/SkillRegistry.js.map +1 -0
- package/dist/registry/ToolRegistry.d.ts +69 -0
- package/dist/registry/ToolRegistry.d.ts.map +1 -0
- package/dist/registry/ToolRegistry.js +93 -0
- package/dist/registry/ToolRegistry.js.map +1 -0
- package/dist/sanitize.d.ts +63 -0
- package/dist/sanitize.d.ts.map +1 -0
- package/dist/sanitize.js +14 -0
- package/dist/sanitize.js.map +1 -0
- package/dist/schema.d.ts +531 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +204 -0
- package/dist/schema.js.map +1 -0
- package/dist/telemetry/Telemetry.d.ts +36 -0
- package/dist/telemetry/Telemetry.d.ts.map +1 -0
- package/dist/telemetry/Telemetry.js +68 -0
- package/dist/telemetry/Telemetry.js.map +1 -0
- package/dist/telemetry/__tests__/Telemetry.test.d.ts +2 -0
- package/dist/telemetry/__tests__/Telemetry.test.d.ts.map +1 -0
- package/dist/transport/BaseTransport.d.ts +184 -0
- package/dist/transport/BaseTransport.d.ts.map +1 -0
- package/dist/transport/BaseTransport.js +200 -0
- package/dist/transport/BaseTransport.js.map +1 -0
- package/dist/transport/HttpHelpers.d.ts +60 -0
- package/dist/transport/HttpHelpers.d.ts.map +1 -0
- package/dist/transport/HttpHelpers.js +50 -0
- package/dist/transport/HttpHelpers.js.map +1 -0
- package/dist/transport/HttpTransport.d.ts +134 -0
- package/dist/transport/HttpTransport.d.ts.map +1 -0
- package/dist/transport/HttpTransport.js +175 -0
- package/dist/transport/HttpTransport.js.map +1 -0
- package/dist/transport/SseTransport.d.ts +133 -0
- package/dist/transport/SseTransport.d.ts.map +1 -0
- package/dist/transport/SseTransport.js +318 -0
- package/dist/transport/SseTransport.js.map +1 -0
- package/dist/transport/StreamableHttpTransport.d.ts +224 -0
- package/dist/transport/StreamableHttpTransport.d.ts.map +1 -0
- package/dist/transport/StreamableHttpTransport.js +407 -0
- package/dist/transport/StreamableHttpTransport.js.map +1 -0
- package/dist/types/disposable.d.ts +22 -0
- package/dist/types/disposable.d.ts.map +1 -0
- package/dist/types/disposable.js +1 -0
- package/dist/types/server-config.d.ts +32 -0
- package/dist/types/server-config.d.ts.map +1 -0
- package/dist/types/server-config.js +1 -0
- package/dist/types/skill.d.ts +69 -0
- package/dist/types/skill.d.ts.map +1 -0
- package/dist/types/skill.js +1 -0
- package/dist/types/tool.d.ts +68 -0
- package/dist/types/tool.d.ts.map +1 -0
- package/dist/types/tool.js +1 -0
- package/dist/watchers/SkillWatcher.d.ts +132 -0
- package/dist/watchers/SkillWatcher.d.ts.map +1 -0
- package/dist/watchers/SkillWatcher.js +73 -0
- package/dist/watchers/SkillWatcher.js.map +1 -0
- package/dist/watchers/ToolWatcher.d.ts +109 -0
- package/dist/watchers/ToolWatcher.d.ts.map +1 -0
- package/dist/watchers/ToolWatcher.js +71 -0
- package/dist/watchers/ToolWatcher.js.map +1 -0
- package/package.json +95 -0
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
const ALL_THOUGHT_TYPES = [
|
|
2
|
+
'regular',
|
|
3
|
+
'hypothesis',
|
|
4
|
+
'verification',
|
|
5
|
+
'critique',
|
|
6
|
+
'synthesis',
|
|
7
|
+
'meta'
|
|
8
|
+
];
|
|
9
|
+
class ThoughtEvaluator {
|
|
10
|
+
computeConfidenceSignals(history, branches) {
|
|
11
|
+
const typeDistribution = this._countByType(history);
|
|
12
|
+
const allConfidences = history.map((t)=>t.confidence).filter((c)=>void 0 !== c);
|
|
13
|
+
const structuralResult = this._computeStructuralQuality(history, branches, typeDistribution, allConfidences);
|
|
14
|
+
return {
|
|
15
|
+
reasoning_depth: history.length,
|
|
16
|
+
revision_count: history.filter((t)=>t.is_revision).length,
|
|
17
|
+
branch_count: Object.keys(branches).length,
|
|
18
|
+
thought_type_distribution: typeDistribution,
|
|
19
|
+
has_hypothesis: history.some((t)=>'hypothesis' === t.thought_type),
|
|
20
|
+
has_verification: history.some((t)=>'verification' === t.thought_type),
|
|
21
|
+
average_confidence: allConfidences.length > 0 ? allConfidences.reduce((a, b)=>a + b, 0) / allConfidences.length : null,
|
|
22
|
+
...null !== structuralResult && {
|
|
23
|
+
structural_quality: structuralResult.score,
|
|
24
|
+
quality_components: structuralResult.components
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
computeReasoningStats(history, branches) {
|
|
29
|
+
const typeCounts = this._countByType(history);
|
|
30
|
+
const allScores = history.map((t)=>t.quality_score).filter((s)=>void 0 !== s);
|
|
31
|
+
const allConfidences = history.map((t)=>t.confidence).filter((c)=>void 0 !== c);
|
|
32
|
+
const hypotheses = history.filter((t)=>'hypothesis' === t.thought_type);
|
|
33
|
+
const hypothesisIds = new Set(hypotheses.map((t)=>t.hypothesis_id).filter(Boolean));
|
|
34
|
+
const verifiedIds = new Set(history.filter((t)=>'verification' === t.thought_type && t.hypothesis_id).map((t)=>t.hypothesis_id));
|
|
35
|
+
const unresolvedCount = [
|
|
36
|
+
...hypothesisIds
|
|
37
|
+
].filter((id)=>!verifiedIds.has(id)).length;
|
|
38
|
+
return {
|
|
39
|
+
total_thoughts: history.length,
|
|
40
|
+
total_branches: Object.keys(branches).length,
|
|
41
|
+
total_revisions: history.filter((t)=>t.is_revision).length,
|
|
42
|
+
total_merges: history.filter((t)=>(t.merge_from_thoughts?.length ?? 0) > 0 || (t.merge_branch_ids?.length ?? 0) > 0).length,
|
|
43
|
+
chain_depth: this._computeChainDepth(history),
|
|
44
|
+
thought_type_counts: typeCounts,
|
|
45
|
+
hypothesis_count: hypothesisIds.size,
|
|
46
|
+
verified_hypothesis_count: [
|
|
47
|
+
...hypothesisIds
|
|
48
|
+
].filter((id)=>verifiedIds.has(id)).length,
|
|
49
|
+
unresolved_hypothesis_count: unresolvedCount,
|
|
50
|
+
average_quality_score: allScores.length > 0 ? allScores.reduce((a, b)=>a + b, 0) / allScores.length : null,
|
|
51
|
+
average_confidence: allConfidences.length > 0 ? allConfidences.reduce((a, b)=>a + b, 0) / allConfidences.length : null
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
computePatternSignals(history, branches) {
|
|
55
|
+
if (0 === history.length) return [];
|
|
56
|
+
const signals = [];
|
|
57
|
+
signals.push(...this._detectConsecutiveWithoutVerification(history));
|
|
58
|
+
signals.push(...this._detectUnverifiedHypothesis(history));
|
|
59
|
+
signals.push(...this._detectNoAlternativesExplored(history, branches));
|
|
60
|
+
signals.push(...this._detectMonotonicType(history));
|
|
61
|
+
signals.push(...this._detectConfidenceDrift(history));
|
|
62
|
+
signals.push(...this._detectHealthyVerification(history));
|
|
63
|
+
return signals;
|
|
64
|
+
}
|
|
65
|
+
_detectConsecutiveWithoutVerification(history) {
|
|
66
|
+
const signals = [];
|
|
67
|
+
let runStart = 0;
|
|
68
|
+
for(let i = 0; i < history.length; i++){
|
|
69
|
+
const type = history[i].thought_type ?? 'regular';
|
|
70
|
+
if ('verification' === type) {
|
|
71
|
+
runStart = i + 1;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (i - runStart + 1 >= 3) {
|
|
75
|
+
const start = history[runStart].thought_number ?? runStart + 1;
|
|
76
|
+
const end = history[i].thought_number ?? i + 1;
|
|
77
|
+
signals.push({
|
|
78
|
+
pattern: 'consecutive_without_verification',
|
|
79
|
+
severity: 'warning',
|
|
80
|
+
message: `3+ consecutive thoughts (${start}-${end}) without verification`,
|
|
81
|
+
thought_range: [
|
|
82
|
+
start,
|
|
83
|
+
end
|
|
84
|
+
]
|
|
85
|
+
});
|
|
86
|
+
runStart = i + 1;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return signals;
|
|
90
|
+
}
|
|
91
|
+
_detectUnverifiedHypothesis(history) {
|
|
92
|
+
const signals = [];
|
|
93
|
+
for(let i = 0; i < history.length; i++){
|
|
94
|
+
if ('hypothesis' !== history[i].thought_type) continue;
|
|
95
|
+
const remaining = history.length - i - 1;
|
|
96
|
+
if (remaining < 3) continue;
|
|
97
|
+
const lookahead = history.slice(i + 1, i + 4);
|
|
98
|
+
const hasVerification = lookahead.some((t)=>'verification' === t.thought_type);
|
|
99
|
+
if (!hasVerification) {
|
|
100
|
+
const n = history[i].thought_number ?? i + 1;
|
|
101
|
+
signals.push({
|
|
102
|
+
pattern: 'unverified_hypothesis',
|
|
103
|
+
severity: 'warning',
|
|
104
|
+
message: `Hypothesis at thought ${n} has not been verified within 3 thoughts`,
|
|
105
|
+
thought_range: [
|
|
106
|
+
n,
|
|
107
|
+
n
|
|
108
|
+
]
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return signals;
|
|
113
|
+
}
|
|
114
|
+
_detectNoAlternativesExplored(history, branches) {
|
|
115
|
+
if (history.length < 5) return [];
|
|
116
|
+
if (history.some((t)=>'critique' === t.thought_type)) return [];
|
|
117
|
+
if (Object.keys(branches).length > 0) return [];
|
|
118
|
+
const start = history[0].thought_number ?? 1;
|
|
119
|
+
const end = history[history.length - 1].thought_number ?? history.length;
|
|
120
|
+
return [
|
|
121
|
+
{
|
|
122
|
+
pattern: 'no_alternatives_explored',
|
|
123
|
+
severity: 'info',
|
|
124
|
+
message: '5+ thoughts with no critique or branching — consider exploring alternatives',
|
|
125
|
+
thought_range: [
|
|
126
|
+
start,
|
|
127
|
+
end
|
|
128
|
+
]
|
|
129
|
+
}
|
|
130
|
+
];
|
|
131
|
+
}
|
|
132
|
+
_detectMonotonicType(history) {
|
|
133
|
+
if (history.length < 5) return [];
|
|
134
|
+
const hasExplicitType = history.some((t)=>void 0 !== t.thought_type);
|
|
135
|
+
if (!hasExplicitType) return [];
|
|
136
|
+
const signals = [];
|
|
137
|
+
let runType = history[0].thought_type ?? 'regular';
|
|
138
|
+
let runStart = 0;
|
|
139
|
+
let runLength = 1;
|
|
140
|
+
for(let i = 1; i < history.length; i++){
|
|
141
|
+
const type = history[i].thought_type ?? 'regular';
|
|
142
|
+
if (type === runType) runLength++;
|
|
143
|
+
else {
|
|
144
|
+
if (runLength >= 4) {
|
|
145
|
+
const start = history[runStart].thought_number ?? runStart + 1;
|
|
146
|
+
const end = history[runStart + runLength - 1].thought_number ?? runStart + runLength;
|
|
147
|
+
signals.push({
|
|
148
|
+
pattern: 'monotonic_type',
|
|
149
|
+
severity: 'info',
|
|
150
|
+
message: `4+ consecutive '${runType}' thoughts (${start}-${end}) — consider varying approach`,
|
|
151
|
+
thought_range: [
|
|
152
|
+
start,
|
|
153
|
+
end
|
|
154
|
+
]
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
runType = type;
|
|
158
|
+
runStart = i;
|
|
159
|
+
runLength = 1;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (runLength >= 4) {
|
|
163
|
+
const start = history[runStart].thought_number ?? runStart + 1;
|
|
164
|
+
const end = history[runStart + runLength - 1].thought_number ?? runStart + runLength;
|
|
165
|
+
signals.push({
|
|
166
|
+
pattern: 'monotonic_type',
|
|
167
|
+
severity: 'info',
|
|
168
|
+
message: `4+ consecutive '${runType}' thoughts (${start}-${end}) — consider varying approach`,
|
|
169
|
+
thought_range: [
|
|
170
|
+
start,
|
|
171
|
+
end
|
|
172
|
+
]
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
return signals;
|
|
176
|
+
}
|
|
177
|
+
_detectConfidenceDrift(history) {
|
|
178
|
+
const signals = [];
|
|
179
|
+
let runStart = -1;
|
|
180
|
+
let runLength = 0;
|
|
181
|
+
let prevConf = -1;
|
|
182
|
+
for(let i = 0; i < history.length; i++){
|
|
183
|
+
const conf = history[i].confidence;
|
|
184
|
+
if (void 0 === conf) {
|
|
185
|
+
if (runLength >= 3) {
|
|
186
|
+
const start = history[runStart].thought_number ?? runStart + 1;
|
|
187
|
+
const end = history[runStart + runLength - 1].thought_number ?? runStart + runLength;
|
|
188
|
+
const firstConf = history[runStart].confidence;
|
|
189
|
+
const lastConf = history[runStart + runLength - 1].confidence;
|
|
190
|
+
signals.push({
|
|
191
|
+
pattern: 'confidence_drift',
|
|
192
|
+
severity: 'warning',
|
|
193
|
+
message: `Confidence decreasing across thoughts ${start}-${end} (${firstConf} → ${lastConf})`,
|
|
194
|
+
thought_range: [
|
|
195
|
+
start,
|
|
196
|
+
end
|
|
197
|
+
]
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
runStart = -1;
|
|
201
|
+
runLength = 0;
|
|
202
|
+
prevConf = -1;
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
if (0 === runLength) {
|
|
206
|
+
runStart = i;
|
|
207
|
+
runLength = 1;
|
|
208
|
+
prevConf = conf;
|
|
209
|
+
} else if (conf < prevConf) {
|
|
210
|
+
runLength++;
|
|
211
|
+
prevConf = conf;
|
|
212
|
+
} else {
|
|
213
|
+
if (runLength >= 3) {
|
|
214
|
+
const start = history[runStart].thought_number ?? runStart + 1;
|
|
215
|
+
const end = history[runStart + runLength - 1].thought_number ?? runStart + runLength;
|
|
216
|
+
const firstConf = history[runStart].confidence;
|
|
217
|
+
const lastConf = history[runStart + runLength - 1].confidence;
|
|
218
|
+
signals.push({
|
|
219
|
+
pattern: 'confidence_drift',
|
|
220
|
+
severity: 'warning',
|
|
221
|
+
message: `Confidence decreasing across thoughts ${start}-${end} (${firstConf} → ${lastConf})`,
|
|
222
|
+
thought_range: [
|
|
223
|
+
start,
|
|
224
|
+
end
|
|
225
|
+
]
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
runStart = i;
|
|
229
|
+
runLength = 1;
|
|
230
|
+
prevConf = conf;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (runLength >= 3) {
|
|
234
|
+
const start = history[runStart].thought_number ?? runStart + 1;
|
|
235
|
+
const end = history[runStart + runLength - 1].thought_number ?? runStart + runLength;
|
|
236
|
+
const firstConf = history[runStart].confidence;
|
|
237
|
+
const lastConf = history[runStart + runLength - 1].confidence;
|
|
238
|
+
signals.push({
|
|
239
|
+
pattern: 'confidence_drift',
|
|
240
|
+
severity: 'warning',
|
|
241
|
+
message: `Confidence decreasing across thoughts ${start}-${end} (${firstConf} → ${lastConf})`,
|
|
242
|
+
thought_range: [
|
|
243
|
+
start,
|
|
244
|
+
end
|
|
245
|
+
]
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
return signals;
|
|
249
|
+
}
|
|
250
|
+
_detectHealthyVerification(history) {
|
|
251
|
+
const signals = [];
|
|
252
|
+
for(let i = 0; i < history.length; i++){
|
|
253
|
+
if ('hypothesis' !== history[i].thought_type) continue;
|
|
254
|
+
const hypId = history[i].hypothesis_id;
|
|
255
|
+
const lookahead = history.slice(i + 1, i + 4);
|
|
256
|
+
const verifier = lookahead.find((t)=>'verification' === t.thought_type && (t.hypothesis_id === hypId || t.verification_target === (history[i].thought_number ?? i + 1)));
|
|
257
|
+
if (verifier) {
|
|
258
|
+
const n = history[i].thought_number ?? i + 1;
|
|
259
|
+
const m = verifier.thought_number ?? history.indexOf(verifier) + 1;
|
|
260
|
+
signals.push({
|
|
261
|
+
pattern: 'healthy_verification',
|
|
262
|
+
severity: 'info',
|
|
263
|
+
message: `Hypothesis at thought ${n} verified at thought ${m} — good practice`,
|
|
264
|
+
thought_range: [
|
|
265
|
+
n,
|
|
266
|
+
m
|
|
267
|
+
]
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return signals;
|
|
272
|
+
}
|
|
273
|
+
_countByType(thoughts) {
|
|
274
|
+
const counts = Object.fromEntries(ALL_THOUGHT_TYPES.map((t)=>[
|
|
275
|
+
t,
|
|
276
|
+
0
|
|
277
|
+
]));
|
|
278
|
+
for (const thought of thoughts){
|
|
279
|
+
const type = thought.thought_type ?? 'regular';
|
|
280
|
+
if (type in counts) counts[type]++;
|
|
281
|
+
}
|
|
282
|
+
return counts;
|
|
283
|
+
}
|
|
284
|
+
_computeChainDepth(history) {
|
|
285
|
+
if (0 === history.length) return 0;
|
|
286
|
+
let maxDepth = 1;
|
|
287
|
+
let currentDepth = 1;
|
|
288
|
+
for(let i = 1; i < history.length; i++){
|
|
289
|
+
const thought = history[i];
|
|
290
|
+
if (thought.branch_from_thought) currentDepth = 1;
|
|
291
|
+
else {
|
|
292
|
+
currentDepth++;
|
|
293
|
+
maxDepth = Math.max(maxDepth, currentDepth);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return maxDepth;
|
|
297
|
+
}
|
|
298
|
+
_computeStructuralQuality(history, branches, typeDistribution, confidences) {
|
|
299
|
+
if (0 === history.length) return null;
|
|
300
|
+
const FLOOR = 0.01;
|
|
301
|
+
const total = history.length;
|
|
302
|
+
let entropy = 0;
|
|
303
|
+
for (const type of ALL_THOUGHT_TYPES){
|
|
304
|
+
const count = typeDistribution[type];
|
|
305
|
+
if (count > 0) {
|
|
306
|
+
const pk = count / total;
|
|
307
|
+
entropy -= pk * Math.log2(pk);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
const typeDiversity = Math.max(entropy / Math.log2(6), FLOOR);
|
|
311
|
+
const hypotheses = history.filter((t)=>'hypothesis' === t.thought_type);
|
|
312
|
+
const hypothesisIds = new Set(hypotheses.map((t)=>t.hypothesis_id).filter(Boolean));
|
|
313
|
+
const verifiedIds = new Set(history.filter((t)=>'verification' === t.thought_type && t.hypothesis_id).map((t)=>t.hypothesis_id));
|
|
314
|
+
const verificationCoverage = 0 === hypothesisIds.size ? 1.0 : Math.max([
|
|
315
|
+
...hypothesisIds
|
|
316
|
+
].filter((id)=>verifiedIds.has(id)).length / hypothesisIds.size, FLOOR);
|
|
317
|
+
const chainDepth = this._computeChainDepth(history);
|
|
318
|
+
const branchCount = Object.keys(branches).length;
|
|
319
|
+
const effectiveDepth = Math.max(chainDepth, branchCount + 1);
|
|
320
|
+
const depthEfficiency = Math.max(Math.min(effectiveDepth / total, 1.0), FLOOR);
|
|
321
|
+
const confidenceStability = this._computeConfidenceStability(confidences);
|
|
322
|
+
const components = {
|
|
323
|
+
type_diversity: typeDiversity,
|
|
324
|
+
verification_coverage: verificationCoverage,
|
|
325
|
+
depth_efficiency: depthEfficiency,
|
|
326
|
+
confidence_stability: confidenceStability
|
|
327
|
+
};
|
|
328
|
+
const score = Math.pow(typeDiversity, 0.3) * Math.pow(verificationCoverage, 0.3) * Math.pow(depthEfficiency, 0.2) * Math.pow(confidenceStability, 0.2);
|
|
329
|
+
return {
|
|
330
|
+
score,
|
|
331
|
+
components
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
_computeConfidenceStability(confidences) {
|
|
335
|
+
const FLOOR = 0.01;
|
|
336
|
+
if (0 === confidences.length) return Math.max(0.5, FLOOR);
|
|
337
|
+
if (1 === confidences.length) return Math.max(1.0, FLOOR);
|
|
338
|
+
const mean = confidences.reduce((a, b)=>a + b, 0) / confidences.length;
|
|
339
|
+
const variance = confidences.reduce((sum, c)=>sum + (c - mean) ** 2, 0) / confidences.length;
|
|
340
|
+
const stddev = Math.sqrt(variance);
|
|
341
|
+
return Math.max(1 - stddev, FLOOR);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
export { ThoughtEvaluator };
|
|
345
|
+
|
|
346
|
+
//# sourceMappingURL=ThoughtEvaluator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core/ThoughtEvaluator.js","sources":["../../src/core/ThoughtEvaluator.ts"],"sourcesContent":["/**\n * Quality signal computation for sequential thinking.\n *\n * Provides the {@link ThoughtEvaluator} class — a stateless service that computes\n * confidence signals and reasoning analytics from thought history. Follows the\n * ThoughtFormatter pattern as a composed dependency of ThoughtProcessor.\n *\n * @module core/evaluator\n */\n\nimport type { ConfidenceSignals, PatternSignal, ReasoningStats, ThoughtType } from './reasoning.js';\nimport type { ThoughtData } from './thought.js';\n\n/** All valid thought types for distribution counting. */\nconst ALL_THOUGHT_TYPES: ThoughtType[] = [\n\t'regular',\n\t'hypothesis',\n\t'verification',\n\t'critique',\n\t'synthesis',\n\t'meta',\n];\n\n/**\n * Stateless service that computes quality signals and reasoning analytics\n * from thought history and branch data.\n *\n * @remarks\n * All methods are pure computations — no side effects, no I/O, no internal state.\n * Designed to be registered as transient in the DI container.\n *\n * @example\n * ```typescript\n * const evaluator = new ThoughtEvaluator();\n *\n * const signals = evaluator.computeConfidenceSignals(history, branches);\n * console.log(signals.reasoning_depth); // 5\n *\n * const stats = evaluator.computeReasoningStats(history, branches);\n * console.log(stats.total_thoughts); // 12\n * ```\n */\nexport class ThoughtEvaluator {\n\t/**\n\t * Compute confidence signals from history context.\n\t * Pure computation — no side effects, no I/O.\n\t *\n\t * @param history - All thoughts in the current session\n\t * @param branches - Map of branch IDs to their thought arrays\n\t * @returns Computed confidence signals reflecting reasoning quality\n\t *\n\t * @example\n\t * ```typescript\n\t * const evaluator = new ThoughtEvaluator();\n * const signals = evaluator.computeConfidenceSignals(\n * [thought1, thought2, thought3],\n * { 'branch-a': [branchThought1] }\n * );\n\t *\n\t * console.log(signals.reasoning_depth); // 3\n\t * console.log(signals.branch_count); // 1\n\t * console.log(signals.has_hypothesis); // false\n\t * console.log(signals.average_confidence); // 0.85 or null\n\t * ```\n\t */\n\tpublic computeConfidenceSignals(\n\t\thistory: ThoughtData[],\n\t\tbranches: Record<string, ThoughtData[]>\n\t): ConfidenceSignals {\n\t\tconst typeDistribution = this._countByType(history);\n\t\tconst allConfidences = history\n\t\t\t.map((t) => t.confidence)\n\t\t\t.filter((c): c is number => c !== undefined);\n\n\t\t// Compute structural quality components\n\t\tconst structuralResult = this._computeStructuralQuality(\n\t\t\thistory,\n\t\t\tbranches,\n\t\t\ttypeDistribution,\n\t\t\tallConfidences\n\t\t);\n\n\t\treturn {\n\t\t\treasoning_depth: history.length,\n\t\t\trevision_count: history.filter((t) => t.is_revision).length,\n\t\t\tbranch_count: Object.keys(branches).length,\n\t\t\tthought_type_distribution: typeDistribution,\n\t\t\thas_hypothesis: history.some((t) => t.thought_type === 'hypothesis'),\n\t\t\thas_verification: history.some((t) => t.thought_type === 'verification'),\n\t\t\taverage_confidence:\n\t\t\t\tallConfidences.length > 0\n\t\t\t\t\t? allConfidences.reduce((a, b) => a + b, 0) / allConfidences.length\n\t\t\t\t\t: null,\n\t\t\t...(structuralResult !== null && {\n\t\t\t\tstructural_quality: structuralResult.score,\n\t\t\t\tquality_components: structuralResult.components,\n\t\t\t}),\n\t\t};\n\t}\n\n\t/**\n\t * Compute aggregated reasoning analytics.\n\t * Pure computation from history + branches.\n\t *\n\t * @param history - All thoughts in the current session\n\t * @param branches - Map of branch IDs to their thought arrays\n\t * @returns Aggregated reasoning statistics for the session\n\t *\n\t * @example\n\t * ```typescript\n\t * const evaluator = new ThoughtEvaluator();\n\t * const stats = evaluator.computeReasoningStats(\n\t * [thought1, thought2, hypothesisThought, verificationThought],\n\t * { 'explore-a': [branchThought] }\n\t * );\n\t *\n\t * console.log(stats.total_thoughts); // 4\n\t * console.log(stats.total_branches); // 1\n\t * console.log(stats.hypothesis_count); // 1\n\t * console.log(stats.verified_hypothesis_count); // 1\n\t * console.log(stats.average_quality_score); // 0.78 or null\n\t * ```\n\t */\n\tpublic computeReasoningStats(\n\t\thistory: ThoughtData[],\n\t\tbranches: Record<string, ThoughtData[]>\n\t): ReasoningStats {\n\t\tconst typeCounts = this._countByType(history);\n\t\tconst allScores = history\n\t\t\t.map((t) => t.quality_score)\n\t\t\t.filter((s): s is number => s !== undefined);\n\t\tconst allConfidences = history\n\t\t\t.map((t) => t.confidence)\n\t\t\t.filter((c): c is number => c !== undefined);\n\n\t\tconst hypotheses = history.filter((t) => t.thought_type === 'hypothesis');\n\t\tconst hypothesisIds = new Set(hypotheses.map((t) => t.hypothesis_id).filter(Boolean));\n\t\tconst verifiedIds = new Set(\n\t\t\thistory\n\t\t\t\t.filter((t) => t.thought_type === 'verification' && t.hypothesis_id)\n\t\t\t\t.map((t) => t.hypothesis_id)\n\t\t);\n\t\tconst unresolvedCount = [...hypothesisIds].filter((id) => !verifiedIds.has(id)).length;\n\n\t\treturn {\n\t\t\ttotal_thoughts: history.length,\n\t\t\ttotal_branches: Object.keys(branches).length,\n\t\t\ttotal_revisions: history.filter((t) => t.is_revision).length,\n\t\t\ttotal_merges: history.filter(\n\t\t\t\t(t) => (t.merge_from_thoughts?.length ?? 0) > 0 || (t.merge_branch_ids?.length ?? 0) > 0\n\t\t\t).length,\n\t\t\tchain_depth: this._computeChainDepth(history),\n\t\t\tthought_type_counts: typeCounts,\n\t\t\thypothesis_count: hypothesisIds.size,\n\t\t\tverified_hypothesis_count: [...hypothesisIds].filter((id) => verifiedIds.has(id)).length,\n\t\t\tunresolved_hypothesis_count: unresolvedCount,\n\t\t\taverage_quality_score:\n\t\t\t\tallScores.length > 0 ? allScores.reduce((a, b) => a + b, 0) / allScores.length : null,\n\t\t\taverage_confidence:\n\t\t\t\tallConfidences.length > 0\n\t\t\t\t\t? allConfidences.reduce((a, b) => a + b, 0) / allConfidences.length\n\t\t\t\t\t: null,\n\t\t};\n\t}\n\n\t/**\n * Detect reasoning patterns (anti-patterns and positive signals) from history.\n * Pure computation — no side effects, no I/O.\n *\n * Detected patterns:\n * - `consecutive_without_verification` (warning) — 3+ consecutive regular thoughts without a verification step\n * - `unverified_hypothesis` (warning) — hypothesis not verified within 3 subsequent thoughts\n * - `no_alternatives_explored` (info) — 5+ thoughts with no critique and no branches\n * - `monotonic_type` (info) — 4+ consecutive thoughts with the same thought_type (requires ≥1 explicit type and ≥5 thoughts)\n * - `confidence_drift` (warning) — 3+ consecutive thoughts with strictly decreasing confidence\n * - `healthy_verification` (info) — hypothesis verified within 3 subsequent thoughts\n *\n * @param history - All thoughts in the current session\n * @param branches - Map of branch IDs to their thought arrays\n * @returns Array of detected pattern signals, possibly empty\n *\n * @example\n * ```typescript\n * const evaluator = new ThoughtEvaluator();\n * const patterns = evaluator.computePatternSignals(history, branches);\n * const warnings = patterns.filter(p => p.severity === 'warning');\n * ```\n */\n\tpublic computePatternSignals(\n\t\thistory: ThoughtData[],\n\t\tbranches: Record<string, ThoughtData[]>\n\t): PatternSignal[] {\n\t\tif (history.length === 0) return [];\n\n\t\tconst signals: PatternSignal[] = [];\n\t\tsignals.push(...this._detectConsecutiveWithoutVerification(history));\n\t\tsignals.push(...this._detectUnverifiedHypothesis(history));\n\t\tsignals.push(...this._detectNoAlternativesExplored(history, branches));\n\t\tsignals.push(...this._detectMonotonicType(history));\n\t\tsignals.push(...this._detectConfidenceDrift(history));\n\t\tsignals.push(...this._detectHealthyVerification(history));\n\t\treturn signals;\n\t}\n\n\t/** Detect runs of 3+ consecutive thoughts without verification. */\n\tprivate _detectConsecutiveWithoutVerification(history: ThoughtData[]): PatternSignal[] {\n\t\tconst signals: PatternSignal[] = [];\n\t\tlet runStart = 0;\n\t\tfor (let i = 0; i < history.length; i++) {\n\t\t\tconst type = history[i]!.thought_type ?? 'regular';\n\t\t\tif (type === 'verification') {\n\t\t\t\trunStart = i + 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (i - runStart + 1 >= 3) {\n\t\t\t\tconst start = history[runStart]!.thought_number ?? runStart + 1;\n\t\t\t\tconst end = history[i]!.thought_number ?? i + 1;\n\t\t\t\tsignals.push({\n\t\t\t\t\tpattern: 'consecutive_without_verification',\n\t\t\t\t\tseverity: 'warning',\n\t\t\t\t\tmessage: `3+ consecutive thoughts (${start}-${end}) without verification`,\n\t\t\t\t\tthought_range: [start, end],\n\t\t\t\t});\n\t\t\t\trunStart = i + 1;\n\t\t\t}\n\t\t}\n\t\treturn signals;\n\t}\n\n\t/** Detect hypothesis thoughts not verified within 3 subsequent thoughts. */\n\tprivate _detectUnverifiedHypothesis(history: ThoughtData[]): PatternSignal[] {\n\t\tconst signals: PatternSignal[] = [];\n\t\tfor (let i = 0; i < history.length; i++) {\n\t\t\tif (history[i]!.thought_type !== 'hypothesis') continue;\n\t\t\tconst remaining = history.length - i - 1;\n\t\t\tif (remaining < 3) continue;\n\t\t\tconst lookahead = history.slice(i + 1, i + 4);\n\t\t\tconst hasVerification = lookahead.some((t) => t.thought_type === 'verification');\n\t\t\tif (!hasVerification) {\n\t\t\t\tconst n = history[i]!.thought_number ?? i + 1;\n\t\t\t\tsignals.push({\n\t\t\t\t\tpattern: 'unverified_hypothesis',\n\t\t\t\t\tseverity: 'warning',\n\t\t\t\t\tmessage: `Hypothesis at thought ${n} has not been verified within 3 thoughts`,\n\t\t\t\t\tthought_range: [n, n],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn signals;\n\t}\n\n\t/** Detect 5+ thoughts with no critique and no branches. */\n\tprivate _detectNoAlternativesExplored(\n\t\thistory: ThoughtData[],\n\t\tbranches: Record<string, ThoughtData[]>\n\t): PatternSignal[] {\n\t\tif (history.length < 5) return [];\n\t\tif (history.some((t) => t.thought_type === 'critique')) return [];\n\t\tif (Object.keys(branches).length > 0) return [];\n\t\tconst start = history[0]!.thought_number ?? 1;\n\t\tconst end = history[history.length - 1]!.thought_number ?? history.length;\n\t\treturn [\n\t\t\t{\n\t\t\t\tpattern: 'no_alternatives_explored',\n\t\t\t\tseverity: 'info',\n\t\t\t\tmessage: '5+ thoughts with no critique or branching — consider exploring alternatives',\n\t\t\t\tthought_range: [start, end],\n\t\t\t},\n\t\t];\n\t}\n\n\t/**\n\t * Detect runs of 4+ consecutive thoughts with the same thought_type.\n\t * Only fires when history has ≥5 thoughts and at least one explicitly set thought_type.\n\t */\n\tprivate _detectMonotonicType(history: ThoughtData[]): PatternSignal[] {\n\t\tif (history.length < 5) return [];\n\t\tconst hasExplicitType = history.some((t) => t.thought_type !== undefined);\n\t\tif (!hasExplicitType) return [];\n\n\t\tconst signals: PatternSignal[] = [];\n\t\tlet runType = history[0]!.thought_type ?? 'regular';\n\t\tlet runStart = 0;\n\t\tlet runLength = 1;\n\n\t\tfor (let i = 1; i < history.length; i++) {\n\t\t\tconst type = history[i]!.thought_type ?? 'regular';\n\t\t\tif (type === runType) {\n\t\t\t\trunLength++;\n\t\t\t} else {\n\t\t\t\tif (runLength >= 4) {\n\t\t\t\t\tconst start = history[runStart]!.thought_number ?? runStart + 1;\n\t\t\t\t\tconst end = history[runStart + runLength - 1]!.thought_number ?? runStart + runLength;\n\t\t\t\t\tsignals.push({\n\t\t\t\t\t\tpattern: 'monotonic_type',\n\t\t\t\t\t\tseverity: 'info',\n\t\t\t\t\t\tmessage: `4+ consecutive '${runType}' thoughts (${start}-${end}) — consider varying approach`,\n\t\t\t\t\t\tthought_range: [start, end],\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\trunType = type;\n\t\t\t\trunStart = i;\n\t\t\t\trunLength = 1;\n\t\t\t}\n\t\t}\n\t\tif (runLength >= 4) {\n\t\t\tconst start = history[runStart]!.thought_number ?? runStart + 1;\n\t\t\tconst end = history[runStart + runLength - 1]!.thought_number ?? runStart + runLength;\n\t\t\tsignals.push({\n\t\t\t\tpattern: 'monotonic_type',\n\t\t\t\tseverity: 'info',\n\t\t\t\tmessage: `4+ consecutive '${runType}' thoughts (${start}-${end}) — consider varying approach`,\n\t\t\t\tthought_range: [start, end],\n\t\t\t});\n\t\t}\n\t\treturn signals;\n\t}\n\n\t/** Detect runs of 3+ consecutive thoughts with strictly decreasing confidence. */\n\tprivate _detectConfidenceDrift(history: ThoughtData[]): PatternSignal[] {\n\t\tconst signals: PatternSignal[] = [];\n\t\tlet runStart = -1;\n\t\tlet runLength = 0;\n\t\tlet prevConf = -1;\n\n\t\tfor (let i = 0; i < history.length; i++) {\n\t\t\tconst conf = history[i]!.confidence;\n\t\t\tif (conf === undefined) {\n\t\t\t\tif (runLength >= 3) {\n\t\t\t\t\tconst start = history[runStart]!.thought_number ?? runStart + 1;\n\t\t\t\t\tconst end = history[runStart + runLength - 1]!.thought_number ?? runStart + runLength;\n\t\t\t\t\tconst firstConf = history[runStart]!.confidence!;\n\t\t\t\t\tconst lastConf = history[runStart + runLength - 1]!.confidence!;\n\t\t\t\t\tsignals.push({\n\t\t\t\t\t\tpattern: 'confidence_drift',\n\t\t\t\t\t\tseverity: 'warning',\n\t\t\t\t\t\tmessage: `Confidence decreasing across thoughts ${start}-${end} (${firstConf} → ${lastConf})`,\n\t\t\t\t\t\tthought_range: [start, end],\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\trunStart = -1;\n\t\t\t\trunLength = 0;\n\t\t\t\tprevConf = -1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (runLength === 0) {\n\t\t\t\trunStart = i;\n\t\t\t\trunLength = 1;\n\t\t\t\tprevConf = conf;\n\t\t\t} else if (conf < prevConf) {\n\t\t\t\trunLength++;\n\t\t\t\tprevConf = conf;\n\t\t\t} else {\n\t\t\t\tif (runLength >= 3) {\n\t\t\t\t\tconst start = history[runStart]!.thought_number ?? runStart + 1;\n\t\t\t\t\tconst end = history[runStart + runLength - 1]!.thought_number ?? runStart + runLength;\n\t\t\t\t\tconst firstConf = history[runStart]!.confidence!;\n\t\t\t\t\tconst lastConf = history[runStart + runLength - 1]!.confidence!;\n\t\t\t\t\tsignals.push({\n\t\t\t\t\t\tpattern: 'confidence_drift',\n\t\t\t\t\t\tseverity: 'warning',\n\t\t\t\t\t\tmessage: `Confidence decreasing across thoughts ${start}-${end} (${firstConf} → ${lastConf})`,\n\t\t\t\t\t\tthought_range: [start, end],\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\trunStart = i;\n\t\t\t\trunLength = 1;\n\t\t\t\tprevConf = conf;\n\t\t\t}\n\t\t}\n\t\t// Flush final run\n\t\tif (runLength >= 3) {\n\t\t\tconst start = history[runStart]!.thought_number ?? runStart + 1;\n\t\t\tconst end = history[runStart + runLength - 1]!.thought_number ?? runStart + runLength;\n\t\t\tconst firstConf = history[runStart]!.confidence!;\n\t\t\tconst lastConf = history[runStart + runLength - 1]!.confidence!;\n\t\t\tsignals.push({\n\t\t\t\tpattern: 'confidence_drift',\n\t\t\t\tseverity: 'warning',\n\t\t\t\tmessage: `Confidence decreasing across thoughts ${start}-${end} (${firstConf} → ${lastConf})`,\n\t\t\t\tthought_range: [start, end],\n\t\t\t});\n\t\t}\n\t\treturn signals;\n\t}\n\n\t/** Detect hypothesis verified within 3 subsequent thoughts — positive signal. */\n\tprivate _detectHealthyVerification(history: ThoughtData[]): PatternSignal[] {\n\t\tconst signals: PatternSignal[] = [];\n\t\tfor (let i = 0; i < history.length; i++) {\n\t\t\tif (history[i]!.thought_type !== 'hypothesis') continue;\n\t\t\tconst hypId = history[i]!.hypothesis_id;\n\t\t\tconst lookahead = history.slice(i + 1, i + 4);\n\t\t\tconst verifier = lookahead.find(\n\t\t\t\t(t) =>\n\t\t\t\t\tt.thought_type === 'verification' &&\n\t\t\t\t\t(t.hypothesis_id === hypId || t.verification_target === (history[i]!.thought_number ?? i + 1))\n\t\t\t);\n\t\t\tif (verifier) {\n\t\t\t\tconst n = history[i]!.thought_number ?? i + 1;\n\t\t\t\tconst m = verifier.thought_number ?? history.indexOf(verifier) + 1;\n\t\t\t\tsignals.push({\n\t\t\t\t\tpattern: 'healthy_verification',\n\t\t\t\t\tseverity: 'info',\n\t\t\t\t\tmessage: `Hypothesis at thought ${n} verified at thought ${m} — good practice`,\n\t\t\t\t\tthought_range: [n, m],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn signals;\n\t}\n\n\t/** Count thoughts by type across history. */\n\tprivate _countByType(thoughts: ThoughtData[]): Record<ThoughtType, number> {\n\t\tconst counts = Object.fromEntries(ALL_THOUGHT_TYPES.map((t) => [t, 0])) as Record<\n\t\t\tThoughtType,\n\t\t\tnumber\n\t\t>;\n\n\t\tfor (const thought of thoughts) {\n\t\t\tconst type = thought.thought_type ?? 'regular';\n\t\t\tif (type in counts) {\n\t\t\t\tcounts[type]++;\n\t\t\t}\n\t\t}\n\n\t\treturn counts;\n\t}\n\n\t/** Find longest sequential chain depth (contiguous thoughts without branching). */\n\tprivate _computeChainDepth(history: ThoughtData[]): number {\n\t\tif (history.length === 0) return 0;\n\t\t// Simple: longest contiguous chain without branching\n\t\tlet maxDepth = 1;\n\t\tlet currentDepth = 1;\n\n\t\tfor (let i = 1; i < history.length; i++) {\n\t\t\tconst thought = history[i]!;\n\t\t\tif (!thought.branch_from_thought) {\n\t\t\t\tcurrentDepth++;\n\t\t\t\tmaxDepth = Math.max(maxDepth, currentDepth);\n\t\t\t} else {\n\t\t\t\tcurrentDepth = 1;\n\t\t\t}\n\t\t}\n\n\t\treturn maxDepth;\n\t}\n\n\t/** Compute composite structural quality score from history. */\n\tprivate _computeStructuralQuality(\n\t\thistory: ThoughtData[],\n\t\tbranches: Record<string, ThoughtData[]>,\n\t\ttypeDistribution: Record<ThoughtType, number>,\n\t\tconfidences: number[]\n\t): { score: number; components: { type_diversity: number; verification_coverage: number; depth_efficiency: number; confidence_stability: number } } | null {\n\t\tif (history.length === 0) return null;\n\n\t\tconst FLOOR = 0.01;\n\n\t\t// 1. type_diversity: Shannon entropy / log2(6)\n\t\tconst total = history.length;\n\t\tlet entropy = 0;\n\t\tfor (const type of ALL_THOUGHT_TYPES) {\n\t\t\tconst count = typeDistribution[type];\n\t\t\tif (count > 0) {\n\t\t\t\tconst pk = count / total;\n\t\t\t\tentropy -= pk * Math.log2(pk);\n\t\t\t}\n\t\t}\n\t\tconst typeDiversity = Math.max(entropy / Math.log2(6), FLOOR);\n\n\t\t// 2. verification_coverage: verified / total hypotheses (1.0 if none)\n\t\tconst hypotheses = history.filter((t) => t.thought_type === 'hypothesis');\n\t\tconst hypothesisIds = new Set(hypotheses.map((t) => t.hypothesis_id).filter(Boolean));\n\t\tconst verifiedIds = new Set(\n\t\t\thistory\n\t\t\t\t.filter((t) => t.thought_type === 'verification' && t.hypothesis_id)\n\t\t\t\t.map((t) => t.hypothesis_id)\n\t\t);\n\t\tconst verificationCoverage =\n\t\t\thypothesisIds.size === 0\n\t\t\t\t? 1.0\n\t\t\t\t: Math.max(\n\t\t\t\t\t\t[...hypothesisIds].filter((id) => verifiedIds.has(id)).length / hypothesisIds.size,\n\t\t\t\t\t\tFLOOR\n\t\t\t\t\t);\n\n\t\t// 3. depth_efficiency: max(chain_depth, branch_count + 1) / total_thoughts, clamped to 1.0\n\t\t// NOTE (Metis H3): Branching is desirable — treat branches as depth-equivalent.\n\t\tconst chainDepth = this._computeChainDepth(history);\n\t\tconst branchCount = Object.keys(branches).length;\n\t\tconst effectiveDepth = Math.max(chainDepth, branchCount + 1);\n\t\tconst depthEfficiency = Math.max(Math.min(effectiveDepth / total, 1.0), FLOOR);\n\n\t\t// 4. confidence_stability: 1 - stddev(confidences), default 0.5\n\t\tconst confidenceStability = this._computeConfidenceStability(confidences);\n\n\t\tconst components = {\n\t\t\ttype_diversity: typeDiversity,\n\t\t\tverification_coverage: verificationCoverage,\n\t\t\tdepth_efficiency: depthEfficiency,\n\t\t\tconfidence_stability: confidenceStability,\n\t\t};\n\n\t\t// Weighted geometric mean: td^0.3 * vc^0.3 * de^0.2 * cs^0.2\n\t\tconst score =\n\t\t\tMath.pow(typeDiversity, 0.3) *\n\t\t\tMath.pow(verificationCoverage, 0.3) *\n\t\t\tMath.pow(depthEfficiency, 0.2) *\n\t\t\tMath.pow(confidenceStability, 0.2);\n\n\t\treturn { score, components };\n\t}\n\n\t/** Compute confidence stability: 1 - stddev(confidences). */\n\tprivate _computeConfidenceStability(confidences: number[]): number {\n\t\tconst FLOOR = 0.01;\n\t\tif (confidences.length === 0) return Math.max(0.5, FLOOR);\n\t\tif (confidences.length === 1) return Math.max(1.0, FLOOR);\n\n\t\tconst mean = confidences.reduce((a, b) => a + b, 0) / confidences.length;\n\t\tconst variance = confidences.reduce((sum, c) => sum + (c - mean) ** 2, 0) / confidences.length;\n\t\tconst stddev = Math.sqrt(variance);\n\t\treturn Math.max(1 - stddev, FLOOR);\n\t}\n}\n"],"names":["ALL_THOUGHT_TYPES","ThoughtEvaluator","history","branches","typeDistribution","allConfidences","t","c","undefined","structuralResult","Object","a","b","typeCounts","allScores","s","hypotheses","hypothesisIds","Set","Boolean","verifiedIds","unresolvedCount","id","signals","runStart","i","type","start","end","remaining","lookahead","hasVerification","n","hasExplicitType","runType","runLength","prevConf","conf","firstConf","lastConf","hypId","verifier","m","thoughts","counts","thought","maxDepth","currentDepth","Math","confidences","FLOOR","total","entropy","count","pk","typeDiversity","verificationCoverage","chainDepth","branchCount","effectiveDepth","depthEfficiency","confidenceStability","components","score","mean","variance","sum","stddev"],"mappings":"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"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Display formatting for thoughts and recommendations.
|
|
3
|
+
*
|
|
4
|
+
* This module provides the `ThoughtFormatter` class which handles all
|
|
5
|
+
* presentation logic for thought data, including clean, simple output
|
|
6
|
+
* formatting and structured display of tool/skill recommendations.
|
|
7
|
+
*
|
|
8
|
+
* @module formatter
|
|
9
|
+
*/
|
|
10
|
+
import type { StepRecommendation } from './step.js';
|
|
11
|
+
import type { ThoughtData } from './thought.js';
|
|
12
|
+
/**
|
|
13
|
+
* Formatter for thought data and step recommendations.
|
|
14
|
+
*
|
|
15
|
+
* This class separates presentation concerns from business logic, providing
|
|
16
|
+
* clean, readable output for thoughts with structured display of
|
|
17
|
+
* tool and skill recommendations.
|
|
18
|
+
*
|
|
19
|
+
* @remarks
|
|
20
|
+
* Output Format is clean and simple:
|
|
21
|
+
* - 💭 Thought - Regular thought (blue)
|
|
22
|
+
* - 🔬 Hypothesis - Proposed explanation (magenta)
|
|
23
|
+
* - ✅ Verification - Testing a hypothesis (green)
|
|
24
|
+
* - 🔍 Critique - Self-critique of reasoning (red)
|
|
25
|
+
* - 🧬 Synthesis - Combining thoughts/branches (cyan)
|
|
26
|
+
* - 🧠 Meta - Metacognitive observation (gray)
|
|
27
|
+
* - 🔄 Revision - Thought that revises a previous thought (yellow)
|
|
28
|
+
* - 🌿 Branch - Thought that creates a new branch (green)
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* const formatter = new ThoughtFormatter();
|
|
32
|
+
*
|
|
33
|
+
* // Format a thought with recommendations
|
|
34
|
+
* const output = formatter.formatThought({
|
|
35
|
+
* thought: 'I need to analyze the data structure',
|
|
36
|
+
* thought_number: 1,
|
|
37
|
+
* total_thoughts: 3,
|
|
38
|
+
* next_thought_needed: true,
|
|
39
|
+
* current_step: {
|
|
40
|
+
* step_description: 'Analyze data structure',
|
|
41
|
+
* recommended_tools: [{
|
|
42
|
+
* tool_name: 'Read',
|
|
43
|
+
* confidence: 0.95,
|
|
44
|
+
* rationale: 'Direct file reading',
|
|
45
|
+
* priority: 1,
|
|
46
|
+
* suggested_inputs: { file_path: './data/schema.json' }
|
|
47
|
+
* }],
|
|
48
|
+
* expected_outcome: 'Understanding of data schema'
|
|
49
|
+
* }
|
|
50
|
+
* });
|
|
51
|
+
*
|
|
52
|
+
* console.log(output);
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare class ThoughtFormatter {
|
|
56
|
+
/**
|
|
57
|
+
* Formats a step recommendation into a readable string.
|
|
58
|
+
*
|
|
59
|
+
* Creates a structured display of the step description, recommended tools,
|
|
60
|
+
* recommended skills, expected outcome, and conditions for the next step.
|
|
61
|
+
*
|
|
62
|
+
* @param step - The step recommendation to format
|
|
63
|
+
* @returns A formatted string representation of the recommendation
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* const step: StepRecommendation = {
|
|
68
|
+
* step_description: 'Search for API endpoints',
|
|
69
|
+
* recommended_tools: [{
|
|
70
|
+
* tool_name: 'Grep',
|
|
71
|
+
* confidence: 0.9,
|
|
72
|
+
* rationale: 'Best for searching code patterns',
|
|
73
|
+
* priority: 1,
|
|
74
|
+
* suggested_inputs: { pattern: 'export.*function' }
|
|
75
|
+
* }],
|
|
76
|
+
* expected_outcome: 'List of all exported API functions',
|
|
77
|
+
* next_step_conditions: ['If no results, try broader pattern']
|
|
78
|
+
* };
|
|
79
|
+
*
|
|
80
|
+
* const formatted = formatter.formatRecommendation(step);
|
|
81
|
+
* console.log(formatted);
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
formatRecommendation(step: StepRecommendation): string;
|
|
85
|
+
/**
|
|
86
|
+
* Formats a thought into a clean, simple display.
|
|
87
|
+
*
|
|
88
|
+
* Creates a clean output containing the thought content with an appropriate
|
|
89
|
+
* header indicating the thought type. Priority order for icon selection:
|
|
90
|
+
* `is_revision` > `branch_from_thought` > `thought_type`.
|
|
91
|
+
*
|
|
92
|
+
* Supported `thought_type` icons:
|
|
93
|
+
* - `'regular'` (or undefined): 💭 blue "Thought" (default)
|
|
94
|
+
* - `'hypothesis'`: 🔬 magenta "Hypothesis"
|
|
95
|
+
* - `'verification'`: ✅ green "Verification"
|
|
96
|
+
* - `'critique'`: 🔍 red "Critique"
|
|
97
|
+
* - `'synthesis'`: 🧬 cyan "Synthesis"
|
|
98
|
+
* - `'meta'`: 🧠 gray "Meta"
|
|
99
|
+
*
|
|
100
|
+
* @param thoughtData - The thought data to format
|
|
101
|
+
* @returns A formatted string with thought and recommendations
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```typescript
|
|
105
|
+
* // Regular thought
|
|
106
|
+
* const regular = formatter.formatThought({
|
|
107
|
+
* thought: 'I should read the configuration file',
|
|
108
|
+
* thought_number: 1,
|
|
109
|
+
* total_thoughts: 3,
|
|
110
|
+
* next_thought_needed: true
|
|
111
|
+
* });
|
|
112
|
+
* // Output: 💭 Thought 1/3: I should read the configuration file
|
|
113
|
+
*
|
|
114
|
+
* // With recommendation
|
|
115
|
+
* const withRec = formatter.formatThought({
|
|
116
|
+
* thought: 'I need to search the codebase',
|
|
117
|
+
* thought_number: 1,
|
|
118
|
+
* total_thoughts: 3,
|
|
119
|
+
* next_thought_needed: true,
|
|
120
|
+
* current_step: {
|
|
121
|
+
* step_description: 'Search for files',
|
|
122
|
+
* recommended_tools: [{ tool_name: 'Grep', priority: 1 }],
|
|
123
|
+
* expected_outcome: 'List of matching files'
|
|
124
|
+
* }
|
|
125
|
+
* });
|
|
126
|
+
* // Output:
|
|
127
|
+
* // 💭 Thought 1/3: I need to search the codebase
|
|
128
|
+
* // → Tools: Grep | List of matching files
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
formatThought(thoughtData: ThoughtData): string;
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=ThoughtFormatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThoughtFormatter.d.ts","sourceRoot":"","sources":["../../src/core/ThoughtFormatter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,qBAAa,gBAAgB;IAC5B;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACI,oBAAoB,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM;IAuB7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6CG;IACI,aAAa,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM;CA0EtD"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
class ThoughtFormatter {
|
|
3
|
+
formatRecommendation(step) {
|
|
4
|
+
const parts = [];
|
|
5
|
+
if (step.recommended_tools?.length) {
|
|
6
|
+
const toolNames = step.recommended_tools.map((t)=>t.tool_name).join(', ');
|
|
7
|
+
parts.push(chalk.cyan(`Tools: ${toolNames}`));
|
|
8
|
+
}
|
|
9
|
+
if (step.recommended_skills?.length) {
|
|
10
|
+
const skillNames = step.recommended_skills.map((s)=>s.skill_name).join(', ');
|
|
11
|
+
parts.push(chalk.green(`Skills: ${skillNames}`));
|
|
12
|
+
}
|
|
13
|
+
if (step.expected_outcome) parts.push(chalk.gray(`→ ${step.expected_outcome}`));
|
|
14
|
+
return parts.join(' | ');
|
|
15
|
+
}
|
|
16
|
+
formatThought(thoughtData) {
|
|
17
|
+
const { thought_number, total_thoughts, thought, is_revision, revises_thought, branch_from_thought, current_step } = thoughtData;
|
|
18
|
+
let icon;
|
|
19
|
+
let label = 'Thought';
|
|
20
|
+
let suffix = '';
|
|
21
|
+
if (is_revision) {
|
|
22
|
+
icon = chalk.yellow('🔄');
|
|
23
|
+
label = 'Revision';
|
|
24
|
+
suffix = chalk.gray(` (revise #${revises_thought})`);
|
|
25
|
+
} else if (branch_from_thought) {
|
|
26
|
+
icon = chalk.green('🌿');
|
|
27
|
+
label = 'Branch';
|
|
28
|
+
suffix = chalk.gray(` (from #${branch_from_thought})`);
|
|
29
|
+
} else {
|
|
30
|
+
const thoughtType = thoughtData.thought_type ?? 'regular';
|
|
31
|
+
switch(thoughtType){
|
|
32
|
+
case 'hypothesis':
|
|
33
|
+
icon = chalk.magenta('🔬');
|
|
34
|
+
label = 'Hypothesis';
|
|
35
|
+
break;
|
|
36
|
+
case 'verification':
|
|
37
|
+
icon = chalk.green('✅');
|
|
38
|
+
label = 'Verification';
|
|
39
|
+
break;
|
|
40
|
+
case 'critique':
|
|
41
|
+
icon = chalk.red('🔍');
|
|
42
|
+
label = 'Critique';
|
|
43
|
+
break;
|
|
44
|
+
case 'synthesis':
|
|
45
|
+
icon = chalk.cyan('🧬');
|
|
46
|
+
label = 'Synthesis';
|
|
47
|
+
break;
|
|
48
|
+
case 'meta':
|
|
49
|
+
icon = chalk.gray('🧠');
|
|
50
|
+
label = 'Meta';
|
|
51
|
+
break;
|
|
52
|
+
default:
|
|
53
|
+
icon = chalk.blue('💭');
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const header = `${icon} ${label} ${thought_number}/${total_thoughts}${suffix}: `;
|
|
58
|
+
const lines = [];
|
|
59
|
+
lines.push(`${header}${thought}`);
|
|
60
|
+
if (current_step) {
|
|
61
|
+
const recommendation = this.formatRecommendation(current_step);
|
|
62
|
+
lines.push(` ${recommendation}`);
|
|
63
|
+
}
|
|
64
|
+
if (thoughtData.meta_observation) lines.push(` ${chalk.gray(`📝 ${thoughtData.meta_observation}`)}`);
|
|
65
|
+
return lines.join('\n');
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export { ThoughtFormatter };
|
|
69
|
+
|
|
70
|
+
//# sourceMappingURL=ThoughtFormatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core/ThoughtFormatter.js","sources":["../../src/core/ThoughtFormatter.ts"],"sourcesContent":["/**\n * Display formatting for thoughts and recommendations.\n *\n * This module provides the `ThoughtFormatter` class which handles all\n * presentation logic for thought data, including clean, simple output\n * formatting and structured display of tool/skill recommendations.\n *\n * @module formatter\n */\n\nimport chalk from 'chalk';\nimport type { ThoughtType } from './reasoning.js';\nimport type { StepRecommendation } from './step.js';\nimport type { ThoughtData } from './thought.js';\n\n/**\n * Formatter for thought data and step recommendations.\n *\n * This class separates presentation concerns from business logic, providing\n * clean, readable output for thoughts with structured display of\n * tool and skill recommendations.\n *\n * @remarks\n * Output Format is clean and simple:\n * - 💭 Thought - Regular thought (blue)\n * - 🔬 Hypothesis - Proposed explanation (magenta)\n * - ✅ Verification - Testing a hypothesis (green)\n * - 🔍 Critique - Self-critique of reasoning (red)\n * - 🧬 Synthesis - Combining thoughts/branches (cyan)\n * - 🧠 Meta - Metacognitive observation (gray)\n * - 🔄 Revision - Thought that revises a previous thought (yellow)\n * - 🌿 Branch - Thought that creates a new branch (green)\n * @example\n * ```typescript\n * const formatter = new ThoughtFormatter();\n *\n * // Format a thought with recommendations\n * const output = formatter.formatThought({\n * thought: 'I need to analyze the data structure',\n * thought_number: 1,\n * total_thoughts: 3,\n * next_thought_needed: true,\n * current_step: {\n * step_description: 'Analyze data structure',\n * recommended_tools: [{\n * tool_name: 'Read',\n * confidence: 0.95,\n * rationale: 'Direct file reading',\n * priority: 1,\n * suggested_inputs: { file_path: './data/schema.json' }\n * }],\n * expected_outcome: 'Understanding of data schema'\n * }\n * });\n *\n * console.log(output);\n * ```\n */\nexport class ThoughtFormatter {\n\t/**\n\t * Formats a step recommendation into a readable string.\n\t *\n\t * Creates a structured display of the step description, recommended tools,\n\t * recommended skills, expected outcome, and conditions for the next step.\n\t *\n\t * @param step - The step recommendation to format\n\t * @returns A formatted string representation of the recommendation\n\t *\n\t * @example\n\t * ```typescript\n\t * const step: StepRecommendation = {\n\t * step_description: 'Search for API endpoints',\n\t * recommended_tools: [{\n\t * tool_name: 'Grep',\n\t * confidence: 0.9,\n\t * rationale: 'Best for searching code patterns',\n\t * priority: 1,\n\t * suggested_inputs: { pattern: 'export.*function' }\n\t * }],\n\t * expected_outcome: 'List of all exported API functions',\n\t * next_step_conditions: ['If no results, try broader pattern']\n\t * };\n\t *\n\t * const formatted = formatter.formatRecommendation(step);\n\t * console.log(formatted);\n\t * ```\n\t */\n\tpublic formatRecommendation(step: StepRecommendation): string {\n\t\tconst parts: string[] = [];\n\n\t\t// Add tools if present\n\t\tif (step.recommended_tools?.length) {\n\t\t\tconst toolNames = step.recommended_tools.map((t) => t.tool_name).join(', ');\n\t\t\tparts.push(chalk.cyan(`Tools: ${toolNames}`));\n\t\t}\n\n\t\t// Add skills if present\n\t\tif (step.recommended_skills?.length) {\n\t\t\tconst skillNames = step.recommended_skills.map((s) => s.skill_name).join(', ');\n\t\t\tparts.push(chalk.green(`Skills: ${skillNames}`));\n\t\t}\n\n\t\t// Add expected outcome\n\t\tif (step.expected_outcome) {\n\t\t\tparts.push(chalk.gray(`→ ${step.expected_outcome}`));\n\t\t}\n\n\t\treturn parts.join(' | ');\n\t}\n\n\t/**\n\t * Formats a thought into a clean, simple display.\n\t *\n\t * Creates a clean output containing the thought content with an appropriate\n\t * header indicating the thought type. Priority order for icon selection:\n\t * `is_revision` > `branch_from_thought` > `thought_type`.\n\t *\n\t * Supported `thought_type` icons:\n\t * - `'regular'` (or undefined): 💭 blue \"Thought\" (default)\n\t * - `'hypothesis'`: 🔬 magenta \"Hypothesis\"\n\t * - `'verification'`: ✅ green \"Verification\"\n\t * - `'critique'`: 🔍 red \"Critique\"\n\t * - `'synthesis'`: 🧬 cyan \"Synthesis\"\n\t * - `'meta'`: 🧠 gray \"Meta\"\n\t *\n\t * @param thoughtData - The thought data to format\n\t * @returns A formatted string with thought and recommendations\n\t *\n\t * @example\n\t * ```typescript\n\t * // Regular thought\n\t * const regular = formatter.formatThought({\n\t * thought: 'I should read the configuration file',\n\t * thought_number: 1,\n\t * total_thoughts: 3,\n\t * next_thought_needed: true\n\t * });\n\t * // Output: 💭 Thought 1/3: I should read the configuration file\n\t *\n\t * // With recommendation\n\t * const withRec = formatter.formatThought({\n\t * thought: 'I need to search the codebase',\n\t * thought_number: 1,\n\t * total_thoughts: 3,\n\t * next_thought_needed: true,\n\t * current_step: {\n\t * step_description: 'Search for files',\n\t * recommended_tools: [{ tool_name: 'Grep', priority: 1 }],\n\t * expected_outcome: 'List of matching files'\n\t * }\n\t * });\n\t * // Output:\n\t * // 💭 Thought 1/3: I need to search the codebase\n\t * // → Tools: Grep | List of matching files\n\t * ```\n\t */\n\tpublic formatThought(thoughtData: ThoughtData): string {\n\t\tconst {\n\t\t\tthought_number,\n\t\t\ttotal_thoughts,\n\t\t\tthought,\n\t\t\tis_revision,\n\t\t\trevises_thought,\n\t\t\tbranch_from_thought,\n\t\t\tcurrent_step,\n\t\t} = thoughtData;\n\n\t\tlet icon: string;\n\t\tlet label = 'Thought';\n\t\tlet suffix = '';\n\n\t\tif (is_revision) {\n\t\t\ticon = chalk.yellow('🔄');\n\t\t\tlabel = 'Revision';\n\t\t\tsuffix = chalk.gray(` (revise #${revises_thought})`);\n\t\t} else if (branch_from_thought) {\n\t\t\ticon = chalk.green('🌿');\n\t\t\tlabel = 'Branch';\n\t\t\tsuffix = chalk.gray(` (from #${branch_from_thought})`);\n\t\t} else {\n\t\t\tconst thoughtType: ThoughtType = thoughtData.thought_type ?? 'regular';\n\t\t\tswitch (thoughtType) {\n\t\t\t\tcase 'hypothesis':\n\t\t\t\t\ticon = chalk.magenta('🔬');\n\t\t\t\t\tlabel = 'Hypothesis';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'verification':\n\t\t\t\t\ticon = chalk.green('✅');\n\t\t\t\t\tlabel = 'Verification';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'critique':\n\t\t\t\t\ticon = chalk.red('🔍');\n\t\t\t\t\tlabel = 'Critique';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'synthesis':\n\t\t\t\t\ticon = chalk.cyan('🧬');\n\t\t\t\t\tlabel = 'Synthesis';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'meta':\n\t\t\t\t\ticon = chalk.gray('🧠');\n\t\t\t\t\tlabel = 'Meta';\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\ticon = chalk.blue('💭');\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// Build header: \"💭 Thought 1/3: \"\n\t\tconst header = `${icon} ${label} ${thought_number}/${total_thoughts}${suffix}: `;\n\n\t\t// Build content lines\n\t\tconst lines: string[] = [];\n\n\t\t// Add the thought content\n\t\tlines.push(`${header}${thought}`);\n\n\t\t// Add recommendation if present\n\t\tif (current_step) {\n\t\t\tconst recommendation = this.formatRecommendation(current_step);\n\t\t\tlines.push(` ${recommendation}`);\n\t\t}\n\n\t\t// Add meta observation if present\n\t\tif (thoughtData.meta_observation) {\n\t\t\tlines.push(` ${chalk.gray(`📝 ${thoughtData.meta_observation}`)}`);\n\t\t}\n\n\t\treturn lines.join('\\n');\n\t}\n}\n"],"names":["ThoughtFormatter","step","parts","toolNames","t","chalk","skillNames","s","thoughtData","thought_number","total_thoughts","thought","is_revision","revises_thought","branch_from_thought","current_step","icon","label","suffix","thoughtType","header","lines","recommendation"],"mappings":";AA0DO,MAAMA;IA6BL,qBAAqBC,IAAwB,EAAU;QAC7D,MAAMC,QAAkB,EAAE;QAG1B,IAAID,KAAK,iBAAiB,EAAE,QAAQ;YACnC,MAAME,YAAYF,KAAK,iBAAiB,CAAC,GAAG,CAAC,CAACG,IAAMA,EAAE,SAAS,EAAE,IAAI,CAAC;YACtEF,MAAM,IAAI,CAACG,MAAM,IAAI,CAAC,CAAC,OAAO,EAAEF,WAAW;QAC5C;QAGA,IAAIF,KAAK,kBAAkB,EAAE,QAAQ;YACpC,MAAMK,aAAaL,KAAK,kBAAkB,CAAC,GAAG,CAAC,CAACM,IAAMA,EAAE,UAAU,EAAE,IAAI,CAAC;YACzEL,MAAM,IAAI,CAACG,MAAM,KAAK,CAAC,CAAC,QAAQ,EAAEC,YAAY;QAC/C;QAGA,IAAIL,KAAK,gBAAgB,EACxBC,MAAM,IAAI,CAACG,MAAM,IAAI,CAAC,CAAC,EAAE,EAAEJ,KAAK,gBAAgB,EAAE;QAGnD,OAAOC,MAAM,IAAI,CAAC;IACnB;IAgDO,cAAcM,WAAwB,EAAU;QACtD,MAAM,EACLC,cAAc,EACdC,cAAc,EACdC,OAAO,EACPC,WAAW,EACXC,eAAe,EACfC,mBAAmB,EACnBC,YAAY,EACZ,GAAGP;QAEJ,IAAIQ;QACJ,IAAIC,QAAQ;QACZ,IAAIC,SAAS;QAEb,IAAIN,aAAa;YAChBI,OAAOX,MAAM,MAAM,CAAC;YACpBY,QAAQ;YACRC,SAASb,MAAM,IAAI,CAAC,CAAC,UAAU,EAAEQ,gBAAgB,CAAC,CAAC;QACpD,OAAO,IAAIC,qBAAqB;YAC/BE,OAAOX,MAAM,KAAK,CAAC;YACnBY,QAAQ;YACRC,SAASb,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAES,oBAAoB,CAAC,CAAC;QACtD,OAAO;YACN,MAAMK,cAA2BX,YAAY,YAAY,IAAI;YAC7D,OAAQW;gBACP,KAAK;oBACJH,OAAOX,MAAM,OAAO,CAAC;oBACrBY,QAAQ;oBACR;gBACD,KAAK;oBACJD,OAAOX,MAAM,KAAK,CAAC;oBACnBY,QAAQ;oBACR;gBACD,KAAK;oBACJD,OAAOX,MAAM,GAAG,CAAC;oBACjBY,QAAQ;oBACR;gBACD,KAAK;oBACJD,OAAOX,MAAM,IAAI,CAAC;oBAClBY,QAAQ;oBACR;gBACD,KAAK;oBACJD,OAAOX,MAAM,IAAI,CAAC;oBAClBY,QAAQ;oBACR;gBACD;oBACCD,OAAOX,MAAM,IAAI,CAAC;oBAClB;YACF;QACD;QAGA,MAAMe,SAAS,GAAGJ,KAAK,CAAC,EAAEC,MAAM,CAAC,EAAER,eAAe,CAAC,EAAEC,iBAAiBQ,OAAO,EAAE,CAAC;QAGhF,MAAMG,QAAkB,EAAE;QAG1BA,MAAM,IAAI,CAAC,GAAGD,SAAST,SAAS;QAGhC,IAAII,cAAc;YACjB,MAAMO,iBAAiB,IAAI,CAAC,oBAAoB,CAACP;YACjDM,MAAM,IAAI,CAAC,CAAC,EAAE,EAAEC,gBAAgB;QACjC;QAGA,IAAId,YAAY,gBAAgB,EAC/Ba,MAAM,IAAI,CAAC,CAAC,EAAE,EAAEhB,MAAM,IAAI,CAAC,CAAC,GAAG,EAAEG,YAAY,gBAAgB,EAAE,GAAG;QAGnE,OAAOa,MAAM,IAAI,CAAC;IACnB;AACD"}
|