@vertana/core 0.1.0-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/dist/_virtual/rolldown_runtime.cjs +29 -0
- package/dist/accumulator.cjs +64 -0
- package/dist/accumulator.d.cts +51 -0
- package/dist/accumulator.d.ts +51 -0
- package/dist/accumulator.js +61 -0
- package/dist/chunking.cjs +76 -0
- package/dist/chunking.d.cts +124 -0
- package/dist/chunking.d.ts +124 -0
- package/dist/chunking.js +74 -0
- package/dist/context.cjs +51 -0
- package/dist/context.d.cts +148 -0
- package/dist/context.d.ts +148 -0
- package/dist/context.js +49 -0
- package/dist/evaluation.cjs +120 -0
- package/dist/evaluation.d.cts +111 -0
- package/dist/evaluation.d.ts +111 -0
- package/dist/evaluation.js +119 -0
- package/dist/glossary.cjs +0 -0
- package/dist/glossary.d.cts +25 -0
- package/dist/glossary.d.ts +25 -0
- package/dist/glossary.js +0 -0
- package/dist/html.cjs +253 -0
- package/dist/html.d.cts +41 -0
- package/dist/html.d.ts +41 -0
- package/dist/html.js +250 -0
- package/dist/index.cjs +39 -0
- package/dist/index.d.cts +17 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +16 -0
- package/dist/markdown.cjs +300 -0
- package/dist/markdown.d.cts +17 -0
- package/dist/markdown.d.ts +17 -0
- package/dist/markdown.js +300 -0
- package/dist/plaintext.cjs +70 -0
- package/dist/plaintext.d.cts +17 -0
- package/dist/plaintext.d.ts +17 -0
- package/dist/plaintext.js +70 -0
- package/dist/prompt.cjs +91 -0
- package/dist/prompt.d.cts +74 -0
- package/dist/prompt.d.ts +74 -0
- package/dist/prompt.js +86 -0
- package/dist/refine.cjs +243 -0
- package/dist/refine.d.cts +148 -0
- package/dist/refine.d.ts +148 -0
- package/dist/refine.js +241 -0
- package/dist/select.cjs +62 -0
- package/dist/select.d.cts +83 -0
- package/dist/select.d.ts +83 -0
- package/dist/select.js +61 -0
- package/dist/terms.cjs +60 -0
- package/dist/terms.d.cts +36 -0
- package/dist/terms.d.ts +36 -0
- package/dist/terms.js +59 -0
- package/dist/tokens.cjs +40 -0
- package/dist/tokens.d.cts +24 -0
- package/dist/tokens.d.ts +24 -0
- package/dist/tokens.js +38 -0
- package/dist/tools.cjs +35 -0
- package/dist/tools.d.cts +20 -0
- package/dist/tools.d.ts +20 -0
- package/dist/tools.js +34 -0
- package/dist/translate.cjs +200 -0
- package/dist/translate.d.cts +190 -0
- package/dist/translate.d.ts +190 -0
- package/dist/translate.js +199 -0
- package/dist/window.cjs +0 -0
- package/dist/window.d.cts +48 -0
- package/dist/window.d.ts +48 -0
- package/dist/window.js +0 -0
- package/package.json +215 -0
package/dist/context.cjs
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
|
|
2
|
+
let _logtape_logtape = require("@logtape/logtape");
|
|
3
|
+
|
|
4
|
+
//#region src/context.ts
|
|
5
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
6
|
+
"vertana",
|
|
7
|
+
"core",
|
|
8
|
+
"context"
|
|
9
|
+
]);
|
|
10
|
+
/**
|
|
11
|
+
* Gathers context from all required context sources.
|
|
12
|
+
*
|
|
13
|
+
* @param sources The context sources to gather from.
|
|
14
|
+
* @param signal An optional abort signal to cancel the operation.
|
|
15
|
+
* @returns A promise that resolves to the gathered context results.
|
|
16
|
+
*/
|
|
17
|
+
async function gatherRequiredContext(sources, signal) {
|
|
18
|
+
const requiredSources = sources.filter((s) => s.mode === "required");
|
|
19
|
+
if (requiredSources.length === 0) return [];
|
|
20
|
+
logger.info("Gathering context from {count} required source(s)...", { count: requiredSources.length });
|
|
21
|
+
const results = [];
|
|
22
|
+
for (const source of requiredSources) {
|
|
23
|
+
signal?.throwIfAborted();
|
|
24
|
+
logger.debug("Gathering context from source: {name}...", { name: source.name });
|
|
25
|
+
const result = await source.gather({ signal });
|
|
26
|
+
results.push(result);
|
|
27
|
+
}
|
|
28
|
+
logger.info("Context gathering completed.", {
|
|
29
|
+
sourceCount: requiredSources.length,
|
|
30
|
+
totalContentLength: results.reduce((sum, r) => sum + r.content.length, 0)
|
|
31
|
+
});
|
|
32
|
+
return results;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Combines gathered context results into a single string.
|
|
36
|
+
*
|
|
37
|
+
* @param results The context results to combine.
|
|
38
|
+
* @returns The combined context as a single string.
|
|
39
|
+
*/
|
|
40
|
+
function combineContextResults(results) {
|
|
41
|
+
const combined = results.map((r) => r.content).filter((c) => c.trim().length > 0).join("\n\n");
|
|
42
|
+
logger.debug("Combined {count} context result(s) into {length} characters.", {
|
|
43
|
+
count: results.length,
|
|
44
|
+
length: combined.length
|
|
45
|
+
});
|
|
46
|
+
return combined;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
//#endregion
|
|
50
|
+
exports.combineContextResults = combineContextResults;
|
|
51
|
+
exports.gatherRequiredContext = gatherRequiredContext;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
2
|
+
|
|
3
|
+
//#region src/context.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Options for the {@link ContextSource.gather} method.
|
|
7
|
+
*/
|
|
8
|
+
interface ContextSourceGatherOptions {
|
|
9
|
+
/**
|
|
10
|
+
* An optional `AbortSignal` to cancel the context gathering operation.
|
|
11
|
+
*/
|
|
12
|
+
readonly signal?: AbortSignal;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The result of gathering context from a {@link ContextSource}.
|
|
16
|
+
*/
|
|
17
|
+
interface ContextResult {
|
|
18
|
+
/**
|
|
19
|
+
* The gathered context content as a string.
|
|
20
|
+
*/
|
|
21
|
+
readonly content: string;
|
|
22
|
+
/**
|
|
23
|
+
* Optional metadata about the gathered context.
|
|
24
|
+
*/
|
|
25
|
+
readonly metadata?: Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Base properties shared by all context sources.
|
|
29
|
+
*/
|
|
30
|
+
interface ContextSourceBase {
|
|
31
|
+
/**
|
|
32
|
+
* A unique identifier for the context source.
|
|
33
|
+
*/
|
|
34
|
+
readonly name: string;
|
|
35
|
+
/**
|
|
36
|
+
* A human-readable description of what this context source provides.
|
|
37
|
+
* For passive sources, this description helps the LLM decide when to use it.
|
|
38
|
+
*/
|
|
39
|
+
readonly description: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* A context source that is automatically invoked during the translation
|
|
43
|
+
* pipeline. Required sources are always executed before translation begins.
|
|
44
|
+
*/
|
|
45
|
+
interface RequiredContextSource extends ContextSourceBase {
|
|
46
|
+
/**
|
|
47
|
+
* Indicates that this source is always invoked.
|
|
48
|
+
*/
|
|
49
|
+
readonly mode: "required";
|
|
50
|
+
/**
|
|
51
|
+
* Gathers context. Called automatically during the translation pipeline.
|
|
52
|
+
*
|
|
53
|
+
* @param options Optional settings for the gathering operation.
|
|
54
|
+
* @returns A promise that resolves to the gathered context.
|
|
55
|
+
*/
|
|
56
|
+
gather(options?: ContextSourceGatherOptions): Promise<ContextResult>;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* A context source that can be invoked by the LLM agent when needed.
|
|
60
|
+
* Passive sources are exposed as tools that the agent can choose to call.
|
|
61
|
+
*
|
|
62
|
+
* @typeParam TParams The type of parameters accepted by the {@link gather}
|
|
63
|
+
* method.
|
|
64
|
+
*/
|
|
65
|
+
interface PassiveContextSource<TParams> extends ContextSourceBase {
|
|
66
|
+
/**
|
|
67
|
+
* Indicates that this source is invoked by the LLM agent on demand.
|
|
68
|
+
*/
|
|
69
|
+
readonly mode: "passive";
|
|
70
|
+
/**
|
|
71
|
+
* A Standard Schema defining the parameters for the {@link gather} method.
|
|
72
|
+
* This schema is used to generate the tool definition for the LLM.
|
|
73
|
+
*/
|
|
74
|
+
readonly parameters: StandardSchemaV1<TParams>;
|
|
75
|
+
/**
|
|
76
|
+
* Gathers context based on the provided parameters.
|
|
77
|
+
*
|
|
78
|
+
* @param params The parameters for gathering context, validated against
|
|
79
|
+
* the {@link parameters} schema.
|
|
80
|
+
* @param options Optional settings for the gathering operation.
|
|
81
|
+
* @returns A promise that resolves to the gathered context.
|
|
82
|
+
*/
|
|
83
|
+
gather(params: TParams, options?: ContextSourceGatherOptions): Promise<ContextResult>;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* A source that provides additional context for translation.
|
|
87
|
+
*
|
|
88
|
+
* Context sources can operate in two modes:
|
|
89
|
+
*
|
|
90
|
+
* - `"required"`: Always invoked at the start of the translation pipeline.
|
|
91
|
+
* Use this for context that is essential for every translation, such as
|
|
92
|
+
* author biography or document metadata.
|
|
93
|
+
*
|
|
94
|
+
* - `"passive"`: Exposed as a tool that the LLM agent can invoke on demand.
|
|
95
|
+
* Use this for context that may or may not be needed, such as fetching
|
|
96
|
+
* linked articles or looking up terminology.
|
|
97
|
+
*
|
|
98
|
+
* @typeParam TParams The type of parameters for passive sources.
|
|
99
|
+
*/
|
|
100
|
+
type ContextSource<TParams = unknown> = RequiredContextSource | PassiveContextSource<TParams>;
|
|
101
|
+
/**
|
|
102
|
+
* A factory function that creates a {@link ContextSource}.
|
|
103
|
+
*
|
|
104
|
+
* Factory functions are the recommended way to create context sources,
|
|
105
|
+
* as they allow for configuration validation and dependency injection.
|
|
106
|
+
*
|
|
107
|
+
* @typeParam TOptions The type of options accepted by the factory.
|
|
108
|
+
* @typeParam TParams The type of parameters for passive sources.
|
|
109
|
+
* @param options Configuration options for the context source.
|
|
110
|
+
* @returns A configured context source.
|
|
111
|
+
*
|
|
112
|
+
* @example Create a factory for fetching author information
|
|
113
|
+
* ```typescript
|
|
114
|
+
* interface AuthorBioOptions {
|
|
115
|
+
* readonly authorId: string;
|
|
116
|
+
* readonly fetchBio: (id: string) => Promise<string>;
|
|
117
|
+
* }
|
|
118
|
+
*
|
|
119
|
+
* const createAuthorBioSource: ContextSourceFactory<AuthorBioOptions> =
|
|
120
|
+
* (options) => ({
|
|
121
|
+
* name: "author-bio",
|
|
122
|
+
* description: "Fetches the author's biography for context",
|
|
123
|
+
* mode: "required",
|
|
124
|
+
* async gather(gatherOptions) {
|
|
125
|
+
* const bio = await options.fetchBio(options.authorId, gatherOptions);
|
|
126
|
+
* return { content: bio };
|
|
127
|
+
* },
|
|
128
|
+
* });
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
type ContextSourceFactory<TOptions, TParams = unknown> = (options: TOptions) => ContextSource<TParams>;
|
|
132
|
+
/**
|
|
133
|
+
* Gathers context from all required context sources.
|
|
134
|
+
*
|
|
135
|
+
* @param sources The context sources to gather from.
|
|
136
|
+
* @param signal An optional abort signal to cancel the operation.
|
|
137
|
+
* @returns A promise that resolves to the gathered context results.
|
|
138
|
+
*/
|
|
139
|
+
declare function gatherRequiredContext(sources: readonly ContextSource[], signal?: AbortSignal): Promise<readonly ContextResult[]>;
|
|
140
|
+
/**
|
|
141
|
+
* Combines gathered context results into a single string.
|
|
142
|
+
*
|
|
143
|
+
* @param results The context results to combine.
|
|
144
|
+
* @returns The combined context as a single string.
|
|
145
|
+
*/
|
|
146
|
+
declare function combineContextResults(results: readonly ContextResult[]): string;
|
|
147
|
+
//#endregion
|
|
148
|
+
export { ContextResult, ContextSource, ContextSourceFactory, ContextSourceGatherOptions, PassiveContextSource, RequiredContextSource, combineContextResults, gatherRequiredContext };
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
2
|
+
|
|
3
|
+
//#region src/context.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Options for the {@link ContextSource.gather} method.
|
|
7
|
+
*/
|
|
8
|
+
interface ContextSourceGatherOptions {
|
|
9
|
+
/**
|
|
10
|
+
* An optional `AbortSignal` to cancel the context gathering operation.
|
|
11
|
+
*/
|
|
12
|
+
readonly signal?: AbortSignal;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The result of gathering context from a {@link ContextSource}.
|
|
16
|
+
*/
|
|
17
|
+
interface ContextResult {
|
|
18
|
+
/**
|
|
19
|
+
* The gathered context content as a string.
|
|
20
|
+
*/
|
|
21
|
+
readonly content: string;
|
|
22
|
+
/**
|
|
23
|
+
* Optional metadata about the gathered context.
|
|
24
|
+
*/
|
|
25
|
+
readonly metadata?: Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Base properties shared by all context sources.
|
|
29
|
+
*/
|
|
30
|
+
interface ContextSourceBase {
|
|
31
|
+
/**
|
|
32
|
+
* A unique identifier for the context source.
|
|
33
|
+
*/
|
|
34
|
+
readonly name: string;
|
|
35
|
+
/**
|
|
36
|
+
* A human-readable description of what this context source provides.
|
|
37
|
+
* For passive sources, this description helps the LLM decide when to use it.
|
|
38
|
+
*/
|
|
39
|
+
readonly description: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* A context source that is automatically invoked during the translation
|
|
43
|
+
* pipeline. Required sources are always executed before translation begins.
|
|
44
|
+
*/
|
|
45
|
+
interface RequiredContextSource extends ContextSourceBase {
|
|
46
|
+
/**
|
|
47
|
+
* Indicates that this source is always invoked.
|
|
48
|
+
*/
|
|
49
|
+
readonly mode: "required";
|
|
50
|
+
/**
|
|
51
|
+
* Gathers context. Called automatically during the translation pipeline.
|
|
52
|
+
*
|
|
53
|
+
* @param options Optional settings for the gathering operation.
|
|
54
|
+
* @returns A promise that resolves to the gathered context.
|
|
55
|
+
*/
|
|
56
|
+
gather(options?: ContextSourceGatherOptions): Promise<ContextResult>;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* A context source that can be invoked by the LLM agent when needed.
|
|
60
|
+
* Passive sources are exposed as tools that the agent can choose to call.
|
|
61
|
+
*
|
|
62
|
+
* @typeParam TParams The type of parameters accepted by the {@link gather}
|
|
63
|
+
* method.
|
|
64
|
+
*/
|
|
65
|
+
interface PassiveContextSource<TParams> extends ContextSourceBase {
|
|
66
|
+
/**
|
|
67
|
+
* Indicates that this source is invoked by the LLM agent on demand.
|
|
68
|
+
*/
|
|
69
|
+
readonly mode: "passive";
|
|
70
|
+
/**
|
|
71
|
+
* A Standard Schema defining the parameters for the {@link gather} method.
|
|
72
|
+
* This schema is used to generate the tool definition for the LLM.
|
|
73
|
+
*/
|
|
74
|
+
readonly parameters: StandardSchemaV1<TParams>;
|
|
75
|
+
/**
|
|
76
|
+
* Gathers context based on the provided parameters.
|
|
77
|
+
*
|
|
78
|
+
* @param params The parameters for gathering context, validated against
|
|
79
|
+
* the {@link parameters} schema.
|
|
80
|
+
* @param options Optional settings for the gathering operation.
|
|
81
|
+
* @returns A promise that resolves to the gathered context.
|
|
82
|
+
*/
|
|
83
|
+
gather(params: TParams, options?: ContextSourceGatherOptions): Promise<ContextResult>;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* A source that provides additional context for translation.
|
|
87
|
+
*
|
|
88
|
+
* Context sources can operate in two modes:
|
|
89
|
+
*
|
|
90
|
+
* - `"required"`: Always invoked at the start of the translation pipeline.
|
|
91
|
+
* Use this for context that is essential for every translation, such as
|
|
92
|
+
* author biography or document metadata.
|
|
93
|
+
*
|
|
94
|
+
* - `"passive"`: Exposed as a tool that the LLM agent can invoke on demand.
|
|
95
|
+
* Use this for context that may or may not be needed, such as fetching
|
|
96
|
+
* linked articles or looking up terminology.
|
|
97
|
+
*
|
|
98
|
+
* @typeParam TParams The type of parameters for passive sources.
|
|
99
|
+
*/
|
|
100
|
+
type ContextSource<TParams = unknown> = RequiredContextSource | PassiveContextSource<TParams>;
|
|
101
|
+
/**
|
|
102
|
+
* A factory function that creates a {@link ContextSource}.
|
|
103
|
+
*
|
|
104
|
+
* Factory functions are the recommended way to create context sources,
|
|
105
|
+
* as they allow for configuration validation and dependency injection.
|
|
106
|
+
*
|
|
107
|
+
* @typeParam TOptions The type of options accepted by the factory.
|
|
108
|
+
* @typeParam TParams The type of parameters for passive sources.
|
|
109
|
+
* @param options Configuration options for the context source.
|
|
110
|
+
* @returns A configured context source.
|
|
111
|
+
*
|
|
112
|
+
* @example Create a factory for fetching author information
|
|
113
|
+
* ```typescript
|
|
114
|
+
* interface AuthorBioOptions {
|
|
115
|
+
* readonly authorId: string;
|
|
116
|
+
* readonly fetchBio: (id: string) => Promise<string>;
|
|
117
|
+
* }
|
|
118
|
+
*
|
|
119
|
+
* const createAuthorBioSource: ContextSourceFactory<AuthorBioOptions> =
|
|
120
|
+
* (options) => ({
|
|
121
|
+
* name: "author-bio",
|
|
122
|
+
* description: "Fetches the author's biography for context",
|
|
123
|
+
* mode: "required",
|
|
124
|
+
* async gather(gatherOptions) {
|
|
125
|
+
* const bio = await options.fetchBio(options.authorId, gatherOptions);
|
|
126
|
+
* return { content: bio };
|
|
127
|
+
* },
|
|
128
|
+
* });
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
type ContextSourceFactory<TOptions, TParams = unknown> = (options: TOptions) => ContextSource<TParams>;
|
|
132
|
+
/**
|
|
133
|
+
* Gathers context from all required context sources.
|
|
134
|
+
*
|
|
135
|
+
* @param sources The context sources to gather from.
|
|
136
|
+
* @param signal An optional abort signal to cancel the operation.
|
|
137
|
+
* @returns A promise that resolves to the gathered context results.
|
|
138
|
+
*/
|
|
139
|
+
declare function gatherRequiredContext(sources: readonly ContextSource[], signal?: AbortSignal): Promise<readonly ContextResult[]>;
|
|
140
|
+
/**
|
|
141
|
+
* Combines gathered context results into a single string.
|
|
142
|
+
*
|
|
143
|
+
* @param results The context results to combine.
|
|
144
|
+
* @returns The combined context as a single string.
|
|
145
|
+
*/
|
|
146
|
+
declare function combineContextResults(results: readonly ContextResult[]): string;
|
|
147
|
+
//#endregion
|
|
148
|
+
export { ContextResult, ContextSource, ContextSourceFactory, ContextSourceGatherOptions, PassiveContextSource, RequiredContextSource, combineContextResults, gatherRequiredContext };
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { getLogger } from "@logtape/logtape";
|
|
2
|
+
|
|
3
|
+
//#region src/context.ts
|
|
4
|
+
const logger = getLogger([
|
|
5
|
+
"vertana",
|
|
6
|
+
"core",
|
|
7
|
+
"context"
|
|
8
|
+
]);
|
|
9
|
+
/**
|
|
10
|
+
* Gathers context from all required context sources.
|
|
11
|
+
*
|
|
12
|
+
* @param sources The context sources to gather from.
|
|
13
|
+
* @param signal An optional abort signal to cancel the operation.
|
|
14
|
+
* @returns A promise that resolves to the gathered context results.
|
|
15
|
+
*/
|
|
16
|
+
async function gatherRequiredContext(sources, signal) {
|
|
17
|
+
const requiredSources = sources.filter((s) => s.mode === "required");
|
|
18
|
+
if (requiredSources.length === 0) return [];
|
|
19
|
+
logger.info("Gathering context from {count} required source(s)...", { count: requiredSources.length });
|
|
20
|
+
const results = [];
|
|
21
|
+
for (const source of requiredSources) {
|
|
22
|
+
signal?.throwIfAborted();
|
|
23
|
+
logger.debug("Gathering context from source: {name}...", { name: source.name });
|
|
24
|
+
const result = await source.gather({ signal });
|
|
25
|
+
results.push(result);
|
|
26
|
+
}
|
|
27
|
+
logger.info("Context gathering completed.", {
|
|
28
|
+
sourceCount: requiredSources.length,
|
|
29
|
+
totalContentLength: results.reduce((sum, r) => sum + r.content.length, 0)
|
|
30
|
+
});
|
|
31
|
+
return results;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Combines gathered context results into a single string.
|
|
35
|
+
*
|
|
36
|
+
* @param results The context results to combine.
|
|
37
|
+
* @returns The combined context as a single string.
|
|
38
|
+
*/
|
|
39
|
+
function combineContextResults(results) {
|
|
40
|
+
const combined = results.map((r) => r.content).filter((c) => c.trim().length > 0).join("\n\n");
|
|
41
|
+
logger.debug("Combined {count} context result(s) into {length} characters.", {
|
|
42
|
+
count: results.length,
|
|
43
|
+
length: combined.length
|
|
44
|
+
});
|
|
45
|
+
return combined;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
//#endregion
|
|
49
|
+
export { combineContextResults, gatherRequiredContext };
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
|
|
2
|
+
let _logtape_logtape = require("@logtape/logtape");
|
|
3
|
+
let ai = require("ai");
|
|
4
|
+
let zod = require("zod");
|
|
5
|
+
|
|
6
|
+
//#region src/evaluation.ts
|
|
7
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
8
|
+
"vertana",
|
|
9
|
+
"core",
|
|
10
|
+
"evaluate"
|
|
11
|
+
]);
|
|
12
|
+
const issueTypeSchema = zod.z.enum([
|
|
13
|
+
"accuracy",
|
|
14
|
+
"fluency",
|
|
15
|
+
"terminology",
|
|
16
|
+
"style"
|
|
17
|
+
]);
|
|
18
|
+
const issueSchema = zod.z.object({
|
|
19
|
+
type: issueTypeSchema,
|
|
20
|
+
description: zod.z.string(),
|
|
21
|
+
location: zod.z.object({
|
|
22
|
+
start: zod.z.number(),
|
|
23
|
+
end: zod.z.number()
|
|
24
|
+
}).optional()
|
|
25
|
+
});
|
|
26
|
+
const evaluationResultSchema = zod.z.object({
|
|
27
|
+
score: zod.z.number().min(0).max(1),
|
|
28
|
+
issues: zod.z.array(issueSchema)
|
|
29
|
+
});
|
|
30
|
+
/**
|
|
31
|
+
* Gets the language name from a locale.
|
|
32
|
+
*/
|
|
33
|
+
function getLanguageName(locale) {
|
|
34
|
+
const tag = typeof locale === "string" ? locale : locale.baseName;
|
|
35
|
+
try {
|
|
36
|
+
return new Intl.DisplayNames(["en"], { type: "language" }).of(tag) ?? tag;
|
|
37
|
+
} catch {
|
|
38
|
+
return tag;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Builds the system prompt for evaluation.
|
|
43
|
+
*/
|
|
44
|
+
function buildEvaluationSystemPrompt(options) {
|
|
45
|
+
const targetLang = getLanguageName(options.targetLanguage);
|
|
46
|
+
let prompt = `You are an expert translation quality evaluator.
|
|
47
|
+
|
|
48
|
+
Your task is to evaluate the quality of a translation from ${(options.sourceLanguage ? getLanguageName(options.sourceLanguage) : null) ?? "the source language"} to ${targetLang}.
|
|
49
|
+
|
|
50
|
+
Evaluate the translation based on these criteria:
|
|
51
|
+
|
|
52
|
+
1. **Accuracy**: Does the translation accurately convey the meaning of the original text?
|
|
53
|
+
2. **Fluency**: Is the translation natural and readable in ${targetLang}?
|
|
54
|
+
3. **Terminology**: Are domain-specific terms translated correctly and consistently?
|
|
55
|
+
4. **Style**: Does the translation maintain the appropriate tone and style?
|
|
56
|
+
|
|
57
|
+
Provide:
|
|
58
|
+
- A score from 0 to 1 (where 1 is perfect, 0.9+ is excellent, 0.7-0.9 is good, 0.5-0.7 is acceptable, below 0.5 is poor)
|
|
59
|
+
- A list of specific issues found, if any
|
|
60
|
+
|
|
61
|
+
Be strict but fair in your evaluation. Minor issues should result in small deductions, while major meaning errors should significantly lower the score.`;
|
|
62
|
+
if (options.glossary != null && options.glossary.length > 0) {
|
|
63
|
+
prompt += `\n\n## Glossary
|
|
64
|
+
|
|
65
|
+
The following terms MUST be translated as specified. Violations should be marked as "terminology" issues:
|
|
66
|
+
|
|
67
|
+
`;
|
|
68
|
+
for (const entry of options.glossary) prompt += `- "${entry.original}" → "${entry.translated}"\n`;
|
|
69
|
+
}
|
|
70
|
+
return prompt;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Builds the user prompt for evaluation.
|
|
74
|
+
*/
|
|
75
|
+
function buildEvaluationUserPrompt(original, translated) {
|
|
76
|
+
return `## Original Text
|
|
77
|
+
|
|
78
|
+
${original}
|
|
79
|
+
|
|
80
|
+
## Translated Text
|
|
81
|
+
|
|
82
|
+
${translated}
|
|
83
|
+
|
|
84
|
+
Please evaluate this translation.`;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Evaluates the quality of a translation using an LLM.
|
|
88
|
+
*
|
|
89
|
+
* @param model The language model to use for evaluation.
|
|
90
|
+
* @param original The original text that was translated.
|
|
91
|
+
* @param translated The translated text to evaluate.
|
|
92
|
+
* @param options Evaluation options including target language.
|
|
93
|
+
* @returns A promise that resolves to the evaluation result.
|
|
94
|
+
*/
|
|
95
|
+
async function evaluate(model, original, translated, options) {
|
|
96
|
+
logger.debug("Evaluating translation quality...");
|
|
97
|
+
const result = await (0, ai.generateObject)({
|
|
98
|
+
model,
|
|
99
|
+
schema: evaluationResultSchema,
|
|
100
|
+
system: buildEvaluationSystemPrompt(options),
|
|
101
|
+
prompt: buildEvaluationUserPrompt(original, translated),
|
|
102
|
+
abortSignal: options.signal
|
|
103
|
+
});
|
|
104
|
+
const issues = result.object.issues.map((issue) => ({
|
|
105
|
+
type: issue.type,
|
|
106
|
+
description: issue.description,
|
|
107
|
+
location: issue.location
|
|
108
|
+
}));
|
|
109
|
+
logger.debug("Evaluation result: score {score}, {issueCount} issue(s).", {
|
|
110
|
+
score: result.object.score,
|
|
111
|
+
issueCount: issues.length
|
|
112
|
+
});
|
|
113
|
+
return {
|
|
114
|
+
score: result.object.score,
|
|
115
|
+
issues
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
//#endregion
|
|
120
|
+
exports.evaluate = evaluate;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { Glossary } from "./glossary.cjs";
|
|
2
|
+
import { LanguageModel } from "ai";
|
|
3
|
+
|
|
4
|
+
//#region src/evaluation.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Options for {@link TranslationEvaluator}.
|
|
8
|
+
*/
|
|
9
|
+
interface EvaluatorOptions {
|
|
10
|
+
/**
|
|
11
|
+
* An optional `AbortSignal` to cancel the evaluation.
|
|
12
|
+
*/
|
|
13
|
+
readonly signal?: AbortSignal;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Options for the {@link evaluate} function.
|
|
17
|
+
*/
|
|
18
|
+
interface EvaluateOptions {
|
|
19
|
+
/**
|
|
20
|
+
* The target language of the translation.
|
|
21
|
+
*/
|
|
22
|
+
readonly targetLanguage: Intl.Locale | string;
|
|
23
|
+
/**
|
|
24
|
+
* The source language of the original text.
|
|
25
|
+
*/
|
|
26
|
+
readonly sourceLanguage?: Intl.Locale | string;
|
|
27
|
+
/**
|
|
28
|
+
* A glossary of terms that should be used consistently.
|
|
29
|
+
*/
|
|
30
|
+
readonly glossary?: Glossary;
|
|
31
|
+
/**
|
|
32
|
+
* An optional `AbortSignal` to cancel the evaluation.
|
|
33
|
+
*/
|
|
34
|
+
readonly signal?: AbortSignal;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Evaluates the quality of a translation.
|
|
38
|
+
*
|
|
39
|
+
* @param original The original text that was translated.
|
|
40
|
+
* @param translated The translated text to evaluate.
|
|
41
|
+
* @param options Optional settings for the evaluation.
|
|
42
|
+
* @returns A promise that resolves to the evaluation result.
|
|
43
|
+
*/
|
|
44
|
+
type TranslationEvaluator = (original: string, translated: string, options?: EvaluatorOptions) => Promise<EvaluationResult>;
|
|
45
|
+
/**
|
|
46
|
+
* The result of evaluating a translation.
|
|
47
|
+
*/
|
|
48
|
+
interface EvaluationResult {
|
|
49
|
+
/**
|
|
50
|
+
* A quality score between 0 and 1, where 1 indicates a perfect translation
|
|
51
|
+
* and 0 indicates a completely incorrect translation.
|
|
52
|
+
*/
|
|
53
|
+
readonly score: number;
|
|
54
|
+
/**
|
|
55
|
+
* Specific issues found in the translation.
|
|
56
|
+
*/
|
|
57
|
+
readonly issues: readonly TranslationIssue[];
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The type of issue found in a translation.
|
|
61
|
+
*
|
|
62
|
+
* - `"accuracy"`: The translation does not accurately convey the meaning
|
|
63
|
+
* of the original text.
|
|
64
|
+
* - `"fluency"`: The translation is not natural or readable in the target
|
|
65
|
+
* language.
|
|
66
|
+
* - `"terminology"`: Incorrect or inconsistent use of domain-specific terms.
|
|
67
|
+
* - `"style"`: The translation does not match the desired tone or style.
|
|
68
|
+
*/
|
|
69
|
+
type TranslationIssueType = "accuracy" | "fluency" | "terminology" | "style";
|
|
70
|
+
/**
|
|
71
|
+
* A specific issue found in a translation.
|
|
72
|
+
*/
|
|
73
|
+
interface TranslationIssue {
|
|
74
|
+
/**
|
|
75
|
+
* The type of issue.
|
|
76
|
+
*/
|
|
77
|
+
readonly type: TranslationIssueType;
|
|
78
|
+
/**
|
|
79
|
+
* A human-readable description of the issue.
|
|
80
|
+
*/
|
|
81
|
+
readonly description: string;
|
|
82
|
+
/**
|
|
83
|
+
* The location of the issue in the translated text, if applicable.
|
|
84
|
+
*/
|
|
85
|
+
readonly location?: TranslationIssueLocation;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The location of a translation issue within the translated text.
|
|
89
|
+
*/
|
|
90
|
+
interface TranslationIssueLocation {
|
|
91
|
+
/**
|
|
92
|
+
* The starting character index (0-based, inclusive).
|
|
93
|
+
*/
|
|
94
|
+
readonly start: number;
|
|
95
|
+
/**
|
|
96
|
+
* The ending character index (0-based, exclusive).
|
|
97
|
+
*/
|
|
98
|
+
readonly end: number;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Evaluates the quality of a translation using an LLM.
|
|
102
|
+
*
|
|
103
|
+
* @param model The language model to use for evaluation.
|
|
104
|
+
* @param original The original text that was translated.
|
|
105
|
+
* @param translated The translated text to evaluate.
|
|
106
|
+
* @param options Evaluation options including target language.
|
|
107
|
+
* @returns A promise that resolves to the evaluation result.
|
|
108
|
+
*/
|
|
109
|
+
declare function evaluate(model: LanguageModel, original: string, translated: string, options: EvaluateOptions): Promise<EvaluationResult>;
|
|
110
|
+
//#endregion
|
|
111
|
+
export { EvaluateOptions, EvaluationResult, EvaluatorOptions, TranslationEvaluator, TranslationIssue, TranslationIssueLocation, TranslationIssueType, evaluate };
|