@mengruo/dsh-vision-toolkit 0.1.5 → 0.1.6-beta.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.
Files changed (48) hide show
  1. package/assets/1.mp4 +0 -0
  2. package/assets/skill/SKILL.md +37 -5
  3. package/docs/plan-per-tool-visibility.md +82 -0
  4. package/lib/client.js +53 -3
  5. package/lib/client.js.map +1 -1
  6. package/lib/config.js +17 -0
  7. package/lib/config.js.map +1 -1
  8. package/lib/exposure.js +35 -8
  9. package/lib/exposure.js.map +1 -1
  10. package/lib/index.js +1 -1
  11. package/lib/index.js.map +1 -1
  12. package/lib/paths.js +9 -0
  13. package/lib/paths.js.map +1 -1
  14. package/lib/runtime.js +175 -1
  15. package/lib/runtime.js.map +1 -1
  16. package/lib/tools.js +116 -4
  17. package/lib/tools.js.map +1 -1
  18. package/lib/types/client/index.d.ts +24 -1
  19. package/lib/types/client/index.d.ts.map +1 -1
  20. package/lib/types/config.d.ts +26 -0
  21. package/lib/types/config.d.ts.map +1 -1
  22. package/lib/types/exposure.d.ts +14 -2
  23. package/lib/types/exposure.d.ts.map +1 -1
  24. package/lib/types/index.d.ts.map +1 -1
  25. package/lib/types/paths.d.ts +7 -0
  26. package/lib/types/paths.d.ts.map +1 -1
  27. package/lib/types/runtime.d.ts +38 -0
  28. package/lib/types/runtime.d.ts.map +1 -1
  29. package/lib/types/tools.d.ts +22 -1
  30. package/lib/types/tools.d.ts.map +1 -1
  31. package/lib/types/video.d.ts +78 -0
  32. package/lib/types/video.d.ts.map +1 -0
  33. package/lib/types/web.d.ts +1 -0
  34. package/lib/types/web.d.ts.map +1 -1
  35. package/lib/video.js +169 -0
  36. package/lib/video.js.map +1 -0
  37. package/lib/web.js +47 -4
  38. package/lib/web.js.map +1 -1
  39. package/package.json +2 -1
  40. package/src/client/index.tsx +72 -1
  41. package/src/config.ts +43 -0
  42. package/src/exposure.ts +34 -9
  43. package/src/index.ts +10 -5
  44. package/src/paths.ts +11 -0
  45. package/src/runtime.ts +196 -0
  46. package/src/tools.ts +144 -3
  47. package/src/video.ts +222 -0
  48. package/src/web.ts +53 -5
package/src/web.ts CHANGED
@@ -131,7 +131,13 @@ interface StorageTestRequest {
131
131
  action: 'test-storage'
132
132
  }
133
133
 
134
- type SettingsRequest = SaveRequest | HealthRequest | CredentialRequest | DeleteCredentialRequest | CheckUpdateRequest | ApplyUpdateRequest | StorageTestRequest
134
+ interface VideoTestRequest {
135
+ action: 'test-video'
136
+ /** 0-based provider index; when absent, the primary provider is tested. */
137
+ providerIndex?: number
138
+ }
139
+
140
+ type SettingsRequest = SaveRequest | HealthRequest | CredentialRequest | DeleteCredentialRequest | CheckUpdateRequest | ApplyUpdateRequest | StorageTestRequest | VideoTestRequest
135
141
 
136
142
  interface JsonError {
137
143
  ok: false
@@ -272,6 +278,16 @@ function parseRequest(value: unknown): SettingsRequest {
272
278
  return { action: 'apply-update', expectedVersion: value.expectedVersion.trim() }
273
279
  }
274
280
  if (value.action === 'test-storage') return { action: 'test-storage' }
281
+ if (value.action === 'test-video') {
282
+ const providerIndex = value.providerIndex
283
+ if (providerIndex !== undefined && (!Number.isSafeInteger(providerIndex) || (providerIndex as number) < 0)) {
284
+ throw new TypeError('test-video.providerIndex must be a non-negative integer')
285
+ }
286
+ return {
287
+ action: 'test-video',
288
+ ...(providerIndex === undefined ? {} : { providerIndex: providerIndex as number }),
289
+ }
290
+ }
275
291
  throw new TypeError(`unsupported action: ${value.action}`)
276
292
  }
277
293
 
@@ -459,6 +475,33 @@ export class VisionToolkitWebBackend {
459
475
  return this.manager.current().testObjectStorage()
460
476
  }
461
477
 
478
+ private async testVideo(request: VideoTestRequest, req: IncomingMessage): Promise<{ detail: string }> {
479
+ if (!this.manager.ready) throw new Error('runtime is not ready; fix Settings and save a valid configuration first')
480
+ const controller = new AbortController()
481
+ const abort = (): void => { controller.abort() }
482
+ req.once('aborted', abort)
483
+ req.socket.once('close', abort)
484
+ try {
485
+ const runtime = this.manager.current()
486
+ let provider: ResolvedProvider | undefined
487
+ if (request.providerIndex !== undefined) {
488
+ const resolved = resolveConfig(descriptorOf(this.ctx).value as VisionToolkitConfig)
489
+ provider = resolved.providers[request.providerIndex]
490
+ if (provider === undefined) {
491
+ throw new Error(`provider index ${request.providerIndex} is out of range`)
492
+ }
493
+ }
494
+ return await runtime.testVideoCall({
495
+ signal: controller.signal,
496
+ workspace: runtime.upstreamVersion.runtimeHome,
497
+ sessionId: 'vision-toolkit-settings',
498
+ }, provider)
499
+ } finally {
500
+ req.off('aborted', abort)
501
+ req.socket.off('close', abort)
502
+ }
503
+ }
504
+
462
505
  /** Handle the exact Settings route. */
463
506
  async handle(req: IncomingMessage, res: ServerResponse): Promise<void> {
464
507
  if (req.method === 'GET') {
@@ -494,6 +537,9 @@ export class VisionToolkitWebBackend {
494
537
  case 'test-storage':
495
538
  responseJson(res, 200, { ok: true, value: await this.testStorage() })
496
539
  break
540
+ case 'test-video':
541
+ responseJson(res, 200, { ok: true, value: await this.testVideo(parsed, req) })
542
+ break
497
543
  case 'save':
498
544
  responseJson(res, 200, { ok: true, value: await this.save(parsed) })
499
545
  break
@@ -524,14 +570,16 @@ export class VisionToolkitWebBackend {
524
570
  ? 'health-failed'
525
571
  : parsed.action === 'test-storage'
526
572
  ? 'storage-test-failed'
527
- : parsed.action === 'credential'
528
- ? 'credential-rejected'
529
- : 'settings-rejected'
573
+ : parsed.action === 'test-video'
574
+ ? 'video-test-failed'
575
+ : parsed.action === 'credential'
576
+ ? 'credential-rejected'
577
+ : 'settings-rejected'
530
578
  const updateConflict = updateError && ['update-in-progress', 'update-stale', 'update-unavailable', 'already-current'].includes(error.code)
531
579
  const updateGateway = updateError && error.code === 'update-check-failed'
532
580
  const status = settingsConflict || credentialConflict || updateConflict
533
581
  ? 409
534
- : parsed.action === 'health' || parsed.action === 'test-storage'
582
+ : parsed.action === 'health' || parsed.action === 'test-storage' || parsed.action === 'test-video'
535
583
  ? 503
536
584
  : updateGateway
537
585
  ? 502