@redaksjon/protokoll-engine 0.1.12 → 0.1.13-dev.20260303161030.b4a6c26

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.
@@ -1 +1 @@
1
- {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/agentic/executor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAoB,WAAW,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAE5E,OAAO,KAAK,SAAS,MAAM,cAAc,CAAC;AAK1C,MAAM,WAAW,mBAAmB;IAChC,UAAU,EAAE,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,SAAS,GAAG,SAAS,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,gBAAgB;IAC7B,OAAO,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC;QACrC,YAAY,EAAE,MAAM,CAAC;QACrB,KAAK,EAAE,kBAAkB,CAAC;QAC1B,SAAS,EAAE,MAAM,EAAE,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,mBAAmB,EAAE,CAAC;KAC1C,CAAC,CAAC;CACN;AAgGD,eAAO,MAAM,MAAM,GACf,WAAW,SAAS,CAAC,iBAAiB,EACtC,KAAK,WAAW,KACjB,gBA89BF,CAAC"}
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/agentic/executor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAIH,WAAW,EACX,kBAAkB,EACrB,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,SAAS,MAAM,cAAc,CAAC;AAK1C,MAAM,WAAW,mBAAmB;IAChC,UAAU,EAAE,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,SAAS,GAAG,SAAS,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,gBAAgB;IAC7B,OAAO,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC;QACrC,YAAY,EAAE,MAAM,CAAC;QACrB,KAAK,EAAE,kBAAkB,CAAC;QAC1B,SAAS,EAAE,MAAM,EAAE,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,mBAAmB,EAAE,CAAC;KAC1C,CAAC,CAAC;CACN;AAgGD,eAAO,MAAM,MAAM,GACf,WAAW,SAAS,CAAC,iBAAiB,EACtC,KAAK,WAAW,KACjB,gBAghCF,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ import { ToolCall, ToolDefinition } from '../reasoning/types';
2
3
  import { WeightModelProvider } from '../weighting/provider';
3
4
  import * as Context from '@redaksjon/context';
4
5
  import * as Routing from '../routing';
@@ -84,6 +85,39 @@ export interface ToolCallLogEntry {
84
85
  success: boolean;
85
86
  timestamp: Date;
86
87
  }
88
+ /**
89
+ * Record of a single model call made during enhancement
90
+ */
91
+ export interface ModelCallStartLogEntry {
92
+ callIndex: number;
93
+ phase: 'initial' | 'continuation' | 'final';
94
+ request: {
95
+ model?: string;
96
+ reasoningLevel?: string;
97
+ prompt: string;
98
+ systemPrompt?: string;
99
+ maxIterations?: number;
100
+ tools?: ToolDefinition[];
101
+ };
102
+ timestamp: Date;
103
+ }
104
+ export interface ModelCallCompleteLogEntry {
105
+ callIndex: number;
106
+ phase: 'initial' | 'continuation' | 'final';
107
+ durationMs: number;
108
+ response: {
109
+ model?: string;
110
+ finishReason?: string;
111
+ usage?: {
112
+ promptTokens: number;
113
+ completionTokens: number;
114
+ totalTokens: number;
115
+ };
116
+ toolCalls?: ToolCall[];
117
+ contentLength: number;
118
+ };
119
+ timestamp: Date;
120
+ }
87
121
  export interface ToolContext {
88
122
  transcriptText: string;
89
123
  audioDate: Date;
@@ -98,6 +132,15 @@ export interface ToolContext {
98
132
  onToolCallStart?: (tool: string, input: Record<string, unknown>) => void;
99
133
  /** Optional: called after a tool completes — enables incremental log writes */
100
134
  onToolCallComplete?: (entry: ToolCallLogEntry) => void;
135
+ /** Optional: called just before each model call to capture request payload details */
136
+ onModelCallStart?: (entry: ModelCallStartLogEntry) => void;
137
+ /** Optional: called after each model call to capture usage/details */
138
+ onModelCallComplete?: (entry: ModelCallCompleteLogEntry) => void;
139
+ /** Optional: model metadata for observability in enhancement logs */
140
+ modelConfiguration?: {
141
+ model: string;
142
+ reasoningLevel?: string;
143
+ };
101
144
  /**
102
145
  * Entities pre-identified by the simple-replace phase before LLM enhancement.
103
146
  * These are seeded into referencedEntities so they show up in the transcript
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/agentic/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/agentic/types.ts"],"names":[],"mappings":"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"}
package/dist/index26.js CHANGED
@@ -92,6 +92,7 @@ const create = (reasoning, ctx) => {
92
92
  let iterations = 0;
93
93
  let totalTokens = 0;
94
94
  const maxIterations = 20;
95
+ let modelCallIndex = 0;
95
96
  const conversation = ConversationBuilder.create({ model: "gpt-4o" }).withTokenBudget({
96
97
  max: 1e5,
97
98
  // 100k token context window
@@ -195,9 +196,48 @@ Steps:
195
196
  2. Use route_note to determine where to file this note
196
197
  3. Then output the transcript with light formatting: paragraphs at topic shifts, a heading where topics clearly change, filler words removed. Keep the speaker's own words.`;
197
198
  conversation.addUserMessage(initialPrompt);
199
+ const callModel = async (phase, request) => {
200
+ modelCallIndex++;
201
+ const startEntry = {
202
+ callIndex: modelCallIndex,
203
+ phase,
204
+ request: {
205
+ model: ctx.modelConfiguration?.model,
206
+ reasoningLevel: ctx.modelConfiguration?.reasoningLevel,
207
+ prompt: request.prompt,
208
+ systemPrompt: request.systemPrompt,
209
+ maxIterations: request.maxIterations,
210
+ tools: request.tools
211
+ },
212
+ timestamp: /* @__PURE__ */ new Date()
213
+ };
214
+ ctx.onModelCallStart?.(startEntry);
215
+ const started = Date.now();
216
+ const response = await reasoning.complete({
217
+ systemPrompt: request.systemPrompt,
218
+ prompt: request.prompt,
219
+ tools: request.tools,
220
+ maxIterations: request.maxIterations
221
+ });
222
+ const completeEntry = {
223
+ callIndex: modelCallIndex,
224
+ phase,
225
+ durationMs: Date.now() - started,
226
+ response: {
227
+ model: response.model,
228
+ finishReason: response.finishReason,
229
+ usage: response.usage,
230
+ toolCalls: response.toolCalls,
231
+ contentLength: response.content?.length ?? 0
232
+ },
233
+ timestamp: /* @__PURE__ */ new Date()
234
+ };
235
+ ctx.onModelCallComplete?.(completeEntry);
236
+ return response;
237
+ };
198
238
  try {
199
239
  logger.debug("Starting agentic transcription - analyzing for names and routing...");
200
- let response = await reasoning.complete({
240
+ let response = await callModel("initial", {
201
241
  systemPrompt,
202
242
  prompt: initialPrompt,
203
243
  tools: registry.getToolDefinitions(),
@@ -318,7 +358,7 @@ ${transcriptText}
318
358
 
319
359
  ${outputInstruction}`;
320
360
  conversation.addUserMessage(continuationPrompt);
321
- response = await reasoning.complete({
361
+ response = await callModel("continuation", {
322
362
  systemPrompt,
323
363
  prompt: continuationPrompt,
324
364
  tools: registry.getToolDefinitions()
@@ -361,7 +401,7 @@ Rules:
361
401
  - Keep the speaker's own words — do not rewrite or rephrase
362
402
  - Preserve ALL content including asides and tangents
363
403
  - Output ONLY the formatted transcript`;
364
- const finalResponse = await reasoning.complete({
404
+ const finalResponse = await callModel("final", {
365
405
  systemPrompt,
366
406
  prompt: finalRequest
367
407
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index26.js","sources":["../src/agentic/executor.ts"],"sourcesContent":["/**\n * Agentic Executor\n * \n * Executes the agentic transcription loop with tool calls.\n * Uses RiotPrompt's ConversationBuilder for conversation management.\n */\n\nimport { ToolCallLogEntry, ToolContext, TranscriptionState } from './types';\nimport * as Registry from './registry';\nimport * as Reasoning from '../reasoning';\nimport * as Logging from '../logging';\nimport { ConversationBuilder, ToolCall as RiotToolCall } from '@kjerneverk/riotprompt';\nimport { EntityPrepositioner } from '../weighting/prepositioning';\n\nexport interface ContextChangeRecord {\n entityType: 'person' | 'project' | 'company' | 'term' | 'ignored';\n entityId: string;\n entityName: string;\n action: 'created' | 'updated';\n details?: Record<string, unknown>;\n}\n\nexport interface ExecutorInstance {\n process(transcriptText: string): Promise<{\n enhancedText: string;\n state: TranscriptionState;\n toolsUsed: string[];\n iterations: number;\n totalTokens?: number;\n contextChanges?: ContextChangeRecord[];\n }>;\n}\n\n/**\n * Convert internal tool call format to RiotPrompt's ToolCall format\n */\nconst toRiotToolCalls = (toolCalls: Array<{ id: string; name: string; arguments: Record<string, unknown> }>): RiotToolCall[] => {\n return toolCalls.map(tc => ({\n id: tc.id,\n type: 'function' as const,\n function: {\n name: tc.name,\n arguments: JSON.stringify(tc.arguments),\n },\n }));\n};\n\n/**\n * Clean response content by removing any leaked internal processing information\n * that should never appear in the user-facing transcript.\n */\nconst cleanResponseContent = (content: string): string => {\n let cleaned = content;\n\n // Strip markdown code fences - LLMs often wrap output in ```markdown ... ```\n // This avoids \"markdown\" appearing as the first line of the transcript\n cleaned = cleaned.replace(/^```\\s*(?:markdown|md|txt)?\\s*\\r?\\n?/i, '');\n cleaned = cleaned.replace(/\\r?\\n?```\\s*$/m, '');\n // Remove orphaned \"markdown\" line (can occur when AI uses ``` on separate line from language tag)\n cleaned = cleaned.replace(/^\\s*markdown\\s*\\r?\\n/i, '');\n\n // Remove common patterns of leaked internal processing\n // Pattern 1: \"Using tools to...\" type commentary\n cleaned = cleaned.replace(/^(?:Using tools?|Let me|I'll|I will|Now I'll|First,?\\s*I(?:'ll| will)).*?[\\r\\n]+/gim, '');\n \n // Pattern 2: JSON tool call artifacts - match complete JSON objects with \"tool\" key\n // Matches: {\"tool\":\"...\",\"args\":{...}}, {\"tool\":\"...\",\"input\":{...}}, etc.\n // Use a more careful pattern that matches balanced braces\n cleaned = cleaned.replace(/\\{\"tool\":\\s*\"[^\"]+\",\\s*\"(?:args|input)\":\\s*\\{[^}]*\\}\\}/g, '');\n \n // Pattern 3: Tool call references in the format tool_name({...})\n cleaned = cleaned.replace(/\\b\\w+_\\w+\\(\\{[^}]*\\}\\)/g, '');\n \n // Pattern 4: Remove lines with \"to=\" patterns (internal routing artifacts)\n // Matches: \"Այ to=lookup_project.commentary\", \"undefined to=route_note.commentary\"\n // Do this BEFORE Unicode filtering to catch mixed corruption\n cleaned = cleaned.replace(/^.*\\s+to=\\w+\\.\\w+.*$/gm, '');\n \n // Pattern 5: Remove lines that look like spam/SEO (Chinese gambling sites, etc.)\n // Matches lines with Chinese characters followed by \"app\", \"官网\", etc.\n // This is more specific than general Unicode filtering\n const spamPattern = /^.*[\\u4E00-\\u9FFF].*(app|官网|彩票|中彩票).*$/gm;\n cleaned = cleaned.replace(spamPattern, '');\n \n // Pattern 6: Remove lines with suspicious Unicode at the START (corruption indicators)\n // Only remove lines that START with non-Latin scripts (not legitimate content)\n // This catches corruption like \"Այ to=...\" or \"สามสิบเอ็ด\" at line start\n const corruptionStartPattern = /^[\\u0530-\\u058F\\u0E00-\\u0E7F\\u0A80-\\u0AFF\\u0C00-\\u0C7F].*$/gm;\n cleaned = cleaned.replace(corruptionStartPattern, '');\n \n // Pattern 7: Lines that are purely reasoning/commentary before the actual content\n // Look for lines like \"I'll verify...\", \"Checking...\", etc.\n const lines = cleaned.split('\\n');\n let startIndex = 0;\n \n // Skip leading lines that look like internal commentary\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n \n // Skip empty lines\n if (line === '') continue;\n \n // Check if line looks like commentary (starts with action verbs, contains \"tool\", etc.)\n const isCommentary = /^(checking|verifying|looking|searching|analyzing|processing|determining|using|calling|executing|I'm|I am|Let me)/i.test(line)\n || line.includes('tool')\n || line.includes('{\"')\n || line.includes('reasoning')\n || line.includes('undefined');\n \n if (!isCommentary) {\n // This looks like actual content - start from here\n startIndex = i;\n break;\n }\n }\n \n // Rejoin from the first real content line\n if (startIndex > 0) {\n cleaned = lines.slice(startIndex).join('\\n');\n }\n \n // Final cleanup: remove multiple consecutive blank lines\n cleaned = cleaned.replace(/\\n{3,}/g, '\\n\\n');\n \n return cleaned.trim();\n};\n\nexport const create = (\n reasoning: Reasoning.ReasoningInstance,\n ctx: ToolContext\n): ExecutorInstance => {\n const logger = Logging.getLogger();\n const registry = Registry.create(ctx);\n\n const logCleaningWarnings = (original: string, cleaned: string, label: string): void => {\n if (cleaned === original) return;\n const removedChars = original.length - cleaned.length;\n logger.warn('Removed leaked internal processing from %s (%d -> %d chars, removed %d chars)',\n label, original.length, cleaned.length, removedChars);\n const corruptionRatio = removedChars / original.length;\n const hasSuspiciousUnicode = /[\\u0530-\\u058F\\u0E00-\\u0E7F\\u4E00-\\u9FFF\\u0A80-\\u0AFF\\u0C00-\\u0C7F]/.test(original);\n if (corruptionRatio > 0.1 || hasSuspiciousUnicode) {\n logger.error('SEVERE CORRUPTION DETECTED in LLM %s (%.1f%% removed, suspicious unicode: %s)',\n label, corruptionRatio * 100, hasSuspiciousUnicode);\n logger.error('Raw preview (first 500 chars): %s',\n original.substring(0, 500).replace(/\\n/g, '\\\\n'));\n }\n };\n \n const process = async (transcriptText: string) => {\n // Seed referencedEntities from pre-identified entities (from simple-replace phase)\n // so they appear in the transcript metadata even if the LLM doesn't re-look them up.\n const pre = ctx.preIdentifiedEntities;\n const state: TranscriptionState = {\n originalText: transcriptText,\n correctedText: transcriptText,\n unknownEntities: [],\n resolvedEntities: new Map(),\n referencedEntities: {\n people: pre?.people ? new Set(pre.people) : new Set(),\n projects: pre?.projects ? new Set(pre.projects) : new Set(),\n terms: pre?.terms ? new Set(pre.terms) : new Set(),\n companies: pre?.companies ? new Set(pre.companies) : new Set(),\n },\n confidence: 0,\n };\n \n // Make resolvedEntities available to tools so they can avoid re-asking\n ctx.resolvedEntities = state.resolvedEntities;\n \n const toolsUsed: string[] = [];\n const contextChanges: ContextChangeRecord[] = [];\n let iterations = 0;\n let totalTokens = 0;\n const maxIterations = 20;\n \n // Use ConversationBuilder for conversation management with token budget\n const conversation = ConversationBuilder.create({ model: 'gpt-4o' })\n .withTokenBudget({\n max: 100000, // 100k token context window\n reserveForResponse: 4000, // Reserve 4k tokens for response\n strategy: 'summarize', // Summarize old messages if budget exceeded\n onBudgetExceeded: 'compress', // Automatically compress when exceeded\n preserveSystem: true, // Always keep system messages\n preserveRecent: 5 // Keep last 5 messages\n });\n \n // Generate entity prepositioning guidance if weight model is available\n // Note: At this point, routing hasn't happened yet, so we can't use project-specific predictions\n // The weight model will still provide co-occurrence predictions based on any entities found\n const prepositioner = ctx.weightModelProvider\n ? new EntityPrepositioner(ctx.weightModelProvider, ctx.contextInstance)\n : null;\n \n const entityGuidance = prepositioner\n ? prepositioner.generateGuidance(undefined) // No project ID yet\n : { likelyEntities: [], guidance: '' };\n\n // Build the system prompt\n let systemPrompt = `You are a light-touch transcription enhancer. You clean up raw voice transcripts with minimal changes — the output should read very close to the input, just better formatted.\n\n## Your job:\n1. Use the available tools to verify entity names and determine routing\n2. Lightly format the transcript for readability\n3. Preserve the speaker's words as closely as possible\n\n## What to do:\n- **Paragraphs**: Break the wall of text into paragraphs where the speaker shifts to a new idea or topic\n- **Headings**: Add a brief ## heading when there is a clear topic change\n- **Entity corrections**: Fix misspelled names/terms using tool lookups\n- **Light cleanup**: Remove obvious filler (um, uh) and false starts, but keep the speaker's natural phrasing otherwise\n- **Formatting**: Use bullet points only where the speaker is clearly listing items\n\n## What NOT to do:\n- Do NOT rewrite sentences or change the speaker's wording beyond filler removal\n- Do NOT add content, interpretation, or editorial commentary\n- Do NOT summarize or condense — the output should be approximately the same length\n- Do NOT over-structure — only add headings where topics genuinely change\n- Do NOT remove conversational asides or tangents — they are part of the content\n\n## OUTPUT REQUIREMENTS:\n- Your final response MUST contain ONLY the enhanced transcript as Markdown\n- DO NOT wrap in code blocks (no \\`\\`\\`markdown)\n- DO NOT include commentary, explanations, or processing notes\n- DO NOT narrate tool usage — use tools silently\n- Your output goes directly into the user-facing document\n\n## Available tools:\n- lookup_person: Verify spelling of people's names\n- lookup_project: Find project routing information\n- verify_spelling: Ask about unknown terms (if interactive mode)\n- route_note: Determine where to file this note\n- store_context: Remember new information for future use\n\n## Tool call discipline — IMPORTANT:\n- You have a budget of approximately 5–8 tool calls for the ENTIRE session\n- Call lookup_person only for names that are clearly misspelled or genuinely ambiguous\n- Call route_note exactly ONCE to determine filing destination\n- Do NOT call the same tool with the same arguments more than once\n- Once you have the key entity corrections and routing, produce the output immediately — do not keep calling tools`;\n\n // Add entity guidance if available\n if (entityGuidance.guidance) {\n systemPrompt += `\\n\\n## Entity Guidance\\n${entityGuidance.guidance}`;\n systemPrompt += '\\n\\nUse this guidance to improve entity recognition, but verify entities exist in the context before referencing them.';\n }\n\n // Inform the LLM about entities already matched by the simple-replace phase\n if (ctx.preIdentifiedEntities) {\n const lines: string[] = [];\n const { preIdentifiedEntities: pre } = ctx;\n\n for (const termId of pre.terms) {\n const term = ctx.contextInstance.getTerm(termId);\n if (term) lines.push(`- Term: **${term.name}** (id: ${term.id})`);\n }\n for (const projectId of pre.projects) {\n const project = ctx.contextInstance.getProject(projectId);\n if (project) lines.push(`- Project: **${project.name}** (id: ${project.id})`);\n }\n for (const personId of pre.people) {\n const person = ctx.contextInstance.getPerson(personId);\n if (person) lines.push(`- Person: **${person.name}** (id: ${person.id})`);\n }\n for (const companyId of pre.companies) {\n const company = ctx.contextInstance.getCompany(companyId);\n if (company) lines.push(`- Company: **${company.name}** (id: ${company.id})`);\n }\n\n if (lines.length > 0) {\n systemPrompt += `\\n\\n## Pre-matched Entities\\nThe following entities were identified via sounds_like matching before you received the transcript. Their names have already been corrected in the text — do NOT call lookup tools for these:\\n${lines.join('\\n')}`;\n }\n }\n\n // Add system message using ConversationBuilder\n conversation.addSystemMessage(systemPrompt);\n \n // Add the initial user message with transcript\n const initialPrompt = `Here is a raw voice transcript to clean up:\n\n--- BEGIN TRANSCRIPT ---\n${transcriptText}\n--- END TRANSCRIPT ---\n\nSteps:\n1. Use lookup_person for any names that might be misspelled\n2. Use route_note to determine where to file this note\n3. Then output the transcript with light formatting: paragraphs at topic shifts, a heading where topics clearly change, filler words removed. Keep the speaker's own words.`;\n\n conversation.addUserMessage(initialPrompt);\n\n try {\n // Initial reasoning call\n logger.debug('Starting agentic transcription - analyzing for names and routing...');\n let response = await reasoning.complete({\n systemPrompt,\n prompt: initialPrompt,\n tools: registry.getToolDefinitions(),\n maxIterations,\n });\n \n // Track token usage\n if (response.usage) {\n totalTokens += response.usage.totalTokens;\n }\n \n // Add assistant response to conversation\n if (response.toolCalls && response.toolCalls.length > 0) {\n conversation.addAssistantWithToolCalls(\n response.content,\n toRiotToolCalls(response.toolCalls)\n );\n } else {\n conversation.addAssistantMessage(response.content);\n }\n \n // Iterative tool use loop\n while (response.toolCalls && response.toolCalls.length > 0 && iterations < maxIterations) {\n iterations++;\n logger.debug('Iteration %d: Processing %d tool calls...', iterations, response.toolCalls.length);\n \n // Collect tool results\n const toolResults: Array<{ id: string; name: string; result: string }> = [];\n \n // Execute each tool call\n for (const toolCall of response.toolCalls) {\n logger.debug('Executing tool: %s', toolCall.name);\n toolsUsed.push(toolCall.name);\n\n // Notify caller that a tool is starting\n ctx.onToolCallStart?.(toolCall.name, toolCall.arguments);\n \n const callStart = Date.now();\n try {\n const result = await registry.executeTool(toolCall.name, toolCall.arguments);\n \n // Format result for the model\n const resultStr = JSON.stringify(result.data || { success: result.success, message: result.error || 'OK' });\n toolResults.push({ id: toolCall.id, name: toolCall.name, result: resultStr });\n \n logger.debug('Tool %s result: %s', toolCall.name, result.success ? 'success' : 'failed');\n\n // Notify caller that the tool completed\n const callEntry: ToolCallLogEntry = {\n tool: toolCall.name,\n input: toolCall.arguments,\n output: result.data ?? { success: result.success, message: result.error || 'OK' },\n durationMs: Date.now() - callStart,\n success: result.success,\n timestamp: new Date(),\n };\n ctx.onToolCallComplete?.(callEntry);\n \n // Handle results that need user input\n // Interactive functionality moved to protokoll-cli\n /* \n // eslint-disable-next-line no-constant-condition\n if (result.needsUserInput && false) {\n logger.info('Interactive: %s requires clarification', toolCall.name);\n \n const termName = String(toolCall.arguments.name || toolCall.arguments.term || '');\n \n const clarification = await ctx.interactiveInstance.handleClarification({\n type: result.data?.clarificationType || 'general',\n term: result.data?.term || termName,\n context: result.userPrompt || '',\n suggestion: result.data?.suggestion,\n options: result.data?.options,\n });\n \n if (clarification.response) {\n state.resolvedEntities.set(termName, clarification.response);\n logger.info('Clarified: %s -> %s', termName, clarification.response);\n \n // Handle new project/term wizard response\n if (result.data?.clarificationType === 'new_project' && clarification.additionalInfo) {\n const wizardResult = clarification.additionalInfo as {\n action: 'create' | 'link' | 'term' | 'skip' | 'ignore';\n projectName?: string;\n destination?: string;\n description?: string;\n linkedProjectIndex?: number;\n linkedTermName?: string;\n aliasName?: string;\n termDescription?: string;\n // For 'term' action\n termName?: string;\n termExpansion?: string;\n termProjects?: number[];\n // For nested project creation from term wizard\n createdProject?: {\n action: 'create' | 'link' | 'skip';\n projectName?: string;\n destination?: string;\n description?: string;\n };\n // For 'ignore' action\n ignoredTerm?: string;\n };\n \n const knownProjects = result.data?.knownProjects as Array<{\n id: string;\n name: string;\n description?: string;\n classification?: { explicit_phrases?: string[]; context_type?: string };\n routing?: { destination: string; structure?: string; filename_options?: string[] };\n }> | undefined;\n \n if (wizardResult.action === 'create') {\n // CREATE NEW PROJECT\n const projectName = wizardResult.projectName || termName;\n const projectId = projectName.toLowerCase().replace(/\\s+/g, '-');\n const projectDestination = wizardResult.destination;\n \n const newProject = {\n id: projectId,\n name: projectName,\n type: 'project' as const,\n description: wizardResult.description || `Project for \"${projectName}\"`,\n classification: {\n context_type: 'work' as const,\n explicit_phrases: [termName.toLowerCase(), projectName.toLowerCase()].filter((v, i, a) => a.indexOf(v) === i),\n },\n routing: {\n // Only include destination if explicitly provided - otherwise uses global default\n ...(projectDestination && { destination: projectDestination }),\n structure: 'month' as const,\n filename_options: ['date', 'time', 'subject'] as Array<'date' | 'time' | 'subject'>,\n },\n active: true,\n };\n \n try {\n await ctx.contextInstance.saveEntity(newProject);\n await ctx.contextInstance.reload(); // Reload so subsequent searches find this entity\n logger.info('Created new project: %s%s', projectName, projectDestination ? ` -> ${projectDestination}` : ' (using default destination)');\n \n contextChanges.push({\n entityType: 'project',\n entityId: projectId,\n entityName: projectName,\n action: 'created',\n details: {\n ...(projectDestination && { destination: projectDestination }),\n description: wizardResult.description,\n triggeredByTerm: termName,\n },\n });\n \n // Update routing if destination was specified\n if (projectDestination) {\n state.routeDecision = {\n projectId,\n destination: { path: projectDestination, structure: 'month' },\n confidence: 1.0,\n signals: [{ type: 'explicit_phrase', value: termName, weight: 1.0 }],\n reasoning: `User created new project \"${projectName}\" routing to ${projectDestination}`,\n };\n }\n } catch (error) {\n logger.warn('Failed to save new project: %s', error);\n }\n \n } else if (wizardResult.action === 'link' && wizardResult.linkedTermName) {\n // LINK AS ALIAS TO EXISTING TERM\n const existingTermName = wizardResult.linkedTermName;\n const aliasVariant = wizardResult.aliasName || termName;\n \n // Search for the existing term\n const termSearch = await ctx.contextInstance.search(existingTermName);\n const existingTerm = termSearch.find(e => e.type === 'term' && \n e.name.toLowerCase() === existingTermName.toLowerCase());\n \n if (existingTerm) {\n // Add the new variant to sounds_like\n const existingVariants = (existingTerm as { sounds_like?: string[] }).sounds_like || [];\n const updatedVariants = [...existingVariants, aliasVariant.toLowerCase()]\n .filter((v, i, a) => a.indexOf(v) === i); // dedupe\n \n const updatedTerm = {\n ...existingTerm,\n type: 'term' as const,\n sounds_like: updatedVariants,\n };\n \n try {\n await ctx.contextInstance.saveEntity(updatedTerm);\n await ctx.contextInstance.reload();\n logger.info('Added alias \"%s\" to existing term \"%s\"', aliasVariant, existingTerm.name);\n \n // Mark as resolved\n state.resolvedEntities.set(termName, existingTerm.name);\n state.resolvedEntities.set(aliasVariant, existingTerm.name);\n \n contextChanges.push({\n entityType: 'term',\n entityId: existingTerm.id,\n entityName: existingTerm.name,\n action: 'updated',\n details: {\n addedAlias: aliasVariant,\n sounds_like: updatedVariants,\n },\n });\n \n // If term has associated projects, use for routing\n const termProjects = (existingTerm as { projects?: string[] }).projects || [];\n if (termProjects.length > 0) {\n const allProjects = ctx.contextInstance.getAllProjects();\n const primaryProject = allProjects.find(p => p.id === termProjects[0]);\n if (primaryProject?.routing?.destination) {\n state.routeDecision = {\n projectId: primaryProject.id,\n destination: {\n path: primaryProject.routing.destination,\n structure: 'month'\n },\n confidence: 1.0,\n signals: [{ type: 'explicit_phrase', value: existingTerm.name, weight: 1.0 }],\n reasoning: `User linked \"${aliasVariant}\" as alias for term \"${existingTerm.name}\" associated with project \"${primaryProject.name}\"`,\n };\n }\n }\n } catch (error) {\n logger.warn('Failed to add alias to existing term: %s', error);\n }\n } else {\n logger.warn('Could not find existing term \"%s\" to link alias', existingTermName);\n }\n \n } else if (wizardResult.action === 'link' && typeof wizardResult.linkedProjectIndex === 'number') {\n // LINK TO EXISTING PROJECT\n if (knownProjects && wizardResult.linkedProjectIndex < knownProjects.length) {\n const linkedProject = knownProjects[wizardResult.linkedProjectIndex];\n \n // Add the term as an alias\n const existingPhrases = linkedProject.classification?.explicit_phrases || [];\n const updatedPhrases = [...existingPhrases, termName.toLowerCase()]\n .filter((v, i, a) => a.indexOf(v) === i); // dedupe\n \n const updatedProject = {\n ...linkedProject,\n type: 'project' as const,\n // Add term description to project notes if provided\n notes: wizardResult.termDescription \n ? `${linkedProject.description || ''}\\n\\n${termName}: ${wizardResult.termDescription}`.trim()\n : linkedProject.description,\n classification: {\n ...linkedProject.classification,\n context_type: (linkedProject.classification?.context_type || 'work') as 'work' | 'personal' | 'mixed',\n explicit_phrases: updatedPhrases,\n },\n routing: {\n // Preserve existing destination (or omit if not set)\n ...(linkedProject.routing?.destination && { destination: linkedProject.routing.destination }),\n structure: (linkedProject.routing?.structure || 'month') as 'none' | 'year' | 'month' | 'day',\n filename_options: (linkedProject.routing?.filename_options || ['date', 'time']) as Array<'date' | 'time' | 'subject'>,\n },\n };\n \n try {\n await ctx.contextInstance.saveEntity(updatedProject);\n await ctx.contextInstance.reload(); // Reload so subsequent searches find this entity\n logger.info('Linked \"%s\" to project \"%s\"', termName, linkedProject.name);\n \n contextChanges.push({\n entityType: 'project',\n entityId: linkedProject.id,\n entityName: linkedProject.name,\n action: 'updated',\n details: {\n addedAlias: termName,\n termDescription: wizardResult.termDescription,\n explicit_phrases: updatedPhrases,\n },\n });\n \n // Update routing to use the linked project\n if (linkedProject.routing?.destination) {\n state.routeDecision = {\n projectId: linkedProject.id,\n destination: { \n path: linkedProject.routing.destination, \n structure: 'month' \n },\n confidence: 1.0,\n signals: [{ type: 'explicit_phrase', value: termName, weight: 1.0 }],\n reasoning: `User linked \"${termName}\" to existing project \"${linkedProject.name}\"`,\n };\n }\n } catch (error) {\n logger.warn('Failed to update project with alias: %s', error);\n }\n }\n } else if (wizardResult.action === 'term') {\n // CREATE NEW TERM ENTITY\n const termNameFinal = wizardResult.termName || termName;\n const termId = termNameFinal.toLowerCase().replace(/\\s+/g, '-');\n \n // Get project IDs from indices\n const projectIds: string[] = [];\n if (wizardResult.termProjects && knownProjects) {\n for (const idx of wizardResult.termProjects) {\n if (idx >= 0 && idx < knownProjects.length) {\n projectIds.push(knownProjects[idx].id);\n }\n }\n }\n \n // Handle nested project creation from term wizard\n if (wizardResult.createdProject?.action === 'create' && wizardResult.createdProject.projectName) {\n const projectName = wizardResult.createdProject.projectName;\n const projectId = projectName.toLowerCase().replace(/\\s+/g, '-');\n const projectDestination = wizardResult.createdProject.destination;\n \n const newProject = {\n id: projectId,\n name: projectName,\n type: 'project' as const,\n description: wizardResult.createdProject.description || `Project for \"${projectName}\"`,\n classification: {\n context_type: 'work' as const,\n explicit_phrases: [projectName.toLowerCase(), termNameFinal.toLowerCase()].filter((v, i, a) => a.indexOf(v) === i),\n },\n routing: {\n // Only include destination if explicitly provided - otherwise uses global default\n ...(projectDestination && { destination: projectDestination }),\n structure: 'month' as const,\n filename_options: ['date', 'time', 'subject'] as Array<'date' | 'time' | 'subject'>,\n },\n active: true,\n };\n \n try {\n await ctx.contextInstance.saveEntity(newProject);\n await ctx.contextInstance.reload(); // Reload so subsequent searches find this entity\n logger.info('Created new project from term wizard: %s%s', projectName, projectDestination ? ` -> ${projectDestination}` : ' (using default destination)');\n \n // Add the new project to the projectIds list for term association\n projectIds.push(projectId);\n \n contextChanges.push({\n entityType: 'project',\n entityId: projectId,\n entityName: projectName,\n action: 'created',\n details: {\n ...(projectDestination && { destination: projectDestination }),\n description: wizardResult.createdProject.description,\n createdForTerm: termNameFinal,\n },\n });\n \n // Update routing to use the new project (if destination was specified)\n if (projectDestination) {\n state.routeDecision = {\n projectId,\n destination: { path: projectDestination, structure: 'month' },\n confidence: 1.0,\n signals: [{ type: 'explicit_phrase', value: termNameFinal, weight: 1.0 }],\n reasoning: `User created project \"${projectName}\" for term \"${termNameFinal}\"`,\n };\n }\n } catch (error) {\n logger.warn('Failed to save new project from term wizard: %s', error);\n }\n }\n \n const newTerm = {\n id: termId,\n name: termNameFinal,\n type: 'term' as const,\n expansion: wizardResult.termExpansion,\n notes: wizardResult.termDescription,\n projects: projectIds.length > 0 ? projectIds : undefined,\n sounds_like: [termName.toLowerCase()],\n };\n \n try {\n await ctx.contextInstance.saveEntity(newTerm);\n await ctx.contextInstance.reload(); // Reload so subsequent searches find this entity\n logger.info('Created new term: %s (projects: %s)', \n termNameFinal, \n projectIds.length > 0 ? projectIds.join(', ') : 'none'\n );\n \n contextChanges.push({\n entityType: 'term',\n entityId: termId,\n entityName: termNameFinal,\n action: 'created',\n details: {\n expansion: wizardResult.termExpansion,\n projects: projectIds,\n description: wizardResult.termDescription,\n },\n });\n \n // If term has associated projects and we haven't set routing yet, use the first one\n if (projectIds.length > 0 && !state.routeDecision) {\n // For newly created project, we already set routing above\n // For existing projects, look them up\n if (knownProjects) {\n const primaryProject = knownProjects.find(p => p.id === projectIds[0]);\n if (primaryProject?.routing?.destination) {\n state.routeDecision = {\n projectId: primaryProject.id,\n destination: { \n path: primaryProject.routing.destination, \n structure: 'month' \n },\n confidence: 1.0,\n signals: [{ type: 'explicit_phrase', value: termNameFinal, weight: 1.0 }],\n reasoning: `User created term \"${termNameFinal}\" associated with project \"${primaryProject.name}\"`,\n };\n }\n }\n }\n } catch (error) {\n logger.warn('Failed to save new term: %s', error);\n }\n } else if (wizardResult.action === 'ignore' && wizardResult.ignoredTerm) {\n // IGNORE - add term to ignore list so user won't be asked again\n const ignoredTermName = wizardResult.ignoredTerm;\n const ignoredId = ignoredTermName.toLowerCase()\n .replace(/[^a-z0-9]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '');\n \n const newIgnored = {\n id: ignoredId,\n name: ignoredTermName,\n type: 'ignored' as const,\n ignoredAt: new Date().toISOString(),\n };\n \n try {\n await ctx.contextInstance.saveEntity(newIgnored);\n await ctx.contextInstance.reload();\n logger.info('Added to ignore list: %s', ignoredTermName);\n \n contextChanges.push({\n entityType: 'ignored',\n entityId: ignoredId,\n entityName: ignoredTermName,\n action: 'created',\n details: {\n reason: 'User chose to ignore this term',\n },\n });\n } catch (error) {\n logger.warn('Failed to save ignored term: %s', error);\n }\n }\n // 'skip' action - do nothing\n }\n \n // Handle new person wizard response\n if (result.data?.clarificationType === 'new_person' && clarification.additionalInfo) {\n const personWizardResult = clarification.additionalInfo as {\n action: 'create' | 'skip';\n personName?: string;\n organization?: string;\n notes?: string;\n linkedProjectId?: string;\n linkedProjectIndex?: number;\n createdProject?: {\n action: 'create' | 'link' | 'skip';\n projectName?: string;\n destination?: string;\n description?: string;\n };\n };\n \n const knownProjects = result.data?.knownProjects as Array<{\n id: string;\n name: string;\n description?: string;\n classification?: { explicit_phrases?: string[]; context_type?: string };\n routing?: { destination: string; structure?: string; filename_options?: string[] };\n }> | undefined;\n \n if (personWizardResult.action === 'create') {\n let linkedProjectId: string | undefined;\n \n // First, handle any nested project creation\n if (personWizardResult.createdProject?.action === 'create' && personWizardResult.createdProject.projectName) {\n const projectName = personWizardResult.createdProject.projectName;\n const projectId = projectName.toLowerCase().replace(/\\s+/g, '-');\n const projectDestination = personWizardResult.createdProject.destination;\n \n const newProject = {\n id: projectId,\n name: projectName,\n type: 'project' as const,\n description: personWizardResult.createdProject.description || `Project for \"${projectName}\"`,\n classification: {\n context_type: 'work' as const,\n explicit_phrases: [projectName.toLowerCase()],\n },\n routing: {\n // Only include destination if explicitly provided - otherwise uses global default\n ...(projectDestination && { destination: projectDestination }),\n structure: 'month' as const,\n filename_options: ['date', 'time', 'subject'] as Array<'date' | 'time' | 'subject'>,\n },\n active: true,\n };\n \n try {\n await ctx.contextInstance.saveEntity(newProject);\n await ctx.contextInstance.reload(); // Reload so subsequent searches find this entity\n logger.info('Created new project from person wizard: %s%s', projectName, projectDestination ? ` -> ${projectDestination}` : ' (using default destination)');\n linkedProjectId = projectId;\n \n contextChanges.push({\n entityType: 'project',\n entityId: projectId,\n entityName: projectName,\n action: 'created',\n details: {\n ...(projectDestination && { destination: projectDestination }),\n description: personWizardResult.createdProject.description,\n createdForPerson: personWizardResult.personName,\n },\n });\n \n // Update routing to use the new project (if destination was specified)\n if (projectDestination) {\n state.routeDecision = {\n projectId,\n destination: { path: projectDestination, structure: 'month' },\n confidence: 1.0,\n signals: [{ type: 'explicit_phrase', value: projectName, weight: 1.0 }],\n reasoning: `User created project \"${projectName}\" for person \"${personWizardResult.personName}\"`,\n };\n }\n } catch (error) {\n logger.warn('Failed to save new project from person wizard: %s', error);\n }\n } else if (typeof personWizardResult.linkedProjectIndex === 'number' && knownProjects) {\n // User linked to existing project\n if (personWizardResult.linkedProjectIndex < knownProjects.length) {\n const linkedProject = knownProjects[personWizardResult.linkedProjectIndex];\n linkedProjectId = linkedProject.id;\n \n // Update routing to use the linked project\n if (linkedProject.routing?.destination) {\n state.routeDecision = {\n projectId: linkedProject.id,\n destination: { \n path: linkedProject.routing.destination, \n structure: 'month' \n },\n confidence: 1.0,\n signals: [{ type: 'explicit_phrase', value: personWizardResult.personName || termName, weight: 1.0 }],\n reasoning: `User linked person \"${personWizardResult.personName}\" to project \"${linkedProject.name}\"`,\n };\n }\n }\n }\n \n // Now save the person\n const personName = personWizardResult.personName || termName;\n const personId = personName.toLowerCase().replace(/\\s+/g, '-');\n \n const newPerson = {\n id: personId,\n name: personName,\n type: 'person' as const,\n organization: personWizardResult.organization,\n notes: personWizardResult.notes,\n projects: linkedProjectId ? [linkedProjectId] : [],\n sounds_like: [termName.toLowerCase()],\n };\n \n try {\n await ctx.contextInstance.saveEntity(newPerson);\n await ctx.contextInstance.reload(); // Reload so subsequent searches find this entity\n logger.info('Created new person: %s (org: %s, project: %s)', \n personName, \n personWizardResult.organization || 'none',\n linkedProjectId || 'none'\n );\n \n // Update resolved entities with correct name\n state.resolvedEntities.set(termName, personName);\n \n contextChanges.push({\n entityType: 'person',\n entityId: personId,\n entityName: personName,\n action: 'created',\n details: {\n organization: personWizardResult.organization,\n linkedProject: linkedProjectId,\n notes: personWizardResult.notes,\n heardAs: termName,\n },\n });\n } catch (error) {\n logger.warn('Failed to save new person: %s', error);\n }\n }\n // 'skip' action - do nothing\n }\n }\n }\n */ // End of commented interactive code\n \n // Update state based on tool results\n if (result.data?.person) {\n state.resolvedEntities.set(result.data.person.name, result.data.suggestion);\n // Track person entity reference\n state.referencedEntities.people.add(result.data.person.id);\n }\n \n // Track term entities\n if (result.data?.term) {\n state.referencedEntities.terms.add(result.data.term.id);\n }\n \n // Track company entities\n if (result.data?.company) {\n state.referencedEntities.companies.add(result.data.company.id);\n }\n \n // Capture routing from route_note tool\n if (result.data?.routingDecision?.destination) {\n const routingDecision = result.data.routingDecision;\n state.routeDecision = {\n projectId: routingDecision.projectId,\n destination: routingDecision.destination,\n confidence: routingDecision.confidence || 1.0,\n signals: routingDecision.signals,\n reasoning: routingDecision.reasoning || 'Determined by route_note tool',\n };\n \n // Track project if routing decision includes it\n if (routingDecision.projectId) {\n state.referencedEntities.projects.add(routingDecision.projectId);\n }\n }\n \n // Capture routing from lookup_project when project has routing config\n if (result.data?.found && result.data?.project?.routing?.destination) {\n const project = result.data.project;\n state.routeDecision = {\n projectId: project.id,\n destination: { \n path: project.routing.destination,\n structure: project.routing.structure || 'month',\n },\n confidence: 1.0,\n signals: [{ type: 'explicit_phrase', value: project.name, weight: 1.0 }],\n reasoning: `Matched project \"${project.name}\" with routing to ${project.routing.destination}`,\n };\n logger.debug('Captured routing from project lookup: %s -> %s', \n project.name, project.routing.destination);\n \n // Track project entity reference\n state.referencedEntities.projects.add(project.id);\n }\n \n } catch (error) {\n logger.error('Tool execution failed', { tool: toolCall.name, error });\n toolResults.push({ \n id: toolCall.id, \n name: toolCall.name, \n result: JSON.stringify({ error: String(error) }) \n });\n ctx.onToolCallComplete?.({\n tool: toolCall.name,\n input: toolCall.arguments,\n output: { error: String(error) },\n durationMs: Date.now() - callStart,\n success: false,\n timestamp: new Date(),\n });\n }\n }\n \n // Add tool results to conversation\n for (const tr of toolResults) {\n conversation.addToolResult(tr.id, tr.result, tr.name);\n }\n \n // Build continuation prompt with full context\n const correctionsNote = state.resolvedEntities.size > 0\n ? `\\nConfirmed corrections: ${Array.from(state.resolvedEntities.entries()).map(([k, v]) => `\"${k}\" → \"${v}\"`).join(', ')}`\n : '';\n\n const toolHistory = toolsUsed.length > 0\n ? `\\nTools called so far (do NOT repeat these): ${toolsUsed.join(', ')}`\n : '';\n\n const urgencyNote = toolsUsed.length >= 8\n ? `\\n\\n🛑 STOP CALLING TOOLS. You have made ${toolsUsed.length} tool calls. Output the formatted transcript NOW — no more tool calls.`\n : toolsUsed.length >= 5\n ? `\\n\\n⚠️ You have made ${toolsUsed.length} tool calls. Make at most 1–2 more critical lookups, then output immediately.`\n : '';\n\n const outputInstruction = toolsUsed.length >= 8\n ? 'Output the formatted transcript immediately. No more tool calls.'\n : 'If you have 1–2 remaining critical lookups, do them now. Then output the lightly formatted transcript: paragraphs at topic shifts, headings where topics clearly change, filler words removed. Keep the speaker\\'s own words — do not rewrite.';\n\n const continuationPrompt = `Tool results processed (iteration ${iterations}, ${toolsUsed.length} tool calls made).${correctionsNote}${toolHistory}${urgencyNote}\n\nORIGINAL TRANSCRIPT (you must use this):\n--- BEGIN TRANSCRIPT ---\n${transcriptText}\n--- END TRANSCRIPT ---\n\n${outputInstruction}`;\n\n conversation.addUserMessage(continuationPrompt);\n \n // Continue conversation with full context\n response = await reasoning.complete({\n systemPrompt,\n prompt: continuationPrompt,\n tools: registry.getToolDefinitions(),\n });\n \n // Track token usage\n if (response.usage) {\n totalTokens += response.usage.totalTokens;\n }\n \n // Add assistant response to conversation\n if (response.toolCalls && response.toolCalls.length > 0) {\n conversation.addAssistantWithToolCalls(\n response.content,\n toRiotToolCalls(response.toolCalls)\n );\n } else {\n conversation.addAssistantMessage(response.content);\n }\n }\n \n // Extract final corrected text\n const needsFinalRequest = !response.content || response.content.length <= 50;\n \n if (needsFinalRequest) {\n if (iterations >= maxIterations) {\n logger.warn('Hit max iterations (%d) without final transcript — requesting explicitly (no tools)', maxIterations);\n } else {\n logger.debug('Model did not produce transcript content, requesting explicitly...');\n }\n \n const correctionsBlock = state.resolvedEntities.size > 0\n ? Array.from(state.resolvedEntities.entries()).map(([k, v]) => `- \"${k}\" should be \"${v}\"`).join('\\n')\n : 'None identified';\n \n const finalRequest = `You have finished analyzing. Now output the lightly formatted transcript.\n\nORIGINAL TRANSCRIPT:\n--- BEGIN ---\n${transcriptText}\n--- END ---\n\nCORRECTIONS TO APPLY:\n${correctionsBlock}\n\nRules:\n- Break into paragraphs where the speaker shifts ideas\n- Add a ## heading only where topics clearly change\n- Remove filler words (um, uh) and false starts\n- Apply entity corrections listed above\n- Keep the speaker's own words — do not rewrite or rephrase\n- Preserve ALL content including asides and tangents\n- Output ONLY the formatted transcript`;\n\n const finalResponse = await reasoning.complete({\n systemPrompt,\n prompt: finalRequest,\n });\n \n if (finalResponse.usage) {\n totalTokens += finalResponse.usage.totalTokens;\n }\n \n if (finalResponse.content && finalResponse.content.length > 50) {\n const cleanedFinalContent = cleanResponseContent(finalResponse.content);\n logCleaningWarnings(finalResponse.content, cleanedFinalContent, 'final');\n state.correctedText = cleanedFinalContent;\n state.confidence = 0.8;\n logger.debug('Final transcript from explicit request: %d characters', cleanedFinalContent.length);\n } else {\n logger.error('Enhancement FAILED: explicit request produced no content (%d chars). Falling back to raw transcript.',\n finalResponse.content?.length || 0);\n state.correctedText = transcriptText;\n state.confidence = 0.5;\n }\n } else {\n const cleanedContent = cleanResponseContent(response.content);\n logCleaningWarnings(response.content, cleanedContent, 'response');\n state.correctedText = cleanedContent;\n state.confidence = 0.9;\n logger.debug('Final transcript generated: %d characters', cleanedContent.length);\n }\n \n } catch (error) {\n logger.error('Agentic processing failed', { error });\n // Fall back to original text\n state.correctedText = transcriptText;\n state.confidence = 0.5;\n }\n \n return {\n enhancedText: state.correctedText,\n state,\n toolsUsed: [...new Set(toolsUsed)],\n iterations,\n totalTokens: totalTokens > 0 ? totalTokens : undefined,\n contextChanges: contextChanges.length > 0 ? contextChanges : undefined,\n };\n };\n \n return { process };\n};\n\n"],"names":["Logging.getLogger","Registry.create","pre"],"mappings":"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"}
1
+ {"version":3,"file":"index26.js","sources":["../src/agentic/executor.ts"],"sourcesContent":["/**\n * Agentic Executor\n * \n * Executes the agentic transcription loop with tool calls.\n * Uses RiotPrompt's ConversationBuilder for conversation management.\n */\n\nimport {\n ModelCallCompleteLogEntry,\n ModelCallStartLogEntry,\n ToolCallLogEntry,\n ToolContext,\n TranscriptionState,\n} from './types';\nimport * as Registry from './registry';\nimport * as Reasoning from '../reasoning';\nimport * as Logging from '../logging';\nimport { ConversationBuilder, ToolCall as RiotToolCall } from '@kjerneverk/riotprompt';\nimport { EntityPrepositioner } from '../weighting/prepositioning';\n\nexport interface ContextChangeRecord {\n entityType: 'person' | 'project' | 'company' | 'term' | 'ignored';\n entityId: string;\n entityName: string;\n action: 'created' | 'updated';\n details?: Record<string, unknown>;\n}\n\nexport interface ExecutorInstance {\n process(transcriptText: string): Promise<{\n enhancedText: string;\n state: TranscriptionState;\n toolsUsed: string[];\n iterations: number;\n totalTokens?: number;\n contextChanges?: ContextChangeRecord[];\n }>;\n}\n\n/**\n * Convert internal tool call format to RiotPrompt's ToolCall format\n */\nconst toRiotToolCalls = (toolCalls: Array<{ id: string; name: string; arguments: Record<string, unknown> }>): RiotToolCall[] => {\n return toolCalls.map(tc => ({\n id: tc.id,\n type: 'function' as const,\n function: {\n name: tc.name,\n arguments: JSON.stringify(tc.arguments),\n },\n }));\n};\n\n/**\n * Clean response content by removing any leaked internal processing information\n * that should never appear in the user-facing transcript.\n */\nconst cleanResponseContent = (content: string): string => {\n let cleaned = content;\n\n // Strip markdown code fences - LLMs often wrap output in ```markdown ... ```\n // This avoids \"markdown\" appearing as the first line of the transcript\n cleaned = cleaned.replace(/^```\\s*(?:markdown|md|txt)?\\s*\\r?\\n?/i, '');\n cleaned = cleaned.replace(/\\r?\\n?```\\s*$/m, '');\n // Remove orphaned \"markdown\" line (can occur when AI uses ``` on separate line from language tag)\n cleaned = cleaned.replace(/^\\s*markdown\\s*\\r?\\n/i, '');\n\n // Remove common patterns of leaked internal processing\n // Pattern 1: \"Using tools to...\" type commentary\n cleaned = cleaned.replace(/^(?:Using tools?|Let me|I'll|I will|Now I'll|First,?\\s*I(?:'ll| will)).*?[\\r\\n]+/gim, '');\n \n // Pattern 2: JSON tool call artifacts - match complete JSON objects with \"tool\" key\n // Matches: {\"tool\":\"...\",\"args\":{...}}, {\"tool\":\"...\",\"input\":{...}}, etc.\n // Use a more careful pattern that matches balanced braces\n cleaned = cleaned.replace(/\\{\"tool\":\\s*\"[^\"]+\",\\s*\"(?:args|input)\":\\s*\\{[^}]*\\}\\}/g, '');\n \n // Pattern 3: Tool call references in the format tool_name({...})\n cleaned = cleaned.replace(/\\b\\w+_\\w+\\(\\{[^}]*\\}\\)/g, '');\n \n // Pattern 4: Remove lines with \"to=\" patterns (internal routing artifacts)\n // Matches: \"Այ to=lookup_project.commentary\", \"undefined to=route_note.commentary\"\n // Do this BEFORE Unicode filtering to catch mixed corruption\n cleaned = cleaned.replace(/^.*\\s+to=\\w+\\.\\w+.*$/gm, '');\n \n // Pattern 5: Remove lines that look like spam/SEO (Chinese gambling sites, etc.)\n // Matches lines with Chinese characters followed by \"app\", \"官网\", etc.\n // This is more specific than general Unicode filtering\n const spamPattern = /^.*[\\u4E00-\\u9FFF].*(app|官网|彩票|中彩票).*$/gm;\n cleaned = cleaned.replace(spamPattern, '');\n \n // Pattern 6: Remove lines with suspicious Unicode at the START (corruption indicators)\n // Only remove lines that START with non-Latin scripts (not legitimate content)\n // This catches corruption like \"Այ to=...\" or \"สามสิบเอ็ด\" at line start\n const corruptionStartPattern = /^[\\u0530-\\u058F\\u0E00-\\u0E7F\\u0A80-\\u0AFF\\u0C00-\\u0C7F].*$/gm;\n cleaned = cleaned.replace(corruptionStartPattern, '');\n \n // Pattern 7: Lines that are purely reasoning/commentary before the actual content\n // Look for lines like \"I'll verify...\", \"Checking...\", etc.\n const lines = cleaned.split('\\n');\n let startIndex = 0;\n \n // Skip leading lines that look like internal commentary\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n \n // Skip empty lines\n if (line === '') continue;\n \n // Check if line looks like commentary (starts with action verbs, contains \"tool\", etc.)\n const isCommentary = /^(checking|verifying|looking|searching|analyzing|processing|determining|using|calling|executing|I'm|I am|Let me)/i.test(line)\n || line.includes('tool')\n || line.includes('{\"')\n || line.includes('reasoning')\n || line.includes('undefined');\n \n if (!isCommentary) {\n // This looks like actual content - start from here\n startIndex = i;\n break;\n }\n }\n \n // Rejoin from the first real content line\n if (startIndex > 0) {\n cleaned = lines.slice(startIndex).join('\\n');\n }\n \n // Final cleanup: remove multiple consecutive blank lines\n cleaned = cleaned.replace(/\\n{3,}/g, '\\n\\n');\n \n return cleaned.trim();\n};\n\nexport const create = (\n reasoning: Reasoning.ReasoningInstance,\n ctx: ToolContext\n): ExecutorInstance => {\n const logger = Logging.getLogger();\n const registry = Registry.create(ctx);\n\n const logCleaningWarnings = (original: string, cleaned: string, label: string): void => {\n if (cleaned === original) return;\n const removedChars = original.length - cleaned.length;\n logger.warn('Removed leaked internal processing from %s (%d -> %d chars, removed %d chars)',\n label, original.length, cleaned.length, removedChars);\n const corruptionRatio = removedChars / original.length;\n const hasSuspiciousUnicode = /[\\u0530-\\u058F\\u0E00-\\u0E7F\\u4E00-\\u9FFF\\u0A80-\\u0AFF\\u0C00-\\u0C7F]/.test(original);\n if (corruptionRatio > 0.1 || hasSuspiciousUnicode) {\n logger.error('SEVERE CORRUPTION DETECTED in LLM %s (%.1f%% removed, suspicious unicode: %s)',\n label, corruptionRatio * 100, hasSuspiciousUnicode);\n logger.error('Raw preview (first 500 chars): %s',\n original.substring(0, 500).replace(/\\n/g, '\\\\n'));\n }\n };\n \n const process = async (transcriptText: string) => {\n // Seed referencedEntities from pre-identified entities (from simple-replace phase)\n // so they appear in the transcript metadata even if the LLM doesn't re-look them up.\n const pre = ctx.preIdentifiedEntities;\n const state: TranscriptionState = {\n originalText: transcriptText,\n correctedText: transcriptText,\n unknownEntities: [],\n resolvedEntities: new Map(),\n referencedEntities: {\n people: pre?.people ? new Set(pre.people) : new Set(),\n projects: pre?.projects ? new Set(pre.projects) : new Set(),\n terms: pre?.terms ? new Set(pre.terms) : new Set(),\n companies: pre?.companies ? new Set(pre.companies) : new Set(),\n },\n confidence: 0,\n };\n \n // Make resolvedEntities available to tools so they can avoid re-asking\n ctx.resolvedEntities = state.resolvedEntities;\n \n const toolsUsed: string[] = [];\n const contextChanges: ContextChangeRecord[] = [];\n let iterations = 0;\n let totalTokens = 0;\n const maxIterations = 20;\n let modelCallIndex = 0;\n \n // Use ConversationBuilder for conversation management with token budget\n const conversation = ConversationBuilder.create({ model: 'gpt-4o' })\n .withTokenBudget({\n max: 100000, // 100k token context window\n reserveForResponse: 4000, // Reserve 4k tokens for response\n strategy: 'summarize', // Summarize old messages if budget exceeded\n onBudgetExceeded: 'compress', // Automatically compress when exceeded\n preserveSystem: true, // Always keep system messages\n preserveRecent: 5 // Keep last 5 messages\n });\n \n // Generate entity prepositioning guidance if weight model is available\n // Note: At this point, routing hasn't happened yet, so we can't use project-specific predictions\n // The weight model will still provide co-occurrence predictions based on any entities found\n const prepositioner = ctx.weightModelProvider\n ? new EntityPrepositioner(ctx.weightModelProvider, ctx.contextInstance)\n : null;\n \n const entityGuidance = prepositioner\n ? prepositioner.generateGuidance(undefined) // No project ID yet\n : { likelyEntities: [], guidance: '' };\n\n // Build the system prompt\n let systemPrompt = `You are a light-touch transcription enhancer. You clean up raw voice transcripts with minimal changes — the output should read very close to the input, just better formatted.\n\n## Your job:\n1. Use the available tools to verify entity names and determine routing\n2. Lightly format the transcript for readability\n3. Preserve the speaker's words as closely as possible\n\n## What to do:\n- **Paragraphs**: Break the wall of text into paragraphs where the speaker shifts to a new idea or topic\n- **Headings**: Add a brief ## heading when there is a clear topic change\n- **Entity corrections**: Fix misspelled names/terms using tool lookups\n- **Light cleanup**: Remove obvious filler (um, uh) and false starts, but keep the speaker's natural phrasing otherwise\n- **Formatting**: Use bullet points only where the speaker is clearly listing items\n\n## What NOT to do:\n- Do NOT rewrite sentences or change the speaker's wording beyond filler removal\n- Do NOT add content, interpretation, or editorial commentary\n- Do NOT summarize or condense — the output should be approximately the same length\n- Do NOT over-structure — only add headings where topics genuinely change\n- Do NOT remove conversational asides or tangents — they are part of the content\n\n## OUTPUT REQUIREMENTS:\n- Your final response MUST contain ONLY the enhanced transcript as Markdown\n- DO NOT wrap in code blocks (no \\`\\`\\`markdown)\n- DO NOT include commentary, explanations, or processing notes\n- DO NOT narrate tool usage — use tools silently\n- Your output goes directly into the user-facing document\n\n## Available tools:\n- lookup_person: Verify spelling of people's names\n- lookup_project: Find project routing information\n- verify_spelling: Ask about unknown terms (if interactive mode)\n- route_note: Determine where to file this note\n- store_context: Remember new information for future use\n\n## Tool call discipline — IMPORTANT:\n- You have a budget of approximately 5–8 tool calls for the ENTIRE session\n- Call lookup_person only for names that are clearly misspelled or genuinely ambiguous\n- Call route_note exactly ONCE to determine filing destination\n- Do NOT call the same tool with the same arguments more than once\n- Once you have the key entity corrections and routing, produce the output immediately — do not keep calling tools`;\n\n // Add entity guidance if available\n if (entityGuidance.guidance) {\n systemPrompt += `\\n\\n## Entity Guidance\\n${entityGuidance.guidance}`;\n systemPrompt += '\\n\\nUse this guidance to improve entity recognition, but verify entities exist in the context before referencing them.';\n }\n\n // Inform the LLM about entities already matched by the simple-replace phase\n if (ctx.preIdentifiedEntities) {\n const lines: string[] = [];\n const { preIdentifiedEntities: pre } = ctx;\n\n for (const termId of pre.terms) {\n const term = ctx.contextInstance.getTerm(termId);\n if (term) lines.push(`- Term: **${term.name}** (id: ${term.id})`);\n }\n for (const projectId of pre.projects) {\n const project = ctx.contextInstance.getProject(projectId);\n if (project) lines.push(`- Project: **${project.name}** (id: ${project.id})`);\n }\n for (const personId of pre.people) {\n const person = ctx.contextInstance.getPerson(personId);\n if (person) lines.push(`- Person: **${person.name}** (id: ${person.id})`);\n }\n for (const companyId of pre.companies) {\n const company = ctx.contextInstance.getCompany(companyId);\n if (company) lines.push(`- Company: **${company.name}** (id: ${company.id})`);\n }\n\n if (lines.length > 0) {\n systemPrompt += `\\n\\n## Pre-matched Entities\\nThe following entities were identified via sounds_like matching before you received the transcript. Their names have already been corrected in the text — do NOT call lookup tools for these:\\n${lines.join('\\n')}`;\n }\n }\n\n // Add system message using ConversationBuilder\n conversation.addSystemMessage(systemPrompt);\n \n // Add the initial user message with transcript\n const initialPrompt = `Here is a raw voice transcript to clean up:\n\n--- BEGIN TRANSCRIPT ---\n${transcriptText}\n--- END TRANSCRIPT ---\n\nSteps:\n1. Use lookup_person for any names that might be misspelled\n2. Use route_note to determine where to file this note\n3. Then output the transcript with light formatting: paragraphs at topic shifts, a heading where topics clearly change, filler words removed. Keep the speaker's own words.`;\n\n conversation.addUserMessage(initialPrompt);\n\n const callModel = async (\n phase: 'initial' | 'continuation' | 'final',\n request: {\n systemPrompt: string;\n prompt: string;\n tools?: ReturnType<typeof registry.getToolDefinitions>;\n maxIterations?: number;\n },\n ) => {\n modelCallIndex++;\n const startEntry: ModelCallStartLogEntry = {\n callIndex: modelCallIndex,\n phase,\n request: {\n model: ctx.modelConfiguration?.model,\n reasoningLevel: ctx.modelConfiguration?.reasoningLevel,\n prompt: request.prompt,\n systemPrompt: request.systemPrompt,\n maxIterations: request.maxIterations,\n tools: request.tools,\n },\n timestamp: new Date(),\n };\n ctx.onModelCallStart?.(startEntry);\n\n const started = Date.now();\n const response = await reasoning.complete({\n systemPrompt: request.systemPrompt,\n prompt: request.prompt,\n tools: request.tools,\n maxIterations: request.maxIterations,\n });\n const completeEntry: ModelCallCompleteLogEntry = {\n callIndex: modelCallIndex,\n phase,\n durationMs: Date.now() - started,\n response: {\n model: response.model,\n finishReason: response.finishReason,\n usage: response.usage,\n toolCalls: response.toolCalls,\n contentLength: response.content?.length ?? 0,\n },\n timestamp: new Date(),\n };\n ctx.onModelCallComplete?.(completeEntry);\n return response;\n };\n\n try {\n // Initial reasoning call\n logger.debug('Starting agentic transcription - analyzing for names and routing...');\n let response = await callModel('initial', {\n systemPrompt,\n prompt: initialPrompt,\n tools: registry.getToolDefinitions(),\n maxIterations,\n });\n \n // Track token usage\n if (response.usage) {\n totalTokens += response.usage.totalTokens;\n }\n \n // Add assistant response to conversation\n if (response.toolCalls && response.toolCalls.length > 0) {\n conversation.addAssistantWithToolCalls(\n response.content,\n toRiotToolCalls(response.toolCalls)\n );\n } else {\n conversation.addAssistantMessage(response.content);\n }\n \n // Iterative tool use loop\n while (response.toolCalls && response.toolCalls.length > 0 && iterations < maxIterations) {\n iterations++;\n logger.debug('Iteration %d: Processing %d tool calls...', iterations, response.toolCalls.length);\n \n // Collect tool results\n const toolResults: Array<{ id: string; name: string; result: string }> = [];\n \n // Execute each tool call\n for (const toolCall of response.toolCalls) {\n logger.debug('Executing tool: %s', toolCall.name);\n toolsUsed.push(toolCall.name);\n\n // Notify caller that a tool is starting\n ctx.onToolCallStart?.(toolCall.name, toolCall.arguments);\n \n const callStart = Date.now();\n try {\n const result = await registry.executeTool(toolCall.name, toolCall.arguments);\n \n // Format result for the model\n const resultStr = JSON.stringify(result.data || { success: result.success, message: result.error || 'OK' });\n toolResults.push({ id: toolCall.id, name: toolCall.name, result: resultStr });\n \n logger.debug('Tool %s result: %s', toolCall.name, result.success ? 'success' : 'failed');\n\n // Notify caller that the tool completed\n const callEntry: ToolCallLogEntry = {\n tool: toolCall.name,\n input: toolCall.arguments,\n output: result.data ?? { success: result.success, message: result.error || 'OK' },\n durationMs: Date.now() - callStart,\n success: result.success,\n timestamp: new Date(),\n };\n ctx.onToolCallComplete?.(callEntry);\n \n // Handle results that need user input\n // Interactive functionality moved to protokoll-cli\n /* \n // eslint-disable-next-line no-constant-condition\n if (result.needsUserInput && false) {\n logger.info('Interactive: %s requires clarification', toolCall.name);\n \n const termName = String(toolCall.arguments.name || toolCall.arguments.term || '');\n \n const clarification = await ctx.interactiveInstance.handleClarification({\n type: result.data?.clarificationType || 'general',\n term: result.data?.term || termName,\n context: result.userPrompt || '',\n suggestion: result.data?.suggestion,\n options: result.data?.options,\n });\n \n if (clarification.response) {\n state.resolvedEntities.set(termName, clarification.response);\n logger.info('Clarified: %s -> %s', termName, clarification.response);\n \n // Handle new project/term wizard response\n if (result.data?.clarificationType === 'new_project' && clarification.additionalInfo) {\n const wizardResult = clarification.additionalInfo as {\n action: 'create' | 'link' | 'term' | 'skip' | 'ignore';\n projectName?: string;\n destination?: string;\n description?: string;\n linkedProjectIndex?: number;\n linkedTermName?: string;\n aliasName?: string;\n termDescription?: string;\n // For 'term' action\n termName?: string;\n termExpansion?: string;\n termProjects?: number[];\n // For nested project creation from term wizard\n createdProject?: {\n action: 'create' | 'link' | 'skip';\n projectName?: string;\n destination?: string;\n description?: string;\n };\n // For 'ignore' action\n ignoredTerm?: string;\n };\n \n const knownProjects = result.data?.knownProjects as Array<{\n id: string;\n name: string;\n description?: string;\n classification?: { explicit_phrases?: string[]; context_type?: string };\n routing?: { destination: string; structure?: string; filename_options?: string[] };\n }> | undefined;\n \n if (wizardResult.action === 'create') {\n // CREATE NEW PROJECT\n const projectName = wizardResult.projectName || termName;\n const projectId = projectName.toLowerCase().replace(/\\s+/g, '-');\n const projectDestination = wizardResult.destination;\n \n const newProject = {\n id: projectId,\n name: projectName,\n type: 'project' as const,\n description: wizardResult.description || `Project for \"${projectName}\"`,\n classification: {\n context_type: 'work' as const,\n explicit_phrases: [termName.toLowerCase(), projectName.toLowerCase()].filter((v, i, a) => a.indexOf(v) === i),\n },\n routing: {\n // Only include destination if explicitly provided - otherwise uses global default\n ...(projectDestination && { destination: projectDestination }),\n structure: 'month' as const,\n filename_options: ['date', 'time', 'subject'] as Array<'date' | 'time' | 'subject'>,\n },\n active: true,\n };\n \n try {\n await ctx.contextInstance.saveEntity(newProject);\n await ctx.contextInstance.reload(); // Reload so subsequent searches find this entity\n logger.info('Created new project: %s%s', projectName, projectDestination ? ` -> ${projectDestination}` : ' (using default destination)');\n \n contextChanges.push({\n entityType: 'project',\n entityId: projectId,\n entityName: projectName,\n action: 'created',\n details: {\n ...(projectDestination && { destination: projectDestination }),\n description: wizardResult.description,\n triggeredByTerm: termName,\n },\n });\n \n // Update routing if destination was specified\n if (projectDestination) {\n state.routeDecision = {\n projectId,\n destination: { path: projectDestination, structure: 'month' },\n confidence: 1.0,\n signals: [{ type: 'explicit_phrase', value: termName, weight: 1.0 }],\n reasoning: `User created new project \"${projectName}\" routing to ${projectDestination}`,\n };\n }\n } catch (error) {\n logger.warn('Failed to save new project: %s', error);\n }\n \n } else if (wizardResult.action === 'link' && wizardResult.linkedTermName) {\n // LINK AS ALIAS TO EXISTING TERM\n const existingTermName = wizardResult.linkedTermName;\n const aliasVariant = wizardResult.aliasName || termName;\n \n // Search for the existing term\n const termSearch = await ctx.contextInstance.search(existingTermName);\n const existingTerm = termSearch.find(e => e.type === 'term' && \n e.name.toLowerCase() === existingTermName.toLowerCase());\n \n if (existingTerm) {\n // Add the new variant to sounds_like\n const existingVariants = (existingTerm as { sounds_like?: string[] }).sounds_like || [];\n const updatedVariants = [...existingVariants, aliasVariant.toLowerCase()]\n .filter((v, i, a) => a.indexOf(v) === i); // dedupe\n \n const updatedTerm = {\n ...existingTerm,\n type: 'term' as const,\n sounds_like: updatedVariants,\n };\n \n try {\n await ctx.contextInstance.saveEntity(updatedTerm);\n await ctx.contextInstance.reload();\n logger.info('Added alias \"%s\" to existing term \"%s\"', aliasVariant, existingTerm.name);\n \n // Mark as resolved\n state.resolvedEntities.set(termName, existingTerm.name);\n state.resolvedEntities.set(aliasVariant, existingTerm.name);\n \n contextChanges.push({\n entityType: 'term',\n entityId: existingTerm.id,\n entityName: existingTerm.name,\n action: 'updated',\n details: {\n addedAlias: aliasVariant,\n sounds_like: updatedVariants,\n },\n });\n \n // If term has associated projects, use for routing\n const termProjects = (existingTerm as { projects?: string[] }).projects || [];\n if (termProjects.length > 0) {\n const allProjects = ctx.contextInstance.getAllProjects();\n const primaryProject = allProjects.find(p => p.id === termProjects[0]);\n if (primaryProject?.routing?.destination) {\n state.routeDecision = {\n projectId: primaryProject.id,\n destination: {\n path: primaryProject.routing.destination,\n structure: 'month'\n },\n confidence: 1.0,\n signals: [{ type: 'explicit_phrase', value: existingTerm.name, weight: 1.0 }],\n reasoning: `User linked \"${aliasVariant}\" as alias for term \"${existingTerm.name}\" associated with project \"${primaryProject.name}\"`,\n };\n }\n }\n } catch (error) {\n logger.warn('Failed to add alias to existing term: %s', error);\n }\n } else {\n logger.warn('Could not find existing term \"%s\" to link alias', existingTermName);\n }\n \n } else if (wizardResult.action === 'link' && typeof wizardResult.linkedProjectIndex === 'number') {\n // LINK TO EXISTING PROJECT\n if (knownProjects && wizardResult.linkedProjectIndex < knownProjects.length) {\n const linkedProject = knownProjects[wizardResult.linkedProjectIndex];\n \n // Add the term as an alias\n const existingPhrases = linkedProject.classification?.explicit_phrases || [];\n const updatedPhrases = [...existingPhrases, termName.toLowerCase()]\n .filter((v, i, a) => a.indexOf(v) === i); // dedupe\n \n const updatedProject = {\n ...linkedProject,\n type: 'project' as const,\n // Add term description to project notes if provided\n notes: wizardResult.termDescription \n ? `${linkedProject.description || ''}\\n\\n${termName}: ${wizardResult.termDescription}`.trim()\n : linkedProject.description,\n classification: {\n ...linkedProject.classification,\n context_type: (linkedProject.classification?.context_type || 'work') as 'work' | 'personal' | 'mixed',\n explicit_phrases: updatedPhrases,\n },\n routing: {\n // Preserve existing destination (or omit if not set)\n ...(linkedProject.routing?.destination && { destination: linkedProject.routing.destination }),\n structure: (linkedProject.routing?.structure || 'month') as 'none' | 'year' | 'month' | 'day',\n filename_options: (linkedProject.routing?.filename_options || ['date', 'time']) as Array<'date' | 'time' | 'subject'>,\n },\n };\n \n try {\n await ctx.contextInstance.saveEntity(updatedProject);\n await ctx.contextInstance.reload(); // Reload so subsequent searches find this entity\n logger.info('Linked \"%s\" to project \"%s\"', termName, linkedProject.name);\n \n contextChanges.push({\n entityType: 'project',\n entityId: linkedProject.id,\n entityName: linkedProject.name,\n action: 'updated',\n details: {\n addedAlias: termName,\n termDescription: wizardResult.termDescription,\n explicit_phrases: updatedPhrases,\n },\n });\n \n // Update routing to use the linked project\n if (linkedProject.routing?.destination) {\n state.routeDecision = {\n projectId: linkedProject.id,\n destination: { \n path: linkedProject.routing.destination, \n structure: 'month' \n },\n confidence: 1.0,\n signals: [{ type: 'explicit_phrase', value: termName, weight: 1.0 }],\n reasoning: `User linked \"${termName}\" to existing project \"${linkedProject.name}\"`,\n };\n }\n } catch (error) {\n logger.warn('Failed to update project with alias: %s', error);\n }\n }\n } else if (wizardResult.action === 'term') {\n // CREATE NEW TERM ENTITY\n const termNameFinal = wizardResult.termName || termName;\n const termId = termNameFinal.toLowerCase().replace(/\\s+/g, '-');\n \n // Get project IDs from indices\n const projectIds: string[] = [];\n if (wizardResult.termProjects && knownProjects) {\n for (const idx of wizardResult.termProjects) {\n if (idx >= 0 && idx < knownProjects.length) {\n projectIds.push(knownProjects[idx].id);\n }\n }\n }\n \n // Handle nested project creation from term wizard\n if (wizardResult.createdProject?.action === 'create' && wizardResult.createdProject.projectName) {\n const projectName = wizardResult.createdProject.projectName;\n const projectId = projectName.toLowerCase().replace(/\\s+/g, '-');\n const projectDestination = wizardResult.createdProject.destination;\n \n const newProject = {\n id: projectId,\n name: projectName,\n type: 'project' as const,\n description: wizardResult.createdProject.description || `Project for \"${projectName}\"`,\n classification: {\n context_type: 'work' as const,\n explicit_phrases: [projectName.toLowerCase(), termNameFinal.toLowerCase()].filter((v, i, a) => a.indexOf(v) === i),\n },\n routing: {\n // Only include destination if explicitly provided - otherwise uses global default\n ...(projectDestination && { destination: projectDestination }),\n structure: 'month' as const,\n filename_options: ['date', 'time', 'subject'] as Array<'date' | 'time' | 'subject'>,\n },\n active: true,\n };\n \n try {\n await ctx.contextInstance.saveEntity(newProject);\n await ctx.contextInstance.reload(); // Reload so subsequent searches find this entity\n logger.info('Created new project from term wizard: %s%s', projectName, projectDestination ? ` -> ${projectDestination}` : ' (using default destination)');\n \n // Add the new project to the projectIds list for term association\n projectIds.push(projectId);\n \n contextChanges.push({\n entityType: 'project',\n entityId: projectId,\n entityName: projectName,\n action: 'created',\n details: {\n ...(projectDestination && { destination: projectDestination }),\n description: wizardResult.createdProject.description,\n createdForTerm: termNameFinal,\n },\n });\n \n // Update routing to use the new project (if destination was specified)\n if (projectDestination) {\n state.routeDecision = {\n projectId,\n destination: { path: projectDestination, structure: 'month' },\n confidence: 1.0,\n signals: [{ type: 'explicit_phrase', value: termNameFinal, weight: 1.0 }],\n reasoning: `User created project \"${projectName}\" for term \"${termNameFinal}\"`,\n };\n }\n } catch (error) {\n logger.warn('Failed to save new project from term wizard: %s', error);\n }\n }\n \n const newTerm = {\n id: termId,\n name: termNameFinal,\n type: 'term' as const,\n expansion: wizardResult.termExpansion,\n notes: wizardResult.termDescription,\n projects: projectIds.length > 0 ? projectIds : undefined,\n sounds_like: [termName.toLowerCase()],\n };\n \n try {\n await ctx.contextInstance.saveEntity(newTerm);\n await ctx.contextInstance.reload(); // Reload so subsequent searches find this entity\n logger.info('Created new term: %s (projects: %s)', \n termNameFinal, \n projectIds.length > 0 ? projectIds.join(', ') : 'none'\n );\n \n contextChanges.push({\n entityType: 'term',\n entityId: termId,\n entityName: termNameFinal,\n action: 'created',\n details: {\n expansion: wizardResult.termExpansion,\n projects: projectIds,\n description: wizardResult.termDescription,\n },\n });\n \n // If term has associated projects and we haven't set routing yet, use the first one\n if (projectIds.length > 0 && !state.routeDecision) {\n // For newly created project, we already set routing above\n // For existing projects, look them up\n if (knownProjects) {\n const primaryProject = knownProjects.find(p => p.id === projectIds[0]);\n if (primaryProject?.routing?.destination) {\n state.routeDecision = {\n projectId: primaryProject.id,\n destination: { \n path: primaryProject.routing.destination, \n structure: 'month' \n },\n confidence: 1.0,\n signals: [{ type: 'explicit_phrase', value: termNameFinal, weight: 1.0 }],\n reasoning: `User created term \"${termNameFinal}\" associated with project \"${primaryProject.name}\"`,\n };\n }\n }\n }\n } catch (error) {\n logger.warn('Failed to save new term: %s', error);\n }\n } else if (wizardResult.action === 'ignore' && wizardResult.ignoredTerm) {\n // IGNORE - add term to ignore list so user won't be asked again\n const ignoredTermName = wizardResult.ignoredTerm;\n const ignoredId = ignoredTermName.toLowerCase()\n .replace(/[^a-z0-9]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '');\n \n const newIgnored = {\n id: ignoredId,\n name: ignoredTermName,\n type: 'ignored' as const,\n ignoredAt: new Date().toISOString(),\n };\n \n try {\n await ctx.contextInstance.saveEntity(newIgnored);\n await ctx.contextInstance.reload();\n logger.info('Added to ignore list: %s', ignoredTermName);\n \n contextChanges.push({\n entityType: 'ignored',\n entityId: ignoredId,\n entityName: ignoredTermName,\n action: 'created',\n details: {\n reason: 'User chose to ignore this term',\n },\n });\n } catch (error) {\n logger.warn('Failed to save ignored term: %s', error);\n }\n }\n // 'skip' action - do nothing\n }\n \n // Handle new person wizard response\n if (result.data?.clarificationType === 'new_person' && clarification.additionalInfo) {\n const personWizardResult = clarification.additionalInfo as {\n action: 'create' | 'skip';\n personName?: string;\n organization?: string;\n notes?: string;\n linkedProjectId?: string;\n linkedProjectIndex?: number;\n createdProject?: {\n action: 'create' | 'link' | 'skip';\n projectName?: string;\n destination?: string;\n description?: string;\n };\n };\n \n const knownProjects = result.data?.knownProjects as Array<{\n id: string;\n name: string;\n description?: string;\n classification?: { explicit_phrases?: string[]; context_type?: string };\n routing?: { destination: string; structure?: string; filename_options?: string[] };\n }> | undefined;\n \n if (personWizardResult.action === 'create') {\n let linkedProjectId: string | undefined;\n \n // First, handle any nested project creation\n if (personWizardResult.createdProject?.action === 'create' && personWizardResult.createdProject.projectName) {\n const projectName = personWizardResult.createdProject.projectName;\n const projectId = projectName.toLowerCase().replace(/\\s+/g, '-');\n const projectDestination = personWizardResult.createdProject.destination;\n \n const newProject = {\n id: projectId,\n name: projectName,\n type: 'project' as const,\n description: personWizardResult.createdProject.description || `Project for \"${projectName}\"`,\n classification: {\n context_type: 'work' as const,\n explicit_phrases: [projectName.toLowerCase()],\n },\n routing: {\n // Only include destination if explicitly provided - otherwise uses global default\n ...(projectDestination && { destination: projectDestination }),\n structure: 'month' as const,\n filename_options: ['date', 'time', 'subject'] as Array<'date' | 'time' | 'subject'>,\n },\n active: true,\n };\n \n try {\n await ctx.contextInstance.saveEntity(newProject);\n await ctx.contextInstance.reload(); // Reload so subsequent searches find this entity\n logger.info('Created new project from person wizard: %s%s', projectName, projectDestination ? ` -> ${projectDestination}` : ' (using default destination)');\n linkedProjectId = projectId;\n \n contextChanges.push({\n entityType: 'project',\n entityId: projectId,\n entityName: projectName,\n action: 'created',\n details: {\n ...(projectDestination && { destination: projectDestination }),\n description: personWizardResult.createdProject.description,\n createdForPerson: personWizardResult.personName,\n },\n });\n \n // Update routing to use the new project (if destination was specified)\n if (projectDestination) {\n state.routeDecision = {\n projectId,\n destination: { path: projectDestination, structure: 'month' },\n confidence: 1.0,\n signals: [{ type: 'explicit_phrase', value: projectName, weight: 1.0 }],\n reasoning: `User created project \"${projectName}\" for person \"${personWizardResult.personName}\"`,\n };\n }\n } catch (error) {\n logger.warn('Failed to save new project from person wizard: %s', error);\n }\n } else if (typeof personWizardResult.linkedProjectIndex === 'number' && knownProjects) {\n // User linked to existing project\n if (personWizardResult.linkedProjectIndex < knownProjects.length) {\n const linkedProject = knownProjects[personWizardResult.linkedProjectIndex];\n linkedProjectId = linkedProject.id;\n \n // Update routing to use the linked project\n if (linkedProject.routing?.destination) {\n state.routeDecision = {\n projectId: linkedProject.id,\n destination: { \n path: linkedProject.routing.destination, \n structure: 'month' \n },\n confidence: 1.0,\n signals: [{ type: 'explicit_phrase', value: personWizardResult.personName || termName, weight: 1.0 }],\n reasoning: `User linked person \"${personWizardResult.personName}\" to project \"${linkedProject.name}\"`,\n };\n }\n }\n }\n \n // Now save the person\n const personName = personWizardResult.personName || termName;\n const personId = personName.toLowerCase().replace(/\\s+/g, '-');\n \n const newPerson = {\n id: personId,\n name: personName,\n type: 'person' as const,\n organization: personWizardResult.organization,\n notes: personWizardResult.notes,\n projects: linkedProjectId ? [linkedProjectId] : [],\n sounds_like: [termName.toLowerCase()],\n };\n \n try {\n await ctx.contextInstance.saveEntity(newPerson);\n await ctx.contextInstance.reload(); // Reload so subsequent searches find this entity\n logger.info('Created new person: %s (org: %s, project: %s)', \n personName, \n personWizardResult.organization || 'none',\n linkedProjectId || 'none'\n );\n \n // Update resolved entities with correct name\n state.resolvedEntities.set(termName, personName);\n \n contextChanges.push({\n entityType: 'person',\n entityId: personId,\n entityName: personName,\n action: 'created',\n details: {\n organization: personWizardResult.organization,\n linkedProject: linkedProjectId,\n notes: personWizardResult.notes,\n heardAs: termName,\n },\n });\n } catch (error) {\n logger.warn('Failed to save new person: %s', error);\n }\n }\n // 'skip' action - do nothing\n }\n }\n }\n */ // End of commented interactive code\n \n // Update state based on tool results\n if (result.data?.person) {\n state.resolvedEntities.set(result.data.person.name, result.data.suggestion);\n // Track person entity reference\n state.referencedEntities.people.add(result.data.person.id);\n }\n \n // Track term entities\n if (result.data?.term) {\n state.referencedEntities.terms.add(result.data.term.id);\n }\n \n // Track company entities\n if (result.data?.company) {\n state.referencedEntities.companies.add(result.data.company.id);\n }\n \n // Capture routing from route_note tool\n if (result.data?.routingDecision?.destination) {\n const routingDecision = result.data.routingDecision;\n state.routeDecision = {\n projectId: routingDecision.projectId,\n destination: routingDecision.destination,\n confidence: routingDecision.confidence || 1.0,\n signals: routingDecision.signals,\n reasoning: routingDecision.reasoning || 'Determined by route_note tool',\n };\n \n // Track project if routing decision includes it\n if (routingDecision.projectId) {\n state.referencedEntities.projects.add(routingDecision.projectId);\n }\n }\n \n // Capture routing from lookup_project when project has routing config\n if (result.data?.found && result.data?.project?.routing?.destination) {\n const project = result.data.project;\n state.routeDecision = {\n projectId: project.id,\n destination: { \n path: project.routing.destination,\n structure: project.routing.structure || 'month',\n },\n confidence: 1.0,\n signals: [{ type: 'explicit_phrase', value: project.name, weight: 1.0 }],\n reasoning: `Matched project \"${project.name}\" with routing to ${project.routing.destination}`,\n };\n logger.debug('Captured routing from project lookup: %s -> %s', \n project.name, project.routing.destination);\n \n // Track project entity reference\n state.referencedEntities.projects.add(project.id);\n }\n \n } catch (error) {\n logger.error('Tool execution failed', { tool: toolCall.name, error });\n toolResults.push({ \n id: toolCall.id, \n name: toolCall.name, \n result: JSON.stringify({ error: String(error) }) \n });\n ctx.onToolCallComplete?.({\n tool: toolCall.name,\n input: toolCall.arguments,\n output: { error: String(error) },\n durationMs: Date.now() - callStart,\n success: false,\n timestamp: new Date(),\n });\n }\n }\n \n // Add tool results to conversation\n for (const tr of toolResults) {\n conversation.addToolResult(tr.id, tr.result, tr.name);\n }\n \n // Build continuation prompt with full context\n const correctionsNote = state.resolvedEntities.size > 0\n ? `\\nConfirmed corrections: ${Array.from(state.resolvedEntities.entries()).map(([k, v]) => `\"${k}\" → \"${v}\"`).join(', ')}`\n : '';\n\n const toolHistory = toolsUsed.length > 0\n ? `\\nTools called so far (do NOT repeat these): ${toolsUsed.join(', ')}`\n : '';\n\n const urgencyNote = toolsUsed.length >= 8\n ? `\\n\\n🛑 STOP CALLING TOOLS. You have made ${toolsUsed.length} tool calls. Output the formatted transcript NOW — no more tool calls.`\n : toolsUsed.length >= 5\n ? `\\n\\n⚠️ You have made ${toolsUsed.length} tool calls. Make at most 1–2 more critical lookups, then output immediately.`\n : '';\n\n const outputInstruction = toolsUsed.length >= 8\n ? 'Output the formatted transcript immediately. No more tool calls.'\n : 'If you have 1–2 remaining critical lookups, do them now. Then output the lightly formatted transcript: paragraphs at topic shifts, headings where topics clearly change, filler words removed. Keep the speaker\\'s own words — do not rewrite.';\n\n const continuationPrompt = `Tool results processed (iteration ${iterations}, ${toolsUsed.length} tool calls made).${correctionsNote}${toolHistory}${urgencyNote}\n\nORIGINAL TRANSCRIPT (you must use this):\n--- BEGIN TRANSCRIPT ---\n${transcriptText}\n--- END TRANSCRIPT ---\n\n${outputInstruction}`;\n\n conversation.addUserMessage(continuationPrompt);\n \n // Continue conversation with full context\n response = await callModel('continuation', {\n systemPrompt,\n prompt: continuationPrompt,\n tools: registry.getToolDefinitions(),\n });\n \n // Track token usage\n if (response.usage) {\n totalTokens += response.usage.totalTokens;\n }\n \n // Add assistant response to conversation\n if (response.toolCalls && response.toolCalls.length > 0) {\n conversation.addAssistantWithToolCalls(\n response.content,\n toRiotToolCalls(response.toolCalls)\n );\n } else {\n conversation.addAssistantMessage(response.content);\n }\n }\n \n // Extract final corrected text\n const needsFinalRequest = !response.content || response.content.length <= 50;\n \n if (needsFinalRequest) {\n if (iterations >= maxIterations) {\n logger.warn('Hit max iterations (%d) without final transcript — requesting explicitly (no tools)', maxIterations);\n } else {\n logger.debug('Model did not produce transcript content, requesting explicitly...');\n }\n \n const correctionsBlock = state.resolvedEntities.size > 0\n ? Array.from(state.resolvedEntities.entries()).map(([k, v]) => `- \"${k}\" should be \"${v}\"`).join('\\n')\n : 'None identified';\n \n const finalRequest = `You have finished analyzing. Now output the lightly formatted transcript.\n\nORIGINAL TRANSCRIPT:\n--- BEGIN ---\n${transcriptText}\n--- END ---\n\nCORRECTIONS TO APPLY:\n${correctionsBlock}\n\nRules:\n- Break into paragraphs where the speaker shifts ideas\n- Add a ## heading only where topics clearly change\n- Remove filler words (um, uh) and false starts\n- Apply entity corrections listed above\n- Keep the speaker's own words — do not rewrite or rephrase\n- Preserve ALL content including asides and tangents\n- Output ONLY the formatted transcript`;\n\n const finalResponse = await callModel('final', {\n systemPrompt,\n prompt: finalRequest,\n });\n \n if (finalResponse.usage) {\n totalTokens += finalResponse.usage.totalTokens;\n }\n \n if (finalResponse.content && finalResponse.content.length > 50) {\n const cleanedFinalContent = cleanResponseContent(finalResponse.content);\n logCleaningWarnings(finalResponse.content, cleanedFinalContent, 'final');\n state.correctedText = cleanedFinalContent;\n state.confidence = 0.8;\n logger.debug('Final transcript from explicit request: %d characters', cleanedFinalContent.length);\n } else {\n logger.error('Enhancement FAILED: explicit request produced no content (%d chars). Falling back to raw transcript.',\n finalResponse.content?.length || 0);\n state.correctedText = transcriptText;\n state.confidence = 0.5;\n }\n } else {\n const cleanedContent = cleanResponseContent(response.content);\n logCleaningWarnings(response.content, cleanedContent, 'response');\n state.correctedText = cleanedContent;\n state.confidence = 0.9;\n logger.debug('Final transcript generated: %d characters', cleanedContent.length);\n }\n \n } catch (error) {\n logger.error('Agentic processing failed', { error });\n // Fall back to original text\n state.correctedText = transcriptText;\n state.confidence = 0.5;\n }\n \n return {\n enhancedText: state.correctedText,\n state,\n toolsUsed: [...new Set(toolsUsed)],\n iterations,\n totalTokens: totalTokens > 0 ? totalTokens : undefined,\n contextChanges: contextChanges.length > 0 ? contextChanges : undefined,\n };\n };\n \n return { process };\n};\n\n"],"names":["Logging.getLogger","Registry.create","pre"],"mappings":"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"}