dsh-draw 0.2.1 → 0.2.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-draw",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Unified static-image generation router for DeepSeek Harness: one image_generate tool with standard parameters, config-driven OpenAI-compatible engine routing (OpenAI Images, Zhipu CogView, and any compatible endpoint) with health-aware fallback, durable workspace attachment results, per-session quota accounting, an in-conversation result card, and a Plugins settings panel that stores API keys as credential references.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -57,7 +57,6 @@
57
57
  "platform": "web",
58
58
  "inject": [
59
59
  "@deepseek-ai/dsh-client-connection",
60
- "@deepseek-ai/dsh-client-runtime",
61
60
  "@deepseek-ai/dsh-client-locale",
62
61
  "@deepseek-ai/dsh-client-ui-slots",
63
62
  "@deepseek-ai/dsh-client-ui-settings",
@@ -89,7 +88,9 @@
89
88
  "attachments:write"
90
89
  ],
91
90
  "compatibility": {
92
- "dshVersions": ["0.1.1-rc.2"]
91
+ "dshVersions": [
92
+ "0.1.2-alpha.3"
93
+ ]
93
94
  },
94
95
  "capability": {
95
96
  "id": "image-generate-tool",
@@ -121,7 +122,7 @@
121
122
  },
122
123
  "packageManager": "pnpm@11.7.0",
123
124
  "peerDependencies": {
124
- "@deepseek-ai/cordis": "^4.0.1",
125
+ "@deepseek-ai/cordis": "^4.0.2",
125
126
  "@deepseek-ai/dsh-attachment": ">=0.1.0-rc.8 <0.2.0",
126
127
  "@deepseek-ai/dsh-brand": ">=0.1.0-rc.8 <0.2.0",
127
128
  "@deepseek-ai/dsh-credentials": ">=0.1.0-rc.8 <0.2.0",
@@ -129,10 +130,9 @@
129
130
  "@deepseek-ai/dsh-session": ">=0.1.0-rc.8 <0.2.0",
130
131
  "@deepseek-ai/dsh-tools": ">=0.1.0-rc.8 <0.2.0",
131
132
  "@deepseek-ai/dsh-typert-protocol": ">=0.1.0-rc.8 <0.2.0",
132
- "@deepseek-ai/schemastery": "^3.18.0",
133
+ "@deepseek-ai/schemastery": "^3.18.2",
133
134
  "@deepseek-ai/dsh-client-connection": ">=0.1.1-rc.2 <0.2.0",
134
135
  "@deepseek-ai/dsh-client-locale": ">=0.1.1-rc.2 <0.2.0",
135
- "@deepseek-ai/dsh-client-runtime": ">=0.1.1-rc.2 <0.2.0",
136
136
  "@deepseek-ai/dsh-client-ui-settings": ">=0.1.1-rc.2 <0.2.0",
137
137
  "@deepseek-ai/dsh-client-ui-slots": ">=0.1.1-rc.2 <0.2.0",
138
138
  "@deepseek-ai/dsh-client-ui-tool": ">=0.1.1-rc.2 <0.2.0"
@@ -144,9 +144,6 @@
144
144
  "@deepseek-ai/dsh-client-locale": {
145
145
  "optional": true
146
146
  },
147
- "@deepseek-ai/dsh-client-runtime": {
148
- "optional": true
149
- },
150
147
  "@deepseek-ai/dsh-client-ui-settings": {
151
148
  "optional": true
152
149
  },
@@ -162,28 +159,27 @@
162
159
  "typescript": "^7.0.2",
163
160
  "zod": "^4.4.3"
164
161
  },
