dsh-modellix 0.2.0 → 0.2.1

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/lib/index.d.ts CHANGED
@@ -555,11 +555,14 @@ declare class MediaUploadClient {
555
555
  declare function prepareMediaUploadFromSession(agent: Agent | undefined, attachmentId: string, signal?: AbortSignal): Promise<PreparedMediaUpload>;
556
556
  declare function prepareMediaUploadFromPath(cwd: string | undefined, inputPath: string): Promise<PreparedMediaUpload>;
557
557
  //#endregion
558
- //#region src/design/schema-ir.d.ts
558
+ //#region src/shared/json-value.d.ts
559
+ /** Lossless JSON values shared across Harness versions. */
559
560
  type JsonPrimitive = null | boolean | number | string;
560
- type JsonValue = JsonPrimitive | readonly JsonValue[] | {
561
- readonly [key: string]: JsonValue;
561
+ type JsonValue = JsonPrimitive | JsonValue[] | {
562
+ [key: string]: JsonValue;
562
563
  };
564
+ //#endregion
565
+ //#region src/design/schema-ir.d.ts
563
566
  type UiFieldKind = "string" | "number" | "integer" | "boolean" | "object" | "array" | "media" | "unknown";
564
567
  type UiMediaKind = "image" | "video" | "audio";
565
568
  interface UiConstraints {
@@ -1100,6 +1103,7 @@ declare class ModellixRuntime {
1100
1103
  private enqueueDesignWrite;
1101
1104
  private rememberDesignModel;
1102
1105
  private syncDesignTools;
1106
+ private syncWebTools;
1103
1107
  private scheduleDesignPoll;
1104
1108
  }
1105
1109
  //#endregion
@@ -1445,5 +1449,5 @@ interface Config {}
1445
1449
  declare const Config: z<Config>;
1446
1450
  declare function apply(ctx: Context): Promise<void>;
1447
1451
  //#endregion
1448
- export { AUTHENTICATED_CATALOG_URL, ApprovedHttpRequest, AvailableDesignResult, BeginLlmMaterializationInput, BeginOnboardingSaveInput, CURRENT_CONFIG_SCHEMA_VERSION, CacheEntry, CachePort, ClockPort, Config, CredentialBroker, CredentialBrokerOptions, CredentialDescriptor, CredentialEpochConflictError, CredentialMutationCoordinator, CredentialMutationResult, CredentialSource, CredentialState, CredentialValidationError, CredentialVerification, DEFAULT_DESIGN_WAL_KEY, DEFAULT_RESULT_TTL_MS, DEFAULT_WEB_RESPONSE_BYTES, DEFAULT_WEB_SEARCH_MAX_RESULTS, DESIGN_PLANNER_ENDPOINT, DESIGN_PLANNER_MODEL, DesignConfig, DesignError, DesignErrorCode, DesignHostController, DesignHostControllerOptions, DesignLogEvent, DesignLogLevel, DesignMediaCategory, DesignModelSummary, DesignPlannerClient, DesignPlannerClientOptions, DesignPlannerRequest, DesignPlannerResult, DesignPollDiagnosticCode, DesignSchemaIR, DesignSnapshotWire, DesignTaskRecord, DesignTaskRepository, DesignTaskRepositoryOptions, DesignTaskState, DesignToolController, DesignWalEvent, EMPTY_LLM_ROUTE_LEDGER, ExactParameterPatch, FetchPort, HarnessCredentialInfo, HarnessCredentialPort, HeaderRecord, HeaderValue, HttpMethod, HttpPolicyError, HttpRequestPolicyInput, HttpResponseBoundaryError, HttpRetryFailure, InvalidCredentialEpoch, JsonPrimitive, JsonValue, LlmCatalogCache, LlmCatalogCacheOptions, LlmCatalogClient, LlmCatalogClientOptions, LlmCatalogRequestError, LlmConfig, LlmCredentialSnapshot, LlmInterruptedMaterializationEvidence, LlmInterruptedMaterializationResult, LlmMaterializationConflictError, LlmMaterializationReceipt, LlmMaterializationRecovery, LlmMaterializationRollbackError, LlmOwnedEntry, LlmOwnershipConfig, LlmPreparedMaterialization, LlmRegistryBackreadError, LlmRegistryReader, LlmRegistryVerificationOptions, LlmRouteConflictError, LlmRouteLedger, LlmRouteOwnership, LlmRouteOwnershipConfig, LlmRouteOwnershipEntry, LlmSettingsMaterializer, LlmSettingsPort, LoggerPort, MAX_WEB_QUERY_CHARS, MAX_WEB_SEARCH_RESULTS, MAX_WEB_URL_CHARS, MODELLIX_CREDENTIAL_REF, MODELLIX_LLM_BASE_URL, MODELLIX_LLM_MODELS_URL, MODELLIX_LLM_PROVENANCE_FIELD, MODELLIX_LLM_PROVIDER_ID, MODELLIX_MEDIA_GENERATE_TOOL, MODELLIX_MEDIA_GET_RESULT_TOOL, MODELLIX_MEDIA_LIST_TOOL, MODELLIX_MEDIA_PREPARE_TOOL, MODELLIX_MEDIA_SCHEMA_TOOL, MODELLIX_MEDIA_UPLOAD_FILE_TOOL, MODELLIX_ORIGINS, MODELLIX_SETTINGS_NAMESPACE, MODELLIX_WEB_FETCH_ENDPOINT, MODELLIX_WEB_FETCH_TOOL, MODELLIX_WEB_PROVIDER_ID, MODELLIX_WEB_SEARCH_ENDPOINT, MODELLIX_WEB_SEARCH_TOOL, MediaUploadClient, MediaUploadInput, MediaUploadRecord, ModelCatalogClient, ModelCatalogClientOptions, ModelCatalogPage, ModelCatalogQuery, ModelSchemaClient, ModelSchemaClientOptions, ModelSchemaDocument, ModellixDesignDomain, ModellixErrorCode, ModellixErrorContext, ModellixErrorContract, ModellixFailure, ModellixLlmCatalog, ModellixLlmModel, ModellixOriginName, ModellixPiAiRoute, ModellixRuntime, ModellixRuntimeState, ModellixService, ModellixWebContractError, ModellixWebCredentialSnapshot, ModellixWebFetchFailedError, ModellixWebFetchProvider, ModellixWebProviderError, ModellixWebProviderOptions, ModellixWebProviders, ModellixWebRegistry, ModellixWebSearchProvider, NaturalLanguagePlan, OnboardingConfig, OnboardingRecoveryAction, OnboardingRecoveryDecision, OnboardingSaveConflictError, OnboardingSavePhase, OnboardingSaveRecovery, OnboardingStatus, PUBLIC_PORTAL_CATALOG_URL, ParsedFetchFailure, ParsedFetchResponse, ParsedFetchSuccess, ParsedSearchResponse, PersistedLlmRouteOwnership, PiAiModelEntry, PluginConfig, PluginSettingsController, PluginSettingsSchema, PluginSettingsSnapshot, PredictionClient, PredictionClientOptions, PredictionResource, PredictionTask, PredictionTaskStatus, PreparedMediaUpload, REDACTED, ReadPredictionInput, RedactedValue, RequestDeadline, RetentionPolicy, RetryDelayInput, RetryOptions, RetrySuccess, RouteMaterializationPlan, RouteRemovalPlan, SchemaDiagnostic, SchemaParserLimits, ServiceId, ServiceToggles, ServicesConfig, SettingsNamespaceDescriptor, SettingsScopeLike, SettingsServiceLike, SleepPort, StaleLlmCatalogError, StoragePort, SubmitPredictionInput, UiConstraints, UiField, UiFieldKind, UiMediaKind, UiVariant, UnauthorizedTransition, UnsupportedConfigVersionError, VerificationTransition, WebConfig, abandonLlmMaterialization, advanceCredentialEpoch, apply, applyCredentialDescriptor, applyExactPatch, applyNaturalLanguage, applyRuntimeUnauthorized, applyVerificationResult, approveHttpRequest, approveRedirect, beginLlmMaterialization, beginOnboardingSave, buildFetchRequest, buildInvocationBody, buildSearchRequest, completeLlmMaterialization, completeOnboardingSave, computeRetryDelay, createCredentialState, createDefaultConfig, createModellixDesignToolDefinitions, createModellixWebProviders, createModellixWebToolDefinitions, deferOnboarding, deriveModellixSessionId, deriveModellixUserId, executeWithRetry, extractAllowedSubmitUrl, getServiceToggles, inject, isAllowedModellixOrigin, isCredentialInvalidError, isPublicHostname, isRetryableError, isRetryableReadFailure, isValidModellixIdentity, markOnboardingCredentialSaved, materializeDefaults, migrateConfig, missingCredentialDescriptor, modellixDesignDomainSpec, name, normalizeCredentialDescriptor, openDesignStorage, parseCatalogPage, parseDesignSchema, parseFetchResponse, parsePredictionTask, parseResources, parseRetryAfter, parseSearchResponse, planLlmRouteMaterialization, planLlmRouteRemoval, prepareMediaUploadFromPath, prepareMediaUploadFromSession, preserveStoredCredentialAfterCandidateFailure, preserveVerificationAfterTransientFailure, readBoundedResponseJson, readBoundedResponseText, reconcileLlmRouteLedgerAfterInterruption, reconcileOnboardingSave, redactForLog, redactHeaders, redactUrl, registerModellixDesignTools, registerModellixWebProviderInstances, registerModellixWebProviders, registerModellixWebTools, replayDesignWal, requestDeadline, retryAfterFromFailure, selectAvailableResults, setServiceToggles, systemClock, systemSleep, toModellixError, validatePublicHttpUrl, validateSubmitEndpoint, verifyLlmRegistryBackread };
1452
+ export { AUTHENTICATED_CATALOG_URL, ApprovedHttpRequest, AvailableDesignResult, BeginLlmMaterializationInput, BeginOnboardingSaveInput, CURRENT_CONFIG_SCHEMA_VERSION, CacheEntry, CachePort, ClockPort, Config, CredentialBroker, CredentialBrokerOptions, CredentialDescriptor, CredentialEpochConflictError, CredentialMutationCoordinator, CredentialMutationResult, CredentialSource, CredentialState, CredentialValidationError, CredentialVerification, DEFAULT_DESIGN_WAL_KEY, DEFAULT_RESULT_TTL_MS, DEFAULT_WEB_RESPONSE_BYTES, DEFAULT_WEB_SEARCH_MAX_RESULTS, DESIGN_PLANNER_ENDPOINT, DESIGN_PLANNER_MODEL, DesignConfig, DesignError, DesignErrorCode, DesignHostController, DesignHostControllerOptions, DesignLogEvent, DesignLogLevel, DesignMediaCategory, DesignModelSummary, DesignPlannerClient, DesignPlannerClientOptions, DesignPlannerRequest, DesignPlannerResult, DesignPollDiagnosticCode, DesignSchemaIR, DesignSnapshotWire, DesignTaskRecord, DesignTaskRepository, DesignTaskRepositoryOptions, DesignTaskState, DesignToolController, DesignWalEvent, EMPTY_LLM_ROUTE_LEDGER, ExactParameterPatch, FetchPort, HarnessCredentialInfo, HarnessCredentialPort, HeaderRecord, HeaderValue, HttpMethod, HttpPolicyError, HttpRequestPolicyInput, HttpResponseBoundaryError, HttpRetryFailure, InvalidCredentialEpoch, type JsonPrimitive, type JsonValue, LlmCatalogCache, LlmCatalogCacheOptions, LlmCatalogClient, LlmCatalogClientOptions, LlmCatalogRequestError, LlmConfig, LlmCredentialSnapshot, LlmInterruptedMaterializationEvidence, LlmInterruptedMaterializationResult, LlmMaterializationConflictError, LlmMaterializationReceipt, LlmMaterializationRecovery, LlmMaterializationRollbackError, LlmOwnedEntry, LlmOwnershipConfig, LlmPreparedMaterialization, LlmRegistryBackreadError, LlmRegistryReader, LlmRegistryVerificationOptions, LlmRouteConflictError, LlmRouteLedger, LlmRouteOwnership, LlmRouteOwnershipConfig, LlmRouteOwnershipEntry, LlmSettingsMaterializer, LlmSettingsPort, LoggerPort, MAX_WEB_QUERY_CHARS, MAX_WEB_SEARCH_RESULTS, MAX_WEB_URL_CHARS, MODELLIX_CREDENTIAL_REF, MODELLIX_LLM_BASE_URL, MODELLIX_LLM_MODELS_URL, MODELLIX_LLM_PROVENANCE_FIELD, MODELLIX_LLM_PROVIDER_ID, MODELLIX_MEDIA_GENERATE_TOOL, MODELLIX_MEDIA_GET_RESULT_TOOL, MODELLIX_MEDIA_LIST_TOOL, MODELLIX_MEDIA_PREPARE_TOOL, MODELLIX_MEDIA_SCHEMA_TOOL, MODELLIX_MEDIA_UPLOAD_FILE_TOOL, MODELLIX_ORIGINS, MODELLIX_SETTINGS_NAMESPACE, MODELLIX_WEB_FETCH_ENDPOINT, MODELLIX_WEB_FETCH_TOOL, MODELLIX_WEB_PROVIDER_ID, MODELLIX_WEB_SEARCH_ENDPOINT, MODELLIX_WEB_SEARCH_TOOL, MediaUploadClient, MediaUploadInput, MediaUploadRecord, ModelCatalogClient, ModelCatalogClientOptions, ModelCatalogPage, ModelCatalogQuery, ModelSchemaClient, ModelSchemaClientOptions, ModelSchemaDocument, ModellixDesignDomain, ModellixErrorCode, ModellixErrorContext, ModellixErrorContract, ModellixFailure, ModellixLlmCatalog, ModellixLlmModel, ModellixOriginName, ModellixPiAiRoute, ModellixRuntime, ModellixRuntimeState, ModellixService, ModellixWebContractError, ModellixWebCredentialSnapshot, ModellixWebFetchFailedError, ModellixWebFetchProvider, ModellixWebProviderError, ModellixWebProviderOptions, ModellixWebProviders, ModellixWebRegistry, ModellixWebSearchProvider, NaturalLanguagePlan, OnboardingConfig, OnboardingRecoveryAction, OnboardingRecoveryDecision, OnboardingSaveConflictError, OnboardingSavePhase, OnboardingSaveRecovery, OnboardingStatus, PUBLIC_PORTAL_CATALOG_URL, ParsedFetchFailure, ParsedFetchResponse, ParsedFetchSuccess, ParsedSearchResponse, PersistedLlmRouteOwnership, PiAiModelEntry, PluginConfig, PluginSettingsController, PluginSettingsSchema, PluginSettingsSnapshot, PredictionClient, PredictionClientOptions, PredictionResource, PredictionTask, PredictionTaskStatus, PreparedMediaUpload, REDACTED, ReadPredictionInput, RedactedValue, RequestDeadline, RetentionPolicy, RetryDelayInput, RetryOptions, RetrySuccess, RouteMaterializationPlan, RouteRemovalPlan, SchemaDiagnostic, SchemaParserLimits, ServiceId, ServiceToggles, ServicesConfig, SettingsNamespaceDescriptor, SettingsScopeLike, SettingsServiceLike, SleepPort, StaleLlmCatalogError, StoragePort, SubmitPredictionInput, UiConstraints, UiField, UiFieldKind, UiMediaKind, UiVariant, UnauthorizedTransition, UnsupportedConfigVersionError, VerificationTransition, WebConfig, abandonLlmMaterialization, advanceCredentialEpoch, apply, applyCredentialDescriptor, applyExactPatch, applyNaturalLanguage, applyRuntimeUnauthorized, applyVerificationResult, approveHttpRequest, approveRedirect, beginLlmMaterialization, beginOnboardingSave, buildFetchRequest, buildInvocationBody, buildSearchRequest, completeLlmMaterialization, completeOnboardingSave, computeRetryDelay, createCredentialState, createDefaultConfig, createModellixDesignToolDefinitions, createModellixWebProviders, createModellixWebToolDefinitions, deferOnboarding, deriveModellixSessionId, deriveModellixUserId, executeWithRetry, extractAllowedSubmitUrl, getServiceToggles, inject, isAllowedModellixOrigin, isCredentialInvalidError, isPublicHostname, isRetryableError, isRetryableReadFailure, isValidModellixIdentity, markOnboardingCredentialSaved, materializeDefaults, migrateConfig, missingCredentialDescriptor, modellixDesignDomainSpec, name, normalizeCredentialDescriptor, openDesignStorage, parseCatalogPage, parseDesignSchema, parseFetchResponse, parsePredictionTask, parseResources, parseRetryAfter, parseSearchResponse, planLlmRouteMaterialization, planLlmRouteRemoval, prepareMediaUploadFromPath, prepareMediaUploadFromSession, preserveStoredCredentialAfterCandidateFailure, preserveVerificationAfterTransientFailure, readBoundedResponseJson, readBoundedResponseText, reconcileLlmRouteLedgerAfterInterruption, reconcileOnboardingSave, redactForLog, redactHeaders, redactUrl, registerModellixDesignTools, registerModellixWebProviderInstances, registerModellixWebProviders, registerModellixWebTools, replayDesignWal, requestDeadline, retryAfterFromFailure, selectAvailableResults, setServiceToggles, systemClock, systemSleep, toModellixError, validatePublicHttpUrl, validateSubmitEndpoint, verifyLlmRegistryBackread };
1449
1453
  //# sourceMappingURL=index.d.ts.map
package/lib/index.js CHANGED
@@ -2,7 +2,7 @@ import z from "@deepseek-ai/schemastery";
2
2
  import { createHash, randomUUID } from "node:crypto";
3
3
  import { getOrCreateAnonymousUserId } from "@deepseek-ai/dsh-anonymous-user-id";
4
4
  import { credentialRef } from "@deepseek-ai/dsh-credentials";
5
- import { SettingsConflictError, settingsNamespace } from "@deepseek-ai/dsh-settings";
5
+ import { SettingsConflictError } from "@deepseek-ai/dsh-settings";
6
6
  import { lstat, open, realpath } from "node:fs/promises";
7
7
  import { basename, isAbsolute, relative, resolve } from "node:path";
8
8
  import { WebError } from "@deepseek-ai/dsh-web";
@@ -6215,13 +6215,14 @@ function stableJson(value) {
6215
6215
  //#region src/host/agent-routing-context.ts
6216
6216
  function createModellixRoutingMessage(state) {
6217
6217
  const sections = [];
6218
+ const nonMediaWebRouting = state.webEnabled ? "use the Modellix Web tools for those questions" : "leave those questions to the Harness-native web_search or web_fetch tools when available";
6218
6219
  if (state.webEnabled) sections.push({
6219
6220
  name: "Web routing",
6220
6221
  text: "Use modellix_web_search automatically for current, changing, external, or source-verification questions. Use modellix_web_fetch automatically when the user supplies a public URL or a Modellix search result needs full-page reading. Prefer these explicit Modellix tools over the native web_search and web_fetch tools, and never call both tool families for the same operation. Do not wait for the user to name a tool, do not browse when the user explicitly says not to, and never automatically repeat a failed or unknown Modellix Web request."
6221
6222
  });
6222
6223
  if (state.mediaEnabled) sections.push({
6223
6224
  name: "Media routing",
6224
- text: "Use Modellix media tools automatically only when the user intends to create, edit, transform, animate, upload, or inspect generated image, video, or audio work. Do not use media tools for documentation, pricing, general model-capability, or public API-reference questions; use the Modellix Web tools for those questions unless the user explicitly requests a live Modellix Design model Schema. For media work, use modellix_media_list then modellix_media_schema when a compatible model is not already known. Treat every returned field description and allowed value as authoritative; do not guess, translate, or replace a published parameter format, and omit optional fields when the user did not request them. A request that refers to the previous/current work, conversation attachments, or prior Modellix result URLs, asks to change or animate it, or asks to preserve its composition, subject, identity, or structure is not a new text-to-media request: select an image-edit/image-to-image, image-to-video, or video-to-video model as appropriate, inspect its schema, and place the latest relevant Modellix result URL in the declared media input field. Never replace that source-dependent operation with text-to-image or text-to-video. Reuse usable URLs and upload local inputs with modellix_media_upload_file. After submitting, inspect the task at most once in the same turn. Hard response rule: while a task is nonterminal, ordinary assistant text may say only that the submission was accepted and that the result card and Modellix Design own the current status. It must not say that the task is queued, running, generating, processing, pending, or any equivalent current-state wording, because ordinary assistant text is immutable and becomes stale. Never launch a replacement or parallel generation while a matching task is active unless the user explicitly requests another result, and never repeat an unknown generation or upload outcome."
6225
+ text: `Use Modellix media tools automatically only when the user intends to create, edit, transform, animate, upload, or inspect generated image, video, or audio work. Do not use media tools for documentation, pricing, general model-capability, or public API-reference questions; ${nonMediaWebRouting} unless the user explicitly requests a live Modellix Design model Schema. For media work, use modellix_media_list then modellix_media_schema when a compatible model is not already known. Treat every returned field description and allowed value as authoritative; do not guess, translate, or replace a published parameter format, and omit optional fields when the user did not request them. A request that refers to the previous/current work, conversation attachments, or prior Modellix result URLs, asks to change or animate it, or asks to preserve its composition, subject, identity, or structure is not a new text-to-media request: select an image-edit/image-to-image, image-to-video, or video-to-video model as appropriate, inspect its schema, and place the latest relevant Modellix result URL in the declared media input field. Never replace that source-dependent operation with text-to-image or text-to-video. Reuse usable URLs and upload local inputs with modellix_media_upload_file. After submitting, inspect the task at most once in the same turn. Hard response rule: while a task is nonterminal, ordinary assistant text may say only that the submission was accepted and that the result card and Modellix Design own the current status. It must not say that the task is queued, running, generating, processing, pending, or any equivalent current-state wording, because ordinary assistant text is immutable and becomes stale. Never launch a replacement or parallel generation while a matching task is active unless the user explicitly requests another result, and never repeat an unknown generation or upload outcome.`
6225
6226
  });
6226
6227
  if (sections.length === 0) return null;
6227
6228
  return createUserMessage({
@@ -7859,7 +7860,7 @@ var PluginSettingsController = class {
7859
7860
  //#endregion
7860
7861
  //#region src/host/runtime.ts
7861
7862
  const RPC_CHANNEL = "/modellix";
7862
- const LLM_SETTINGS_NAMESPACE = settingsNamespace("llm-pi-ai");
7863
+ const LLM_SETTINGS_NAMESPACE = "llm-pi-ai";
7863
7864
  const LLM_OWNERSHIP_ROLLBACK_FAILED = "MODELLIX_LLM_OWNERSHIP_ROLLBACK_FAILED";
7864
7865
  const LLM_MATERIALIZATION_RECOVERED = "MODELLIX_LLM_MATERIALIZATION_RECOVERED";
7865
7866
  const LLM_MATERIALIZATION_RECOVERY_FAILED = "MODELLIX_LLM_MATERIALIZATION_RECOVERY_FAILED";
@@ -7899,6 +7900,7 @@ var ModellixRuntime = class ModellixRuntime {
7899
7900
  #credentialRecoveryRequestId = null;
7900
7901
  #designPollTimer;
7901
7902
  #disposeDesignTools;
7903
+ #disposeWebTools;
7902
7904
  #closing = false;
7903
7905
  #lifecycleAbort = new AbortController();
7904
7906
  static async create(ctx) {
@@ -7977,6 +7979,7 @@ var ModellixRuntime = class ModellixRuntime {
7977
7979
  this.syncDesignTools(next.services.design.enabled);
7978
7980
  if (next.services.design.enabled) this.scheduleDesignPoll(0);
7979
7981
  }
7982
+ if (next.services.web.enabled !== previous.services.web.enabled) this.syncWebTools(next.services.web.enabled);
7980
7983
  if (next.services.llm.enabled !== previous.services.llm.enabled || next.credentialEpoch !== previous.credentialEpoch) return this.enqueueWrite(() => this.reconcileLiveSettings());
7981
7984
  }), "dsh-modellix: live settings snapshot");
7982
7985
  this.#ctx.on("credentials/reference-updated", (updated) => {
@@ -8008,36 +8011,12 @@ var ModellixRuntime = class ModellixRuntime {
8008
8011
  });
8009
8012
  });
8010
8013
  this.#ctx.effect(() => {
8011
- const providers = createModellixWebProviders({
8012
- isEnabled: () => this.#config.services.web.enabled,
8013
- hasCredential: () => this.credentialIsUsable(),
8014
- resolveCredential: async () => {
8015
- const hit = await this.resolveUsableCredential();
8016
- if (hit === void 0) this.requestCredentialRecovery();
8017
- return hit === void 0 ? null : {
8018
- apiKey: hit.value,
8019
- credentialEpoch: hit.credentialEpoch
8020
- };
8021
- },
8022
- getUserId: () => this.#userId,
8023
- isCredentialEpochCurrent: (epoch) => epoch === this.#config.credentialEpoch,
8024
- onCredentialRejected: async (epoch) => {
8025
- if (epoch !== this.#config.credentialEpoch) return;
8026
- this.markCredentialRejected(epoch);
8027
- }
8028
- });
8029
- const disposeProviders = registerModellixWebProviderInstances(this.#ctx.web, providers);
8030
- try {
8031
- const disposeTools = registerModellixWebTools(this.#ctx, providers);
8032
- return () => {
8033
- disposeTools();
8034
- disposeProviders();
8035
- };
8036
- } catch (error) {
8037
- disposeProviders();
8038
- throw error;
8039
- }
8040
- }, "dsh-modellix: Web providers and explicit Modellix tools");
8014
+ this.syncWebTools(this.#config.services.web.enabled);
8015
+ return () => {
8016
+ this.#disposeWebTools?.();
8017
+ this.#disposeWebTools = void 0;
8018
+ };
8019
+ }, "dsh-modellix: explicit Modellix Web tools");
8041
8020
  this.#ctx.on("agent/session-start", ({ agent }) => {
8042
8021
  const message = createModellixRoutingMessage({
8043
8022
  mediaEnabled: this.#config.services.design.enabled && this.credentialIsUsable(),
@@ -8045,7 +8024,8 @@ var ModellixRuntime = class ModellixRuntime {
8045
8024
  });
8046
8025
  if (message !== null) agent.inject(message);
8047
8026
  });
8048
- this.#ctx.effect(() => this.#ctx.connection.rpc.handle(RPC_CHANNEL, (endpoint, payload, signal) => this.handleRpc(endpoint, payload, signal), { authority: "loopback" }), "dsh-modellix: loopback configuration and Design RPC");
8027
+ const connectionRpc = this.#ctx.connection.rpc;
8028
+ this.#ctx.effect(() => connectionRpc.handle(RPC_CHANNEL, (endpoint, payload, signal) => this.handleRpc(endpoint, payload, signal), { authority: "loopback" }), "dsh-modellix: loopback configuration and Design RPC");
8049
8029
  this.#ctx.effect(() => {
8050
8030
  this.scheduleDesignPoll(2e3);
8051
8031
  return async () => {
@@ -8719,6 +8699,34 @@ var ModellixRuntime = class ModellixRuntime {
8719
8699
  this.#disposeDesignTools = void 0;
8720
8700
  }
8721
8701
  }
8702
+ syncWebTools(enabled) {
8703
+ if (enabled && this.#disposeWebTools === void 0) {
8704
+ const providers = createModellixWebProviders({
8705
+ isEnabled: () => this.#config.services.web.enabled,
8706
+ hasCredential: () => this.credentialIsUsable(),
8707
+ resolveCredential: async () => {
8708
+ const hit = await this.resolveUsableCredential();
8709
+ if (hit === void 0) this.requestCredentialRecovery();
8710
+ return hit === void 0 ? null : {
8711
+ apiKey: hit.value,
8712
+ credentialEpoch: hit.credentialEpoch
8713
+ };
8714
+ },
8715
+ getUserId: () => this.#userId,
8716
+ isCredentialEpochCurrent: (epoch) => epoch === this.#config.credentialEpoch,
8717
+ onCredentialRejected: async (epoch) => {
8718
+ if (epoch !== this.#config.credentialEpoch) return;
8719
+ this.markCredentialRejected(epoch);
8720
+ }
8721
+ });
8722
+ this.#disposeWebTools = registerModellixWebTools(this.#ctx, providers);
8723
+ return;
8724
+ }
8725
+ if (!enabled && this.#disposeWebTools !== void 0) {
8726
+ this.#disposeWebTools();
8727
+ this.#disposeWebTools = void 0;
8728
+ }
8729
+ }
8722
8730
  scheduleDesignPoll(delayMs) {
8723
8731
  if (this.#closing || this.#designPollTimer !== void 0) return;
8724
8732
  this.#designPollTimer = setTimeout(() => {