@arronqzy/react-view 1.0.11 → 1.0.12

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/dist/styles.css CHANGED
@@ -1090,6 +1090,10 @@ video {
1090
1090
  width: 2.25rem;
1091
1091
  }
1092
1092
 
1093
+ .w-\[108px\] {
1094
+ width: 108px;
1095
+ }
1096
+
1093
1097
  .w-\[220px\] {
1094
1098
  width: 220px;
1095
1099
  }
@@ -1098,10 +1102,6 @@ video {
1098
1102
  width: 280px;
1099
1103
  }
1100
1104
 
1101
- .w-\[96px\] {
1102
- width: 96px;
1103
- }
1104
-
1105
1105
  .w-\[min\(92vw\2c 720px\)\] {
1106
1106
  width: min(92vw, 720px);
1107
1107
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arronqzy/react-view",
3
- "version": "1.0.11",
3
+ "version": "1.0.12",
4
4
  "files": [
5
5
  "src",
6
6
  "dist",
@@ -31,12 +31,12 @@
31
31
  "@codemirror/theme-one-dark": "^6.1.2",
32
32
  "@codemirror/view": "^6.36.2",
33
33
  "@arronqzy/blueprint-dsl": "1.0.5",
34
- "@arronqzy/i18n": "0.1.3",
35
34
  "@arronqzy/ui": "1.0.5",
35
+ "@arronqzy/i18n": "0.1.4",
36
+ "@arronqzy/webllm-assistant": "0.1.6",
36
37
  "@arronqzy/react-blueprint": "1.0.6",
37
- "@arronqzy/rx-store": "1.0.4",
38
- "@arronqzy/webllm-assistant": "0.1.5",
39
- "@arronqzy/view-table": "0.1.3"
38
+ "@arronqzy/view-table": "0.1.3",
39
+ "@arronqzy/rx-store": "1.0.4"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@types/react": "^19.0.1",
@@ -3,18 +3,17 @@ import {
3
3
  ASSISTANT_MODEL_OPTIONS,
4
4
  DEFAULT_MODEL_ID,
5
5
  WebLLMAssistantRuntime,
6
- buildSystemPrompt,
7
6
  isWebGPUAvailable,
8
7
  looksLikePureQuestion,
9
- parseAssistantAction,
10
8
  inferPanelAddFromUserText,
11
9
  runAgentLoop,
12
10
  buildEditorContext,
13
11
  tryLocalFaqReply,
12
+ buildChatSystemPrompt,
14
13
  buildForceReplyPrompt,
14
+ unwrapChatReply,
15
15
  buildPriorChatMessages,
16
16
  buildRecentDialogSummary,
17
- looksLikeUnclearIntent,
18
17
  UNCLEAR_INTENT_REPLY,
19
18
  inferLocalEditorPlan,
20
19
  type ChatMessage,
@@ -345,15 +344,6 @@ export function AssistantChatPanel({
345
344
  return;
346
345
  }
347
346
 
348
- // Vague greetings / short junk — ask instead of mutating.
349
- if (looksLikeUnclearIntent(trimmed)) {
350
- pushMessage({
351
- role: "assistant",
352
- content: t("panel.ai.unclearIntent") || UNCLEAR_INTENT_REPLY,
353
- });
354
- return;
355
- }
356
-
357
347
  // High-confidence local tools (add / resize / delete / save …) — skip model.
358
348
  const selectedIds = depsRef.current.getSelectedIds() ?? [];
359
349
  const localPlan = inferLocalEditorPlan(trimmed, { selectedIds });
@@ -402,41 +392,20 @@ export function AssistantChatPanel({
402
392
  const runtime = runtimeRef.current!;
403
393
 
404
394
  if (looksLikePureQuestion(trimmed)) {
405
- const ctx = buildEditorContext({
406
- ...buildObservation(),
407
- userGoal: trimmed,
408
- recentDialog,
409
- });
410
395
  const history: ChatMessage[] = [
411
- { role: "system", content: buildSystemPrompt(ctx) },
396
+ { role: "system", content: buildChatSystemPrompt() },
412
397
  ...priorChat,
413
398
  { role: "user", content: trimmed },
414
399
  ];
415
- let parsed = parseAssistantAction(await runtime.chat(history));
416
- if (parsed.ok && parsed.action.type !== "reply") {
417
- // Small models often mutate the page on Q&A — force a reply-only turn.
418
- history.push({
419
- role: "assistant",
420
- content: JSON.stringify(parsed.action),
421
- });
400
+ let message = unwrapChatReply(await runtime.chat(history));
401
+ if (!message) {
422
402
  history.push({ role: "user", content: buildForceReplyPrompt() });
423
- parsed = parseAssistantAction(await runtime.chat(history));
403
+ message = unwrapChatReply(await runtime.chat(history));
424
404
  }
425
- if (!parsed.ok) {
426
- pushMessage({
427
- role: "assistant",
428
- content: `${t("panel.ai.parseFailed")}\n\n\`\`\`\n${parsed.rawText.slice(0, 800)}\n\`\`\``,
429
- });
430
- return;
431
- }
432
- if (parsed.action.type === "reply") {
433
- pushMessage({ role: "assistant", content: parsed.action.message });
434
- return;
435
- }
436
- // Still not a reply — refuse to mutate; ask clearly instead.
437
405
  pushMessage({
438
406
  role: "assistant",
439
- content: t("panel.ai.unclearIntent") || UNCLEAR_INTENT_REPLY,
407
+ content:
408
+ message || t("panel.ai.unclearIntent") || UNCLEAR_INTENT_REPLY,
440
409
  });
441
410
  return;
442
411
  }
@@ -625,12 +594,17 @@ export function AssistantChatPanel({
625
594
  onValueChange={setModelId}
626
595
  disabled={busy || status === "loading"}
627
596
  >
628
- <SelectTrigger className="h-8 w-[96px] rounded-md border-border bg-background text-[12px] shadow-none">
597
+ <SelectTrigger className="h-8 w-[108px] rounded-md border-border bg-background text-[12px] shadow-none">
629
598
  <SelectValue />
630
599
  </SelectTrigger>
631
600
  <SelectContent position="popper" sideOffset={6}>
632
601
  {ASSISTANT_MODEL_OPTIONS.map((opt) => (
633
- <SelectItem key={opt.id} value={opt.id} className="text-[12px]">
602
+ <SelectItem
603
+ key={opt.id}
604
+ value={opt.id}
605
+ className="text-[12px]"
606
+ title={t(opt.hintKey)}
607
+ >
634
608
  {t(opt.labelKey)}
635
609
  </SelectItem>
636
610
  ))}
@@ -84,6 +84,40 @@ function deepMerge<T extends Record<string, any>>(base: T, patch?: Record<string
84
84
  return next as T;
85
85
  }
86
86
 
87
+ function mixHex(a: string, b: string, t: number): string {
88
+ const pa = parseHex(a);
89
+ const pb = parseHex(b);
90
+ if (!pa || !pb) return a;
91
+ const m = (i: number) => Math.round(pa[i]! * (1 - t) + pb[i]! * t);
92
+ return `#${[m(0), m(1), m(2)].map((n) => n.toString(16).padStart(2, "0")).join("")}`;
93
+ }
94
+
95
+ function parseHex(hex: string): [number, number, number] | null {
96
+ const s = hex.replace("#", "").trim();
97
+ const full =
98
+ s.length === 3
99
+ ? s
100
+ .split("")
101
+ .map((c) => c + c)
102
+ .join("")
103
+ : s.slice(0, 6);
104
+ if (!/^[0-9a-fA-F]{6}$/.test(full)) return null;
105
+ return [
106
+ Number.parseInt(full.slice(0, 2), 16),
107
+ Number.parseInt(full.slice(2, 4), 16),
108
+ Number.parseInt(full.slice(4, 6), 16),
109
+ ];
110
+ }
111
+
112
+ function pieSliceColors(base: string, count: number): string[] {
113
+ const n = Math.max(count, 1);
114
+ if (n === 1) return [base];
115
+ return Array.from({ length: n }, (_, i) => {
116
+ const t = n === 1 ? 0 : i / (n - 1);
117
+ return mixHex(mixHex(base, "#111827", 0.12), "#fefce8", t * 0.45);
118
+ });
119
+ }
120
+
87
121
  export function buildChartOption(element: PanelElement): EChartsOption {
88
122
  const chartType = (element.materialType ?? "") as ChartType;
89
123
  const labels = resolveChartLabels(element);
@@ -144,10 +178,11 @@ export function buildChartOption(element: PanelElement): EChartsOption {
144
178
  if (chartType === "pie") {
145
179
  const inner = element.chart?.pieInnerRadius ?? 30;
146
180
  const outer = element.chart?.pieOuterRadius ?? 65;
181
+ const sliceColors = pieSliceColors(color, labels.length);
147
182
  const baseOption: EChartsOption = {
148
183
  animation: false,
149
184
  title: { text: title, left: "center", top: 6, textStyle: { fontSize: 12 } },
150
- color: [chartColor as any],
185
+ color: sliceColors as any,
151
186
  tooltip: tooltipOption,
152
187
  series: [
153
188
  {
@@ -155,7 +190,11 @@ export function buildChartOption(element: PanelElement): EChartsOption {
155
190
  radius: [`${inner}%`, `${outer}%`],
156
191
  center: ["50%", "58%"],
157
192
  label: { fontSize: 10 },
158
- data: labels.map((name, i) => ({ name, value: values[i] ?? 0 })),
193
+ data: labels.map((name, i) => ({
194
+ name,
195
+ value: values[i] ?? 0,
196
+ itemStyle: { color: sliceColors[i % sliceColors.length] as any },
197
+ })),
159
198
  },
160
199
  ],
161
200
  };