dsh-draw 0.1.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 (104) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/LICENSE +201 -0
  3. package/README.es.md +194 -0
  4. package/README.hi.md +194 -0
  5. package/README.md +194 -0
  6. package/README.pt.md +194 -0
  7. package/README.zh.md +194 -0
  8. package/SECURITY.md +39 -0
  9. package/THIRD_PARTY_NOTICES.md +21 -0
  10. package/cordis.patch.yml +48 -0
  11. package/lib/client.js +4787 -0
  12. package/lib/client.js.map +1 -0
  13. package/lib/index.js +1429 -0
  14. package/lib/typert.host.js +26 -0
  15. package/lib/types/client/DrawResultCard.d.ts +58 -0
  16. package/lib/types/client/DrawResultCard.d.ts.map +1 -0
  17. package/lib/types/client/DrawResultCard.js +48 -0
  18. package/lib/types/client/DrawSettingsTab.d.ts +31 -0
  19. package/lib/types/client/DrawSettingsTab.d.ts.map +1 -0
  20. package/lib/types/client/DrawSettingsTab.js +129 -0
  21. package/lib/types/client/index.d.ts +35 -0
  22. package/lib/types/client/index.d.ts.map +1 -0
  23. package/lib/types/client/index.js +98 -0
  24. package/lib/types/client/locales.d.ts +14 -0
  25. package/lib/types/client/locales.d.ts.map +1 -0
  26. package/lib/types/client/locales.js +57 -0
  27. package/lib/types/client/present.d.ts +80 -0
  28. package/lib/types/client/present.d.ts.map +1 -0
  29. package/lib/types/client/present.js +86 -0
  30. package/lib/types/client/remote.d.ts +268 -0
  31. package/lib/types/client/remote.d.ts.map +1 -0
  32. package/lib/types/client/remote.js +15 -0
  33. package/lib/types/client/styles.d.ts +11 -0
  34. package/lib/types/client/styles.d.ts.map +1 -0
  35. package/lib/types/client/styles.js +43 -0
  36. package/lib/types/config.d.ts +160 -0
  37. package/lib/types/config.d.ts.map +1 -0
  38. package/lib/types/config.js +230 -0
  39. package/lib/types/drawer.d.ts +114 -0
  40. package/lib/types/drawer.d.ts.map +1 -0
  41. package/lib/types/drawer.js +138 -0
  42. package/lib/types/engine.d.ts +58 -0
  43. package/lib/types/engine.d.ts.map +1 -0
  44. package/lib/types/engine.js +135 -0
  45. package/lib/types/http.d.ts +89 -0
  46. package/lib/types/http.d.ts.map +1 -0
  47. package/lib/types/http.js +127 -0
  48. package/lib/types/index.d.ts +43 -0
  49. package/lib/types/index.d.ts.map +1 -0
  50. package/lib/types/index.js +78 -0
  51. package/lib/types/quota.d.ts +69 -0
  52. package/lib/types/quota.d.ts.map +1 -0
  53. package/lib/types/quota.js +56 -0
  54. package/lib/types/router.d.ts +141 -0
  55. package/lib/types/router.d.ts.map +1 -0
  56. package/lib/types/router.js +207 -0
  57. package/lib/types/sanitize.d.ts +40 -0
  58. package/lib/types/sanitize.d.ts.map +1 -0
  59. package/lib/types/sanitize.js +103 -0
  60. package/lib/types/service.d.ts +59 -0
  61. package/lib/types/service.d.ts.map +1 -0
  62. package/lib/types/service.js +131 -0
  63. package/lib/types/session-events.d.ts +66 -0
  64. package/lib/types/session-events.d.ts.map +1 -0
  65. package/lib/types/session-events.js +32 -0
  66. package/lib/types/tool.d.ts +30 -0
  67. package/lib/types/tool.d.ts.map +1 -0
  68. package/lib/types/tool.js +131 -0
  69. package/lib/types/translate.d.ts +64 -0
  70. package/lib/types/translate.d.ts.map +1 -0
  71. package/lib/types/translate.js +56 -0
  72. package/lib/types/typert.host.d.ts +250 -0
  73. package/lib/types/typert.host.d.ts.map +1 -0
  74. package/lib/types/typert.host.js +23 -0
  75. package/lib/types/version.d.ts +10 -0
  76. package/lib/types/version.d.ts.map +1 -0
  77. package/lib/types/version.js +9 -0
  78. package/lib/types/wire.d.ts +699 -0
  79. package/lib/types/wire.d.ts.map +1 -0
  80. package/lib/types/wire.js +273 -0
  81. package/lib/wire-Cc4JZ3jR.js +4370 -0
  82. package/package.json +179 -0
  83. package/src/client/DrawResultCard.tsx +100 -0
  84. package/src/client/DrawSettingsTab.tsx +159 -0
  85. package/src/client/index.ts +123 -0
  86. package/src/client/locales.ts +84 -0
  87. package/src/client/present.ts +137 -0
  88. package/src/client/remote.ts +44 -0
  89. package/src/client/styles.ts +44 -0
  90. package/src/config.ts +358 -0
  91. package/src/drawer.ts +234 -0
  92. package/src/engine.ts +182 -0
  93. package/src/http.ts +161 -0
  94. package/src/index.ts +93 -0
  95. package/src/quota.ts +98 -0
  96. package/src/router.ts +309 -0
  97. package/src/sanitize.ts +113 -0
  98. package/src/service.ts +169 -0
  99. package/src/session-events.ts +70 -0
  100. package/src/tool.ts +145 -0
  101. package/src/translate.ts +101 -0
  102. package/src/typert.host.ts +25 -0
  103. package/src/version.ts +10 -0
  104. package/src/wire.ts +417 -0