165
- "devDependencies": {
166
- "@deepseek-ai/cordis": "^4.0.1",
162
+ "devDependencies": {"@deepseek-ai/dsh-util-values": "0.1.2-alpha.3",
163
+ "@deepseek-ai/cordis": "^4.0.2",
167
164
  "@deepseek-ai/cordis-plugin-include": "1.0.6",
168
165
  "@deepseek-ai/cordis-plugin-loader": "1.0.2",
169
- "@deepseek-ai/dsh-agent": "0.1.1-rc.2",
170
- "@deepseek-ai/dsh-api-remotes": "0.1.1-rc.2",
171
- "@deepseek-ai/dsh-attachment": "0.1.1-rc.2",
172
- "@deepseek-ai/dsh-attachment-local": "0.1.1-rc.2",
173
- "@deepseek-ai/dsh-brand": "0.1.1-rc.2",
174
- "@deepseek-ai/dsh-client-connection": "0.1.1-rc.2",
175
- "@deepseek-ai/dsh-client-locale": "0.1.1-rc.2",
176
- "@deepseek-ai/dsh-client-runtime": "0.1.1-rc.2",
177
- "@deepseek-ai/dsh-client-ui-settings": "0.1.1-rc.2",
178
- "@deepseek-ai/dsh-client-ui-slots": "0.1.1-rc.2",
179
- "@deepseek-ai/dsh-client-ui-tool": "0.1.1-rc.2",
180
- "@deepseek-ai/dsh-credentials": "0.1.1-rc.2",
181
- "@deepseek-ai/dsh-credentials-local": "0.1.1-rc.2",
182
- "@deepseek-ai/dsh-llm": "0.1.1-rc.2",
183
- "@deepseek-ai/dsh-session": "0.1.1-rc.2",
184
- "@deepseek-ai/dsh-tools": "0.1.1-rc.2",
185
- "@deepseek-ai/dsh-typert-protocol": "0.1.1-rc.2",
186
- "@deepseek-ai/schemastery": "^3.18.0",
166
+ "@deepseek-ai/dsh-agent": "0.1.2-alpha.3",
167
+ "@deepseek-ai/dsh-api-remotes": "0.1.2-alpha.3",
168
+ "@deepseek-ai/dsh-attachment": "0.1.2-alpha.3",
169
+ "@deepseek-ai/dsh-attachment-local": "0.1.2-alpha.3",
170
+ "@deepseek-ai/dsh-brand": "0.1.2-alpha.3",
171
+ "@deepseek-ai/dsh-client-connection": "0.1.2-alpha.3",
172
+ "@deepseek-ai/dsh-client-locale": "0.1.2-alpha.3",
173
+ "@deepseek-ai/dsh-client-ui-settings": "0.1.2-alpha.3",
174
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.2-alpha.3",
175
+ "@deepseek-ai/dsh-client-ui-tool": "0.1.2-alpha.3",
176
+ "@deepseek-ai/dsh-credentials": "0.1.2-alpha.3",
177
+ "@deepseek-ai/dsh-credentials-local": "0.1.2-alpha.3",
178
+ "@deepseek-ai/dsh-llm": "0.1.2-alpha.3",
179
+ "@deepseek-ai/dsh-session": "0.1.2-alpha.3",
180
+ "@deepseek-ai/dsh-tools": "0.1.2-alpha.3",
181
+ "@deepseek-ai/dsh-typert-protocol": "0.1.2-alpha.3",
182
+ "@deepseek-ai/schemastery": "^3.18.2",
187
183
  "@types/node": "^22.19.0",
188
184
  "@types/react": "18.3.31",
189
185
  "@vitest/coverage-v8": "4.1.10",
@@ -206,5 +202,9 @@
206
202
  "verify:self-contained": "node scripts/verify-self-contained.mjs",
207
203
  "verify:artifacts": "node scripts/verify-artifacts.mjs"
208
204
  },
209
- "license": "Apache-2.0"
205
+ "license": "Apache-2.0",
206
+ "funding": {
207
+ "type": "individual",
208
+ "url": "https://github.com/sponsors/PerryLink"
209
+ }
210
210
  }
@@ -13,8 +13,7 @@
13
13
 
14
14
  import { createElement as h, useState, type ReactElement } from 'react'
