@khorsheed/dsh-local-agent-dsh 0.2.0-rc.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,3 @@
1
+ import { a as MEMBER_BRIDGE_ENTRY_ENV, c as dshTextTask, d as startDshCliRun, i as DshCliProvider, l as registerMemberRun, n as DEFAULT_DISPOSE_GRACE_MS, o as dshCliVersion, r as DEFAULT_LIVE_MIRROR_INTERVAL_MS, s as dshLaunchArgv, t as CONTAINER_NODE_OPTIONS, u as resolveApiKey } from "./dsh-cli-provider-DYRuRpVz.js";
1
2
  import "./provision.js";
2
- import { a as MEMBER_BRIDGE_ENTRY_ENV, c as dshTextTask, d as startDshCliRun, i as DshCliProvider, l as registerMemberRun, n as DEFAULT_DISPOSE_GRACE_MS, o as dshCliVersion, r as DEFAULT_LIVE_MIRROR_INTERVAL_MS, s as dshLaunchArgv, t as CONTAINER_NODE_OPTIONS, u as resolveApiKey } from "./dsh-cli-provider-UhWvivte.js";
3
3
  export { CONTAINER_NODE_OPTIONS, DEFAULT_DISPOSE_GRACE_MS, DEFAULT_LIVE_MIRROR_INTERVAL_MS, DshCliProvider, MEMBER_BRIDGE_ENTRY_ENV, dshCliVersion, dshLaunchArgv, dshTextTask, registerMemberRun, resolveApiKey, startDshCliRun };
package/lib/index.js CHANGED
@@ -1,9 +1,9 @@
1
- import { DEFAULT_SUB_PROFILE_NAME, USER_PRESET_DIR, defaultPresetRoot, provisionDshScope } from "./provision.js";
2
- import { f as DEFAULT_LIVE_IDLE_MS, i as DshCliProvider, o as dshCliVersion, p as DshLiveDriver, t as CONTAINER_NODE_OPTIONS } from "./dsh-cli-provider-UhWvivte.js";
1
+ import { f as DEFAULT_LIVE_IDLE_MS, h as localModelLaunch, i as DshCliProvider, m as canInheritModelProvider, o as dshCliVersion, p as DshLiveDriver, t as CONTAINER_NODE_OPTIONS } from "./dsh-cli-provider-DYRuRpVz.js";
2
+ import { DEFAULT_SUB_PROFILE_NAME, provisionDshScope } from "./provision.js";
3
3
  import { listDshSessions } from "./records.js";
4
- import { join } from "node:path";
4
+ import { dirname } from "node:path";
5
+ import { fileURLToPath } from "node:url";
5
6
  import z from "@deepseek-ai/schemastery";
6
- import { credentialRef } from "@deepseek-ai/dsh-credentials";
7
7
  import { ModelDirectoryCache, extendModelDirectory, settingsFace, vol } from "@khorsheed/dsh-local-agent";
8
8
  import { mountSubagentDelegationTool } from "@khorsheed/dsh-local-agent/tool-factory";
9
9
  //#region lib/types/live-switch.js
@@ -156,7 +156,8 @@ var DshModelCatalog = class {
156
156
  unsupported: true,
157
157
  reason: "The host exposes no adapter model directory"
158
158
  };
