@qvac/sdk 0.10.1 → 0.11.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/NOTICE +92 -54
- package/dist/client/api/cancel.d.ts +24 -32
- package/dist/client/api/cancel.js +58 -31
- package/dist/client/api/client-request-id.d.ts +17 -0
- package/dist/client/api/client-request-id.js +27 -0
- package/dist/client/api/completion-stream.d.ts +1 -1
- package/dist/client/api/completion-stream.js +34 -3
- package/dist/client/api/diffusion.d.ts +46 -0
- package/dist/client/api/diffusion.js +50 -1
- package/dist/client/api/download-asset.d.ts +12 -2
- package/dist/client/api/download-asset.js +21 -3
- package/dist/client/api/embed.d.ts +8 -4
- package/dist/client/api/embed.js +14 -1
- package/dist/client/api/get-model-info.d.ts +1 -1
- package/dist/client/api/index.d.ts +1 -0
- package/dist/client/api/index.js +1 -0
- package/dist/client/api/load-model.d.ts +12 -4
- package/dist/client/api/load-model.js +25 -1
- package/dist/client/api/rag.d.ts +9 -3
- package/dist/client/api/rag.js +23 -3
- package/dist/client/api/transcribe.d.ts +20 -8
- package/dist/client/api/transcribe.js +58 -4
- package/dist/client/api/unload-model.d.ts +5 -2
- package/dist/client/api/unload-model.js +9 -4
- package/dist/client/api/upscale.d.ts +45 -0
- package/dist/client/api/upscale.js +99 -0
- package/dist/client/rpc/expo-rpc-client.js +2 -1
- package/dist/client/rpc/node-rpc-client.js +18 -7
- package/dist/client/rpc/rpc-client.d.ts +2 -2
- package/dist/client/rpc/rpc-client.js +10 -4
- package/dist/client/rpc/rpc-error.d.ts +9 -0
- package/dist/client/rpc/rpc-error.js +92 -0
- package/dist/examples/cancel-by-request-id.d.ts +38 -0
- package/dist/examples/cancel-by-request-id.js +103 -0
- package/dist/examples/diffusion-esrgan-upscale.d.ts +2 -0
- package/dist/examples/diffusion-esrgan-upscale.js +78 -0
- package/dist/examples/download-with-cancel.js +10 -10
- package/dist/examples/embed-multi-gpu.d.ts +2 -0
- package/dist/examples/embed-multi-gpu.js +46 -0
- package/dist/examples/llamacpp-multi-gpu.d.ts +2 -0
- package/dist/examples/llamacpp-multi-gpu.js +57 -0
- package/dist/examples/rag/rag-hyperdb/cancellation.js +20 -17
- package/dist/examples/tools/llamacpp-tools-gemma4.d.ts +2 -0
- package/dist/examples/tools/llamacpp-tools-gemma4.js +76 -0
- package/dist/examples/tools/llamacpp-tools-qwen35.d.ts +2 -0
- package/dist/examples/tools/llamacpp-tools-qwen35.js +70 -0
- package/dist/examples/transcription/whispercpp-microphone-conversation.d.ts +2 -0
- package/dist/examples/transcription/whispercpp-microphone-conversation.js +102 -0
- package/dist/examples/tts/supertonic.js +1 -1
- package/dist/expo/plugins/withMobileBundle.d.ts +20 -4
- package/dist/expo/plugins/withMobileBundle.js +44 -6
- package/dist/index.d.ts +5 -2
- package/dist/index.js +21 -1
- package/dist/models/registry/models.d.ts +186 -318
- package/dist/models/registry/models.js +1522 -1667
- package/dist/pear/pre.d.ts +3 -0
- package/dist/pear/pre.js +3 -0
- package/dist/schemas/cancel.d.ts +167 -28
- package/dist/schemas/cancel.js +119 -19
- package/dist/schemas/common.d.ts +427 -208
- package/dist/schemas/common.js +3 -1
- package/dist/schemas/completion-event.d.ts +14 -0
- package/dist/schemas/completion-event.js +11 -1
- package/dist/schemas/completion-stream.d.ts +15 -1
- package/dist/schemas/completion-stream.js +25 -7
- package/dist/schemas/download-asset.d.ts +15 -9
- package/dist/schemas/download-asset.js +17 -6
- package/dist/schemas/embed.d.ts +1 -0
- package/dist/schemas/embed.js +5 -0
- package/dist/schemas/error.d.ts +31 -0
- package/dist/schemas/error.js +29 -1
- package/dist/schemas/finetune.d.ts +2 -0
- package/dist/schemas/finetune.js +5 -0
- package/dist/schemas/get-model-info.d.ts +6 -6
- package/dist/schemas/llamacpp-config.d.ts +54 -8
- package/dist/schemas/llamacpp-config.js +12 -0
- package/dist/schemas/load-model.d.ts +1911 -1260
- package/dist/schemas/load-model.js +15 -0
- package/dist/schemas/model-src-utils.d.ts +14 -14
- package/dist/schemas/model-types.d.ts +10 -10
- package/dist/schemas/ocr.d.ts +3 -3
- package/dist/schemas/plugin.d.ts +40 -1
- package/dist/schemas/plugin.js +10 -1
- package/dist/schemas/rag.d.ts +9 -0
- package/dist/schemas/rag.js +17 -9
- package/dist/schemas/registry.d.ts +30 -30
- package/dist/schemas/reload-config.d.ts +14 -14
- package/dist/schemas/sdcpp-config.d.ts +131 -17
- package/dist/schemas/sdcpp-config.js +163 -1
- package/dist/schemas/sdk-config.d.ts +649 -271
- package/dist/schemas/sdk-errors-client.d.ts +1 -0
- package/dist/schemas/sdk-errors-client.js +5 -0
- package/dist/schemas/sdk-errors-server.d.ts +5 -0
- package/dist/schemas/sdk-errors-server.js +25 -0
- package/dist/schemas/text-to-speech.d.ts +78 -78
- package/dist/schemas/transcription-config.d.ts +24 -24
- package/dist/schemas/transcription.d.ts +56 -2
- package/dist/schemas/transcription.js +27 -0
- package/dist/schemas/translate.d.ts +2 -0
- package/dist/schemas/translate.js +13 -2
- package/dist/schemas/translation-config.d.ts +40 -40
- package/dist/schemas/unload-model.d.ts +2 -1
- package/dist/schemas/unload-model.js +4 -1
- package/dist/scripts/run-unit-tests.js +15 -2
- package/dist/server/bare/delegate-rpc-client.js +10 -8
- package/dist/server/bare/ops/cancel.d.ts +27 -1
- package/dist/server/bare/ops/cancel.js +36 -10
- package/dist/server/bare/ops/embed.d.ts +3 -3
- package/dist/server/bare/ops/embed.js +144 -28
- package/dist/server/bare/ops/kv-cache-utils.d.ts +0 -7
- package/dist/server/bare/ops/kv-cache-utils.js +8 -47
- package/dist/server/bare/ops/transcribe.d.ts +10 -5
- package/dist/server/bare/ops/transcribe.js +196 -41
- package/dist/server/bare/ops/translate.d.ts +1 -1
- package/dist/server/bare/ops/translate.js +197 -88
- package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.d.ts +12 -3
- package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.js +170 -172
- package/dist/server/bare/plugins/llamacpp-completion/ops/finetune.js +125 -21
- package/dist/server/bare/plugins/llamacpp-completion/ops/kv-cache-session.d.ts +154 -0
- package/dist/server/bare/plugins/llamacpp-completion/ops/kv-cache-session.js +448 -0
- package/dist/server/bare/plugins/llamacpp-completion/ops/kv-cache-state.d.ts +21 -73
- package/dist/server/bare/plugins/llamacpp-completion/ops/kv-cache-state.js +18 -101
- package/dist/server/bare/plugins/llamacpp-completion/plugin.d.ts +30 -3
- package/dist/server/bare/plugins/llamacpp-completion/plugin.js +157 -85
- package/dist/server/bare/plugins/llamacpp-completion/transform.d.ts +10 -0
- package/dist/server/bare/plugins/llamacpp-completion/transform.js +34 -0
- package/dist/server/bare/plugins/llamacpp-embedding/plugin.d.ts +7 -0
- package/dist/server/bare/plugins/llamacpp-embedding/plugin.js +10 -1
- package/dist/server/bare/plugins/nmtcpp-translation/plugin.d.ts +17 -15
- package/dist/server/bare/plugins/nmtcpp-translation/plugin.js +5 -1
- package/dist/server/bare/plugins/onnx-ocr/plugin.d.ts +3 -3
- package/dist/server/bare/plugins/onnx-ocr/plugin.js +3 -0
- package/dist/server/bare/plugins/onnx-tts/plugin.d.ts +39 -39
- package/dist/server/bare/plugins/onnx-tts/plugin.js +6 -0
- package/dist/server/bare/plugins/parakeet-transcription/plugin.d.ts +29 -21
- package/dist/server/bare/plugins/parakeet-transcription/plugin.js +4 -1
- package/dist/server/bare/plugins/sdcpp-generation/ops/diffusion.js +8 -0
- package/dist/server/bare/plugins/sdcpp-generation/ops/upscale.d.ts +3 -0
- package/dist/server/bare/plugins/sdcpp-generation/ops/upscale.js +40 -0
- package/dist/server/bare/plugins/sdcpp-generation/plugin.d.ts +91 -16
- package/dist/server/bare/plugins/sdcpp-generation/plugin.js +97 -7
- package/dist/server/bare/plugins/whispercpp-transcription/plugin.d.ts +22 -3
- package/dist/server/bare/plugins/whispercpp-transcription/plugin.js +50 -14
- package/dist/server/bare/rag-hyperdb/index.d.ts +1 -1
- package/dist/server/bare/rag-hyperdb/index.js +1 -1
- package/dist/server/bare/rag-hyperdb/rag-operation-manager.d.ts +26 -4
- package/dist/server/bare/rag-hyperdb/rag-operation-manager.js +65 -28
- package/dist/server/bare/runtime/disposable-scope.d.ts +36 -0
- package/dist/server/bare/runtime/disposable-scope.js +69 -0
- package/dist/server/bare/runtime/index.d.ts +8 -0
- package/dist/server/bare/runtime/index.js +3 -0
- package/dist/server/bare/runtime/request-context.d.ts +49 -0
- package/dist/server/bare/runtime/request-context.js +1 -0
- package/dist/server/bare/runtime/request-id.d.ts +12 -0
- package/dist/server/bare/runtime/request-id.js +14 -0
- package/dist/server/bare/runtime/request-registry-singleton.d.ts +4 -0
- package/dist/server/bare/runtime/request-registry-singleton.js +27 -0
- package/dist/server/bare/runtime/request-registry.d.ts +136 -0
- package/dist/server/bare/runtime/request-registry.js +297 -0
- package/dist/server/bare/runtime/with-request-context.d.ts +22 -0
- package/dist/server/bare/runtime/with-request-context.js +53 -0
- package/dist/server/bare/types/addon-responses.d.ts +11 -1
- package/dist/server/rpc/handler-registry.js +26 -7
- package/dist/server/rpc/handlers/cancel-delegated.js +28 -31
- package/dist/server/rpc/handlers/cancelHandler.d.ts +30 -1
- package/dist/server/rpc/handlers/cancelHandler.js +54 -22
- package/dist/server/rpc/handlers/delete-cache.d.ts +9 -0
- package/dist/server/rpc/handlers/delete-cache.js +13 -15
- package/dist/server/rpc/handlers/download-asset.js +133 -40
- package/dist/server/rpc/handlers/index.d.ts +2 -0
- package/dist/server/rpc/handlers/index.js +2 -0
- package/dist/server/rpc/handlers/load-model/download-manager.d.ts +60 -2
- package/dist/server/rpc/handlers/load-model/download-manager.js +141 -8
- package/dist/server/rpc/handlers/load-model/handler.js +213 -98
- package/dist/server/rpc/handlers/load-model/http.js +3 -3
- package/dist/server/rpc/handlers/load-model/hyperdrive.js +1 -1
- package/dist/server/rpc/handlers/load-model/registry.js +1 -1
- package/dist/server/rpc/handlers/load-model/resolve-session.d.ts +20 -1
- package/dist/server/rpc/handlers/load-model/resolve-session.js +6 -5
- package/dist/server/rpc/handlers/load-model/resolve.d.ts +3 -2
- package/dist/server/rpc/handlers/load-model/resolve.js +9 -6
- package/dist/server/rpc/handlers/load-model/types.d.ts +24 -0
- package/dist/server/rpc/handlers/rag.js +133 -15
- package/dist/server/rpc/handlers/upscale-stream.d.ts +3 -0
- package/dist/server/rpc/handlers/upscale-stream.js +4 -0
- package/dist/server/utils/completion-normalizer.js +8 -0
- package/dist/server/utils/tools/dialect.js +4 -0
- package/dist/server/utils/tools/parser.js +16 -1
- package/dist/server/utils/tools/parsers/gemma4native.d.ts +4 -0
- package/dist/server/utils/tools/parsers/gemma4native.js +60 -0
- package/dist/server/utils/tools/parsers/qwen35.d.ts +4 -0
- package/dist/server/utils/tools/parsers/qwen35.js +120 -0
- package/dist/utils/aggregate-events.d.ts +9 -0
- package/dist/utils/aggregate-events.js +18 -3
- package/dist/utils/decorate-promise.d.ts +34 -0
- package/dist/utils/decorate-promise.js +35 -0
- package/dist/utils/errors-client.d.ts +3 -0
- package/dist/utils/errors-client.js +5 -0
- package/dist/utils/errors-server.d.ts +85 -0
- package/dist/utils/errors-server.js +97 -0
- package/package.json +20 -15
|
@@ -1,3 +1,55 @@
|
|
|
1
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
2
|
+
if (value !== null && value !== void 0) {
|
|
3
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
4
|
+
var dispose, inner;
|
|
5
|
+
if (async) {
|
|
6
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
7
|
+
dispose = value[Symbol.asyncDispose];
|
|
8
|
+
}
|
|
9
|
+
if (dispose === void 0) {
|
|
10
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
11
|
+
dispose = value[Symbol.dispose];
|
|
12
|
+
if (async) inner = dispose;
|
|
13
|
+
}
|
|
14
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
15
|
+
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
16
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
17
|
+
}
|
|
18
|
+
else if (async) {
|
|
19
|
+
env.stack.push({ async: true });
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
};
|
|
23
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
24
|
+
return function (env) {
|
|
25
|
+
function fail(e) {
|
|
26
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
27
|
+
env.hasError = true;
|
|
28
|
+
}
|
|
29
|
+
var r, s = 0;
|
|
30
|
+
function next() {
|
|
31
|
+
while (r = env.stack.pop()) {
|
|
32
|
+
try {
|
|
33
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
34
|
+
if (r.dispose) {
|
|
35
|
+
var result = r.dispose.call(r.value);
|
|
36
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
37
|
+
}
|
|
38
|
+
else s |= 1;
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
fail(e);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
45
|
+
if (env.hasError) throw env.error;
|
|
46
|
+
}
|
|
47
|
+
return next();
|
|
48
|
+
};
|
|
49
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
50
|
+
var e = new Error(message);
|
|
51
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
|
+
});
|
|
1
53
|
import { getModel, getModelConfig, getModelEntry, } from "../registry/model-registry.js";
|
|
2
54
|
import { ModelType, } from "../../../schemas/index.js";
|
|
3
55
|
import { createAudioStream } from "../utils/audio-input.js";
|
|
@@ -6,8 +58,9 @@ import { TranscriptionFailedError } from "../../../utils/errors-server.js";
|
|
|
6
58
|
import { nowMs } from "../../../profiling/index.js";
|
|
7
59
|
import { buildStreamResult } from "../../../profiling/model-execution.js";
|
|
8
60
|
import { assertMetadataSupported, toTranscribeSegment, } from "../utils/transcribe-metadata.js";
|
|
61
|
+
import { getRequestRegistry, withRequestContext, } from "../runtime/index.js";
|
|
62
|
+
import { generateServerRequestId } from "../runtime/request-id.js";
|
|
9
63
|
export { assertMetadataSupported, toTranscribeSegment, };
|
|
10
|
-
const logger = getServerLogger();
|
|
11
64
|
function hasRunStreaming(model) {
|
|
12
65
|
return "runStreaming" in model && typeof model.runStreaming === "function";
|
|
13
66
|
}
|
|
@@ -56,22 +109,59 @@ async function restorePrompt(modelId, originalConfig) {
|
|
|
56
109
|
...(miscConfig && { miscConfig }),
|
|
57
110
|
});
|
|
58
111
|
}
|
|
59
|
-
export async function* transcribe(params) {
|
|
60
|
-
const {
|
|
61
|
-
const engineType = getEngineModelType(modelId);
|
|
62
|
-
assertMetadataSupported(modelId, engineType, metadata);
|
|
63
|
-
const silenceMarker = SILENCE_MARKERS[engineType] ?? "";
|
|
64
|
-
const audioFormat = getAudioFormat(modelId, engineType);
|
|
65
|
-
const originalConfig = await applyPrompt(modelId, params.prompt, engineType);
|
|
66
|
-
let modelExecutionMs = 0;
|
|
67
|
-
let response;
|
|
112
|
+
export async function* transcribe(params, requestId) {
|
|
113
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
68
114
|
try {
|
|
115
|
+
const { modelId, metadata } = params;
|
|
116
|
+
// Open a request-scoped lifecycle. The registry routes
|
|
117
|
+
// `cancel({ requestId })` and `cancel({ modelId, kind: "transcribe" })`
|
|
118
|
+
// through this context. Falls back to a server-generated id if the
|
|
119
|
+
// client didn't send one.
|
|
120
|
+
const ctx = __addDisposableResource(env_1, getRequestRegistry().begin({
|
|
121
|
+
requestId: requestId ?? generateServerRequestId(),
|
|
122
|
+
kind: "transcribe",
|
|
123
|
+
modelId,
|
|
124
|
+
}), true);
|
|
125
|
+
const requestLogger = withRequestContext(getServerLogger(), ctx);
|
|
126
|
+
const engineType = getEngineModelType(modelId);
|
|
127
|
+
assertMetadataSupported(modelId, engineType, metadata);
|
|
128
|
+
const silenceMarker = SILENCE_MARKERS[engineType] ?? "";
|
|
129
|
+
const audioFormat = getAudioFormat(modelId, engineType);
|
|
130
|
+
const originalConfig = await applyPrompt(modelId, params.prompt, engineType);
|
|
131
|
+
if (originalConfig) {
|
|
132
|
+
// `restorePrompt` runs on every exit path — happy, throw, cancel —
|
|
133
|
+
// via the scope. LIFO unwinding pairs with the addon-cancel detach
|
|
134
|
+
// below.
|
|
135
|
+
ctx.scope.defer(() => restorePrompt(modelId, originalConfig));
|
|
136
|
+
}
|
|
69
137
|
const model = getModel(modelId);
|
|
138
|
+
// Hard-cancel wiring: whisper.cpp / parakeet expose model-wide
|
|
139
|
+
// `addon.cancel()`. The listener forwards an abort so the
|
|
140
|
+
// currently-running transcription stops decoding ASAP. The
|
|
141
|
+
// `if (ctx.signal.aborted) break` guard inside the iterate loop is
|
|
142
|
+
// the soft-cancel safety net for the case where the abort fires
|
|
143
|
+
// between the addon flag flipping and the iterator's next pull.
|
|
144
|
+
const onAbort = () => {
|
|
145
|
+
const addon = model.addon;
|
|
146
|
+
if (addon?.cancel) {
|
|
147
|
+
addon.cancel.call(addon).catch((err) => {
|
|
148
|
+
requestLogger.warn(`[cancel] addon.cancel() rejected during abort for modelId=${modelId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
ctx.signal.addEventListener("abort", onAbort, { once: true });
|
|
153
|
+
if (ctx.signal.aborted)
|
|
154
|
+
onAbort();
|
|
155
|
+
ctx.scope.defer(() => {
|
|
156
|
+
ctx.signal.removeEventListener("abort", onAbort);
|
|
157
|
+
});
|
|
70
158
|
const audioStream = await createAudioStream(params.audioChunk, audioFormat);
|
|
71
159
|
const modelStart = nowMs();
|
|
72
|
-
response = (await model.run(audioStream));
|
|
160
|
+
const response = (await model.run(audioStream));
|
|
73
161
|
for await (const output of response.iterate()) {
|
|
74
|
-
|
|
162
|
+
if (ctx.signal.aborted)
|
|
163
|
+
break;
|
|
164
|
+
requestLogger.debug("Streaming Transcription Update:", output);
|
|
75
165
|
const chunks = output;
|
|
76
166
|
if (metadata) {
|
|
77
167
|
for (const chunk of chunks) {
|
|
@@ -91,41 +181,102 @@ export async function* transcribe(params) {
|
|
|
91
181
|
yield text;
|
|
92
182
|
}
|
|
93
183
|
}
|
|
94
|
-
modelExecutionMs = nowMs() - modelStart;
|
|
184
|
+
const modelExecutionMs = nowMs() - modelStart;
|
|
185
|
+
const stats = {
|
|
186
|
+
...(response.stats?.audioDurationMs !== undefined && { audioDuration: response.stats.audioDurationMs }),
|
|
187
|
+
...(response.stats?.realTimeFactor !== undefined && { realTimeFactor: response.stats.realTimeFactor }),
|
|
188
|
+
...(response.stats?.tokensPerSecond !== undefined && { tokensPerSecond: response.stats.tokensPerSecond }),
|
|
189
|
+
...(response.stats?.totalTokens !== undefined && { totalTokens: response.stats.totalTokens }),
|
|
190
|
+
...(response.stats?.totalSegments !== undefined && { totalSegments: response.stats.totalSegments }),
|
|
191
|
+
...(response.stats?.whisperEncodeMs !== undefined && { whisperEncodeTime: response.stats.whisperEncodeMs }),
|
|
192
|
+
...(response.stats?.whisperDecodeMs !== undefined && { whisperDecodeTime: response.stats.whisperDecodeMs }),
|
|
193
|
+
...(response.stats?.encoderMs !== undefined && { encoderTime: response.stats.encoderMs }),
|
|
194
|
+
...(response.stats?.decoderMs !== undefined && { decoderTime: response.stats.decoderMs }),
|
|
195
|
+
...(response.stats?.melSpecMs !== undefined && { melSpecTime: response.stats.melSpecMs }),
|
|
196
|
+
};
|
|
197
|
+
return buildStreamResult(modelExecutionMs, stats);
|
|
198
|
+
}
|
|
199
|
+
catch (e_1) {
|
|
200
|
+
env_1.error = e_1;
|
|
201
|
+
env_1.hasError = true;
|
|
95
202
|
}
|
|
96
203
|
finally {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
204
|
+
const result_1 = __disposeResources(env_1);
|
|
205
|
+
if (result_1)
|
|
206
|
+
await result_1;
|
|
100
207
|
}
|
|
101
|
-
const stats = {
|
|
102
|
-
...(response?.stats?.audioDurationMs !== undefined && { audioDuration: response.stats.audioDurationMs }),
|
|
103
|
-
...(response?.stats?.realTimeFactor !== undefined && { realTimeFactor: response.stats.realTimeFactor }),
|
|
104
|
-
...(response?.stats?.tokensPerSecond !== undefined && { tokensPerSecond: response.stats.tokensPerSecond }),
|
|
105
|
-
...(response?.stats?.totalTokens !== undefined && { totalTokens: response.stats.totalTokens }),
|
|
106
|
-
...(response?.stats?.totalSegments !== undefined && { totalSegments: response.stats.totalSegments }),
|
|
107
|
-
...(response?.stats?.whisperEncodeMs !== undefined && { whisperEncodeTime: response.stats.whisperEncodeMs }),
|
|
108
|
-
...(response?.stats?.whisperDecodeMs !== undefined && { whisperDecodeTime: response.stats.whisperDecodeMs }),
|
|
109
|
-
...(response?.stats?.encoderMs !== undefined && { encoderTime: response.stats.encoderMs }),
|
|
110
|
-
...(response?.stats?.decoderMs !== undefined && { decoderTime: response.stats.decoderMs }),
|
|
111
|
-
...(response?.stats?.melSpecMs !== undefined && { melSpecTime: response.stats.melSpecMs }),
|
|
112
|
-
};
|
|
113
|
-
return buildStreamResult(modelExecutionMs, stats);
|
|
114
208
|
}
|
|
115
|
-
export async function* transcribeStream(modelId, audioInputStream, prompt, metadata) {
|
|
116
|
-
const
|
|
117
|
-
assertMetadataSupported(modelId, engineType, metadata);
|
|
118
|
-
const silenceMarker = SILENCE_MARKERS[engineType] ?? "";
|
|
119
|
-
const originalConfig = await applyPrompt(modelId, prompt, engineType);
|
|
209
|
+
export async function* transcribeStream(modelId, audioInputStream, prompt, metadata, opts, requestId) {
|
|
210
|
+
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
120
211
|
try {
|
|
212
|
+
// Same `kind: "transcribe"` as the unary variant — the registry
|
|
213
|
+
// doesn't distinguish streaming vs non-streaming variants of the same
|
|
214
|
+
// operation, so `cancel({ modelId, kind: "transcribe" })` cancels
|
|
215
|
+
// either shape.
|
|
216
|
+
const ctx = __addDisposableResource(env_2, getRequestRegistry().begin({
|
|
217
|
+
requestId: requestId ?? generateServerRequestId(),
|
|
218
|
+
kind: "transcribe",
|
|
219
|
+
modelId,
|
|
220
|
+
}), true);
|
|
221
|
+
const requestLogger = withRequestContext(getServerLogger(), ctx);
|
|
222
|
+
const engineType = getEngineModelType(modelId);
|
|
223
|
+
assertMetadataSupported(modelId, engineType, metadata);
|
|
224
|
+
const silenceMarker = SILENCE_MARKERS[engineType] ?? "";
|
|
225
|
+
const originalConfig = await applyPrompt(modelId, prompt, engineType);
|
|
226
|
+
if (originalConfig) {
|
|
227
|
+
ctx.scope.defer(() => restorePrompt(modelId, originalConfig));
|
|
228
|
+
}
|
|
121
229
|
const model = getModel(modelId);
|
|
122
230
|
if (!hasRunStreaming(model)) {
|
|
123
231
|
throw new TranscriptionFailedError(`Model ${modelId} does not support streaming transcription`);
|
|
124
232
|
}
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
233
|
+
const onAbort = () => {
|
|
234
|
+
const addon = model.addon;
|
|
235
|
+
if (addon?.cancel) {
|
|
236
|
+
addon.cancel.call(addon).catch((err) => {
|
|
237
|
+
requestLogger.warn(`[cancel] addon.cancel() rejected during abort for modelId=${modelId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
ctx.signal.addEventListener("abort", onAbort, { once: true });
|
|
242
|
+
if (ctx.signal.aborted)
|
|
243
|
+
onAbort();
|
|
244
|
+
ctx.scope.defer(() => {
|
|
245
|
+
ctx.signal.removeEventListener("abort", onAbort);
|
|
246
|
+
});
|
|
247
|
+
const runOpts = {};
|
|
248
|
+
if (opts?.emitVadEvents)
|
|
249
|
+
runOpts.emitVadEvents = true;
|
|
250
|
+
if (opts?.endOfTurnSilenceMs !== undefined) {
|
|
251
|
+
runOpts.endOfTurnSilenceMs = opts.endOfTurnSilenceMs;
|
|
252
|
+
}
|
|
253
|
+
if (opts?.vadRunIntervalMs !== undefined) {
|
|
254
|
+
runOpts.vadRunIntervalMs = opts.vadRunIntervalMs;
|
|
255
|
+
}
|
|
256
|
+
const response = await model.runStreaming(audioInputStream, runOpts);
|
|
257
|
+
for await (const output of response.iterate()) {
|
|
258
|
+
if (ctx.signal.aborted)
|
|
259
|
+
break;
|
|
260
|
+
requestLogger.debug("Live Transcription Update:", output);
|
|
261
|
+
if (!Array.isArray(output)) {
|
|
262
|
+
if (output.type === "vad") {
|
|
263
|
+
yield {
|
|
264
|
+
type: "vad",
|
|
265
|
+
speaking: output.speaking,
|
|
266
|
+
probability: output.probability,
|
|
267
|
+
};
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
if (output.type === "endOfTurn") {
|
|
271
|
+
yield {
|
|
272
|
+
type: "endOfTurn",
|
|
273
|
+
silenceDurationMs: output.silenceDurationMs,
|
|
274
|
+
};
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
for (const segment of output) {
|
|
129
280
|
if (!segment.text)
|
|
130
281
|
continue;
|
|
131
282
|
if (silenceMarker && segment.text.includes(silenceMarker))
|
|
@@ -140,9 +291,13 @@ export async function* transcribeStream(modelId, audioInputStream, prompt, metad
|
|
|
140
291
|
}
|
|
141
292
|
}
|
|
142
293
|
}
|
|
294
|
+
catch (e_2) {
|
|
295
|
+
env_2.error = e_2;
|
|
296
|
+
env_2.hasError = true;
|
|
297
|
+
}
|
|
143
298
|
finally {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
299
|
+
const result_2 = __disposeResources(env_2);
|
|
300
|
+
if (result_2)
|
|
301
|
+
await result_2;
|
|
147
302
|
}
|
|
148
303
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type TranslateParams, type TranslationStats } from "../../../schemas/index";
|
|
2
2
|
export declare function getLanguage(code: string | undefined): string;
|
|
3
3
|
export declare function isAfrican(code: string | undefined): boolean;
|
|
4
|
-
export declare function translate(params: TranslateParams): AsyncGenerator<string, {
|
|
4
|
+
export declare function translate(params: TranslateParams, requestId?: string): AsyncGenerator<string, {
|
|
5
5
|
modelExecutionMs: number;
|
|
6
6
|
stats?: TranslationStats;
|
|
7
7
|
}, unknown>;
|
|
@@ -1,9 +1,64 @@
|
|
|
1
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
2
|
+
if (value !== null && value !== void 0) {
|
|
3
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
4
|
+
var dispose, inner;
|
|
5
|
+
if (async) {
|
|
6
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
7
|
+
dispose = value[Symbol.asyncDispose];
|
|
8
|
+
}
|
|
9
|
+
if (dispose === void 0) {
|
|
10
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
11
|
+
dispose = value[Symbol.dispose];
|
|
12
|
+
if (async) inner = dispose;
|
|
13
|
+
}
|
|
14
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
15
|
+
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
16
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
17
|
+
}
|
|
18
|
+
else if (async) {
|
|
19
|
+
env.stack.push({ async: true });
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
};
|
|
23
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
24
|
+
return function (env) {
|
|
25
|
+
function fail(e) {
|
|
26
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
27
|
+
env.hasError = true;
|
|
28
|
+
}
|
|
29
|
+
var r, s = 0;
|
|
30
|
+
function next() {
|
|
31
|
+
while (r = env.stack.pop()) {
|
|
32
|
+
try {
|
|
33
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
34
|
+
if (r.dispose) {
|
|
35
|
+
var result = r.dispose.call(r.value);
|
|
36
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
37
|
+
}
|
|
38
|
+
else s |= 1;
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
fail(e);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
45
|
+
if (env.hasError) throw env.error;
|
|
46
|
+
}
|
|
47
|
+
return next();
|
|
48
|
+
};
|
|
49
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
50
|
+
var e = new Error(message);
|
|
51
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
|
+
});
|
|
1
53
|
import { getModelEntry } from "../registry/model-registry.js";
|
|
2
54
|
import { translateServerParamsSchema, normalizeModelType, ModelType, AFRICAN_LANGUAGES_MAP, } from "../../../schemas/index.js";
|
|
3
55
|
import { getLangName } from "@qvac/langdetect-text";
|
|
4
56
|
import { nowMs } from "../../../profiling/index.js";
|
|
5
57
|
import { buildStreamResult } from "../../../profiling/model-execution.js";
|
|
6
58
|
import { ModelIsDelegatedError, ModelNotFoundError, ModelTypeMismatchError, } from "../../../utils/errors-server.js";
|
|
59
|
+
import { getRequestRegistry, withRequestContext, } from "../runtime/index.js";
|
|
60
|
+
import { generateServerRequestId } from "../runtime/request-id.js";
|
|
61
|
+
import { getServerLogger } from "../../../logging/index.js";
|
|
7
62
|
export function getLanguage(code) {
|
|
8
63
|
if (!code)
|
|
9
64
|
return "";
|
|
@@ -26,104 +81,158 @@ const LLM_TRANSLATE_GENERATION_PARAMS = {
|
|
|
26
81
|
function shouldSkipPerCallSampling(modelName) {
|
|
27
82
|
return !!modelName && modelName.startsWith("AFRICAN_");
|
|
28
83
|
}
|
|
29
|
-
export async function* translate(params) {
|
|
30
|
-
const {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
throw new ModelIsDelegatedError(modelId);
|
|
37
|
-
}
|
|
38
|
-
const canonicalModelType = entry.local.modelType;
|
|
39
|
-
const model = entry.local.model;
|
|
40
|
-
if (inputModelType !== undefined) {
|
|
41
|
-
const requestedCanonical = normalizeModelType(inputModelType);
|
|
42
|
-
if (requestedCanonical !== canonicalModelType) {
|
|
43
|
-
throw new ModelTypeMismatchError(canonicalModelType, requestedCanonical);
|
|
84
|
+
export async function* translate(params, requestId) {
|
|
85
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
86
|
+
try {
|
|
87
|
+
const { modelId, text, modelType: inputModelType } = params;
|
|
88
|
+
const entry = getModelEntry(modelId);
|
|
89
|
+
if (!entry) {
|
|
90
|
+
throw new ModelNotFoundError(modelId);
|
|
44
91
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
canonicalModelType === ModelType.
|
|
57
|
-
|
|
92
|
+
if (entry.isDelegated) {
|
|
93
|
+
throw new ModelIsDelegatedError(modelId);
|
|
94
|
+
}
|
|
95
|
+
const canonicalModelType = entry.local.modelType;
|
|
96
|
+
const model = entry.local.model;
|
|
97
|
+
if (inputModelType !== undefined) {
|
|
98
|
+
const requestedCanonical = normalizeModelType(inputModelType);
|
|
99
|
+
if (requestedCanonical !== canonicalModelType) {
|
|
100
|
+
throw new ModelTypeMismatchError(canonicalModelType, requestedCanonical);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const isLlm = canonicalModelType === ModelType.llamacppCompletion;
|
|
104
|
+
const from = isLlm ? params.from : undefined;
|
|
105
|
+
const to = isLlm ? params.to : undefined;
|
|
106
|
+
const context = isLlm ? params.context : undefined;
|
|
107
|
+
const afriquePrompt = isLlm && (isAfrican(from) || isAfrican(to));
|
|
108
|
+
translateServerParamsSchema.parse(params);
|
|
109
|
+
const fromLanguage = getLanguage(from);
|
|
110
|
+
const toLanguage = getLanguage(to);
|
|
111
|
+
// Open a request-scoped lifecycle for both engine branches. LLM-
|
|
112
|
+
// translate inherits llamacpp-completion's `{ scope: "model",
|
|
113
|
+
// hard: true }` cancel surface; NMT-translate inherits nmtcpp's
|
|
114
|
+
// `{ scope: "none" }` — so the addon-cancel wiring below only
|
|
115
|
+
// engages on the LLM path. NMT cancel is purely soft: the loop
|
|
116
|
+
// exits on `signal.aborted`, scope unwinds, and the addon may run
|
|
117
|
+
// to completion in the background — acceptable because the result
|
|
118
|
+
// is dropped either way.
|
|
119
|
+
const ctx = __addDisposableResource(env_1, getRequestRegistry().begin({
|
|
120
|
+
requestId: requestId ?? generateServerRequestId(),
|
|
121
|
+
kind: "translate",
|
|
122
|
+
modelId,
|
|
123
|
+
}), true);
|
|
124
|
+
const requestLogger = withRequestContext(getServerLogger(), ctx);
|
|
125
|
+
if (isLlm) {
|
|
126
|
+
const onAbort = () => {
|
|
127
|
+
const addon = model.addon;
|
|
128
|
+
if (addon?.cancel) {
|
|
129
|
+
addon.cancel.call(addon).catch((err) => {
|
|
130
|
+
requestLogger.warn(`[cancel] addon.cancel() rejected during abort for modelId=${modelId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
ctx.signal.addEventListener("abort", onAbort, { once: true });
|
|
135
|
+
if (ctx.signal.aborted)
|
|
136
|
+
onAbort();
|
|
137
|
+
ctx.scope.defer(() => {
|
|
138
|
+
ctx.signal.removeEventListener("abort", onAbort);
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
// Check if input is an array and model type is NMT
|
|
142
|
+
if (Array.isArray(text) &&
|
|
143
|
+
canonicalModelType === ModelType.nmtcppTranslation) {
|
|
144
|
+
// Use runBatch for batch processing
|
|
145
|
+
const modelStart = nowMs();
|
|
146
|
+
const translations = await model.runBatch(text);
|
|
147
|
+
const modelExecutionMs = nowMs() - modelStart;
|
|
148
|
+
// Soft-cancel boundary: if `cancel({ requestId })` landed while
|
|
149
|
+
// the addon was running the batch, bail before yielding anything.
|
|
150
|
+
// The addon may have completed its work; the result is dropped.
|
|
151
|
+
if (ctx.signal.aborted) {
|
|
152
|
+
return { modelExecutionMs };
|
|
153
|
+
}
|
|
154
|
+
// Yield each translation with a newline separator
|
|
155
|
+
for (let i = 0; i < translations.length; i++) {
|
|
156
|
+
if (ctx.signal.aborted)
|
|
157
|
+
break;
|
|
158
|
+
const translation = translations[i];
|
|
159
|
+
yield translation;
|
|
160
|
+
if (i < translations.length - 1) {
|
|
161
|
+
yield "\n";
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return { modelExecutionMs };
|
|
165
|
+
}
|
|
166
|
+
// Single text processing (for NMT or LLM)
|
|
167
|
+
const singleText = Array.isArray(text) ? text[0] : text;
|
|
168
|
+
// Prepare input based on model type
|
|
169
|
+
const input = canonicalModelType === ModelType.nmtcppTranslation
|
|
170
|
+
? singleText
|
|
171
|
+
: [
|
|
172
|
+
{
|
|
173
|
+
role: afriquePrompt ? "user" : "system",
|
|
174
|
+
content: afriquePrompt
|
|
175
|
+
? `Translate ${fromLanguage} to ${toLanguage}.\n${fromLanguage}: ${singleText}\n${toLanguage}:`
|
|
176
|
+
: `${context ? `${context}. ` : ""}Translate the following text from ${fromLanguage} into ${toLanguage}. Only output the translation, nothing else.\n\n${fromLanguage}: ${singleText}\n${toLanguage}:`,
|
|
177
|
+
},
|
|
178
|
+
];
|
|
58
179
|
const modelStart = nowMs();
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
180
|
+
let response;
|
|
181
|
+
if (canonicalModelType === ModelType.llamacppCompletion &&
|
|
182
|
+
!shouldSkipPerCallSampling(entry.local.name)) {
|
|
183
|
+
// AnyModel.run is intentionally erased to a single-arg signature in the
|
|
184
|
+
// registry layer (Omit<BaseInference, "addon">). Re-narrow to the engine
|
|
185
|
+
// shape so we get the same typing as @qvac/llm-llamacpp.run().
|
|
186
|
+
const llmRun = model.run.bind(model);
|
|
187
|
+
response = await llmRun(input, {
|
|
188
|
+
generationParams: LLM_TRANSLATE_GENERATION_PARAMS,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
response = await model.run(input);
|
|
193
|
+
}
|
|
194
|
+
// Check if the response has an iterate method (like LLM models)
|
|
195
|
+
if (canonicalModelType === ModelType.llamacppCompletion &&
|
|
196
|
+
typeof response.iterate === "function") {
|
|
197
|
+
const llmResponse = response;
|
|
198
|
+
for await (const token of llmResponse.iterate()) {
|
|
199
|
+
if (ctx.signal.aborted)
|
|
200
|
+
break;
|
|
201
|
+
yield token;
|
|
67
202
|
}
|
|
203
|
+
const modelExecutionMs = nowMs() - modelStart;
|
|
204
|
+
const stats = {
|
|
205
|
+
...(llmResponse.stats?.TPS !== undefined && { tokensPerSecond: llmResponse.stats.TPS }),
|
|
206
|
+
...(llmResponse.stats?.TTFT !== undefined && { timeToFirstToken: llmResponse.stats.TTFT }),
|
|
207
|
+
...(llmResponse.stats?.CacheTokens !== undefined && { cacheTokens: llmResponse.stats.CacheTokens }),
|
|
208
|
+
...(llmResponse.stats?.generatedTokens !== undefined && { totalTokens: llmResponse.stats.generatedTokens }),
|
|
209
|
+
};
|
|
210
|
+
return buildStreamResult(modelExecutionMs, stats);
|
|
68
211
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
// Prepare input based on model type
|
|
74
|
-
const input = canonicalModelType === ModelType.nmtcppTranslation
|
|
75
|
-
? singleText
|
|
76
|
-
: [
|
|
77
|
-
{
|
|
78
|
-
role: afriquePrompt ? "user" : "system",
|
|
79
|
-
content: afriquePrompt
|
|
80
|
-
? `Translate ${fromLanguage} to ${toLanguage}.\n${fromLanguage}: ${singleText}\n${toLanguage}:`
|
|
81
|
-
: `${context ? `${context}. ` : ""}Translate the following text from ${fromLanguage} into ${toLanguage}. Only output the translation, nothing else.\n\n${fromLanguage}: ${singleText}\n${toLanguage}:`,
|
|
82
|
-
},
|
|
83
|
-
];
|
|
84
|
-
const modelStart = nowMs();
|
|
85
|
-
let response;
|
|
86
|
-
if (canonicalModelType === ModelType.llamacppCompletion &&
|
|
87
|
-
!shouldSkipPerCallSampling(entry.local.name)) {
|
|
88
|
-
// AnyModel.run is intentionally erased to a single-arg signature in the
|
|
89
|
-
// registry layer (Omit<BaseInference, "addon">). Re-narrow to the engine
|
|
90
|
-
// shape so we get the same typing as @qvac/llm-llamacpp.run().
|
|
91
|
-
const llmRun = model.run.bind(model);
|
|
92
|
-
response = await llmRun(input, {
|
|
93
|
-
generationParams: LLM_TRANSLATE_GENERATION_PARAMS,
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
else {
|
|
97
|
-
response = await model.run(input);
|
|
98
|
-
}
|
|
99
|
-
// Check if the response has an iterate method (like LLM models)
|
|
100
|
-
if (canonicalModelType === ModelType.llamacppCompletion &&
|
|
101
|
-
typeof response.iterate === "function") {
|
|
102
|
-
const llmResponse = response;
|
|
103
|
-
for await (const token of llmResponse.iterate()) {
|
|
212
|
+
const nmtResponse = response;
|
|
213
|
+
for await (const token of nmtResponse.iterate()) {
|
|
214
|
+
if (ctx.signal.aborted)
|
|
215
|
+
break;
|
|
104
216
|
yield token;
|
|
105
217
|
}
|
|
106
218
|
const modelExecutionMs = nowMs() - modelStart;
|
|
107
219
|
const stats = {
|
|
108
|
-
...(
|
|
109
|
-
...(
|
|
110
|
-
...(
|
|
111
|
-
...(
|
|
220
|
+
...(nmtResponse.stats?.totalTime !== undefined && { totalTime: nmtResponse.stats.totalTime }),
|
|
221
|
+
...(nmtResponse.stats?.totalTokens !== undefined && { totalTokens: nmtResponse.stats.totalTokens }),
|
|
222
|
+
...(nmtResponse.stats?.decodeTime !== undefined && { decodeTime: nmtResponse.stats.decodeTime }),
|
|
223
|
+
...(nmtResponse.stats?.encodeTime !== undefined && { encodeTime: nmtResponse.stats.encodeTime }),
|
|
224
|
+
...(nmtResponse.stats?.TPS !== undefined && { tokensPerSecond: nmtResponse.stats.TPS }),
|
|
225
|
+
...(nmtResponse.stats?.TTFT !== undefined && { timeToFirstToken: nmtResponse.stats.TTFT }),
|
|
112
226
|
};
|
|
113
227
|
return buildStreamResult(modelExecutionMs, stats);
|
|
114
228
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
229
|
+
catch (e_1) {
|
|
230
|
+
env_1.error = e_1;
|
|
231
|
+
env_1.hasError = true;
|
|
232
|
+
}
|
|
233
|
+
finally {
|
|
234
|
+
const result_1 = __disposeResources(env_1);
|
|
235
|
+
if (result_1)
|
|
236
|
+
await result_1;
|
|
118
237
|
}
|
|
119
|
-
const modelExecutionMs = nowMs() - modelStart;
|
|
120
|
-
const stats = {
|
|
121
|
-
...(nmtResponse.stats?.totalTime !== undefined && { totalTime: nmtResponse.stats.totalTime }),
|
|
122
|
-
...(nmtResponse.stats?.totalTokens !== undefined && { totalTokens: nmtResponse.stats.totalTokens }),
|
|
123
|
-
...(nmtResponse.stats?.decodeTime !== undefined && { decodeTime: nmtResponse.stats.decodeTime }),
|
|
124
|
-
...(nmtResponse.stats?.encodeTime !== undefined && { encodeTime: nmtResponse.stats.encodeTime }),
|
|
125
|
-
...(nmtResponse.stats?.TPS !== undefined && { tokensPerSecond: nmtResponse.stats.TPS }),
|
|
126
|
-
...(nmtResponse.stats?.TTFT !== undefined && { timeToFirstToken: nmtResponse.stats.TTFT }),
|
|
127
|
-
};
|
|
128
|
-
return buildStreamResult(modelExecutionMs, stats);
|
|
129
238
|
}
|
|
@@ -1,17 +1,26 @@
|
|
|
1
|
+
import type { AbortSignal } from "bare-abort-controller";
|
|
1
2
|
import type { CompletionParams, CompletionStats, GenerationParams, ResponseFormat, Tool, ToolCall, ToolDialect } from "../../../../../schemas/index";
|
|
2
|
-
import {
|
|
3
|
+
import type { DisposableScope } from "../../../runtime/disposable-scope";
|
|
4
|
+
import type { Logger } from "../../../../../logging/types";
|
|
3
5
|
interface CompletionResult {
|
|
4
6
|
modelExecutionMs: number;
|
|
5
7
|
stats?: CompletionStats;
|
|
6
8
|
toolCalls: ToolCall[];
|
|
7
9
|
}
|
|
8
|
-
export declare function clearCachedMessageCounts(prefix?: string): void;
|
|
9
|
-
export declare const noteCancelRequested: typeof noteCancelRequestedFromState;
|
|
10
10
|
export declare function completion(params: CompletionParams & {
|
|
11
11
|
tools?: Tool[];
|
|
12
12
|
generationParams?: GenerationParams;
|
|
13
13
|
toolDialect?: ToolDialect;
|
|
14
14
|
responseFormat?: ResponseFormat;
|
|
15
|
+
}, opts: {
|
|
16
|
+
signal: AbortSignal;
|
|
17
|
+
scope: DisposableScope;
|
|
18
|
+
/**
|
|
19
|
+
* Request-scoped logger forwarded to `createKvCacheSession` so
|
|
20
|
+
* kv-cache lines share the request's lifecycle prefix. Falls
|
|
21
|
+
* back to the module-level server logger when omitted.
|
|
22
|
+
*/
|
|
23
|
+
logger?: Logger;
|
|
15
24
|
}): AsyncGenerator<{
|
|
16
25
|
token: string;
|
|
17
26
|
}, CompletionResult, unknown>;
|