@qvac/harness 0.2.12 → 0.3.0
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/harness.bundle +9 -8
- package/dist-lib/index.d.ts +11 -1
- package/dist-lib/index.js +66 -5
- package/dist-lib/lib/capabilities/completion.d.ts +2 -0
- package/dist-lib/lib/capabilities/enhance.d.ts +10 -0
- package/dist-lib/lib/capabilities/enhance.js +29 -0
- package/dist-lib/lib/capabilities/invoke.d.ts +11 -2
- package/dist-lib/lib/capabilities/invoke.js +32 -8
- package/dist-lib/lib/connect.js +1 -0
- package/dist-lib/lib/contract-types.d.ts +1 -0
- package/dist-lib/lib/helpers/clean-answer.d.ts +1 -0
- package/dist-lib/lib/helpers/clean-answer.js +16 -0
- package/dist-lib/lib/helpers/load-stall.d.ts +6 -0
- package/dist-lib/lib/helpers/load-stall.js +24 -0
- package/dist-lib/lib/models/model-pool.d.ts +6 -0
- package/dist-lib/lib/models/model-pool.js +12 -0
- package/dist-lib/lib/models/nmt-catalog.d.ts +34 -0
- package/dist-lib/lib/models/nmt-catalog.js +166 -0
- package/dist-lib/lib/serve.js +1 -0
- package/dist-lib/lib/tools/generate-image.js +2 -25
- package/dist-lib/lib/tools/translate.d.ts +78 -0
- package/dist-lib/lib/tools/translate.js +228 -0
- package/dist-lib/schema/harness.js +2 -1
- package/dist-lib/spec/hrpc/messages.js +10 -5
- package/dist-lib/spec/hyperschema/index.js +10 -5
- package/dist-lib/spec/hyperschema/schema.json +6 -1
- package/dist-lib/spec/hyperschema/types.d.ts +2 -1
- package/package.json +6 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import ScopeLock from 'scope-lock';
|
|
2
2
|
import { AbortedError, raceAbort } from '../helpers/race-abort.js';
|
|
3
3
|
import { DIFFUSION_CATALOG, imageModelFor } from '../models/model-catalog.js';
|
|
4
|
+
import { createLoadStall } from '../helpers/load-stall.js';
|
|
4
5
|
import { createLoadTracker } from '../models/model-pool.js';
|
|
5
6
|
import { resolveModelSrc } from '../models/model-source.js';
|
|
6
7
|
export const MAX_DIM = 1024;
|
|
@@ -36,30 +37,6 @@ function diffusionProgressName(set) {
|
|
|
36
37
|
return entry?.name ?? set.model;
|
|
37
38
|
}
|
|
38
39
|
export const IMAGE_LOAD_STALL_ERROR = 'image model download stalled';
|
|
39
|
-
function createLoadStall(ms) {
|
|
40
|
-
let timer = null;
|
|
41
|
-
let rejectStall = null;
|
|
42
|
-
const promise = new Promise((_, reject) => {
|
|
43
|
-
rejectStall = reject;
|
|
44
|
-
});
|
|
45
|
-
const arm = () => {
|
|
46
|
-
if (timer !== null)
|
|
47
|
-
clearTimeout(timer);
|
|
48
|
-
timer = setTimeout(() => {
|
|
49
|
-
rejectStall?.(new Error(IMAGE_LOAD_STALL_ERROR));
|
|
50
|
-
}, ms);
|
|
51
|
-
};
|
|
52
|
-
arm();
|
|
53
|
-
return {
|
|
54
|
-
bump: arm,
|
|
55
|
-
clear: () => {
|
|
56
|
-
if (timer !== null)
|
|
57
|
-
clearTimeout(timer);
|
|
58
|
-
timer = null;
|
|
59
|
-
},
|
|
60
|
-
promise
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
40
|
export function createDiffusionRuntime({ loadSdk, onProgress, onLoaded, onBeforeLoad, loads = createLoadTracker(), stallMs = IMAGE_LOAD_STALL_MS, ...base }) {
|
|
64
41
|
let loading = null;
|
|
65
42
|
let residentFingerprint = null;
|
|
@@ -116,7 +93,7 @@ export function createDiffusionRuntime({ loadSdk, onProgress, onLoaded, onBefore
|
|
|
116
93
|
config.vaeModelSrc = await resolveModelSrc(sdk, set.vaeModel, 'diffusion');
|
|
117
94
|
}
|
|
118
95
|
const modelConfig = Object.keys(config).length ? config : undefined;
|
|
119
|
-
const stall = createLoadStall(stallMs);
|
|
96
|
+
const stall = createLoadStall(stallMs, IMAGE_LOAD_STALL_ERROR);
|
|
120
97
|
const pending = sdk.loadModel({
|
|
121
98
|
modelSrc,
|
|
122
99
|
modelType: 'diffusion',
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { AbortSignal as BareAbortSignal } from 'bare-abort-controller';
|
|
2
|
+
import type { ToolDefinition } from '../capabilities/completion.ts';
|
|
3
|
+
import type { ModelSrc } from '../models/context.ts';
|
|
4
|
+
import { type NmtPlan } from '../models/nmt-catalog.ts';
|
|
5
|
+
import { type LoadTracker, type TrackedLoad } from '../models/model-pool.ts';
|
|
6
|
+
import { type ModelRegistrySdk } from '../models/model-source.ts';
|
|
7
|
+
interface BergamotConfig {
|
|
8
|
+
engine: 'Bergamot';
|
|
9
|
+
from: string;
|
|
10
|
+
to: string;
|
|
11
|
+
pivotModel?: {
|
|
12
|
+
modelSrc: ModelSrc;
|
|
13
|
+
};
|
|
14
|
+
srcVocabSrc?: string;
|
|
15
|
+
dstVocabSrc?: string;
|
|
16
|
+
}
|
|
17
|
+
export type TranslationSdk = ModelRegistrySdk & {
|
|
18
|
+
loadModel(params: {
|
|
19
|
+
modelSrc: ModelSrc;
|
|
20
|
+
modelType: 'nmtcpp-translation';
|
|
21
|
+
modelConfig: BergamotConfig;
|
|
22
|
+
onProgress?: (progress: Record<string, unknown>) => void;
|
|
23
|
+
}): TrackedLoad;
|
|
24
|
+
unloadModel(params: {
|
|
25
|
+
modelId: string;
|
|
26
|
+
}): Promise<unknown>;
|
|
27
|
+
cancel?(params: {
|
|
28
|
+
requestId: string;
|
|
29
|
+
}): Promise<void>;
|
|
30
|
+
translate(params: {
|
|
31
|
+
modelId: string;
|
|
32
|
+
text: string;
|
|
33
|
+
stream: false;
|
|
34
|
+
modelType: 'nmt';
|
|
35
|
+
}): {
|
|
36
|
+
text: Promise<string>;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
export declare const TRANSLATION_LOAD_STALL_MS: number;
|
|
40
|
+
export declare const TRANSLATION_LOAD_STALL_ERROR = "translation model download stalled";
|
|
41
|
+
export interface TranslationRuntimeOptions {
|
|
42
|
+
loadSdk: () => Promise<TranslationSdk>;
|
|
43
|
+
loads?: LoadTracker;
|
|
44
|
+
onProgress?: (model: string, progress: Record<string, unknown>) => void;
|
|
45
|
+
stallMs?: number;
|
|
46
|
+
}
|
|
47
|
+
export interface TranslationRuntime {
|
|
48
|
+
loadSdk: () => Promise<TranslationSdk>;
|
|
49
|
+
ensureLoaded: (sdk: TranslationSdk, plan: NmtPlan, signal?: BareAbortSignal) => Promise<{
|
|
50
|
+
modelId: string;
|
|
51
|
+
}>;
|
|
52
|
+
unload: () => Promise<void>;
|
|
53
|
+
enter: (signal?: BareAbortSignal) => Promise<void>;
|
|
54
|
+
exit: () => void;
|
|
55
|
+
}
|
|
56
|
+
export declare function createTranslationRuntime({ loadSdk, loads, onProgress, stallMs }: TranslationRuntimeOptions): TranslationRuntime;
|
|
57
|
+
export type SlmTranslateFn = (model: string, params: {
|
|
58
|
+
text: string;
|
|
59
|
+
from: string;
|
|
60
|
+
to: string;
|
|
61
|
+
}, signal?: BareAbortSignal) => Promise<string>;
|
|
62
|
+
export declare function stripLanguageLabel(text: string, ...codes: string[]): string;
|
|
63
|
+
export interface TranslateArgs {
|
|
64
|
+
text: string;
|
|
65
|
+
to: string;
|
|
66
|
+
from?: string;
|
|
67
|
+
}
|
|
68
|
+
export declare function parseTranslateArgs(args: Record<string, unknown>): TranslateArgs | {
|
|
69
|
+
error: string;
|
|
70
|
+
};
|
|
71
|
+
export declare function sourceLanguage(text: string, from?: string): string | {
|
|
72
|
+
error: string;
|
|
73
|
+
};
|
|
74
|
+
export interface TranslateToolOptions {
|
|
75
|
+
slm?: SlmTranslateFn;
|
|
76
|
+
}
|
|
77
|
+
export declare function createTranslateTool(runtime: TranslationRuntime, { slm }?: TranslateToolOptions): ToolDefinition;
|
|
78
|
+
export {};
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import ScopeLock from 'scope-lock';
|
|
2
|
+
import { getLangName } from '@qvac/langdetect-text';
|
|
3
|
+
import { detectLanguage, UNDETERMINED } from '../capabilities/detect-language.js';
|
|
4
|
+
import { AbortedError, raceAbort } from '../helpers/race-abort.js';
|
|
5
|
+
import { ENGLISH, NMT_FROM_ENGLISH, NMT_TO_ENGLISH, languageLabel, SLM_LANGUAGE_CODES, sameLanguage, translationPlanFor } from '../models/nmt-catalog.js';
|
|
6
|
+
import { createLoadStall } from '../helpers/load-stall.js';
|
|
7
|
+
import { createLoadTracker } from '../models/model-pool.js';
|
|
8
|
+
import { resolveModelSrc } from '../models/model-source.js';
|
|
9
|
+
export const TRANSLATION_LOAD_STALL_MS = 15 * 60_000;
|
|
10
|
+
export const TRANSLATION_LOAD_STALL_ERROR = 'translation model download stalled';
|
|
11
|
+
function packName(plan) {
|
|
12
|
+
const pair = plan.model.match(/model\.([a-z]+)\.intgemm/)?.[1];
|
|
13
|
+
if (pair)
|
|
14
|
+
return `Bergamot ${pair}`;
|
|
15
|
+
return plan.model.includes('/en-xx/') ? 'EuroNano en-xx' : 'EuroNano xx-en';
|
|
16
|
+
}
|
|
17
|
+
const fingerprintOf = (plan) => `${plan.model}|${plan.pivot ?? ''}`;
|
|
18
|
+
function bergamotConfig(plan) {
|
|
19
|
+
const config = { engine: 'Bergamot', from: plan.from, to: plan.to };
|
|
20
|
+
if (plan.srcVocab)
|
|
21
|
+
config.srcVocabSrc = plan.srcVocab;
|
|
22
|
+
if (plan.dstVocab)
|
|
23
|
+
config.dstVocabSrc = plan.dstVocab;
|
|
24
|
+
return config;
|
|
25
|
+
}
|
|
26
|
+
export function createTranslationRuntime({ loadSdk, loads = createLoadTracker(), onProgress, stallMs = TRANSLATION_LOAD_STALL_MS }) {
|
|
27
|
+
let loading = null;
|
|
28
|
+
let residentFingerprint = null;
|
|
29
|
+
const lock = new ScopeLock();
|
|
30
|
+
const turn = new ScopeLock();
|
|
31
|
+
const loadPack = async (sdk, plan) => {
|
|
32
|
+
const modelSrc = await resolveModelSrc(sdk, plan.model, 'nmt');
|
|
33
|
+
const modelConfig = bergamotConfig(plan);
|
|
34
|
+
if (plan.pivot) {
|
|
35
|
+
modelConfig.pivotModel = { modelSrc: await resolveModelSrc(sdk, plan.pivot, 'nmt') };
|
|
36
|
+
}
|
|
37
|
+
const name = packName(plan);
|
|
38
|
+
const stall = createLoadStall(stallMs, TRANSLATION_LOAD_STALL_ERROR);
|
|
39
|
+
onProgress?.(name, {});
|
|
40
|
+
const pending = sdk.loadModel({
|
|
41
|
+
modelSrc,
|
|
42
|
+
modelType: 'nmtcpp-translation',
|
|
43
|
+
modelConfig,
|
|
44
|
+
onProgress: (progress) => {
|
|
45
|
+
stall.bump();
|
|
46
|
+
onProgress?.(name, progress);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
try {
|
|
50
|
+
const modelId = await Promise.race([loads.track(pending), stall.promise]);
|
|
51
|
+
return { modelId };
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
if (err instanceof Error &&
|
|
55
|
+
err.message === TRANSLATION_LOAD_STALL_ERROR &&
|
|
56
|
+
pending.requestId) {
|
|
57
|
+
void sdk.cancel?.({ requestId: pending.requestId }).catch(() => { });
|
|
58
|
+
}
|
|
59
|
+
throw err;
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
stall.clear();
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
const doUnload = async () => {
|
|
66
|
+
const pending = loading;
|
|
67
|
+
if (!pending) {
|
|
68
|
+
residentFingerprint = null;
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const loaded = await pending.catch(() => null);
|
|
72
|
+
if (!loaded) {
|
|
73
|
+
loading = null;
|
|
74
|
+
residentFingerprint = null;
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const sdk = await loadSdk();
|
|
78
|
+
await sdk.unloadModel({ modelId: loaded.modelId });
|
|
79
|
+
loading = null;
|
|
80
|
+
residentFingerprint = null;
|
|
81
|
+
};
|
|
82
|
+
const unload = async () => {
|
|
83
|
+
await lock.lock();
|
|
84
|
+
try {
|
|
85
|
+
await doUnload();
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
lock.unlock();
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
return {
|
|
92
|
+
loadSdk,
|
|
93
|
+
ensureLoaded: async (sdk, plan, signal) => {
|
|
94
|
+
const fingerprint = fingerprintOf(plan);
|
|
95
|
+
await lock.lock();
|
|
96
|
+
try {
|
|
97
|
+
if (loading && residentFingerprint !== fingerprint)
|
|
98
|
+
await doUnload();
|
|
99
|
+
residentFingerprint = fingerprint;
|
|
100
|
+
loading ??= loadPack(sdk, plan).catch((err) => {
|
|
101
|
+
loading = null;
|
|
102
|
+
residentFingerprint = null;
|
|
103
|
+
throw err;
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
lock.unlock();
|
|
108
|
+
}
|
|
109
|
+
return raceAbort(loading, signal);
|
|
110
|
+
},
|
|
111
|
+
unload,
|
|
112
|
+
enter: async (signal) => {
|
|
113
|
+
const pending = turn.lock();
|
|
114
|
+
try {
|
|
115
|
+
await raceAbort(pending, signal);
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
void pending.then(() => turn.unlock());
|
|
119
|
+
throw err;
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
exit: () => turn.unlock()
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
export function stripLanguageLabel(text, ...codes) {
|
|
126
|
+
const at = text.indexOf(':');
|
|
127
|
+
if (at === -1)
|
|
128
|
+
return text;
|
|
129
|
+
const head = text.slice(0, at).trim();
|
|
130
|
+
const labels = codes.map((code) => languageLabel(code) ?? getLangName(code));
|
|
131
|
+
return labels.includes(head) ? text.slice(at + 1).trim() : text;
|
|
132
|
+
}
|
|
133
|
+
export function parseTranslateArgs(args) {
|
|
134
|
+
const text = typeof args.text === 'string' ? args.text.trim() : '';
|
|
135
|
+
if (!text)
|
|
136
|
+
return { error: 'text must be a non-empty string' };
|
|
137
|
+
const to = typeof args.to === 'string' ? args.to.trim() : '';
|
|
138
|
+
if (!to)
|
|
139
|
+
return { error: 'to must be a language code' };
|
|
140
|
+
const from = typeof args.from === 'string' ? args.from.trim() : undefined;
|
|
141
|
+
return { text, to, from };
|
|
142
|
+
}
|
|
143
|
+
export function sourceLanguage(text, from) {
|
|
144
|
+
if (from)
|
|
145
|
+
return from;
|
|
146
|
+
const [{ code }] = detectLanguage({ text });
|
|
147
|
+
if (code === UNDETERMINED)
|
|
148
|
+
return { error: NEEDS_SOURCE };
|
|
149
|
+
return code;
|
|
150
|
+
}
|
|
151
|
+
const NEEDS_SOURCE = 'could not detect the source language; pass `from` explicitly';
|
|
152
|
+
export function createTranslateTool(runtime, { slm } = {}) {
|
|
153
|
+
return {
|
|
154
|
+
name: 'translate',
|
|
155
|
+
toolset: null,
|
|
156
|
+
description: 'Translate text between languages using the local neural translation models. ' +
|
|
157
|
+
`\`to\` and \`from\` are ISO 639-1 codes. Translating into ${ENGLISH} supports ` +
|
|
158
|
+
`${NMT_TO_ENGLISH.length} languages and out of it ${NMT_FROM_ENGLISH.length}; a pair ` +
|
|
159
|
+
'with English on neither side is translated through English, except between the ' +
|
|
160
|
+
'languages below. ' +
|
|
161
|
+
`${SLM_LANGUAGE_CODES.length} further languages, mostly African, may also be named by ` +
|
|
162
|
+
'their FLORES-200 code and always need an explicit `from`, which the detector cannot ' +
|
|
163
|
+
'name. Elsewhere `from` is detected from the text when omitted; pass it when known.',
|
|
164
|
+
parameters: {
|
|
165
|
+
type: 'object',
|
|
166
|
+
properties: {
|
|
167
|
+
text: { type: 'string', description: 'The text to translate' },
|
|
168
|
+
to: {
|
|
169
|
+
type: 'string',
|
|
170
|
+
description: 'Target language as an ISO 639-1 code, e.g. `es`, or a FLORES-200 code'
|
|
171
|
+
},
|
|
172
|
+
from: {
|
|
173
|
+
type: 'string',
|
|
174
|
+
description: 'Source language as an ISO 639-1 or FLORES-200 code; detected from the text when omitted'
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
required: ['text', 'to']
|
|
178
|
+
},
|
|
179
|
+
effect: () => 'read',
|
|
180
|
+
resource: (args) => ({ kind: 'translation', label: String(args.to ?? '') }),
|
|
181
|
+
execute: async (args, ctx) => {
|
|
182
|
+
const parsed = parseTranslateArgs(args);
|
|
183
|
+
if ('error' in parsed)
|
|
184
|
+
return parsed;
|
|
185
|
+
const from = sourceLanguage(parsed.text, parsed.from);
|
|
186
|
+
if (typeof from === 'object')
|
|
187
|
+
return from;
|
|
188
|
+
if (sameLanguage(from, parsed.to)) {
|
|
189
|
+
return { text: parsed.text, from, to: parsed.to, engine: 'none' };
|
|
190
|
+
}
|
|
191
|
+
const plan = translationPlanFor(from, parsed.to);
|
|
192
|
+
if ('error' in plan)
|
|
193
|
+
return plan;
|
|
194
|
+
if (plan.route === 'slm' && !slm) {
|
|
195
|
+
return { error: `this device cannot translate ${from} to ${parsed.to}` };
|
|
196
|
+
}
|
|
197
|
+
let entered = false;
|
|
198
|
+
try {
|
|
199
|
+
await runtime.enter(ctx?.signal);
|
|
200
|
+
entered = true;
|
|
201
|
+
if (plan.route === 'slm') {
|
|
202
|
+
const text = await slm(plan.model, { text: parsed.text, from: plan.from, to: plan.to }, ctx?.signal);
|
|
203
|
+
return {
|
|
204
|
+
text: stripLanguageLabel(text, plan.from, plan.to),
|
|
205
|
+
from,
|
|
206
|
+
to: parsed.to,
|
|
207
|
+
engine: 'slm',
|
|
208
|
+
model: plan.model
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
const sdk = await runtime.loadSdk();
|
|
212
|
+
const { modelId } = await runtime.ensureLoaded(sdk, plan, ctx?.signal);
|
|
213
|
+
const source = plan.tag ? `${plan.tag} ${parsed.text}` : parsed.text;
|
|
214
|
+
const text = await raceAbort(sdk.translate({ modelId, text: source, stream: false, modelType: 'nmt' }).text, ctx?.signal);
|
|
215
|
+
return { text, from, to: parsed.to, engine: 'nmt', pivoted: Boolean(plan.pivot) };
|
|
216
|
+
}
|
|
217
|
+
catch (err) {
|
|
218
|
+
if (err instanceof AbortedError)
|
|
219
|
+
return { error: 'translation canceled' };
|
|
220
|
+
throw err;
|
|
221
|
+
}
|
|
222
|
+
finally {
|
|
223
|
+
if (entered)
|
|
224
|
+
runtime.exit();
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
}
|
|
@@ -112,7 +112,8 @@ export function registerHarnessTypes(ns) {
|
|
|
112
112
|
{ name: 'grantedWriteDirs', type: 'string', array: true },
|
|
113
113
|
{ name: 'captureInferenceCalls', type: 'bool' },
|
|
114
114
|
{ name: 'capability', type: 'string' },
|
|
115
|
-
{ name: 'arguments', type: 'json' }
|
|
115
|
+
{ name: 'arguments', type: 'json' },
|
|
116
|
+
{ name: 'enhance', type: 'string' }
|
|
116
117
|
]
|
|
117
118
|
});
|
|
118
119
|
ns.register({
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// This file is autogenerated by the hyperschema compiler
|
|
2
|
-
// Schema Version:
|
|
2
|
+
// Schema Version: 12
|
|
3
3
|
/* eslint-disable camelcase */
|
|
4
4
|
/* eslint-disable quotes */
|
|
5
5
|
/* eslint-disable space-before-function-paren */
|
|
6
6
|
|
|
7
7
|
import { c } from 'hyperschema/runtime'
|
|
8
8
|
|
|
9
|
-
const VERSION =
|
|
9
|
+
const VERSION = 12
|
|
10
10
|
|
|
11
11
|
// eslint-disable-next-line no-unused-vars
|
|
12
12
|
let version = VERSION
|
|
@@ -490,7 +490,8 @@ const encoding11 = {
|
|
|
490
490
|
((version >= 5 && m.grantedWriteDirs) ? 16777216 : 0) |
|
|
491
491
|
((version >= 9 && m.captureInferenceCalls) ? 33554432 : 0) |
|
|
492
492
|
((version >= 11 && m.capability) ? 67108864 : 0) |
|
|
493
|
-
((version >= 11 && m.arguments) ? 134217728 : 0)
|
|
493
|
+
((version >= 11 && m.arguments) ? 134217728 : 0) |
|
|
494
|
+
((version >= 12 && m.enhance) ? 268435456 : 0)
|
|
494
495
|
|
|
495
496
|
encoding10.preencode(state, m.type)
|
|
496
497
|
c.uint.preencode(state, flags)
|
|
@@ -520,6 +521,7 @@ const encoding11 = {
|
|
|
520
521
|
if (version >= 5 && m.grantedWriteDirs) encoding11_25.preencode(state, m.grantedWriteDirs)
|
|
521
522
|
if (version >= 11 && m.capability) c.string.preencode(state, m.capability)
|
|
522
523
|
if (version >= 11 && m.arguments) c.json.preencode(state, m.arguments)
|
|
524
|
+
if (version >= 12 && m.enhance) c.string.preencode(state, m.enhance)
|
|
523
525
|
},
|
|
524
526
|
encode(state, m) {
|
|
525
527
|
const flags =
|
|
@@ -550,7 +552,8 @@ const encoding11 = {
|
|
|
550
552
|
((version >= 5 && m.grantedWriteDirs) ? 16777216 : 0) |
|
|
551
553
|
((version >= 9 && m.captureInferenceCalls) ? 33554432 : 0) |
|
|
552
554
|
((version >= 11 && m.capability) ? 67108864 : 0) |
|
|
553
|
-
((version >= 11 && m.arguments) ? 134217728 : 0)
|
|
555
|
+
((version >= 11 && m.arguments) ? 134217728 : 0) |
|
|
556
|
+
((version >= 12 && m.enhance) ? 268435456 : 0)
|
|
554
557
|
|
|
555
558
|
encoding10.encode(state, m.type)
|
|
556
559
|
c.uint.encode(state, flags)
|
|
@@ -580,6 +583,7 @@ const encoding11 = {
|
|
|
580
583
|
if (version >= 5 && m.grantedWriteDirs) encoding11_25.encode(state, m.grantedWriteDirs)
|
|
581
584
|
if (version >= 11 && m.capability) c.string.encode(state, m.capability)
|
|
582
585
|
if (version >= 11 && m.arguments) c.json.encode(state, m.arguments)
|
|
586
|
+
if (version >= 12 && m.enhance) c.string.encode(state, m.enhance)
|
|
583
587
|
},
|
|
584
588
|
decode(state) {
|
|
585
589
|
const r0 = encoding10.decode(state)
|
|
@@ -614,7 +618,8 @@ const encoding11 = {
|
|
|
614
618
|
grantedWriteDirs: (version >= 5 && (flags & 16777216) !== 0) ? encoding11_25.decode(state) : null,
|
|
615
619
|
captureInferenceCalls: (version >= 9 && (flags & 33554432) !== 0),
|
|
616
620
|
capability: (version >= 11 && (flags & 67108864) !== 0) ? c.string.decode(state) : null,
|
|
617
|
-
arguments: (version >= 11 && (flags & 134217728) !== 0) ? c.json.decode(state) : null
|
|
621
|
+
arguments: (version >= 11 && (flags & 134217728) !== 0) ? c.json.decode(state) : null,
|
|
622
|
+
enhance: (version >= 12 && (flags & 268435456) !== 0) ? c.string.decode(state) : null
|
|
618
623
|
}
|
|
619
624
|
}
|
|
620
625
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// This file is autogenerated by the hyperschema compiler
|
|
2
|
-
// Schema Version:
|
|
2
|
+
// Schema Version: 12
|
|
3
3
|
/* eslint-disable camelcase */
|
|
4
4
|
/* eslint-disable quotes */
|
|
5
5
|
/* eslint-disable space-before-function-paren */
|
|
6
6
|
|
|
7
7
|
import { c } from 'hyperschema/runtime'
|
|
8
8
|
|
|
9
|
-
const VERSION =
|
|
9
|
+
const VERSION = 12
|
|
10
10
|
|
|
11
11
|
// eslint-disable-next-line no-unused-vars
|
|
12
12
|
let version = VERSION
|
|
@@ -490,7 +490,8 @@ const encoding11 = {
|
|
|
490
490
|
((version >= 5 && m.grantedWriteDirs) ? 16777216 : 0) |
|
|
491
491
|
((version >= 9 && m.captureInferenceCalls) ? 33554432 : 0) |
|
|
492
492
|
((version >= 11 && m.capability) ? 67108864 : 0) |
|
|
493
|
-
((version >= 11 && m.arguments) ? 134217728 : 0)
|
|
493
|
+
((version >= 11 && m.arguments) ? 134217728 : 0) |
|
|
494
|
+
((version >= 12 && m.enhance) ? 268435456 : 0)
|
|
494
495
|
|
|
495
496
|
encoding10.preencode(state, m.type)
|
|
496
497
|
c.uint.preencode(state, flags)
|
|
@@ -520,6 +521,7 @@ const encoding11 = {
|
|
|
520
521
|
if (version >= 5 && m.grantedWriteDirs) encoding11_25.preencode(state, m.grantedWriteDirs)
|
|
521
522
|
if (version >= 11 && m.capability) c.string.preencode(state, m.capability)
|
|
522
523
|
if (version >= 11 && m.arguments) c.json.preencode(state, m.arguments)
|
|
524
|
+
if (version >= 12 && m.enhance) c.string.preencode(state, m.enhance)
|
|
523
525
|
},
|
|
524
526
|
encode(state, m) {
|
|
525
527
|
const flags =
|
|
@@ -550,7 +552,8 @@ const encoding11 = {
|
|
|
550
552
|
((version >= 5 && m.grantedWriteDirs) ? 16777216 : 0) |
|
|
551
553
|
((version >= 9 && m.captureInferenceCalls) ? 33554432 : 0) |
|
|
552
554
|
((version >= 11 && m.capability) ? 67108864 : 0) |
|
|
553
|
-
((version >= 11 && m.arguments) ? 134217728 : 0)
|
|
555
|
+
((version >= 11 && m.arguments) ? 134217728 : 0) |
|
|
556
|
+
((version >= 12 && m.enhance) ? 268435456 : 0)
|
|
554
557
|
|
|
555
558
|
encoding10.encode(state, m.type)
|
|
556
559
|
c.uint.encode(state, flags)
|
|
@@ -580,6 +583,7 @@ const encoding11 = {
|
|
|
580
583
|
if (version >= 5 && m.grantedWriteDirs) encoding11_25.encode(state, m.grantedWriteDirs)
|
|
581
584
|
if (version >= 11 && m.capability) c.string.encode(state, m.capability)
|
|
582
585
|
if (version >= 11 && m.arguments) c.json.encode(state, m.arguments)
|
|
586
|
+
if (version >= 12 && m.enhance) c.string.encode(state, m.enhance)
|
|
583
587
|
},
|
|
584
588
|
decode(state) {
|
|
585
589
|
const r0 = encoding10.decode(state)
|
|
@@ -614,7 +618,8 @@ const encoding11 = {
|
|
|
614
618
|
grantedWriteDirs: (version >= 5 && (flags & 16777216) !== 0) ? encoding11_25.decode(state) : null,
|
|
615
619
|
captureInferenceCalls: (version >= 9 && (flags & 33554432) !== 0),
|
|
616
620
|
capability: (version >= 11 && (flags & 67108864) !== 0) ? c.string.decode(state) : null,
|
|
617
|
-
arguments: (version >= 11 && (flags & 134217728) !== 0) ? c.json.decode(state) : null
|
|
621
|
+
arguments: (version >= 11 && (flags & 134217728) !== 0) ? c.json.decode(state) : null,
|
|
622
|
+
enhance: (version >= 12 && (flags & 268435456) !== 0) ? c.string.decode(state) : null
|
|
618
623
|
}
|
|
619
624
|
}
|
|
620
625
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version":
|
|
2
|
+
"version": 12,
|
|
3
3
|
"schema": [
|
|
4
4
|
{
|
|
5
5
|
"name": "empty",
|
|
@@ -470,6 +470,11 @@
|
|
|
470
470
|
"name": "arguments",
|
|
471
471
|
"type": "json",
|
|
472
472
|
"version": 11
|
|
473
|
+
},
|
|
474
|
+
{
|
|
475
|
+
"name": "enhance",
|
|
476
|
+
"type": "string",
|
|
477
|
+
"version": 12
|
|
473
478
|
}
|
|
474
479
|
]
|
|
475
480
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// This file is autogenerated by hyperschema-ts
|
|
2
|
-
// Schema version:
|
|
2
|
+
// Schema version: 12
|
|
3
3
|
// Do not edit manually.
|
|
4
4
|
|
|
5
5
|
export interface HarnessEmpty {
|
|
@@ -90,6 +90,7 @@ export interface HarnessCompletionFrame {
|
|
|
90
90
|
captureInferenceCalls?: boolean
|
|
91
91
|
capability?: string | null
|
|
92
92
|
arguments?: unknown | null
|
|
93
|
+
enhance?: string | null
|
|
93
94
|
}
|
|
94
95
|
|
|
95
96
|
export type HarnessCompletionEventType = "content" | "thinking" | "tool-call" | "tool-result" | "approval-ask" | "metrics" | "error" | "aborted" | "attach-ask" | "fetch-ask" | "progress" | "rag-ask" | "question-ask" | "done" | "tool-activity" | "drive-ask" | "inference-call" | "inference-sent"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qvac/harness",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "An AI harness implementing generate(context) via @qvac/sdk. Knows nothing about workbench, hyperdb, or chunks — just inference in, events out.",
|
|
6
6
|
"exports": {
|
|
@@ -540,6 +540,10 @@
|
|
|
540
540
|
"types": "./dist-lib/lib/tools/skills/tool-grants.d.ts",
|
|
541
541
|
"default": "./dist-lib/lib/tools/skills/tool-grants.js"
|
|
542
542
|
},
|
|
543
|
+
"./lib/tools/translate.ts": {
|
|
544
|
+
"types": "./dist-lib/lib/tools/translate.d.ts",
|
|
545
|
+
"default": "./dist-lib/lib/tools/translate.js"
|
|
546
|
+
},
|
|
543
547
|
"./lib/tools/url-guard.ts": {
|
|
544
548
|
"types": "./dist-lib/lib/tools/url-guard.d.ts",
|
|
545
549
|
"default": "./dist-lib/lib/tools/url-guard.js"
|
|
@@ -565,6 +569,7 @@
|
|
|
565
569
|
"lint": "prettier . --check && lunte && tsc --noEmit",
|
|
566
570
|
"build:bundle": "node scripts/build-bundle.mjs",
|
|
567
571
|
"skill-eval": "bare examples/skill-eval/run.ts",
|
|
572
|
+
"translate-eval": "bare examples/translate-eval/run.ts",
|
|
568
573
|
"prepack": "node scripts/vendor-python-wheels.mjs && node scripts/build-lib.mjs && node scripts/build-bundle.mjs --minify",
|
|
569
574
|
"vendor:wheels": "node scripts/vendor-python-wheels.mjs",
|
|
570
575
|
"build:lib": "node scripts/build-lib.mjs",
|