@agent-native/core 0.80.7 → 0.80.8
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/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +6 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/client/AssistantChat.tsx +70 -27
- package/corpus/core/src/client/analytics.ts +3 -1
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +69 -16
- package/corpus/templates/content/changelog/2026-06-29-read-only-pages-no-longer-try-to-autosave-or-open-editor-onl.md +6 -0
- package/corpus/templates/design/AGENTS.md +4 -2
- package/corpus/templates/design/actions/edit-design.ts +6 -3
- package/corpus/templates/design/actions/generate-screens.ts +5 -3
- package/corpus/templates/design/actions/update-design.ts +47 -10
- package/corpus/templates/design/actions/update-file.ts +33 -8
- package/corpus/templates/design/actions/view-screen.ts +14 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +75 -17
- package/corpus/templates/design/app/components/design/EditPanel.tsx +121 -22
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +51 -8
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +148 -33
- package/corpus/templates/design/app/components/design/QuestionFlow.tsx +11 -11
- package/corpus/templates/design/app/components/design/TweaksPanel.tsx +27 -13
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +3 -37
- package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +18 -2
- package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +15 -3
- package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +4 -2
- package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +18 -4
- package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +10 -4
- package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +448 -259
- package/corpus/templates/design/app/hooks/use-variant-flow.ts +176 -92
- package/corpus/templates/design/app/i18n/zh-TW.ts +1 -0
- package/corpus/templates/design/app/i18n-data.ts +10 -0
- package/corpus/templates/design/app/pages/DesignEditor.tsx +220 -40
- package/corpus/templates/design/changelog/2026-06-29-agent-edits-to-a-design-are-no-longer-occasionally-dropped-o.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-box-shadow-and-gradient-colors-keep-named-css-colors-like-re.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-cut-cmd-ctrl-x-now-removes-the-selected-element-to-the-clipb.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-deleting-with-multiple-layers-selected-in-the-layers-panel-n.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-duplicating-a-screen-now-gives-the-copy-its-own-layer-ids-so.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-hiding-and-re-showing-a-gradient-fill-now-preserves-each-sto.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-picking-a-design-direction-now-submits-to-the-agent-right-aw.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-style-changes-that-set-several-properties-at-once-fixed-size.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-the-editor-no-longer-crashes-when-a-screen-ends-up-with-dupl.md +6 -0
- package/corpus/templates/design/e2e/README.md +1 -0
- package/corpus/templates/design/e2e/global-setup.ts +13 -1
- package/corpus/templates/design/playwright.config.ts +10 -1
- package/corpus/templates/design/shared/color-utils.ts +159 -0
- package/corpus/templates/design/shared/generation-session.ts +1 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +54 -24
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +2 -1
- package/dist/client/analytics.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +8 -8
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/package.json +1 -1
|
@@ -17,6 +17,160 @@ const RGB_PATTERN =
|
|
|
17
17
|
const HSL_PATTERN =
|
|
18
18
|
/^hsla?\(\s*([0-9.]+)(?:deg)?\s*,\s*([0-9.]+)%\s*,\s*([0-9.]+)%(?:\s*,\s*([0-9.]+%?))?\s*\)$/i;
|
|
19
19
|
|
|
20
|
+
// CSS named colors → hex, so detection/round-tripping works for shadows, gradient
|
|
21
|
+
// stops, and the color picker (not just #hex/rgb()/hsl()). `transparent` is handled
|
|
22
|
+
// separately as fully transparent black.
|
|
23
|
+
const NAMED_COLOR_HEX: Record<string, string> = {
|
|
24
|
+
aliceblue: "#f0f8ff",
|
|
25
|
+
antiquewhite: "#faebd7",
|
|
26
|
+
aqua: "#00ffff",
|
|
27
|
+
aquamarine: "#7fffd4",
|
|
28
|
+
azure: "#f0ffff",
|
|
29
|
+
beige: "#f5f5dc",
|
|
30
|
+
bisque: "#ffe4c4",
|
|
31
|
+
black: "#000000",
|
|
32
|
+
blanchedalmond: "#ffebcd",
|
|
33
|
+
blue: "#0000ff",
|
|
34
|
+
blueviolet: "#8a2be2",
|
|
35
|
+
brown: "#a52a2a",
|
|
36
|
+
burlywood: "#deb887",
|
|
37
|
+
cadetblue: "#5f9ea0",
|
|
38
|
+
chartreuse: "#7fff00",
|
|
39
|
+
chocolate: "#d2691e",
|
|
40
|
+
coral: "#ff7f50",
|
|
41
|
+
cornflowerblue: "#6495ed",
|
|
42
|
+
cornsilk: "#fff8dc",
|
|
43
|
+
crimson: "#dc143c",
|
|
44
|
+
cyan: "#00ffff",
|
|
45
|
+
darkblue: "#00008b",
|
|
46
|
+
darkcyan: "#008b8b",
|
|
47
|
+
darkgoldenrod: "#b8860b",
|
|
48
|
+
darkgray: "#a9a9a9",
|
|
49
|
+
darkgreen: "#006400",
|
|
50
|
+
darkgrey: "#a9a9a9",
|
|
51
|
+
darkkhaki: "#bdb76b",
|
|
52
|
+
darkmagenta: "#8b008b",
|
|
53
|
+
darkolivegreen: "#556b2f",
|
|
54
|
+
darkorange: "#ff8c00",
|
|
55
|
+
darkorchid: "#9932cc",
|
|
56
|
+
darkred: "#8b0000",
|
|
57
|
+
darksalmon: "#e9967a",
|
|
58
|
+
darkseagreen: "#8fbc8f",
|
|
59
|
+
darkslateblue: "#483d8b",
|
|
60
|
+
darkslategray: "#2f4f4f",
|
|
61
|
+
darkslategrey: "#2f4f4f",
|
|
62
|
+
darkturquoise: "#00ced1",
|
|
63
|
+
darkviolet: "#9400d3",
|
|
64
|
+
deeppink: "#ff1493",
|
|
65
|
+
deepskyblue: "#00bfff",
|
|
66
|
+
dimgray: "#696969",
|
|
67
|
+
dimgrey: "#696969",
|
|
68
|
+
dodgerblue: "#1e90ff",
|
|
69
|
+
firebrick: "#b22222",
|
|
70
|
+
floralwhite: "#fffaf0",
|
|
71
|
+
forestgreen: "#228b22",
|
|
72
|
+
fuchsia: "#ff00ff",
|
|
73
|
+
gainsboro: "#dcdcdc",
|
|
74
|
+
ghostwhite: "#f8f8ff",
|
|
75
|
+
gold: "#ffd700",
|
|
76
|
+
goldenrod: "#daa520",
|
|
77
|
+
gray: "#808080",
|
|
78
|
+
green: "#008000",
|
|
79
|
+
greenyellow: "#adff2f",
|
|
80
|
+
grey: "#808080",
|
|
81
|
+
honeydew: "#f0fff0",
|
|
82
|
+
hotpink: "#ff69b4",
|
|
83
|
+
indianred: "#cd5c5c",
|
|
84
|
+
indigo: "#4b0082",
|
|
85
|
+
ivory: "#fffff0",
|
|
86
|
+
khaki: "#f0e68c",
|
|
87
|
+
lavender: "#e6e6fa",
|
|
88
|
+
lavenderblush: "#fff0f5",
|
|
89
|
+
lawngreen: "#7cfc00",
|
|
90
|
+
lemonchiffon: "#fffacd",
|
|
91
|
+
lightblue: "#add8e6",
|
|
92
|
+
lightcoral: "#f08080",
|
|
93
|
+
lightcyan: "#e0ffff",
|
|
94
|
+
lightgoldenrodyellow: "#fafad2",
|
|
95
|
+
lightgray: "#d3d3d3",
|
|
96
|
+
lightgreen: "#90ee90",
|
|
97
|
+
lightgrey: "#d3d3d3",
|
|
98
|
+
lightpink: "#ffb6c1",
|
|
99
|
+
lightsalmon: "#ffa07a",
|
|
100
|
+
lightseagreen: "#20b2aa",
|
|
101
|
+
lightskyblue: "#87cefa",
|
|
102
|
+
lightslategray: "#778899",
|
|
103
|
+
lightslategrey: "#778899",
|
|
104
|
+
lightsteelblue: "#b0c4de",
|
|
105
|
+
lightyellow: "#ffffe0",
|
|
106
|
+
lime: "#00ff00",
|
|
107
|
+
limegreen: "#32cd32",
|
|
108
|
+
linen: "#faf0e6",
|
|
109
|
+
magenta: "#ff00ff",
|
|
110
|
+
maroon: "#800000",
|
|
111
|
+
mediumaquamarine: "#66cdaa",
|
|
112
|
+
mediumblue: "#0000cd",
|
|
113
|
+
mediumorchid: "#ba55d3",
|
|
114
|
+
mediumpurple: "#9370db",
|
|
115
|
+
mediumseagreen: "#3cb371",
|
|
116
|
+
mediumslateblue: "#7b68ee",
|
|
117
|
+
mediumspringgreen: "#00fa9a",
|
|
118
|
+
mediumturquoise: "#48d1cc",
|
|
119
|
+
mediumvioletred: "#c71585",
|
|
120
|
+
midnightblue: "#191970",
|
|
121
|
+
mintcream: "#f5fffa",
|
|
122
|
+
mistyrose: "#ffe4e1",
|
|
123
|
+
moccasin: "#ffe4b5",
|
|
124
|
+
navajowhite: "#ffdead",
|
|
125
|
+
navy: "#000080",
|
|
126
|
+
oldlace: "#fdf5e6",
|
|
127
|
+
olive: "#808000",
|
|
128
|
+
olivedrab: "#6b8e23",
|
|
129
|
+
orange: "#ffa500",
|
|
130
|
+
orangered: "#ff4500",
|
|
131
|
+
orchid: "#da70d6",
|
|
132
|
+
palegoldenrod: "#eee8aa",
|
|
133
|
+
palegreen: "#98fb98",
|
|
134
|
+
paleturquoise: "#afeeee",
|
|
135
|
+
palevioletred: "#db7093",
|
|
136
|
+
papayawhip: "#ffefd5",
|
|
137
|
+
peachpuff: "#ffdab9",
|
|
138
|
+
peru: "#cd853f",
|
|
139
|
+
pink: "#ffc0cb",
|
|
140
|
+
plum: "#dda0dd",
|
|
141
|
+
powderblue: "#b0e0e6",
|
|
142
|
+
purple: "#800080",
|
|
143
|
+
rebeccapurple: "#663399",
|
|
144
|
+
red: "#ff0000",
|
|
145
|
+
rosybrown: "#bc8f8f",
|
|
146
|
+
royalblue: "#4169e1",
|
|
147
|
+
saddlebrown: "#8b4513",
|
|
148
|
+
salmon: "#fa8072",
|
|
149
|
+
sandybrown: "#f4a460",
|
|
150
|
+
seagreen: "#2e8b57",
|
|
151
|
+
seashell: "#fff5ee",
|
|
152
|
+
sienna: "#a0522d",
|
|
153
|
+
silver: "#c0c0c0",
|
|
154
|
+
skyblue: "#87ceeb",
|
|
155
|
+
slateblue: "#6a5acd",
|
|
156
|
+
slategray: "#708090",
|
|
157
|
+
slategrey: "#708090",
|
|
158
|
+
snow: "#fffafa",
|
|
159
|
+
springgreen: "#00ff7f",
|
|
160
|
+
steelblue: "#4682b4",
|
|
161
|
+
tan: "#d2b48c",
|
|
162
|
+
teal: "#008080",
|
|
163
|
+
thistle: "#d8bfd8",
|
|
164
|
+
tomato: "#ff6347",
|
|
165
|
+
turquoise: "#40e0d0",
|
|
166
|
+
violet: "#ee82ee",
|
|
167
|
+
wheat: "#f5deb3",
|
|
168
|
+
white: "#ffffff",
|
|
169
|
+
whitesmoke: "#f5f5f5",
|
|
170
|
+
yellow: "#ffff00",
|
|
171
|
+
yellowgreen: "#9acd32",
|
|
172
|
+
};
|
|
173
|
+
|
|
20
174
|
export function parseCssColor(value: string): RgbaColor | null {
|
|
21
175
|
const trimmed = value.trim();
|
|
22
176
|
if (!trimmed) return null;
|
|
@@ -43,6 +197,11 @@ export function parseCssColor(value: string): RgbaColor | null {
|
|
|
43
197
|
});
|
|
44
198
|
}
|
|
45
199
|
|
|
200
|
+
const lower = trimmed.toLowerCase();
|
|
201
|
+
if (lower === "transparent") return { r: 0, g: 0, b: 0, a: 0 };
|
|
202
|
+
const namedHex = NAMED_COLOR_HEX[lower];
|
|
203
|
+
if (namedHex) return hexToRgba(namedHex);
|
|
204
|
+
|
|
46
205
|
return null;
|
|
47
206
|
}
|
|
48
207
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssistantChat.d.ts","sourceRoot":"","sources":["../../src/client/AssistantChat.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAEV,gBAAgB,EAChB,yBAAyB,EAC1B,MAAM,qBAAqB,CAAC;AAW7B,OAAO,KASN,MAAM,OAAO,CAAC;AAGf,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAOrE,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAQL,KAAK,oBAAoB,EAC1B,MAAM,iBAAiB,CAAC;AAqCzB,OAAO,EAQL,KAAK,sBAAsB,EAG5B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,mBAAmB,CAAC;AAiB3B,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAE5B,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EACV,0BAA0B,EAE3B,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAEL,KAAK,6BAA6B,EACnC,MAAM,0BAA0B,CAAC;AAelC,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EACnB,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EACL,iCAAiC,EACjC,kCAAkC,EAClC,qCAAqC,EACrC,mCAAmC,EACnC,4BAA4B,GAC7B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAK1E,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,MAAM,CAAC;AAC9C,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,OAAO,CAAC;AACvD,MAAM,WAAW,wBAAwB;IACvC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,gBAAgB,CAAC;CAChC;
|
|
1
|
+
{"version":3,"file":"AssistantChat.d.ts","sourceRoot":"","sources":["../../src/client/AssistantChat.tsx"],"names":[],"mappings":"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"}
|
|
@@ -66,13 +66,20 @@ function createUserMessageRunConfig(references, requestMode, recoveryAction, tra
|
|
|
66
66
|
}
|
|
67
67
|
const PENDING_SELECTION_KEY = "pending-selection-context";
|
|
68
68
|
const ACTIVE_RUN_CLEAR_TIMEOUT_MS = 5_000;
|
|
69
|
+
const ACTIVE_RUN_STUCK_THRESHOLD_MS = 90_000;
|
|
69
70
|
const ACTIVE_RUN_POLL_INTERVAL_MS = 150;
|
|
70
71
|
const SUBMIT_ENGINE_STATUS_TIMEOUT_MS = 1000;
|
|
71
72
|
function activeRunLooksStale(runInfo) {
|
|
72
|
-
const
|
|
73
|
+
const lastProgressAt = typeof runInfo.lastProgressAt === "number" ? runInfo.lastProgressAt : null;
|
|
74
|
+
const nowMs = typeof runInfo.serverNow === "number" ? runInfo.serverNow : Date.now();
|
|
73
75
|
return (runInfo.status === "running" &&
|
|
74
|
-
|
|
75
|
-
|
|
76
|
+
lastProgressAt != null &&
|
|
77
|
+
nowMs - lastProgressAt > ACTIVE_RUN_STUCK_THRESHOLD_MS);
|
|
78
|
+
}
|
|
79
|
+
function isAssistantUiDuplicateMessageIdError(error) {
|
|
80
|
+
const message = error instanceof Error ? error.message : String(error ?? "");
|
|
81
|
+
return (message.includes("MessageRepository") &&
|
|
82
|
+
message.includes("same id already exists"));
|
|
76
83
|
}
|
|
77
84
|
function cloneContentParts(content) {
|
|
78
85
|
return content.map((part) => part.type === "text"
|
|
@@ -108,12 +115,10 @@ async function waitForThreadRunToClear(apiUrl, threadId) {
|
|
|
108
115
|
try {
|
|
109
116
|
const res = await fetch(`${apiUrl}/runs/active?threadId=${encodeURIComponent(threadId)}`);
|
|
110
117
|
if (res.ok) {
|
|
111
|
-
const info = await res.json();
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
Date.now() - heartbeatAt > 5000;
|
|
116
|
-
if (!info?.active || info?.status !== "running" || stale)
|
|
118
|
+
const info = (await res.json());
|
|
119
|
+
if (!info?.active ||
|
|
120
|
+
info?.status !== "running" ||
|
|
121
|
+
activeRunLooksStale(info))
|
|
117
122
|
return;
|
|
118
123
|
}
|
|
119
124
|
}
|
|
@@ -824,10 +829,35 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
824
829
|
return null;
|
|
825
830
|
}
|
|
826
831
|
}, [apiUrl, importThreadData, loadHistoryRepository, threadId]);
|
|
832
|
+
const exportCleanThreadRepo = useCallback(() => ensureMessageMetadata(normalizeThreadRepository(threadRuntime.export())), [threadRuntime]);
|
|
833
|
+
const appendThreadMessage = useCallback((message) => {
|
|
834
|
+
try {
|
|
835
|
+
threadRuntime.append(message);
|
|
836
|
+
return;
|
|
837
|
+
}
|
|
838
|
+
catch (error) {
|
|
839
|
+
if (!isAssistantUiDuplicateMessageIdError(error))
|
|
840
|
+
throw error;
|
|
841
|
+
}
|
|
842
|
+
try {
|
|
843
|
+
threadRuntime.import(exportCleanThreadRepo());
|
|
844
|
+
}
|
|
845
|
+
catch {
|
|
846
|
+
// Best effort cleanup; retry below handles the still-duplicated case.
|
|
847
|
+
}
|
|
848
|
+
try {
|
|
849
|
+
threadRuntime.append(message);
|
|
850
|
+
}
|
|
851
|
+
catch (retryError) {
|
|
852
|
+
if (isAssistantUiDuplicateMessageIdError(retryError))
|
|
853
|
+
return;
|
|
854
|
+
throw retryError;
|
|
855
|
+
}
|
|
856
|
+
}, [exportCleanThreadRepo, threadRuntime]);
|
|
827
857
|
const cacheCurrentThreadSnapshot = useCallback(() => {
|
|
828
858
|
if (!threadId || messages.length === 0)
|
|
829
859
|
return;
|
|
830
|
-
const repo =
|
|
860
|
+
const repo = exportCleanThreadRepo();
|
|
831
861
|
const threadData = JSON.stringify(stripBase64FromRepo(repo));
|
|
832
862
|
const { title, preview } = extractThreadMeta(repo);
|
|
833
863
|
writeCachedThreadSnapshot(apiUrl, threadId, {
|
|
@@ -836,7 +866,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
836
866
|
preview,
|
|
837
867
|
messageCount: messages.length,
|
|
838
868
|
});
|
|
839
|
-
}, [apiUrl, messages.length, threadId
|
|
869
|
+
}, [apiUrl, exportCleanThreadRepo, messages.length, threadId]);
|
|
840
870
|
useBrowserLayoutEffect(() => {
|
|
841
871
|
if (hasImportedInitialCachedSnapshotRef.current)
|
|
842
872
|
return;
|
|
@@ -1298,7 +1328,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1298
1328
|
const timeSinceLastSave = now - lastSaveTimeRef.current;
|
|
1299
1329
|
if (timeSinceLastSave < 5000)
|
|
1300
1330
|
return;
|
|
1301
|
-
const repo =
|
|
1331
|
+
const repo = exportCleanThreadRepo();
|
|
1302
1332
|
const { title, preview } = extractThreadMeta(repo);
|
|
1303
1333
|
const threadData = JSON.stringify(stripBase64FromRepo(repo));
|
|
1304
1334
|
const snapshot = {
|
|
@@ -1311,7 +1341,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1311
1341
|
savedTitleRef.current = title;
|
|
1312
1342
|
writeCachedThreadSnapshot(apiUrl, threadId, snapshot);
|
|
1313
1343
|
onSaveThreadRef.current(threadId, snapshot);
|
|
1314
|
-
}, [apiUrl, messages, isRunning, threadId
|
|
1344
|
+
}, [apiUrl, exportCleanThreadRepo, messages, isRunning, threadId]);
|
|
1315
1345
|
// Persist full thread data after each completed response
|
|
1316
1346
|
useEffect(() => {
|
|
1317
1347
|
if (!hasRestoredRef.current)
|
|
@@ -1320,7 +1350,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1320
1350
|
return;
|
|
1321
1351
|
if (messages.length === 0)
|
|
1322
1352
|
return;
|
|
1323
|
-
const repo =
|
|
1353
|
+
const repo = exportCleanThreadRepo();
|
|
1324
1354
|
if (threadId && onSaveThreadRef.current) {
|
|
1325
1355
|
// Save to server via the hook callback
|
|
1326
1356
|
const { title, preview } = extractThreadMeta(repo);
|
|
@@ -1343,7 +1373,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1343
1373
|
}
|
|
1344
1374
|
catch { }
|
|
1345
1375
|
}
|
|
1346
|
-
}, [apiUrl, messages, isRunning, threadId, tabId
|
|
1376
|
+
}, [apiUrl, exportCleanThreadRepo, messages, isRunning, threadId, tabId]);
|
|
1347
1377
|
useEffect(() => {
|
|
1348
1378
|
onMessageCountChange?.(messages.length);
|
|
1349
1379
|
}, [messages.length, onMessageCountChange]);
|
|
@@ -1577,7 +1607,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1577
1607
|
const messageAttachments = next.attachments && next.attachments.length > 0
|
|
1578
1608
|
? next.attachments
|
|
1579
1609
|
: (imageAttachments ?? []);
|
|
1580
|
-
|
|
1610
|
+
appendThreadMessage({
|
|
1581
1611
|
role: "user",
|
|
1582
1612
|
content: [{ type: "text", text: next.text }],
|
|
1583
1613
|
...(messageAttachments.length > 0
|
|
@@ -1624,12 +1654,12 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1624
1654
|
};
|
|
1625
1655
|
}, [
|
|
1626
1656
|
apiUrl,
|
|
1657
|
+
appendThreadMessage,
|
|
1627
1658
|
applyLocalQueuedMessages,
|
|
1628
1659
|
isRestoring,
|
|
1629
1660
|
isRunning,
|
|
1630
1661
|
queuedMessages,
|
|
1631
1662
|
threadId,
|
|
1632
|
-
threadRuntime,
|
|
1633
1663
|
]);
|
|
1634
1664
|
// Clear frozen reconnect content + forceStopped only on the false→true
|
|
1635
1665
|
// transition of isRuntimeRunning (i.e. a NEW run is actually starting).
|
|
@@ -1924,7 +1954,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1924
1954
|
]);
|
|
1925
1955
|
}
|
|
1926
1956
|
else {
|
|
1927
|
-
|
|
1957
|
+
appendThreadMessage({
|
|
1928
1958
|
role: "user",
|
|
1929
1959
|
content: [{ type: "text", text: submittedText }],
|
|
1930
1960
|
...(messageAttachments.length > 0
|
|
@@ -1943,7 +1973,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1943
1973
|
execMode,
|
|
1944
1974
|
isRunning,
|
|
1945
1975
|
materializeFrozenReconnectContent,
|
|
1946
|
-
|
|
1976
|
+
appendThreadMessage,
|
|
1947
1977
|
updateComposerContextItems,
|
|
1948
1978
|
]);
|
|
1949
1979
|
// Expose imperative handle
|
|
@@ -1980,7 +2010,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1980
2010
|
exportThreadSnapshot() {
|
|
1981
2011
|
if (messages.length === 0)
|
|
1982
2012
|
return null;
|
|
1983
|
-
const repo =
|
|
2013
|
+
const repo = exportCleanThreadRepo();
|
|
1984
2014
|
const { title, preview } = extractThreadMeta(repo);
|
|
1985
2015
|
return {
|
|
1986
2016
|
threadData: JSON.stringify(repo),
|
|
@@ -1991,10 +2021,10 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1991
2021
|
},
|
|
1992
2022
|
}), [
|
|
1993
2023
|
addToQueue,
|
|
2024
|
+
exportCleanThreadRepo,
|
|
1994
2025
|
messages.length,
|
|
1995
2026
|
stageComposerContextItem,
|
|
1996
2027
|
thread.isRunning,
|
|
1997
|
-
threadRuntime,
|
|
1998
2028
|
]);
|
|
1999
2029
|
const autoscrollFollowKey = useMemo(() => [
|
|
2000
2030
|
messages.map(messageFollowKey).join(";"),
|
|
@@ -2137,7 +2167,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
2137
2167
|
// queued messages (no hand-written fetch).
|
|
2138
2168
|
const approvalCtx = useMemo(() => ({
|
|
2139
2169
|
onApprove: (approvalKey) => {
|
|
2140
|
-
|
|
2170
|
+
appendThreadMessage({
|
|
2141
2171
|
role: "user",
|
|
2142
2172
|
content: [
|
|
2143
2173
|
{
|
|
@@ -2152,7 +2182,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
2152
2182
|
: undefined, undefined, undefined, [approvalKey]),
|
|
2153
2183
|
});
|
|
2154
2184
|
},
|
|
2155
|
-
}), [
|
|
2185
|
+
}), [appendThreadMessage, execMode]);
|
|
2156
2186
|
return (_jsx(CheckpointContext.Provider, { value: checkpointCtx, children: _jsx(MessageActionsContext.Provider, { value: messageActionsCtx, children: _jsx(ApprovalContext.Provider, { value: approvalCtx, children: _jsx(ChatRunningContext.Provider, { value: isRunning, children: _jsx(TextStreamingContext.Provider, { value: textStreaming, children: _jsxs("div", { "data-agent-empty-state": centeredEmptyState ? "centered" : undefined, className: cn("relative flex flex-1 flex-col h-full min-h-0 text-foreground", className), onDragEnter: handleChatDragEnter, onDragOver: handleChatDragOver, onDragLeave: handleChatDragLeave, onDropCapture: handleChatDropCapture, onDrop: handleChatDrop, children: [dropActive && (_jsx("div", { "aria-hidden": "true", className: "pointer-events-none absolute inset-0 z-50 flex items-center justify-center rounded-md border-2 border-dashed border-primary/70 bg-primary/5 backdrop-blur-[1px]", children: _jsx("span", { className: "rounded-md bg-background/90 px-3 py-1.5 text-xs font-medium text-foreground shadow-sm", children: "Drop to attach" }) })), showHeader && (_jsxs("div", { className: "flex h-11 shrink-0 items-center justify-between border-b border-border px-4", children: [_jsx("span", { className: "text-[13px] font-medium text-muted-foreground", children: "Agent" }), _jsx("div", { className: "flex items-center gap-1", children: onSwitchToCli && (_jsx(TooltipProvider, { delayDuration: 200, children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { onClick: onSwitchToCli, "aria-label": "Switch to CLI", className: "flex items-center gap-1 text-[12px] text-muted-foreground hover:text-foreground px-2 py-1 rounded-md hover:bg-accent", children: [_jsx(IconTerminal, { className: "h-3.5 w-3.5" }), "CLI"] }) }), _jsx(TooltipContent, { children: "Switch to CLI" })] }) })) })] })), _jsx("div", { ref: scrollRef, className: "agent-chat-scroll flex-1 overflow-y-auto overflow-x-hidden min-h-0", children: authError ? (_jsxs("div", { className: "flex flex-col items-center justify-center h-full px-4 gap-3", children: [_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full bg-muted", children: authSessionAvailable ? (_jsx(IconRefresh, { className: "h-5 w-5 text-muted-foreground" })) : (_jsx(IconMessage, { className: "h-5 w-5 text-muted-foreground" })) }), _jsxs("div", { className: "text-center max-w-[280px]", children: [_jsx("p", { className: "text-sm font-medium text-foreground mb-1", children: authSessionAvailable
|
|
2157
2187
|
? "Chat session needs refresh"
|
|
2158
2188
|
: authError.sessionExpired
|
|
@@ -2189,7 +2219,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
2189
2219
|
setMissingKeyBouncePulse((p) => p + 1);
|
|
2190
2220
|
return;
|
|
2191
2221
|
}
|
|
2192
|
-
|
|
2222
|
+
appendThreadMessage({
|
|
2193
2223
|
role: "user",
|
|
2194
2224
|
content: [{ type: "text", text: suggestion }],
|
|
2195
2225
|
});
|