@qvac/sdk 0.8.2 → 0.9.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 +267 -63
- package/README.md +2 -0
- package/dist/client/api/diffusion.d.ts +32 -0
- package/dist/client/api/diffusion.js +103 -0
- package/dist/client/api/embed.d.ts +9 -3
- package/dist/client/api/embed.js +4 -1
- package/dist/client/api/finetune.d.ts +69 -0
- package/dist/client/api/finetune.js +139 -0
- package/dist/client/api/get-model-info.d.ts +1 -1
- package/dist/client/api/index.d.ts +4 -0
- package/dist/client/api/index.js +4 -0
- package/dist/client/api/rag.d.ts +1 -1
- package/dist/client/api/rag.js +1 -1
- package/dist/client/api/resume.d.ts +14 -0
- package/dist/client/api/resume.js +20 -0
- package/dist/client/api/suspend.d.ts +13 -0
- package/dist/client/api/suspend.js +19 -0
- package/dist/client/api/transcribe.d.ts +25 -17
- package/dist/client/api/transcribe.js +115 -35
- package/dist/client/rpc/bare-client.d.ts +5 -1
- package/dist/client/rpc/bare-client.js +70 -57
- package/dist/client/rpc/expo-rpc-client.d.ts +4 -0
- package/dist/client/rpc/expo-rpc-client.js +8 -0
- package/dist/client/rpc/node-rpc-client.d.ts +4 -0
- package/dist/client/rpc/node-rpc-client.js +8 -0
- package/dist/client/rpc/rpc-client.d.ts +13 -0
- package/dist/client/rpc/rpc-client.js +131 -1
- package/dist/examples/delegated-inference/composite.d.ts +2 -0
- package/dist/examples/delegated-inference/composite.js +99 -0
- package/dist/examples/diffusion-flux2-klein.d.ts +2 -0
- package/dist/examples/diffusion-flux2-klein.js +46 -0
- package/dist/examples/diffusion-simple.d.ts +2 -0
- package/dist/examples/diffusion-simple.js +17 -0
- package/dist/examples/diffusion-txt2img.d.ts +2 -0
- package/dist/examples/diffusion-txt2img.js +40 -0
- package/dist/examples/embed-p2p.js +2 -2
- package/dist/examples/finetune/llamacpp-finetune.d.ts +2 -0
- package/dist/examples/finetune/llamacpp-finetune.js +78 -0
- package/dist/examples/logging-streaming.js +1 -1
- package/dist/examples/mcp-websearch.js +2 -0
- package/dist/examples/ocr-fasttext.js +11 -0
- package/dist/examples/profiling/per-call.js +3 -3
- package/dist/examples/rag/rag-chromadb.js +2 -2
- package/dist/examples/rag/rag-hyperdb/pipeline.js +1 -1
- package/dist/examples/rag/rag-lancedb.js +2 -2
- package/dist/examples/rag/rag-sqlite.js +2 -2
- package/dist/examples/suspend-resume.d.ts +2 -0
- package/dist/examples/suspend-resume.js +52 -0
- package/dist/examples/transcription/parakeet-ctc-filesystem.js +3 -5
- package/dist/examples/transcription/parakeet-microphone-record.js +42 -33
- package/dist/examples/transcription/parakeet-sortformer.js +13 -3
- package/dist/examples/transcription/parakeet-tdt-filesystem.js +5 -7
- package/dist/examples/transcription/whispercpp-filesystem-streaming.d.ts +2 -0
- package/dist/examples/transcription/whispercpp-filesystem-streaming.js +99 -0
- package/dist/examples/transcription/whispercpp-microphone-record.js +78 -299
- package/dist/examples/transcription/whispercpp-prompt.js +11 -0
- package/dist/examples/translation/translation-llm.js +2 -2
- package/dist/examples/tts/supertonic-multilingual.d.ts +2 -0
- package/dist/examples/tts/supertonic-multilingual.js +56 -0
- package/dist/examples/tts/supertonic.js +12 -7
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/dist/logging/utils.js +1 -1
- package/dist/models/registry/models.d.ts +15176 -4264
- package/dist/models/registry/models.js +18657 -7404
- package/dist/models/update-models/codegen.js +2 -2
- package/dist/models/update-models/naming.js +26 -0
- package/dist/pear/pre.js +2 -0
- package/dist/polyfills/bare-globals.d.ts +2 -0
- package/dist/polyfills/bare-globals.js +4 -0
- package/dist/polyfills/bare-globals.noop.d.ts +2 -0
- package/dist/polyfills/bare-globals.noop.js +1 -0
- package/dist/profiling/exporters.js +16 -11
- package/dist/profiling/model-execution.d.ts +16 -0
- package/dist/profiling/model-execution.js +33 -0
- package/dist/schemas/common.d.ts +967 -198
- package/dist/schemas/common.js +16 -1
- package/dist/schemas/completion-stream.d.ts +14 -6
- package/dist/schemas/completion-stream.js +4 -3
- package/dist/schemas/download-asset.d.ts +7 -3
- package/dist/schemas/embed.d.ts +19 -0
- package/dist/schemas/embed.js +7 -0
- package/dist/schemas/engine-addon-map.js +4 -1
- package/dist/schemas/finetune.d.ts +620 -0
- package/dist/schemas/finetune.js +161 -0
- package/dist/schemas/get-model-info.d.ts +2 -0
- package/dist/schemas/get-model-info.js +1 -0
- package/dist/schemas/index.d.ts +5 -1
- package/dist/schemas/index.js +5 -1
- package/dist/schemas/llamacpp-config.d.ts +26 -6
- package/dist/schemas/llamacpp-config.js +12 -0
- package/dist/schemas/load-model.d.ts +4005 -1400
- package/dist/schemas/load-model.js +34 -1
- package/dist/schemas/model-src-utils.d.ts +10 -2
- package/dist/schemas/model-types.d.ts +19 -1
- package/dist/schemas/model-types.js +11 -0
- package/dist/schemas/ocr.d.ts +2 -0
- package/dist/schemas/plugin.d.ts +24 -3
- package/dist/schemas/plugin.js +14 -0
- package/dist/schemas/profiling.d.ts +4 -0
- package/dist/schemas/profiling.js +4 -0
- package/dist/schemas/registry.d.ts +18 -0
- package/dist/schemas/registry.js +2 -0
- package/dist/schemas/reload-config.d.ts +9 -1
- package/dist/schemas/resume.d.ts +10 -0
- package/dist/schemas/resume.js +7 -0
- package/dist/schemas/sdcpp-config.d.ts +327 -0
- package/dist/schemas/sdcpp-config.js +102 -0
- package/dist/schemas/sdk-config.d.ts +1225 -235
- package/dist/schemas/sdk-config.js +4 -0
- package/dist/schemas/sdk-errors-server.d.ts +2 -0
- package/dist/schemas/sdk-errors-server.js +12 -0
- package/dist/schemas/suspend.d.ts +10 -0
- package/dist/schemas/suspend.js +7 -0
- package/dist/schemas/text-to-speech.d.ts +187 -10
- package/dist/schemas/text-to-speech.js +12 -4
- package/dist/schemas/transcription-config.d.ts +16 -56
- package/dist/schemas/transcription-config.js +0 -2
- package/dist/schemas/transcription.d.ts +66 -6
- package/dist/schemas/transcription.js +29 -7
- package/dist/schemas/translate.d.ts +14 -4
- package/dist/schemas/translate.js +10 -2
- package/dist/schemas/translation-config.d.ts +30 -10
- package/dist/server/bare/delegate-rpc-client.js +3 -3
- package/dist/server/bare/hyperswarm.js +15 -3
- package/dist/server/bare/ops/embed.d.ts +8 -4
- package/dist/server/bare/ops/embed.js +15 -4
- package/dist/server/bare/ops/transcribe.d.ts +6 -2
- package/dist/server/bare/ops/transcribe.js +53 -1
- package/dist/server/bare/ops/translate.d.ts +4 -1
- package/dist/server/bare/ops/translate.js +28 -65
- package/dist/server/bare/ops/unload-model.js +2 -0
- package/dist/server/bare/plugins/index.d.ts +1 -0
- package/dist/server/bare/plugins/index.js +1 -0
- package/dist/server/bare/plugins/llamacpp-completion/ops/cache-logger.d.ts +1 -0
- package/dist/server/bare/plugins/llamacpp-completion/ops/cache-logger.js +3 -0
- package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.d.ts +3 -1
- package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.js +57 -11
- package/dist/server/bare/plugins/llamacpp-completion/ops/finetune.d.ts +11 -0
- package/dist/server/bare/plugins/llamacpp-completion/ops/finetune.js +112 -0
- package/dist/server/bare/plugins/llamacpp-completion/plugin.d.ts +175 -5
- package/dist/server/bare/plugins/llamacpp-completion/plugin.js +45 -35
- package/dist/server/bare/plugins/llamacpp-embedding/plugin.d.ts +11 -1
- package/dist/server/bare/plugins/llamacpp-embedding/plugin.js +9 -4
- package/dist/server/bare/plugins/nmtcpp-translation/plugin.d.ts +17 -2
- package/dist/server/bare/plugins/nmtcpp-translation/plugin.js +16 -15
- package/dist/server/bare/plugins/onnx-ocr/ops/ocr-stream.d.ts +5 -7
- package/dist/server/bare/plugins/onnx-ocr/ops/ocr-stream.js +11 -3
- package/dist/server/bare/plugins/onnx-ocr/plugin.d.ts +2 -0
- package/dist/server/bare/plugins/onnx-ocr/plugin.js +24 -19
- package/dist/server/bare/plugins/onnx-tts/ops/text-to-speech.d.ts +7 -2
- package/dist/server/bare/plugins/onnx-tts/ops/text-to-speech.js +22 -97
- package/dist/server/bare/plugins/onnx-tts/plugin.d.ts +98 -9
- package/dist/server/bare/plugins/onnx-tts/plugin.js +85 -46
- package/dist/server/bare/plugins/parakeet-transcription/plugin.d.ts +30 -60
- package/dist/server/bare/plugins/parakeet-transcription/plugin.js +49 -37
- package/dist/server/bare/plugins/sdcpp-generation/ops/diffusion.d.ts +3 -0
- package/dist/server/bare/plugins/sdcpp-generation/ops/diffusion.js +51 -0
- package/dist/server/bare/plugins/sdcpp-generation/plugin.d.ts +278 -0
- package/dist/server/bare/plugins/sdcpp-generation/plugin.js +70 -0
- package/dist/server/bare/plugins/whispercpp-transcription/plugin.d.ts +38 -2
- package/dist/server/bare/plugins/whispercpp-transcription/plugin.js +43 -22
- package/dist/server/bare/rag-hyperdb/handlers/ingest.js +2 -1
- package/dist/server/bare/rag-hyperdb/handlers/search.js +2 -1
- package/dist/server/bare/rag-hyperdb/rag-workspace-manager.js +7 -0
- package/dist/server/bare/registry/model-config-utils.js +3 -0
- package/dist/server/bare/registry/model-registry.d.ts +2 -2
- package/dist/server/bare/registry/model-registry.js +1 -1
- package/dist/server/bare/registry/registry-client.js +21 -0
- package/dist/server/bare/runtime-lifecycle.d.ts +28 -0
- package/dist/server/bare/runtime-lifecycle.js +132 -0
- package/dist/server/bare/types/addon-responses.d.ts +62 -0
- package/dist/server/bare/types/addon-responses.js +1 -0
- package/dist/server/env.js +3 -1
- package/dist/server/rpc/delegate-transport.js +1 -1
- package/dist/server/rpc/handle-request.js +50 -4
- package/dist/server/rpc/handler-registry.js +20 -1
- package/dist/server/rpc/handler-utils.d.ts +5 -3
- package/dist/server/rpc/handler-utils.js +52 -50
- package/dist/server/rpc/handlers/delete-cache.js +3 -0
- package/dist/server/rpc/handlers/diffusion-stream.d.ts +3 -0
- package/dist/server/rpc/handlers/diffusion-stream.js +4 -0
- package/dist/server/rpc/handlers/finetune.d.ts +3 -0
- package/dist/server/rpc/handlers/finetune.js +16 -0
- package/dist/server/rpc/handlers/index.d.ts +10 -0
- package/dist/server/rpc/handlers/index.js +10 -0
- package/dist/server/rpc/handlers/load-model/hyperdrive.js +24 -9
- package/dist/server/rpc/handlers/load-model/registry.d.ts +11 -0
- package/dist/server/rpc/handlers/load-model/registry.js +31 -4
- package/dist/server/rpc/handlers/plugin-dispatch.d.ts +1 -13
- package/dist/server/rpc/handlers/plugin-dispatch.js +21 -21
- package/dist/server/rpc/handlers/resume.d.ts +3 -0
- package/dist/server/rpc/handlers/resume.js +11 -0
- package/dist/server/rpc/handlers/suspend.d.ts +3 -0
- package/dist/server/rpc/handlers/suspend.js +11 -0
- package/dist/server/rpc/handlers/transcribe-stream.d.ts +1 -1
- package/dist/server/rpc/handlers/transcribe-stream.js +2 -2
- package/dist/server/rpc/handlers/transcribe.d.ts +3 -0
- package/dist/server/rpc/handlers/transcribe.js +4 -0
- package/dist/server/rpc/profiling/operation-metrics.js +107 -16
- package/dist/server/rpc/profiling/operation-wrappers.d.ts +1 -1
- package/dist/server/rpc/profiling/operation-wrappers.js +51 -19
- package/dist/server/rpc/progress-throttle.d.ts +8 -0
- package/dist/server/rpc/progress-throttle.js +47 -0
- package/dist/server/rpc/rpc-utils.d.ts +5 -0
- package/dist/server/rpc/rpc-utils.js +11 -0
- package/dist/server/utils/path-security.js +1 -1
- package/dist/server/utils/tool-integration.js +10 -0
- package/dist/server/utils/tool-parser.js +9 -5
- package/dist/server/worker-core.d.ts +2 -0
- package/dist/server/worker-core.js +26 -23
- package/dist/server/worker.js +2 -1
- package/dist/utils/encoding.d.ts +9 -0
- package/dist/utils/encoding.js +14 -0
- package/dist/utils/errors-server.d.ts +6 -0
- package/dist/utils/errors-server.js +11 -0
- package/package.json +81 -25
- package/dist/server/rpc/delegate-utils.d.ts +0 -2
- package/dist/server/rpc/delegate-utils.js +0 -5
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { QVACRegistryClient } from "@qvac/registry-client";
|
|
2
2
|
import { getCacheDir } from "../../utils/cache.js";
|
|
3
|
+
import { registerSwarm, unregisterSwarm, registerCorestore, unregisterCorestore, } from "../runtime-lifecycle.js";
|
|
3
4
|
import { getServerLogger } from "../../../logging/index.js";
|
|
4
5
|
import { DEFAULT_REGISTRY_CORE_KEY } from "../../../constants/index.js";
|
|
5
6
|
const logger = getServerLogger();
|
|
@@ -15,6 +16,18 @@ export async function getRegistryClient() {
|
|
|
15
16
|
storage: getCacheDir(`registry-corestore/${DEFAULT_REGISTRY_CORE_KEY}`),
|
|
16
17
|
});
|
|
17
18
|
await registryClient.ready();
|
|
19
|
+
if (registryClient.corestore) {
|
|
20
|
+
registerCorestore(registryClient.corestore, {
|
|
21
|
+
label: "registry-client",
|
|
22
|
+
createdAt: Date.now(),
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
if (registryClient.hyperswarm) {
|
|
26
|
+
registerSwarm(registryClient.hyperswarm, {
|
|
27
|
+
label: "registry-client",
|
|
28
|
+
createdAt: Date.now(),
|
|
29
|
+
});
|
|
30
|
+
}
|
|
18
31
|
logger.info("✅ Registry client ready");
|
|
19
32
|
return registryClient;
|
|
20
33
|
}
|
|
@@ -23,6 +36,8 @@ export async function closeRegistryClient() {
|
|
|
23
36
|
return;
|
|
24
37
|
const client = registryClient;
|
|
25
38
|
registryClient = null;
|
|
39
|
+
const corestore = client.corestore;
|
|
40
|
+
const hyperswarm = client.hyperswarm;
|
|
26
41
|
logger.info("🔌 Closing registry client...");
|
|
27
42
|
try {
|
|
28
43
|
await client.close();
|
|
@@ -31,6 +46,12 @@ export async function closeRegistryClient() {
|
|
|
31
46
|
catch (error) {
|
|
32
47
|
logger.error("❌ Error closing registry client:", error instanceof Error ? error.message : String(error));
|
|
33
48
|
}
|
|
49
|
+
finally {
|
|
50
|
+
if (corestore)
|
|
51
|
+
unregisterCorestore(corestore);
|
|
52
|
+
if (hyperswarm)
|
|
53
|
+
unregisterSwarm(hyperswarm);
|
|
54
|
+
}
|
|
34
55
|
}
|
|
35
56
|
export function hasActiveRegistryClient() {
|
|
36
57
|
return registryClient !== null;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface SuspendableSwarm {
|
|
2
|
+
readonly suspended: boolean;
|
|
3
|
+
suspend(): Promise<void>;
|
|
4
|
+
resume(): Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
export interface SuspendableStore {
|
|
7
|
+
suspend(): Promise<void>;
|
|
8
|
+
resume(): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
type LifecycleState = "active" | "suspending" | "suspended" | "resuming";
|
|
11
|
+
interface ResourceMeta {
|
|
12
|
+
label: string;
|
|
13
|
+
createdAt: number;
|
|
14
|
+
}
|
|
15
|
+
export declare function registerSwarm(swarm: SuspendableSwarm, meta: ResourceMeta): void;
|
|
16
|
+
export declare function unregisterSwarm(swarm: SuspendableSwarm): void;
|
|
17
|
+
export declare function registerCorestore(store: SuspendableStore, meta: ResourceMeta): void;
|
|
18
|
+
export declare function unregisterCorestore(store: SuspendableStore): void;
|
|
19
|
+
export declare function getLifecycleState(): LifecycleState;
|
|
20
|
+
export declare function getRegisteredResourceCounts(): {
|
|
21
|
+
swarms: number;
|
|
22
|
+
stores: number;
|
|
23
|
+
};
|
|
24
|
+
export declare function resetLifecycleState(): void;
|
|
25
|
+
export declare function suspendRuntime(): Promise<void>;
|
|
26
|
+
export declare function resumeRuntime(): Promise<void>;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=runtime-lifecycle.d.ts.map
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { getServerLogger } from "../../logging/index.js";
|
|
2
|
+
const logger = getServerLogger();
|
|
3
|
+
const swarms = new Map();
|
|
4
|
+
const stores = new Map();
|
|
5
|
+
let state = "active";
|
|
6
|
+
let transitionPromise = null;
|
|
7
|
+
export function registerSwarm(swarm, meta) {
|
|
8
|
+
swarms.set(swarm, meta);
|
|
9
|
+
logger.debug(`Lifecycle: registered swarm [${meta.label}]`);
|
|
10
|
+
}
|
|
11
|
+
export function unregisterSwarm(swarm) {
|
|
12
|
+
const meta = swarms.get(swarm);
|
|
13
|
+
swarms.delete(swarm);
|
|
14
|
+
if (meta) {
|
|
15
|
+
logger.debug(`Lifecycle: unregistered swarm [${meta.label}]`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export function registerCorestore(store, meta) {
|
|
19
|
+
stores.set(store, meta);
|
|
20
|
+
logger.debug(`Lifecycle: registered corestore [${meta.label}]`);
|
|
21
|
+
}
|
|
22
|
+
export function unregisterCorestore(store) {
|
|
23
|
+
const meta = stores.get(store);
|
|
24
|
+
stores.delete(store);
|
|
25
|
+
if (meta) {
|
|
26
|
+
logger.debug(`Lifecycle: unregistered corestore [${meta.label}]`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export function getLifecycleState() {
|
|
30
|
+
return state;
|
|
31
|
+
}
|
|
32
|
+
export function getRegisteredResourceCounts() {
|
|
33
|
+
return { swarms: swarms.size, stores: stores.size };
|
|
34
|
+
}
|
|
35
|
+
export function resetLifecycleState() {
|
|
36
|
+
swarms.clear();
|
|
37
|
+
stores.clear();
|
|
38
|
+
state = "active";
|
|
39
|
+
transitionPromise = null;
|
|
40
|
+
}
|
|
41
|
+
async function runPhase(snapshot, liveSet, fn, phaseLabel) {
|
|
42
|
+
const errors = [];
|
|
43
|
+
for (const [resource, meta] of snapshot) {
|
|
44
|
+
try {
|
|
45
|
+
await fn(resource);
|
|
46
|
+
logger.debug(`Lifecycle: ${phaseLabel} [${meta.label}] OK`);
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
if (!liveSet.has(resource))
|
|
50
|
+
continue;
|
|
51
|
+
logger.error(`Lifecycle: ${phaseLabel} [${meta.label}] failed:`, error);
|
|
52
|
+
errors.push(new Error(`${meta.label}: ${String(error)}`));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (errors.length > 0) {
|
|
56
|
+
throw new AggregateError(errors, `Lifecycle ${phaseLabel} phase failed`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export async function suspendRuntime() {
|
|
60
|
+
if (state === "suspended")
|
|
61
|
+
return;
|
|
62
|
+
if (state === "suspending" && transitionPromise)
|
|
63
|
+
return transitionPromise;
|
|
64
|
+
// Opposite transition in flight: wait for it, then re-evaluate
|
|
65
|
+
if (state === "resuming" && transitionPromise) {
|
|
66
|
+
await transitionPromise;
|
|
67
|
+
return suspendRuntime();
|
|
68
|
+
}
|
|
69
|
+
state = "suspending";
|
|
70
|
+
logger.info(`⏸️ Suspending runtime (${swarms.size} swarms, ${stores.size} stores)`);
|
|
71
|
+
transitionPromise = (async () => {
|
|
72
|
+
const swarmSnapshot = Array.from(swarms.entries());
|
|
73
|
+
const storeSnapshot = Array.from(stores.entries());
|
|
74
|
+
await runPhase(swarmSnapshot, swarms, async (swarm) => {
|
|
75
|
+
if (!swarm.suspended)
|
|
76
|
+
await swarm.suspend();
|
|
77
|
+
}, "suspend-swarm");
|
|
78
|
+
await runPhase(storeSnapshot, stores, async (store) => {
|
|
79
|
+
await store.suspend();
|
|
80
|
+
}, "suspend-store");
|
|
81
|
+
})()
|
|
82
|
+
.then(() => {
|
|
83
|
+
state = "suspended";
|
|
84
|
+
logger.info("⏸️ Runtime suspended");
|
|
85
|
+
})
|
|
86
|
+
.catch((error) => {
|
|
87
|
+
// Partial failure: commit to target so recovery resume() can repair
|
|
88
|
+
// instead of leaving state as "suspending" which blocks all future calls.
|
|
89
|
+
state = "suspended";
|
|
90
|
+
logger.error("⏸️ Runtime suspend partially failed, state committed for recovery");
|
|
91
|
+
throw error;
|
|
92
|
+
})
|
|
93
|
+
.finally(() => {
|
|
94
|
+
transitionPromise = null;
|
|
95
|
+
});
|
|
96
|
+
return transitionPromise;
|
|
97
|
+
}
|
|
98
|
+
export async function resumeRuntime() {
|
|
99
|
+
if (state === "active")
|
|
100
|
+
return;
|
|
101
|
+
if (state === "resuming" && transitionPromise)
|
|
102
|
+
return transitionPromise;
|
|
103
|
+
if (state === "suspending" && transitionPromise) {
|
|
104
|
+
await transitionPromise;
|
|
105
|
+
return resumeRuntime();
|
|
106
|
+
}
|
|
107
|
+
state = "resuming";
|
|
108
|
+
logger.info(`▶️ Resuming runtime (${stores.size} stores, ${swarms.size} swarms)`);
|
|
109
|
+
transitionPromise = (async () => {
|
|
110
|
+
const storeSnapshot = Array.from(stores.entries());
|
|
111
|
+
const swarmSnapshot = Array.from(swarms.entries());
|
|
112
|
+
await runPhase(storeSnapshot, stores, async (store) => {
|
|
113
|
+
await store.resume();
|
|
114
|
+
}, "resume-store");
|
|
115
|
+
await runPhase(swarmSnapshot, swarms, async (swarm) => {
|
|
116
|
+
await swarm.resume();
|
|
117
|
+
}, "resume-swarm");
|
|
118
|
+
})()
|
|
119
|
+
.then(() => {
|
|
120
|
+
state = "active";
|
|
121
|
+
logger.info("▶️ Runtime resumed");
|
|
122
|
+
})
|
|
123
|
+
.catch((error) => {
|
|
124
|
+
state = "active";
|
|
125
|
+
logger.error("▶️ Runtime resume partially failed, state committed for recovery");
|
|
126
|
+
throw error;
|
|
127
|
+
})
|
|
128
|
+
.finally(() => {
|
|
129
|
+
transitionPromise = null;
|
|
130
|
+
});
|
|
131
|
+
return transitionPromise;
|
|
132
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export interface LlmStats {
|
|
2
|
+
TTFT?: number;
|
|
3
|
+
TPS?: number;
|
|
4
|
+
CacheTokens?: number;
|
|
5
|
+
generatedTokens?: number;
|
|
6
|
+
backendDevice?: "cpu" | "gpu";
|
|
7
|
+
}
|
|
8
|
+
export interface LlmResponse {
|
|
9
|
+
stats?: LlmStats;
|
|
10
|
+
iterate(): AsyncIterable<string>;
|
|
11
|
+
}
|
|
12
|
+
export interface NmtStats {
|
|
13
|
+
totalTime?: number;
|
|
14
|
+
totalTokens?: number;
|
|
15
|
+
decodeTime?: number;
|
|
16
|
+
encodeTime?: number;
|
|
17
|
+
TPS?: number;
|
|
18
|
+
TTFT?: number;
|
|
19
|
+
}
|
|
20
|
+
export interface NmtResponse {
|
|
21
|
+
stats?: NmtStats;
|
|
22
|
+
iterate(): AsyncIterable<string>;
|
|
23
|
+
}
|
|
24
|
+
export interface TtsStats {
|
|
25
|
+
audioDurationMs?: number;
|
|
26
|
+
totalSamples?: number;
|
|
27
|
+
}
|
|
28
|
+
export interface TtsResponse {
|
|
29
|
+
stats?: TtsStats;
|
|
30
|
+
iterate(): AsyncIterable<{
|
|
31
|
+
outputArray: ArrayLike<number>;
|
|
32
|
+
}>;
|
|
33
|
+
}
|
|
34
|
+
export interface EmbedStats {
|
|
35
|
+
total_time_ms?: number;
|
|
36
|
+
tokens_per_second?: number;
|
|
37
|
+
total_tokens?: number;
|
|
38
|
+
backendDevice?: "cpu" | "gpu";
|
|
39
|
+
}
|
|
40
|
+
export interface EmbedResponse {
|
|
41
|
+
stats?: EmbedStats;
|
|
42
|
+
await(): Promise<Float32Array[][]>;
|
|
43
|
+
}
|
|
44
|
+
export interface TranscribeStats {
|
|
45
|
+
audioDurationMs?: number;
|
|
46
|
+
realTimeFactor?: number;
|
|
47
|
+
tokensPerSecond?: number;
|
|
48
|
+
totalTokens?: number;
|
|
49
|
+
totalSegments?: number;
|
|
50
|
+
whisperEncodeMs?: number;
|
|
51
|
+
whisperDecodeMs?: number;
|
|
52
|
+
encoderMs?: number;
|
|
53
|
+
decoderMs?: number;
|
|
54
|
+
melSpecMs?: number;
|
|
55
|
+
}
|
|
56
|
+
export interface TranscribeResponse {
|
|
57
|
+
stats?: TranscribeStats;
|
|
58
|
+
iterate(): AsyncIterable<Array<{
|
|
59
|
+
text: string;
|
|
60
|
+
}>>;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=addon-responses.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/server/env.js
CHANGED
|
@@ -11,7 +11,9 @@ let validatedEnv = null;
|
|
|
11
11
|
* Returns whether RPC config was parsed from arguments.
|
|
12
12
|
*/
|
|
13
13
|
export function initEnv() {
|
|
14
|
-
const defaultHomeDir = process.env["HOME"]
|
|
14
|
+
const defaultHomeDir = process.env["HOME"] ??
|
|
15
|
+
process.env["USERPROFILE"] ??
|
|
16
|
+
"/tmp";
|
|
15
17
|
let envConfig = {
|
|
16
18
|
HOME_DIR: defaultHomeDir,
|
|
17
19
|
};
|
|
@@ -12,7 +12,7 @@ import { DelegateProviderError } from "../../utils/errors-server.js";
|
|
|
12
12
|
import { cleanupStaleConnection } from "../bare/delegate-rpc-client.js";
|
|
13
13
|
import { shouldProfileDelegation, createDelegationTimings, createDelegationStreamTimings, recordDelegationEvents, recordDelegationStreamEvents, buildDelegationStreamBreakdown, flushServerConnectionEvent, consumeBreakdownConnectionTime, } from "./profiling/delegation-profiler.js";
|
|
14
14
|
const logger = getServerLogger();
|
|
15
|
-
import { getNextCommandId } from "./
|
|
15
|
+
import { getNextCommandId } from "./rpc-utils.js";
|
|
16
16
|
function checkAndThrowError(response) {
|
|
17
17
|
if (response.type === "error") {
|
|
18
18
|
throw new DelegateProviderError(response.message || "Unknown provider error", response.code);
|
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
import { requestSchema, normalizeModelType, PROFILING_KEY, } from "../../schemas/index.js";
|
|
2
2
|
import { nowMs } from "../../profiling/index.js";
|
|
3
3
|
import { resolveModelConfig } from "../bare/registry/model-config-registry.js";
|
|
4
|
-
import { sendErrorResponse } from "../error-handlers.js";
|
|
5
|
-
import {
|
|
4
|
+
import { sendErrorResponse, sendStreamErrorResponse, } from "../error-handlers.js";
|
|
5
|
+
import { RPCUnknownRequestTypeError, PluginHandlerTypeMismatchError, } from "../../utils/errors-server.js";
|
|
6
6
|
import { registry } from "./handler-registry.js";
|
|
7
|
-
import { executeHandler, handleInitConfig, isInitConfigMessage, } from "./handler-utils.js";
|
|
7
|
+
import { executeHandler, executeDuplexHandler, handleInitConfig, isInitConfigMessage, } from "./handler-utils.js";
|
|
8
8
|
import { createServerProfiler } from "./profiling/index.js";
|
|
9
9
|
export async function handleRequest(req) {
|
|
10
10
|
let profiler;
|
|
11
11
|
let validationStart = 0;
|
|
12
12
|
try {
|
|
13
13
|
const rawData = req.data?.toString();
|
|
14
|
+
// Duplex stream request: metadata arrives as the first chunk on the
|
|
15
|
+
// request stream (client used createRequestStream instead of send).
|
|
14
16
|
if (!rawData) {
|
|
15
|
-
|
|
17
|
+
await handleDuplexRequest(req);
|
|
18
|
+
return;
|
|
16
19
|
}
|
|
17
20
|
// Timing runs unconditionally since we can't know if client
|
|
18
21
|
// requested profiling until after parsing.
|
|
@@ -67,6 +70,49 @@ function extractProfilingMeta(data) {
|
|
|
67
70
|
profilingMeta: meta,
|
|
68
71
|
};
|
|
69
72
|
}
|
|
73
|
+
async function handleDuplexRequest(req) {
|
|
74
|
+
const inputStream = req.createRequestStream();
|
|
75
|
+
const outputStream = req.createResponseStream();
|
|
76
|
+
let profiler;
|
|
77
|
+
try {
|
|
78
|
+
const firstChunk = await new Promise((resolve, reject) => {
|
|
79
|
+
const onData = (data) => {
|
|
80
|
+
inputStream.off("error", onError);
|
|
81
|
+
inputStream.pause();
|
|
82
|
+
resolve(data);
|
|
83
|
+
};
|
|
84
|
+
const onError = (err) => {
|
|
85
|
+
inputStream.off("data", onData);
|
|
86
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
87
|
+
};
|
|
88
|
+
inputStream.once("data", onData);
|
|
89
|
+
inputStream.once("error", onError);
|
|
90
|
+
});
|
|
91
|
+
const parseStart = nowMs();
|
|
92
|
+
const jsonData = JSON.parse(firstChunk.toString());
|
|
93
|
+
const jsonParseMs = nowMs() - parseStart;
|
|
94
|
+
const { data: cleanData, profilingMeta } = extractProfilingMeta(jsonData);
|
|
95
|
+
profiler = createServerProfiler(profilingMeta);
|
|
96
|
+
profiler.markRequestParsed(jsonParseMs);
|
|
97
|
+
const validationStart = nowMs();
|
|
98
|
+
const processedData = applyDeviceDefaultsToRequest(cleanData);
|
|
99
|
+
const request = requestSchema.parse(processedData);
|
|
100
|
+
attachProfilingMetaToRequest(request, profilingMeta);
|
|
101
|
+
profiler.markRequestValidated(nowMs() - validationStart);
|
|
102
|
+
const entry = registry[request.type];
|
|
103
|
+
if (!entry) {
|
|
104
|
+
throw new RPCUnknownRequestTypeError(request.type);
|
|
105
|
+
}
|
|
106
|
+
if (entry.type !== "duplex") {
|
|
107
|
+
throw new PluginHandlerTypeMismatchError(request.type, "duplex", entry.type);
|
|
108
|
+
}
|
|
109
|
+
await executeDuplexHandler(req, request, entry, inputStream, outputStream, profiler);
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
inputStream.destroy();
|
|
113
|
+
sendStreamErrorResponse(outputStream, error, profiler);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
70
116
|
/**
|
|
71
117
|
* Apply device-specific config defaults to loadModel requests before schema parsing.
|
|
72
118
|
* This ensures device defaults are applied before schema defaults.
|
|
@@ -7,6 +7,7 @@ import { handleCompletionStreamDelegated } from "./handlers/completion-stream-de
|
|
|
7
7
|
import { getModelEntry } from "../bare/registry/model-registry.js";
|
|
8
8
|
import { handleUnloadModel } from "./handlers/unload-model.js";
|
|
9
9
|
import { handleUnloadModelDelegated } from "./handlers/unload-model-delegated.js";
|
|
10
|
+
import { handleTranscribe } from "./handlers/transcribe.js";
|
|
10
11
|
import { handleTranscribeStream } from "./handlers/transcribe-stream.js";
|
|
11
12
|
import { handleEmbed } from "./handlers/embed.js";
|
|
12
13
|
import { handleTranslate } from "./handlers/translate.js";
|
|
@@ -20,15 +21,24 @@ import { handleTextToSpeech } from "./handlers/text-to-speech.js";
|
|
|
20
21
|
import { handleGetModelInfo } from "./handlers/get-model-info.js";
|
|
21
22
|
import { handleOCRStream } from "./handlers/ocr-stream.js";
|
|
22
23
|
import { handleHeartbeat } from "./handlers/heartbeat.js";
|
|
24
|
+
import { handleFinetune } from "./handlers/finetune.js";
|
|
23
25
|
import { handleHeartbeatDelegated } from "./handlers/heartbeat-delegated.js";
|
|
24
26
|
import { handleCancelDelegated } from "./handlers/cancel-delegated.js";
|
|
27
|
+
import { handleDiffusionStream } from "./handlers/diffusion-stream.js";
|
|
25
28
|
import { handlePluginInvoke, handlePluginInvokeStream, } from "./handlers/plugin-invoke.js";
|
|
26
29
|
import { handleModelRegistryList, handleModelRegistrySearch, handleModelRegistryGetModel, } from "./handlers/registry.js";
|
|
30
|
+
import { handleSuspend } from "./handlers/suspend.js";
|
|
31
|
+
import { handleResume } from "./handlers/resume.js";
|
|
27
32
|
function ragSupportsProgress(request) {
|
|
28
33
|
if (request.type !== "rag")
|
|
29
34
|
return false;
|
|
30
35
|
return ["ingest", "saveEmbeddings", "reindex"].includes(request.operation);
|
|
31
36
|
}
|
|
37
|
+
function finetuneSupportsProgress(request) {
|
|
38
|
+
if (request.type !== "finetune")
|
|
39
|
+
return false;
|
|
40
|
+
return ["start", "resume", undefined].includes(request.operation);
|
|
41
|
+
}
|
|
32
42
|
function isModelDelegated(request) {
|
|
33
43
|
if (!("modelId" in request))
|
|
34
44
|
return false;
|
|
@@ -78,12 +88,16 @@ export const registry = {
|
|
|
78
88
|
type: "reply",
|
|
79
89
|
handler: handleModelRegistryGetModel,
|
|
80
90
|
},
|
|
91
|
+
suspend: { type: "reply", handler: handleSuspend },
|
|
92
|
+
resume: { type: "reply", handler: handleResume },
|
|
81
93
|
// Simple Stream handlers
|
|
82
|
-
|
|
94
|
+
transcribe: { type: "stream", handler: handleTranscribe },
|
|
95
|
+
transcribeStream: { type: "duplex", handler: handleTranscribeStream },
|
|
83
96
|
loggingStream: { type: "stream", handler: handleLoggingStream },
|
|
84
97
|
translate: { type: "stream", handler: handleTranslate },
|
|
85
98
|
textToSpeech: { type: "stream", handler: handleTextToSpeech },
|
|
86
99
|
ocrStream: { type: "stream", handler: handleOCRStream },
|
|
100
|
+
diffusionStream: { type: "stream", handler: handleDiffusionStream },
|
|
87
101
|
pluginInvokeStream: { type: "stream", handler: handlePluginInvokeStream },
|
|
88
102
|
// Handlers with delegation support
|
|
89
103
|
loadModel: {
|
|
@@ -110,4 +124,9 @@ export const registry = {
|
|
|
110
124
|
handler: handleRag,
|
|
111
125
|
supportsProgress: ragSupportsProgress,
|
|
112
126
|
},
|
|
127
|
+
finetune: {
|
|
128
|
+
type: "reply",
|
|
129
|
+
handler: handleFinetune,
|
|
130
|
+
supportsProgress: finetuneSupportsProgress,
|
|
131
|
+
},
|
|
113
132
|
};
|
|
@@ -4,13 +4,15 @@ import { type ServerProfiler } from "./profiling/index";
|
|
|
4
4
|
type ReplyHandler = (request: any, ...args: any[]) => Promise<Response> | Response;
|
|
5
5
|
type StreamHandler = (request: any, ...args: any[]) => AsyncGenerator<Response>;
|
|
6
6
|
type ProgressHandler = (request: any, ...args: any[]) => Promise<Response>;
|
|
7
|
+
type DuplexStreamHandler = (request: any, inputStream: any) => AsyncGenerator<Response>;
|
|
7
8
|
export type HandlerEntry = {
|
|
8
|
-
type: "reply" | "stream";
|
|
9
|
-
handler: ReplyHandler | StreamHandler | ProgressHandler;
|
|
10
|
-
delegatedHandler?: ReplyHandler | StreamHandler | ProgressHandler;
|
|
9
|
+
type: "reply" | "stream" | "duplex";
|
|
10
|
+
handler: ReplyHandler | StreamHandler | ProgressHandler | DuplexStreamHandler;
|
|
11
|
+
delegatedHandler?: ReplyHandler | StreamHandler | ProgressHandler | DuplexStreamHandler;
|
|
11
12
|
isDelegated?: (request: Request) => boolean;
|
|
12
13
|
supportsProgress?: boolean | ((request: Request) => boolean);
|
|
13
14
|
};
|
|
15
|
+
export declare function executeDuplexHandler(_req: RPC.IncomingRequest, request: Request, entry: HandlerEntry, inputStream: ReturnType<RPC.IncomingRequest["createRequestStream"]>, outputStream: ReturnType<RPC.IncomingRequest["createResponseStream"]>, profiler: ServerProfiler): Promise<void>;
|
|
14
16
|
export declare function executeHandler(req: RPC.IncomingRequest, request: Request, entry: HandlerEntry, profiler: ServerProfiler): Promise<void>;
|
|
15
17
|
type InitConfigMessage = {
|
|
16
18
|
type: "__init_config";
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { PROFILING_KEY, } from "../../schemas/index.js";
|
|
2
2
|
import { sendErrorResponse, sendStreamErrorResponse, } from "../error-handlers.js";
|
|
3
|
+
import { PluginHandlerTypeMismatchError } from "../../utils/errors-server.js";
|
|
3
4
|
import { setSDKConfig } from "../bare/registry/config-registry.js";
|
|
4
5
|
import { setRuntimeContext } from "../bare/registry/runtime-context-registry.js";
|
|
5
6
|
import {} from "./profiling/index.js";
|
|
6
|
-
import {
|
|
7
|
+
import { isTerminalChunk } from "./rpc-utils.js";
|
|
8
|
+
import { createProgressThrottle } from "./progress-throttle.js";
|
|
7
9
|
function getProfilingMetaFromRequest(request) {
|
|
8
10
|
if (PROFILING_KEY in request) {
|
|
9
11
|
return request[PROFILING_KEY];
|
|
@@ -32,6 +34,7 @@ async function executeReplyHandler(req, request, handler, profiler, isDelegated)
|
|
|
32
34
|
async function executeStreamHandler(req, request, handler, profiler, isDelegated) {
|
|
33
35
|
const stream = req.createResponseStream();
|
|
34
36
|
profiler.startHandler();
|
|
37
|
+
let sentFinalChunk = false;
|
|
35
38
|
try {
|
|
36
39
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
37
40
|
let generator;
|
|
@@ -43,12 +46,22 @@ async function executeStreamHandler(req, request, handler, profiler, isDelegated
|
|
|
43
46
|
generator = handler(request);
|
|
44
47
|
}
|
|
45
48
|
for await (const response of generator) {
|
|
46
|
-
|
|
49
|
+
if (isTerminalChunk(response)) {
|
|
50
|
+
profiler.endHandler();
|
|
51
|
+
stream.write(profiler.serialize(response, true) + "\n", "utf-8");
|
|
52
|
+
sentFinalChunk = true;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
stream.write(profiler.serialize(response, false) + "\n", "utf-8");
|
|
56
|
+
}
|
|
47
57
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
58
|
+
// Fallback
|
|
59
|
+
if (!sentFinalChunk) {
|
|
60
|
+
profiler.endHandler();
|
|
61
|
+
const trailer = profiler.serialize();
|
|
62
|
+
if (trailer) {
|
|
63
|
+
stream.write(trailer + "\n", "utf-8");
|
|
64
|
+
}
|
|
52
65
|
}
|
|
53
66
|
stream.end();
|
|
54
67
|
}
|
|
@@ -57,73 +70,59 @@ async function executeStreamHandler(req, request, handler, profiler, isDelegated
|
|
|
57
70
|
sendStreamErrorResponse(stream, error, profiler);
|
|
58
71
|
}
|
|
59
72
|
}
|
|
60
|
-
const PROGRESS_THROTTLE_MS = 150;
|
|
61
73
|
async function executeProgressHandler(req, request, handler, profiler, isDelegated) {
|
|
62
74
|
const stream = req.createResponseStream();
|
|
63
75
|
profiler.startHandler();
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
stream.write(
|
|
69
|
-
};
|
|
70
|
-
const progressCallback = (update) => {
|
|
71
|
-
const now = nowMs();
|
|
72
|
-
if (now - lastProgressWrite >= PROGRESS_THROTTLE_MS) {
|
|
73
|
-
lastProgressWrite = now;
|
|
74
|
-
pendingUpdate = null;
|
|
75
|
-
writeProgress(update);
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
pendingUpdate = update;
|
|
79
|
-
if (!flushTimer) {
|
|
80
|
-
flushTimer = setTimeout(() => {
|
|
81
|
-
flushTimer = null;
|
|
82
|
-
if (pendingUpdate) {
|
|
83
|
-
lastProgressWrite = nowMs();
|
|
84
|
-
writeProgress(pendingUpdate);
|
|
85
|
-
pendingUpdate = null;
|
|
86
|
-
}
|
|
87
|
-
}, PROGRESS_THROTTLE_MS - (now - lastProgressWrite));
|
|
88
|
-
}
|
|
89
|
-
}
|
|
76
|
+
const writeBatch = (updates) => {
|
|
77
|
+
const payload = updates
|
|
78
|
+
.map((u) => profiler.serialize(u, false))
|
|
79
|
+
.join("\n");
|
|
80
|
+
stream.write(payload + "\n", "utf-8");
|
|
90
81
|
};
|
|
82
|
+
const throttle = createProgressThrottle(writeBatch);
|
|
91
83
|
try {
|
|
92
84
|
let response;
|
|
93
85
|
if (isDelegated) {
|
|
94
86
|
const profilingMeta = getProfilingMetaFromRequest(request);
|
|
95
|
-
const options = { progressCallback };
|
|
87
|
+
const options = { progressCallback: throttle.push };
|
|
96
88
|
if (profilingMeta) {
|
|
97
89
|
options.profilingMeta = profilingMeta;
|
|
98
90
|
}
|
|
99
91
|
response = await handler(request, options);
|
|
100
92
|
}
|
|
101
93
|
else {
|
|
102
|
-
response = await handler(request,
|
|
103
|
-
}
|
|
104
|
-
if (flushTimer) {
|
|
105
|
-
clearTimeout(flushTimer);
|
|
106
|
-
flushTimer = null;
|
|
107
|
-
}
|
|
108
|
-
if (pendingUpdate) {
|
|
109
|
-
writeProgress(pendingUpdate);
|
|
110
|
-
pendingUpdate = null;
|
|
94
|
+
response = await handler(request, throttle.push);
|
|
111
95
|
}
|
|
96
|
+
throttle.flush();
|
|
112
97
|
profiler.endHandler();
|
|
113
98
|
stream.write(profiler.serialize(response, true) + "\n", "utf-8");
|
|
114
99
|
stream.end();
|
|
115
100
|
}
|
|
116
101
|
catch (error) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
102
|
+
throttle.flush();
|
|
103
|
+
profiler.endHandler();
|
|
104
|
+
sendStreamErrorResponse(stream, error, profiler);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
export async function executeDuplexHandler(_req, request, entry, inputStream, outputStream, profiler) {
|
|
108
|
+
const handler = entry.delegatedHandler && entry.isDelegated?.(request)
|
|
109
|
+
? entry.delegatedHandler
|
|
110
|
+
: entry.handler;
|
|
111
|
+
profiler.startHandler();
|
|
112
|
+
try {
|
|
113
|
+
for await (const response of handler(request, inputStream)) {
|
|
114
|
+
outputStream.write(profiler.serialize(response, false) + "\n", "utf-8");
|
|
120
115
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
116
|
+
profiler.endHandler();
|
|
117
|
+
const trailer = profiler.serialize();
|
|
118
|
+
if (trailer) {
|
|
119
|
+
outputStream.write(trailer + "\n", "utf-8");
|
|
124
120
|
}
|
|
121
|
+
outputStream.end();
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
125
124
|
profiler.endHandler();
|
|
126
|
-
sendStreamErrorResponse(
|
|
125
|
+
sendStreamErrorResponse(outputStream, error, profiler);
|
|
127
126
|
}
|
|
128
127
|
}
|
|
129
128
|
// Unified handler executor with delegation and progress support
|
|
@@ -135,6 +134,9 @@ export async function executeHandler(req, request, entry, profiler) {
|
|
|
135
134
|
(typeof entry.supportsProgress === "function"
|
|
136
135
|
? entry.supportsProgress(request)
|
|
137
136
|
: entry.supportsProgress);
|
|
137
|
+
if (entry.type === "duplex") {
|
|
138
|
+
throw new PluginHandlerTypeMismatchError(request.type, "reply or stream", "duplex");
|
|
139
|
+
}
|
|
138
140
|
if (entry.type === "stream") {
|
|
139
141
|
await executeStreamHandler(req, request, handler, profiler, isDelegated);
|
|
140
142
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { deleteCache as deleteCacheUtil } from "../../bare/ops/kv-cache-utils.js";
|
|
2
|
+
import { clearCachedMessageCounts } from "../../bare/plugins/llamacpp-completion/ops/completion-stream.js";
|
|
2
3
|
import { getServerLogger } from "../../../logging/index.js";
|
|
3
4
|
const logger = getServerLogger();
|
|
4
5
|
export async function handleDeleteCache(request) {
|
|
5
6
|
try {
|
|
6
7
|
if ("all" in request && request.all) {
|
|
7
8
|
await deleteCacheUtil({ all: true });
|
|
9
|
+
clearCachedMessageCounts();
|
|
8
10
|
}
|
|
9
11
|
else if ("kvCacheKey" in request) {
|
|
10
12
|
const params = {
|
|
@@ -14,6 +16,7 @@ export async function handleDeleteCache(request) {
|
|
|
14
16
|
params.modelId = request.modelId;
|
|
15
17
|
}
|
|
16
18
|
await deleteCacheUtil(params);
|
|
19
|
+
clearCachedMessageCounts();
|
|
17
20
|
}
|
|
18
21
|
return {
|
|
19
22
|
type: "deleteCache",
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { FinetuneProgressResponse, FinetuneRequest, FinetuneResult } from "../../../schemas/index";
|
|
2
|
+
export declare function handleFinetune(request: FinetuneRequest, progressCallback?: (update: FinetuneProgressResponse) => void): Promise<FinetuneResult>;
|
|
3
|
+
//# sourceMappingURL=finetune.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { dispatchPluginReply } from "./plugin-dispatch.js";
|
|
2
|
+
import { startFinetune } from "../../bare/plugins/llamacpp-completion/ops/finetune.js";
|
|
3
|
+
export async function handleFinetune(request, progressCallback) {
|
|
4
|
+
if (progressCallback &&
|
|
5
|
+
(request.operation === "start" || request.operation === "resume" || request.operation === undefined)) {
|
|
6
|
+
return startFinetune(request, (progress) => {
|
|
7
|
+
const update = {
|
|
8
|
+
type: "finetune:progress",
|
|
9
|
+
modelId: request.modelId,
|
|
10
|
+
...progress,
|
|
11
|
+
};
|
|
12
|
+
progressCallback(update);
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
return dispatchPluginReply(request.modelId, "finetune", request);
|
|
16
|
+
}
|