@mcoda/mswarm 0.1.133 → 0.1.135-codali.2
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/README.md +44 -0
- package/dist/codali-executor.d.ts +66 -1
- package/dist/codali-executor.d.ts.map +1 -1
- package/dist/codali-executor.js +83 -8
- package/dist/codali-executor.js.map +1 -1
- package/dist/invocation-token.d.ts.map +1 -1
- package/dist/invocation-token.js +1 -0
- package/dist/invocation-token.js.map +1 -1
- package/dist/native-reasoning.d.ts +8 -0
- package/dist/native-reasoning.d.ts.map +1 -0
- package/dist/native-reasoning.js +18 -0
- package/dist/native-reasoning.js.map +1 -0
- package/dist/runtime.d.ts +25 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +220 -20
- package/dist/runtime.js.map +1 -1
- package/dist/server.d.ts +3 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +58 -8
- package/dist/server.js.map +1 -1
- package/dist/vendor/codali/agents/RoleResolution.d.ts.map +1 -1
- package/dist/vendor/codali/agents/RoleResolution.js +4 -4
- package/dist/vendor/codali/api/CodaliApi.d.ts +16 -0
- package/dist/vendor/codali/api/CodaliApi.d.ts.map +1 -1
- package/dist/vendor/codali/api/CodaliApi.js +39 -10
- package/dist/vendor/codali/cli/AskCommand.d.ts +3 -0
- package/dist/vendor/codali/cli/AskCommand.d.ts.map +1 -1
- package/dist/vendor/codali/cli/AskCommand.js +76 -13
- package/dist/vendor/codali/cli/RunCommand.d.ts +4 -0
- package/dist/vendor/codali/cli/RunCommand.d.ts.map +1 -1
- package/dist/vendor/codali/cli/RunCommand.js +110 -24
- package/dist/vendor/codali/cli/TerminalCommand.d.ts +35 -0
- package/dist/vendor/codali/cli/TerminalCommand.d.ts.map +1 -0
- package/dist/vendor/codali/cli/TerminalCommand.js +616 -0
- package/dist/vendor/codali/cli/TerminalCredentials.d.ts +3 -0
- package/dist/vendor/codali/cli/TerminalCredentials.d.ts.map +1 -0
- package/dist/vendor/codali/cli/TerminalCredentials.js +89 -0
- package/dist/vendor/codali/cli/TerminalInput.d.ts +24 -0
- package/dist/vendor/codali/cli/TerminalInput.d.ts.map +1 -0
- package/dist/vendor/codali/cli/TerminalInput.js +98 -0
- package/dist/vendor/codali/cli/TerminalText.d.ts +10 -0
- package/dist/vendor/codali/cli/TerminalText.d.ts.map +1 -0
- package/dist/vendor/codali/cli/TerminalText.js +53 -0
- package/dist/vendor/codali/cli.d.ts.map +1 -1
- package/dist/vendor/codali/cli.js +33 -4
- package/dist/vendor/codali/cognitive/ConfiguredPipeline.d.ts +34 -0
- package/dist/vendor/codali/cognitive/ConfiguredPipeline.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/ConfiguredPipeline.js +50 -0
- package/dist/vendor/codali/cognitive/ValidationRunner.d.ts +4 -0
- package/dist/vendor/codali/cognitive/ValidationRunner.d.ts.map +1 -1
- package/dist/vendor/codali/cognitive/ValidationRunner.js +18 -41
- package/dist/vendor/codali/config/NodeOrchestration.d.ts +21 -0
- package/dist/vendor/codali/config/NodeOrchestration.d.ts.map +1 -0
- package/dist/vendor/codali/config/NodeOrchestration.js +54 -0
- package/dist/vendor/codali/config/OrchestrationConfig.d.ts +100 -0
- package/dist/vendor/codali/config/OrchestrationConfig.d.ts.map +1 -0
- package/dist/vendor/codali/config/OrchestrationConfig.js +245 -0
- package/dist/vendor/codali/connectors/mcp/McpClient.d.ts +3 -1
- package/dist/vendor/codali/connectors/mcp/McpClient.d.ts.map +1 -1
- package/dist/vendor/codali/connectors/mcp/McpClient.js +3 -2
- package/dist/vendor/codali/connectors/mcp/McpServerRegistry.d.ts +2 -2
- package/dist/vendor/codali/connectors/mcp/McpServerRegistry.d.ts.map +1 -1
- package/dist/vendor/codali/connectors/mcp/McpServerRegistry.js +39 -16
- package/dist/vendor/codali/connectors/mcp/McpToolAdapter.js +2 -2
- package/dist/vendor/codali/connectors/media/ConfiguredMediaTools.d.ts +6 -0
- package/dist/vendor/codali/connectors/media/ConfiguredMediaTools.d.ts.map +1 -0
- package/dist/vendor/codali/connectors/media/ConfiguredMediaTools.js +41 -0
- package/dist/vendor/codali/connectors/media/ImageGenerationTool.js +3 -3
- package/dist/vendor/codali/connectors/media/MediaArtifactReceipt.d.ts +5 -0
- package/dist/vendor/codali/connectors/media/MediaArtifactReceipt.d.ts.map +1 -0
- package/dist/vendor/codali/connectors/media/MediaArtifactReceipt.js +65 -0
- package/dist/vendor/codali/connectors/media/MediaJobStore.d.ts +68 -0
- package/dist/vendor/codali/connectors/media/MediaJobStore.d.ts.map +1 -0
- package/dist/vendor/codali/connectors/media/MediaJobStore.js +199 -0
- package/dist/vendor/codali/connectors/media/MediaJobWorker.d.ts +2 -0
- package/dist/vendor/codali/connectors/media/MediaJobWorker.d.ts.map +1 -0
- package/dist/vendor/codali/connectors/media/MediaJobWorker.js +65 -0
- package/dist/vendor/codali/connectors/media/RemoteMediaJob.d.ts +6 -0
- package/dist/vendor/codali/connectors/media/RemoteMediaJob.d.ts.map +1 -0
- package/dist/vendor/codali/connectors/media/RemoteMediaJob.js +80 -0
- package/dist/vendor/codali/docdex/DocdexClient.d.ts +18 -1
- package/dist/vendor/codali/docdex/DocdexClient.d.ts.map +1 -1
- package/dist/vendor/codali/docdex/DocdexClient.js +135 -19
- package/dist/vendor/codali/docdex/ManagedDocdex.d.ts +29 -0
- package/dist/vendor/codali/docdex/ManagedDocdex.d.ts.map +1 -0
- package/dist/vendor/codali/docdex/ManagedDocdex.js +215 -0
- package/dist/vendor/codali/docdex/ManagedRuntime.d.ts +28 -0
- package/dist/vendor/codali/docdex/ManagedRuntime.d.ts.map +1 -0
- package/dist/vendor/codali/docdex/ManagedRuntime.js +212 -0
- package/dist/vendor/codali/eval/EvaluationProcess.d.ts +13 -0
- package/dist/vendor/codali/eval/EvaluationProcess.d.ts.map +1 -0
- package/dist/vendor/codali/eval/EvaluationProcess.js +76 -0
- package/dist/vendor/codali/eval/LongWorkflowJourney.d.ts +34 -0
- package/dist/vendor/codali/eval/LongWorkflowJourney.d.ts.map +1 -0
- package/dist/vendor/codali/eval/LongWorkflowJourney.js +243 -0
- package/dist/vendor/codali/eval/PlanningCorpus.d.ts +45 -0
- package/dist/vendor/codali/eval/PlanningCorpus.d.ts.map +1 -0
- package/dist/vendor/codali/eval/PlanningCorpus.js +189 -0
- package/dist/vendor/codali/eval/PlanningCorpusRunner.d.ts +13 -0
- package/dist/vendor/codali/eval/PlanningCorpusRunner.d.ts.map +1 -0
- package/dist/vendor/codali/eval/PlanningCorpusRunner.js +89 -0
- package/dist/vendor/codali/eval/TerminalCorpusRunner.d.ts +36 -0
- package/dist/vendor/codali/eval/TerminalCorpusRunner.d.ts.map +1 -0
- package/dist/vendor/codali/eval/TerminalCorpusRunner.js +222 -0
- package/dist/vendor/codali/eval/TerminalTaskCorpus.d.ts +26 -0
- package/dist/vendor/codali/eval/TerminalTaskCorpus.d.ts.map +1 -0
- package/dist/vendor/codali/eval/TerminalTaskCorpus.js +105 -0
- package/dist/vendor/codali/eval/TerminalWorkflowCorpus.d.ts +11 -0
- package/dist/vendor/codali/eval/TerminalWorkflowCorpus.d.ts.map +1 -0
- package/dist/vendor/codali/eval/TerminalWorkflowCorpus.js +116 -0
- package/dist/vendor/codali/eval/fixtures/TerminalRecoveryJourney.d.ts +4 -0
- package/dist/vendor/codali/eval/fixtures/TerminalRecoveryJourney.d.ts.map +1 -0
- package/dist/vendor/codali/eval/fixtures/TerminalRecoveryJourney.js +132 -0
- package/dist/vendor/codali/gateway/CodaliGateway.d.ts +2 -0
- package/dist/vendor/codali/gateway/CodaliGateway.d.ts.map +1 -1
- package/dist/vendor/codali/gateway/CodaliGateway.js +16 -4
- package/dist/vendor/codali/gateway/ConfiguredGateway.d.ts +23 -0
- package/dist/vendor/codali/gateway/ConfiguredGateway.d.ts.map +1 -0
- package/dist/vendor/codali/gateway/ConfiguredGateway.js +44 -0
- package/dist/vendor/codali/gateway/GatewayTracer.d.ts +1 -1
- package/dist/vendor/codali/gateway/GatewayTracer.d.ts.map +1 -1
- package/dist/vendor/codali/gateway/GatewayTracer.js +2 -27
- package/dist/vendor/codali/gateway/LocalGatewayTaskRunner.d.ts.map +1 -1
- package/dist/vendor/codali/gateway/LocalGatewayTaskRunner.js +13 -1
- package/dist/vendor/codali/index.d.ts +23 -0
- package/dist/vendor/codali/index.d.ts.map +1 -1
- package/dist/vendor/codali/index.js +12 -0
- package/dist/vendor/codali/permissions/PermissionGate.d.ts +44 -0
- package/dist/vendor/codali/permissions/PermissionGate.d.ts.map +1 -0
- package/dist/vendor/codali/permissions/PermissionGate.js +97 -0
- package/dist/vendor/codali/providers/ConfiguredEmbeddings.d.ts +43 -0
- package/dist/vendor/codali/providers/ConfiguredEmbeddings.d.ts.map +1 -0
- package/dist/vendor/codali/providers/ConfiguredEmbeddings.js +87 -0
- package/dist/vendor/codali/providers/ConfiguredModelScope.d.ts +69 -0
- package/dist/vendor/codali/providers/ConfiguredModelScope.d.ts.map +1 -0
- package/dist/vendor/codali/providers/ConfiguredModelScope.js +113 -0
- package/dist/vendor/codali/providers/ConfiguredProvider.d.ts +79 -0
- package/dist/vendor/codali/providers/ConfiguredProvider.d.ts.map +1 -0
- package/dist/vendor/codali/providers/ConfiguredProvider.js +238 -0
- package/dist/vendor/codali/providers/ModelServiceError.d.ts +10 -0
- package/dist/vendor/codali/providers/ModelServiceError.d.ts.map +1 -0
- package/dist/vendor/codali/providers/ModelServiceError.js +45 -0
- package/dist/vendor/codali/providers/MswarmWorkerProvider.d.ts.map +1 -1
- package/dist/vendor/codali/providers/MswarmWorkerProvider.js +4 -0
- package/dist/vendor/codali/providers/OpenAiCompatibleProvider.d.ts.map +1 -1
- package/dist/vendor/codali/providers/OpenAiCompatibleProvider.js +134 -52
- package/dist/vendor/codali/providers/ProviderTypes.d.ts +14 -0
- package/dist/vendor/codali/providers/ProviderTypes.d.ts.map +1 -1
- package/dist/vendor/codali/runtime/CodaliJobRuntime.d.ts +6 -0
- package/dist/vendor/codali/runtime/CodaliJobRuntime.d.ts.map +1 -1
- package/dist/vendor/codali/runtime/CodaliJobRuntime.js +36 -1
- package/dist/vendor/codali/runtime/CodaliRuntime.d.ts +30 -0
- package/dist/vendor/codali/runtime/CodaliRuntime.d.ts.map +1 -1
- package/dist/vendor/codali/runtime/CodaliRuntime.js +71 -1
- package/dist/vendor/codali/runtime/CompletionReport.d.ts +5 -0
- package/dist/vendor/codali/runtime/CompletionReport.d.ts.map +1 -0
- package/dist/vendor/codali/runtime/CompletionReport.js +12 -0
- package/dist/vendor/codali/runtime/ProgressTracker.d.ts +17 -0
- package/dist/vendor/codali/runtime/ProgressTracker.d.ts.map +1 -0
- package/dist/vendor/codali/runtime/ProgressTracker.js +27 -0
- package/dist/vendor/codali/runtime/RequestedTestEvidence.d.ts +12 -0
- package/dist/vendor/codali/runtime/RequestedTestEvidence.d.ts.map +1 -0
- package/dist/vendor/codali/runtime/RequestedTestEvidence.js +16 -0
- package/dist/vendor/codali/runtime/RequiredRetrieval.d.ts +13 -0
- package/dist/vendor/codali/runtime/RequiredRetrieval.d.ts.map +1 -0
- package/dist/vendor/codali/runtime/RequiredRetrieval.js +25 -0
- package/dist/vendor/codali/runtime/ReviewSource.d.ts +6 -0
- package/dist/vendor/codali/runtime/ReviewSource.d.ts.map +1 -0
- package/dist/vendor/codali/runtime/ReviewSource.js +38 -0
- package/dist/vendor/codali/runtime/Runner.d.ts +13 -0
- package/dist/vendor/codali/runtime/Runner.d.ts.map +1 -1
- package/dist/vendor/codali/runtime/Runner.js +220 -158
- package/dist/vendor/codali/runtime/SecretRedaction.d.ts +11 -0
- package/dist/vendor/codali/runtime/SecretRedaction.d.ts.map +1 -0
- package/dist/vendor/codali/runtime/SecretRedaction.js +85 -0
- package/dist/vendor/codali/runtime/SessionController.d.ts +148 -0
- package/dist/vendor/codali/runtime/SessionController.d.ts.map +1 -0
- package/dist/vendor/codali/runtime/SessionController.js +1356 -0
- package/dist/vendor/codali/runtime/StructuralEvidence.d.ts +22 -0
- package/dist/vendor/codali/runtime/StructuralEvidence.d.ts.map +1 -0
- package/dist/vendor/codali/runtime/StructuralEvidence.js +87 -0
- package/dist/vendor/codali/runtime/TaskReviewContext.d.ts +34 -0
- package/dist/vendor/codali/runtime/TaskReviewContext.d.ts.map +1 -0
- package/dist/vendor/codali/runtime/TaskReviewContext.js +34 -0
- package/dist/vendor/codali/runtime/ValidationOutput.d.ts +5 -0
- package/dist/vendor/codali/runtime/ValidationOutput.d.ts.map +1 -0
- package/dist/vendor/codali/runtime/ValidationOutput.js +32 -0
- package/dist/vendor/codali/runtime/VerificationCommand.d.ts +3 -0
- package/dist/vendor/codali/runtime/VerificationCommand.d.ts.map +1 -0
- package/dist/vendor/codali/runtime/VerificationCommand.js +48 -0
- package/dist/vendor/codali/runtime/WorkStatusPage.d.ts +15 -0
- package/dist/vendor/codali/runtime/WorkStatusPage.d.ts.map +1 -0
- package/dist/vendor/codali/runtime/WorkStatusPage.js +58 -0
- package/dist/vendor/codali/runtime/WorkspaceLedger.d.ts +13 -0
- package/dist/vendor/codali/runtime/WorkspaceLedger.d.ts.map +1 -0
- package/dist/vendor/codali/runtime/WorkspaceLedger.js +145 -0
- package/dist/vendor/codali/runtime/WorkspaceLock.d.ts.map +1 -1
- package/dist/vendor/codali/runtime/WorkspaceLock.js +20 -17
- package/dist/vendor/codali/runtime/WorkspaceSnapshot.d.ts +13 -0
- package/dist/vendor/codali/runtime/WorkspaceSnapshot.d.ts.map +1 -0
- package/dist/vendor/codali/runtime/WorkspaceSnapshot.js +88 -0
- package/dist/vendor/codali/session/AtomicState.d.ts +13 -0
- package/dist/vendor/codali/session/AtomicState.d.ts.map +1 -0
- package/dist/vendor/codali/session/AtomicState.js +109 -0
- package/dist/vendor/codali/session/SessionStoragePath.d.ts +15 -0
- package/dist/vendor/codali/session/SessionStoragePath.d.ts.map +1 -0
- package/dist/vendor/codali/session/SessionStoragePath.js +89 -0
- package/dist/vendor/codali/session/SessionStore.d.ts +9 -0
- package/dist/vendor/codali/session/SessionStore.d.ts.map +1 -1
- package/dist/vendor/codali/session/SessionStore.js +181 -47
- package/dist/vendor/codali/session/WorkState.d.ts +23 -0
- package/dist/vendor/codali/session/WorkState.d.ts.map +1 -0
- package/dist/vendor/codali/session/WorkState.js +367 -0
- package/dist/vendor/codali/session/WorkTypes.d.ts +94 -0
- package/dist/vendor/codali/session/WorkTypes.d.ts.map +1 -0
- package/dist/vendor/codali/session/WorkTypes.js +1 -0
- package/dist/vendor/codali/tools/ToolRegistry.d.ts +2 -0
- package/dist/vendor/codali/tools/ToolRegistry.d.ts.map +1 -1
- package/dist/vendor/codali/tools/ToolRegistry.js +12 -2
- package/dist/vendor/codali/tools/ToolTypes.d.ts +16 -0
- package/dist/vendor/codali/tools/ToolTypes.d.ts.map +1 -1
- package/dist/vendor/codali/tools/docdex/DocdexTools.d.ts +2 -0
- package/dist/vendor/codali/tools/docdex/DocdexTools.d.ts.map +1 -1
- package/dist/vendor/codali/tools/docdex/DocdexTools.js +17 -2
- package/dist/vendor/codali/tools/filesystem/FileTools.d.ts.map +1 -1
- package/dist/vendor/codali/tools/filesystem/FileTools.js +30 -10
- package/dist/vendor/codali/tools/shell/AsyncProcess.d.ts +16 -0
- package/dist/vendor/codali/tools/shell/AsyncProcess.d.ts.map +1 -0
- package/dist/vendor/codali/tools/shell/AsyncProcess.js +94 -0
- package/dist/vendor/codali/tools/shell/DarwinRuntimeLibraries.d.ts +13 -0
- package/dist/vendor/codali/tools/shell/DarwinRuntimeLibraries.d.ts.map +1 -0
- package/dist/vendor/codali/tools/shell/DarwinRuntimeLibraries.js +130 -0
- package/dist/vendor/codali/tools/shell/HostToolchain.d.ts +19 -0
- package/dist/vendor/codali/tools/shell/HostToolchain.d.ts.map +1 -0
- package/dist/vendor/codali/tools/shell/HostToolchain.js +264 -0
- package/dist/vendor/codali/tools/shell/IsolatedExecutor.d.ts +15 -0
- package/dist/vendor/codali/tools/shell/IsolatedExecutor.d.ts.map +1 -0
- package/dist/vendor/codali/tools/shell/IsolatedExecutor.js +134 -0
- package/dist/vendor/codali/tools/shell/ShellTool.d.ts.map +1 -1
- package/dist/vendor/codali/tools/shell/ShellTool.js +9 -29
- package/dist/vendor/codali/tools/shell/ShellWorkingDirectory.d.ts +3 -0
- package/dist/vendor/codali/tools/shell/ShellWorkingDirectory.d.ts.map +1 -0
- package/dist/vendor/codali/tools/shell/ShellWorkingDirectory.js +30 -0
- package/package.json +31 -29
- package/scripts/backend-http-drain.mjs +152 -0
- package/scripts/media_gpu_lock.py +238 -0
- package/scripts/stable-audio-3-openai-server.py +45 -14
- package/scripts/stable-diffusion-cpp-openai-server.py +34 -4
- package/scripts/stable-diffusion-cpp-webm-duration.patch +22 -0
- package/scripts/wan22-openai-server.py +97 -18
package/dist/runtime.js
CHANGED
|
@@ -5,9 +5,10 @@ import { spawn } from "node:child_process";
|
|
|
5
5
|
import { createHash, createHmac, randomBytes, randomUUID } from "node:crypto";
|
|
6
6
|
import { isIP } from "node:net";
|
|
7
7
|
import { Agent, fetch as undiciFetch } from "undici";
|
|
8
|
+
import { nativeReasoningRequest } from "./native-reasoning.js";
|
|
8
9
|
import { GlobalRepository } from "@mcoda/db";
|
|
9
10
|
import { MswarmCodaliExecutor } from "./codali-executor.js";
|
|
10
|
-
import { GENERATIVE_OPERATION_DEFAULT_PATHS, GENERATIVE_REQUEST_PARAMETER_ALLOWLISTS, MSWARM_CAPABILITY_SCHEMA_VERSION, CryptoHelper, assertMswarmSafeRelativePath, validateMswarmArchiveEntry, buildMswarmCapabilityNames, buildMswarmPrivateCapabilityCatalogEntry, buildMswarmLocalArtifactUri, buildMswarmSandboxProfile, defaultMswarmArtifactAccessPolicy, defaultMswarmArtifactRetentionPolicy, normalizeGenerativeModalities, normalizeSelfHostedGenerativeOperation, projectMswarmPublicCapabilities, validateMswarmGenericJobRequest } from "@mcoda/shared";
|
|
11
|
+
import { GENERATIVE_OPERATION_DEFAULT_PATHS, GENERATIVE_REQUEST_PARAMETER_ALLOWLISTS, validateEmbeddingRequest, validateEmbeddingResponse, validateEmbeddingPreprocessing, MSWARM_CAPABILITY_SCHEMA_VERSION, CryptoHelper, assertMswarmSafeRelativePath, validateMswarmArchiveEntry, buildMswarmCapabilityNames, buildMswarmPrivateCapabilityCatalogEntry, buildMswarmLocalArtifactUri, buildMswarmSandboxProfile, defaultMswarmArtifactAccessPolicy, defaultMswarmArtifactRetentionPolicy, normalizeGenerativeModalities, normalizeSelfHostedGenerativeOperation, projectMswarmPublicCapabilities, validateMswarmGenericJobRequest } from "@mcoda/shared";
|
|
11
12
|
const REGISTRATION_POLL_INTERVAL_MS = 5000;
|
|
12
13
|
const REGISTRATION_POLL_TIMEOUT_MS = 30 * 60000;
|
|
13
14
|
/**
|
|
@@ -202,12 +203,16 @@ function resolvePersistentNodePath(nodePath) {
|
|
|
202
203
|
const DEFAULT_EXPOSE_ALL_MODELS = true;
|
|
203
204
|
const LOCAL_OPENAI_COMPATIBLE_ADAPTERS = new Set([
|
|
204
205
|
"openai-compatible-local",
|
|
206
|
+
"strata-local",
|
|
205
207
|
"vllm-local",
|
|
206
208
|
"llama-cpp-local",
|
|
207
209
|
"llamacpp-local"
|
|
208
210
|
]);
|
|
209
211
|
const SECRET_LOCAL_RUNNER_HEADER_KEYS = new Set(["authorization", "proxy-authorization", "x-api-key", "api-key"]);
|
|
210
212
|
const RESERVED_LOCAL_RUNNER_EXTRA_BODY_KEYS = new Set([
|
|
213
|
+
"input",
|
|
214
|
+
"dimensions",
|
|
215
|
+
"encoding_format",
|
|
211
216
|
"model",
|
|
212
217
|
"messages",
|
|
213
218
|
"prompt",
|
|
@@ -229,6 +234,7 @@ const RESERVED_LOCAL_RUNNER_EXTRA_BODY_KEYS = new Set([
|
|
|
229
234
|
"temperature"
|
|
230
235
|
]);
|
|
231
236
|
const REQUIRED_GENERATIVE_OPERATION_REQUEST_PARAMETERS = {
|
|
237
|
+
embeddings: ["model", "input", "encoding_format"],
|
|
232
238
|
"chat.completions": ["model", "messages"],
|
|
233
239
|
"images.generations": ["model", "prompt", "response_format"],
|
|
234
240
|
"audio.generations": ["model", "prompt", "response_format"],
|
|
@@ -244,6 +250,7 @@ const DEFAULT_VIDEO_GENERATIVE_OUTPUT_BYTES = 256 * 1024 * 1024;
|
|
|
244
250
|
const GENERATIVE_RESPONSE_JSON_OVERHEAD_BYTES = 64 * 1024;
|
|
245
251
|
const LOCAL_RUNNER_KIND_ALIASES = {
|
|
246
252
|
vllm: "vllm",
|
|
253
|
+
strata: "strata",
|
|
247
254
|
"llama-cpp": "llama-cpp",
|
|
248
255
|
"llama.cpp": "llama-cpp",
|
|
249
256
|
llamacpp: "llama-cpp",
|
|
@@ -328,7 +335,7 @@ function isRecord(value) {
|
|
|
328
335
|
}
|
|
329
336
|
export function normalizeSelfHostedGenerativeOperationName(value) {
|
|
330
337
|
const normalized = optionalText(value);
|
|
331
|
-
return normalized === "chat.completions" ||
|
|
338
|
+
return normalized === "embeddings" || normalized === "chat.completions" ||
|
|
332
339
|
normalized === "images.generations" ||
|
|
333
340
|
normalized === "audio.generations" ||
|
|
334
341
|
normalized === "videos.generations"
|
|
@@ -369,7 +376,7 @@ function normalizeGenerativeOperationDescriptor(value) {
|
|
|
369
376
|
]));
|
|
370
377
|
const responseFormats = normalized.responseFormats?.length
|
|
371
378
|
? normalized.responseFormats
|
|
372
|
-
: operation === "chat.completions"
|
|
379
|
+
: operation === "embeddings" ? ["float"] : operation === "chat.completions"
|
|
373
380
|
? undefined
|
|
374
381
|
: operation === "images.generations"
|
|
375
382
|
? ["b64_json"]
|
|
@@ -420,6 +427,8 @@ function normalizeGenerativeOperations(value) {
|
|
|
420
427
|
function inferGenerativeModalities(operations, direction) {
|
|
421
428
|
const modalities = new Set();
|
|
422
429
|
for (const descriptor of operations) {
|
|
430
|
+
if (direction === "output" && descriptor.operation === "embeddings")
|
|
431
|
+
modalities.add("embedding");
|
|
423
432
|
if (direction === "input" || descriptor.operation === "chat.completions") {
|
|
424
433
|
modalities.add("text");
|
|
425
434
|
}
|
|
@@ -438,6 +447,10 @@ function inferGenerativeModalities(operations, direction) {
|
|
|
438
447
|
function generativeOperationCatalogInput(descriptor) {
|
|
439
448
|
const limits = descriptor.limits
|
|
440
449
|
? {
|
|
450
|
+
...(descriptor.limits.maxInputItems !== undefined ? { max_input_items: descriptor.limits.maxInputItems } : {}),
|
|
451
|
+
...(descriptor.limits.maxInputChars !== undefined ? { max_input_chars: descriptor.limits.maxInputChars } : {}),
|
|
452
|
+
...(descriptor.limits.maxTotalInputChars !== undefined ? { max_total_input_chars: descriptor.limits.maxTotalInputChars } : {}),
|
|
453
|
+
...(descriptor.limits.embeddingDimensions !== undefined ? { embedding_dimensions: descriptor.limits.embeddingDimensions } : {}),
|
|
441
454
|
...(descriptor.limits.maxRequestBytes !== undefined
|
|
442
455
|
? { max_request_bytes: descriptor.limits.maxRequestBytes }
|
|
443
456
|
: {}),
|
|
@@ -526,6 +539,8 @@ function defaultLocalRunnerKindForAdapter(adapter) {
|
|
|
526
539
|
const lookupKey = normalizeLookupKey(normalized);
|
|
527
540
|
if (lookupKey === "vllm-local")
|
|
528
541
|
return "vllm";
|
|
542
|
+
if (lookupKey === "strata-local")
|
|
543
|
+
return "strata";
|
|
529
544
|
if (lookupKey === "llama-cpp-local" || lookupKey === "llamacpp-local")
|
|
530
545
|
return "llama-cpp";
|
|
531
546
|
return undefined;
|
|
@@ -617,6 +632,7 @@ function normalizeMcodaLocalRunnerConfig(adapter, config) {
|
|
|
617
632
|
inputModalities: normalizeGenerativeModalities(merged.inputModalities ?? merged.input_modalities),
|
|
618
633
|
outputModalities: normalizeGenerativeModalities(merged.outputModalities ?? merged.output_modalities),
|
|
619
634
|
operations: normalizeGenerativeOperations(merged.operations),
|
|
635
|
+
embedding: merged.embedding === undefined || merged.embedding === null ? undefined : validateEmbeddingPreprocessing(merged.embedding),
|
|
620
636
|
publicModelId: readConfigString(merged, ["publicModelId", "public_model_id"])
|
|
621
637
|
};
|
|
622
638
|
}
|
|
@@ -1228,12 +1244,12 @@ export function agentRunsOnThisNode(agent) {
|
|
|
1228
1244
|
return false;
|
|
1229
1245
|
}
|
|
1230
1246
|
}
|
|
1231
|
-
function isAgentExposed(agentSlug, defaultModel, bestUsage, config) {
|
|
1247
|
+
function isAgentExposed(agentSlug, defaultModel, bestUsage, config, supportsEmbeddings = false) {
|
|
1232
1248
|
const identities = [agentSlug, defaultModel].filter((value) => Boolean(value));
|
|
1233
1249
|
if (identities.some((identity) => config.modelBlocklist.includes(identity))) {
|
|
1234
1250
|
return false;
|
|
1235
1251
|
}
|
|
1236
|
-
if (isEmbeddingUsage(bestUsage) || identities.some((identity) => isEmbeddingModel(identity))) {
|
|
1252
|
+
if (!supportsEmbeddings && (isEmbeddingUsage(bestUsage) || identities.some((identity) => isEmbeddingModel(identity)))) {
|
|
1237
1253
|
return false;
|
|
1238
1254
|
}
|
|
1239
1255
|
if (config.modelAllowlist.length > 0) {
|
|
@@ -1500,6 +1516,8 @@ Wants=network-online.target
|
|
|
1500
1516
|
Type=simple
|
|
1501
1517
|
ExecStart=${quoteSystemdValue(input.wrapperPath)}
|
|
1502
1518
|
Restart=always
|
|
1519
|
+
TimeoutStopSec=infinity
|
|
1520
|
+
KillMode=mixed
|
|
1503
1521
|
RestartSec=5
|
|
1504
1522
|
StandardOutput=append:${input.logPath}
|
|
1505
1523
|
StandardError=append:${input.errorLogPath}
|
|
@@ -2095,6 +2113,8 @@ export function mapMcodaAgentToSelfHostedModel(agent, config) {
|
|
|
2095
2113
|
model_id: publicModelId || model,
|
|
2096
2114
|
public_model_id: publicModelId,
|
|
2097
2115
|
upstream_model: model,
|
|
2116
|
+
digest: optionalText(legacyConfig.modelDigest),
|
|
2117
|
+
embedding: localRunner?.embedding,
|
|
2098
2118
|
base_url: localRunner?.baseUrl ?? legacyNativeBase ?? undefined,
|
|
2099
2119
|
runner_kind: localRunner?.generativeRunnerKind ?? localRunner?.runnerKind ?? (legacyNativeBase ? "llama-cpp" : undefined),
|
|
2100
2120
|
auth_mode: localRunner?.authMode ?? (legacyNativeBase ? normalizeLocalRunnerAuthMode(legacyConfig.authMode) : undefined),
|
|
@@ -2109,10 +2129,13 @@ export function mapMcodaAgentToSelfHostedModel(agent, config) {
|
|
|
2109
2129
|
supports_vision: supportsVision,
|
|
2110
2130
|
supports_json_schema: localRunner?.supportsJsonSchema,
|
|
2111
2131
|
supports_gbnf: localRunner?.supportsGbnf,
|
|
2132
|
+
// Transport metadata must not change semantic model capability sets: those
|
|
2133
|
+
// sets participate in stable load-balanced pool identifiers on the gateway.
|
|
2134
|
+
native_reasoning_transport_version: localRunner?.runnerKind === "strata" ? 1 : undefined,
|
|
2112
2135
|
openai_compatible: openaiCompatible,
|
|
2113
2136
|
exposed: healthStatus !== "blocked" &&
|
|
2114
2137
|
agentRunsOnThisNode(agent) &&
|
|
2115
|
-
isAgentExposed(slug, defaultModel, bestUsage, config),
|
|
2138
|
+
isAgentExposed(slug, defaultModel, bestUsage, config, operations.some(entry => entry.operation === "embeddings")),
|
|
2116
2139
|
best_usage: bestUsage,
|
|
2117
2140
|
capabilities,
|
|
2118
2141
|
cost_per_million: optionalNumber(agent.costPerMillion, agent.cost_per_million),
|
|
@@ -2465,6 +2488,8 @@ function mapMcodaAgentToCodaliAgent(agent, fallbackSlug) {
|
|
|
2465
2488
|
const generativeOperations = localRunner?.operations ??
|
|
2466
2489
|
[defaultGenerativeOperationDescriptor("chat.completions", localRunner ? "/chat/completions" : undefined)];
|
|
2467
2490
|
return {
|
|
2491
|
+
modelDigest: configText(config, "modelDigest"),
|
|
2492
|
+
orchestrationConfigPath: configText(config, "codaliOrchestrationPath"),
|
|
2468
2493
|
slug: optionalText(agent.slug) || fallbackSlug,
|
|
2469
2494
|
adapter,
|
|
2470
2495
|
provider: resolveCodaliProviderForAgent(agent),
|
|
@@ -2491,6 +2516,10 @@ function mapMcodaAgentToCodaliAgent(agent, fallbackSlug) {
|
|
|
2491
2516
|
supportsJsonSchema: localRunner?.supportsJsonSchema,
|
|
2492
2517
|
supportsGbnf: localRunner?.supportsGbnf,
|
|
2493
2518
|
capabilities: normalizeCapabilities(agent.capabilities),
|
|
2519
|
+
rating: optionalNumber(agent.rating) ?? undefined,
|
|
2520
|
+
reasoningRating: optionalNumber(agent.reasoningRating, agent.reasoning_rating) ?? undefined,
|
|
2521
|
+
maxComplexity: optionalNumber(agent.maxComplexity, agent.max_complexity) ?? undefined,
|
|
2522
|
+
bestUsage: optionalText(agent.bestUsage) ?? optionalText(agent.best_usage) ?? undefined,
|
|
2494
2523
|
contextWindow: optionalNumber(agent.contextWindow, agent.context_window) ?? undefined,
|
|
2495
2524
|
maxOutputTokens: optionalNumber(agent.maxOutputTokens, agent.max_output_tokens) ?? undefined,
|
|
2496
2525
|
generativeOperations,
|
|
@@ -4467,11 +4496,18 @@ export class MswarmSelfHostedNodeClient {
|
|
|
4467
4496
|
}
|
|
4468
4497
|
}
|
|
4469
4498
|
export class SelfHostedNodeRuntime {
|
|
4499
|
+
get isDraining() {
|
|
4500
|
+
return this.admissionClosed || this.config.drainMode === true;
|
|
4501
|
+
}
|
|
4502
|
+
beginDrain() {
|
|
4503
|
+
this.admissionClosed = true;
|
|
4504
|
+
}
|
|
4470
4505
|
constructor(config, deps) {
|
|
4471
4506
|
this.activeChatJobs = 0;
|
|
4472
4507
|
this.activeRequestIds = new Set();
|
|
4473
4508
|
this.lastModels = [];
|
|
4474
4509
|
this.loadRuntimeToken = null;
|
|
4510
|
+
this.loadReportQueue = Promise.resolve();
|
|
4475
4511
|
this.fastLoadUnsupported = false;
|
|
4476
4512
|
this.nativeActiveJobs = 0;
|
|
4477
4513
|
this.nativeProbeKeys = new Map();
|
|
@@ -4484,6 +4520,9 @@ export class SelfHostedNodeRuntime {
|
|
|
4484
4520
|
this.latencySamplesMs = [];
|
|
4485
4521
|
this.recentFailures = [];
|
|
4486
4522
|
this.lifecyclePollingDisabled = false;
|
|
4523
|
+
this.admissionClosed = false;
|
|
4524
|
+
this.admittedJobs = 0;
|
|
4525
|
+
this.manualRelayOperations = 0;
|
|
4487
4526
|
/**
|
|
4488
4527
|
* The capability snapshot a heartbeat carries, without making the heartbeat
|
|
4489
4528
|
* wait for it.
|
|
@@ -4677,7 +4716,7 @@ export class SelfHostedNodeRuntime {
|
|
|
4677
4716
|
return Math.round(total / this.latencySamplesMs.length);
|
|
4678
4717
|
}
|
|
4679
4718
|
buildLoadTelemetry(input) {
|
|
4680
|
-
const drainMode = this.
|
|
4719
|
+
const drainMode = this.isDraining;
|
|
4681
4720
|
const llmMaxConcurrency = Math.max(1, Math.floor(this.config.maxConcurrentLlmJobs || this.config.maxConcurrentJobs || 1));
|
|
4682
4721
|
const genericMaxConcurrency = Math.max(1, Math.floor(this.config.genericJobMaxConcurrency || 1));
|
|
4683
4722
|
const maxConcurrency = Math.max(1, Math.floor(this.config.maxConcurrentJobs || 1), llmMaxConcurrency, this.config.genericJobsEnabled ? genericMaxConcurrency : 1);
|
|
@@ -5034,7 +5073,7 @@ export class SelfHostedNodeRuntime {
|
|
|
5034
5073
|
generic_jobs_enabled: this.config.genericJobsEnabled,
|
|
5035
5074
|
generic_job_timeout_ms: this.config.genericJobTimeoutMs,
|
|
5036
5075
|
generic_job_max_concurrency: this.config.genericJobMaxConcurrency,
|
|
5037
|
-
drain_mode: this.
|
|
5076
|
+
drain_mode: this.isDraining,
|
|
5038
5077
|
load_reporting_enabled: this.config.loadReportingEnabled !== false,
|
|
5039
5078
|
hardware_telemetry_enabled: this.config.hardwareTelemetryEnabled === true,
|
|
5040
5079
|
expose_all_models: this.config.exposeAllModels,
|
|
@@ -5100,6 +5139,9 @@ export class SelfHostedNodeRuntime {
|
|
|
5100
5139
|
body.max_tokens = job.openai_request.max_tokens;
|
|
5101
5140
|
if (job.openai_request.stop !== undefined)
|
|
5102
5141
|
body.stop = job.openai_request.stop;
|
|
5142
|
+
if (job.openai_request.response_format !== undefined)
|
|
5143
|
+
body.response_format = job.openai_request.response_format;
|
|
5144
|
+
Object.assign(body, nativeReasoningRequest(job.openai_request));
|
|
5103
5145
|
const url = `${baseUrl.replace(/\/+$/, "")}/chat/completions`;
|
|
5104
5146
|
const response = await this.fetchImpl(url, { method: "POST", headers, body: JSON.stringify(body) });
|
|
5105
5147
|
const text = await response.text();
|
|
@@ -5358,6 +5400,61 @@ export class SelfHostedNodeRuntime {
|
|
|
5358
5400
|
body
|
|
5359
5401
|
};
|
|
5360
5402
|
}
|
|
5403
|
+
prepareEmbeddingPassthrough(job, agent) {
|
|
5404
|
+
if (job.policy?.expected_model_digest && agent.modelDigest !== job.policy.expected_model_digest) {
|
|
5405
|
+
throw new SelfHostedPreStartJobError("selected_agent_unavailable", "Embedding model revision changed after admission");
|
|
5406
|
+
}
|
|
5407
|
+
const descriptor = this.generativeOperationForAgent(agent, "embeddings");
|
|
5408
|
+
const baseUrl = optionalText(agent.baseUrl);
|
|
5409
|
+
let endpoint;
|
|
5410
|
+
try {
|
|
5411
|
+
endpoint = new URL(baseUrl || "");
|
|
5412
|
+
}
|
|
5413
|
+
catch {
|
|
5414
|
+
throw new SelfHostedPreStartJobError("selected_agent_unavailable", "embedding runner URL is missing or invalid");
|
|
5415
|
+
}
|
|
5416
|
+
if (!["http:", "https:"].includes(endpoint.protocol) || endpoint.username || endpoint.password || endpoint.search || endpoint.hash) {
|
|
5417
|
+
throw new SelfHostedPreStartJobError("selected_agent_unavailable", "embedding runner URL is invalid");
|
|
5418
|
+
}
|
|
5419
|
+
let body;
|
|
5420
|
+
try {
|
|
5421
|
+
body = validateEmbeddingRequest(job.openai_request, optionalText(agent.model) || job.openai_request.model, descriptor.limits);
|
|
5422
|
+
}
|
|
5423
|
+
catch (error) {
|
|
5424
|
+
throw new SelfHostedPreStartJobError("validation_failed", error instanceof Error ? error.message : "invalid embedding request");
|
|
5425
|
+
}
|
|
5426
|
+
if (Buffer.byteLength(JSON.stringify(body)) > Math.min(descriptor.limits?.maxRequestBytes || 1048576, 1048576)) {
|
|
5427
|
+
throw new SelfHostedPreStartJobError("validation_failed", "embedding request exceeds byte limit");
|
|
5428
|
+
}
|
|
5429
|
+
const headers = {};
|
|
5430
|
+
const bearer = agent.authMode === "bearer" ? optionalText(agent.apiKey)
|
|
5431
|
+
: agent.authMode === "dummy-bearer" ? optionalText(agent.dummyBearerToken) || "local" : undefined;
|
|
5432
|
+
if (bearer)
|
|
5433
|
+
headers.authorization = `Bearer ${bearer}`;
|
|
5434
|
+
for (const [key, value] of Object.entries(agent.headers ?? {}))
|
|
5435
|
+
if (typeof value === "string")
|
|
5436
|
+
headers[key.toLowerCase()] = value;
|
|
5437
|
+
headers["content-type"] = "application/json";
|
|
5438
|
+
return { descriptor, body, headers, url: `${baseUrl.replace(/\/+$/, "")}${descriptor.path}` };
|
|
5439
|
+
}
|
|
5440
|
+
async executeEmbeddingPassthrough(prepared) {
|
|
5441
|
+
const controller = new AbortController();
|
|
5442
|
+
const timeout = setTimeout(() => controller.abort(), Math.min(this.config.jobTimeoutMs, 120000));
|
|
5443
|
+
try {
|
|
5444
|
+
const response = await this.fetchImpl(prepared.url, {
|
|
5445
|
+
method: "POST", headers: prepared.headers, body: JSON.stringify(prepared.body), signal: controller.signal,
|
|
5446
|
+
});
|
|
5447
|
+
if (!response.ok) {
|
|
5448
|
+
await response.body?.cancel().catch(() => undefined);
|
|
5449
|
+
throw new Error(`local embeddings runner request failed with status ${response.status}`);
|
|
5450
|
+
}
|
|
5451
|
+
const raw = await readBoundedResponseText(response, Math.min(prepared.descriptor.limits?.maxOutputBytes || 16777216, 16777216), "embedding response exceeds byte limit");
|
|
5452
|
+
return validateEmbeddingResponse(JSON.parse(raw), prepared.body.input.length, prepared.descriptor.limits?.embeddingDimensions ?? prepared.body.dimensions, prepared.body.model);
|
|
5453
|
+
}
|
|
5454
|
+
finally {
|
|
5455
|
+
clearTimeout(timeout);
|
|
5456
|
+
}
|
|
5457
|
+
}
|
|
5361
5458
|
async executeOpenAiGenerativePassthrough(prepared, operation) {
|
|
5362
5459
|
const outputByteLimit = generativeOutputByteLimit(operation, prepared.descriptor.limits?.maxOutputBytes);
|
|
5363
5460
|
const jsonResponseByteLimit = generativeJsonResponseByteLimit(outputByteLimit);
|
|
@@ -5505,6 +5602,21 @@ export class SelfHostedNodeRuntime {
|
|
|
5505
5602
|
return codaliAgent;
|
|
5506
5603
|
}
|
|
5507
5604
|
async executeGenericJob(envelope, options = {}) {
|
|
5605
|
+
if (this.isDraining)
|
|
5606
|
+
throw new SelfHostedPreStartJobError("node_draining", "Node is draining; no new work was admitted.");
|
|
5607
|
+
return this.executePreviouslyAdmittedGenericJob(envelope, options);
|
|
5608
|
+
}
|
|
5609
|
+
/** Host scheduler only: finish work accepted before admission was closed. */
|
|
5610
|
+
async executePreviouslyAdmittedGenericJob(envelope, options = {}) {
|
|
5611
|
+
this.admittedJobs += 1;
|
|
5612
|
+
try {
|
|
5613
|
+
return await this.executeAdmittedGenericJob(envelope, options);
|
|
5614
|
+
}
|
|
5615
|
+
finally {
|
|
5616
|
+
this.admittedJobs -= 1;
|
|
5617
|
+
}
|
|
5618
|
+
}
|
|
5619
|
+
async executeAdmittedGenericJob(envelope, options) {
|
|
5508
5620
|
const startedAt = Date.now();
|
|
5509
5621
|
this.beginExecutionTelemetry("generic_job");
|
|
5510
5622
|
const events = [];
|
|
@@ -5678,12 +5790,26 @@ export class SelfHostedNodeRuntime {
|
|
|
5678
5790
|
}
|
|
5679
5791
|
}
|
|
5680
5792
|
async executeJob(job, options = {}) {
|
|
5793
|
+
if (this.isDraining) {
|
|
5794
|
+
return {
|
|
5795
|
+
job_id: job.job_id, request_id: job.request_id, status: "failed",
|
|
5796
|
+
error: { code: "node_draining", message: "Node is draining; no new work was admitted." }
|
|
5797
|
+
};
|
|
5798
|
+
}
|
|
5799
|
+
return this.executeAdmittedJob(job, options);
|
|
5800
|
+
}
|
|
5801
|
+
async executeAdmittedJob(job, options) {
|
|
5802
|
+
this.admittedJobs += 1;
|
|
5681
5803
|
this.activeRequestIds.add(job.request_id);
|
|
5682
5804
|
try {
|
|
5683
5805
|
return await this.executeTrackedJob(job, options);
|
|
5684
5806
|
}
|
|
5685
5807
|
finally {
|
|
5686
5808
|
this.activeRequestIds.delete(job.request_id);
|
|
5809
|
+
// A product often starts its next stage immediately after this result.
|
|
5810
|
+
// Publish the newly free native slot before the gateway delivers it.
|
|
5811
|
+
await this.reportLoad().catch(() => undefined);
|
|
5812
|
+
this.admittedJobs -= 1;
|
|
5687
5813
|
}
|
|
5688
5814
|
}
|
|
5689
5815
|
async executeTrackedJob(job, options) {
|
|
@@ -5749,6 +5875,9 @@ export class SelfHostedNodeRuntime {
|
|
|
5749
5875
|
throw new SelfHostedPreStartJobError("unsupported_operation", `unsupported self-hosted operation ${optionalText(job.operation) || String(job.operation)}`);
|
|
5750
5876
|
}
|
|
5751
5877
|
if (job.provider === "ollama") {
|
|
5878
|
+
if (Object.keys(nativeReasoningRequest(job.openai_request)).length) {
|
|
5879
|
+
throw new SelfHostedPreStartJobError("unsupported_operation", "Native reasoning options require an OpenAI-compatible runner");
|
|
5880
|
+
}
|
|
5752
5881
|
if (operation !== "chat.completions") {
|
|
5753
5882
|
throw new SelfHostedPreStartJobError("unsupported_operation", `Ollama relay jobs do not support ${operation}`);
|
|
5754
5883
|
}
|
|
@@ -5822,6 +5951,17 @@ export class SelfHostedNodeRuntime {
|
|
|
5822
5951
|
const agent = await this.resolveMcodaAgentForJob(job);
|
|
5823
5952
|
selectedAgent = agent;
|
|
5824
5953
|
this.generativeOperationForAgent(agent, operation);
|
|
5954
|
+
if (operation === "embeddings") {
|
|
5955
|
+
const prepared = this.prepareEmbeddingPassthrough(job, agent);
|
|
5956
|
+
await acknowledgeStarted(agent);
|
|
5957
|
+
await recordProgress({ type: "agent_selected", operation, job_id: job.job_id,
|
|
5958
|
+
request_id: job.request_id, agent_slug: agent.slug, adapter: agent.adapter, local_model: prepared.body.model });
|
|
5959
|
+
const result = await this.executeEmbeddingPassthrough(prepared);
|
|
5960
|
+
this.finishExecutionTelemetry({ executionClass, startedAt, ok: true });
|
|
5961
|
+
return { job_id: job.job_id, request_id: job.request_id, operation, status: "success",
|
|
5962
|
+
openai_response: { ...result, ...(agent.modelDigest ? { embedding_revision: agent.modelDigest } : {}) }, ...(result.usage ? { usage: { ...result.usage, completion_tokens: 0 } } : {}),
|
|
5963
|
+
...(progressEvents.length ? { progress_events: progressEvents } : {}), timing: { local_latency_ms: Date.now() - startedAt } };
|
|
5964
|
+
}
|
|
5825
5965
|
if (operation === "images.generations" ||
|
|
5826
5966
|
operation === "audio.generations" ||
|
|
5827
5967
|
operation === "videos.generations") {
|
|
@@ -5899,6 +6039,7 @@ export class SelfHostedNodeRuntime {
|
|
|
5899
6039
|
attachedMswarmApiKey,
|
|
5900
6040
|
policy: buildCodaliPolicy(job),
|
|
5901
6041
|
temperature: job.openai_request.temperature,
|
|
6042
|
+
nativeReasoning: nativeReasoningRequest(job.openai_request),
|
|
5902
6043
|
responseFormat: isRecord(job.openai_request.response_format)
|
|
5903
6044
|
? job.openai_request.response_format
|
|
5904
6045
|
: null,
|
|
@@ -5976,6 +6117,7 @@ export class SelfHostedNodeRuntime {
|
|
|
5976
6117
|
agent_slug: response.metadata.agent_slug,
|
|
5977
6118
|
runtime: response.metadata.runtime,
|
|
5978
6119
|
codali_run_id: response.metadata.run_id,
|
|
6120
|
+
orchestration: response.metadata.orchestration,
|
|
5979
6121
|
tool_calls_executed: response.metadata.tool_calls_executed,
|
|
5980
6122
|
called_tools: response.metadata.called_tools,
|
|
5981
6123
|
dynamic_tools_considered: response.metadata.dynamic_tools_considered,
|
|
@@ -6057,14 +6199,15 @@ export class SelfHostedNodeRuntime {
|
|
|
6057
6199
|
async refreshNativeLoad() {
|
|
6058
6200
|
const runners = new Map();
|
|
6059
6201
|
for (const model of this.lastModels) {
|
|
6202
|
+
const isStrata = model.runner_kind === "strata" || model.adapter === "strata-local";
|
|
6060
6203
|
if (model.exposed === false || !model.base_url ||
|
|
6061
|
-
(model.runner_kind !== "llama-cpp" && model.adapter !== "llama-cpp-local"))
|
|
6204
|
+
(!isStrata && model.runner_kind !== "llama-cpp" && model.adapter !== "llama-cpp-local"))
|
|
6062
6205
|
continue;
|
|
6063
6206
|
try {
|
|
6064
6207
|
const url = new URL(model.base_url);
|
|
6065
6208
|
if (!["127.0.0.1", "localhost", "[::1]"].includes(url.hostname))
|
|
6066
6209
|
continue;
|
|
6067
|
-
const endpoint = new URL("/slots", url).toString();
|
|
6210
|
+
const endpoint = new URL(isStrata ? "/v1/status" : "/slots", url).toString();
|
|
6068
6211
|
const models = runners.get(endpoint) || [];
|
|
6069
6212
|
models.push(model);
|
|
6070
6213
|
runners.set(endpoint, models);
|
|
@@ -6089,12 +6232,30 @@ export class SelfHostedNodeRuntime {
|
|
|
6089
6232
|
}
|
|
6090
6233
|
const response = await this.fetchImpl(endpoint, { signal: AbortSignal.timeout(1500),
|
|
6091
6234
|
...(apiKey ? { headers: { authorization: `Bearer ${apiKey}` } } : {}) });
|
|
6092
|
-
|
|
6093
|
-
|
|
6235
|
+
const isStrata = new URL(endpoint).pathname === "/v1/status";
|
|
6236
|
+
// llama.cpp slot introspection is optional. Strata status also proves the model is loaded.
|
|
6237
|
+
if (!isStrata && [401, 403, 404].includes(response.status))
|
|
6094
6238
|
return;
|
|
6095
6239
|
if (!response.ok)
|
|
6096
6240
|
throw new Error("runner_load_unavailable");
|
|
6097
6241
|
const slots = await response.json();
|
|
6242
|
+
if (isStrata) {
|
|
6243
|
+
const concurrency = isRecord(slots) && isRecord(slots.concurrency) ? slots.concurrency.serving : undefined;
|
|
6244
|
+
const inFlight = isRecord(slots) && isRecord(slots.activity) ? slots.activity.in_flight : undefined;
|
|
6245
|
+
if (!isRecord(slots) || slots.loaded !== true ||
|
|
6246
|
+
typeof concurrency !== "number" || !Number.isSafeInteger(concurrency) || concurrency < 1 ||
|
|
6247
|
+
typeof inFlight !== "number" || !Number.isSafeInteger(inFlight) || inFlight < 0) {
|
|
6248
|
+
throw new Error("runner_load_unavailable");
|
|
6249
|
+
}
|
|
6250
|
+
const processing = Math.min(concurrency, inFlight);
|
|
6251
|
+
active += processing;
|
|
6252
|
+
const capacity = { max_concurrency: concurrency, active_jobs: processing,
|
|
6253
|
+
queued_jobs: Math.max(0, inFlight - concurrency), free_slots: Math.max(0, concurrency - inFlight),
|
|
6254
|
+
pool: `runner:${createHash("sha256").update(endpoint).digest("hex").slice(0, 16)}` };
|
|
6255
|
+
for (const model of models)
|
|
6256
|
+
modelCapacity[model.model_id || model.model || model.name] = capacity;
|
|
6257
|
+
return;
|
|
6258
|
+
}
|
|
6098
6259
|
if (!Array.isArray(slots))
|
|
6099
6260
|
return;
|
|
6100
6261
|
const processing = slots.filter((slot) => isRecord(slot) && slot.is_processing === true).length;
|
|
@@ -6114,7 +6275,14 @@ export class SelfHostedNodeRuntime {
|
|
|
6114
6275
|
this.nativeModelCapacity = modelCapacity;
|
|
6115
6276
|
this.unavailableModelIds = [...new Set(unavailable)];
|
|
6116
6277
|
}
|
|
6117
|
-
|
|
6278
|
+
reportLoad() {
|
|
6279
|
+
// Serialize probes and writes so an older busy snapshot cannot overwrite
|
|
6280
|
+
// the completion snapshot when the periodic reporter is already running.
|
|
6281
|
+
const pending = this.loadReportQueue.then(() => this.reportLoadSnapshot());
|
|
6282
|
+
this.loadReportQueue = pending.catch(() => undefined);
|
|
6283
|
+
return pending;
|
|
6284
|
+
}
|
|
6285
|
+
async reportLoadSnapshot() {
|
|
6118
6286
|
if (this.config.loadReportingEnabled === false || this.fastLoadUnsupported || !this.loadRuntimeToken)
|
|
6119
6287
|
return;
|
|
6120
6288
|
await this.refreshNativeLoad();
|
|
@@ -6210,7 +6378,7 @@ export class SelfHostedNodeRuntime {
|
|
|
6210
6378
|
relay_mode: this.config.relayMode || "outbound",
|
|
6211
6379
|
load_reporting_enabled: loadReportingEnabled,
|
|
6212
6380
|
hardware_telemetry_enabled: this.config.hardwareTelemetryEnabled === true,
|
|
6213
|
-
drain_mode: this.
|
|
6381
|
+
drain_mode: this.isDraining,
|
|
6214
6382
|
...(lifecycleProtocolDegraded
|
|
6215
6383
|
? {
|
|
6216
6384
|
lifecycle: {
|
|
@@ -6385,7 +6553,9 @@ export class SelfHostedNodeRuntime {
|
|
|
6385
6553
|
streamEventForwardingFailed = true;
|
|
6386
6554
|
}
|
|
6387
6555
|
};
|
|
6388
|
-
|
|
6556
|
+
// A claim returned by an outstanding poll already belongs to this node,
|
|
6557
|
+
// including a poll that finishes after drain began. Never discard it.
|
|
6558
|
+
let result = await this.executeAdmittedJob(job, {
|
|
6389
6559
|
attachedMswarmApiKey: claim.attachedMswarmApiKey,
|
|
6390
6560
|
onStarted: async (event) => {
|
|
6391
6561
|
try {
|
|
@@ -6473,11 +6643,19 @@ export class SelfHostedNodeRuntime {
|
|
|
6473
6643
|
return { executed: true, job_id: job.job_id, status: result.status };
|
|
6474
6644
|
}
|
|
6475
6645
|
async pollAndExecuteJob(waitMs = DEFAULT_JOB_POLL_WAIT_MS) {
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6646
|
+
if (this.isDraining)
|
|
6647
|
+
return { executed: false };
|
|
6648
|
+
this.manualRelayOperations += 1;
|
|
6649
|
+
try {
|
|
6650
|
+
const polled = await this.pollRelayJob(waitMs);
|
|
6651
|
+
if (!polled.claim) {
|
|
6652
|
+
return { executed: false, ...(polled.status ? { status: polled.status } : {}) };
|
|
6653
|
+
}
|
|
6654
|
+
return await this.executeRelayJobClaim(polled.claim);
|
|
6655
|
+
}
|
|
6656
|
+
finally {
|
|
6657
|
+
this.manualRelayOperations -= 1;
|
|
6479
6658
|
}
|
|
6480
|
-
return this.executeRelayJobClaim(polled.claim);
|
|
6481
6659
|
}
|
|
6482
6660
|
async doctor() {
|
|
6483
6661
|
const checks = [];
|
|
@@ -6591,6 +6769,7 @@ export class SelfHostedNodeRuntime {
|
|
|
6591
6769
|
const currentRelayRetryDelayMs = () => Math.max(pollRetryDelayMs(relayPollFailureStreak), pollRetryDelayMs(relayExecutionFailureStreak));
|
|
6592
6770
|
const schedulePoll = (delayMs) => {
|
|
6593
6771
|
if (stopped ||
|
|
6772
|
+
this.isDraining ||
|
|
6594
6773
|
polling ||
|
|
6595
6774
|
revoked ||
|
|
6596
6775
|
this.lifecyclePollingDisabled ||
|
|
@@ -6612,6 +6791,7 @@ export class SelfHostedNodeRuntime {
|
|
|
6612
6791
|
};
|
|
6613
6792
|
const poll = () => {
|
|
6614
6793
|
if (stopped ||
|
|
6794
|
+
this.isDraining ||
|
|
6615
6795
|
polling ||
|
|
6616
6796
|
revoked ||
|
|
6617
6797
|
this.lifecyclePollingDisabled ||
|
|
@@ -6710,7 +6890,27 @@ export class SelfHostedNodeRuntime {
|
|
|
6710
6890
|
schedule();
|
|
6711
6891
|
schedulePoll(0);
|
|
6712
6892
|
});
|
|
6713
|
-
return {
|
|
6893
|
+
return {
|
|
6894
|
+
stop: halt,
|
|
6895
|
+
drain: async ({ timeoutMs } = {}) => {
|
|
6896
|
+
if (timeoutMs !== undefined && (!Number.isFinite(timeoutMs) || timeoutMs < 0)) {
|
|
6897
|
+
throw new Error("drain timeoutMs must be a finite non-negative number");
|
|
6898
|
+
}
|
|
6899
|
+
this.beginDrain();
|
|
6900
|
+
clearPollTimer();
|
|
6901
|
+
// Keep regular heartbeats alive during a drain and publish zero free
|
|
6902
|
+
// slots promptly. Failure to report cannot reopen local admission.
|
|
6903
|
+
void this.reportLoad().catch(() => undefined);
|
|
6904
|
+
const deadline = timeoutMs === undefined ? Infinity : Date.now() + timeoutMs;
|
|
6905
|
+
while (polling || activeRelayExecutions > 0 || this.admittedJobs > 0 || this.queuedGenericJobs > 0 || this.manualRelayOperations > 0) {
|
|
6906
|
+
if (Date.now() >= deadline)
|
|
6907
|
+
return false;
|
|
6908
|
+
await sleep(Math.min(25, Math.max(1, deadline - Date.now())));
|
|
6909
|
+
}
|
|
6910
|
+
await this.reportLoad().catch(() => undefined);
|
|
6911
|
+
return true;
|
|
6912
|
+
}
|
|
6913
|
+
};
|
|
6714
6914
|
}
|
|
6715
6915
|
}
|
|
6716
6916
|
//# sourceMappingURL=runtime.js.map
|