dsh-model-everything 0.3.0 → 0.4.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.
- package/README.en-US.md +23 -3
- package/README.md +17 -3
- package/lib/automaton-tool.js +3 -2
- package/lib/automaton.js +10 -9
- package/lib/compose-tool.js +4 -2
- package/lib/concurrency-tool.js +4 -2
- package/lib/data-tool.js +4 -2
- package/lib/design-tool.js +4 -2
- package/lib/edit-tool.js +4 -2
- package/lib/export-tool.js +6 -3
- package/lib/presentation.js +236 -8
- package/lib/report-diff-tool.js +4 -2
- package/lib/structure-tool.js +3 -2
- package/lib/tool.js +3 -2
- package/lib/types/presentation.d.ts +108 -3
- package/lib/uml-tool.js +7 -2
- package/package.json +3 -1
- package/src/automaton-tool.ts +3 -2
- package/src/automaton.ts +10 -9
- package/src/compose-tool.ts +4 -2
- package/src/concurrency-tool.ts +4 -2
- package/src/data-tool.ts +4 -2
- package/src/design-tool.ts +4 -2
- package/src/edit-tool.ts +4 -2
- package/src/export-tool.ts +6 -3
- package/src/presentation.ts +249 -9
- package/src/report-diff-tool.ts +4 -2
- package/src/structure-tool.ts +3 -2
- package/src/tool.ts +3 -2
- package/src/uml-tool.ts +7 -2
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* Both are pure and replayable: they read the persisted value, never the filesystem.
|
|
16
16
|
*/
|
|
17
17
|
import type { ContentBlock } from '@deepseek-ai/dsh-llm';
|
|
18
|
-
import type { ToolResultView } from '@deepseek-ai/dsh-tools';
|
|
18
|
+
import type { ToolCallView, ToolResultView } from '@deepseek-ai/dsh-tools';
|
|
19
19
|
/** One finding, as a card needs it: a code to name it and a sentence to read. */
|
|
20
20
|
export interface CardFinding {
|
|
21
21
|
code: string;
|
|
@@ -39,6 +39,53 @@ export interface ReportCard {
|
|
|
39
39
|
owns: string;
|
|
40
40
|
instead: string;
|
|
41
41
|
};
|
|
42
|
+
/** `model_edit`: the changes this call applied, as the report lists them. */
|
|
43
|
+
changes?: Array<{
|
|
44
|
+
kind: string;
|
|
45
|
+
what: string;
|
|
46
|
+
detail?: string;
|
|
47
|
+
}>;
|
|
48
|
+
/** `model_edit` and `report_diff`: how the findings moved, when either report could compare. */
|
|
49
|
+
delta?: {
|
|
50
|
+
added: number;
|
|
51
|
+
removed: number;
|
|
52
|
+
changed: number;
|
|
53
|
+
addedErrors: number;
|
|
54
|
+
};
|
|
55
|
+
/** `report_diff`: the first finding the change adds, so a card can lead with it. */
|
|
56
|
+
firstAdded?: CardFinding;
|
|
57
|
+
/** `report_diff`: the current report's own verdict, which differs from the delta's when a clean change lands on a failing report. */
|
|
58
|
+
currentVerdict?: string;
|
|
59
|
+
/** The artifact a translation or a rendering produced, as the first lines of it. */
|
|
60
|
+
source?: {
|
|
61
|
+
label: string;
|
|
62
|
+
lines: string[];
|
|
63
|
+
total: number;
|
|
64
|
+
};
|
|
65
|
+
/** `uml_structure_verify`: the graph's own counts, which are measurements rather than findings. */
|
|
66
|
+
graph?: {
|
|
67
|
+
nodes: number;
|
|
68
|
+
edges: number;
|
|
69
|
+
cycles: number;
|
|
70
|
+
isolated: number;
|
|
71
|
+
dangling: number;
|
|
72
|
+
};
|
|
73
|
+
/** `model_design_review`: three levels, because a signal is not a violation and a fact is neither. */
|
|
74
|
+
levels?: {
|
|
75
|
+
violations: number;
|
|
76
|
+
signals: number;
|
|
77
|
+
facts: number;
|
|
78
|
+
skipped: number;
|
|
79
|
+
};
|
|
80
|
+
/** `model_interleaving_scan`: how many claims were found, and in which families. */
|
|
81
|
+
claims?: {
|
|
82
|
+
absolute: number;
|
|
83
|
+
keywords: number;
|
|
84
|
+
families: Array<{
|
|
85
|
+
family: string;
|
|
86
|
+
count: number;
|
|
87
|
+
}>;
|
|
88
|
+
};
|
|
42
89
|
}
|
|
43
90
|
/**
|
|
44
91
|
* Project a report into the card payload.
|
|
@@ -50,10 +97,68 @@ export declare function reportCard(value: unknown, family: string): ReportCard;
|
|
|
50
97
|
/** The card body: four lines, in the order a reader asks the questions. */
|
|
51
98
|
export declare function cardBlocks(card: ReportCard): ContentBlock[];
|
|
52
99
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
100
|
+
* The pending card for a report tool: a title naming the artifact, and the file to follow.
|
|
101
|
+
*
|
|
102
|
+
* From the arguments only, because a UI calls this during streaming and again on replay; the file has not
|
|
103
|
+
* been opened at that point and must not be.
|
|
104
|
+
*/
|
|
105
|
+
/**
|
|
106
|
+
* The card payload with the artifact previewed.
|
|
107
|
+
*
|
|
108
|
+
* A translation and a rendering both produce text a reader wants to see the shape of, and neither should
|
|
109
|
+
* paste the whole file into a card: the preview is bounded, and it says how much it left out. The report
|
|
110
|
+
* keeps the artifact in full for whoever needs it.
|
|
55
111
|
*/
|
|
112
|
+
export declare function cardWithSource(value: unknown, family: string, text: string | undefined, label: string, limit?: number): ReportCard;
|
|
113
|
+
export declare function reportCallView(family: string): (args: unknown) => ToolCallView | undefined;
|
|
114
|
+
/**
|
|
115
|
+
* The card for `model_edit`: what changed, and what the change did to the findings.
|
|
116
|
+
*
|
|
117
|
+
* Both lists are already in the report, so this is a rendering of the same value rather than a second
|
|
118
|
+
* computation - the rule every card here follows.
|
|
119
|
+
*/
|
|
120
|
+
export declare function editCardBlocks(card: ReportCard): ContentBlock[];
|
|
121
|
+
/**
|
|
122
|
+
* The card for `report_diff`: does this change add anything, read as counts and the first added error.
|
|
123
|
+
*
|
|
124
|
+
* A diff's `verdict` is about the delta, so the card leads with the delta and never with the current
|
|
125
|
+
* report's own verdict - the two differ exactly when a clean change lands on an already-failing report.
|
|
126
|
+
*/
|
|
127
|
+
export declare function diffCardBlocks(card: ReportCard): ContentBlock[];
|
|
128
|
+
/** `presentResult` for `model_edit`, falling back to the generic card when the payload has no changes. */
|
|
129
|
+
export declare function editResultView(family: string): (_args: unknown, result: {
|
|
130
|
+
content: ContentBlock[];
|
|
131
|
+
meta?: unknown;
|
|
132
|
+
}) => ToolResultView | undefined;
|
|
56
133
|
export declare function reportResultView(family: string): (_args: unknown, result: {
|
|
57
134
|
content: ContentBlock[];
|
|
58
135
|
meta?: unknown;
|
|
59
136
|
}) => ToolResultView | undefined;
|
|
137
|
+
/** The card for `uml_structure_verify`: the graph's shape first, then the first finding. */
|
|
138
|
+
export declare function structureCardBlocks(card: ReportCard): ContentBlock[];
|
|
139
|
+
/** The card for `model_design_review`: violations, then signals, then facts - never one number. */
|
|
140
|
+
export declare function designCardBlocks(card: ReportCard): ContentBlock[];
|
|
141
|
+
/** The card for `model_interleaving_scan`: claims by family, and the reminder that nothing was proven. */
|
|
142
|
+
export declare function scanCardBlocks(card: ReportCard): ContentBlock[];
|
|
143
|
+
/** One `presentResult` per card body, since the shapes differ but the fallback does not. */
|
|
144
|
+
export declare function familyResultView(family: string, body: (card: ReportCard) => ContentBlock[]): (_args: unknown, result: {
|
|
145
|
+
content: ContentBlock[];
|
|
146
|
+
meta?: unknown;
|
|
147
|
+
}) => ToolResultView | undefined;
|
|
148
|
+
export declare const structureResultView: (_args: unknown, result: {
|
|
149
|
+
content: ContentBlock[];
|
|
150
|
+
meta?: unknown;
|
|
151
|
+
}) => ToolResultView | undefined;
|
|
152
|
+
export declare const designResultView: (_args: unknown, result: {
|
|
153
|
+
content: ContentBlock[];
|
|
154
|
+
meta?: unknown;
|
|
155
|
+
}) => ToolResultView | undefined;
|
|
156
|
+
export declare const scanResultView: (_args: unknown, result: {
|
|
157
|
+
content: ContentBlock[];
|
|
158
|
+
meta?: unknown;
|
|
159
|
+
}) => ToolResultView | undefined;
|
|
160
|
+
/** `presentResult` for `report_diff`: the delta leads, never the current report's own verdict. */
|
|
161
|
+
export declare function diffResultView(family: string): (_args: unknown, result: {
|
|
162
|
+
content: ContentBlock[];
|
|
163
|
+
meta?: unknown;
|
|
164
|
+
}) => ToolResultView | undefined;
|
package/lib/uml-tool.js
CHANGED
|
@@ -3,7 +3,7 @@ import { createHash } from 'node:crypto';
|
|
|
3
3
|
import { REPORT_SCHEMAS, DEFAULT_HASH_SPEC, valueHash, refusalVerdict, verdictOf, verdictOfFindings } from './engine.js';
|
|
4
4
|
import { renderUml, parseUml, parseFindings, reviewUml, explainLabels, checkUmlIntent, UmlError, UML_DIAGRAMS, } from './uml.js';
|
|
5
5
|
import { renderReportText } from './report-view.js';
|
|
6
|
-
import { reportCard, reportResultView } from './presentation.js';
|
|
6
|
+
import { cardWithSource, reportCallView, reportCard, reportResultView } from './presentation.js';
|
|
7
7
|
/**
|
|
8
8
|
* The UML front end as four tools, one per job.
|
|
9
9
|
*
|
|
@@ -51,7 +51,8 @@ const reportOutput = (family) => ({
|
|
|
51
51
|
// The card a UI shows, separated from the text the model reads. The family is the tool's own name, so
|
|
52
52
|
// one shared output does not have to guess which tool is calling it.
|
|
53
53
|
presentationMeta(_args, value) {
|
|
54
|
-
|
|
54
|
+
const report = value;
|
|
55
|
+
return cardWithSource(value, family, typeof report.diagram === 'string' ? report.diagram : undefined, 'diagram source');
|
|
55
56
|
},
|
|
56
57
|
});
|
|
57
58
|
/** Draw a model as diagram source. */
|
|
@@ -67,6 +68,7 @@ export const umlRenderTool = defineTool({
|
|
|
67
68
|
reportView: reportViewParameter,
|
|
68
69
|
},
|
|
69
70
|
output: reportOutput(UML_RENDER_TOOL_NAME),
|
|
71
|
+
presentCall: reportCallView(UML_RENDER_TOOL_NAME),
|
|
70
72
|
presentResult: reportResultView(UML_RENDER_TOOL_NAME),
|
|
71
73
|
timeoutMs: 10_000,
|
|
72
74
|
isConcurrencySafe: () => true,
|
|
@@ -105,6 +107,7 @@ export const umlParseTool = defineTool({
|
|
|
105
107
|
reportView: reportViewParameter,
|
|
106
108
|
},
|
|
107
109
|
output: reportOutput(UML_PARSE_TOOL_NAME),
|
|
110
|
+
presentCall: reportCallView(UML_PARSE_TOOL_NAME),
|
|
108
111
|
presentResult: reportResultView(UML_PARSE_TOOL_NAME),
|
|
109
112
|
timeoutMs: 10_000,
|
|
110
113
|
isConcurrencySafe: () => true,
|
|
@@ -157,6 +160,7 @@ export const umlReviewTool = defineTool({
|
|
|
157
160
|
reportView: reportViewParameter,
|
|
158
161
|
},
|
|
159
162
|
output: reportOutput(UML_REVIEW_TOOL_NAME),
|
|
163
|
+
presentCall: reportCallView(UML_REVIEW_TOOL_NAME),
|
|
160
164
|
presentResult: reportResultView(UML_REVIEW_TOOL_NAME),
|
|
161
165
|
timeoutMs: 10_000,
|
|
162
166
|
isConcurrencySafe: () => true,
|
|
@@ -189,6 +193,7 @@ export const umlExplainLabelsTool = defineTool({
|
|
|
189
193
|
reportView: reportViewParameter,
|
|
190
194
|
},
|
|
191
195
|
output: reportOutput(UML_LABELS_TOOL_NAME),
|
|
196
|
+
presentCall: reportCallView(UML_LABELS_TOOL_NAME),
|
|
192
197
|
presentResult: reportResultView(UML_LABELS_TOOL_NAME),
|
|
193
198
|
timeoutMs: 10_000,
|
|
194
199
|
isConcurrencySafe: () => true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-model-everything",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Modeling abstraction and automated review for designs and code, including a refactoring harness: UML diagrams, executable verification of machines and protocols with before/after regression, data-model and migration checks, concurrency claim routing, export to external checkers, dependency-graph review, and report diffing. Native plugin for DeepSeek Harness (dsh).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -64,6 +64,8 @@
|
|
|
64
64
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
65
65
|
"lint:md": "markdownlint --dot --ignore \"**/node_modules/**\" .",
|
|
66
66
|
"bump": "node scripts/bump-version.mjs",
|
|
67
|
+
"test:cards": "node tests/presentation/run.mjs && node tests/automaton/run.mjs && node tests/routing/run.mjs",
|
|
68
|
+
"coverage": "c8 --reporter=text --exclude-after-remap=false npm run test:engine",
|
|
67
69
|
"test:engine": "npm run build && node tests/engine/run.mjs && node tests/design-engine/run.mjs && node tests/catalog/run.mjs && node tests/data-engine/run.mjs && node tests/concurrency/run.mjs && node tests/uml/run.mjs && node tests/apply-smoke.mjs && node tests/memory/run.mjs && node tests/skills/run.mjs && node tests/gate/run.mjs && node tests/skill-routing/run.mjs && node tests/toolset/run.mjs && node tests/principles/run.mjs && node tests/feature-checklist/run.mjs && node tests/usage/run.mjs && node tests/translation/run.mjs && node tests/documentation/run.mjs && node tests/contributing/run.mjs && node tests/routing-map/run.mjs && node tests/report-reading/run.mjs && node tests/structure/run.mjs && node tests/automaton/run.mjs && node tests/presentation/run.mjs && node tests/routing/run.mjs && node tests/tool-routing/run.mjs && node tests/tools/run.mjs && node tests/baseline/run.mjs && node tests/granularity/run.mjs && node tests/exporters/run.mjs && node tests/report-view/run.mjs && node tests/contracts/run.mjs && node tests/tool-boundary/run.mjs && node tests/negatives/run.mjs && node tests/external/run.mjs",
|
|
68
70
|
"test:full": "npm run build && node tests/full-suite.mjs",
|
|
69
71
|
"check": "npm run lint:md && npm run test:engine"
|
package/src/automaton-tool.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { verifyAutomaton, type AutomatonRelation } from './automaton.js'
|
|
|
11
11
|
import type { JsonValue } from './json-value.js'
|
|
12
12
|
import { optionRefusal } from './option-shape.js'
|
|
13
13
|
import { renderReportText } from './report-view.js'
|
|
14
|
-
import { reportCard, reportResultView } from './presentation.js'
|
|
14
|
+
import { reportCallView, reportCard, reportResultView } from './presentation.js'
|
|
15
15
|
|
|
16
16
|
export const MODEL_AUTOMATON_TOOL_NAME = 'model_automaton_verify'
|
|
17
17
|
|
|
@@ -53,10 +53,11 @@ export const modelAutomatonTool = defineTool({
|
|
|
53
53
|
},
|
|
54
54
|
// The card a UI shows, separated from the text the model reads: a verdict and the first thing wrong,
|
|
55
55
|
// never the whole report.
|
|
56
|
-
presentationMeta(
|
|
56
|
+
presentationMeta(args, value) {
|
|
57
57
|
return reportCard(value, MODEL_AUTOMATON_TOOL_NAME) as unknown as JsonValue
|
|
58
58
|
},
|
|
59
59
|
},
|
|
60
|
+
presentCall: reportCallView(MODEL_AUTOMATON_TOOL_NAME),
|
|
60
61
|
presentResult: reportResultView(MODEL_AUTOMATON_TOOL_NAME),
|
|
61
62
|
timeoutMs: 10_000,
|
|
62
63
|
isConcurrencySafe: () => true,
|
package/src/automaton.ts
CHANGED
|
@@ -261,6 +261,7 @@ function isDeterministic(automaton: Automaton): boolean {
|
|
|
261
261
|
return true
|
|
262
262
|
}
|
|
263
263
|
|
|
264
|
+
|
|
264
265
|
export function verifyAutomaton(input: unknown, options: { other?: unknown; relation?: AutomatonRelation } = {}): AutomatonReport {
|
|
265
266
|
const parsed = validateAutomaton(input)
|
|
266
267
|
if (!parsed.ok) {
|
|
@@ -281,9 +282,6 @@ export function verifyAutomaton(input: unknown, options: { other?: unknown; rela
|
|
|
281
282
|
// accepts nothing: the first is a modelling smell, the second is usually a defect in the intended language.
|
|
282
283
|
for (const [index, label] of dfa.labels.entries()) {
|
|
283
284
|
if (label.length === 0) continue
|
|
284
|
-
if (label.length === 1 && !reach[index]) {
|
|
285
|
-
findings.push({ code: 'AUT001_UNREACHABLE_STATE', severity: 'warning', message: `state "${label[0]}" cannot be reached from init` })
|
|
286
|
-
}
|
|
287
285
|
if (!dfa.accept[index] && reach[index] && !canAccept[index]) {
|
|
288
286
|
findings.push({ code: 'AUT002_TRAP_STATE', severity: 'warning', message: `state "${label[0]}" is reachable but can never reach an accepting state` })
|
|
289
287
|
}
|
|
@@ -321,10 +319,12 @@ export function verifyAutomaton(input: unknown, options: { other?: unknown; rela
|
|
|
321
319
|
findings.push({ code: 'AUT009_UNDECIDED', severity: 'warning', message: 'the product search stopped at its state cap before deciding the relation, so equality is neither proven nor refuted', detail: 'the product of two automata can be exponential; reduce one of them, or decide the relation with a tool that searches symbolically' })
|
|
322
320
|
} else
|
|
323
321
|
if (relation === 'equivalent') {
|
|
324
|
-
if (missing !== undefined
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
322
|
+
if (missing !== undefined) {
|
|
323
|
+
witness = { word: missing, reason: 'accepted by the first automaton, rejected by the second' }
|
|
324
|
+
findings.push({ code: 'AUT006_NOT_EQUIVALENT', severity: 'error', message: 'the two automata accept different languages', detail: `shortest witness: ${missing.length === 0 ? 'the empty word' : missing.join(' ')}; ${witness.reason}` })
|
|
325
|
+
} else if (extra !== undefined) {
|
|
326
|
+
witness = { word: extra, reason: 'accepted by the second automaton, rejected by the first' }
|
|
327
|
+
findings.push({ code: 'AUT006_NOT_EQUIVALENT', severity: 'error', message: 'the two automata accept different languages', detail: `shortest witness: ${extra.length === 0 ? 'the empty word' : extra.join(' ')}; ${witness.reason}` })
|
|
328
328
|
}
|
|
329
329
|
} else if (relation === 'subset') {
|
|
330
330
|
if (missing !== undefined) {
|
|
@@ -338,11 +338,12 @@ export function verifyAutomaton(input: unknown, options: { other?: unknown; rela
|
|
|
338
338
|
}
|
|
339
339
|
}
|
|
340
340
|
|
|
341
|
-
const
|
|
341
|
+
const errorFindings = findings.filter((finding) => finding.severity === 'error')
|
|
342
|
+
const errors = errorFindings.length
|
|
342
343
|
const warnings = findings.filter((finding) => finding.severity === 'warning').length
|
|
343
344
|
const verdict = errors > 0 ? 'fail' : warnings > 0 ? 'pass_with_findings' : 'pass'
|
|
344
345
|
const reason = errors > 0
|
|
345
|
-
? `${String(errors)} error finding(s) (first: ${
|
|
346
|
+
? `${String(errors)} error finding(s) (first: ${errorFindings[0].code})`
|
|
346
347
|
: warnings > 0
|
|
347
348
|
? `no error findings; ${String(warnings)} warning finding(s)`
|
|
348
349
|
: 'every check passed'
|
package/src/compose-tool.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
2
2
|
import type { JsonValue } from './json-value.js'
|
|
3
3
|
import { runCompositionVerification } from './engine.js'
|
|
4
|
-
import { reportCard, reportResultView } from './presentation.js'
|
|
4
|
+
import { reportCallView, reportCard, reportResultView } from './presentation.js'
|
|
5
5
|
import type { SharedAccess, SharedLocation } from './engine.js'
|
|
6
6
|
import { OptionShapeError, optionRefusal, requireArrayOption } from './option-shape.js'
|
|
7
7
|
import { renderReportText } from './report-view.js'
|
|
@@ -61,7 +61,9 @@ export const modelComposeTool = defineTool({
|
|
|
61
61
|
presentationMeta(_args, value) {
|
|
62
62
|
return reportCard(value, COMPOSE_TOOL_NAME) as unknown as JsonValue
|
|
63
63
|
},
|
|
64
|
-
},
|
|
64
|
+
},
|
|
65
|
+
presentCall: reportCallView(COMPOSE_TOOL_NAME),
|
|
66
|
+
presentResult: reportResultView(COMPOSE_TOOL_NAME),
|
|
65
67
|
|
|
66
68
|
timeoutMs: 10_000,
|
|
67
69
|
isConcurrencySafe: () => true,
|
package/src/concurrency-tool.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
|
2
2
|
import type { JsonValue } from './json-value.js'
|
|
3
3
|
import { runConcurrencyScan } from './concurrency.js'
|
|
4
4
|
import { renderReportText } from './report-view.js'
|
|
5
|
-
import { reportCard,
|
|
5
|
+
import { reportCallView, reportCard, scanResultView } from './presentation.js'
|
|
6
6
|
|
|
7
7
|
export const INTERLEAVING_SCAN_TOOL_NAME = 'model_interleaving_scan'
|
|
8
8
|
|
|
@@ -40,7 +40,9 @@ export const modelConcurrencyScanTool = defineTool({
|
|
|
40
40
|
presentationMeta(_args, value) {
|
|
41
41
|
return reportCard(value, INTERLEAVING_SCAN_TOOL_NAME) as unknown as JsonValue
|
|
42
42
|
},
|
|
43
|
-
},
|
|
43
|
+
},
|
|
44
|
+
presentCall: reportCallView(INTERLEAVING_SCAN_TOOL_NAME),
|
|
45
|
+
presentResult: scanResultView,
|
|
44
46
|
|
|
45
47
|
timeoutMs: 10_000,
|
|
46
48
|
isConcurrencySafe: () => true,
|
package/src/data-tool.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { runDataVerification, DATA_ENGINE_SCHEMA_VERSION } from './data-engine.j
|
|
|
4
4
|
import { oneOf } from './model-file.js'
|
|
5
5
|
import { optionRefusal, requireArrayOption, requireObjectOption } from './option-shape.js'
|
|
6
6
|
import { renderReportText } from './report-view.js'
|
|
7
|
-
import { reportCard, reportResultView } from './presentation.js'
|
|
7
|
+
import { reportCallView, reportCard, reportResultView } from './presentation.js'
|
|
8
8
|
|
|
9
9
|
export const DATAMODEL_VERIFY_TOOL_NAME = 'model_datamodel_verify'
|
|
10
10
|
|
|
@@ -69,7 +69,9 @@ export const modelDataModelVerifyTool = defineTool({
|
|
|
69
69
|
presentationMeta(_args, value) {
|
|
70
70
|
return reportCard(value, DATAMODEL_VERIFY_TOOL_NAME) as unknown as JsonValue
|
|
71
71
|
},
|
|
72
|
-
},
|
|
72
|
+
},
|
|
73
|
+
presentCall: reportCallView(DATAMODEL_VERIFY_TOOL_NAME),
|
|
74
|
+
presentResult: reportResultView(DATAMODEL_VERIFY_TOOL_NAME),
|
|
73
75
|
|
|
74
76
|
timeoutMs: 10_000,
|
|
75
77
|
isConcurrencySafe: () => true,
|
package/src/design-tool.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
2
2
|
import type { JsonValue } from './json-value.js'
|
|
3
3
|
import { REPORT_SCHEMAS } from './engine.js'
|
|
4
|
-
import {
|
|
4
|
+
import { designResultView, reportCallView, reportCard } from './presentation.js'
|
|
5
5
|
import { oneOf } from './model-file.js'
|
|
6
6
|
import { runDesignReview } from './design-engine.js'
|
|
7
7
|
import { renderReportText } from './report-view.js'
|
|
@@ -53,7 +53,9 @@ export const designTool = defineTool({
|
|
|
53
53
|
presentationMeta(_args, value) {
|
|
54
54
|
return reportCard(value, DESIGN_TOOL_NAME) as unknown as JsonValue
|
|
55
55
|
},
|
|
56
|
-
},
|
|
56
|
+
},
|
|
57
|
+
presentCall: reportCallView(DESIGN_TOOL_NAME),
|
|
58
|
+
presentResult: designResultView,
|
|
57
59
|
|
|
58
60
|
timeoutMs: 10_000,
|
|
59
61
|
isConcurrencySafe: () => true,
|
package/src/edit-tool.ts
CHANGED
|
@@ -14,7 +14,7 @@ import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
|
14
14
|
import { diffReports } from './baseline.js'
|
|
15
15
|
import { applyEdits, readModelFile } from './editor.js'
|
|
16
16
|
import { REPORT_SCHEMAS, runVerification } from './engine.js'
|
|
17
|
-
import {
|
|
17
|
+
import { editResultView, reportCallView, reportCard } from './presentation.js'
|
|
18
18
|
import type { JsonValue } from './json-value.js'
|
|
19
19
|
import { optionRefusal } from './option-shape.js'
|
|
20
20
|
import { renderReportText } from './report-view.js'
|
|
@@ -66,7 +66,9 @@ export const modelEditTool = defineTool({
|
|
|
66
66
|
presentationMeta(_args, value) {
|
|
67
67
|
return reportCard(value, MODEL_EDIT_TOOL_NAME) as unknown as JsonValue
|
|
68
68
|
},
|
|
69
|
-
},
|
|
69
|
+
},
|
|
70
|
+
presentCall: reportCallView(MODEL_EDIT_TOOL_NAME),
|
|
71
|
+
presentResult: editResultView(MODEL_EDIT_TOOL_NAME),
|
|
70
72
|
|
|
71
73
|
timeoutMs: 20_000,
|
|
72
74
|
isConcurrencySafe: () => false,
|
package/src/export-tool.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
2
2
|
import type { JsonValue } from './json-value.js'
|
|
3
3
|
import { REPORT_SCHEMAS, DEFAULT_HASH_SPEC, modelHash, refusalVerdict, validateModel, verdictOf } from './engine.js'
|
|
4
|
-
import { reportCard, reportResultView } from './presentation.js'
|
|
4
|
+
import { cardWithSource, reportCallView, reportCard, reportResultView } from './presentation.js'
|
|
5
5
|
import { ExportError, exportModel, type ExportFormat } from './exporters.js'
|
|
6
6
|
import { renderReportText } from './report-view.js'
|
|
7
7
|
|
|
@@ -52,9 +52,12 @@ export const modelExportTool = defineTool({
|
|
|
52
52
|
},
|
|
53
53
|
// The card a UI shows, separated from the text the model reads.
|
|
54
54
|
presentationMeta(_args, value) {
|
|
55
|
-
|
|
55
|
+
const report = value as Record<string, unknown>
|
|
56
|
+
return cardWithSource(value, EXPORT_TOOL_NAME, typeof report.primary === 'string' ? report.primary : undefined, typeof report.format === 'string' ? 'artifact: ' + report.format : 'artifact') as unknown as JsonValue
|
|
56
57
|
},
|
|
57
|
-
},
|
|
58
|
+
},
|
|
59
|
+
presentCall: reportCallView(EXPORT_TOOL_NAME),
|
|
60
|
+
presentResult: reportResultView(EXPORT_TOOL_NAME),
|
|
58
61
|
|
|
59
62
|
timeoutMs: 10_000,
|
|
60
63
|
isConcurrencySafe: () => true,
|