15
15
  import type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'
16
- import type { ToolCallBlock } from '@deepseek-ai/dsh-client-runtime/client'
17
- import { presentDrawResult } from './present.ts'
16
+ import { presentDrawResult, type ToolCallBlock } from './present.ts'
18
17
 
19
18
  /**
20
19
  * Standard owner currency for one keyed tool view (mirror of the harness
@@ -8,7 +8,9 @@
8
8
  * @module dsh-draw/client
9
9
  */
10
10
 
11
- import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'
11
+ import type { Context as ClientContext } from '@deepseek-ai/cordis'
12
+ // Type-only: activates the ctx.remote Context merge (TypertClientRemote).
13
+ import type {} from '@deepseek-ai/dsh-api-remotes/client'
12
14
  import type {} from '@deepseek-ai/dsh-client-locale/client'
13
15
  // Type-only: pulls the 'settings.plugins.tab' SlotMap declaration into this
14
16
  // program so the tab registration typechecks against the real declaration.
@@ -44,6 +46,18 @@ export const name = 'dsh-draw'
44
46
  /** Services the browser half reads; `remote.draw` appears once the contribution mounts. */
45
47
  export const inject = ['slots', 'locale', 'remote', 'sessions']
46
48
 
49
+ /**
50
+ * Structural face of the slots service. Declared locally because the owning
51
+ * merge publishes differently across host lines (the removed
52
+ * `dsh-client-runtime` on 0.1.1-rc.2, the unpublished ui-renderer domain on
53
+ * 0.1.2-alpha.1); the runtime contract is structural and read through
54
+ * `ctx.get` without a dependency edge.
55
+ */
56
+ interface SlotsFace {
57
+ inject(slot: string, callback: () => unknown): void
58
+ register(options: unknown, component: unknown): unknown
59
+ }
60
+
47
61
  /**
48
62
  * Browser plugin body: dictionaries, the scoped stylesheet, the Remote
49
63
  * contribution mount, the result card, and the settings tab registration.
@@ -60,6 +74,7 @@ export async function apply(ctx: ClientContext): Promise<void> {
60
74
 
61
75
  ctx.inject(['remote.draw'], (scope) => {
62
76
  const t = scope.locale.bind(NS)
77
+ const slots = scope.get('slots') as SlotsFace
63
78
  const unwrap = <T>(result: RemoteResult<T>, method: string): T => {
64
79
  if (!result.ok) {
65
80
  throw new Error(`draw.${method} failed: ${result.error.code}: ${result.error.message}`)
@@ -67,7 +82,7 @@ export async function apply(ctx: ClientContext): Promise<void> {
67
82
  return result.value
68
83
  }
69
84
 
70
- scope.slots.inject('tool.call.toolview', () => scope.slots.register({
85
+ slots.inject('tool.call.toolview', () => slots.register({
71
86
  name: 'tool.call.toolview',
72
87
  key: 'image_generate',
73
88
  locale: NS,
@@ -80,7 +95,7 @@ export async function apply(ctx: ClientContext): Promise<void> {
80
95
  }),
81
96
  }, DrawResultCard))
82
97
 
83
- scope.slots.inject('settings.plugins.tab', () => scope.slots.register({
98
+ slots.inject('settings.plugins.tab', () => slots.register({
84
99
  name: 'settings.plugins.tab',
85
100
  id: 'draw',
86
101
  order: 40,
@@ -7,9 +7,50 @@
7
7
  * @module dsh-draw/client/present
8
8
  */
9
9
 
10
- import type { ToolCallBlock } from '@deepseek-ai/dsh-client-runtime/client'
11
10
  import type { DrawStatusSnapshot } from '../wire.ts'
12
11
 
