@mcoda/mswarm 0.1.134 → 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 +40 -0
- package/dist/codali-executor.d.ts +63 -0
- package/dist/codali-executor.d.ts.map +1 -1
- package/dist/codali-executor.js +78 -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 +23 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +181 -15
- 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 +11 -1
- 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/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 +91 -50
- package/dist/vendor/codali/providers/ProviderTypes.d.ts +12 -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 +28 -0
- package/dist/vendor/codali/runtime/CodaliRuntime.d.ts.map +1 -1
- package/dist/vendor/codali/runtime/CodaliRuntime.js +69 -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 +7 -0
- package/dist/vendor/codali/runtime/Runner.d.ts.map +1 -1
- package/dist/vendor/codali/runtime/Runner.js +215 -171
- 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
|
/**
|
|
@@ -209,6 +210,9 @@ const LOCAL_OPENAI_COMPATIBLE_ADAPTERS = new Set([
|
|
|
209
210
|
]);
|
|
210
211
|
const SECRET_LOCAL_RUNNER_HEADER_KEYS = new Set(["authorization", "proxy-authorization", "x-api-key", "api-key"]);
|
|
211
212
|
const RESERVED_LOCAL_RUNNER_EXTRA_BODY_KEYS = new Set([
|
|
213
|
+
"input",
|
|
214
|
+
"dimensions",
|
|
215
|
+
"encoding_format",
|
|
212
216
|
"model",
|
|
213
217
|
"messages",
|
|
214
218
|
"prompt",
|
|
@@ -230,6 +234,7 @@ const RESERVED_LOCAL_RUNNER_EXTRA_BODY_KEYS = new Set([
|
|
|
230
234
|
"temperature"
|
|
231
235
|
]);
|
|
232
236
|
const REQUIRED_GENERATIVE_OPERATION_REQUEST_PARAMETERS = {
|
|
237
|
+
embeddings: ["model", "input", "encoding_format"],
|
|
233
238
|
"chat.completions": ["model", "messages"],
|
|
234
239
|
"images.generations": ["model", "prompt", "response_format"],
|
|
235
240
|
"audio.generations": ["model", "prompt", "response_format"],
|
|
@@ -330,7 +335,7 @@ function isRecord(value) {
|
|
|
330
335
|
}
|
|
331
336
|
export function normalizeSelfHostedGenerativeOperationName(value) {
|
|
332
337
|
const normalized = optionalText(value);
|
|
333
|
-
return normalized === "chat.completions" ||
|
|
338
|
+
return normalized === "embeddings" || normalized === "chat.completions" ||
|
|
334
339
|
normalized === "images.generations" ||
|
|
335
340
|
normalized === "audio.generations" ||
|
|
336
341
|
normalized === "videos.generations"
|
|
@@ -371,7 +376,7 @@ function normalizeGenerativeOperationDescriptor(value) {
|
|
|
371
376
|
]));
|
|
372
377
|
const responseFormats = normalized.responseFormats?.length
|
|
373
378
|
? normalized.responseFormats
|
|
374
|
-
: operation === "chat.completions"
|
|
379
|
+
: operation === "embeddings" ? ["float"] : operation === "chat.completions"
|
|
375
380
|
? undefined
|
|
376
381
|
: operation === "images.generations"
|
|
377
382
|
? ["b64_json"]
|
|
@@ -422,6 +427,8 @@ function normalizeGenerativeOperations(value) {
|
|
|
422
427
|
function inferGenerativeModalities(operations, direction) {
|
|
423
428
|
const modalities = new Set();
|
|
424
429
|
for (const descriptor of operations) {
|
|
430
|
+
if (direction === "output" && descriptor.operation === "embeddings")
|
|
431
|
+
modalities.add("embedding");
|
|
425
432
|
if (direction === "input" || descriptor.operation === "chat.completions") {
|
|
426
433
|
modalities.add("text");
|
|
427
434
|
}
|
|
@@ -440,6 +447,10 @@ function inferGenerativeModalities(operations, direction) {
|
|
|
440
447
|
function generativeOperationCatalogInput(descriptor) {
|
|
441
448
|
const limits = descriptor.limits
|
|
442
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 } : {}),
|
|
443
454
|
...(descriptor.limits.maxRequestBytes !== undefined
|
|
444
455
|
? { max_request_bytes: descriptor.limits.maxRequestBytes }
|
|
445
456
|
: {}),
|
|
@@ -621,6 +632,7 @@ function normalizeMcodaLocalRunnerConfig(adapter, config) {
|
|
|
621
632
|
inputModalities: normalizeGenerativeModalities(merged.inputModalities ?? merged.input_modalities),
|
|
622
633
|
outputModalities: normalizeGenerativeModalities(merged.outputModalities ?? merged.output_modalities),
|
|
623
634
|
operations: normalizeGenerativeOperations(merged.operations),
|
|
635
|
+
embedding: merged.embedding === undefined || merged.embedding === null ? undefined : validateEmbeddingPreprocessing(merged.embedding),
|
|
624
636
|
publicModelId: readConfigString(merged, ["publicModelId", "public_model_id"])
|
|
625
637
|
};
|
|
626
638
|
}
|
|
@@ -1232,12 +1244,12 @@ export function agentRunsOnThisNode(agent) {
|
|
|
1232
1244
|
return false;
|
|
1233
1245
|
}
|
|
1234
1246
|
}
|
|
1235
|
-
function isAgentExposed(agentSlug, defaultModel, bestUsage, config) {
|
|
1247
|
+
function isAgentExposed(agentSlug, defaultModel, bestUsage, config, supportsEmbeddings = false) {
|
|
1236
1248
|
const identities = [agentSlug, defaultModel].filter((value) => Boolean(value));
|
|
1237
1249
|
if (identities.some((identity) => config.modelBlocklist.includes(identity))) {
|
|
1238
1250
|
return false;
|
|
1239
1251
|
}
|
|
1240
|
-
if (isEmbeddingUsage(bestUsage) || identities.some((identity) => isEmbeddingModel(identity))) {
|
|
1252
|
+
if (!supportsEmbeddings && (isEmbeddingUsage(bestUsage) || identities.some((identity) => isEmbeddingModel(identity)))) {
|
|
1241
1253
|
return false;
|
|
1242
1254
|
}
|
|
1243
1255
|
if (config.modelAllowlist.length > 0) {
|
|
@@ -1504,6 +1516,8 @@ Wants=network-online.target
|
|
|
1504
1516
|
Type=simple
|
|
1505
1517
|
ExecStart=${quoteSystemdValue(input.wrapperPath)}
|
|
1506
1518
|
Restart=always
|
|
1519
|
+
TimeoutStopSec=infinity
|
|
1520
|
+
KillMode=mixed
|
|
1507
1521
|
RestartSec=5
|
|
1508
1522
|
StandardOutput=append:${input.logPath}
|
|
1509
1523
|
StandardError=append:${input.errorLogPath}
|
|
@@ -2099,6 +2113,8 @@ export function mapMcodaAgentToSelfHostedModel(agent, config) {
|
|
|
2099
2113
|
model_id: publicModelId || model,
|
|
2100
2114
|
public_model_id: publicModelId,
|
|
2101
2115
|
upstream_model: model,
|
|
2116
|
+
digest: optionalText(legacyConfig.modelDigest),
|
|
2117
|
+
embedding: localRunner?.embedding,
|
|
2102
2118
|
base_url: localRunner?.baseUrl ?? legacyNativeBase ?? undefined,
|
|
2103
2119
|
runner_kind: localRunner?.generativeRunnerKind ?? localRunner?.runnerKind ?? (legacyNativeBase ? "llama-cpp" : undefined),
|
|
2104
2120
|
auth_mode: localRunner?.authMode ?? (legacyNativeBase ? normalizeLocalRunnerAuthMode(legacyConfig.authMode) : undefined),
|
|
@@ -2113,10 +2129,13 @@ export function mapMcodaAgentToSelfHostedModel(agent, config) {
|
|
|
2113
2129
|
supports_vision: supportsVision,
|
|
2114
2130
|
supports_json_schema: localRunner?.supportsJsonSchema,
|
|
2115
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,
|
|
2116
2135
|
openai_compatible: openaiCompatible,
|
|
2117
2136
|
exposed: healthStatus !== "blocked" &&
|
|
2118
2137
|
agentRunsOnThisNode(agent) &&
|
|
2119
|
-
isAgentExposed(slug, defaultModel, bestUsage, config),
|
|
2138
|
+
isAgentExposed(slug, defaultModel, bestUsage, config, operations.some(entry => entry.operation === "embeddings")),
|
|
2120
2139
|
best_usage: bestUsage,
|
|
2121
2140
|
capabilities,
|
|
2122
2141
|
cost_per_million: optionalNumber(agent.costPerMillion, agent.cost_per_million),
|
|
@@ -2469,6 +2488,8 @@ function mapMcodaAgentToCodaliAgent(agent, fallbackSlug) {
|
|
|
2469
2488
|
const generativeOperations = localRunner?.operations ??
|
|
2470
2489
|
[defaultGenerativeOperationDescriptor("chat.completions", localRunner ? "/chat/completions" : undefined)];
|
|
2471
2490
|
return {
|
|
2491
|
+
modelDigest: configText(config, "modelDigest"),
|
|
2492
|
+
orchestrationConfigPath: configText(config, "codaliOrchestrationPath"),
|
|
2472
2493
|
slug: optionalText(agent.slug) || fallbackSlug,
|
|
2473
2494
|
adapter,
|
|
2474
2495
|
provider: resolveCodaliProviderForAgent(agent),
|
|
@@ -2495,6 +2516,10 @@ function mapMcodaAgentToCodaliAgent(agent, fallbackSlug) {
|
|
|
2495
2516
|
supportsJsonSchema: localRunner?.supportsJsonSchema,
|
|
2496
2517
|
supportsGbnf: localRunner?.supportsGbnf,
|
|
2497
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,
|
|
2498
2523
|
contextWindow: optionalNumber(agent.contextWindow, agent.context_window) ?? undefined,
|
|
2499
2524
|
maxOutputTokens: optionalNumber(agent.maxOutputTokens, agent.max_output_tokens) ?? undefined,
|
|
2500
2525
|
generativeOperations,
|
|
@@ -4471,6 +4496,12 @@ export class MswarmSelfHostedNodeClient {
|
|
|
4471
4496
|
}
|
|
4472
4497
|
}
|
|
4473
4498
|
export class SelfHostedNodeRuntime {
|
|
4499
|
+
get isDraining() {
|
|
4500
|
+
return this.admissionClosed || this.config.drainMode === true;
|
|
4501
|
+
}
|
|
4502
|
+
beginDrain() {
|
|
4503
|
+
this.admissionClosed = true;
|
|
4504
|
+
}
|
|
4474
4505
|
constructor(config, deps) {
|
|
4475
4506
|
this.activeChatJobs = 0;
|
|
4476
4507
|
this.activeRequestIds = new Set();
|
|
@@ -4489,6 +4520,9 @@ export class SelfHostedNodeRuntime {
|
|
|
4489
4520
|
this.latencySamplesMs = [];
|
|
4490
4521
|
this.recentFailures = [];
|
|
4491
4522
|
this.lifecyclePollingDisabled = false;
|
|
4523
|
+
this.admissionClosed = false;
|
|
4524
|
+
this.admittedJobs = 0;
|
|
4525
|
+
this.manualRelayOperations = 0;
|
|
4492
4526
|
/**
|
|
4493
4527
|
* The capability snapshot a heartbeat carries, without making the heartbeat
|
|
4494
4528
|
* wait for it.
|
|
@@ -4682,7 +4716,7 @@ export class SelfHostedNodeRuntime {
|
|
|
4682
4716
|
return Math.round(total / this.latencySamplesMs.length);
|
|
4683
4717
|
}
|
|
4684
4718
|
buildLoadTelemetry(input) {
|
|
4685
|
-
const drainMode = this.
|
|
4719
|
+
const drainMode = this.isDraining;
|
|
4686
4720
|
const llmMaxConcurrency = Math.max(1, Math.floor(this.config.maxConcurrentLlmJobs || this.config.maxConcurrentJobs || 1));
|
|
4687
4721
|
const genericMaxConcurrency = Math.max(1, Math.floor(this.config.genericJobMaxConcurrency || 1));
|
|
4688
4722
|
const maxConcurrency = Math.max(1, Math.floor(this.config.maxConcurrentJobs || 1), llmMaxConcurrency, this.config.genericJobsEnabled ? genericMaxConcurrency : 1);
|
|
@@ -5039,7 +5073,7 @@ export class SelfHostedNodeRuntime {
|
|
|
5039
5073
|
generic_jobs_enabled: this.config.genericJobsEnabled,
|
|
5040
5074
|
generic_job_timeout_ms: this.config.genericJobTimeoutMs,
|
|
5041
5075
|
generic_job_max_concurrency: this.config.genericJobMaxConcurrency,
|
|
5042
|
-
drain_mode: this.
|
|
5076
|
+
drain_mode: this.isDraining,
|
|
5043
5077
|
load_reporting_enabled: this.config.loadReportingEnabled !== false,
|
|
5044
5078
|
hardware_telemetry_enabled: this.config.hardwareTelemetryEnabled === true,
|
|
5045
5079
|
expose_all_models: this.config.exposeAllModels,
|
|
@@ -5105,6 +5139,9 @@ export class SelfHostedNodeRuntime {
|
|
|
5105
5139
|
body.max_tokens = job.openai_request.max_tokens;
|
|
5106
5140
|
if (job.openai_request.stop !== undefined)
|
|
5107
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));
|
|
5108
5145
|
const url = `${baseUrl.replace(/\/+$/, "")}/chat/completions`;
|
|
5109
5146
|
const response = await this.fetchImpl(url, { method: "POST", headers, body: JSON.stringify(body) });
|
|
5110
5147
|
const text = await response.text();
|
|
@@ -5363,6 +5400,61 @@ export class SelfHostedNodeRuntime {
|
|
|
5363
5400
|
body
|
|
5364
5401
|
};
|
|
5365
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
|
+
}
|
|
5366
5458
|
async executeOpenAiGenerativePassthrough(prepared, operation) {
|
|
5367
5459
|
const outputByteLimit = generativeOutputByteLimit(operation, prepared.descriptor.limits?.maxOutputBytes);
|
|
5368
5460
|
const jsonResponseByteLimit = generativeJsonResponseByteLimit(outputByteLimit);
|
|
@@ -5510,6 +5602,21 @@ export class SelfHostedNodeRuntime {
|
|
|
5510
5602
|
return codaliAgent;
|
|
5511
5603
|
}
|
|
5512
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) {
|
|
5513
5620
|
const startedAt = Date.now();
|
|
5514
5621
|
this.beginExecutionTelemetry("generic_job");
|
|
5515
5622
|
const events = [];
|
|
@@ -5683,6 +5790,16 @@ export class SelfHostedNodeRuntime {
|
|
|
5683
5790
|
}
|
|
5684
5791
|
}
|
|
5685
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;
|
|
5686
5803
|
this.activeRequestIds.add(job.request_id);
|
|
5687
5804
|
try {
|
|
5688
5805
|
return await this.executeTrackedJob(job, options);
|
|
@@ -5692,6 +5809,7 @@ export class SelfHostedNodeRuntime {
|
|
|
5692
5809
|
// A product often starts its next stage immediately after this result.
|
|
5693
5810
|
// Publish the newly free native slot before the gateway delivers it.
|
|
5694
5811
|
await this.reportLoad().catch(() => undefined);
|
|
5812
|
+
this.admittedJobs -= 1;
|
|
5695
5813
|
}
|
|
5696
5814
|
}
|
|
5697
5815
|
async executeTrackedJob(job, options) {
|
|
@@ -5757,6 +5875,9 @@ export class SelfHostedNodeRuntime {
|
|
|
5757
5875
|
throw new SelfHostedPreStartJobError("unsupported_operation", `unsupported self-hosted operation ${optionalText(job.operation) || String(job.operation)}`);
|
|
5758
5876
|
}
|
|
5759
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
|
+
}
|
|
5760
5881
|
if (operation !== "chat.completions") {
|
|
5761
5882
|
throw new SelfHostedPreStartJobError("unsupported_operation", `Ollama relay jobs do not support ${operation}`);
|
|
5762
5883
|
}
|
|
@@ -5830,6 +5951,17 @@ export class SelfHostedNodeRuntime {
|
|
|
5830
5951
|
const agent = await this.resolveMcodaAgentForJob(job);
|
|
5831
5952
|
selectedAgent = agent;
|
|
5832
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
|
+
}
|
|
5833
5965
|
if (operation === "images.generations" ||
|
|
5834
5966
|
operation === "audio.generations" ||
|
|
5835
5967
|
operation === "videos.generations") {
|
|
@@ -5907,6 +6039,7 @@ export class SelfHostedNodeRuntime {
|
|
|
5907
6039
|
attachedMswarmApiKey,
|
|
5908
6040
|
policy: buildCodaliPolicy(job),
|
|
5909
6041
|
temperature: job.openai_request.temperature,
|
|
6042
|
+
nativeReasoning: nativeReasoningRequest(job.openai_request),
|
|
5910
6043
|
responseFormat: isRecord(job.openai_request.response_format)
|
|
5911
6044
|
? job.openai_request.response_format
|
|
5912
6045
|
: null,
|
|
@@ -5984,6 +6117,7 @@ export class SelfHostedNodeRuntime {
|
|
|
5984
6117
|
agent_slug: response.metadata.agent_slug,
|
|
5985
6118
|
runtime: response.metadata.runtime,
|
|
5986
6119
|
codali_run_id: response.metadata.run_id,
|
|
6120
|
+
orchestration: response.metadata.orchestration,
|
|
5987
6121
|
tool_calls_executed: response.metadata.tool_calls_executed,
|
|
5988
6122
|
called_tools: response.metadata.called_tools,
|
|
5989
6123
|
dynamic_tools_considered: response.metadata.dynamic_tools_considered,
|
|
@@ -6244,7 +6378,7 @@ export class SelfHostedNodeRuntime {
|
|
|
6244
6378
|
relay_mode: this.config.relayMode || "outbound",
|
|
6245
6379
|
load_reporting_enabled: loadReportingEnabled,
|
|
6246
6380
|
hardware_telemetry_enabled: this.config.hardwareTelemetryEnabled === true,
|
|
6247
|
-
drain_mode: this.
|
|
6381
|
+
drain_mode: this.isDraining,
|
|
6248
6382
|
...(lifecycleProtocolDegraded
|
|
6249
6383
|
? {
|
|
6250
6384
|
lifecycle: {
|
|
@@ -6419,7 +6553,9 @@ export class SelfHostedNodeRuntime {
|
|
|
6419
6553
|
streamEventForwardingFailed = true;
|
|
6420
6554
|
}
|
|
6421
6555
|
};
|
|
6422
|
-
|
|
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, {
|
|
6423
6559
|
attachedMswarmApiKey: claim.attachedMswarmApiKey,
|
|
6424
6560
|
onStarted: async (event) => {
|
|
6425
6561
|
try {
|
|
@@ -6507,11 +6643,19 @@ export class SelfHostedNodeRuntime {
|
|
|
6507
6643
|
return { executed: true, job_id: job.job_id, status: result.status };
|
|
6508
6644
|
}
|
|
6509
6645
|
async pollAndExecuteJob(waitMs = DEFAULT_JOB_POLL_WAIT_MS) {
|
|
6510
|
-
|
|
6511
|
-
|
|
6512
|
-
|
|
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;
|
|
6513
6658
|
}
|
|
6514
|
-
return this.executeRelayJobClaim(polled.claim);
|
|
6515
6659
|
}
|
|
6516
6660
|
async doctor() {
|
|
6517
6661
|
const checks = [];
|
|
@@ -6625,6 +6769,7 @@ export class SelfHostedNodeRuntime {
|
|
|
6625
6769
|
const currentRelayRetryDelayMs = () => Math.max(pollRetryDelayMs(relayPollFailureStreak), pollRetryDelayMs(relayExecutionFailureStreak));
|
|
6626
6770
|
const schedulePoll = (delayMs) => {
|
|
6627
6771
|
if (stopped ||
|
|
6772
|
+
this.isDraining ||
|
|
6628
6773
|
polling ||
|
|
6629
6774
|
revoked ||
|
|
6630
6775
|
this.lifecyclePollingDisabled ||
|
|
@@ -6646,6 +6791,7 @@ export class SelfHostedNodeRuntime {
|
|
|
6646
6791
|
};
|
|
6647
6792
|
const poll = () => {
|
|
6648
6793
|
if (stopped ||
|
|
6794
|
+
this.isDraining ||
|
|
6649
6795
|
polling ||
|
|
6650
6796
|
revoked ||
|
|
6651
6797
|
this.lifecyclePollingDisabled ||
|
|
@@ -6744,7 +6890,27 @@ export class SelfHostedNodeRuntime {
|
|
|
6744
6890
|
schedule();
|
|
6745
6891
|
schedulePoll(0);
|
|
6746
6892
|
});
|
|
6747
|
-
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
|
+
};
|
|
6748
6914
|
}
|
|
6749
6915
|
}
|
|
6750
6916
|
//# sourceMappingURL=runtime.js.map
|