package/src/wire.ts ADDED
@@ -0,0 +1,417 @@
1
+ /**
2
+ * The panel's wire vocabulary: the snapshot and action types served over the
3
+ * `draw` Remote namespace, their zod v4 validation schemas (the strict codecs
4
+ * both Typert faces carry), and the invocation descriptors shared verbatim by
5
+ * the host `./typert` manifest and the client Remote contribution. One
6
+ * canonical source for both faces keeps the host and client codecs from ever
7
+ * drifting apart.
8
+ *
9
+ * @module dsh-draw/wire
10
+ */
11
+
12
+ import { z } from 'zod'
13
+ import type { InvocationDescriptor } from '@deepseek-ai/dsh-typert-protocol'
14
+ import type { AttemptView, EngineStatus, ProbeOutcome } from './router.ts'
15
+ import type { QuotaLimits, QuotaState } from './quota.ts'
16
+ import type { DrawImage } from './drawer.ts'
17
+
18
+ /** Credential facts for one engine, safe for configuration UIs — never the value. */
19
+ export interface EngineCredentialView {
20
+ /** Whether the reference currently resolves to a value. */
21
+ configured: boolean
22
+ /** Source layer supplying the value; absent while unconfigured. */
23
+ source?: string
24
+ /** Whether the panel may store a value for this reference. */
25
+ writable: boolean
26
+ }
27
+
28
+ /** One engine's panel view. */
29
+ export interface EngineView {
30
+ /** Engine id. */
31
+ id: string
32
+ /** Engine model name. */
33
+ model: string
34
+ /** Sanitized API root. */
35
+ baseUrl: string
36
+ /** Credential reference (environment-variable name); never a value. */
37
+ apiKeyRef: string
38
+ /** Whether the router may use this engine. */
39
+ enabled: boolean
40
+ /** Whether the router prefers this engine. */
41
+ preferred: boolean
42
+ /** Credential resolution facts. */
43
+ credential: EngineCredentialView
44
+ /** Routing health. */
45
+ health: {
46
+ /** Consecutive failures since the last success. */
47
+ consecutiveFailures: number
48
+ /** Epoch ms until which the engine is in cooldown; `null` = not cooling down. */
49
+ cooldownUntil: number | null
50
+ /** Display-safe last failure detail; `null` = none. */
51
+ lastError: string | null
52
+ /** HTTP status of the last failure; `null` = none. */
53
+ lastStatus: number | null
54
+ }
55
+ }
56
+
57
+ /** The complete panel snapshot served by `draw/status`. */
58
+ export interface DrawStatusSnapshot {
59
+ /** Plugin build version. */
60
+ pluginVersion: string
61
+ /** Engine chain in config order. */
62
+ engines: readonly EngineView[]
63
+ /** Effective quota limits. */
64
+ quota: {
65
+ /** Per-session generation-call cap. */
66
+ maxGenerationsPerSession: number
67
+ /** Per-session image-byte cap. */
68
+ maxBytesPerSession: number
69
+ }
70
+ /** Per-generation request timeout in milliseconds. */
71
+ requestTimeoutMs: number
72
+ /** Cap on images one call may produce. */
73
+ maxImagesPerCall: number
74
+ }
75
+
76
+ /** Strict wire schema for {@link DrawStatusSnapshot} (zod v4, both Typert faces). */
77
+ export const DRAW_STATUS_SCHEMA = z.object({
78
+ pluginVersion: z.string(),
79
+ engines: z.array(z.object({
80
+ id: z.string(),
81
+ model: z.string(),
82
+ baseUrl: z.string(),
83
+ apiKeyRef: z.string(),
84
+ enabled: z.boolean(),
85
+ preferred: z.boolean(),
86
+ credential: z.object({
87
+ configured: z.boolean(),
88
+ source: z.string().optional(),
89
+ writable: z.boolean(),
90
+ }),
91
+ health: z.object({
92
+ consecutiveFailures: z.number().int(),
93
+ cooldownUntil: z.number().int().nullable(),
94
+ lastError: z.string().nullable(),
95
+ lastStatus: z.number().int().nullable(),
96
+ }),
97
+ })),
98
+ quota: z.object({
99
+ maxGenerationsPerSession: z.number().int(),
100
+ maxBytesPerSession: z.number().int(),
101
+ }),
102
+ requestTimeoutMs: z.number().int(),
103
+ maxImagesPerCall: z.number().int(),
104
+ })
105
+
106
+ /** Result of the `draw/probe` invocation: one engine's connectivity check. */
107
+ export interface DrawProbeResult {
108
+ /** Engine id. */
109
+ engineId: string
110
+ /** Whether the endpoint answered with any HTTP status. */
111
+ reachable: boolean
112
+ /** HTTP status when one existed. */
113
+ httpStatus: number | null
114
+ /** Sanitized probed URL. */
115
+ target: string
116
+ /** Display-safe note. */
117
+ note: string
118
+ /** Whether the credential reference resolved at probe time. */
119
+ credentialConfigured: boolean
120
+ }
121
+
122
+ /** Strict wire schema for {@link DrawProbeResult}. */
123
+ export const DRAW_PROBE_SCHEMA = z.object({
124
+ engineId: z.string(),
125
+ reachable: z.boolean(),
126
+ httpStatus: z.number().int().nullable(),
127
+ target: z.string(),
128
+ note: z.string(),
129
+ credentialConfigured: z.boolean(),
130
+ })
131
+
132
+ /** Result of the `draw/setCredential` and `draw/unsetCredential` invocations. */
133
+ export interface CredentialActionResult {
134
+ /** Engine id the action targeted. */
135
+ engineId: string
136
+ /** Credential reference the value was stored under / removed from. */
137
+ reference: string
138
+ /** Display-safe confirmation. */
139
+ note: string
140
+ }
141
+
142
+ /** Strict wire schema for {@link CredentialActionResult}. */
143
+ export const CREDENTIAL_ACTION_SCHEMA = z.object({
144
+ engineId: z.string(),
145
+ reference: z.string(),
146
+ note: z.string(),
147
+ })
148
+
149
+ /** One regenerated image as the wire carries it (lossless JSON only). */
150
+ export interface DrawImageWire {
151
+ /** Opaque attachment id. */
152
+ attachmentId: string
153
+ /** Verified media type. */
154
+ mediaType: string
155
+ /** Exact byte length. */
156
+ bytes: number
157
+ /** Intrinsic width in pixels. */
158
+ width: number
159
+ /** Intrinsic height in pixels. */
160
+ height: number
161
+ /** Display name. */
162
+ name?: string
163
+ }
164
+
165
+ /** The regenerate result served by `draw/regenerate`. */
166
+ export interface DrawRegenerateResult {
167
+ /** Engine id that produced the images. */
168
+ engine: string
169
+ /** Engine model name. */
170
+ model: string
171
+ /** Standard size vocabulary value of the request. */
172
+ size: string
173
+ /** Durable result images. */
174
+ images: readonly DrawImageWire[]
175
+ /** Usage after this generation committed. */
176
+ quota: QuotaState
177
+ /** Quota limits in force. */
178
+ quotaLimits: QuotaLimits
179
+ /** Whether an earlier engine in the chain failed first. */
180
+ fallbackUsed: boolean
181
+ /** Engine round-trip latency in milliseconds. */
182
+ elapsedMs: number
183
+ /** Every router attempt in chain order (display-safe). */
184
+ attempts: readonly AttemptView[]
185
+ }
186
+
187
+ /** Strict wire schema for {@link DrawRegenerateResult}. */
188
+ export const DRAW_REGENERATE_SCHEMA = z.object({
189
+ engine: z.string(),
190
+ model: z.string(),
191
+ size: z.string(),
192
+ images: z.array(z.object({
193
+ attachmentId: z.string(),
194
+ mediaType: z.string(),
195
+ bytes: z.number().int(),
196
+ width: z.number().int(),
197
+ height: z.number().int(),
198
+ name: z.string().optional(),
199
+ })),
200
+ quota: z.object({ generations: z.number().int(), bytes: z.number().int() }),
201
+ quotaLimits: z.object({ maxGenerations: z.number().int(), maxBytes: z.number().int() }),
202
+ fallbackUsed: z.boolean(),
203
+ elapsedMs: z.number().int(),
204
+ attempts: z.array(z.object({
205
+ engine: z.string(),
206
+ phase: z.union([z.literal('credential'), z.literal('request'), z.literal('parse')]).optional(),
207
+ code: z.string(),
208
+ message: z.string().optional(),
209
+ status: z.number().int().optional(),
210
+ })),
211
+ })
212
+
213
+ /** Project a draw outcome image onto the wire shape. */
214
+ export function imageToWire(image: DrawImage): DrawImageWire {
215
+ return {
216
+ attachmentId: image.attachmentId,
217
+ mediaType: image.mediaType,
218
+ bytes: image.bytes,
219
+ width: image.width,
220
+ height: image.height,
221
+ ...(image.name !== undefined ? { name: image.name } : {}),
222
+ }
223
+ }
224
+
225
+ /** Project a router engine status onto the panel view shape. */
226
+ export function statusToView(status: EngineStatus, engine: { id: string; model: string; baseUrl: string; apiKeyRef: string; enabled: boolean; preferred: boolean }, credential: EngineCredentialView): EngineView {
227
+ return {
228
+ id: engine.id,
229
+ model: engine.model,
230
+ baseUrl: engine.baseUrl,
231
+ apiKeyRef: engine.apiKeyRef,
232
+ enabled: engine.enabled,
233
+ preferred: engine.preferred,
234
+ credential,
235
+ health: {
236
+ consecutiveFailures: status.consecutiveFailures,
237
+ cooldownUntil: status.cooldownUntil,
238
+ lastError: status.lastError,
239
+ lastStatus: status.lastStatus,
240
+ },
241
+ }
242
+ }
243
+
244
+ /** Project a probe outcome onto the wire shape. */
245
+ export function probeToWire(probe: ProbeOutcome): DrawProbeResult {
246
+ return {
247
+ engineId: probe.engineId,
248
+ reachable: probe.reachable,
249
+ httpStatus: probe.httpStatus,
250
+ target: probe.target,
251
+ note: probe.note,
252
+ credentialConfigured: probe.credentialConfigured,
253
+ }
254
+ }
255
+
256
+ /** JSON codec for one engine id. */
257
+ const ENGINE_ID_CODEC = z.string()
258
+
259
+ /** JSON codec for one credential value (non-empty). */
260
+ const CREDENTIAL_VALUE_CODEC = z.string().min(1)
261
+
262
+ /** JSON codec for regenerate arguments: the original tool args, verbatim. */
263
+ const REGENERATE_ARGS_CODEC = z.object({
264
+ prompt: z.string().min(1),
265
+ size: z.string().optional(),
266
+ count: z.number().int().optional(),
267
+ quality: z.string().optional(),
268
+ style: z.string().optional(),
269
+ engine: z.string().optional(),
270
+ }).passthrough()
271
+
272
+ /** JSON codec for one session id (the wire carries the branded id as a string). */
273
+ const SESSION_ID_CODEC = z.string().min(1)
274
+
275
+ /**
276
+ * The `draw/status` invocation descriptor: the settings-panel snapshot.
277
+ */
278
+ export const DRAW_STATUS_DESCRIPTOR = Object.freeze({
279
+ id: 'dsh-draw#draw/status',
280
+ service: 'dsh-draw',
281
+ namespace: 'draw',
282
+ method: 'status',
283
+ invocation: Object.freeze({ kind: 'direct' }),
284
+ parameters: Object.freeze([]),
285
+ result: Object.freeze({
286
+ mode: 'strict',
287
+ typeSymbol: 'dsh-draw/types#DrawStatusSnapshot',
288
+ schema: DRAW_STATUS_SCHEMA,
289
+ }),
290
+ sourceLocation: Object.freeze({ file: 'src/wire.ts', line: 1, column: 1 }),
291
+ } as const) satisfies InvocationDescriptor
292
+
293
+ /**
294
+ * The `draw/probe` invocation descriptor: one engine's connectivity check.
295
+ */
296
+ export const DRAW_PROBE_DESCRIPTOR = Object.freeze({
297
+ id: 'dsh-draw#draw/probe',
298
+ service: 'dsh-draw',
299
+ namespace: 'draw',
300
+ method: 'probe',
301
+ invocation: Object.freeze({ kind: 'direct' }),
302
+ parameters: Object.freeze([Object.freeze({
303
+ name: 'engineId',
304
+ wire: 'engineId',
305
+ source: 'json',
306
+ codec: Object.freeze({
307
+ mode: 'strict',
308
+ typeSymbol: 'dsh-draw/types#EngineId',
309
+ schema: ENGINE_ID_CODEC,
310
+ }),
311
+ } satisfies InvocationDescriptor['parameters'][number])]),
312
+ result: Object.freeze({
313
+ mode: 'strict',
314
+ typeSymbol: 'dsh-draw/types#DrawProbeResult',
315
+ schema: DRAW_PROBE_SCHEMA,
316
+ }),
317
+ sourceLocation: Object.freeze({ file: 'src/wire.ts', line: 1, column: 1 }),
318
+ } as const) satisfies InvocationDescriptor
319
+
320
+ /**
321
+ * The `draw/setCredential` invocation descriptor: store an API key under the
322
+ * engine's credential reference. The value crosses the wire once and is never
323
+ * logged, snapshotted, or returned.
324
+ */
325
+ export const DRAW_SET_CREDENTIAL_DESCRIPTOR = Object.freeze({
326
+ id: 'dsh-draw#draw/setCredential',
327
+ service: 'dsh-draw',
328
+ namespace: 'draw',
329
+ method: 'setCredential',
330
+ invocation: Object.freeze({ kind: 'direct' }),
331
+ parameters: Object.freeze([
332
+ Object.freeze({
333
+ name: 'engineId',
334
+ wire: 'engineId',
335
+ source: 'json',
336
+ codec: Object.freeze({ mode: 'strict', typeSymbol: 'dsh-draw/types#EngineId', schema: ENGINE_ID_CODEC }),
337
+ } satisfies InvocationDescriptor['parameters'][number]),
338
+ Object.freeze({
339
+ name: 'value',
340
+ wire: 'value',
341
+ source: 'json',
342
+ codec: Object.freeze({ mode: 'strict', typeSymbol: 'dsh-draw/types#CredentialValue', schema: CREDENTIAL_VALUE_CODEC }),
343
+ } satisfies InvocationDescriptor['parameters'][number]),
344
+ ]),
345
+ result: Object.freeze({
346
+ mode: 'strict',
347
+ typeSymbol: 'dsh-draw/types#CredentialActionResult',
348
+ schema: CREDENTIAL_ACTION_SCHEMA,
349
+ }),
350
+ sourceLocation: Object.freeze({ file: 'src/wire.ts', line: 1, column: 1 }),
351
+ } as const) satisfies InvocationDescriptor
352
+
353
+ /**
354
+ * The `draw/unsetCredential` invocation descriptor: remove a stored API key.
355
+ */
356
+ export const DRAW_UNSET_CREDENTIAL_DESCRIPTOR = Object.freeze({
357
+ id: 'dsh-draw#draw/unsetCredential',
358
+ service: 'dsh-draw',
359
+ namespace: 'draw',
360
+ method: 'unsetCredential',
361
+ invocation: Object.freeze({ kind: 'direct' }),
362
+ parameters: Object.freeze([Object.freeze({
363
+ name: 'engineId',
364
+ wire: 'engineId',
365
+ source: 'json',
366
+ codec: Object.freeze({ mode: 'strict', typeSymbol: 'dsh-draw/types#EngineId', schema: ENGINE_ID_CODEC }),
367
+ } satisfies InvocationDescriptor['parameters'][number])]),
368
+ result: Object.freeze({
369
+ mode: 'strict',
370
+ typeSymbol: 'dsh-draw/types#CredentialActionResult',
371
+ schema: CREDENTIAL_ACTION_SCHEMA,
372
+ }),
373
+ sourceLocation: Object.freeze({ file: 'src/wire.ts', line: 1, column: 1 }),
374
+ } as const) satisfies InvocationDescriptor
375
+
376
+ /**
377
+ * The `draw/regenerate` invocation descriptor: re-run a generation from the
378
+ * result card with the original tool args. The host re-runs the full drawer
379
+ * path (quota, routing, attachment storage, audit event) so a regenerate is
380
+ * as durable and accounted as a tool call.
381
+ */
382
+ export const DRAW_REGENERATE_DESCRIPTOR = Object.freeze({
383
+ id: 'dsh-draw#draw/regenerate',
384
+ service: 'dsh-draw',
385
+ namespace: 'draw',
386
+ method: 'regenerate',
387
+ invocation: Object.freeze({ kind: 'direct' }),
388
+ parameters: Object.freeze([
389
+ Object.freeze({
390
+ name: 'sessionId',
391
+ wire: 'sessionId',
392
+ source: 'json',
393
+ codec: Object.freeze({ mode: 'strict', typeSymbol: 'dsh-draw/types#SessionId', schema: SESSION_ID_CODEC }),
394
+ } satisfies InvocationDescriptor['parameters'][number]),
395
+ Object.freeze({
396
+ name: 'args',
397
+ wire: 'args',
398
+ source: 'json',
399
+ codec: Object.freeze({ mode: 'strict', typeSymbol: 'dsh-draw/types#RegenerateArgs', schema: REGENERATE_ARGS_CODEC }),
400
+ } satisfies InvocationDescriptor['parameters'][number]),
401
+ ]),
402
+ result: Object.freeze({
403
+ mode: 'strict',
404
+ typeSymbol: 'dsh-draw/types#DrawRegenerateResult',
405
+ schema: DRAW_REGENERATE_SCHEMA,
406
+ }),
407
+ sourceLocation: Object.freeze({ file: 'src/wire.ts', line: 1, column: 1 }),
408
+ } as const) satisfies InvocationDescriptor
409
+
410
+ /** The canonical invocation list both Typert faces register. */
411
+ export const DRAW_INVOCATIONS = Object.freeze([
412
+ DRAW_STATUS_DESCRIPTOR,
413
+ DRAW_PROBE_DESCRIPTOR,
414
+ DRAW_SET_CREDENTIAL_DESCRIPTOR,
415
+ DRAW_UNSET_CREDENTIAL_DESCRIPTOR,
416
+ DRAW_REGENERATE_DESCRIPTOR,
417
+ ])