dsh-draw 0.2.16 → 0.2.18
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 +24 -0
- package/README-es.md +13 -4
- package/README-hi.md +13 -4
- package/README-pt.md +13 -4
- package/README-zh.md +13 -4
- package/README.md +14 -4
- package/THIRD_PARTY_NOTICES.md +2 -2
- package/lib/client.js +75 -7
- package/lib/client.js.map +1 -1
- package/lib/index.js +1 -1
- package/lib/types/client/DrawResultCard.d.ts +44 -14
- package/lib/types/client/DrawResultCard.d.ts.map +1 -1
- package/lib/types/client/DrawResultCard.js +45 -9
- package/lib/types/client/locales.d.ts +1 -1
- package/lib/types/client/locales.d.ts.map +1 -1
- package/lib/types/client/locales.js +6 -0
- package/lib/types/client/present.d.ts +60 -0
- package/lib/types/client/present.d.ts.map +1 -1
- package/lib/types/client/present.js +74 -0
- package/lib/types/client/styles.d.ts.map +1 -1
- package/lib/types/client/styles.js +5 -0
- package/lib/types/version.d.ts +1 -1
- package/lib/types/version.js +1 -1
- package/package.json +22 -20
- package/src/client/DrawResultCard.tsx +76 -16
- package/src/client/locales.ts +9 -0
- package/src/client/present.ts +90 -0
- package/src/client/styles.ts +5 -0
- package/src/version.ts +1 -1
package/lib/index.js
CHANGED
|
@@ -1391,7 +1391,7 @@ var EngineRouter = class {
|
|
|
1391
1391
|
* @module dsh-draw/version
|
|
1392
1392
|
*/
|
|
1393
1393
|
/** Plugin version; must equal the `version` field in `package.json`. */
|
|
1394
|
-
const PLUGIN_VERSION = "0.2.
|
|
1394
|
+
const PLUGIN_VERSION = "0.2.18";
|
|
1395
1395
|
//#endregion
|
|
1396
1396
|
//#region src/service.ts
|
|
1397
1397
|
/**
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The keyed `image_generate` tool
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* The keyed `image_generate` tool view: engine/quota facts and the regenerate
|
|
3
|
+
* action once the call settles, and an in-flight row of its own while the
|
|
4
|
+
* arguments are still arriving. The images themselves are the attachment
|
|
5
|
+
* content blocks the shell already renders from the tool result, so the card
|
|
6
|
+
* only adds the accounting line and the action — it never duplicates image
|
|
7
|
+
* transport.
|
|
8
|
+
*
|
|
9
|
+
* The Host dispatches this keyed entry in EVERY stage of the call, and a keyed
|
|
10
|
+
* cell that is occupied never reaches the owner fallback — so the earlier
|
|
11
|
+
* stages cannot be answered with nothing without blanking the row.
|
|
6
12
|
*
|
|
7
13
|
* The `tool.call.toolview` SlotMap member is declared locally (mirroring the
|
|
8
14
|
* harness's own ui-tool contract declaration, which its package index does not
|
|
@@ -14,17 +20,32 @@ import { type ReactElement } from 'react';
|
|
|
14
20
|
import type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
15
21
|
import { type ToolCallBlock } from './present.js';
|
|
16
22
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
23
|
+
* Stage-specific tool data, mirror of the harness ui-tool contract
|
|
24
|
+
* `ToolCallPhaseProps`. The Host dispatches the SAME keyed entry in every
|
|
25
|
+
* stage, so the card's own contract must discriminate on `phase` exactly as
|
|
26
|
+
* the Host's does — a narrower declaration here hides the preparing owner
|
|
27
|
+
* rather than rejecting it (the slot is occupied for every stage).
|
|
28
|
+
*/
|
|
29
|
+
export type ToolCallPhaseProps = {
|
|
30
|
+
readonly phase: 'preparing';
|
|
31
|
+
readonly block: ToolCallBlock;
|
|
32
|
+
} | {
|
|
33
|
+
readonly phase: 'start';
|
|
34
|
+
readonly block: ToolCallBlock;
|
|
35
|
+
} | {
|
|
36
|
+
readonly phase: 'result';
|
|
37
|
+
readonly block: ToolCallBlock;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Common owner currency declared beside the phase share, mirror of the
|
|
41
|
+
* harness ui-tool contract `ToolCallCommonProps` (which the package index
|
|
42
|
+
* does not re-export — keep the shape identical so the declarations merge).
|
|
20
43
|
*/
|
|
21
|
-
export interface
|
|
22
|
-
/** Tool call identity, stable across
|
|
44
|
+
export interface ToolCallCommonProps {
|
|
45
|
+
/** Tool call identity, stable across all stages. */
|
|
23
46
|
callId: string;
|
|
24
47
|
/** Wire tool name and keyed dispatch value. */
|
|
25
48
|
toolName: string;
|
|
26
|
-
/** Frozen running call or settled result node. */
|
|
27
|
-
block: ToolCallBlock;
|
|
28
49
|
/** Session workspace root for relative summaries. */
|
|
29
50
|
cwd?: string;
|
|
30
51
|
/** Open a tool argument path through the host. */
|
|
@@ -32,6 +53,11 @@ export interface ToolCallOwnerProps {
|
|
|
32
53
|
/** Inspect this call in the trajectory view when available. */
|
|
33
54
|
inspect?: () => void;
|
|
34
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Standard owner currency for one keyed tool view: the common share plus the
|
|
58
|
+
* stage share, mirroring the harness ui-tool contract `ToolCallOwnerProps`.
|
|
59
|
+
*/
|
|
60
|
+
export type ToolCallOwnerProps = ToolCallCommonProps & ToolCallPhaseProps;
|
|
35
61
|
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
36
62
|
interface SlotMap {
|
|
37
63
|
/** Keyed atomic tool-call view, dispatched by the wire tool name. */
|
|
@@ -50,9 +76,13 @@ export interface DrawResultCardInjected {
|
|
|
50
76
|
/** Full component props assembled by the tool-view slot renderer. */
|
|
51
77
|
export type DrawResultCardProps = PropsRuntime<'tool.call.toolview'> & PropsLocale<'draw'> & InjectFace<DrawResultCardInjected>;
|
|
52
78
|
/**
|
|
53
|
-
* The keyed tool
|
|
54
|
-
*
|
|
55
|
-
*
|
|
79
|
+
* The keyed tool view. Dispatched by the wire tool name in EVERY stage of the
|
|
80
|
+
* call, so the card owes a presentation to the in-flight stages too: returning
|
|
81
|
+
* an empty node would leave the row blank, because an occupied keyed cell
|
|
82
|
+
* never reaches the Host's own generic row.
|
|
83
|
+
*
|
|
84
|
+
* @param props - owner currency (common + stage shares), locale, and injected bindings.
|
|
85
|
+
* @returns the in-flight row, or the settled result card.
|
|
56
86
|
*/
|
|
57
87
|
export declare function DrawResultCard(props: DrawResultCardProps): ReactElement;
|
|
58
88
|
//# sourceMappingURL=DrawResultCard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DrawResultCard.d.ts","sourceRoot":"","sources":["../../../src/client/DrawResultCard.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"DrawResultCard.d.ts","sourceRoot":"","sources":["../../../src/client/DrawResultCard.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAgC,KAAK,YAAY,EAAE,MAAM,OAAO,CAAA;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAC7F,OAAO,EAAoC,KAAK,aAAa,EAAsB,MAAM,cAAc,CAAA;AAEvG;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAC1B;IAAE,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAA;CAAE,GAC9D;IAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAA;CAAE,GAC1D;IAAE,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAA;CAAE,CAAA;AAE/D;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAA;IACd,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAA;IAChB,qDAAqD;IACrD,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,kDAAkD;IAClD,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB;AAED;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,mBAAmB,GAAG,kBAAkB,CAAA;AAEzE,OAAO,QAAQ,kCAAkC,CAAC;IAChD,UAAU,OAAO;QACf,qEAAqE;QACrE,oBAAoB,EAAE;YAAE,IAAI,EAAE,OAAO,CAAC;YAAC,KAAK,EAAE,SAAS,CAAC;YAAC,KAAK,EAAE,kBAAkB,CAAA;SAAE,CAAA;KACrF;CACF;AAED,8EAA8E;AAC9E,MAAM,WAAW,sBAAsB;IACrC,yEAAyE;IACzE,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7D;AAED,qEAAqE;AACrE,MAAM,MAAM,mBAAmB,GAC7B,YAAY,CAAC,oBAAoB,CAAC,GAChC,WAAW,CAAC,MAAM,CAAC,GACnB,UAAU,CAAC,sBAAsB,CAAC,CAAA;AAEtC;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,YAAY,CAiBvE"}
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The keyed `image_generate` tool
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* The keyed `image_generate` tool view: engine/quota facts and the regenerate
|
|
3
|
+
* action once the call settles, and an in-flight row of its own while the
|
|
4
|
+
* arguments are still arriving. The images themselves are the attachment
|
|
5
|
+
* content blocks the shell already renders from the tool result, so the card
|
|
6
|
+
* only adds the accounting line and the action — it never duplicates image
|
|
7
|
+
* transport.
|
|
8
|
+
*
|
|
9
|
+
* The Host dispatches this keyed entry in EVERY stage of the call, and a keyed
|
|
10
|
+
* cell that is occupied never reaches the owner fallback — so the earlier
|
|
11
|
+
* stages cannot be answered with nothing without blanking the row.
|
|
6
12
|
*
|
|
7
13
|
* The `tool.call.toolview` SlotMap member is declared locally (mirroring the
|
|
8
14
|
* harness's own ui-tool contract declaration, which its package index does not
|
|
@@ -11,19 +17,49 @@
|
|
|
11
17
|
* @module dsh-draw/client/DrawResultCard
|
|
12
18
|
*/
|
|
13
19
|
import { createElement as h, useState } from 'react';
|
|
14
|
-
import { presentDrawResult } from './present.js';
|
|
20
|
+
import { presentDrawResult, toolCallPhase } from './present.js';
|
|
15
21
|
/**
|
|
16
|
-
* The keyed tool
|
|
17
|
-
*
|
|
18
|
-
*
|
|
22
|
+
* The keyed tool view. Dispatched by the wire tool name in EVERY stage of the
|
|
23
|
+
* call, so the card owes a presentation to the in-flight stages too: returning
|
|
24
|
+
* an empty node would leave the row blank, because an occupied keyed cell
|
|
25
|
+
* never reaches the Host's own generic row.
|
|
26
|
+
*
|
|
27
|
+
* @param props - owner currency (common + stage shares), locale, and injected bindings.
|
|
28
|
+
* @returns the in-flight row, or the settled result card.
|
|
19
29
|
*/
|
|
20
30
|
export function DrawResultCard(props) {
|
|
31
|
+
// The owner's discriminant and the block are two statements of the same fact,
|
|
32
|
+
// and the block is the one the presenter reads — so the card classifies the
|
|
33
|
+
// stage from the block, through the same function the presenter uses. The
|
|
34
|
+
// owner's arm only breaks the tie in the impossible case of a `result` owner
|
|
35
|
+
// carrying a block that is not a settled node.
|
|
36
|
+
const phase = toolCallPhase(props.block);
|
|
37
|
+
if (phase !== 'result') {
|
|
38
|
+
const stage = props.phase === 'result' ? phase : props.phase;
|
|
39
|
+
return h('div', { className: 'dshdraw-inflight', 'aria-busy': 'true', 'data-phase': stage }, h('span', { className: 'dshdraw-inflight-title' }, props.t('row.title')), h('span', { className: 'dshdraw-sep', 'aria-hidden': 'true' }, '·'), h('span', { className: 'dshdraw-inflight-summary' }, props.toolName), h('span', { className: 'dshdraw-inflight-state' }, props.t(inFlightKey(stage))));
|
|
40
|
+
}
|
|
41
|
+
return h(DrawResultCardBody, props);
|
|
42
|
+
}
|
|
43
|
+
/** Locale key naming the stage of a call that has not settled yet. */
|
|
44
|
+
function inFlightKey(phase) {
|
|
45
|
+
return phase === 'preparing' ? 'row.preparing' : 'row.running';
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The settled result card: engine/quota facts and the regenerate action.
|
|
49
|
+
*
|
|
50
|
+
* @param props - the owner at its `result` stage, locale, and injected bindings.
|
|
51
|
+
* @returns the card element.
|
|
52
|
+
*/
|
|
53
|
+
function DrawResultCardBody(props) {
|
|
21
54
|
const { block, regenerate, t } = props;
|
|
22
55
|
const presented = presentDrawResult(block);
|
|
23
56
|
const [busy, setBusy] = useState(false);
|
|
24
57
|
const [failed, setFailed] = useState(false);
|
|
25
|
-
if (presented === undefined)
|
|
58
|
+
if (presented === undefined) {
|
|
59
|
+
// The Host handed this card a settled node it does not own (a foreign call
|
|
60
|
+
// head after window truncation, or an error result) — nothing to add.
|
|
26
61
|
return h('div', null);
|
|
62
|
+
}
|
|
27
63
|
const runRegenerate = async () => {
|
|
28
64
|
if (presented.args === undefined)
|
|
29
65
|
return;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @module dsh-draw/client/locales
|
|
7
7
|
*/
|
|
8
8
|
/** Dictionary key union. */
|
|
9
|
-
export type DrawLocaleKey = 'result.title' | 'result.fallback' | 'result.quota' | 'result.engine' | 'result.regenerate' | 'result.regenerating' | 'result.failed' | 'tab' | 'tab.engines' | 'tab.preferred' | 'tab.disabled' | 'tab.keyRef' | 'tab.credentialSet' | 'tab.credentialMissing' | 'tab.setKey' | 'tab.removeKey' | 'tab.probe' | 'tab.quotaCalls' | 'tab.quotaBytes' | 'tab.health' | 'tab.healthOk' | 'tab.healthError';
|
|
9
|
+
export type DrawLocaleKey = 'result.title' | 'result.fallback' | 'result.quota' | 'result.engine' | 'result.regenerate' | 'result.regenerating' | 'result.failed' | 'row.title' | 'row.preparing' | 'row.running' | 'tab' | 'tab.engines' | 'tab.preferred' | 'tab.disabled' | 'tab.keyRef' | 'tab.credentialSet' | 'tab.credentialMissing' | 'tab.setKey' | 'tab.removeKey' | 'tab.probe' | 'tab.quotaCalls' | 'tab.quotaBytes' | 'tab.health' | 'tab.healthOk' | 'tab.healthError';
|
|
10
10
|
/** English dictionary. */
|
|
11
11
|
export declare const en: Record<DrawLocaleKey, string>;
|
|
12
12
|
/** Chinese dictionary. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../../src/client/locales.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,4BAA4B;AAC5B,MAAM,MAAM,aAAa,GACrB,cAAc,GACd,iBAAiB,GACjB,cAAc,GACd,eAAe,GACf,mBAAmB,GACnB,qBAAqB,GACrB,eAAe,GACf,KAAK,GACL,aAAa,GACb,eAAe,GACf,cAAc,GACd,YAAY,GACZ,mBAAmB,GACnB,uBAAuB,GACvB,YAAY,GACZ,eAAe,GACf,WAAW,GACX,gBAAgB,GAChB,gBAAgB,GAChB,YAAY,GACZ,cAAc,GACd,iBAAiB,CAAA;AAErB,0BAA0B;AAC1B,eAAO,MAAM,EAAE,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../../src/client/locales.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,4BAA4B;AAC5B,MAAM,MAAM,aAAa,GACrB,cAAc,GACd,iBAAiB,GACjB,cAAc,GACd,eAAe,GACf,mBAAmB,GACnB,qBAAqB,GACrB,eAAe,GACf,WAAW,GACX,eAAe,GACf,aAAa,GACb,KAAK,GACL,aAAa,GACb,eAAe,GACf,cAAc,GACd,YAAY,GACZ,mBAAmB,GACnB,uBAAuB,GACvB,YAAY,GACZ,eAAe,GACf,WAAW,GACX,gBAAgB,GAChB,gBAAgB,GAChB,YAAY,GACZ,cAAc,GACd,iBAAiB,CAAA;AAErB,0BAA0B;AAC1B,eAAO,MAAM,EAAE,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CA0B5C,CAAA;AAED,0BAA0B;AAC1B,eAAO,MAAM,EAAE,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CA0B5C,CAAA"}
|
|
@@ -14,6 +14,9 @@ export const en = {
|
|
|
14
14
|
'result.regenerate': 'Regenerate',
|
|
15
15
|
'result.regenerating': 'Regenerating…',
|
|
16
16
|
'result.failed': 'Regenerate failed',
|
|
17
|
+
'row.title': 'Tool call',
|
|
18
|
+
'row.preparing': 'Preparing tool call',
|
|
19
|
+
'row.running': 'Running',
|
|
17
20
|
'tab': 'Image generation',
|
|
18
21
|
'tab.engines': 'Engines',
|
|
19
22
|
'tab.preferred': 'preferred',
|
|
@@ -39,6 +42,9 @@ export const zh = {
|
|
|
39
42
|
'result.regenerate': '重新生成',
|
|
40
43
|
'result.regenerating': '正在重新生成…',
|
|
41
44
|
'result.failed': '重新生成失败',
|
|
45
|
+
'row.title': '工具调用',
|
|
46
|
+
'row.preparing': '正在准备调用',
|
|
47
|
+
'row.running': '运行中',
|
|
42
48
|
'tab': '图像生成',
|
|
43
49
|
'tab.engines': '引擎',
|
|
44
50
|
'tab.preferred': '首选',
|
|
@@ -47,6 +47,59 @@ export interface SettledToolResultBlock {
|
|
|
47
47
|
export type ToolCallBlock = RunningToolCallBlock | SettledToolResultBlock;
|
|
48
48
|
/** Settled tool-result node only. */
|
|
49
49
|
export type ToolResultNode = SettledToolResultBlock;
|
|
50
|
+
/**
|
|
51
|
+
* The Host's tool-call-view stage discriminant. The Host splits the owner
|
|
52
|
+
* currency into `preparing` / `start` / `result`, each carrying its own stage
|
|
53
|
+
* block, and dispatches the SAME keyed entry in every stage — so a keyed card
|
|
54
|
+
* receives a preparing owner whose block has no `kind` and no `argsRaw`.
|
|
55
|
+
*
|
|
56
|
+
* {@link TOOL_CALL_PHASES} is the single source of truth for this union: the
|
|
57
|
+
* literal type is derived from the array, so a value and its type can never
|
|
58
|
+
* drift apart, and `scripts/verify-host-contract.mjs` compares the array
|
|
59
|
+
* against the Host's own `ToolCallPhaseProps` declaration.
|
|
60
|
+
*/
|
|
61
|
+
export declare const TOOL_CALL_PHASES: readonly ['preparing', 'start', 'result'];
|
|
62
|
+
/** One stage of the Host's tool-call view. */
|
|
63
|
+
export type ToolCallPhase = (typeof TOOL_CALL_PHASES)[number];
|
|
64
|
+
/**
|
|
65
|
+
* Classify a frozen tool block into its Host stage, mirroring the Host's own
|
|
66
|
+
* `toolCallPhase`: a settled node wins on `kind`, and the running family splits
|
|
67
|
+
* on `phase`. `ToolCallBlock` is structurally narrower than the Host union
|
|
68
|
+
* (`RunningToolCallBlock` declares no `phase` field), so the running arm is
|
|
69
|
+
* read through a structural probe rather than a declared member.
|
|
70
|
+
*
|
|
71
|
+
* @param block - the frozen tool block the owner delivered.
|
|
72
|
+
* @returns the stage this block belongs to.
|
|
73
|
+
*/
|
|
74
|
+
export declare function toolCallPhase(block: ToolCallBlock): ToolCallPhase;
|
|
75
|
+
/** How a card presents one stage of its own keyed tool call. */
|
|
76
|
+
export interface PresentedToolCallPhase {
|
|
77
|
+
/** The Host stage this presentation covers. */
|
|
78
|
+
phase: ToolCallPhase;
|
|
79
|
+
/**
|
|
80
|
+
* Whether this stage carries a settled result to present, or whether the
|
|
81
|
+
* card must render its own in-flight row for a call still arriving.
|
|
82
|
+
*/
|
|
83
|
+
state: 'result' | 'in-flight';
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Project the card's one appearance per Host stage.
|
|
87
|
+
*
|
|
88
|
+
* Only the `result` stage carries the engine/quota facts and the regenerate
|
|
89
|
+
* action. The earlier stages have no arguments and no result, and the keyed
|
|
90
|
+
* slot is OCCUPIED for them — the Host's own generic row is unreachable
|
|
91
|
+
* (the renderer falls back only for an empty cell) — so the card owning an
|
|
92
|
+
* in-flight row is what keeps the row visible while the call streams.
|
|
93
|
+
*
|
|
94
|
+
* A stage outside the declared vocabulary is reported loudly instead of being
|
|
95
|
+
* silently swept into `preparing`; the `switch` is exhaustive over
|
|
96
|
+
* {@link ToolCallPhase}, so a new stage fails the build before it can reach
|
|
97
|
+
* this default.
|
|
98
|
+
*
|
|
99
|
+
* @param phase - the stage classified from the owner's block.
|
|
100
|
+
* @returns the presentation this card owes that stage.
|
|
101
|
+
*/
|
|
102
|
+
export declare function presentToolCallPhase(phase: ToolCallPhase): PresentedToolCallPhase;
|
|
50
103
|
/** One image of the presented result card. */
|
|
51
104
|
export interface PresentedImage {
|
|
52
105
|
attachmentId: string;
|
|
@@ -78,6 +131,13 @@ export interface PresentedDrawResult {
|
|
|
78
131
|
/**
|
|
79
132
|
* Project one settled `image_generate` tool block onto the card model.
|
|
80
133
|
*
|
|
134
|
+
* The stage guard is explicit, not incidental: only the Host's `result` stage
|
|
135
|
+
* carries `kind`, and the preparing stage's block is an ordinary object, so
|
|
136
|
+
* an `undefined` return is the presenter's answer for every non-result stage
|
|
137
|
+
* as well as for a foreign tool, an error result, or a window-truncated call
|
|
138
|
+
* head. The card pairs that answer with {@link toolCallPhase} to render its
|
|
139
|
+
* in-flight row instead of an empty node.
|
|
140
|
+
*
|
|
81
141
|
* @param block - the frozen tool-call block (running or settled).
|
|
82
142
|
* @returns the presented model, or `undefined` when the block is not a settled
|
|
83
143
|
* image_generate result.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"present.d.ts","sourceRoot":"","sources":["../../../src/client/present.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEpD;;;;;;;;GAQG;AAEH,sFAAsF;AACtF,MAAM,WAAW,oBAAoB;IACnC,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAA;IACd,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,qCAAqC;IACrC,OAAO,EAAE,MAAM,CAAA;IACf,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAA;CACb;AAED,4DAA4D;AAC5D,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,aAAa,CAAA;IACnB,OAAO,EAAE,OAAO,CAAA;IAChB,oEAAoE;IACpE,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IAC9C,+EAA+E;IAC/E,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,4CAA4C;AAC5C,MAAM,MAAM,aAAa,GAAG,oBAAoB,GAAG,sBAAsB,CAAA;AAEzE,qCAAqC;AACrC,MAAM,MAAM,cAAc,GAAG,sBAAsB,CAAA;AAEnD,8CAA8C;AAC9C,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;CACb;AAED,uCAAuC;AACvC,MAAM,WAAW,mBAAmB;IAClC,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAA;IACd,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,8CAA8C;IAC9C,YAAY,EAAE,OAAO,CAAA;IACrB,mCAAmC;IACnC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAA;IACjC,8CAA8C;IAC9C,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IAC7C,wBAAwB;IACxB,MAAM,EAAE;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;IACpD,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAA;CAC1C;AAED
|
|
1
|
+
{"version":3,"file":"present.d.ts","sourceRoot":"","sources":["../../../src/client/present.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,14 +6,88 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @module dsh-draw/client/present
|
|
8
8
|
*/
|
|
9
|
+
/**
|
|
10
|
+
* The Host's tool-call-view stage discriminant. The Host splits the owner
|
|
11
|
+
* currency into `preparing` / `start` / `result`, each carrying its own stage
|
|
12
|
+
* block, and dispatches the SAME keyed entry in every stage — so a keyed card
|
|
13
|
+
* receives a preparing owner whose block has no `kind` and no `argsRaw`.
|
|
14
|
+
*
|
|
15
|
+
* {@link TOOL_CALL_PHASES} is the single source of truth for this union: the
|
|
16
|
+
* literal type is derived from the array, so a value and its type can never
|
|
17
|
+
* drift apart, and `scripts/verify-host-contract.mjs` compares the array
|
|
18
|
+
* against the Host's own `ToolCallPhaseProps` declaration.
|
|
19
|
+
*/
|
|
20
|
+
export const TOOL_CALL_PHASES = ['preparing', 'start', 'result'];
|
|
21
|
+
/**
|
|
22
|
+
* Classify a frozen tool block into its Host stage, mirroring the Host's own
|
|
23
|
+
* `toolCallPhase`: a settled node wins on `kind`, and the running family splits
|
|
24
|
+
* on `phase`. `ToolCallBlock` is structurally narrower than the Host union
|
|
25
|
+
* (`RunningToolCallBlock` declares no `phase` field), so the running arm is
|
|
26
|
+
* read through a structural probe rather than a declared member.
|
|
27
|
+
*
|
|
28
|
+
* @param block - the frozen tool block the owner delivered.
|
|
29
|
+
* @returns the stage this block belongs to.
|
|
30
|
+
*/
|
|
31
|
+
export function toolCallPhase(block) {
|
|
32
|
+
if ('kind' in block)
|
|
33
|
+
return 'result';
|
|
34
|
+
return block.phase === 'preparing' ? 'preparing' : 'start';
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Project the card's one appearance per Host stage.
|
|
38
|
+
*
|
|
39
|
+
* Only the `result` stage carries the engine/quota facts and the regenerate
|
|
40
|
+
* action. The earlier stages have no arguments and no result, and the keyed
|
|
41
|
+
* slot is OCCUPIED for them — the Host's own generic row is unreachable
|
|
42
|
+
* (the renderer falls back only for an empty cell) — so the card owning an
|
|
43
|
+
* in-flight row is what keeps the row visible while the call streams.
|
|
44
|
+
*
|
|
45
|
+
* A stage outside the declared vocabulary is reported loudly instead of being
|
|
46
|
+
* silently swept into `preparing`; the `switch` is exhaustive over
|
|
47
|
+
* {@link ToolCallPhase}, so a new stage fails the build before it can reach
|
|
48
|
+
* this default.
|
|
49
|
+
*
|
|
50
|
+
* @param phase - the stage classified from the owner's block.
|
|
51
|
+
* @returns the presentation this card owes that stage.
|
|
52
|
+
*/
|
|
53
|
+
export function presentToolCallPhase(phase) {
|
|
54
|
+
switch (phase) {
|
|
55
|
+
case 'result':
|
|
56
|
+
return { phase, state: 'result' };
|
|
57
|
+
case 'preparing':
|
|
58
|
+
case 'start':
|
|
59
|
+
return { phase, state: 'in-flight' };
|
|
60
|
+
default:
|
|
61
|
+
return exhaustiveToolCallPhase(phase);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Compile-time completeness check for the stage vocabulary: a new Host stage
|
|
66
|
+
* added to {@link ToolCallPhase} without a branch above fails the build here.
|
|
67
|
+
*
|
|
68
|
+
* @param phase - the unhandled stage.
|
|
69
|
+
* @returns never; throws at runtime.
|
|
70
|
+
*/
|
|
71
|
+
function exhaustiveToolCallPhase(phase) {
|
|
72
|
+
throw new Error(`unhandled tool-call phase: ${JSON.stringify(phase)}`);
|
|
73
|
+
}
|
|
9
74
|
/**
|
|
10
75
|
* Project one settled `image_generate` tool block onto the card model.
|
|
11
76
|
*
|
|
77
|
+
* The stage guard is explicit, not incidental: only the Host's `result` stage
|
|
78
|
+
* carries `kind`, and the preparing stage's block is an ordinary object, so
|
|
79
|
+
* an `undefined` return is the presenter's answer for every non-result stage
|
|
80
|
+
* as well as for a foreign tool, an error result, or a window-truncated call
|
|
81
|
+
* head. The card pairs that answer with {@link toolCallPhase} to render its
|
|
82
|
+
* in-flight row instead of an empty node.
|
|
83
|
+
*
|
|
12
84
|
* @param block - the frozen tool-call block (running or settled).
|
|
13
85
|
* @returns the presented model, or `undefined` when the block is not a settled
|
|
14
86
|
* image_generate result.
|
|
15
87
|
*/
|
|
16
88
|
export function presentDrawResult(block) {
|
|
89
|
+
if (toolCallPhase(block) !== 'result')
|
|
90
|
+
return undefined;
|
|
17
91
|
if (!('kind' in block) || block.kind !== 'tool-result' || block.isError)
|
|
18
92
|
return undefined;
|
|
19
93
|
if (block.call?.name !== 'image_generate')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/client/styles.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAaH,wEAAwE;AACxE,wBAAgB,iBAAiB,IAAI,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/client/styles.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAaH,wEAAwE;AACxE,wBAAgB,iBAAiB,IAAI,MAAM,IAAI,CA6C9C"}
|
|
@@ -28,6 +28,11 @@ export function installDrawStyles() {
|
|
|
28
28
|
.dshdraw-figure img { max-width: 100%; border-radius: 6px; border: 1px solid var(--dsh-border, #d0d7de); }
|
|
29
29
|
.dshdraw-figure figcaption { font-size: 11px; opacity: 0.75; overflow-wrap: anywhere; }
|
|
30
30
|
.dshdraw-meta { font-size: 12px; opacity: 0.85; display: flex; flex-wrap: wrap; gap: 12px; }
|
|
31
|
+
.dshdraw-inflight { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; font-size: 13px; min-height: 20px; }
|
|
32
|
+
.dshdraw-inflight .dshdraw-sep { opacity: 0.45; }
|
|
33
|
+
.dshdraw-inflight-title { font-weight: 500; }
|
|
34
|
+
.dshdraw-inflight-summary { opacity: 0.85; overflow-wrap: anywhere; }
|
|
35
|
+
.dshdraw-inflight-state { font-size: 12px; opacity: 0.7; }
|
|
31
36
|
.dshdraw-actions { display: flex; gap: 8px; }
|
|
32
37
|
.dshdraw-button {
|
|
33
38
|
border: 1px solid var(--dsh-border, #d0d7de); border-radius: 6px; background: transparent;
|
package/lib/types/version.d.ts
CHANGED
package/lib/types/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-draw",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.18",
|
|
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",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"attachments:write"
|
|
90
90
|
],
|
|
91
91
|
"compatibility": {
|
|
92
|
-
"dshVersions": ["0.1.2-rc.1","0.1.5-rc.2","0.1.7-alpha.2"]
|
|
92
|
+
"dshVersions": ["0.1.2-rc.1","0.1.5-rc.2","0.1.7-alpha.2","0.1.7-rc.1", "0.1.7-rc.2"]
|
|
93
93
|
},
|
|
94
94
|
"capability": {
|
|
95
95
|
"id": "image-generate-tool",
|
|
@@ -160,29 +160,30 @@
|
|
|
160
160
|
"zod": "^4.4.3"
|
|
161
161
|
},
|
|
162
162
|
"devDependencies": {
|
|
163
|
-
"@deepseek-ai/dsh-util-values": "0.1.7-
|
|
163
|
+
"@deepseek-ai/dsh-util-values": "0.1.7-rc.2",
|
|
164
164
|
"@deepseek-ai/cordis": "^4.0.4",
|
|
165
165
|
"@deepseek-ai/cordis-plugin-include": "^1.0.7",
|
|
166
166
|
"@deepseek-ai/cordis-plugin-loader": "^1.0.3",
|
|
167
|
-
"@deepseek-ai/dsh-agent": "0.1.7-
|
|
168
|
-
"@deepseek-ai/dsh-api-remotes": "0.1.7-
|
|
169
|
-
"@deepseek-ai/dsh-attachment": "0.1.7-
|
|
170
|
-
"@deepseek-ai/dsh-attachment-local": "0.1.7-
|
|
171
|
-
"@deepseek-ai/dsh-brand": "0.1.7-
|
|
172
|
-
"@deepseek-ai/dsh-client-connection": "0.1.7-
|
|
173
|
-
"@deepseek-ai/dsh-client-locale": "0.1.7-
|
|
174
|
-
"@deepseek-ai/dsh-client-ui-settings": "0.1.7-
|
|
175
|
-
"@deepseek-ai/dsh-client-ui-slots": "0.1.7-
|
|
176
|
-
"@deepseek-ai/dsh-client-ui-tool": "0.1.7-
|
|
177
|
-
"@deepseek-ai/dsh-credentials": "0.1.7-
|
|
178
|
-
"@deepseek-ai/dsh-credentials-local": "0.1.7-
|
|
179
|
-
"@deepseek-ai/dsh-llm": "0.1.7-
|
|
180
|
-
"@deepseek-ai/dsh-session": "0.1.7-
|
|
181
|
-
"@deepseek-ai/dsh-tools": "0.1.7-
|
|
182
|
-
"@deepseek-ai/dsh-typert-protocol": "0.1.7-
|
|
167
|
+
"@deepseek-ai/dsh-agent": "0.1.7-rc.2",
|
|
168
|
+
"@deepseek-ai/dsh-api-remotes": "0.1.7-rc.2",
|
|
169
|
+
"@deepseek-ai/dsh-attachment": "0.1.7-rc.2",
|
|
170
|
+
"@deepseek-ai/dsh-attachment-local": "0.1.7-rc.2",
|
|
171
|
+
"@deepseek-ai/dsh-brand": "0.1.7-rc.2",
|
|
172
|
+
"@deepseek-ai/dsh-client-connection": "0.1.7-rc.2",
|
|
173
|
+
"@deepseek-ai/dsh-client-locale": "0.1.7-rc.2",
|
|
174
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.1.7-rc.2",
|
|
175
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.7-rc.2",
|
|
176
|
+
"@deepseek-ai/dsh-client-ui-tool": "0.1.7-rc.2",
|
|
177
|
+
"@deepseek-ai/dsh-credentials": "0.1.7-rc.2",
|
|
178
|
+
"@deepseek-ai/dsh-credentials-local": "0.1.7-rc.2",
|
|
179
|
+
"@deepseek-ai/dsh-llm": "0.1.7-rc.2",
|
|
180
|
+
"@deepseek-ai/dsh-session": "0.1.7-rc.2",
|
|
181
|
+
"@deepseek-ai/dsh-tools": "0.1.7-rc.2",
|
|
182
|
+
"@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2",
|
|
183
183
|
"@deepseek-ai/schemastery": "^3.18.3",
|
|
184
184
|
"@types/node": "^22.19.0",
|
|
185
185
|
"@types/react": "18.3.31",
|
|
186
|
+
"@types/react-dom": "18.3.7",
|
|
186
187
|
"@vitest/coverage-v8": "4.1.10",
|
|
187
188
|
"jsdom": "^30.0.1",
|
|
188
189
|
"oxlint": "0.18.1",
|
|
@@ -201,7 +202,8 @@
|
|
|
201
202
|
"check:readmes": "node scripts/check-readme-sync.mjs",
|
|
202
203
|
"prepare": "node scripts/prepare.mjs",
|
|
203
204
|
"verify:self-contained": "node scripts/verify-self-contained.mjs",
|
|
204
|
-
"verify:artifacts": "node scripts/verify-artifacts.mjs"
|
|
205
|
+
"verify:artifacts": "node scripts/verify-artifacts.mjs",
|
|
206
|
+
"verify:host-contract": "node scripts/verify-host-contract.mjs"
|
|
205
207
|
},
|
|
206
208
|
"license": "Apache-2.0",
|
|
207
209
|
"funding": {
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The keyed `image_generate` tool
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* The keyed `image_generate` tool view: engine/quota facts and the regenerate
|
|
3
|
+
* action once the call settles, and an in-flight row of its own while the
|
|
4
|
+
* arguments are still arriving. The images themselves are the attachment
|
|
5
|
+
* content blocks the shell already renders from the tool result, so the card
|
|
6
|
+
* only adds the accounting line and the action — it never duplicates image
|
|
7
|
+
* transport.
|
|
8
|
+
*
|
|
9
|
+
* The Host dispatches this keyed entry in EVERY stage of the call, and a keyed
|
|
10
|
+
* cell that is occupied never reaches the owner fallback — so the earlier
|
|
11
|
+
* stages cannot be answered with nothing without blanking the row.
|
|
6
12
|
*
|
|
7
13
|
* The `tool.call.toolview` SlotMap member is declared locally (mirroring the
|
|
8
14
|
* harness's own ui-tool contract declaration, which its package index does not
|
|
@@ -13,20 +19,30 @@
|
|
|
13
19
|
|
|
14
20
|
import { createElement as h, useState, type ReactElement } from 'react'
|
|
15
21
|
import type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'
|
|
16
|
-
import { presentDrawResult, type ToolCallBlock } from './present.ts'
|
|
22
|
+
import { presentDrawResult, toolCallPhase, type ToolCallBlock, type ToolCallPhase } from './present.ts'
|
|
17
23
|
|
|
18
24
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
25
|
+
* Stage-specific tool data, mirror of the harness ui-tool contract
|
|
26
|
+
* `ToolCallPhaseProps`. The Host dispatches the SAME keyed entry in every
|
|
27
|
+
* stage, so the card's own contract must discriminate on `phase` exactly as
|
|
28
|
+
* the Host's does — a narrower declaration here hides the preparing owner
|
|
29
|
+
* rather than rejecting it (the slot is occupied for every stage).
|
|
22
30
|
*/
|
|
23
|
-
export
|
|
24
|
-
|
|
31
|
+
export type ToolCallPhaseProps =
|
|
32
|
+
| { readonly phase: 'preparing'; readonly block: ToolCallBlock }
|
|
33
|
+
| { readonly phase: 'start'; readonly block: ToolCallBlock }
|
|
34
|
+
| { readonly phase: 'result'; readonly block: ToolCallBlock }
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Common owner currency declared beside the phase share, mirror of the
|
|
38
|
+
* harness ui-tool contract `ToolCallCommonProps` (which the package index
|
|
39
|
+
* does not re-export — keep the shape identical so the declarations merge).
|
|
40
|
+
*/
|
|
41
|
+
export interface ToolCallCommonProps {
|
|
42
|
+
/** Tool call identity, stable across all stages. */
|
|
25
43
|
callId: string
|
|
26
44
|
/** Wire tool name and keyed dispatch value. */
|
|
27
45
|
toolName: string
|
|
28
|
-
/** Frozen running call or settled result node. */
|
|
29
|
-
block: ToolCallBlock
|
|
30
46
|
/** Session workspace root for relative summaries. */
|
|
31
47
|
cwd?: string
|
|
32
48
|
/** Open a tool argument path through the host. */
|
|
@@ -35,6 +51,12 @@ export interface ToolCallOwnerProps {
|
|
|
35
51
|
inspect?: () => void
|
|
36
52
|
}
|
|
37
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Standard owner currency for one keyed tool view: the common share plus the
|
|
56
|
+
* stage share, mirroring the harness ui-tool contract `ToolCallOwnerProps`.
|
|
57
|
+
*/
|
|
58
|
+
export type ToolCallOwnerProps = ToolCallCommonProps & ToolCallPhaseProps
|
|
59
|
+
|
|
38
60
|
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
39
61
|
interface SlotMap {
|
|
40
62
|
/** Keyed atomic tool-call view, dispatched by the wire tool name. */
|
|
@@ -55,17 +77,55 @@ export type DrawResultCardProps =
|
|
|
55
77
|
& InjectFace<DrawResultCardInjected>
|
|
56
78
|
|
|
57
79
|
/**
|
|
58
|
-
* The keyed tool
|
|
59
|
-
*
|
|
60
|
-
*
|
|
80
|
+
* The keyed tool view. Dispatched by the wire tool name in EVERY stage of the
|
|
81
|
+
* call, so the card owes a presentation to the in-flight stages too: returning
|
|
82
|
+
* an empty node would leave the row blank, because an occupied keyed cell
|
|
83
|
+
* never reaches the Host's own generic row.
|
|
84
|
+
*
|
|
85
|
+
* @param props - owner currency (common + stage shares), locale, and injected bindings.
|
|
86
|
+
* @returns the in-flight row, or the settled result card.
|
|
61
87
|
*/
|
|
62
88
|
export function DrawResultCard(props: DrawResultCardProps): ReactElement {
|
|
89
|
+
// The owner's discriminant and the block are two statements of the same fact,
|
|
90
|
+
// and the block is the one the presenter reads — so the card classifies the
|
|
91
|
+
// stage from the block, through the same function the presenter uses. The
|
|
92
|
+
// owner's arm only breaks the tie in the impossible case of a `result` owner
|
|
93
|
+
// carrying a block that is not a settled node.
|
|
94
|
+
const phase = toolCallPhase(props.block)
|
|
95
|
+
if (phase !== 'result') {
|
|
96
|
+
const stage = props.phase === 'result' ? phase : props.phase
|
|
97
|
+
return h('div', { className: 'dshdraw-inflight', 'aria-busy': 'true', 'data-phase': stage },
|
|
98
|
+
h('span', { className: 'dshdraw-inflight-title' }, props.t('row.title')),
|
|
99
|
+
h('span', { className: 'dshdraw-sep', 'aria-hidden': 'true' }, '·'),
|
|
100
|
+
h('span', { className: 'dshdraw-inflight-summary' }, props.toolName),
|
|
101
|
+
h('span', { className: 'dshdraw-inflight-state' }, props.t(inFlightKey(stage))),
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
return h(DrawResultCardBody, props)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Locale key naming the stage of a call that has not settled yet. */
|
|
108
|
+
function inFlightKey(phase: ToolCallPhase): 'row.preparing' | 'row.running' {
|
|
109
|
+
return phase === 'preparing' ? 'row.preparing' : 'row.running'
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* The settled result card: engine/quota facts and the regenerate action.
|
|
114
|
+
*
|
|
115
|
+
* @param props - the owner at its `result` stage, locale, and injected bindings.
|
|
116
|
+
* @returns the card element.
|
|
117
|
+
*/
|
|
118
|
+
function DrawResultCardBody(props: DrawResultCardProps): ReactElement {
|
|
63
119
|
const { block, regenerate, t } = props
|
|
64
120
|
const presented = presentDrawResult(block)
|
|
65
121
|
const [busy, setBusy] = useState(false)
|
|
66
122
|
const [failed, setFailed] = useState(false)
|
|
67
123
|
|
|
68
|
-
if (presented === undefined)
|
|
124
|
+
if (presented === undefined) {
|
|
125
|
+
// The Host handed this card a settled node it does not own (a foreign call
|
|
126
|
+
// head after window truncation, or an error result) — nothing to add.
|
|
127
|
+
return h('div', null)
|
|
128
|
+
}
|
|
69
129
|
|
|
70
130
|
const runRegenerate = async (): Promise<void> => {
|
|
71
131
|
if (presented.args === undefined) return
|