@redaksjon/protokoll-engine 0.1.3 → 0.1.4-dev.20260216151443.e1454c9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agentic/executor.d.ts.map +1 -1
- package/dist/agentic/types.d.ts +4 -1
- package/dist/agentic/types.d.ts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -5
- package/dist/index.js.map +1 -1
- package/dist/index10.js +4 -3
- package/dist/index10.js.map +1 -1
- package/dist/index11.js +2 -2
- package/dist/index12.js +3 -124
- package/dist/index12.js.map +1 -1
- package/dist/index13.js +101 -100
- package/dist/index13.js.map +1 -1
- package/dist/index14.js +109 -281
- package/dist/index14.js.map +1 -1
- package/dist/index15.js +285 -89
- package/dist/index15.js.map +1 -1
- package/dist/index16.js +97 -104
- package/dist/index16.js.map +1 -1
- package/dist/index17.js +18 -179
- package/dist/index17.js.map +1 -1
- package/dist/index18.js +102 -48
- package/dist/index18.js.map +1 -1
- package/dist/index19.js +182 -16
- package/dist/index19.js.map +1 -1
- package/dist/index2.js +3 -3
- package/dist/index20.js +48 -100
- package/dist/index20.js.map +1 -1
- package/dist/index21.js +16 -23
- package/dist/index21.js.map +1 -1
- package/dist/index22.js +98 -42
- package/dist/index22.js.map +1 -1
- package/dist/index23.js +19 -112
- package/dist/index23.js.map +1 -1
- package/dist/index24.js +42 -323
- package/dist/index24.js.map +1 -1
- package/dist/index25.js +114 -52
- package/dist/index25.js.map +1 -1
- package/dist/index26.js +339 -37
- package/dist/index26.js.map +1 -1
- package/dist/index27.js +51 -121
- package/dist/index27.js.map +1 -1
- package/dist/index28.js +36 -155
- package/dist/index28.js.map +1 -1
- package/dist/index29.js +114 -150
- package/dist/index29.js.map +1 -1
- package/dist/index3.js +2 -2
- package/dist/index30.js +171 -161
- package/dist/index30.js.map +1 -1
- package/dist/index31.js +141 -401
- package/dist/index31.js.map +1 -1
- package/dist/index32.js +158 -146
- package/dist/index32.js.map +1 -1
- package/dist/index33.js +425 -130
- package/dist/index33.js.map +1 -1
- package/dist/index34.js +145 -40
- package/dist/index34.js.map +1 -1
- package/dist/index35.js +159 -83
- package/dist/index35.js.map +1 -1
- package/dist/index36.js +46 -439
- package/dist/index36.js.map +1 -1
- package/dist/index37.js +91 -419
- package/dist/index37.js.map +1 -1
- package/dist/index38.js +447 -66
- package/dist/index38.js.map +1 -1
- package/dist/index39.js +424 -115
- package/dist/index39.js.map +1 -1
- package/dist/index4.js +2 -2
- package/dist/index40.js +78 -290
- package/dist/index40.js.map +1 -1
- package/dist/index41.js +112 -44
- package/dist/index41.js.map +1 -1
- package/dist/index42.js +115 -44
- package/dist/index42.js.map +1 -1
- package/dist/index43.js +295 -35
- package/dist/index43.js.map +1 -1
- package/dist/index44.js +270 -218
- package/dist/index44.js.map +1 -1
- package/dist/index45.js +131 -150
- package/dist/index45.js.map +1 -1
- package/dist/index46.js +117 -73
- package/dist/index46.js.map +1 -1
- package/dist/index47.js +45 -74
- package/dist/index47.js.map +1 -1
- package/dist/index48.js +48 -5
- package/dist/index48.js.map +1 -1
- package/dist/index49.js +33 -145
- package/dist/index49.js.map +1 -1
- package/dist/index5.js +3 -3
- package/dist/index50.js +216 -203
- package/dist/index50.js.map +1 -1
- package/dist/index51.js +153 -39
- package/dist/index51.js.map +1 -1
- package/dist/index52.js +74 -38
- package/dist/index52.js.map +1 -1
- package/dist/index53.js +74 -33
- package/dist/index53.js.map +1 -1
- package/dist/index54.js +149 -6
- package/dist/index54.js.map +1 -1
- package/dist/index55.js +224 -6
- package/dist/index55.js.map +1 -1
- package/dist/index56.js +42 -143
- package/dist/index56.js.map +1 -1
- package/dist/index57.js +43 -15
- package/dist/index57.js.map +1 -1
- package/dist/index58.js +35 -2
- package/dist/index58.js.map +1 -1
- package/dist/index59.js +5 -14
- package/dist/index59.js.map +1 -1
- package/dist/index6.js +4 -4
- package/dist/index6.js.map +1 -1
- package/dist/index60.js +6 -2
- package/dist/index60.js.map +1 -1
- package/dist/index61.js +6 -4
- package/dist/index61.js.map +1 -1
- package/dist/index62.js +151 -0
- package/dist/index62.js.map +1 -0
- package/dist/index63.js +17 -0
- package/dist/index63.js.map +1 -0
- package/dist/index64.js +4 -0
- package/dist/index64.js.map +1 -0
- package/dist/index65.js +17 -0
- package/dist/index65.js.map +1 -0
- package/dist/index66.js +4 -0
- package/dist/index66.js.map +1 -0
- package/dist/index67.js +6 -0
- package/dist/index67.js.map +1 -0
- package/dist/index7.js +2 -2
- package/dist/index8.js +1 -1
- package/dist/index9.js +4 -4
- package/dist/phases/simple-replace.d.ts +2 -1
- package/dist/phases/simple-replace.d.ts.map +1 -1
- package/dist/pipeline/orchestrator.d.ts.map +1 -1
- package/dist/pipeline/types.d.ts +3 -0
- package/dist/pipeline/types.d.ts.map +1 -1
- package/dist/routing/classifier.d.ts +2 -1
- package/dist/routing/classifier.d.ts.map +1 -1
- package/dist/routing/index.d.ts +2 -1
- package/dist/routing/index.d.ts.map +1 -1
- package/dist/routing/types.d.ts +1 -1
- package/dist/routing/types.d.ts.map +1 -1
- package/dist/transcript/index.d.ts +1 -0
- package/dist/transcript/index.d.ts.map +1 -1
- package/dist/transcript/operations.d.ts +14 -1
- package/dist/transcript/operations.d.ts.map +1 -1
- package/dist/transcript/upload-utils.d.ts +80 -0
- package/dist/transcript/upload-utils.d.ts.map +1 -0
- package/dist/util/enhancement-logger.d.ts +19 -0
- package/dist/util/enhancement-logger.d.ts.map +1 -0
- package/dist/util/metadata.d.ts +1 -0
- package/dist/util/metadata.d.ts.map +1 -1
- package/dist/weighting/builder.d.ts +126 -0
- package/dist/weighting/builder.d.ts.map +1 -0
- package/dist/weighting/index.d.ts +12 -0
- package/dist/weighting/index.d.ts.map +1 -0
- package/dist/weighting/prepositioning.d.ts +55 -0
- package/dist/weighting/prepositioning.d.ts.map +1 -0
- package/dist/weighting/provider.d.ts +78 -0
- package/dist/weighting/provider.d.ts.map +1 -0
- package/dist/weighting/types.d.ts +119 -0
- package/dist/weighting/types.d.ts.map +1 -0
- package/package.json +2 -2
package/dist/index15.js
CHANGED
|
@@ -1,100 +1,296 @@
|
|
|
1
|
-
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
1
|
+
const formatMetadataMarkdown = (metadata) => {
|
|
2
|
+
const lines = [];
|
|
3
|
+
if (metadata.title) {
|
|
4
|
+
lines.push(`# ${metadata.title}`);
|
|
5
|
+
lines.push("");
|
|
6
|
+
}
|
|
7
|
+
lines.push("## Metadata");
|
|
8
|
+
lines.push("");
|
|
9
|
+
if (metadata.date) {
|
|
10
|
+
const dateStr = metadata.date.toLocaleDateString("en-US", {
|
|
11
|
+
year: "numeric",
|
|
12
|
+
month: "long",
|
|
13
|
+
day: "numeric"
|
|
14
|
+
});
|
|
15
|
+
lines.push(`**Date**: ${dateStr}`);
|
|
16
|
+
if (metadata.recordingTime) {
|
|
17
|
+
lines.push(`**Time**: ${metadata.recordingTime}`);
|
|
18
|
+
} else {
|
|
19
|
+
const timeStr = metadata.date.toLocaleTimeString("en-US", {
|
|
20
|
+
hour: "2-digit",
|
|
21
|
+
minute: "2-digit",
|
|
22
|
+
hour12: true
|
|
23
|
+
});
|
|
24
|
+
lines.push(`**Time**: ${timeStr}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
lines.push("");
|
|
28
|
+
if (metadata.project) {
|
|
29
|
+
lines.push(`**Project**: ${metadata.project}`);
|
|
30
|
+
if (metadata.projectId) {
|
|
31
|
+
lines.push(`**Project ID**: \`${metadata.projectId}\``);
|
|
32
|
+
}
|
|
33
|
+
lines.push("");
|
|
34
|
+
}
|
|
35
|
+
if (metadata.routing) {
|
|
36
|
+
lines.push("### Routing");
|
|
37
|
+
lines.push("");
|
|
38
|
+
lines.push(`**Destination**: ${metadata.routing.destination}`);
|
|
39
|
+
lines.push(`**Confidence**: ${(metadata.routing.confidence * 100).toFixed(1)}%`);
|
|
40
|
+
lines.push("");
|
|
41
|
+
if (metadata.routing.signals.length > 0) {
|
|
42
|
+
lines.push("**Classification Signals**:");
|
|
43
|
+
for (const signal of metadata.routing.signals) {
|
|
44
|
+
const signalType = signal.type.replace(/_/g, " ");
|
|
45
|
+
const weight = (signal.weight * 100).toFixed(0);
|
|
46
|
+
lines.push(`- ${signalType}: "${signal.value}" (${weight}% weight)`);
|
|
27
47
|
}
|
|
48
|
+
lines.push("");
|
|
49
|
+
}
|
|
50
|
+
if (metadata.routing.reasoning) {
|
|
51
|
+
lines.push(`**Reasoning**: ${metadata.routing.reasoning}`);
|
|
52
|
+
lines.push("");
|
|
28
53
|
}
|
|
29
54
|
}
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
55
|
+
if (metadata.tags && metadata.tags.length > 0) {
|
|
56
|
+
lines.push("**Tags**: " + metadata.tags.map((tag) => `\`${tag}\``).join(", "));
|
|
57
|
+
lines.push("");
|
|
58
|
+
}
|
|
59
|
+
if (metadata.duration) {
|
|
60
|
+
lines.push(`**Duration**: ${metadata.duration}`);
|
|
61
|
+
lines.push("");
|
|
62
|
+
}
|
|
63
|
+
lines.push("---");
|
|
64
|
+
lines.push("");
|
|
65
|
+
return lines.join("\n");
|
|
66
|
+
};
|
|
67
|
+
const formatEntityMetadataMarkdown = (metadata) => {
|
|
68
|
+
if (!metadata.entities) {
|
|
69
|
+
return "";
|
|
70
|
+
}
|
|
71
|
+
const lines = [];
|
|
72
|
+
lines.push("");
|
|
73
|
+
lines.push("---");
|
|
74
|
+
lines.push("");
|
|
75
|
+
lines.push("## Entity References");
|
|
76
|
+
lines.push("");
|
|
77
|
+
lines.push("<!-- Machine-readable entity metadata for indexing and querying -->");
|
|
78
|
+
lines.push("");
|
|
79
|
+
if (metadata.entities.people && metadata.entities.people.length > 0) {
|
|
80
|
+
lines.push("### People");
|
|
81
|
+
lines.push("");
|
|
82
|
+
for (const person of metadata.entities.people) {
|
|
83
|
+
lines.push(`- \`${person.id}\`: ${person.name}`);
|
|
46
84
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
85
|
+
lines.push("");
|
|
86
|
+
}
|
|
87
|
+
if (metadata.entities.projects && metadata.entities.projects.length > 0) {
|
|
88
|
+
lines.push("### Projects");
|
|
89
|
+
lines.push("");
|
|
90
|
+
for (const project of metadata.entities.projects) {
|
|
91
|
+
lines.push(`- \`${project.id}\`: ${project.name}`);
|
|
50
92
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
93
|
+
lines.push("");
|
|
94
|
+
}
|
|
95
|
+
if (metadata.entities.terms && metadata.entities.terms.length > 0) {
|
|
96
|
+
lines.push("### Terms");
|
|
97
|
+
lines.push("");
|
|
98
|
+
for (const term of metadata.entities.terms) {
|
|
99
|
+
lines.push(`- \`${term.id}\`: ${term.name}`);
|
|
54
100
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
101
|
+
lines.push("");
|
|
102
|
+
}
|
|
103
|
+
if (metadata.entities.companies && metadata.entities.companies.length > 0) {
|
|
104
|
+
lines.push("### Companies");
|
|
105
|
+
lines.push("");
|
|
106
|
+
for (const company of metadata.entities.companies) {
|
|
107
|
+
lines.push(`- \`${company.id}\`: ${company.name}`);
|
|
58
108
|
}
|
|
109
|
+
lines.push("");
|
|
59
110
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
return matches[0].entity;
|
|
111
|
+
return lines.join("\n");
|
|
112
|
+
};
|
|
113
|
+
const parseEntityMetadata = (content) => {
|
|
114
|
+
const headerIndex = content.indexOf("## Entity References");
|
|
115
|
+
if (headerIndex === -1) {
|
|
116
|
+
return void 0;
|
|
67
117
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
118
|
+
let contentStart = headerIndex + "## Entity References".length;
|
|
119
|
+
while (contentStart < content.length && (content[contentStart] === "\n" || content[contentStart] === "\r" || content[contentStart] === " " || content[contentStart] === " ")) {
|
|
120
|
+
contentStart++;
|
|
121
|
+
}
|
|
122
|
+
const remainingContent = content.substring(contentStart);
|
|
123
|
+
const nextHeaderMatch = remainingContent.match(/\n## /);
|
|
124
|
+
const sectionContent = nextHeaderMatch ? remainingContent.substring(0, nextHeaderMatch.index) : remainingContent;
|
|
125
|
+
const entities = {
|
|
126
|
+
people: [],
|
|
127
|
+
projects: [],
|
|
128
|
+
terms: [],
|
|
129
|
+
companies: []
|
|
130
|
+
};
|
|
131
|
+
const parseEntities = (type) => {
|
|
132
|
+
const typeMap = {
|
|
133
|
+
"People": "person",
|
|
134
|
+
"Projects": "project",
|
|
135
|
+
"Terms": "term",
|
|
136
|
+
"Companies": "company"
|
|
137
|
+
};
|
|
138
|
+
const entityType = typeMap[type];
|
|
139
|
+
const sectionHeader = `### ${type}`;
|
|
140
|
+
const sectionStart = sectionContent.indexOf(sectionHeader);
|
|
141
|
+
if (sectionStart === -1) return [];
|
|
142
|
+
const headerEnd = sectionStart + sectionHeader.length;
|
|
143
|
+
let sectionTextStart = headerEnd;
|
|
144
|
+
while (sectionTextStart < sectionContent.length && (sectionContent[sectionTextStart] === "\n" || sectionContent[sectionTextStart] === "\r" || sectionContent[sectionTextStart] === " ")) {
|
|
145
|
+
sectionTextStart++;
|
|
146
|
+
}
|
|
147
|
+
const afterSection = sectionContent.substring(sectionTextStart);
|
|
148
|
+
const nextSection = afterSection.search(/\n###/);
|
|
149
|
+
const sectionText = nextSection === -1 ? afterSection : afterSection.substring(0, nextSection);
|
|
150
|
+
const items = [];
|
|
151
|
+
const lines = sectionText.split("\n");
|
|
152
|
+
for (const line of lines) {
|
|
153
|
+
const trimmed = line.trim();
|
|
154
|
+
const match = trimmed.match(/^- `([^`]+)`:\s*(.+)$/);
|
|
155
|
+
if (match) {
|
|
156
|
+
items.push({
|
|
157
|
+
id: match[1],
|
|
158
|
+
name: match[2].trim(),
|
|
159
|
+
type: entityType
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return items;
|
|
164
|
+
};
|
|
165
|
+
entities.people = parseEntities("People");
|
|
166
|
+
entities.projects = parseEntities("Projects");
|
|
167
|
+
entities.terms = parseEntities("Terms");
|
|
168
|
+
entities.companies = parseEntities("Companies");
|
|
169
|
+
const hasEntities = entities.people.length > 0 || entities.projects.length > 0 || entities.terms.length > 0 || entities.companies.length > 0;
|
|
170
|
+
return hasEntities ? entities : void 0;
|
|
171
|
+
};
|
|
172
|
+
const createRoutingMetadata = (decision) => {
|
|
173
|
+
return {
|
|
174
|
+
destination: decision.destination.path,
|
|
175
|
+
confidence: decision.confidence,
|
|
176
|
+
signals: decision.signals,
|
|
177
|
+
reasoning: decision.reasoning
|
|
178
|
+
};
|
|
179
|
+
};
|
|
180
|
+
const formatDuration = (seconds) => {
|
|
181
|
+
const minutes = Math.floor(seconds / 60);
|
|
182
|
+
const secs = Math.round(seconds % 60);
|
|
183
|
+
if (minutes === 0) {
|
|
184
|
+
return `${secs}s`;
|
|
185
|
+
}
|
|
186
|
+
if (secs === 0) {
|
|
187
|
+
return `${minutes}m`;
|
|
188
|
+
}
|
|
189
|
+
return `${minutes}m ${secs}s`;
|
|
190
|
+
};
|
|
191
|
+
const formatTime = (date) => {
|
|
192
|
+
return date.toLocaleTimeString("en-US", {
|
|
193
|
+
hour: "2-digit",
|
|
194
|
+
minute: "2-digit",
|
|
195
|
+
hour12: true
|
|
196
|
+
});
|
|
197
|
+
};
|
|
198
|
+
const extractTopicFromSignals = (signals) => {
|
|
199
|
+
const topicSignal = signals.find((s) => s.type === "topic" || s.type === "context_type");
|
|
200
|
+
return topicSignal?.value;
|
|
201
|
+
};
|
|
202
|
+
const extractTagsFromSignals = (signals) => {
|
|
203
|
+
const tags = signals.filter((s) => s.type !== "context_type").map((s) => s.value).filter((v) => typeof v === "string");
|
|
204
|
+
return Array.from(new Set(tags));
|
|
205
|
+
};
|
|
206
|
+
const VALID_STATUSES = [
|
|
207
|
+
"initial",
|
|
208
|
+
"enhanced",
|
|
209
|
+
"reviewed",
|
|
210
|
+
"in_progress",
|
|
211
|
+
"closed",
|
|
212
|
+
"archived"
|
|
213
|
+
];
|
|
214
|
+
const isValidStatus = (status) => {
|
|
215
|
+
return VALID_STATUSES.includes(status);
|
|
216
|
+
};
|
|
217
|
+
const generateTaskId = () => {
|
|
218
|
+
const timestamp = Date.now();
|
|
219
|
+
const random = Math.random().toString(36).substring(2, 8);
|
|
220
|
+
return `task-${timestamp}-${random}`;
|
|
221
|
+
};
|
|
222
|
+
const createTask = (description) => {
|
|
223
|
+
return {
|
|
224
|
+
id: generateTaskId(),
|
|
225
|
+
description,
|
|
226
|
+
status: "open",
|
|
227
|
+
created: (/* @__PURE__ */ new Date()).toISOString()
|
|
228
|
+
};
|
|
229
|
+
};
|
|
230
|
+
const updateStatus = (metadata, newStatus) => {
|
|
231
|
+
const oldStatus = metadata.status;
|
|
232
|
+
if (oldStatus === newStatus) {
|
|
233
|
+
return metadata;
|
|
234
|
+
}
|
|
235
|
+
const transition = {
|
|
236
|
+
from: oldStatus || "reviewed",
|
|
237
|
+
to: newStatus,
|
|
238
|
+
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
239
|
+
};
|
|
240
|
+
return {
|
|
241
|
+
...metadata,
|
|
242
|
+
status: newStatus,
|
|
243
|
+
history: [...metadata.history || [], transition]
|
|
244
|
+
};
|
|
245
|
+
};
|
|
246
|
+
const applyLifecycleDefaults = (metadata) => {
|
|
247
|
+
return {
|
|
248
|
+
...metadata,
|
|
249
|
+
status: metadata.status ?? "reviewed",
|
|
250
|
+
history: metadata.history ?? [],
|
|
251
|
+
tasks: metadata.tasks ?? []
|
|
252
|
+
};
|
|
253
|
+
};
|
|
254
|
+
const completeTask = (metadata, taskId) => {
|
|
255
|
+
const tasks = metadata.tasks || [];
|
|
256
|
+
const taskIndex = tasks.findIndex((t) => t.id === taskId);
|
|
257
|
+
if (taskIndex === -1) {
|
|
258
|
+
throw new Error(`Task not found: ${taskId}`);
|
|
259
|
+
}
|
|
260
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
261
|
+
const updatedTasks = [...tasks];
|
|
262
|
+
updatedTasks[taskIndex] = {
|
|
263
|
+
...updatedTasks[taskIndex],
|
|
264
|
+
status: "done",
|
|
265
|
+
changed: now,
|
|
266
|
+
completed: now
|
|
267
|
+
};
|
|
268
|
+
return {
|
|
269
|
+
...metadata,
|
|
270
|
+
tasks: updatedTasks
|
|
271
|
+
};
|
|
272
|
+
};
|
|
273
|
+
const deleteTask = (metadata, taskId) => {
|
|
274
|
+
const tasks = metadata.tasks || [];
|
|
275
|
+
const taskIndex = tasks.findIndex((t) => t.id === taskId);
|
|
276
|
+
if (taskIndex === -1) {
|
|
277
|
+
throw new Error(`Task not found: ${taskId}`);
|
|
278
|
+
}
|
|
279
|
+
return {
|
|
280
|
+
...metadata,
|
|
281
|
+
tasks: tasks.filter((t) => t.id !== taskId)
|
|
282
|
+
};
|
|
283
|
+
};
|
|
284
|
+
const addTask = (metadata, description) => {
|
|
285
|
+
const task = createTask(description);
|
|
286
|
+
return {
|
|
287
|
+
metadata: {
|
|
288
|
+
...metadata,
|
|
289
|
+
tasks: [...metadata.tasks || [], task]
|
|
290
|
+
},
|
|
291
|
+
task
|
|
292
|
+
};
|
|
293
|
+
};
|
|
98
294
|
|
|
99
|
-
export {
|
|
295
|
+
export { VALID_STATUSES, addTask, applyLifecycleDefaults, completeTask, createRoutingMetadata, createTask, deleteTask, extractTagsFromSignals, extractTopicFromSignals, formatDuration, formatEntityMetadataMarkdown, formatMetadataMarkdown, formatTime, generateTaskId, isValidStatus, parseEntityMetadata, updateStatus };
|
|
100
296
|
//# sourceMappingURL=index15.js.map
|
package/dist/index15.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index15.js","sources":["../src/utils/entityFinder.ts"],"sourcesContent":["/**\n * Resilient Entity Finder\n * \n * Provides case-insensitive and fuzzy matching for all entity types.\n * Handles typos, capitalization differences, and matches by both ID and name.\n */\n\nimport * as Context from '@redaksjon/context';\nimport type { Entity, Person, Project, Company, Term, IgnoredTerm } from '@redaksjon/context';\n\n/**\n * Calculate Levenshtein distance between two strings\n * Returns the minimum number of single-character edits needed to transform str1 into str2\n */\nfunction levenshteinDistance(str1: string, str2: string): number {\n const s1 = str1.toLowerCase();\n const s2 = str2.toLowerCase();\n \n if (s1 === s2) return 0;\n if (s1.length === 0) return s2.length;\n if (s2.length === 0) return s1.length;\n \n const matrix: number[][] = [];\n \n // Initialize first row and column\n for (let i = 0; i <= s2.length; i++) {\n matrix[i] = [i];\n }\n for (let j = 0; j <= s1.length; j++) {\n matrix[0][j] = j;\n }\n \n // Fill the matrix\n for (let i = 1; i <= s2.length; i++) {\n for (let j = 1; j <= s1.length; j++) {\n if (s2.charAt(i - 1) === s1.charAt(j - 1)) {\n matrix[i][j] = matrix[i - 1][j - 1];\n } else {\n matrix[i][j] = Math.min(\n matrix[i - 1][j - 1] + 1, // substitution\n matrix[i][j - 1] + 1, // insertion\n matrix[i - 1][j] + 1 // deletion\n );\n }\n }\n }\n \n return matrix[s2.length][s1.length];\n}\n\n/**\n * Calculate similarity score (0-1) based on Levenshtein distance\n * 1.0 = identical, 0.0 = completely different\n */\nfunction similarityScore(str1: string, str2: string): number {\n const distance = levenshteinDistance(str1, str2);\n const maxLength = Math.max(str1.length, str2.length);\n if (maxLength === 0) return 1.0;\n return 1 - (distance / maxLength);\n}\n\ninterface EntityMatch<T extends Entity> {\n entity: T;\n score: number;\n matchType: 'exact_id' | 'exact_name' | 'fuzzy_id' | 'fuzzy_name';\n}\n\n/**\n * Generic resilient entity finder\n * Works for any entity type that has id and name properties\n */\nfunction findEntityResilient<T extends Entity>(\n allEntities: T[],\n query: string,\n entityTypeName: string\n): T {\n const queryLower = query.toLowerCase();\n const matches: EntityMatch<T>[] = [];\n \n for (const entity of allEntities) {\n const idLower = entity.id.toLowerCase();\n const nameLower = entity.name.toLowerCase();\n \n // 1. Exact ID match\n if (idLower === queryLower) {\n return entity; // Return immediately for exact match\n }\n \n // 2. Exact name match\n if (nameLower === queryLower) {\n matches.push({ entity, score: 1.0, matchType: 'exact_name' });\n continue;\n }\n \n // 3. Fuzzy ID match\n const idSimilarity = similarityScore(query, entity.id);\n if (idSimilarity >= 0.7) {\n matches.push({ entity, score: idSimilarity, matchType: 'fuzzy_id' });\n }\n \n // 4. Fuzzy name match\n const nameSimilarity = similarityScore(query, entity.name);\n if (nameSimilarity >= 0.7) {\n matches.push({ entity, score: nameSimilarity, matchType: 'fuzzy_name' });\n }\n }\n \n // If we found matches, return the best one\n if (matches.length > 0) {\n matches.sort((a, b) => {\n // Prefer exact matches over fuzzy\n if (a.matchType === 'exact_name' && b.matchType !== 'exact_name') return -1;\n if (b.matchType === 'exact_name' && a.matchType !== 'exact_name') return 1;\n // Then sort by score\n return b.score - a.score;\n });\n return matches[0].entity;\n }\n \n // No match found - build helpful error message\n const entityList = allEntities\n .map(e => ` - ${e.id} (${e.name})`)\n .join('\\n');\n \n throw new Error(\n `${entityTypeName} not found: \"${query}\"\\n\\n` +\n `Available ${entityTypeName.toLowerCase()}s:\\n${entityList}\\n\\n` +\n `Note: Matching is case-insensitive and supports fuzzy matching. ` +\n `Try using the ${entityTypeName.toLowerCase()} ID or name exactly as shown above.`\n );\n}\n\n/**\n * Find a project using resilient matching\n */\nexport function findProjectResilient(\n context: Context.ContextInstance,\n query: string\n): Project {\n const allProjects = context.getAllProjects();\n return findEntityResilient(allProjects, query, 'Project');\n}\n\n/**\n * Find a person using resilient matching\n */\nexport function findPersonResilient(\n context: Context.ContextInstance,\n query: string\n): Person {\n const allPeople = context.getAllPeople();\n return findEntityResilient(allPeople, query, 'Person');\n}\n\n/**\n * Find a company using resilient matching\n */\nexport function findCompanyResilient(\n context: Context.ContextInstance,\n query: string\n): Company {\n const allCompanies = context.getAllCompanies();\n return findEntityResilient(allCompanies, query, 'Company');\n}\n\n/**\n * Find a term using resilient matching\n */\nexport function findTermResilient(\n context: Context.ContextInstance,\n query: string\n): Term {\n const allTerms = context.getAllTerms();\n return findEntityResilient(allTerms, query, 'Term');\n}\n\n/**\n * Find an ignored term using resilient matching\n */\nexport function findIgnoredResilient(\n context: Context.ContextInstance,\n query: string\n): IgnoredTerm {\n const allIgnored = context.getAllIgnored();\n return findEntityResilient(allIgnored, query, 'Ignored term');\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index15.js","sources":["../src/util/metadata.ts"],"sourcesContent":["import * as Routing from '@/routing';\n\n// ============================================================================\n// Lifecycle Types\n// ============================================================================\n\n/**\n * Transcript lifecycle status\n * - initial: Whisper transcription complete\n * - enhanced: Context-aware enhancement complete\n * - reviewed: User has reviewed the transcript\n * - in_progress: Has outstanding tasks to complete\n * - closed: All work complete, no pending tasks\n * - archived: Archived for long-term storage\n */\nexport type TranscriptStatus = 'initial' | 'enhanced' | 'reviewed' | 'in_progress' | 'closed' | 'archived';\n\n/**\n * Record of a status transition with timestamp\n */\nexport interface StatusTransition {\n from: TranscriptStatus;\n to: TranscriptStatus;\n at: string; // ISO 8601 timestamp\n}\n\n/**\n * A follow-up task associated with a transcript\n */\nexport interface Task {\n id: string; // generated unique ID (e.g., task-1234567890-abc123)\n description: string;\n status: 'open' | 'done';\n created: string; // ISO 8601 timestamp\n changed?: string; // ISO 8601 timestamp - when last modified\n completed?: string; // ISO 8601 timestamp - when marked done\n}\n\n// ============================================================================\n// Entity Types\n// ============================================================================\n\nexport interface EntityReference {\n id: string;\n name: string;\n type: 'person' | 'project' | 'term' | 'company';\n}\n\nexport interface TranscriptMetadata {\n // UUID identifier\n id?: string;\n \n // Core fields\n title?: string;\n project?: string;\n projectId?: string;\n routing?: RoutingMetadata;\n tags?: string[];\n date?: Date;\n recordingTime?: string;\n confidence?: number;\n duration?: string;\n \n // Lifecycle fields\n status?: TranscriptStatus;\n history?: StatusTransition[];\n tasks?: Task[];\n \n // Entity references - entities mentioned/used in this transcript\n entities?: {\n people?: EntityReference[];\n projects?: EntityReference[];\n terms?: EntityReference[];\n companies?: EntityReference[];\n };\n}\n\nexport interface RoutingMetadata {\n destination: string;\n confidence: number;\n signals: Routing.ClassificationSignal[];\n reasoning: string;\n}\n\n/**\n * Format metadata as Markdown heading section\n */\nexport const formatMetadataMarkdown = (metadata: TranscriptMetadata): string => {\n const lines: string[] = [];\n \n // Title section\n if (metadata.title) {\n lines.push(`# ${metadata.title}`);\n lines.push('');\n }\n \n // Metadata frontmatter as readable markdown\n lines.push('## Metadata');\n lines.push('');\n \n // Date and Time\n if (metadata.date) {\n const dateStr = metadata.date.toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'long',\n day: 'numeric'\n });\n lines.push(`**Date**: ${dateStr}`);\n \n if (metadata.recordingTime) {\n lines.push(`**Time**: ${metadata.recordingTime}`);\n } else {\n const timeStr = metadata.date.toLocaleTimeString('en-US', {\n hour: '2-digit',\n minute: '2-digit',\n hour12: true\n });\n lines.push(`**Time**: ${timeStr}`);\n }\n }\n \n lines.push('');\n \n // Project\n if (metadata.project) {\n lines.push(`**Project**: ${metadata.project}`);\n if (metadata.projectId) {\n lines.push(`**Project ID**: \\`${metadata.projectId}\\``);\n }\n lines.push('');\n }\n \n // Routing Information\n if (metadata.routing) {\n lines.push('### Routing');\n lines.push('');\n lines.push(`**Destination**: ${metadata.routing.destination}`);\n lines.push(`**Confidence**: ${(metadata.routing.confidence * 100).toFixed(1)}%`);\n lines.push('');\n \n if (metadata.routing.signals.length > 0) {\n lines.push('**Classification Signals**:');\n for (const signal of metadata.routing.signals) {\n const signalType = signal.type.replace(/_/g, ' ');\n const weight = (signal.weight * 100).toFixed(0);\n lines.push(`- ${signalType}: \"${signal.value}\" (${weight}% weight)`);\n }\n lines.push('');\n }\n \n if (metadata.routing.reasoning) {\n lines.push(`**Reasoning**: ${metadata.routing.reasoning}`);\n lines.push('');\n }\n }\n \n // Tags\n if (metadata.tags && metadata.tags.length > 0) {\n lines.push('**Tags**: ' + metadata.tags.map(tag => `\\`${tag}\\``).join(', '));\n lines.push('');\n }\n \n // Duration\n if (metadata.duration) {\n lines.push(`**Duration**: ${metadata.duration}`);\n lines.push('');\n }\n \n // Separator\n lines.push('---');\n lines.push('');\n \n return lines.join('\\n');\n};\n\n/**\n * Format entity metadata as Markdown footer section\n * This goes at the END of the transcript for machine readability\n */\nexport const formatEntityMetadataMarkdown = (metadata: TranscriptMetadata): string => {\n if (!metadata.entities) {\n return '';\n }\n \n const lines: string[] = [];\n lines.push('');\n lines.push('---');\n lines.push('');\n lines.push('## Entity References');\n lines.push('');\n lines.push('<!-- Machine-readable entity metadata for indexing and querying -->');\n lines.push('');\n \n // People\n if (metadata.entities.people && metadata.entities.people.length > 0) {\n lines.push('### People');\n lines.push('');\n for (const person of metadata.entities.people) {\n lines.push(`- \\`${person.id}\\`: ${person.name}`);\n }\n lines.push('');\n }\n \n // Projects\n if (metadata.entities.projects && metadata.entities.projects.length > 0) {\n lines.push('### Projects');\n lines.push('');\n for (const project of metadata.entities.projects) {\n lines.push(`- \\`${project.id}\\`: ${project.name}`);\n }\n lines.push('');\n }\n \n // Terms\n if (metadata.entities.terms && metadata.entities.terms.length > 0) {\n lines.push('### Terms');\n lines.push('');\n for (const term of metadata.entities.terms) {\n lines.push(`- \\`${term.id}\\`: ${term.name}`);\n }\n lines.push('');\n }\n \n // Companies\n if (metadata.entities.companies && metadata.entities.companies.length > 0) {\n lines.push('### Companies');\n lines.push('');\n for (const company of metadata.entities.companies) {\n lines.push(`- \\`${company.id}\\`: ${company.name}`);\n }\n lines.push('');\n }\n \n return lines.join('\\n');\n};\n\n/**\n * Parse entity metadata from a transcript\n * Reads the Entity References section if present\n */\nexport const parseEntityMetadata = (content: string): TranscriptMetadata['entities'] | undefined => {\n // Find the Entity References section\n // Look for \"## Entity References\" and capture everything after it until the next \"##\" header or end of content\n const headerIndex = content.indexOf('## Entity References');\n if (headerIndex === -1) {\n return undefined;\n }\n \n // Find the start of the content (after the header and any whitespace/newlines)\n let contentStart = headerIndex + '## Entity References'.length;\n // Skip whitespace and newlines\n while (contentStart < content.length && (content[contentStart] === '\\n' || content[contentStart] === '\\r' || content[contentStart] === ' ' || content[contentStart] === '\\t')) {\n contentStart++;\n }\n \n // Find the end - look for next \"##\" at start of line or end of content\n const remainingContent = content.substring(contentStart);\n const nextHeaderMatch = remainingContent.match(/\\n## /);\n const sectionContent = nextHeaderMatch \n ? remainingContent.substring(0, nextHeaderMatch.index)\n : remainingContent;\n const entities: NonNullable<TranscriptMetadata['entities']> = {\n people: [],\n projects: [],\n terms: [],\n companies: [],\n };\n \n // Parse each entity type\n const parseEntities = (type: 'People' | 'Projects' | 'Terms' | 'Companies'): EntityReference[] => {\n // Map plural type names to singular entity types\n const typeMap: Record<string, 'person' | 'project' | 'term' | 'company'> = {\n 'People': 'person',\n 'Projects': 'project',\n 'Terms': 'term',\n 'Companies': 'company',\n };\n \n const entityType = typeMap[type];\n \n // Find the section for this type\n const sectionHeader = `### ${type}`;\n const sectionStart = sectionContent.indexOf(sectionHeader);\n if (sectionStart === -1) return [];\n \n // Find the end (next ### or end of content)\n // Skip past the header line (including newline)\n const headerEnd = sectionStart + sectionHeader.length;\n let sectionTextStart = headerEnd;\n // Skip whitespace and newlines after the header\n while (sectionTextStart < sectionContent.length && \n (sectionContent[sectionTextStart] === '\\n' || sectionContent[sectionTextStart] === '\\r' || sectionContent[sectionTextStart] === ' ')) {\n sectionTextStart++;\n }\n \n const afterSection = sectionContent.substring(sectionTextStart);\n const nextSection = afterSection.search(/\\n###/);\n const sectionText = nextSection === -1 ? afterSection : afterSection.substring(0, nextSection);\n \n // Extract items - match format: \"- `id`: name\"\n // Match bullet point with backticked ID and name\n const items: EntityReference[] = [];\n // Use multiline regex to match across lines, look for \"- `id`: name\" pattern\n const lines = sectionText.split('\\n');\n for (const line of lines) {\n const trimmed = line.trim();\n // Match: \"- `id`: name\" or \"- `id`:name\" (with or without space after colon)\n const match = trimmed.match(/^- `([^`]+)`:\\s*(.+)$/);\n if (match) {\n items.push({\n id: match[1],\n name: match[2].trim(),\n type: entityType,\n });\n }\n }\n \n return items;\n };\n \n entities.people = parseEntities('People');\n entities.projects = parseEntities('Projects');\n entities.terms = parseEntities('Terms');\n entities.companies = parseEntities('Companies');\n \n // Only return if we found any entities\n const hasEntities = \n entities.people.length > 0 ||\n entities.projects.length > 0 ||\n entities.terms.length > 0 ||\n entities.companies.length > 0;\n \n return hasEntities ? entities : undefined;\n};\n\n/**\n * Extract routing metadata from a RouteDecision\n */\nexport const createRoutingMetadata = (decision: Routing.RouteDecision): RoutingMetadata => {\n return {\n destination: decision.destination.path,\n confidence: decision.confidence,\n signals: decision.signals,\n reasoning: decision.reasoning,\n };\n};\n\n/**\n * Format duration in seconds to readable format (e.g., \"2m 30s\")\n */\nexport const formatDuration = (seconds: number): string => {\n const minutes = Math.floor(seconds / 60);\n const secs = Math.round(seconds % 60);\n \n if (minutes === 0) {\n return `${secs}s`;\n }\n \n if (secs === 0) {\n return `${minutes}m`;\n }\n \n return `${minutes}m ${secs}s`;\n};\n\n/**\n * Format time as HH:MM AM/PM\n */\nexport const formatTime = (date: Date): string => {\n return date.toLocaleTimeString('en-US', {\n hour: '2-digit',\n minute: '2-digit',\n hour12: true\n });\n};\n\n/**\n * Extract topic from routing signals\n */\nexport const extractTopicFromSignals = (signals: Routing.ClassificationSignal[]): string | undefined => {\n const topicSignal = signals.find(s => s.type === 'topic' || s.type === 'context_type');\n return topicSignal?.value;\n};\n\n/**\n * Extract all tags from routing signals\n * Tags are deduplicated to avoid duplicates from multiple signal sources\n */\nexport const extractTagsFromSignals = (signals: Routing.ClassificationSignal[]): string[] => {\n const tags = signals\n .filter(s => s.type !== 'context_type') // Skip generic context type\n .map(s => s.value)\n .filter((v): v is string => typeof v === 'string');\n \n // Deduplicate tags using Set\n return Array.from(new Set(tags));\n};\n\n// ============================================================================\n// Lifecycle Utilities\n// ============================================================================\n\n/**\n * Valid transcript statuses for validation\n */\nexport const VALID_STATUSES: TranscriptStatus[] = [\n 'initial', 'enhanced', 'reviewed', 'in_progress', 'closed', 'archived'\n];\n\n/**\n * Check if a string is a valid TranscriptStatus\n */\nexport const isValidStatus = (status: string): status is TranscriptStatus => {\n return VALID_STATUSES.includes(status as TranscriptStatus);\n};\n\n/**\n * Generate a unique task ID\n */\nexport const generateTaskId = (): string => {\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 8);\n return `task-${timestamp}-${random}`;\n};\n\n/**\n * Create a new task\n */\nexport const createTask = (description: string): Task => {\n return {\n id: generateTaskId(),\n description,\n status: 'open',\n created: new Date().toISOString(),\n };\n};\n\n/**\n * Update transcript status and record the transition in history\n * Returns unchanged metadata if status is the same (no duplicate history)\n */\nexport const updateStatus = (\n metadata: TranscriptMetadata,\n newStatus: TranscriptStatus\n): TranscriptMetadata => {\n const oldStatus = metadata.status;\n \n // Don't add duplicate history if status unchanged\n if (oldStatus === newStatus) {\n return metadata;\n }\n \n const transition: StatusTransition = {\n from: oldStatus || 'reviewed',\n to: newStatus,\n at: new Date().toISOString(),\n };\n \n return {\n ...metadata,\n status: newStatus,\n history: [...(metadata.history || []), transition],\n };\n};\n\n/**\n * Apply default lifecycle fields to metadata\n * Used during lazy migration of old-format transcripts\n */\nexport const applyLifecycleDefaults = (metadata: TranscriptMetadata): TranscriptMetadata => {\n return {\n ...metadata,\n status: metadata.status ?? 'reviewed',\n history: metadata.history ?? [],\n tasks: metadata.tasks ?? [],\n };\n};\n\n/**\n * Complete a task by ID\n */\nexport const completeTask = (metadata: TranscriptMetadata, taskId: string): TranscriptMetadata => {\n const tasks = metadata.tasks || [];\n const taskIndex = tasks.findIndex(t => t.id === taskId);\n \n if (taskIndex === -1) {\n throw new Error(`Task not found: ${taskId}`);\n }\n \n const now = new Date().toISOString();\n const updatedTasks = [...tasks];\n updatedTasks[taskIndex] = {\n ...updatedTasks[taskIndex],\n status: 'done',\n changed: now,\n completed: now,\n };\n \n return {\n ...metadata,\n tasks: updatedTasks,\n };\n};\n\n/**\n * Delete a task by ID\n */\nexport const deleteTask = (metadata: TranscriptMetadata, taskId: string): TranscriptMetadata => {\n const tasks = metadata.tasks || [];\n const taskIndex = tasks.findIndex(t => t.id === taskId);\n \n if (taskIndex === -1) {\n throw new Error(`Task not found: ${taskId}`);\n }\n \n return {\n ...metadata,\n tasks: tasks.filter(t => t.id !== taskId),\n };\n};\n\n/**\n * Add a task to metadata\n */\nexport const addTask = (metadata: TranscriptMetadata, description: string): { metadata: TranscriptMetadata; task: Task } => {\n const task = createTask(description);\n \n return {\n metadata: {\n ...metadata,\n tasks: [...(metadata.tasks || []), task],\n },\n task,\n };\n};\n\n\n"],"names":[],"mappings":"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"}
|