@redaksjon/protokoll 0.0.13 → 0.0.15
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/README.md +199 -0
- package/dist/feedback.js +5193 -0
- package/dist/feedback.js.map +1 -0
- package/dist/main.js +1858 -9
- package/dist/main.js.map +1 -1
- package/dist/mcp/server.js +1330 -0
- package/dist/mcp/server.js.map +1 -0
- package/guide/index.md +16 -0
- package/guide/mcp-integration.md +341 -0
- package/package.json +5 -3
- package/tsconfig.tsbuildinfo +1 -1
- package/vite.config.ts +13 -29
- package/dist/agentic/executor.js +0 -747
- package/dist/agentic/executor.js.map +0 -1
- package/dist/agentic/index.js +0 -19
- package/dist/agentic/index.js.map +0 -1
- package/dist/agentic/registry.js +0 -41
- package/dist/agentic/registry.js.map +0 -1
- package/dist/agentic/tools/lookup-person.js +0 -185
- package/dist/agentic/tools/lookup-person.js.map +0 -1
- package/dist/agentic/tools/lookup-project.js +0 -210
- package/dist/agentic/tools/lookup-project.js.map +0 -1
- package/dist/agentic/tools/route-note.js +0 -49
- package/dist/agentic/tools/route-note.js.map +0 -1
- package/dist/agentic/tools/store-context.js +0 -51
- package/dist/agentic/tools/store-context.js.map +0 -1
- package/dist/agentic/tools/verify-spelling.js +0 -57
- package/dist/agentic/tools/verify-spelling.js.map +0 -1
- package/dist/arguments.js +0 -178
- package/dist/arguments.js.map +0 -1
- package/dist/cli/action.js +0 -704
- package/dist/cli/action.js.map +0 -1
- package/dist/cli/config.js +0 -482
- package/dist/cli/config.js.map +0 -1
- package/dist/cli/context.js +0 -466
- package/dist/cli/context.js.map +0 -1
- package/dist/cli/feedback.js +0 -858
- package/dist/cli/feedback.js.map +0 -1
- package/dist/cli/index.js +0 -103
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/install.js +0 -572
- package/dist/cli/install.js.map +0 -1
- package/dist/cli/transcript.js +0 -199
- package/dist/cli/transcript.js.map +0 -1
- package/dist/constants.js +0 -91
- package/dist/constants.js.map +0 -1
- package/dist/context/discovery.js +0 -114
- package/dist/context/discovery.js.map +0 -1
- package/dist/context/index.js +0 -82
- package/dist/context/index.js.map +0 -1
- package/dist/context/storage.js +0 -184
- package/dist/context/storage.js.map +0 -1
- package/dist/interactive/handler.js +0 -524
- package/dist/interactive/handler.js.map +0 -1
- package/dist/interactive/index.js +0 -18
- package/dist/interactive/index.js.map +0 -1
- package/dist/interactive/onboarding.js +0 -28
- package/dist/interactive/onboarding.js.map +0 -1
- package/dist/logging.js +0 -46
- package/dist/logging.js.map +0 -1
- package/dist/output/index.js +0 -8
- package/dist/output/index.js.map +0 -1
- package/dist/output/manager.js +0 -150
- package/dist/output/manager.js.map +0 -1
- package/dist/phases/complete.js +0 -142
- package/dist/phases/complete.js.map +0 -1
- package/dist/phases/locate.js +0 -64
- package/dist/phases/locate.js.map +0 -1
- package/dist/pipeline/index.js +0 -8
- package/dist/pipeline/index.js.map +0 -1
- package/dist/pipeline/orchestrator.js +0 -354
- package/dist/pipeline/orchestrator.js.map +0 -1
- package/dist/protokoll.js +0 -180
- package/dist/protokoll.js.map +0 -1
- package/dist/reasoning/client.js +0 -233
- package/dist/reasoning/client.js.map +0 -1
- package/dist/reasoning/index.js +0 -37
- package/dist/reasoning/index.js.map +0 -1
- package/dist/reasoning/strategy.js +0 -60
- package/dist/reasoning/strategy.js.map +0 -1
- package/dist/reflection/collector.js +0 -124
- package/dist/reflection/collector.js.map +0 -1
- package/dist/reflection/index.js +0 -16
- package/dist/reflection/index.js.map +0 -1
- package/dist/reflection/reporter.js +0 -238
- package/dist/reflection/reporter.js.map +0 -1
- package/dist/routing/classifier.js +0 -201
- package/dist/routing/classifier.js.map +0 -1
- package/dist/routing/index.js +0 -27
- package/dist/routing/index.js.map +0 -1
- package/dist/routing/router.js +0 -153
- package/dist/routing/router.js.map +0 -1
- package/dist/transcription/index.js +0 -41
- package/dist/transcription/index.js.map +0 -1
- package/dist/transcription/service.js +0 -64
- package/dist/transcription/service.js.map +0 -1
- package/dist/transcription/types.js +0 -31
- package/dist/transcription/types.js.map +0 -1
- package/dist/util/dates.js +0 -96
- package/dist/util/dates.js.map +0 -1
- package/dist/util/media.js +0 -103
- package/dist/util/media.js.map +0 -1
- package/dist/util/metadata.js +0 -95
- package/dist/util/metadata.js.map +0 -1
- package/dist/util/sound.js +0 -116
- package/dist/util/sound.js.map +0 -1
- package/dist/util/storage.js +0 -135
- package/dist/util/storage.js.map +0 -1
package/dist/reflection/index.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { create as create$2 } from './collector.js';
|
|
2
|
-
import { create as create$1 } from './reporter.js';
|
|
3
|
-
|
|
4
|
-
const create = (config)=>{
|
|
5
|
-
const collector = create$2();
|
|
6
|
-
const reporter = create$1();
|
|
7
|
-
return {
|
|
8
|
-
collector,
|
|
9
|
-
reporter,
|
|
10
|
-
generate: (audioFile, outputFile, conversationHistory, output)=>reporter.generate(collector, audioFile, outputFile, conversationHistory, output),
|
|
11
|
-
save: (report, path)=>reporter.save(report, path)
|
|
12
|
-
};
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export { create };
|
|
16
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/reflection/index.ts"],"sourcesContent":["/**\n * Self-Reflection System\n *\n * Main entry point for the self-reflection system. Provides metrics collection\n * and report generation for transcription quality analysis.\n */\n\nimport { ReflectionConfig, ReflectionReport } from './types';\nimport * as Collector from './collector';\nimport * as Reporter from './reporter';\n\nexport interface ReflectionInstance {\n collector: Collector.CollectorInstance;\n reporter: Reporter.ReporterInstance;\n generate(\n audioFile: string,\n outputFile: string,\n conversationHistory?: unknown[],\n output?: string\n ): ReflectionReport;\n save(report: ReflectionReport, path: string): Promise<void>;\n}\n\nexport const create = (config: ReflectionConfig): ReflectionInstance => {\n const collector = Collector.create();\n const reporter = Reporter.create(config);\n \n return {\n collector,\n reporter,\n generate: (audioFile, outputFile, conversationHistory, output) => \n reporter.generate(collector, audioFile, outputFile, conversationHistory, output),\n save: (report, path) => reporter.save(report, path),\n };\n};\n\nexport const DEFAULT_REFLECTION_CONFIG: ReflectionConfig = {\n enabled: false,\n format: 'markdown',\n includeConversation: false,\n includeOutput: true,\n};\n\n// Re-export types\nexport * from './types';\n\n"],"names":["create","config","collector","Collector","reporter","Reporter","generate","audioFile","outputFile","conversationHistory","output","save","report","path"],"mappings":";;;AAuBO,MAAMA,SAAS,CAACC,MAAAA,GAAAA;IACnB,MAAMC,SAAAA,GAAYC,QAAgB,EAAA;IAClC,MAAMC,QAAAA,GAAWC,QAAe,CAACJ,CAAAA;IAEjC,OAAO;AACHC,QAAAA,SAAAA;AACAE,QAAAA,QAAAA;QACAE,QAAAA,EAAU,CAACC,SAAAA,EAAWC,UAAAA,EAAYC,mBAAAA,EAAqBC,MAAAA,GACnDN,QAAAA,CAASE,QAAQ,CAACJ,SAAAA,EAAWK,SAAAA,EAAWC,UAAAA,EAAYC,mBAAAA,EAAqBC,MAAAA,CAAAA;AAC7EC,QAAAA,IAAAA,EAAM,CAACC,MAAAA,EAAQC,IAAAA,GAAST,QAAAA,CAASO,IAAI,CAACC,MAAAA,EAAQC,IAAAA;AAClD,KAAA;AACJ;;;;"}
|
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
import * as fs from 'fs/promises';
|
|
2
|
-
import { getLogger } from '../logging.js';
|
|
3
|
-
|
|
4
|
-
const create = (config)=>{
|
|
5
|
-
const logger = getLogger();
|
|
6
|
-
const assessQuality = (metrics, toolEffectiveness)=>{
|
|
7
|
-
// Calculate name accuracy based on resolution rate
|
|
8
|
-
const nameAccuracy = metrics.unknownEntitiesFound > 0 ? metrics.entitiesResolved / metrics.unknownEntitiesFound : 1.0;
|
|
9
|
-
// Content preservation (should be close to 1.0)
|
|
10
|
-
const contentPreservation = metrics.originalLength > 0 ? Math.min(metrics.correctedLength / metrics.originalLength, 1.0) : 1.0;
|
|
11
|
-
// Tool success rate
|
|
12
|
-
const avgToolSuccess = toolEffectiveness.length > 0 ? toolEffectiveness.reduce((sum, t)=>sum + t.successRate, 0) / toolEffectiveness.length : 1.0;
|
|
13
|
-
// Overall confidence
|
|
14
|
-
const confidence = nameAccuracy * 0.4 + contentPreservation * 0.3 + avgToolSuccess * 0.3;
|
|
15
|
-
return {
|
|
16
|
-
confidence,
|
|
17
|
-
nameAccuracy,
|
|
18
|
-
routingConfidence: 0.9,
|
|
19
|
-
contentPreservation,
|
|
20
|
-
overallScore: confidence
|
|
21
|
-
};
|
|
22
|
-
};
|
|
23
|
-
const generateRecommendations = (metrics, toolEffectiveness, quality)=>{
|
|
24
|
-
const recommendations = [];
|
|
25
|
-
// Check for tool failures
|
|
26
|
-
const failedTools = toolEffectiveness.filter((t)=>t.successRate < 0.8);
|
|
27
|
-
if (failedTools.length > 0) {
|
|
28
|
-
recommendations.push({
|
|
29
|
-
type: 'tool-issue',
|
|
30
|
-
severity: 'high',
|
|
31
|
-
message: `${failedTools.length} tool(s) had low success rates`,
|
|
32
|
-
suggestion: `Review tool implementations: ${failedTools.map((t)=>t.name).join(', ')}`
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
// Check for unresolved entities
|
|
36
|
-
if (metrics.unknownEntitiesFound > metrics.entitiesResolved) {
|
|
37
|
-
const unresolved = metrics.unknownEntitiesFound - metrics.entitiesResolved;
|
|
38
|
-
recommendations.push({
|
|
39
|
-
type: 'context-gap',
|
|
40
|
-
severity: 'medium',
|
|
41
|
-
message: `${unresolved} entities could not be resolved`,
|
|
42
|
-
suggestion: 'Run in interactive mode to add new context entries'
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
// Check for high iteration count (real issue is usually unclear routing)
|
|
46
|
-
if (metrics.iterations > 10) {
|
|
47
|
-
recommendations.push({
|
|
48
|
-
type: 'context-gap',
|
|
49
|
-
severity: 'medium',
|
|
50
|
-
message: `High iteration count (${metrics.iterations}) - model may be struggling to route this note`,
|
|
51
|
-
suggestion: 'Add explicit trigger phrases to your project context files (e.g., "update on [project]")'
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
// Only flag extremely long processing (> 5 minutes) as potential issue
|
|
55
|
-
// Normal reasoning with gpt-5.2 can take 1-3 minutes and that's fine
|
|
56
|
-
if (metrics.totalDuration > 300000) {
|
|
57
|
-
recommendations.push({
|
|
58
|
-
type: 'performance',
|
|
59
|
-
severity: 'low',
|
|
60
|
-
message: `Processing took ${(metrics.totalDuration / 1000).toFixed(1)}s`,
|
|
61
|
-
suggestion: 'Consider reviewing context files - unclear routing can cause excessive iterations'
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
// Check content preservation
|
|
65
|
-
if (quality.contentPreservation < 0.9) {
|
|
66
|
-
recommendations.push({
|
|
67
|
-
type: 'quality',
|
|
68
|
-
severity: 'high',
|
|
69
|
-
message: 'Significant content may have been lost',
|
|
70
|
-
suggestion: 'Review prompt to ensure full content preservation'
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
return recommendations;
|
|
74
|
-
};
|
|
75
|
-
const generate = (collector, audioFile, outputFile, conversationHistory, output)=>{
|
|
76
|
-
const metrics = collector.getMetrics();
|
|
77
|
-
const toolEffectiveness = collector.getToolEffectiveness();
|
|
78
|
-
const contextChanges = collector.getContextChanges();
|
|
79
|
-
const routingDecision = collector.getRoutingDecision();
|
|
80
|
-
const quality = assessQuality(metrics, toolEffectiveness);
|
|
81
|
-
const recommendations = generateRecommendations(metrics, toolEffectiveness, quality);
|
|
82
|
-
return {
|
|
83
|
-
id: `reflection-${Date.now()}`,
|
|
84
|
-
generated: new Date(),
|
|
85
|
-
audioFile,
|
|
86
|
-
outputFile,
|
|
87
|
-
summary: {
|
|
88
|
-
duration: metrics.totalDuration,
|
|
89
|
-
iterations: metrics.iterations,
|
|
90
|
-
toolCalls: metrics.toolCallsExecuted,
|
|
91
|
-
corrections: metrics.correctionsApplied,
|
|
92
|
-
confidence: quality.confidence
|
|
93
|
-
},
|
|
94
|
-
metrics,
|
|
95
|
-
toolEffectiveness,
|
|
96
|
-
quality,
|
|
97
|
-
recommendations,
|
|
98
|
-
routingDecision,
|
|
99
|
-
contextChanges: contextChanges.length > 0 ? contextChanges : undefined,
|
|
100
|
-
conversationHistory: undefined,
|
|
101
|
-
output: output
|
|
102
|
-
};
|
|
103
|
-
};
|
|
104
|
-
const formatMarkdown = (report)=>{
|
|
105
|
-
let md = `# Protokoll - Self-Reflection Report\n\n`;
|
|
106
|
-
md += `**Generated:** ${report.generated.toISOString()}\n`;
|
|
107
|
-
md += `**Audio File:** ${report.audioFile}\n`;
|
|
108
|
-
md += `**Output:** ${report.outputFile}\n\n`;
|
|
109
|
-
md += `## Summary\n\n`;
|
|
110
|
-
md += `- **Duration**: ${(report.summary.duration / 1000).toFixed(1)}s\n`;
|
|
111
|
-
md += `- **Iterations**: ${report.summary.iterations}\n`;
|
|
112
|
-
md += `- **Tool Calls**: ${report.summary.toolCalls}\n`;
|
|
113
|
-
md += `- **Corrections**: ${report.summary.corrections}\n`;
|
|
114
|
-
md += `- **Confidence**: ${(report.summary.confidence * 100).toFixed(1)}%\n\n`;
|
|
115
|
-
md += `## Quality Assessment\n\n`;
|
|
116
|
-
md += `- **Overall Score**: ${(report.quality.overallScore * 100).toFixed(1)}%\n`;
|
|
117
|
-
md += `- **Name Accuracy**: ${(report.quality.nameAccuracy * 100).toFixed(1)}%\n`;
|
|
118
|
-
md += `- **Content Preservation**: ${(report.quality.contentPreservation * 100).toFixed(1)}%\n`;
|
|
119
|
-
md += `- **Routing Confidence**: ${(report.quality.routingConfidence * 100).toFixed(1)}%\n\n`;
|
|
120
|
-
// Routing Decision with Reasoning
|
|
121
|
-
if (report.routingDecision) {
|
|
122
|
-
const rd = report.routingDecision;
|
|
123
|
-
md += `## Routing Decision\n\n`;
|
|
124
|
-
md += `**Project**: ${rd.projectId || '(default routing)'}\n`;
|
|
125
|
-
md += `**Destination**: \`${rd.destination}\`\n`;
|
|
126
|
-
md += `**Confidence**: ${(rd.confidence * 100).toFixed(1)}%\n\n`;
|
|
127
|
-
md += `### Reasoning\n\n`;
|
|
128
|
-
md += `${rd.reasoning}\n\n`;
|
|
129
|
-
if (rd.signals && rd.signals.length > 0) {
|
|
130
|
-
md += `### Classification Signals\n\n`;
|
|
131
|
-
md += `| Signal Type | Value | Weight | Source |\n`;
|
|
132
|
-
md += `|-------------|-------|--------|--------|\n`;
|
|
133
|
-
for (const signal of rd.signals){
|
|
134
|
-
const source = signal.source || '-';
|
|
135
|
-
md += `| ${signal.type} | "${signal.value}" | ${(signal.weight * 100).toFixed(0)}% | ${source} |\n`;
|
|
136
|
-
}
|
|
137
|
-
md += '\n';
|
|
138
|
-
}
|
|
139
|
-
if (rd.alternativesConsidered && rd.alternativesConsidered.length > 0) {
|
|
140
|
-
md += `### Alternatives Considered\n\n`;
|
|
141
|
-
for (const alt of rd.alternativesConsidered){
|
|
142
|
-
md += `- **${alt.projectId}** (${(alt.confidence * 100).toFixed(1)}% confidence)\n`;
|
|
143
|
-
md += ` - Not chosen because: ${alt.whyNotChosen}\n`;
|
|
144
|
-
}
|
|
145
|
-
md += '\n';
|
|
146
|
-
}
|
|
147
|
-
if (rd.userConfirmed) {
|
|
148
|
-
md += `*User confirmed this routing decision in interactive mode.*\n\n`;
|
|
149
|
-
}
|
|
150
|
-
if (rd.feedbackProvided) {
|
|
151
|
-
md += `### Feedback Received\n\n`;
|
|
152
|
-
md += `This routing was later corrected: ${rd.feedbackCorrection}\n\n`;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
if (report.toolEffectiveness.length > 0) {
|
|
156
|
-
md += `## Tool Effectiveness\n\n`;
|
|
157
|
-
md += `| Tool | Calls | Success | Failure | Success Rate | Avg Duration |\n`;
|
|
158
|
-
md += `|------|-------|---------|---------|--------------|-------------|\n`;
|
|
159
|
-
for (const tool of report.toolEffectiveness){
|
|
160
|
-
md += `| ${tool.name} | ${tool.callCount} | ${tool.successCount} | ${tool.failureCount} | `;
|
|
161
|
-
md += `${(tool.successRate * 100).toFixed(1)}% | ${tool.avgDuration.toFixed(0)}ms |\n`;
|
|
162
|
-
}
|
|
163
|
-
md += '\n';
|
|
164
|
-
}
|
|
165
|
-
if (report.recommendations.length > 0) {
|
|
166
|
-
md += `## Recommendations\n\n`;
|
|
167
|
-
const bySeverity = {
|
|
168
|
-
high: report.recommendations.filter((r)=>r.severity === 'high'),
|
|
169
|
-
medium: report.recommendations.filter((r)=>r.severity === 'medium'),
|
|
170
|
-
low: report.recommendations.filter((r)=>r.severity === 'low')
|
|
171
|
-
};
|
|
172
|
-
if (bySeverity.high.length > 0) {
|
|
173
|
-
md += `### 🔴 High Priority\n\n`;
|
|
174
|
-
bySeverity.high.forEach((rec, i)=>{
|
|
175
|
-
md += `${i + 1}. **${rec.message}**\n`;
|
|
176
|
-
if (rec.suggestion) md += ` - ${rec.suggestion}\n`;
|
|
177
|
-
});
|
|
178
|
-
md += '\n';
|
|
179
|
-
}
|
|
180
|
-
if (bySeverity.medium.length > 0) {
|
|
181
|
-
md += `### 🟡 Medium Priority\n\n`;
|
|
182
|
-
bySeverity.medium.forEach((rec, i)=>{
|
|
183
|
-
md += `${i + 1}. **${rec.message}**\n`;
|
|
184
|
-
if (rec.suggestion) md += ` - ${rec.suggestion}\n`;
|
|
185
|
-
});
|
|
186
|
-
md += '\n';
|
|
187
|
-
}
|
|
188
|
-
if (bySeverity.low.length > 0) {
|
|
189
|
-
md += `### 🟢 Low Priority\n\n`;
|
|
190
|
-
bySeverity.low.forEach((rec, i)=>{
|
|
191
|
-
md += `${i + 1}. **${rec.message}**\n`;
|
|
192
|
-
if (rec.suggestion) md += ` - ${rec.suggestion}\n`;
|
|
193
|
-
});
|
|
194
|
-
md += '\n';
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
// Context changes section
|
|
198
|
-
if (report.contextChanges && report.contextChanges.length > 0) {
|
|
199
|
-
md += `## Context Changes\n\n`;
|
|
200
|
-
md += `The following context entries were created or updated during this session:\n\n`;
|
|
201
|
-
for (const change of report.contextChanges){
|
|
202
|
-
const emoji = change.action === 'created' ? '✨' : '📝';
|
|
203
|
-
md += `${emoji} **${change.action.charAt(0).toUpperCase() + change.action.slice(1)} ${change.entityType}**: ${change.entityName}\n`;
|
|
204
|
-
if (change.details) {
|
|
205
|
-
const details = change.details;
|
|
206
|
-
const routing = details.routing;
|
|
207
|
-
const destination = details.destination || (routing === null || routing === void 0 ? void 0 : routing.destination);
|
|
208
|
-
if (destination) {
|
|
209
|
-
md += ` - Routing to: \`${destination}\`\n`;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
md += '\n';
|
|
214
|
-
}
|
|
215
|
-
md += `---\n\n`;
|
|
216
|
-
md += `*Report generated by Protokoll Self-Reflection System*\n`;
|
|
217
|
-
return md;
|
|
218
|
-
};
|
|
219
|
-
const formatJson = (report)=>{
|
|
220
|
-
return JSON.stringify(report, null, 2);
|
|
221
|
-
};
|
|
222
|
-
const save = async (report, path)=>{
|
|
223
|
-
const content = formatMarkdown(report) ;
|
|
224
|
-
await fs.writeFile(path, content, 'utf-8');
|
|
225
|
-
logger.info('Saved reflection report', {
|
|
226
|
-
path
|
|
227
|
-
});
|
|
228
|
-
};
|
|
229
|
-
return {
|
|
230
|
-
generate,
|
|
231
|
-
formatMarkdown,
|
|
232
|
-
formatJson,
|
|
233
|
-
save
|
|
234
|
-
};
|
|
235
|
-
};
|
|
236
|
-
|
|
237
|
-
export { create };
|
|
238
|
-
//# sourceMappingURL=reporter.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"reporter.js","sources":["../../src/reflection/reporter.ts"],"sourcesContent":["/**\n * Report Generator\n *\n * Generates self-reflection reports in markdown or JSON format.\n */\n\nimport { \n ReflectionReport, \n ReflectionConfig, \n TranscriptionMetrics, \n ToolEffectiveness,\n QualityAssessment,\n Recommendation \n} from './types';\nimport * as Collector from './collector';\nimport * as fs from 'fs/promises';\nimport * as Logging from '../logging';\n\nexport interface ReporterInstance {\n generate(\n collector: Collector.CollectorInstance,\n audioFile: string,\n outputFile: string,\n conversationHistory?: unknown[],\n output?: string\n ): ReflectionReport;\n \n formatMarkdown(report: ReflectionReport): string;\n formatJson(report: ReflectionReport): string;\n save(report: ReflectionReport, path: string): Promise<void>;\n}\n\nexport const create = (config: ReflectionConfig): ReporterInstance => {\n const logger = Logging.getLogger();\n \n const assessQuality = (\n metrics: TranscriptionMetrics,\n toolEffectiveness: ToolEffectiveness[]\n ): QualityAssessment => {\n // Calculate name accuracy based on resolution rate\n const nameAccuracy = metrics.unknownEntitiesFound > 0\n ? metrics.entitiesResolved / metrics.unknownEntitiesFound\n : 1.0;\n \n // Content preservation (should be close to 1.0)\n const contentPreservation = metrics.originalLength > 0\n ? Math.min(metrics.correctedLength / metrics.originalLength, 1.0)\n : 1.0;\n \n // Tool success rate\n const avgToolSuccess = toolEffectiveness.length > 0\n ? toolEffectiveness.reduce((sum, t) => sum + t.successRate, 0) / toolEffectiveness.length\n : 1.0;\n \n // Overall confidence\n const confidence = (nameAccuracy * 0.4) + (contentPreservation * 0.3) + (avgToolSuccess * 0.3);\n \n return {\n confidence,\n nameAccuracy,\n routingConfidence: 0.9, // Would be calculated from routing decision\n contentPreservation,\n overallScore: confidence,\n };\n };\n \n const generateRecommendations = (\n metrics: TranscriptionMetrics,\n toolEffectiveness: ToolEffectiveness[],\n quality: QualityAssessment\n ): Recommendation[] => {\n const recommendations: Recommendation[] = [];\n \n // Check for tool failures\n const failedTools = toolEffectiveness.filter(t => t.successRate < 0.8);\n if (failedTools.length > 0) {\n recommendations.push({\n type: 'tool-issue',\n severity: 'high',\n message: `${failedTools.length} tool(s) had low success rates`,\n suggestion: `Review tool implementations: ${failedTools.map(t => t.name).join(', ')}`,\n });\n }\n \n // Check for unresolved entities\n if (metrics.unknownEntitiesFound > metrics.entitiesResolved) {\n const unresolved = metrics.unknownEntitiesFound - metrics.entitiesResolved;\n recommendations.push({\n type: 'context-gap',\n severity: 'medium',\n message: `${unresolved} entities could not be resolved`,\n suggestion: 'Run in interactive mode to add new context entries',\n });\n }\n \n // Check for high iteration count (real issue is usually unclear routing)\n if (metrics.iterations > 10) {\n recommendations.push({\n type: 'context-gap',\n severity: 'medium',\n message: `High iteration count (${metrics.iterations}) - model may be struggling to route this note`,\n suggestion: 'Add explicit trigger phrases to your project context files (e.g., \"update on [project]\")',\n });\n }\n \n // Only flag extremely long processing (> 5 minutes) as potential issue\n // Normal reasoning with gpt-5.2 can take 1-3 minutes and that's fine\n if (metrics.totalDuration > 300000) { // > 5 minutes\n recommendations.push({\n type: 'performance',\n severity: 'low',\n message: `Processing took ${(metrics.totalDuration / 1000).toFixed(1)}s`,\n suggestion: 'Consider reviewing context files - unclear routing can cause excessive iterations',\n });\n }\n \n // Check content preservation\n if (quality.contentPreservation < 0.9) {\n recommendations.push({\n type: 'quality',\n severity: 'high',\n message: 'Significant content may have been lost',\n suggestion: 'Review prompt to ensure full content preservation',\n });\n }\n \n return recommendations;\n };\n \n const generate = (\n collector: Collector.CollectorInstance,\n audioFile: string,\n outputFile: string,\n conversationHistory?: unknown[],\n output?: string\n ): ReflectionReport => {\n const metrics = collector.getMetrics();\n const toolEffectiveness = collector.getToolEffectiveness();\n const contextChanges = collector.getContextChanges();\n const routingDecision = collector.getRoutingDecision();\n const quality = assessQuality(metrics, toolEffectiveness);\n const recommendations = generateRecommendations(metrics, toolEffectiveness, quality);\n \n return {\n id: `reflection-${Date.now()}`,\n generated: new Date(),\n audioFile,\n outputFile,\n summary: {\n duration: metrics.totalDuration,\n iterations: metrics.iterations,\n toolCalls: metrics.toolCallsExecuted,\n corrections: metrics.correctionsApplied,\n confidence: quality.confidence,\n },\n metrics,\n toolEffectiveness,\n quality,\n recommendations,\n routingDecision,\n contextChanges: contextChanges.length > 0 ? contextChanges : undefined,\n conversationHistory: config.includeConversation ? conversationHistory : undefined,\n output: config.includeOutput ? output : undefined,\n };\n };\n \n const formatMarkdown = (report: ReflectionReport): string => {\n let md = `# Protokoll - Self-Reflection Report\\n\\n`;\n md += `**Generated:** ${report.generated.toISOString()}\\n`;\n md += `**Audio File:** ${report.audioFile}\\n`;\n md += `**Output:** ${report.outputFile}\\n\\n`;\n \n md += `## Summary\\n\\n`;\n md += `- **Duration**: ${(report.summary.duration / 1000).toFixed(1)}s\\n`;\n md += `- **Iterations**: ${report.summary.iterations}\\n`;\n md += `- **Tool Calls**: ${report.summary.toolCalls}\\n`;\n md += `- **Corrections**: ${report.summary.corrections}\\n`;\n md += `- **Confidence**: ${(report.summary.confidence * 100).toFixed(1)}%\\n\\n`;\n \n md += `## Quality Assessment\\n\\n`;\n md += `- **Overall Score**: ${(report.quality.overallScore * 100).toFixed(1)}%\\n`;\n md += `- **Name Accuracy**: ${(report.quality.nameAccuracy * 100).toFixed(1)}%\\n`;\n md += `- **Content Preservation**: ${(report.quality.contentPreservation * 100).toFixed(1)}%\\n`;\n md += `- **Routing Confidence**: ${(report.quality.routingConfidence * 100).toFixed(1)}%\\n\\n`;\n \n // Routing Decision with Reasoning\n if (report.routingDecision) {\n const rd = report.routingDecision;\n md += `## Routing Decision\\n\\n`;\n md += `**Project**: ${rd.projectId || '(default routing)'}\\n`;\n md += `**Destination**: \\`${rd.destination}\\`\\n`;\n md += `**Confidence**: ${(rd.confidence * 100).toFixed(1)}%\\n\\n`;\n \n md += `### Reasoning\\n\\n`;\n md += `${rd.reasoning}\\n\\n`;\n \n if (rd.signals && rd.signals.length > 0) {\n md += `### Classification Signals\\n\\n`;\n md += `| Signal Type | Value | Weight | Source |\\n`;\n md += `|-------------|-------|--------|--------|\\n`;\n for (const signal of rd.signals) {\n const source = signal.source || '-';\n md += `| ${signal.type} | \"${signal.value}\" | ${(signal.weight * 100).toFixed(0)}% | ${source} |\\n`;\n }\n md += '\\n';\n }\n \n if (rd.alternativesConsidered && rd.alternativesConsidered.length > 0) {\n md += `### Alternatives Considered\\n\\n`;\n for (const alt of rd.alternativesConsidered) {\n md += `- **${alt.projectId}** (${(alt.confidence * 100).toFixed(1)}% confidence)\\n`;\n md += ` - Not chosen because: ${alt.whyNotChosen}\\n`;\n }\n md += '\\n';\n }\n \n if (rd.userConfirmed) {\n md += `*User confirmed this routing decision in interactive mode.*\\n\\n`;\n }\n \n if (rd.feedbackProvided) {\n md += `### Feedback Received\\n\\n`;\n md += `This routing was later corrected: ${rd.feedbackCorrection}\\n\\n`;\n }\n }\n \n if (report.toolEffectiveness.length > 0) {\n md += `## Tool Effectiveness\\n\\n`;\n md += `| Tool | Calls | Success | Failure | Success Rate | Avg Duration |\\n`;\n md += `|------|-------|---------|---------|--------------|-------------|\\n`;\n \n for (const tool of report.toolEffectiveness) {\n md += `| ${tool.name} | ${tool.callCount} | ${tool.successCount} | ${tool.failureCount} | `;\n md += `${(tool.successRate * 100).toFixed(1)}% | ${tool.avgDuration.toFixed(0)}ms |\\n`;\n }\n md += '\\n';\n }\n \n if (report.recommendations.length > 0) {\n md += `## Recommendations\\n\\n`;\n \n const bySeverity = {\n high: report.recommendations.filter(r => r.severity === 'high'),\n medium: report.recommendations.filter(r => r.severity === 'medium'),\n low: report.recommendations.filter(r => r.severity === 'low'),\n };\n \n if (bySeverity.high.length > 0) {\n md += `### 🔴 High Priority\\n\\n`;\n bySeverity.high.forEach((rec, i) => {\n md += `${i + 1}. **${rec.message}**\\n`;\n if (rec.suggestion) md += ` - ${rec.suggestion}\\n`;\n });\n md += '\\n';\n }\n \n if (bySeverity.medium.length > 0) {\n md += `### 🟡 Medium Priority\\n\\n`;\n bySeverity.medium.forEach((rec, i) => {\n md += `${i + 1}. **${rec.message}**\\n`;\n if (rec.suggestion) md += ` - ${rec.suggestion}\\n`;\n });\n md += '\\n';\n }\n \n if (bySeverity.low.length > 0) {\n md += `### 🟢 Low Priority\\n\\n`;\n bySeverity.low.forEach((rec, i) => {\n md += `${i + 1}. **${rec.message}**\\n`;\n if (rec.suggestion) md += ` - ${rec.suggestion}\\n`;\n });\n md += '\\n';\n }\n }\n \n // Context changes section\n if (report.contextChanges && report.contextChanges.length > 0) {\n md += `## Context Changes\\n\\n`;\n md += `The following context entries were created or updated during this session:\\n\\n`;\n \n for (const change of report.contextChanges) {\n const emoji = change.action === 'created' ? '✨' : '📝';\n md += `${emoji} **${change.action.charAt(0).toUpperCase() + change.action.slice(1)} ${change.entityType}**: ${change.entityName}\\n`;\n if (change.details) {\n const details = change.details as Record<string, unknown>;\n const routing = details.routing as Record<string, unknown> | undefined;\n const destination = details.destination || routing?.destination;\n if (destination) {\n md += ` - Routing to: \\`${destination}\\`\\n`;\n }\n }\n }\n md += '\\n';\n }\n \n md += `---\\n\\n`;\n md += `*Report generated by Protokoll Self-Reflection System*\\n`;\n \n return md;\n };\n \n const formatJson = (report: ReflectionReport): string => {\n return JSON.stringify(report, null, 2);\n };\n \n const save = async (report: ReflectionReport, path: string): Promise<void> => {\n const content = config.format === 'markdown' \n ? formatMarkdown(report)\n : formatJson(report);\n \n await fs.writeFile(path, content, 'utf-8');\n logger.info('Saved reflection report', { path });\n };\n \n return {\n generate,\n formatMarkdown,\n formatJson,\n save,\n };\n};\n\n"],"names":["create","config","logger","Logging","assessQuality","metrics","toolEffectiveness","nameAccuracy","unknownEntitiesFound","entitiesResolved","contentPreservation","originalLength","Math","min","correctedLength","avgToolSuccess","length","reduce","sum","t","successRate","confidence","routingConfidence","overallScore","generateRecommendations","quality","recommendations","failedTools","filter","push","type","severity","message","suggestion","map","name","join","unresolved","iterations","totalDuration","toFixed","generate","collector","audioFile","outputFile","conversationHistory","output","getMetrics","getToolEffectiveness","contextChanges","getContextChanges","routingDecision","getRoutingDecision","id","Date","now","generated","summary","duration","toolCalls","toolCallsExecuted","corrections","correctionsApplied","undefined","formatMarkdown","report","md","toISOString","rd","projectId","destination","reasoning","signals","signal","source","value","weight","alternativesConsidered","alt","whyNotChosen","userConfirmed","feedbackProvided","feedbackCorrection","tool","callCount","successCount","failureCount","avgDuration","bySeverity","high","r","medium","low","forEach","rec","i","change","emoji","action","charAt","toUpperCase","slice","entityType","entityName","details","routing","formatJson","JSON","stringify","save","path","content","fs","writeFile","info"],"mappings":"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"}
|
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Intelligent Classifier
|
|
3
|
-
*
|
|
4
|
-
* Multi-signal classification system for routing transcripts to projects.
|
|
5
|
-
* Uses various signals (explicit phrases, associated people/companies, topics)
|
|
6
|
-
* to determine the best project match with confidence scoring.
|
|
7
|
-
*
|
|
8
|
-
* Design Note: This module is designed to be self-contained and may be
|
|
9
|
-
* extracted for use in other tools (kronologi, observasjon) in the future.
|
|
10
|
-
*/ const create = (contextInstance)=>{
|
|
11
|
-
const classify = (routingContext, routes)=>{
|
|
12
|
-
const results = [];
|
|
13
|
-
const normalizedText = routingContext.transcriptText.toLowerCase();
|
|
14
|
-
for (const route of routes){
|
|
15
|
-
var _classification_explicit_phrases, _routingContext_detectedPeople, _classification_associated_people, _routingContext_detectedCompanies, _classification_associated_companies, _classification_topics;
|
|
16
|
-
if (route.active === false) continue;
|
|
17
|
-
const signals = [];
|
|
18
|
-
const classification = route.classification;
|
|
19
|
-
// 1. Check explicit phrases (highest weight)
|
|
20
|
-
for (const phrase of (_classification_explicit_phrases = classification.explicit_phrases) !== null && _classification_explicit_phrases !== void 0 ? _classification_explicit_phrases : []){
|
|
21
|
-
if (normalizedText.includes(phrase.toLowerCase())) {
|
|
22
|
-
signals.push({
|
|
23
|
-
type: 'explicit_phrase',
|
|
24
|
-
value: phrase,
|
|
25
|
-
weight: 0.9
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
// 2. Check associated people
|
|
30
|
-
const peopleInText = (_routingContext_detectedPeople = routingContext.detectedPeople) !== null && _routingContext_detectedPeople !== void 0 ? _routingContext_detectedPeople : detectPeopleFromContext(normalizedText, contextInstance);
|
|
31
|
-
for (const personId of (_classification_associated_people = classification.associated_people) !== null && _classification_associated_people !== void 0 ? _classification_associated_people : []){
|
|
32
|
-
if (peopleInText.includes(personId)) {
|
|
33
|
-
var _ref;
|
|
34
|
-
const person = contextInstance.getPerson(personId);
|
|
35
|
-
signals.push({
|
|
36
|
-
type: 'associated_person',
|
|
37
|
-
value: (_ref = person === null || person === void 0 ? void 0 : person.name) !== null && _ref !== void 0 ? _ref : personId,
|
|
38
|
-
weight: 0.6
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
// 3. Check associated companies
|
|
43
|
-
const companiesInText = (_routingContext_detectedCompanies = routingContext.detectedCompanies) !== null && _routingContext_detectedCompanies !== void 0 ? _routingContext_detectedCompanies : detectCompaniesFromContext(normalizedText, contextInstance);
|
|
44
|
-
for (const companyId of (_classification_associated_companies = classification.associated_companies) !== null && _classification_associated_companies !== void 0 ? _classification_associated_companies : []){
|
|
45
|
-
if (companiesInText.includes(companyId)) {
|
|
46
|
-
var _ref1;
|
|
47
|
-
const company = contextInstance.getCompany(companyId);
|
|
48
|
-
signals.push({
|
|
49
|
-
type: 'associated_company',
|
|
50
|
-
value: (_ref1 = company === null || company === void 0 ? void 0 : company.name) !== null && _ref1 !== void 0 ? _ref1 : companyId,
|
|
51
|
-
weight: 0.5
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
// 4. Check topics
|
|
56
|
-
for (const topic of (_classification_topics = classification.topics) !== null && _classification_topics !== void 0 ? _classification_topics : []){
|
|
57
|
-
if (normalizedText.includes(topic.toLowerCase())) {
|
|
58
|
-
signals.push({
|
|
59
|
-
type: 'topic',
|
|
60
|
-
value: topic,
|
|
61
|
-
weight: 0.3
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
// 5. Context type (if we can infer work vs personal)
|
|
66
|
-
// This is a weaker signal but helps with disambiguation
|
|
67
|
-
const inferredContextType = inferContextType(normalizedText);
|
|
68
|
-
if (inferredContextType === classification.context_type) {
|
|
69
|
-
signals.push({
|
|
70
|
-
type: 'context_type',
|
|
71
|
-
value: classification.context_type,
|
|
72
|
-
weight: 0.2
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
// Only include if we have at least one signal
|
|
76
|
-
if (signals.length > 0) {
|
|
77
|
-
const confidence = calculateConfidence(signals);
|
|
78
|
-
results.push({
|
|
79
|
-
projectId: route.projectId,
|
|
80
|
-
confidence,
|
|
81
|
-
signals,
|
|
82
|
-
reasoning: buildReasoning(signals)
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
// Sort by confidence descending
|
|
87
|
-
return results.sort((a, b)=>b.confidence - a.confidence);
|
|
88
|
-
};
|
|
89
|
-
const calculateConfidence = (signals)=>{
|
|
90
|
-
if (signals.length === 0) return 0;
|
|
91
|
-
// Weighted average with diminishing returns for multiple signals
|
|
92
|
-
let totalWeight = 0;
|
|
93
|
-
let weightedSum = 0;
|
|
94
|
-
for(let i = 0; i < signals.length; i++){
|
|
95
|
-
const signal = signals[i];
|
|
96
|
-
// Later signals contribute less (diminishing returns)
|
|
97
|
-
const positionFactor = 1 / (1 + i * 0.3);
|
|
98
|
-
const effectiveWeight = signal.weight * positionFactor;
|
|
99
|
-
weightedSum += effectiveWeight;
|
|
100
|
-
totalWeight += positionFactor;
|
|
101
|
-
}
|
|
102
|
-
// Normalize and cap at 0.99
|
|
103
|
-
return Math.min(weightedSum / Math.max(totalWeight, 1), 0.99);
|
|
104
|
-
};
|
|
105
|
-
const buildReasoning = (signals)=>{
|
|
106
|
-
const parts = signals.map((s)=>{
|
|
107
|
-
switch(s.type){
|
|
108
|
-
case 'explicit_phrase':
|
|
109
|
-
return `explicit phrase: "${s.value}"`;
|
|
110
|
-
case 'associated_person':
|
|
111
|
-
return `mentioned ${s.value} (associated)`;
|
|
112
|
-
case 'associated_company':
|
|
113
|
-
return `mentioned ${s.value} (associated company)`;
|
|
114
|
-
case 'topic':
|
|
115
|
-
return `topic: ${s.value}`;
|
|
116
|
-
case 'context_type':
|
|
117
|
-
return `context: ${s.value}`;
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
return parts.join(', ');
|
|
121
|
-
};
|
|
122
|
-
return {
|
|
123
|
-
classify,
|
|
124
|
-
calculateConfidence
|
|
125
|
-
};
|
|
126
|
-
};
|
|
127
|
-
// Helper functions
|
|
128
|
-
function detectPeopleFromContext(text, context) {
|
|
129
|
-
const found = [];
|
|
130
|
-
for (const person of context.getAllPeople()){
|
|
131
|
-
var _person_sounds_like;
|
|
132
|
-
const nameNormalized = person.name.toLowerCase();
|
|
133
|
-
if (text.includes(nameNormalized)) {
|
|
134
|
-
found.push(person.id);
|
|
135
|
-
continue;
|
|
136
|
-
}
|
|
137
|
-
// Check phonetic variants (sounds_like)
|
|
138
|
-
for (const variant of (_person_sounds_like = person.sounds_like) !== null && _person_sounds_like !== void 0 ? _person_sounds_like : []){
|
|
139
|
-
if (text.includes(variant.toLowerCase())) {
|
|
140
|
-
found.push(person.id);
|
|
141
|
-
break;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
return found;
|
|
146
|
-
}
|
|
147
|
-
function detectCompaniesFromContext(text, context) {
|
|
148
|
-
const found = [];
|
|
149
|
-
for (const company of context.getAllCompanies()){
|
|
150
|
-
var _company_sounds_like;
|
|
151
|
-
const nameNormalized = company.name.toLowerCase();
|
|
152
|
-
if (text.includes(nameNormalized)) {
|
|
153
|
-
found.push(company.id);
|
|
154
|
-
continue;
|
|
155
|
-
}
|
|
156
|
-
// Check full name
|
|
157
|
-
if (company.fullName && text.includes(company.fullName.toLowerCase())) {
|
|
158
|
-
found.push(company.id);
|
|
159
|
-
continue;
|
|
160
|
-
}
|
|
161
|
-
// Check phonetic variants (sounds_like)
|
|
162
|
-
for (const variant of (_company_sounds_like = company.sounds_like) !== null && _company_sounds_like !== void 0 ? _company_sounds_like : []){
|
|
163
|
-
if (text.includes(variant.toLowerCase())) {
|
|
164
|
-
found.push(company.id);
|
|
165
|
-
break;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
return found;
|
|
170
|
-
}
|
|
171
|
-
function inferContextType(text) {
|
|
172
|
-
const workIndicators = [
|
|
173
|
-
'meeting',
|
|
174
|
-
'project',
|
|
175
|
-
'deadline',
|
|
176
|
-
'team',
|
|
177
|
-
'client',
|
|
178
|
-
'report'
|
|
179
|
-
];
|
|
180
|
-
const personalIndicators = [
|
|
181
|
-
'family',
|
|
182
|
-
'weekend',
|
|
183
|
-
'vacation',
|
|
184
|
-
'hobby',
|
|
185
|
-
'friend'
|
|
186
|
-
];
|
|
187
|
-
let workScore = 0;
|
|
188
|
-
let personalScore = 0;
|
|
189
|
-
for (const word of workIndicators){
|
|
190
|
-
if (text.includes(word)) workScore++;
|
|
191
|
-
}
|
|
192
|
-
for (const word of personalIndicators){
|
|
193
|
-
if (text.includes(word)) personalScore++;
|
|
194
|
-
}
|
|
195
|
-
if (workScore > personalScore + 1) return 'work';
|
|
196
|
-
if (personalScore > workScore + 1) return 'personal';
|
|
197
|
-
return 'mixed';
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
export { create };
|
|
201
|
-
//# sourceMappingURL=classifier.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"classifier.js","sources":["../../src/routing/classifier.ts"],"sourcesContent":["/**\n * Intelligent Classifier\n * \n * Multi-signal classification system for routing transcripts to projects.\n * Uses various signals (explicit phrases, associated people/companies, topics)\n * to determine the best project match with confidence scoring.\n * \n * Design Note: This module is designed to be self-contained and may be\n * extracted for use in other tools (kronologi, observasjon) in the future.\n */\n\nimport { \n ClassificationResult, \n ClassificationSignal, \n ProjectRoute, \n RoutingContext \n} from './types';\nimport * as Context from '../context';\n\nexport interface ClassifierInstance {\n classify(context: RoutingContext, routes: ProjectRoute[]): ClassificationResult[];\n calculateConfidence(signals: ClassificationSignal[]): number;\n}\n\nexport const create = (contextInstance: Context.ContextInstance): ClassifierInstance => {\n \n const classify = (\n routingContext: RoutingContext, \n routes: ProjectRoute[]\n ): ClassificationResult[] => {\n const results: ClassificationResult[] = [];\n const normalizedText = routingContext.transcriptText.toLowerCase();\n \n for (const route of routes) {\n if (route.active === false) continue;\n \n const signals: ClassificationSignal[] = [];\n const classification = route.classification;\n \n // 1. Check explicit phrases (highest weight)\n for (const phrase of classification.explicit_phrases ?? []) {\n if (normalizedText.includes(phrase.toLowerCase())) {\n signals.push({\n type: 'explicit_phrase',\n value: phrase,\n weight: 0.9, // High confidence\n });\n }\n }\n \n // 2. Check associated people\n const peopleInText = routingContext.detectedPeople ?? \n detectPeopleFromContext(normalizedText, contextInstance);\n \n for (const personId of classification.associated_people ?? []) {\n if (peopleInText.includes(personId)) {\n const person = contextInstance.getPerson(personId);\n signals.push({\n type: 'associated_person',\n value: person?.name ?? personId,\n weight: 0.6,\n });\n }\n }\n \n // 3. Check associated companies\n const companiesInText = routingContext.detectedCompanies ?? \n detectCompaniesFromContext(normalizedText, contextInstance);\n \n for (const companyId of classification.associated_companies ?? []) {\n if (companiesInText.includes(companyId)) {\n const company = contextInstance.getCompany(companyId);\n signals.push({\n type: 'associated_company',\n value: company?.name ?? companyId,\n weight: 0.5,\n });\n }\n }\n \n // 4. Check topics\n for (const topic of classification.topics ?? []) {\n if (normalizedText.includes(topic.toLowerCase())) {\n signals.push({\n type: 'topic',\n value: topic,\n weight: 0.3,\n });\n }\n }\n \n // 5. Context type (if we can infer work vs personal)\n // This is a weaker signal but helps with disambiguation\n const inferredContextType = inferContextType(normalizedText);\n if (inferredContextType === classification.context_type) {\n signals.push({\n type: 'context_type',\n value: classification.context_type,\n weight: 0.2,\n });\n }\n \n // Only include if we have at least one signal\n if (signals.length > 0) {\n const confidence = calculateConfidence(signals);\n results.push({\n projectId: route.projectId,\n confidence,\n signals,\n reasoning: buildReasoning(signals),\n });\n }\n }\n \n // Sort by confidence descending\n return results.sort((a, b) => b.confidence - a.confidence);\n };\n \n const calculateConfidence = (signals: ClassificationSignal[]): number => {\n if (signals.length === 0) return 0;\n \n // Weighted average with diminishing returns for multiple signals\n let totalWeight = 0;\n let weightedSum = 0;\n \n for (let i = 0; i < signals.length; i++) {\n const signal = signals[i];\n // Later signals contribute less (diminishing returns)\n const positionFactor = 1 / (1 + i * 0.3);\n const effectiveWeight = signal.weight * positionFactor;\n \n weightedSum += effectiveWeight;\n totalWeight += positionFactor;\n }\n \n // Normalize and cap at 0.99\n return Math.min(weightedSum / Math.max(totalWeight, 1), 0.99);\n };\n \n const buildReasoning = (signals: ClassificationSignal[]): string => {\n const parts = signals.map(s => {\n switch (s.type) {\n case 'explicit_phrase': return `explicit phrase: \"${s.value}\"`;\n case 'associated_person': return `mentioned ${s.value} (associated)`;\n case 'associated_company': return `mentioned ${s.value} (associated company)`;\n case 'topic': return `topic: ${s.value}`;\n case 'context_type': return `context: ${s.value}`;\n }\n });\n return parts.join(', ');\n };\n \n return { classify, calculateConfidence };\n};\n\n// Helper functions\nfunction detectPeopleFromContext(\n text: string, \n context: Context.ContextInstance\n): string[] {\n const found: string[] = [];\n \n for (const person of context.getAllPeople()) {\n const nameNormalized = person.name.toLowerCase();\n if (text.includes(nameNormalized)) {\n found.push(person.id);\n continue;\n }\n \n // Check phonetic variants (sounds_like)\n for (const variant of person.sounds_like ?? []) {\n if (text.includes(variant.toLowerCase())) {\n found.push(person.id);\n break;\n }\n }\n }\n \n return found;\n}\n\nfunction detectCompaniesFromContext(\n text: string, \n context: Context.ContextInstance\n): string[] {\n const found: string[] = [];\n \n for (const company of context.getAllCompanies()) {\n const nameNormalized = company.name.toLowerCase();\n if (text.includes(nameNormalized)) {\n found.push(company.id);\n continue;\n }\n \n // Check full name\n if (company.fullName && text.includes(company.fullName.toLowerCase())) {\n found.push(company.id);\n continue;\n }\n \n // Check phonetic variants (sounds_like)\n for (const variant of company.sounds_like ?? []) {\n if (text.includes(variant.toLowerCase())) {\n found.push(company.id);\n break;\n }\n }\n }\n \n return found;\n}\n\nfunction inferContextType(text: string): 'work' | 'personal' | 'mixed' {\n const workIndicators = ['meeting', 'project', 'deadline', 'team', 'client', 'report'];\n const personalIndicators = ['family', 'weekend', 'vacation', 'hobby', 'friend'];\n \n let workScore = 0;\n let personalScore = 0;\n \n for (const word of workIndicators) {\n if (text.includes(word)) workScore++;\n }\n \n for (const word of personalIndicators) {\n if (text.includes(word)) personalScore++;\n }\n \n if (workScore > personalScore + 1) return 'work';\n if (personalScore > workScore + 1) return 'personal';\n return 'mixed';\n}\n\n"],"names":["create","contextInstance","classify","routingContext","routes","results","normalizedText","transcriptText","toLowerCase","route","classification","active","signals","phrase","explicit_phrases","includes","push","type","value","weight","peopleInText","detectedPeople","detectPeopleFromContext","personId","associated_people","person","getPerson","name","companiesInText","detectedCompanies","detectCompaniesFromContext","companyId","associated_companies","company","getCompany","topic","topics","inferredContextType","inferContextType","context_type","length","confidence","calculateConfidence","projectId","reasoning","buildReasoning","sort","a","b","totalWeight","weightedSum","i","signal","positionFactor","effectiveWeight","Math","min","max","parts","map","s","join","text","context","found","getAllPeople","nameNormalized","id","variant","sounds_like","getAllCompanies","fullName","workIndicators","personalIndicators","workScore","personalScore","word"],"mappings":"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"}
|
package/dist/routing/index.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { create as create$1 } from './router.js';
|
|
2
|
-
import { create as create$2 } from './classifier.js';
|
|
3
|
-
|
|
4
|
-
const create = (config, context)=>{
|
|
5
|
-
const classifier = create$2(context);
|
|
6
|
-
const router = create$1(config, classifier);
|
|
7
|
-
// Mutable config for self-update feature
|
|
8
|
-
const currentConfig = {
|
|
9
|
-
...config
|
|
10
|
-
};
|
|
11
|
-
return {
|
|
12
|
-
route: (ctx)=>router.route(ctx),
|
|
13
|
-
buildOutputPath: (decision, ctx)=>router.buildOutputPath(decision, ctx),
|
|
14
|
-
addProject: (project)=>{
|
|
15
|
-
currentConfig.projects.push(project);
|
|
16
|
-
},
|
|
17
|
-
updateDefaultRoute: (destination)=>{
|
|
18
|
-
currentConfig.default = destination;
|
|
19
|
-
},
|
|
20
|
-
getConfig: ()=>({
|
|
21
|
-
...currentConfig
|
|
22
|
-
})
|
|
23
|
-
};
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export { create };
|
|
27
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/routing/index.ts"],"sourcesContent":["/**\n * Routing System\n * \n * Main entry point for the routing system. Provides a factory function\n * to create routing instances that can classify transcripts and determine\n * output destinations using Dreadcabinet patterns.\n * \n * Design Note: This module is designed to be self-contained and may be\n * extracted for use in other tools (kronologi, observasjon) in the future.\n */\n\nimport { RoutingConfig, RouteDecision, RoutingContext, RouteDestination, ProjectRoute } from './types';\nimport * as Router from './router';\nimport * as Classifier from './classifier';\nimport * as Context from '../context';\n\nexport interface RoutingInstance {\n route(context: RoutingContext): RouteDecision;\n buildOutputPath(decision: RouteDecision, context: RoutingContext): string;\n addProject(project: ProjectRoute): void;\n updateDefaultRoute(destination: RouteDestination): void;\n getConfig(): RoutingConfig;\n}\n\nexport const create = (\n config: RoutingConfig,\n context: Context.ContextInstance\n): RoutingInstance => {\n const classifier = Classifier.create(context);\n const router = Router.create(config, classifier);\n \n // Mutable config for self-update feature\n const currentConfig = { ...config };\n \n return {\n route: (ctx) => router.route(ctx),\n buildOutputPath: (decision, ctx) => router.buildOutputPath(decision, ctx),\n \n addProject: (project) => {\n currentConfig.projects.push(project);\n },\n \n updateDefaultRoute: (destination) => {\n currentConfig.default = destination;\n },\n \n getConfig: () => ({ ...currentConfig }),\n };\n};\n\n// Re-export types\nexport * from './types';\n\n"],"names":["create","config","context","classifier","Classifier","router","Router","currentConfig","route","ctx","buildOutputPath","decision","addProject","project","projects","push","updateDefaultRoute","destination","default","getConfig"],"mappings":";;;AAwBO,MAAMA,MAAAA,GAAS,CAClBC,MAAAA,EACAC,OAAAA,GAAAA;IAEA,MAAMC,UAAAA,GAAaC,QAAiB,CAACF,OAAAA,CAAAA;AACrC,IAAA,MAAMG,MAAAA,GAASC,QAAa,CAACL,MAAAA,EAAQE,UAAAA,CAAAA;;AAGrC,IAAA,MAAMI,aAAAA,GAAgB;AAAE,QAAA,GAAGN;AAAO,KAAA;IAElC,OAAO;AACHO,QAAAA,KAAAA,EAAO,CAACC,GAAAA,GAAQJ,MAAAA,CAAOG,KAAK,CAACC,GAAAA,CAAAA;AAC7BC,QAAAA,eAAAA,EAAiB,CAACC,QAAAA,EAAUF,GAAAA,GAAQJ,MAAAA,CAAOK,eAAe,CAACC,QAAAA,EAAUF,GAAAA,CAAAA;AAErEG,QAAAA,UAAAA,EAAY,CAACC,OAAAA,GAAAA;YACTN,aAAAA,CAAcO,QAAQ,CAACC,IAAI,CAACF,OAAAA,CAAAA;AAChC,QAAA,CAAA;AAEAG,QAAAA,kBAAAA,EAAoB,CAACC,WAAAA,GAAAA;AACjBV,YAAAA,aAAAA,CAAcW,OAAO,GAAGD,WAAAA;AAC5B,QAAA,CAAA;AAEAE,QAAAA,SAAAA,EAAW,KAAO;AAAE,gBAAA,GAAGZ;aAAc;AACzC,KAAA;AACJ;;;;"}
|