@moguiyu/dsh-tavily 0.2.5 → 0.2.7

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.
Files changed (2) hide show
  1. package/package.json +4 -4
  2. package/src/index.js +43 -19
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moguiyu/dsh-tavily",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "Opt-in advanced Tavily model tools for DeepSeek Harness with the Tavily Search settings card (rc.7/rc.8 and the 0.1.2-0.1.6 plugin management lines). The built-in web_search is never replaced.",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -65,9 +65,9 @@
65
65
  },
66
66
  "peerDependencies": {
67
67
  "@deepseek-ai/cordis": "^4.0.1",
68
- "@deepseek-ai/dsh-home-paths": "^0.1.0-rc.8 || ^0.1.2-alpha.2 || ^0.1.3-alpha.2 || ^0.1.5-0 || ^0.1.6-0",
69
- "@deepseek-ai/dsh-tools": "^0.1.0-rc.8 || ^0.1.2-alpha.2 || ^0.1.3-alpha.2 || ^0.1.5-0 || ^0.1.6-0",
70
- "@deepseek-ai/dsh-settings": "^0.1.0-rc.8 || ^0.1.2-alpha.2 || ^0.1.3-alpha.2 || ^0.1.5-0 || ^0.1.6-0"
68
+ "@deepseek-ai/dsh-home-paths": "^0.1.0-rc.7 || ^0.1.1-rc.1 || ^0.1.2-alpha.2 || ^0.1.3-alpha.1 || ^0.1.5-0 || ^0.1.6-0",
69
+ "@deepseek-ai/dsh-tools": "^0.1.0-rc.7 || ^0.1.1-rc.1 || ^0.1.2-alpha.2 || ^0.1.3-alpha.1 || ^0.1.5-0 || ^0.1.6-0",
70
+ "@deepseek-ai/dsh-settings": "^0.1.0-rc.7 || ^0.1.1-rc.1 || ^0.1.2-alpha.2 || ^0.1.3-alpha.1 || ^0.1.5-0 || ^0.1.6-0"
71
71
  },
72
72
  "dependencies": {
73
73
  "@deepseek-ai/schemastery": "^3.18.2",
package/src/index.js CHANGED
@@ -11,9 +11,15 @@
11
11
  * `tavily-search` settings section (the key the Plugins configuration tab
12
12
  * pairs the card against). The switch value lives both in that namespace and
13
13
  * in `~/.dsh/tavily-tool.json`; every write path converges on
14
- * `settings.update` (or the state file when no settings service exists),
15
- * persisted first, then the row restarts itself so the tool registers or
16
- * unregisters cleanly.
14
+ * `settings.update` (or the state file when no settings service exists).
15
+ *
16
+ * The switch owns the tool half's lifecycle DIRECTLY: it holds the disposer
17
+ * returned by {@link installTavilyTool} and disposes / re-installs it in place.
18
+ * Earlier versions instead restarted the composing row and let `apply()` re-run;
19
+ * that is gone on purpose. A row restart on 0.1.6 re-mounts the fiber into a
20
+ * scope the agent does not see, so the tools ended up registered nowhere and
21
+ * stayed missing for every session until DSH restarted (AGENTS.md §9 gate 5).
22
+ * Do not reintroduce the restart.
17
23
  *
18
24
  * The settings-card switch controls ONLY the opt-in `tavily_search` tool. The
19
25
  * built-in `web_search` tool is never replaced: this package registers no web
@@ -26,7 +32,7 @@ import { installBackend, readToolState, restoreToolState, writeToolState } from
26
32
 
27
33
  export const name = 'dsh-tavily'
28
34
 
29
- export const inject = ['tools', 'webServer', 'credentials', 'systemPrompt', 'loader']
35
+ export const inject = ['tools', 'webServer', 'credentials', 'systemPrompt']
30
36
 
31
37
  export const Config = z.object({
32
38
  enabled: z.boolean().default(false),
@@ -44,31 +50,52 @@ export const Config = z.object({
44
50
  export const TAVILY_NS = 'tavily-search'
45
51
 
46
52
  export function apply(ctx, config) {
47
- // The switch value the current fiber is acting on. Every write path updates
48
- // this before the row restart so a watcher re-fired after a restart no-ops.
53
+ // The switch value this fiber is acting on. Every write path updates it
54
+ // before (un)registering, so a watcher re-fired afterwards no-ops.
49
55
  let lastApplied = isToolEnabled(config)
50
56
  // Settings seam state: the attached provider (null on hosts without one)
51
57
  // and the authoritative switch source — the resolved section while the
52
58
  // provider is attached, the composition entry otherwise.
53
59
  let settingsProvider = null
54
60
  let settingsSource = () => config
61
+ // The live registration of the tool half, or null while it is off.
62
+ let disposeTools = null
63
+
64
+ /**
65
+ * Add or remove the tool half to match `enabled`. This is the whole switch:
66
+ * `installTavilyTool` hands back a disposer covering its tools and prompt
67
+ * sections, so turning the capability off is a disposal rather than a row
68
+ * restart. See the module header for why the restart is gone.
69
+ */
70
+ function setTools(enabled) {
71
+ if (enabled) {
72
+ if (disposeTools === null) disposeTools = installTavilyTool(ctx)
73
+ return
74
+ }
75
+ if (disposeTools !== null) {
76
+ const dispose = disposeTools
77
+ disposeTools = null
78
+ dispose()
79
+ }
80
+ }
55
81
 
56
- /** Persist the switch first, then restart this row so the tool (un)registers. */
82
+ // Seed from the composition entry / persisted switch, and hand the fiber the
83
+ // teardown so unloading the row leaves nothing registered.
84
+ setTools(lastApplied)
85
+ ctx.effect(() => () => { setTools(false) })
86
+
87
+ /** Persist the switch, then (un)register the tool half in place. */
57
88
  async function applySwitchLocal(enabled) {
58
89
  if (enabled === lastApplied) return
59
- lastApplied = enabled
60
90
  const previous = readToolState()
91
+ lastApplied = enabled
61
92
  writeToolState(enabled)
62
93
  try {
63
- const loader = ctx.get('loader')
64
- const self = loader !== undefined && loader !== null ? loader.resolve('include:dsh-tavily') : undefined
65
- if (self === undefined || self === null || self.fiber === undefined) {
66
- throw new Error('dsh-tavily: row include:dsh-tavily is not loaded')
67
- }
68
- await self.fiber.update({ enabled }, true)
94
+ setTools(enabled)
69
95
  } catch (error) {
70
96
  lastApplied = previous !== null ? previous.enabled : (config.enabled !== false)
71
97
  restoreToolState(previous)
98
+ setTools(lastApplied)
72
99
  throw error
73
100
  }
74
101
  }
@@ -131,8 +158,8 @@ export function apply(ctx, config) {
131
158
  enabled: () => isToolEnabled(config),
132
159
  async applySwitch(enabled) {
133
160
  // Every write converges on one pipeline: the settings namespace when a
134
- // settings service is attached (its watcher persists and restarts this
135
- // row), or the plain state-file path otherwise.
161
+ // settings service is attached (its watcher persists and re-applies the
162
+ // switch in place), or the plain state-file path otherwise.
136
163
  if (settingsProvider !== null) {
137
164
  await settingsProvider.update(TAVILY_NS, { enabled })
138
165
  } else {
@@ -140,7 +167,4 @@ export function apply(ctx, config) {
140
167
  }
141
168
  },
142
169
  })
143
-
144
- if (!isToolEnabled(config)) return
145
- installTavilyTool(ctx)
146
170
  }