@anionex/dsh-computer-use 0.3.2 → 0.3.3
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/CHANGELOG.md +130 -0
- package/README.md +4 -1
- package/README.zh.md +4 -1
- package/lib/client.js +1 -1
- package/lib/client.js.map +1 -1
- package/lib/config.js +37 -17
- package/lib/config.js.map +1 -1
- package/lib/confirmations.js.map +1 -1
- package/lib/exposure.js +4 -4
- package/lib/exposure.js.map +1 -1
- package/lib/index.js +5 -1
- package/lib/index.js.map +1 -1
- package/lib/leases.js.map +1 -1
- package/lib/providers/macos.js +27 -11
- package/lib/providers/macos.js.map +1 -1
- package/lib/skill.js +13 -2
- package/lib/skill.js.map +1 -1
- package/lib/tools.js +1 -1
- package/lib/tools.js.map +1 -1
- package/lib/types/client/index.d.ts +1 -1
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/config.d.ts +2 -0
- package/lib/types/config.d.ts.map +1 -1
- package/lib/types/confirmations.d.ts +1 -1
- package/lib/types/confirmations.d.ts.map +1 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/leases.d.ts +2 -1
- package/lib/types/leases.d.ts.map +1 -1
- package/lib/types/providers/macos.d.ts +0 -1
- package/lib/types/providers/macos.d.ts.map +1 -1
- package/lib/types/skill.d.ts +7 -2
- package/lib/types/skill.d.ts.map +1 -1
- package/lib/types/tools.d.ts.map +1 -1
- package/lib/types/types.d.ts +3 -1
- package/lib/types/types.d.ts.map +1 -1
- package/lib/types/web.d.ts +2 -1
- package/lib/types/web.d.ts.map +1 -1
- package/lib/types.js.map +1 -1
- package/lib/web.js +18 -8
- package/lib/web.js.map +1 -1
- package/native/macos/Sources/Helper/CursorOverlay.swift +3 -0
- package/native/macos/Sources/Helper/main.swift +35 -19
- package/native/macos/bin/dsh-computer-use-helper +0 -0
- package/native/macos/manifest.json +3 -3
- package/package.json +64 -24
- package/scripts/model-e2e.mjs +7 -3
- package/scripts/session-transcript.mjs +4 -3
- package/src/client/index.tsx +4 -2
- package/src/config.ts +40 -18
- package/src/confirmations.ts +1 -1
- package/src/exposure.ts +5 -5
- package/src/index.ts +5 -1
- package/src/leases.ts +3 -2
- package/src/providers/macos.ts +31 -11
- package/src/skill.ts +14 -2
- package/src/tools.ts +3 -2
- package/src/types.ts +2 -1
- package/src/web.ts +21 -6
package/src/skill.ts
CHANGED
|
@@ -2,8 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
import type { SkillRegistration } from '@deepseek-ai/dsh-skill'
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
export const COMPUTER_USE_SKILL_NAME = 'computer-use'
|
|
5
|
+
/** Namespaced entry avoids collisions with filesystem Skills in Agent presets. */
|
|
6
|
+
export const COMPUTER_USE_SKILL_NAME = 'dsh-computer-use'
|
|
7
|
+
/** Existing sessions and slash-command workflows continue to recognize this entry. */
|
|
8
|
+
export const LEGACY_COMPUTER_USE_SKILL_NAME = 'computer-use'
|
|
9
|
+
export const COMPUTER_USE_SKILL_NAMES: ReadonlySet<string> = new Set([
|
|
10
|
+
COMPUTER_USE_SKILL_NAME,
|
|
11
|
+
LEGACY_COMPUTER_USE_SKILL_NAME,
|
|
12
|
+
])
|
|
7
13
|
|
|
8
14
|
/** Complete model-visible operating and confirmation workflow. */
|
|
9
15
|
export const COMPUTER_USE_SKILL_CONTENT = `# DSH Computer Use
|
|
@@ -127,3 +133,9 @@ export const COMPUTER_USE_SKILL: SkillRegistration = {
|
|
|
127
133
|
source: 'runtime',
|
|
128
134
|
content: COMPUTER_USE_SKILL_CONTENT,
|
|
129
135
|
}
|
|
136
|
+
|
|
137
|
+
/** Compatibility alias for existing Sessions; preset Skills may shadow it. */
|
|
138
|
+
export const LEGACY_COMPUTER_USE_SKILL: SkillRegistration = {
|
|
139
|
+
...COMPUTER_USE_SKILL,
|
|
140
|
+
name: LEGACY_COMPUTER_USE_SKILL_NAME,
|
|
141
|
+
}
|
package/src/tools.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/** Focused model-facing Computer Use Tool definitions. */
|
|
2
2
|
|
|
3
|
+
import type { JsonValue } from '@deepseek-ai/dsh-util-values'
|
|
3
4
|
import { createUserMessage, type ContentBlock } from '@deepseek-ai/dsh-llm'
|
|
4
|
-
import { defineTool, type
|
|
5
|
+
import { defineTool, type ToolDefinition, type ToolRunContext, type ValueSchemaSpec } from '@deepseek-ai/dsh-tools'
|
|
5
6
|
import {
|
|
6
7
|
ComputerConfirmationToken,
|
|
7
8
|
ComputerObservationId,
|
|
@@ -38,7 +39,7 @@ function deferVisionHandoff(exec: ToolRunContext, artifact: ComputerArtifact | u
|
|
|
38
39
|
'Do not inspect OCR executables or use bash, tesseract, screencapture, or an ad hoc Swift/Python OCR implementation.',
|
|
39
40
|
].join(' '),
|
|
40
41
|
}],
|
|
41
|
-
source: { kind: '
|
|
42
|
+
source: { kind: 'tool', callId: exec.callId },
|
|
42
43
|
}))
|
|
43
44
|
}
|
|
44
45
|
|
package/src/types.ts
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import type { Agent } from '@deepseek-ai/dsh-agent'
|
|
4
4
|
import type { Branded } from '@deepseek-ai/dsh-brand'
|
|
5
|
-
import type {
|
|
5
|
+
import type { ToolRunContext } from '@deepseek-ai/dsh-tools'
|
|
6
|
+
type CallId = ToolRunContext['callId']
|
|
6
7
|
|
|
7
8
|
/** Opaque identifier for one immutable observed UI state. */
|
|
8
9
|
export type ComputerObservationId = Branded<'ComputerObservationId'>
|
package/src/web.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { SettingsConflictError, type SettingsDescriptor } from '@deepseek-ai/dsh
|
|
|
6
6
|
import type {} from '@deepseek-ai/dsh-host-webserver'
|
|
7
7
|
import {
|
|
8
8
|
COMPUTER_USE_SETTINGS_NAMESPACE,
|
|
9
|
+
resolveConfig,
|
|
9
10
|
type ComputerUseConfig,
|
|
10
11
|
} from './config.ts'
|
|
11
12
|
import type { ComputerUseStatus } from './types.ts'
|
|
@@ -59,11 +60,17 @@ function requestError(res: ServerResponse, status: number, code: string, message
|
|
|
59
60
|
responseJson(res, status, { ok: false, error: { code, message } })
|
|
60
61
|
}
|
|
61
62
|
|
|
62
|
-
function sameOriginPost(req: IncomingMessage): boolean {
|
|
63
|
+
function sameOriginPost(req: IncomingMessage, authorizeUnmarkedPost?: (req: IncomingMessage) => boolean): boolean {
|
|
63
64
|
const fetchSite = req.headers['sec-fetch-site']
|
|
64
65
|
if (fetchSite === 'cross-site') return false
|
|
65
66
|
const origin = req.headers.origin
|
|
66
|
-
if (origin === undefined)
|
|
67
|
+
if (origin === undefined) {
|
|
68
|
+
if (fetchSite === 'same-origin' || fetchSite === 'same-site' || fetchSite === 'none') return true
|
|
69
|
+
// Desktop strips browser origin metadata before forwarding, but injects a
|
|
70
|
+
// Host-issued signed cookie. Verify it through Connection's own fence;
|
|
71
|
+
// mere Cookie header presence is not authentication.
|
|
72
|
+
return fetchSite === undefined && authorizeUnmarkedPost?.(req) === true
|
|
73
|
+
}
|
|
67
74
|
const host = req.headers.host
|
|
68
75
|
if (host === undefined) return false
|
|
69
76
|
try {
|
|
@@ -123,7 +130,10 @@ function isSettingsConflict(error: unknown): boolean {
|
|
|
123
130
|
|
|
124
131
|
/** Same-origin backend used by the optional client Settings section. */
|
|
125
132
|
export class ComputerUseWebBackend {
|
|
126
|
-
constructor(
|
|
133
|
+
constructor(
|
|
134
|
+
private readonly ctx: Context,
|
|
135
|
+
private readonly authorizeUnmarkedPost?: (req: IncomingMessage) => boolean,
|
|
136
|
+
) {}
|
|
127
137
|
|
|
128
138
|
/** Current browser-safe Settings and health state. */
|
|
129
139
|
snapshot(): ComputerUseSettingsSnapshot {
|
|
@@ -154,7 +164,7 @@ export class ComputerUseWebBackend {
|
|
|
154
164
|
requestError(res, 405, 'method-not-allowed', 'Use GET or POST')
|
|
155
165
|
return
|
|
156
166
|
}
|
|
157
|
-
if (!sameOriginPost(req)) {
|
|
167
|
+
if (!sameOriginPost(req, this.authorizeUnmarkedPost)) {
|
|
158
168
|
requestError(res, 403, 'origin-rejected', 'The request must originate from this DSH Web application')
|
|
159
169
|
return
|
|
160
170
|
}
|
|
@@ -167,6 +177,7 @@ export class ComputerUseWebBackend {
|
|
|
167
177
|
try {
|
|
168
178
|
if (parsed.action === 'save') {
|
|
169
179
|
if (!this.ctx.settings.writable) throw new Error('settings provider is read-only')
|
|
180
|
+
resolveConfig(parsed.value)
|
|
170
181
|
await this.ctx.settings.replace(COMPUTER_USE_SETTINGS_NAMESPACE, parsed.value as object, parsed.expectedRevision)
|
|
171
182
|
} else if (parsed.action === 'health') {
|
|
172
183
|
await this.ctx.computerUse.health(AbortSignal.timeout(30000))
|
|
@@ -184,8 +195,12 @@ export class ComputerUseWebBackend {
|
|
|
184
195
|
|
|
185
196
|
/** Attach the optional route when a Web host is present. */
|
|
186
197
|
export function installComputerUseWeb(ctx: Context): void {
|
|
187
|
-
|
|
188
|
-
|
|
198
|
+
ctx.inject(['webServer', 'connection'], (webCtx) => {
|
|
199
|
+
const connection = (webCtx as Context & {
|
|
200
|
+
connection?: { requestRejection?: (req: IncomingMessage) => 401 | 403 | undefined }
|
|
201
|
+
}).connection
|
|
202
|
+
const backend = new ComputerUseWebBackend(webCtx, (req) =>
|
|
203
|
+
typeof connection?.requestRejection === 'function' && connection.requestRejection(req) === undefined)
|
|
189
204
|
webCtx.effect(() => webCtx.webServer.register({
|
|
190
205
|
kind: 'exact',
|
|
191
206
|
path: COMPUTER_USE_SETTINGS_ROUTE,
|