dsh-vision-router 1.7.5 → 1.7.6
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,7 +1,84 @@
|
|
|
1
1
|
const wrappedContexts = new WeakMap()
|
|
2
|
+
const wrappedLlmServices = new WeakMap()
|
|
3
|
+
const preparedAdapterCompat = new WeakMap()
|
|
2
4
|
|
|
3
5
|
export const DEFAULT_ADAPTER_RECONCILE_MAX_PASSES = 32
|
|
4
6
|
|
|
7
|
+
/**
|
|
8
|
+
* DSH 0.1.1 dispatches every model call through adapter.prepareCall(). Older
|
|
9
|
+
* Vision Router adapters are intentionally duck-typed objects and therefore do
|
|
10
|
+
* not inherit LlmAdapter's default implementation. Normalize only adapters
|
|
11
|
+
* registered through Vision Router's wrapped context so host/foreign adapters
|
|
12
|
+
* keep their native identity and behavior.
|
|
13
|
+
*/
|
|
14
|
+
export function ensureAdapterPrepareCall(adapter) {
|
|
15
|
+
if (!adapter || (typeof adapter !== 'object' && typeof adapter !== 'function')) return adapter
|
|
16
|
+
if (typeof adapter.prepareCall === 'function') return adapter
|
|
17
|
+
|
|
18
|
+
const cached = preparedAdapterCompat.get(adapter)
|
|
19
|
+
if (cached) return cached
|
|
20
|
+
|
|
21
|
+
const prepareCall = async (provider, model, signal) => {
|
|
22
|
+
const fallbackModel = { provider, id: model, name: model }
|
|
23
|
+
const resolved =
|
|
24
|
+
typeof adapter.resolveModel === 'function'
|
|
25
|
+
? await adapter.resolveModel.call(adapter, provider, model, signal)
|
|
26
|
+
: fallbackModel
|
|
27
|
+
return {
|
|
28
|
+
model: resolved && typeof resolved === 'object' ? resolved : fallbackModel,
|
|
29
|
+
stream(options) {
|
|
30
|
+
return adapter.stream.call(adapter, options)
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Preserve the exact adapter object whenever possible. Some runtime paths
|
|
36
|
+
// retain registration.adapter and compare/reuse it later, so mutation is less
|
|
37
|
+
// surprising than substituting a wrapper. Frozen/sealed adapters fall back to
|
|
38
|
+
// a proxy that exposes only the missing contract method.
|
|
39
|
+
try {
|
|
40
|
+
Object.defineProperty(adapter, 'prepareCall', {
|
|
41
|
+
configurable: true,
|
|
42
|
+
writable: true,
|
|
43
|
+
value: prepareCall,
|
|
44
|
+
})
|
|
45
|
+
preparedAdapterCompat.set(adapter, adapter)
|
|
46
|
+
return adapter
|
|
47
|
+
} catch {
|
|
48
|
+
const wrapped = new Proxy(adapter, {
|
|
49
|
+
get(target, property) {
|
|
50
|
+
if (property === 'prepareCall') return prepareCall
|
|
51
|
+
const value = Reflect.get(target, property, target)
|
|
52
|
+
return typeof value === 'function' ? value.bind(target) : value
|
|
53
|
+
},
|
|
54
|
+
})
|
|
55
|
+
preparedAdapterCompat.set(adapter, wrapped)
|
|
56
|
+
return wrapped
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function wrapLlmService(llm) {
|
|
61
|
+
if (!llm || (typeof llm !== 'object' && typeof llm !== 'function')) return llm
|
|
62
|
+
const cached = wrappedLlmServices.get(llm)
|
|
63
|
+
if (cached) return cached
|
|
64
|
+
|
|
65
|
+
const wrapped = new Proxy(llm, {
|
|
66
|
+
get(target, property) {
|
|
67
|
+
if (property === 'registerAdapter') {
|
|
68
|
+
const registerAdapter = Reflect.get(target, property, target)
|
|
69
|
+
if (typeof registerAdapter !== 'function') return registerAdapter
|
|
70
|
+
return (providers, adapter, ...rest) =>
|
|
71
|
+
registerAdapter.call(target, providers, ensureAdapterPrepareCall(adapter), ...rest)
|
|
72
|
+
}
|
|
73
|
+
const value = Reflect.get(target, property, target)
|
|
74
|
+
return typeof value === 'function' ? value.bind(target) : value
|
|
75
|
+
},
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
wrappedLlmServices.set(llm, wrapped)
|
|
79
|
+
return wrapped
|
|
80
|
+
}
|
|
81
|
+
|
|
5
82
|
/**
|
|
6
83
|
* Turn a synchronous reconciliation pass into a bounded fixed-point runner.
|
|
7
84
|
*
|
|
@@ -76,6 +153,10 @@ export function createCoalescingRunner(run, options = {}) {
|
|
|
76
153
|
* registerAdapter() returns. Only Vision Router listeners registered through
|
|
77
154
|
* this wrapped context are coalesced; host and other plugin listeners keep
|
|
78
155
|
* their native event semantics.
|
|
156
|
+
*
|
|
157
|
+
* The same boundary also normalizes Vision Router-owned adapter registrations
|
|
158
|
+
* to the DSH 0.1.1 prepareCall contract. This stays scoped to the wrapped
|
|
159
|
+
* context instead of monkey-patching the Host LLM service process-wide.
|
|
79
160
|
*/
|
|
80
161
|
export function contextWithCoalescedAdapterUpdates(ctx) {
|
|
81
162
|
if (!ctx || (typeof ctx !== 'object' && typeof ctx !== 'function')) return ctx
|
|
@@ -84,6 +165,9 @@ export function contextWithCoalescedAdapterUpdates(ctx) {
|
|
|
84
165
|
|
|
85
166
|
const wrapped = new Proxy(ctx, {
|
|
86
167
|
get(target, property) {
|
|
168
|
+
if (property === 'llm') {
|
|
169
|
+
return wrapLlmService(Reflect.get(target, property, target))
|
|
170
|
+
}
|
|
87
171
|
if (property === 'on') {
|
|
88
172
|
const on = Reflect.get(target, property, target)
|
|
89
173
|
if (typeof on !== 'function') return on
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-vision-router",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.6",
|
|
4
4
|
"description": "Eyes for text-only DeepSeek Harness agents: built-in free vision chain (no key) + pixel-level vision tools (Q&A, grounding, crop, pixel diff, colors, OCR, SVG trace, cutout, screenshots). One-command install, no Python, image turns work like ordinary tool-calling turns.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"sharp": "^0.35.3"
|
|
70
70
|
},
|
|
71
71
|
"scripts": {
|
|
72
|
-
"test": "node --test tests/core.test.js tests/capability-advisory.test.js tests/vision-execution-policy.test.js tests/vision-backend-diagnostics.test.js tests/vision-backend-smoke-test.test.js tests/live-model-discovery.test.js tests/live-model-credential-resolution.test.js tests/vision-model-registry.test.js tests/live-model-client-stability.test.js tests/provider-directory-fallback.test.js tests/settings-section-order.test.js tests/attachment-admission-policy.test.js tests/vision-resilience.test.js tests/client.test.js tests/client-presentation-boundary.test.js tests/remote-settings-bridge.test.js tests/remote-settings-risk-confirmation.test.js tests/local-remote-settings-permission.test.js tests/rc6-real-settings-persistence.test.js tests/artifact-path-security.test.js tests/http-compat.test.js tests/catalog-corrections.test.js tests/update-check.test.js tests/self-update.test.js tests/doctor.test.js tests/doctor-cli.test.js tests/legacy-session-repair.test.js tests/profile-pnpm-diagnostics.test.js tests/doctor-v2.test.js tests/doctor-cli-v2.test.js tests/doctor-runtime.test.js tests/session-repair-v2.test.js tests/bundle-defaults.test.js tests/file-logger.test.js tests/replay-delegation.test.js tests/adversarial-hardening.test.js tests/wrapper-directory.test.js tests/logging-ui.test.js tests/manifest-dependencies.test.js tests/structured-bootstrap.test.js tests/structured-bootstrap-gate.test.js tests/local-ollama.test.js tests/ollama-cold-start.test.js tests/ollama-cold-start-loaded.test.js tests/zero-regression-gate.test.js tests/runtime-e2e.test.js tests/local-vision-stabilizer.test.js tests/local-connection-probe.test.js tests/repetition-guard.test.js tests/guide-scroll-gate.test.js tests/settings-scroll-jank-regression.test.js tests/android-attachment-compat.test.js tests/free-cloud-first.test.js tests/rc6-rc7-compat.test.js tests/native-image-coexistence.test.js tests/pi-ai-bridge-wire-compat.test.js tests/mixed-router.test.js tests/depth-tier.test.js tests/depth-quota-behavior.test.js tests/structured-flow-hardening.test.js tests/vision-budget-activation.test.js tests/runtime-boundary-fixes.test.js tests/tesseract-node24-boot.test.js tests/session-vision-state.test.js tests/session-vision-state-integration.test.js tests/image-resource-governor.test.js tests/pixel-diff-stream.test.js tests/large-image-resource-integration.test.js tests/structured-guard-idempotency.test.js tests/qa-top5-reliability.test.js tests/qa-screenshot-runtime.test.js tests/qa-runtime-identity.test.js tests/qa-turn-budget-cancellation.test.js tests/qa-cancellation-publication.test.js tests/qa-reliability-tail.test.js tests/qa-endpoint-route-alias.test.js"
|
|
72
|
+
"test": "node --test tests/adapter-prepare-call-compat.test.js tests/core.test.js tests/capability-advisory.test.js tests/vision-execution-policy.test.js tests/vision-backend-diagnostics.test.js tests/vision-backend-smoke-test.test.js tests/live-model-discovery.test.js tests/live-model-credential-resolution.test.js tests/vision-model-registry.test.js tests/live-model-client-stability.test.js tests/provider-directory-fallback.test.js tests/settings-section-order.test.js tests/attachment-admission-policy.test.js tests/vision-resilience.test.js tests/client.test.js tests/client-presentation-boundary.test.js tests/remote-settings-bridge.test.js tests/remote-settings-risk-confirmation.test.js tests/local-remote-settings-permission.test.js tests/rc6-real-settings-persistence.test.js tests/artifact-path-security.test.js tests/http-compat.test.js tests/catalog-corrections.test.js tests/update-check.test.js tests/self-update.test.js tests/doctor.test.js tests/doctor-cli.test.js tests/legacy-session-repair.test.js tests/profile-pnpm-diagnostics.test.js tests/doctor-v2.test.js tests/doctor-cli-v2.test.js tests/doctor-runtime.test.js tests/session-repair-v2.test.js tests/bundle-defaults.test.js tests/file-logger.test.js tests/replay-delegation.test.js tests/adversarial-hardening.test.js tests/wrapper-directory.test.js tests/logging-ui.test.js tests/manifest-dependencies.test.js tests/structured-bootstrap.test.js tests/structured-bootstrap-gate.test.js tests/local-ollama.test.js tests/ollama-cold-start.test.js tests/ollama-cold-start-loaded.test.js tests/zero-regression-gate.test.js tests/runtime-e2e.test.js tests/local-vision-stabilizer.test.js tests/local-connection-probe.test.js tests/repetition-guard.test.js tests/guide-scroll-gate.test.js tests/settings-scroll-jank-regression.test.js tests/android-attachment-compat.test.js tests/free-cloud-first.test.js tests/rc6-rc7-compat.test.js tests/native-image-coexistence.test.js tests/pi-ai-bridge-wire-compat.test.js tests/mixed-router.test.js tests/depth-tier.test.js tests/depth-quota-behavior.test.js tests/structured-flow-hardening.test.js tests/vision-budget-activation.test.js tests/runtime-boundary-fixes.test.js tests/tesseract-node24-boot.test.js tests/session-vision-state.test.js tests/session-vision-state-integration.test.js tests/image-resource-governor.test.js tests/pixel-diff-stream.test.js tests/large-image-resource-integration.test.js tests/structured-guard-idempotency.test.js tests/qa-top5-reliability.test.js tests/qa-screenshot-runtime.test.js tests/qa-runtime-identity.test.js tests/qa-turn-budget-cancellation.test.js tests/qa-cancellation-publication.test.js tests/qa-reliability-tail.test.js tests/qa-endpoint-route-alias.test.js"
|
|
73
73
|
},
|
|
74
74
|
"pnpm": {
|
|
75
75
|
"onlyBuiltDependencies": ["sharp"]
|