@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/index16.js
CHANGED
|
@@ -1,107 +1,100 @@
|
|
|
1
|
-
|
|
1
|
+
function levenshteinDistance(str1, str2) {
|
|
2
|
+
const s1 = str1.toLowerCase();
|
|
3
|
+
const s2 = str2.toLowerCase();
|
|
4
|
+
if (s1 === s2) return 0;
|
|
5
|
+
if (s1.length === 0) return s2.length;
|
|
6
|
+
if (s2.length === 0) return s1.length;
|
|
7
|
+
const matrix = [];
|
|
8
|
+
for (let i = 0; i <= s2.length; i++) {
|
|
9
|
+
matrix[i] = [i];
|
|
10
|
+
}
|
|
11
|
+
for (let j = 0; j <= s1.length; j++) {
|
|
12
|
+
matrix[0][j] = j;
|
|
13
|
+
}
|
|
14
|
+
for (let i = 1; i <= s2.length; i++) {
|
|
15
|
+
for (let j = 1; j <= s1.length; j++) {
|
|
16
|
+
if (s2.charAt(i - 1) === s1.charAt(j - 1)) {
|
|
17
|
+
matrix[i][j] = matrix[i - 1][j - 1];
|
|
18
|
+
} else {
|
|
19
|
+
matrix[i][j] = Math.min(
|
|
20
|
+
matrix[i - 1][j - 1] + 1,
|
|
21
|
+
// substitution
|
|
22
|
+
matrix[i][j - 1] + 1,
|
|
23
|
+
// insertion
|
|
24
|
+
matrix[i - 1][j] + 1
|
|
25
|
+
// deletion
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return matrix[s2.length][s1.length];
|
|
31
|
+
}
|
|
32
|
+
function similarityScore(str1, str2) {
|
|
33
|
+
const distance = levenshteinDistance(str1, str2);
|
|
34
|
+
const maxLength = Math.max(str1.length, str2.length);
|
|
35
|
+
if (maxLength === 0) return 1;
|
|
36
|
+
return 1 - distance / maxLength;
|
|
37
|
+
}
|
|
38
|
+
function findEntityResilient(allEntities, query, entityTypeName) {
|
|
39
|
+
const queryLower = query.toLowerCase();
|
|
40
|
+
const matches = [];
|
|
41
|
+
for (const entity of allEntities) {
|
|
42
|
+
const idLower = entity.id.toLowerCase();
|
|
43
|
+
const nameLower = entity.name.toLowerCase();
|
|
44
|
+
if (idLower === queryLower) {
|
|
45
|
+
return entity;
|
|
46
|
+
}
|
|
47
|
+
if (nameLower === queryLower) {
|
|
48
|
+
matches.push({ entity, score: 1, matchType: "exact_name" });
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
const idSimilarity = similarityScore(query, entity.id);
|
|
52
|
+
if (idSimilarity >= 0.7) {
|
|
53
|
+
matches.push({ entity, score: idSimilarity, matchType: "fuzzy_id" });
|
|
54
|
+
}
|
|
55
|
+
const nameSimilarity = similarityScore(query, entity.name);
|
|
56
|
+
if (nameSimilarity >= 0.7) {
|
|
57
|
+
matches.push({ entity, score: nameSimilarity, matchType: "fuzzy_name" });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (matches.length > 0) {
|
|
61
|
+
matches.sort((a, b) => {
|
|
62
|
+
if (a.matchType === "exact_name" && b.matchType !== "exact_name") return -1;
|
|
63
|
+
if (b.matchType === "exact_name" && a.matchType !== "exact_name") return 1;
|
|
64
|
+
return b.score - a.score;
|
|
65
|
+
});
|
|
66
|
+
return matches[0].entity;
|
|
67
|
+
}
|
|
68
|
+
const entityList = allEntities.map((e) => ` - ${e.id} (${e.name})`).join("\n");
|
|
69
|
+
throw new Error(
|
|
70
|
+
`${entityTypeName} not found: "${query}"
|
|
2
71
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const DEFAULT_BINARY_TO_TEXT_ENCODING = "base64";
|
|
6
|
-
const DEFAULT_DIFF = true;
|
|
7
|
-
const DEFAULT_LOG = false;
|
|
8
|
-
const DEFAULT_TIMEZONE = "Etc/UTC";
|
|
9
|
-
const DATE_FORMAT_MONTH_DAY = "M-D";
|
|
10
|
-
const DATE_FORMAT_YEAR = "YYYY";
|
|
11
|
-
const DATE_FORMAT_YEAR_MONTH = "YYYY-M";
|
|
12
|
-
const DATE_FORMAT_YEAR_MONTH_DAY = "YYYY-M-D";
|
|
13
|
-
const DATE_FORMAT_YEAR_MONTH_DAY_SLASH = "YYYY/M/D";
|
|
14
|
-
const DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES = "YYYY-M-D-HHmm";
|
|
15
|
-
const DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS = "YYYY-M-D-HHmmss";
|
|
16
|
-
const DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS_MILLISECONDS = "YYYY-M-D-HHmmss.SSS";
|
|
17
|
-
const DATE_FORMAT_MONTH = "M";
|
|
18
|
-
const DATE_FORMAT_DAY = "D";
|
|
19
|
-
const DATE_FORMAT_HOURS = "HHmm";
|
|
20
|
-
const DATE_FORMAT_MINUTES = "mm";
|
|
21
|
-
const DATE_FORMAT_SECONDS = "ss";
|
|
22
|
-
const DATE_FORMAT_MILLISECONDS = "SSS";
|
|
23
|
-
const DEFAULT_VERBOSE = false;
|
|
24
|
-
const DEFAULT_DRY_RUN = false;
|
|
25
|
-
const DEFAULT_DEBUG = false;
|
|
26
|
-
const DEFAULT_CONTENT_TYPES = ["diff"];
|
|
27
|
-
const DEFAULT_RECURSIVE = false;
|
|
28
|
-
const DEFAULT_INPUT_DIRECTORY = "./";
|
|
29
|
-
const DEFAULT_OUTPUT_DIRECTORY = "./";
|
|
30
|
-
const DEFAULT_AUDIO_EXTENSIONS = ["mp3", "mp4", "mpeg", "mpga", "m4a", "wav", "webm", "qta"];
|
|
31
|
-
const ALLOWED_CONTENT_TYPES = ["log", "diff"];
|
|
32
|
-
const ALLOWED_AUDIO_EXTENSIONS = ["mp3", "mp4", "mpeg", "mpga", "m4a", "wav", "webm", "qta"];
|
|
33
|
-
const DEFAULT_OUTPUT_STRUCTURE = "month";
|
|
34
|
-
const DEFAULT_OUTPUT_FILENAME_OPTIONS = ["date", "time", "subject"];
|
|
35
|
-
const ALLOWED_OUTPUT_STRUCTURES = ["none", "year", "month", "day"];
|
|
36
|
-
const ALLOWED_OUTPUT_FILENAME_OPTIONS = ["date", "time", "subject"];
|
|
37
|
-
const DEFAULT_CONFIG_DIR = `./.${PROGRAM_NAME}`;
|
|
38
|
-
const DEFAULT_PROCESSED_DIR = "./processed";
|
|
39
|
-
const DEFAULT_CONTEXT_DIR_NAME = ".protokoll";
|
|
40
|
-
const DEFAULT_CONTEXT_NAMESPACE = "redaksjon";
|
|
41
|
-
const DEFAULT_CONTEXT_CONFIG_FILE_NAME = "config.yaml";
|
|
42
|
-
const DEFAULT_MAX_DISCOVERY_LEVELS = 10;
|
|
43
|
-
const CONTEXT_SUBDIRECTORIES = {
|
|
44
|
-
people: "people",
|
|
45
|
-
projects: "projects",
|
|
46
|
-
companies: "companies",
|
|
47
|
-
terms: "terms"
|
|
48
|
-
};
|
|
49
|
-
const DEFAULT_PERSONAS_DIR = `/personas`;
|
|
50
|
-
const DEFAULT_PERSONA_TRANSCRIBER_FILE = `${DEFAULT_PERSONAS_DIR}/transcriber.md`;
|
|
51
|
-
const DEFAULT_INSTRUCTIONS_DIR = `/instructions`;
|
|
52
|
-
const DEFAULT_INSTRUCTIONS_TRANSCRIBE_FILE = `${DEFAULT_INSTRUCTIONS_DIR}/transcribe.md`;
|
|
53
|
-
const DEFAULT_TRANSCRIPTION_MODEL = "whisper-1";
|
|
54
|
-
const DEFAULT_MODEL = "gpt-5.2";
|
|
55
|
-
const DEFAULT_REASONING_LEVEL = "medium";
|
|
56
|
-
const DEFAULT_PHONETIC_MODEL = "gpt-5-nano";
|
|
57
|
-
const DEFAULT_ANALYSIS_MODEL = "gpt-5-mini";
|
|
58
|
-
const DEFAULT_SMART_ASSISTANCE = true;
|
|
59
|
-
const DEFAULT_SOUNDS_LIKE_ON_ADD = true;
|
|
60
|
-
const DEFAULT_TRIGGER_PHRASES_ON_ADD = true;
|
|
61
|
-
const DEFAULT_PROMPT_FOR_SOURCE = true;
|
|
62
|
-
const DEFAULT_TERMS_ENABLED = true;
|
|
63
|
-
const DEFAULT_TERM_SOUNDS_LIKE_ON_ADD = true;
|
|
64
|
-
const DEFAULT_TERM_DESCRIPTION_ON_ADD = true;
|
|
65
|
-
const DEFAULT_TERM_TOPICS_ON_ADD = true;
|
|
66
|
-
const DEFAULT_TERM_PROJECT_SUGGESTIONS = true;
|
|
67
|
-
const MAX_CONTENT_LENGTH = 15e3;
|
|
68
|
-
const MAX_TERM_CONTEXT_LENGTH = 1e4;
|
|
69
|
-
const ASSIST_TIMEOUT_MS = 3e4;
|
|
70
|
-
const TERM_ASSIST_TIMEOUT_MS = 2e4;
|
|
71
|
-
const DEFAULT_OVERRIDES = false;
|
|
72
|
-
const DEFAULT_MAX_AUDIO_SIZE = 26214400;
|
|
73
|
-
const DEFAULT_TEMP_DIRECTORY = os__default.tmpdir();
|
|
74
|
-
const DEFAULT_INTERACTIVE = true;
|
|
75
|
-
const DEFAULT_SELF_REFLECTION = true;
|
|
76
|
-
const DEFAULT_SILENT = false;
|
|
77
|
-
const DEFAULT_INTERMEDIATE_DIRECTORY = "./output/protokoll";
|
|
78
|
-
const DEFAULT_KEEP_INTERMEDIATES = true;
|
|
79
|
-
const OUTPUT_FILE_TYPES = [
|
|
80
|
-
"transcript",
|
|
81
|
-
"context",
|
|
82
|
-
"request",
|
|
83
|
-
"response",
|
|
84
|
-
"reflection",
|
|
85
|
-
"session"
|
|
86
|
-
];
|
|
87
|
-
const PROTOKOLL_DEFAULTS = {
|
|
88
|
-
dryRun: DEFAULT_DRY_RUN,
|
|
89
|
-
verbose: DEFAULT_VERBOSE,
|
|
90
|
-
debug: DEFAULT_DEBUG,
|
|
91
|
-
diff: DEFAULT_DIFF,
|
|
92
|
-
log: DEFAULT_LOG,
|
|
93
|
-
transcriptionModel: DEFAULT_TRANSCRIPTION_MODEL,
|
|
94
|
-
model: DEFAULT_MODEL,
|
|
95
|
-
reasoningLevel: DEFAULT_REASONING_LEVEL,
|
|
96
|
-
contentTypes: DEFAULT_CONTENT_TYPES,
|
|
97
|
-
overrides: DEFAULT_OVERRIDES,
|
|
98
|
-
maxAudioSize: DEFAULT_MAX_AUDIO_SIZE,
|
|
99
|
-
tempDirectory: DEFAULT_TEMP_DIRECTORY || os__default.tmpdir(),
|
|
100
|
-
configDirectory: DEFAULT_CONFIG_DIR,
|
|
101
|
-
interactive: DEFAULT_INTERACTIVE,
|
|
102
|
-
selfReflection: DEFAULT_SELF_REFLECTION,
|
|
103
|
-
silent: DEFAULT_SILENT
|
|
104
|
-
};
|
|
72
|
+
Available ${entityTypeName.toLowerCase()}s:
|
|
73
|
+
${entityList}
|
|
105
74
|
|
|
106
|
-
|
|
75
|
+
Note: Matching is case-insensitive and supports fuzzy matching. Try using the ${entityTypeName.toLowerCase()} ID or name exactly as shown above.`
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
function findProjectResilient(context, query) {
|
|
79
|
+
const allProjects = context.getAllProjects();
|
|
80
|
+
return findEntityResilient(allProjects, query, "Project");
|
|
81
|
+
}
|
|
82
|
+
function findPersonResilient(context, query) {
|
|
83
|
+
const allPeople = context.getAllPeople();
|
|
84
|
+
return findEntityResilient(allPeople, query, "Person");
|
|
85
|
+
}
|
|
86
|
+
function findCompanyResilient(context, query) {
|
|
87
|
+
const allCompanies = context.getAllCompanies();
|
|
88
|
+
return findEntityResilient(allCompanies, query, "Company");
|
|
89
|
+
}
|
|
90
|
+
function findTermResilient(context, query) {
|
|
91
|
+
const allTerms = context.getAllTerms();
|
|
92
|
+
return findEntityResilient(allTerms, query, "Term");
|
|
93
|
+
}
|
|
94
|
+
function findIgnoredResilient(context, query) {
|
|
95
|
+
const allIgnored = context.getAllIgnored();
|
|
96
|
+
return findEntityResilient(allIgnored, query, "Ignored term");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export { findCompanyResilient, findIgnoredResilient, findPersonResilient, findProjectResilient, findTermResilient };
|
|
107
100
|
//# sourceMappingURL=index16.js.map
|
package/dist/index16.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index16.js","sources":["../src/
|
|
1
|
+
{"version":3,"file":"index16.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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"}
|
package/dist/index17.js
CHANGED
|
@@ -1,185 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return client;
|
|
12
|
-
};
|
|
13
|
-
const getModelFamily = (model) => {
|
|
14
|
-
if (model.startsWith("gpt") || model.startsWith("o1") || model.startsWith("o3")) return "openai";
|
|
15
|
-
if (model.startsWith("claude")) return "anthropic";
|
|
16
|
-
if (model.startsWith("gemini")) return "gemini";
|
|
17
|
-
return "unknown";
|
|
18
|
-
};
|
|
19
|
-
const isReasoningModel = (model) => {
|
|
20
|
-
const reasoningModels = [
|
|
21
|
-
"gpt-4o",
|
|
22
|
-
"gpt-4-turbo",
|
|
23
|
-
"gpt-5",
|
|
24
|
-
"gpt-5-mini",
|
|
25
|
-
"gpt-5.1",
|
|
26
|
-
"gpt-5.2",
|
|
27
|
-
"o1",
|
|
28
|
-
"o1-mini",
|
|
29
|
-
"o1-preview",
|
|
30
|
-
"o3",
|
|
31
|
-
"o3-mini",
|
|
32
|
-
"claude-3-5-sonnet",
|
|
33
|
-
"claude-3-opus",
|
|
34
|
-
"claude-4"
|
|
35
|
-
];
|
|
36
|
-
return reasoningModels.some((rm) => model.includes(rm));
|
|
37
|
-
};
|
|
38
|
-
const supportsReasoningLevel = (model) => {
|
|
39
|
-
const models = ["gpt-5.1", "gpt-5.2", "o1", "o1-mini", "o3", "o3-mini"];
|
|
40
|
-
return models.some((m) => model.includes(m));
|
|
41
|
-
};
|
|
42
|
-
const complete = async (request) => {
|
|
43
|
-
const startTime = Date.now();
|
|
44
|
-
logger.debug("Reasoning request starting", { model: config.model });
|
|
45
|
-
try {
|
|
46
|
-
const messages = [];
|
|
47
|
-
if (request.systemPrompt) {
|
|
48
|
-
messages.push({ role: "system", content: request.systemPrompt });
|
|
49
|
-
}
|
|
50
|
-
messages.push({ role: "user", content: request.prompt });
|
|
51
|
-
const tools = request.tools?.map((tool) => ({
|
|
52
|
-
type: "function",
|
|
53
|
-
function: {
|
|
54
|
-
name: tool.name,
|
|
55
|
-
description: tool.description,
|
|
56
|
-
parameters: tool.parameters
|
|
57
|
-
}
|
|
58
|
-
}));
|
|
59
|
-
const requestOptions = {
|
|
60
|
-
model: config.model,
|
|
61
|
-
messages,
|
|
62
|
-
tools: tools && tools.length > 0 ? tools : void 0,
|
|
63
|
-
tool_choice: tools && tools.length > 0 ? "auto" : void 0
|
|
64
|
-
};
|
|
65
|
-
if (supportsReasoningLevel(config.model)) {
|
|
66
|
-
const reasoningLevel = config.reasoningLevel || "medium";
|
|
67
|
-
requestOptions.reasoning_effort = reasoningLevel;
|
|
68
|
-
logger.debug("Using reasoning_effort: %s for model %s", reasoningLevel, config.model);
|
|
69
|
-
}
|
|
70
|
-
const response = await getClient().chat.completions.create(
|
|
71
|
-
requestOptions
|
|
72
|
-
);
|
|
73
|
-
const duration = Date.now() - startTime;
|
|
74
|
-
logger.debug("Reasoning model responded in %dms", duration);
|
|
75
|
-
const choice = response.choices[0];
|
|
76
|
-
const message = choice.message;
|
|
77
|
-
const usage = response.usage ? {
|
|
78
|
-
promptTokens: response.usage.prompt_tokens,
|
|
79
|
-
completionTokens: response.usage.completion_tokens,
|
|
80
|
-
totalTokens: response.usage.total_tokens
|
|
81
|
-
} : void 0;
|
|
82
|
-
const toolCalls = message.tool_calls?.map((tc) => {
|
|
83
|
-
const fn = "function" in tc ? tc.function : null;
|
|
84
|
-
if (!fn) {
|
|
85
|
-
return { id: tc.id, name: "unknown", arguments: {} };
|
|
86
|
-
}
|
|
87
|
-
return {
|
|
88
|
-
id: tc.id,
|
|
89
|
-
name: fn.name,
|
|
90
|
-
arguments: JSON.parse(fn.arguments)
|
|
91
|
-
};
|
|
92
|
-
});
|
|
93
|
-
if (toolCalls && toolCalls.length > 0) {
|
|
94
|
-
logger.debug("Model requested %d tool calls: %s", toolCalls.length, toolCalls.map((t) => t.name).join(", "));
|
|
95
|
-
}
|
|
96
|
-
return {
|
|
97
|
-
content: message.content || "",
|
|
98
|
-
model: config.model,
|
|
99
|
-
duration,
|
|
100
|
-
usage,
|
|
101
|
-
toolCalls,
|
|
102
|
-
finishReason: choice.finish_reason
|
|
103
|
-
};
|
|
104
|
-
} catch (error) {
|
|
105
|
-
logger.error("Reasoning request failed", { error });
|
|
106
|
-
throw error;
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
const completeWithTools = async (request) => {
|
|
110
|
-
logger.debug("Tool call request starting", { model: config.model, messageCount: request.messages.length });
|
|
111
|
-
try {
|
|
112
|
-
const messages = request.messages.map((msg) => {
|
|
113
|
-
if (msg.role === "tool") {
|
|
114
|
-
return {
|
|
115
|
-
role: "tool",
|
|
116
|
-
content: msg.content,
|
|
117
|
-
tool_call_id: msg.tool_call_id || ""
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
if (msg.role === "assistant" && msg.tool_calls) {
|
|
121
|
-
return {
|
|
122
|
-
role: "assistant",
|
|
123
|
-
content: msg.content || null,
|
|
124
|
-
tool_calls: msg.tool_calls.map((tc) => ({
|
|
125
|
-
id: tc.id,
|
|
126
|
-
type: "function",
|
|
127
|
-
function: tc.function
|
|
128
|
-
}))
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
return {
|
|
132
|
-
role: msg.role,
|
|
133
|
-
content: msg.content
|
|
134
|
-
};
|
|
135
|
-
});
|
|
136
|
-
const requestOptions = {
|
|
137
|
-
model: config.model,
|
|
138
|
-
messages,
|
|
139
|
-
tools: request.tools,
|
|
140
|
-
tool_choice: request.tools && request.tools.length > 0 ? "auto" : void 0
|
|
141
|
-
};
|
|
142
|
-
if (supportsReasoningLevel(config.model)) {
|
|
143
|
-
requestOptions.reasoning_effort = config.reasoningLevel || "medium";
|
|
144
|
-
}
|
|
145
|
-
const response = await getClient().chat.completions.create(
|
|
146
|
-
requestOptions
|
|
147
|
-
);
|
|
148
|
-
const choice = response.choices[0];
|
|
149
|
-
const message = choice.message;
|
|
150
|
-
const toolCalls = message.tool_calls?.map((tc) => {
|
|
151
|
-
const fn = "function" in tc ? tc.function : null;
|
|
152
|
-
if (!fn) {
|
|
153
|
-
return { id: tc.id, function: { name: "unknown", arguments: "{}" } };
|
|
154
|
-
}
|
|
155
|
-
return {
|
|
156
|
-
id: tc.id,
|
|
157
|
-
function: {
|
|
158
|
-
name: fn.name,
|
|
159
|
-
arguments: fn.arguments
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
});
|
|
163
|
-
if (toolCalls && toolCalls.length > 0) {
|
|
164
|
-
logger.debug("Model requested %d tool calls: %s", toolCalls.length, toolCalls.map((t) => t.function.name).join(", "));
|
|
165
|
-
}
|
|
166
|
-
return {
|
|
167
|
-
content: message.content || "",
|
|
168
|
-
tool_calls: toolCalls,
|
|
169
|
-
finish_reason: choice.finish_reason
|
|
170
|
-
};
|
|
171
|
-
} catch (error) {
|
|
172
|
-
logger.error("Tool call request failed", { error });
|
|
173
|
-
throw error;
|
|
1
|
+
function createEnhancementLogger(manager) {
|
|
2
|
+
return {
|
|
3
|
+
logStep(phase, action, details, entities) {
|
|
4
|
+
manager.logStep(/* @__PURE__ */ new Date(), phase, action, details, entities);
|
|
5
|
+
},
|
|
6
|
+
logSteps(steps) {
|
|
7
|
+
manager.logSteps(steps.map((step) => ({
|
|
8
|
+
...step,
|
|
9
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
10
|
+
})));
|
|
174
11
|
}
|
|
175
12
|
};
|
|
13
|
+
}
|
|
14
|
+
function createNoOpLogger() {
|
|
176
15
|
return {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
16
|
+
logStep() {
|
|
17
|
+
},
|
|
18
|
+
logSteps() {
|
|
19
|
+
}
|
|
181
20
|
};
|
|
182
|
-
}
|
|
21
|
+
}
|
|
183
22
|
|
|
184
|
-
export {
|
|
23
|
+
export { createEnhancementLogger, createNoOpLogger };
|
|
185
24
|
//# sourceMappingURL=index17.js.map
|
package/dist/index17.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index17.js","sources":["../src/reasoning/client.ts"],"sourcesContent":["/**\n * Reasoning Client\n * \n * Wrapper for reasoning model calls with tool/function calling support.\n * Uses OpenAI's native function calling for agentic workflows.\n */\n\nimport OpenAI from 'openai';\nimport { ReasoningConfig, ReasoningRequest, ReasoningResponse, ToolCall } from './types';\nimport * as Logging from '../logging';\n\nexport interface ToolCallRequest {\n messages: Array<{\n role: 'system' | 'user' | 'assistant' | 'tool';\n content: string;\n tool_call_id?: string;\n tool_calls?: Array<{ id: string; function: { name: string; arguments: string } }>;\n }>;\n tools?: Array<{\n type: 'function';\n function: {\n name: string;\n description: string;\n parameters: Record<string, unknown>;\n };\n }>;\n}\n\nexport interface ToolCallResponse {\n content: string;\n tool_calls?: Array<{\n id: string;\n function: {\n name: string;\n arguments: string;\n };\n }>;\n finish_reason?: string;\n}\n\nexport interface ClientInstance {\n complete(request: ReasoningRequest): Promise<ReasoningResponse>;\n completeWithTools(request: ToolCallRequest): Promise<ToolCallResponse>;\n isReasoningModel(model: string): boolean;\n getModelFamily(model: string): 'openai' | 'anthropic' | 'gemini' | 'unknown';\n}\n\nexport const create = (config: ReasoningConfig): ClientInstance => {\n const logger = Logging.getLogger();\n \n // Lazy-initialize OpenAI client (only when actually needed)\n let client: OpenAI | null = null;\n const getClient = (): OpenAI => {\n if (!client) {\n client = new OpenAI({ apiKey: config.apiKey });\n }\n return client;\n };\n \n const getModelFamily = (model: string): 'openai' | 'anthropic' | 'gemini' | 'unknown' => {\n if (model.startsWith('gpt') || model.startsWith('o1') || model.startsWith('o3')) return 'openai';\n if (model.startsWith('claude')) return 'anthropic';\n if (model.startsWith('gemini')) return 'gemini';\n return 'unknown';\n };\n \n const isReasoningModel = (model: string): boolean => {\n // Models known for strong reasoning\n const reasoningModels = [\n 'gpt-4o', 'gpt-4-turbo', 'gpt-5', 'gpt-5-mini', 'gpt-5.1', 'gpt-5.2',\n 'o1', 'o1-mini', 'o1-preview', 'o3', 'o3-mini',\n 'claude-3-5-sonnet', 'claude-3-opus', 'claude-4',\n ];\n return reasoningModels.some(rm => model.includes(rm));\n };\n \n const supportsReasoningLevel = (model: string): boolean => {\n // Models that support reasoning_effort parameter\n const models = ['gpt-5.1', 'gpt-5.2', 'o1', 'o1-mini', 'o3', 'o3-mini'];\n return models.some(m => model.includes(m));\n };\n \n const complete = async (request: ReasoningRequest): Promise<ReasoningResponse> => {\n const startTime = Date.now();\n logger.debug('Reasoning request starting', { model: config.model });\n \n try {\n // Build messages for OpenAI\n const messages: Array<OpenAI.Chat.ChatCompletionMessageParam> = [];\n \n if (request.systemPrompt) {\n messages.push({ role: 'system', content: request.systemPrompt });\n }\n \n // Add the main prompt\n messages.push({ role: 'user', content: request.prompt });\n \n // Build tools if provided\n const tools: OpenAI.Chat.ChatCompletionTool[] | undefined = request.tools?.map(tool => ({\n type: 'function' as const,\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n },\n }));\n \n // Build request options\n const requestOptions: Record<string, unknown> = {\n model: config.model,\n messages,\n tools: tools && tools.length > 0 ? tools : undefined,\n tool_choice: tools && tools.length > 0 ? 'auto' : undefined,\n };\n \n // Add reasoning_effort for models that support it (default to 'medium')\n if (supportsReasoningLevel(config.model)) {\n const reasoningLevel = config.reasoningLevel || 'medium';\n requestOptions.reasoning_effort = reasoningLevel;\n logger.debug('Using reasoning_effort: %s for model %s', reasoningLevel, config.model);\n }\n \n const response = await getClient().chat.completions.create(\n requestOptions as unknown as OpenAI.Chat.ChatCompletionCreateParamsNonStreaming\n );\n \n const duration = Date.now() - startTime;\n logger.debug('Reasoning model responded in %dms', duration);\n \n const choice = response.choices[0];\n const message = choice.message;\n \n // Extract token usage\n const usage = response.usage ? {\n promptTokens: response.usage.prompt_tokens,\n completionTokens: response.usage.completion_tokens,\n totalTokens: response.usage.total_tokens,\n } : undefined;\n \n // Extract tool calls if any\n const toolCalls: ToolCall[] | undefined = message.tool_calls?.map(tc => {\n // Handle both standard and custom tool call formats\n const fn = 'function' in tc ? tc.function : null;\n if (!fn) {\n return { id: tc.id, name: 'unknown', arguments: {} };\n }\n return {\n id: tc.id,\n name: fn.name,\n arguments: JSON.parse(fn.arguments),\n };\n });\n \n if (toolCalls && toolCalls.length > 0) {\n logger.debug('Model requested %d tool calls: %s', toolCalls.length, toolCalls.map(t => t.name).join(', '));\n }\n \n return {\n content: message.content || '',\n model: config.model,\n duration,\n usage,\n toolCalls,\n finishReason: choice.finish_reason,\n };\n } catch (error) {\n logger.error('Reasoning request failed', { error });\n throw error;\n }\n };\n \n const completeWithTools = async (request: ToolCallRequest): Promise<ToolCallResponse> => {\n logger.debug('Tool call request starting', { model: config.model, messageCount: request.messages.length });\n \n try {\n // Convert messages to OpenAI format\n const messages: Array<OpenAI.Chat.ChatCompletionMessageParam> = request.messages.map(msg => {\n if (msg.role === 'tool') {\n return {\n role: 'tool' as const,\n content: msg.content,\n tool_call_id: msg.tool_call_id || '',\n };\n }\n if (msg.role === 'assistant' && msg.tool_calls) {\n return {\n role: 'assistant' as const,\n content: msg.content || null,\n tool_calls: msg.tool_calls.map(tc => ({\n id: tc.id,\n type: 'function' as const,\n function: tc.function,\n })),\n };\n }\n return {\n role: msg.role as 'system' | 'user' | 'assistant',\n content: msg.content,\n };\n });\n \n // Build request options\n const requestOptions: Record<string, unknown> = {\n model: config.model,\n messages,\n tools: request.tools,\n tool_choice: request.tools && request.tools.length > 0 ? 'auto' : undefined,\n };\n \n // Add reasoning_effort for models that support it\n if (supportsReasoningLevel(config.model)) {\n requestOptions.reasoning_effort = config.reasoningLevel || 'medium';\n }\n \n const response = await getClient().chat.completions.create(\n requestOptions as unknown as OpenAI.Chat.ChatCompletionCreateParamsNonStreaming\n );\n \n const choice = response.choices[0];\n const message = choice.message;\n \n // Extract tool calls if any\n const toolCalls = message.tool_calls?.map(tc => {\n // Handle both standard and custom tool call formats\n const fn = 'function' in tc ? tc.function : null;\n if (!fn) {\n return { id: tc.id, function: { name: 'unknown', arguments: '{}' } };\n }\n return {\n id: tc.id,\n function: {\n name: fn.name,\n arguments: fn.arguments,\n },\n };\n });\n \n if (toolCalls && toolCalls.length > 0) {\n logger.debug('Model requested %d tool calls: %s', toolCalls.length, toolCalls.map(t => t.function.name).join(', '));\n }\n \n return {\n content: message.content || '',\n tool_calls: toolCalls,\n finish_reason: choice.finish_reason,\n };\n } catch (error) {\n logger.error('Tool call request failed', { error });\n throw error;\n }\n };\n \n return {\n complete,\n completeWithTools,\n isReasoningModel,\n getModelFamily,\n };\n};\n"],"names":["Logging.getLogger"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index17.js","sources":["../src/util/enhancement-logger.ts"],"sourcesContent":["/**\n * Enhancement Logger\n * \n * Utility for logging enhancement pipeline steps to the enhancement_log table.\n * Provides a simple interface that can be passed to pipeline phases.\n */\n\nimport type { EnhancementLogManager, EntityReference } from '@redaksjon/protokoll-format';\n\nexport interface EnhancementLogger {\n logStep(\n phase: 'transcribe' | 'enhance' | 'simple-replace',\n action: string,\n details?: Record<string, unknown>,\n entities?: EntityReference[]\n ): void;\n \n logSteps(steps: Array<{\n phase: 'transcribe' | 'enhance' | 'simple-replace';\n action: string;\n details?: Record<string, unknown>;\n entities?: EntityReference[];\n }>): void;\n}\n\n/**\n * Create an enhancement logger from an EnhancementLogManager\n */\nexport function createEnhancementLogger(manager: EnhancementLogManager): EnhancementLogger {\n return {\n logStep(phase, action, details, entities) {\n manager.logStep(new Date(), phase, action, details, entities);\n },\n \n logSteps(steps) {\n manager.logSteps(steps.map(step => ({\n ...step,\n timestamp: new Date(),\n })));\n },\n };\n}\n\n/**\n * Create a no-op logger for when enhancement logging is not available\n */\nexport function createNoOpLogger(): EnhancementLogger {\n return {\n logStep() {\n // No-op\n },\n logSteps() {\n // No-op\n },\n };\n}\n"],"names":[],"mappings":"AA4BO,SAAS,wBAAwB,OAAA,EAAmD;AACvF,EAAA,OAAO;AAAA,IACH,OAAA,CAAQ,KAAA,EAAO,MAAA,EAAQ,OAAA,EAAS,QAAA,EAAU;AACtC,MAAA,OAAA,CAAQ,wBAAQ,IAAI,IAAA,IAAQ,KAAA,EAAO,MAAA,EAAQ,SAAS,QAAQ,CAAA;AAAA,IAChE,CAAA;AAAA,IAEA,SAAS,KAAA,EAAO;AACZ,MAAA,OAAA,CAAQ,QAAA,CAAS,KAAA,CAAM,GAAA,CAAI,CAAA,IAAA,MAAS;AAAA,QAChC,GAAG,IAAA;AAAA,QACH,SAAA,sBAAe,IAAA;AAAK,QACtB,CAAC,CAAA;AAAA,IACP;AAAA,GACJ;AACJ;AAKO,SAAS,gBAAA,GAAsC;AAClD,EAAA,OAAO;AAAA,IACH,OAAA,GAAU;AAAA,IAEV,CAAA;AAAA,IACA,QAAA,GAAW;AAAA,IAEX;AAAA,GACJ;AACJ;;;;"}
|