12
+ /**
13
+ * Local structural contract for the frozen tool-call block the card reads.
14
+ * Declared locally because the owning packages publish the block union
15
+ * differently across host lines: the published `0.1.1-rc.2` line keeps it in
16
+ * the removed `dsh-client-runtime` package, and the unreleased
17
+ * `0.1.2-alpha.1` host owns it in the unpublished `dsh-client-ui-chat`. The
18
+ * runtime contract is structural — the presenter only discriminates on
19
+ * `kind` and reads the call head, error flag, and meta.
20
+ */
21
+
22
+ /** One frozen running tool call (no `kind`; the presenter's first guard drops it). */
23
+ export interface RunningToolCallBlock {
24
+ /** Tool call identity, stable across running and settled forms. */
25
+ callId: string
26
+ /** Wire tool name. */
27
+ name: string
28
+ /** Verbatim serialized arguments. */
29
+ argsRaw: string
30
+ /** Owning turn. */
31
+ turn: number
32
+ /** Owning step. */
33
+ step: number
34
+ /** Unix epoch ms when the call was logged. */
35
+ time: number
36
+ }
37
+
38
+ /** One settled tool result (fields the presenter reads). */
39
+ export interface SettledToolResultBlock {
40
+ kind: 'tool-result'
41
+ isError: boolean
42
+ /** Call head; null when window truncation left the call outside. */
43
+ call: { name: string; argsRaw: string } | null
44
+ /** Tool-owned presentation metadata (the card's engine/quota/limits facts). */
45
+ meta?: unknown
46
+ }
47
+
48
+ /** Frozen running-or-settled tool block. */
49
+ export type ToolCallBlock = RunningToolCallBlock | SettledToolResultBlock
50
+
51
+ /** Settled tool-result node only. */
52
+ export type ToolResultNode = SettledToolResultBlock
53
+
13
54
  /** One image of the presented result card. */
14
55
  export interface PresentedImage {
15
56
  attachmentId: string
package/src/event-gate.ts CHANGED
@@ -3,9 +3,11 @@
3
3
  * package's types, so it sits outside every host's `KNOWN_SESSION_EVENT_TYPES`:
4
4
  * hosts whose session reader validates a static whitelist (rc.6/rc.7) refuse to
5
5
  * reopen a session containing the event unless it carries the `ignorable`
6
- * envelope — and those hosts' `Session.append` cannot stamp it. The gate
7
- * therefore appends only when the type is host-known or a mount-time probe
8
- * proves envelope support; otherwise the accounting payload goes to the
6
+ * envelope — and those hosts' `Session.append` cannot stamp it. The
7
+ * `0.1.2-alpha.1` host removed the envelope entirely and fails closed on
8
+ * unknown event types at read, so the probe never reports support there. The
9
+ * gate therefore appends only when the type is host-known or a mount-time
10
+ * probe proves envelope support; otherwise the accounting payload goes to the
9
11
  * in-memory fallback ledger (see session-events.ts) so quota keeps working for
10
12
  * the live session without poisoning the log.
11
13
  *
@@ -44,15 +46,16 @@ export function makeEventGate(knownTypes: ReadonlySet<string>, ignorableAppend =
44
46
  }
45
47
  }
46
48
 
47
- /** The append face the probe needs; rc.6 types declare no envelope parameter. */
49
+ /** The append face the probe needs; envelope-less hosts declare no options parameter. */
48
50
  type EnvelopeAppend = (type: string, data: unknown, opts: { ignorable: boolean }) => { ignorable?: boolean } | undefined
49
51
 
50
52
  /**
51
53
  * Probe whether the host `Session.append` stamps the ignorable envelope. Runs
52
54
  * on a fully detached SessionStore — never host persistence — appending one
53
55
  * probe event with `{ ignorable: true }` and reading the marker back. rc.6's
54
- * append silently drops the unknown options key (probe false); every failure
55
- * is contained as "unsupported".
56
+ * append silently drops the unknown options key (probe false), and the
57
+ * envelope-less `0.1.2-alpha.1` append takes no options at all (probe false);
58
+ * every failure is contained as "unsupported".
56
59
  *
57
60
  * @returns whether the envelope is honored.
58
61
  */