159
- const providers = llm.listProviders();
159
+ const allProviders = llm.listProviders();
160
+ const providers = allProviders.filter((provider) => this.deps.canInheritProvider?.(provider.id) ?? true);
160
161
  const groups = await Promise.allSettled(providers.map(async (provider) => Promise.all((await llm.listModels(provider.id)).map(async (model) => {
161
162
  let resolved;
162
163
  try {
@@ -182,12 +183,13 @@ var DshModelCatalog = class {
182
183
  if (failed > 0 && failed === groups.length) throw new Error("DSH adapters could not list models");
183
184
  const entries = groups.flatMap((group) => group.status === "fulfilled" ? group.value : []);
184
185
  const defaultModel = this.deps.defaultModel();
186
+ const omitted = allProviders.length - providers.length;
185
187
  return {
186
188
  entries,
187
- complete: failed === 0,
189
+ complete: failed === 0 && providers.length === allProviders.length,
188
190
  customInput: true,
189
- ...defaultModel === void 0 ? {} : { defaultModel },
190
- ...failed === 0 ? {} : { reason: `${failed} adapter model list(s) unavailable` }
191
+ ...defaultModel === void 0 || !entries.some((entry) => entry.value === defaultModel) ? {} : { defaultModel },
192
+ ...failed === 0 && omitted === 0 ? {} : { reason: [...failed === 0 ? [] : [`${failed} adapter model list(s) unavailable`], ...omitted === 0 ? [] : [`${omitted} provider(s) do not support local API-key inheritance`]].join("; ") }
191
193
  };
192
194
  }
193
195
  };
@@ -356,7 +358,7 @@ var DshModelBroker = class {
356
358
  * namespace (default off); while ON, the controller registers the `dsh`
357
359
  * harness into the core registry (scoped home under the shared homes root,
358
360
  * `$DSH_HOME`), the `dsh-cli` delegation provider (sub-dsh headless runs with
359
- * the parent's resolved DeepSeek key), and the family delegation tool for it.
361
+ * the parent's selected API-key model route), and the family delegation tool for it.
360
362
  * While OFF — the default — nothing model-visible mounts, so the instance
361
363
  * keeps exactly the current behavior (official in-process subagent tools) and
362
364
  * the model never sees two overlapping delegation tools at once.
@@ -413,9 +415,10 @@ function volatilize(field) {
413
415
  }
414
416
  const Config = z.object({
415
417
  profileName: z.string().default(DEFAULT_SUB_PROFILE_NAME),
416
- apiKeyRef: z.string().default("DEEPSEEK_API_KEY"),
418
+ apiKeyRef: z.string(),
417
419
  cliLaunch: z.array(z.string()),
418
420
  headlessBundleDir: z.string(),
421
+ unitHeadlessBundleDir: z.string(),
419
422
  permissions: z.union([
420
423
  z.const("read-only"),
421
424
  z.const("workspace-write"),
@@ -448,8 +451,8 @@ const DSH_TOOL_NAME = "subagent_dsh";
448
451
  /**
449
452
  * This package's own name, passed to the family tool factory as the
450
453
  * tool-origin owner (AGENTS.md § Tool origin tagging — a shared factory never
451
- * hardcodes an owner). Duplicated from src/invariant.ts, the same pattern the
452
- * worktrees/room `./tool` entries use.
454
+ * hardcodes an owner), the same pattern the worktrees/room `./tool` entries
455
+ * use.
453
456
  */
454
457
  const PACKAGE_NAME = "@khorsheed/dsh-local-agent-dsh";
455
458
  /**
@@ -471,10 +474,6 @@ const dshSubagentTool = {
471
474
  }, PACKAGE_NAME);
472
475
  }
473
476
  };
474
- /** Resolve the sub-dsh credential or report unconfigured. */
475
- async function resolveApiKey(ctx, config) {
476
- return ctx.credentials.resolve(credentialRef(config.apiKeyRef ?? "DEEPSEEK_API_KEY"));
477
- }
478
477
  /**
479
478
  * Mount the toggle controller: register the settings namespace, then mirror
480
479
  * its value into harness/provider/tool registrations, live.
@@ -519,7 +518,8 @@ function apply(ctx, config) {
519
518
  };
520
519
  const modelCatalog = new DshModelCatalog({
521
520
  llm: () => ctx.get("llm"),
522
- defaultModel: hostDefaultModel
521
+ defaultModel: hostDefaultModel,
522
+ canInheritProvider: (provider) => canInheritModelProvider(ctx, provider)
523
523
  });
524
524
  modelCatalog.read();
525
525
  ctx.on("llm/adapters-updated", () => {
@@ -541,14 +541,26 @@ function apply(ctx, config) {
541
541
  retireRuntime: (childSessionId) => currentLiveSwitch?.retireRuntime(childSessionId) ?? Promise.resolve()
542
542
  });
543
543
  /**
544
- * This deployment's preset root — where a person or a pack installed the
545
- * presets this instance offers, and the SOURCE every scope's own copy is
546
- * taken from. Derived the way the roster derives it, from the settings
547
- * service's harness home when there is one.
544
+ * This instance's own profile directory — the loader's `baseUrl`, which
545
+ * the host sets to the directory holding the profile's `cordis.yml`. Its
546
+ * direct dependencies are where an installed preset package is found, and
547
+ * the SOURCE every scope's own copy is taken from (the same package this
548
+ * instance's capability catalog measures). Undefined when the loader
549
+ * exposes no file URL, which leaves a scope able to keep the copy it has
550
+ * but unable to take a new one.
548
551
  */
549
- const instancePresetRoot = () => {
550
- const home = ctx.get?.("settings")?.home;
551
- return home === void 0 ? defaultPresetRoot() : join(home, USER_PRESET_DIR);
552
+ const instanceProfileDir = () => {
553
+ const baseUrl = ctx.baseUrl;
554
+ if (typeof baseUrl !== "string" || !baseUrl.startsWith("file:")) return void 0;
555
+ try {
556
+ return dirname(fileURLToPath(new URL("./package.json", baseUrl)));
557
+ } catch {
558
+ return;
559
+ }
560
+ };
561
+ const profileDirOption = () => {
562
+ const dir = instanceProfileDir();
563
+ return dir === void 0 ? {} : { instanceProfileDir: dir };
552
564
  };
553
565
  const harness = {
554
566
  prepareMember: async ({ binding, childSession, configuration, signal }) => {
@@ -572,7 +584,7 @@ function apply(ctx, config) {
572
584
  provision: (scopedHome, options) => {
573
585
  const provisioned = provisionDshScope(scopedHome, config, {
574
586
  ...options?.preset === void 0 ? {} : { preset: options.preset },
575
- presetRoot: instancePresetRoot()
587
+ ...profileDirOption()
576
588
  });
577
589
  return {
578
590
  ...provisioned.preset === void 0 ? {} : { preset: provisioned.preset },
@@ -581,7 +593,8 @@ function apply(ctx, config) {
581
593
  },
582
594
  isAuthenticated: async () => {
583
595
  try {
584
- return await resolveApiKey(ctx, config) !== void 0;
596
+ await localModelLaunch(ctx, config, resolveModel() ?? hostDefaultModel());
597
+ return true;
585
598
  } catch {
586
599
  return false;
587
600
  }
@@ -610,7 +623,7 @@ function apply(ctx, config) {
610
623
  const gen = generation;
611
624
  for (const dispose of disposers.splice(0)) dispose();
612
625
  if (!enabled) return;
613
- provisionDshScope(homeDir, config, { presetRoot: instancePresetRoot() });
626
+ provisionDshScope(homeDir, config, profileDirOption());
614
627
  disposers.push(ctx.localAgent.register(harness));
615
628
  const liveSwitch = new LiveDriverSwitch(ctx, face, config, { modelFor: (childSessionId) => memberModelOverrides.get(childSessionId) ?? resolveModel() });
616
629
  currentLiveSwitch = liveSwitch;