@@ -1,17 +1,19 @@
1
1
  /**
2
2
  * The dsh-draw session event: one durable record per completed generation
3
3
  * (tool call or panel regenerate), appended to the owning session log. It is
4
- * log-only (`ignorable`) and exists so quota accounting and the durable audit
5
- * trail are reconstructable from the log alone. The model-visible input and
6
- * output of the call ride the loop-owned `tool/call` and `tool/result`
7
- * events; this event carries the accounting facts those events do not.
4
+ * log-only and exists so quota accounting and the durable audit trail are
5
+ * reconstructable from the log alone. The model-visible input and output of
6
+ * the call ride the loop-owned `tool/call` and `tool/result` events; this
7
+ * event carries the accounting facts those events do not.
8
8
  *
9
9
  * The event type is declared only here, so plugin paths append it through
10
10
  * {@link commitDrawGenerated}: the adaptive gate (event-gate.ts) appends only
11
- * when the host knows the type or honors the `ignorable` envelope, and
12
- * otherwise records the payload in the in-memory fallback ledger (live-session
13
- * quota keeps working; the durable trail resumes once the host gains a plugin
14
- * event surface).
11
+ * when the host knows the type or honors the `ignorable` envelope (pre-0.1.2
12
+ * host lines), and otherwise records the payload in the in-memory fallback
13
+ * ledger (live-session quota keeps working; the durable trail resumes once
14
+ * the host gains a plugin event surface). `0.1.2-alpha.1` removed the
15
+ * envelope and fails closed on unknown event types at read, so the probe
16
+ * reports no support there and every commit degrades to the ledger. On 0.1.2-alpha.3 the envelope field is retained for stored-log read compatibility only - its Session.append still cannot stamp the marker, so the gate behavior is unchanged.
15
17
  *
16
18
  * @module dsh-draw/session-events
17
19
  */
@@ -66,12 +68,13 @@ export function appendDrawGenerated(session: Session, event: DrawGeneratedEvent)
66
68
  return session.append('draw/generated', event)
67
69
  }
68
70
 
69
- /** The append face with the envelope option; rc.6 types declare none. */
71
+ /** The append face with the envelope option; only pre-0.1.2 host lines honor it. */
70
72
  type EnvelopeAppend = (type: string, data: unknown, opts: { ignorable: boolean }) => unknown
71
73
 
72
74
  /**
73
75
  * In-memory accounting ledger for hosts whose session log cannot carry
74
- * `draw/generated` safely (rc.6/rc.7 static whitelist, no ignorable envelope).
76
+ * `draw/generated` safely (rc.6/rc.7 static whitelist and the envelope-less
77
+ * `0.1.2-alpha.1`, which fails closed on unknown types at read).
75
78
  * Keyed by Session identity: the entries live exactly as long as the session.
76
79
  */
77
80
  const fallbackLedger = new WeakMap<Session, DrawGeneratedEvent[]>()
package/src/tool.ts CHANGED
@@ -11,7 +11,7 @@
11
11
 
12
12
  import { AttachmentId, type ImageAttachmentRef } from '@deepseek-ai/dsh-attachment'
13
13
  import type { ContentBlock } from '@deepseek-ai/dsh-llm'
14
- import type { JsonValue } from '@deepseek-ai/dsh-session'
14
+ import type { JsonValue } from '@deepseek-ai/dsh-util-values'
15
15
  import { defineTool } from '@deepseek-ai/dsh-tools'
16
16
  import type { ResolvedConfig } from './config.ts'
17
17
  import type { Drawer, DrawSuccess } from './drawer.ts'
package/src/version.ts CHANGED
@@ -8,4 +8,4 @@
8
8
  */
9
9
 
10
10
  /** Plugin version; must equal the `version` field in `package.json`. */
11
- export const PLUGIN_VERSION = '0.2.1'
11
+ export const PLUGIN_VERSION = '0.2.3'