@agent-native/core 0.84.37 → 0.84.39
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 +12 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/production-agent.ts +2 -0
- package/corpus/core/src/client/agent-chat-adapter.ts +20 -0
- package/corpus/core/src/client/sse-event-processor.ts +31 -6
- package/corpus/core/src/server/agent-chat-plugin.ts +8 -0
- package/corpus/templates/design/app/components/design/CodeWorkbenchHost.tsx +486 -341
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +13 -0
- package/corpus/templates/design/app/components/design/DesignImportPanel.tsx +76 -58
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +6 -0
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +80 -8
- package/corpus/templates/design/app/i18n/zh-TW.ts +2 -2
- package/corpus/templates/design/app/i18n-data.ts +22 -30
- package/corpus/templates/design/app/lib/design-import.ts +42 -0
- package/corpus/templates/design/app/pages/DesignEditor.tsx +180 -109
- package/corpus/templates/design/changelog/2026-07-01-code-workspace-now-opens-a-vs-code-like-editor-with-real-cod.md +6 -0
- package/corpus/templates/design/changelog/2026-07-01-import-is-more-compact-local-app-setup-is-clearer-and-figma.md +6 -0
- package/corpus/templates/design/package.json +1 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +2 -0
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +17 -2
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts +11 -2
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +15 -10
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +3 -3
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +2 -0
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/package.json +1 -1
package/corpus/README.md
CHANGED
package/corpus/core/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @agent-native/core
|
|
2
2
|
|
|
3
|
+
## 0.84.39
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- ca6912b: Fix hosted Google Analytics / Tag Manager injection by baking the measurement id into Nitro server bundles and merging the required GA/GTM script, connect, and image hosts into existing stricter document CSPs.
|
|
8
|
+
|
|
9
|
+
## 0.84.38
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 203c1c3: Keep durable background chat runs attached during long action preparation instead of aborting on keepalive-only or zero-byte preparation activity.
|
|
14
|
+
|
|
3
15
|
## 0.84.37
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/corpus/core/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.84.
|
|
3
|
+
"version": "0.84.39",
|
|
4
4
|
"description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -5106,6 +5106,7 @@ export function createProductionAgentHandler(
|
|
|
5106
5106
|
setResponseHeader(event, "Cache-Control", "no-cache");
|
|
5107
5107
|
setResponseHeader(event, "Connection", "keep-alive");
|
|
5108
5108
|
setResponseHeader(event, "X-Run-Id", runId);
|
|
5109
|
+
setResponseHeader(event, "X-Dispatch-Mode", "background");
|
|
5109
5110
|
return stream;
|
|
5110
5111
|
}
|
|
5111
5112
|
// A background worker owns this run but we cannot subscribe — surface an
|
|
@@ -5912,6 +5913,7 @@ export function createProductionAgentHandler(
|
|
|
5912
5913
|
setResponseHeader(event, "Cache-Control", "no-cache");
|
|
5913
5914
|
setResponseHeader(event, "Connection", "keep-alive");
|
|
5914
5915
|
setResponseHeader(event, "X-Run-Id", runId);
|
|
5916
|
+
setResponseHeader(event, "X-Dispatch-Mode", "foreground");
|
|
5915
5917
|
|
|
5916
5918
|
return stream;
|
|
5917
5919
|
});
|
|
@@ -1418,6 +1418,7 @@ export function createAgentChatAdapter(
|
|
|
1418
1418
|
const turnId = generateTurnId();
|
|
1419
1419
|
let runId: string | null = null;
|
|
1420
1420
|
let lastSeq = -1;
|
|
1421
|
+
let currentRunDispatchMode: string | null = null;
|
|
1421
1422
|
let currentMessageText = normalizeMentions(
|
|
1422
1423
|
recoveryMessageText.trim() || userMessageText,
|
|
1423
1424
|
);
|
|
@@ -1579,6 +1580,17 @@ export function createAgentChatAdapter(
|
|
|
1579
1580
|
}
|
|
1580
1581
|
};
|
|
1581
1582
|
|
|
1583
|
+
const updateCurrentRunDispatchMode = (value: unknown) => {
|
|
1584
|
+
if (typeof value !== "string") return;
|
|
1585
|
+
const mode = value.trim();
|
|
1586
|
+
if (mode) currentRunDispatchMode = mode;
|
|
1587
|
+
};
|
|
1588
|
+
|
|
1589
|
+
const currentSSEOptions = () => ({
|
|
1590
|
+
durableBackgroundRun:
|
|
1591
|
+
currentRunDispatchMode?.startsWith("background") === true,
|
|
1592
|
+
});
|
|
1593
|
+
|
|
1582
1594
|
const captureChatClientError = (
|
|
1583
1595
|
error: unknown,
|
|
1584
1596
|
phase: string,
|
|
@@ -1687,6 +1699,9 @@ export function createAgentChatAdapter(
|
|
|
1687
1699
|
reconnectErrorCaptured = true;
|
|
1688
1700
|
break;
|
|
1689
1701
|
}
|
|
1702
|
+
updateCurrentRunDispatchMode(
|
|
1703
|
+
reconnectRes.headers.get("X-Dispatch-Mode"),
|
|
1704
|
+
);
|
|
1690
1705
|
|
|
1691
1706
|
for await (const result of readSSEStream(
|
|
1692
1707
|
reconnectRes.body,
|
|
@@ -1698,6 +1713,7 @@ export function createAgentChatAdapter(
|
|
|
1698
1713
|
if (threadId) updateActiveRunSeq(seq);
|
|
1699
1714
|
},
|
|
1700
1715
|
runId,
|
|
1716
|
+
currentSSEOptions(),
|
|
1701
1717
|
)) {
|
|
1702
1718
|
yield withRequestModeMetadata(result);
|
|
1703
1719
|
}
|
|
@@ -1778,6 +1794,7 @@ export function createAgentChatAdapter(
|
|
|
1778
1794
|
}
|
|
1779
1795
|
const active = await activeRes.json();
|
|
1780
1796
|
if (active?.active && active.runId) {
|
|
1797
|
+
updateCurrentRunDispatchMode(active.dispatchMode);
|
|
1781
1798
|
const activeStatus =
|
|
1782
1799
|
typeof active.status === "string" ? active.status : "";
|
|
1783
1800
|
const activeTurnId =
|
|
@@ -1851,6 +1868,7 @@ export function createAgentChatAdapter(
|
|
|
1851
1868
|
typeof active.dispatchMode === "string"
|
|
1852
1869
|
? active.dispatchMode
|
|
1853
1870
|
: "";
|
|
1871
|
+
updateCurrentRunDispatchMode(dispatchMode);
|
|
1854
1872
|
if (activeRunId === interruptedRunId) {
|
|
1855
1873
|
if (dispatchMode.startsWith("background")) continue;
|
|
1856
1874
|
return false;
|
|
@@ -2429,6 +2447,7 @@ export function createAgentChatAdapter(
|
|
|
2429
2447
|
|
|
2430
2448
|
// Track the run ID for reconnection
|
|
2431
2449
|
runId = res.headers.get("X-Run-Id");
|
|
2450
|
+
updateCurrentRunDispatchMode(res.headers.get("X-Dispatch-Mode"));
|
|
2432
2451
|
if (runId && !attemptedRunIds.includes(runId)) {
|
|
2433
2452
|
attemptedRunIds.push(runId);
|
|
2434
2453
|
}
|
|
@@ -2448,6 +2467,7 @@ export function createAgentChatAdapter(
|
|
|
2448
2467
|
}
|
|
2449
2468
|
},
|
|
2450
2469
|
runId,
|
|
2470
|
+
currentSSEOptions(),
|
|
2451
2471
|
)) {
|
|
2452
2472
|
yield withRequestModeMetadata(result);
|
|
2453
2473
|
}
|
|
@@ -148,6 +148,16 @@ export class AgentAutoContinueSignal extends Error {
|
|
|
148
148
|
export const SSE_NO_PROGRESS_TIMEOUT_MS = 75_000;
|
|
149
149
|
export const SSE_ACTION_PREPARATION_STALL_TIMEOUT_MS = 90_000;
|
|
150
150
|
|
|
151
|
+
export interface SSEStreamOptions {
|
|
152
|
+
/**
|
|
153
|
+
* Durable background runs have their own server-side liveness budget and
|
|
154
|
+
* heartbeat. While one is active, keepalive-only periods and zero-byte
|
|
155
|
+
* action-preparation activity should keep the client attached instead of
|
|
156
|
+
* aborting and starting duplicate continuations.
|
|
157
|
+
*/
|
|
158
|
+
durableBackgroundRun?: boolean;
|
|
159
|
+
}
|
|
160
|
+
|
|
151
161
|
type ActivityTrailEntry = AgentActivityTrailEntry;
|
|
152
162
|
|
|
153
163
|
type PreparingActionEntry = {
|
|
@@ -193,9 +203,13 @@ function isPreparingActionActivity(ev: SSEEvent): boolean {
|
|
|
193
203
|
function isMeaningfulProgressEvent(
|
|
194
204
|
ev: SSEEvent,
|
|
195
205
|
actionPreparationProgress?: boolean,
|
|
206
|
+
options?: SSEStreamOptions,
|
|
196
207
|
): boolean {
|
|
197
|
-
if (ev.type === "stream_keepalive")
|
|
208
|
+
if (ev.type === "stream_keepalive") {
|
|
209
|
+
return options?.durableBackgroundRun === true;
|
|
210
|
+
}
|
|
198
211
|
if (ev.type === "activity" && isPreparingActionActivity(ev)) {
|
|
212
|
+
if (options?.durableBackgroundRun === true) return true;
|
|
199
213
|
return actionPreparationProgress === true;
|
|
200
214
|
}
|
|
201
215
|
return true;
|
|
@@ -345,7 +359,12 @@ function updatePreparingActionState(
|
|
|
345
359
|
return undefined;
|
|
346
360
|
}
|
|
347
361
|
|
|
348
|
-
function hasStalledPreparingAction(
|
|
362
|
+
function hasStalledPreparingAction(
|
|
363
|
+
state: PreparingActionState,
|
|
364
|
+
now: number,
|
|
365
|
+
options?: SSEStreamOptions,
|
|
366
|
+
) {
|
|
367
|
+
if (options?.durableBackgroundRun === true) return false;
|
|
349
368
|
// Fire only when a tool input has gone SILENT — no further streaming deltas
|
|
350
369
|
// for the whole window — never merely because a large input has been
|
|
351
370
|
// streaming for a long time. `lastProgressAt` advances on every delta
|
|
@@ -1193,6 +1212,7 @@ export async function* readSSEStream(
|
|
|
1193
1212
|
tabId: string | undefined,
|
|
1194
1213
|
onSeq?: (seq: number) => void,
|
|
1195
1214
|
runId?: string | null,
|
|
1215
|
+
options?: SSEStreamOptions,
|
|
1196
1216
|
): AsyncGenerator<ChatModelRunResult> {
|
|
1197
1217
|
const reader = body.getReader();
|
|
1198
1218
|
const decoder = new TextDecoder();
|
|
@@ -1278,7 +1298,7 @@ export async function* readSSEStream(
|
|
|
1278
1298
|
ev,
|
|
1279
1299
|
now,
|
|
1280
1300
|
);
|
|
1281
|
-
if (isMeaningfulProgressEvent(ev, actionPreparationProgress)) {
|
|
1301
|
+
if (isMeaningfulProgressEvent(ev, actionPreparationProgress, options)) {
|
|
1282
1302
|
sawProgressEvent = true;
|
|
1283
1303
|
lastMeaningfulEventAt = now;
|
|
1284
1304
|
}
|
|
@@ -1320,7 +1340,9 @@ export async function* readSSEStream(
|
|
|
1320
1340
|
);
|
|
1321
1341
|
|
|
1322
1342
|
if (result) yield withStreamMetadata(result);
|
|
1323
|
-
if (
|
|
1343
|
+
if (
|
|
1344
|
+
hasStalledPreparingAction(preparingActionState, Date.now(), options)
|
|
1345
|
+
) {
|
|
1324
1346
|
throw new AgentAutoContinueSignal({
|
|
1325
1347
|
reason: "no_progress",
|
|
1326
1348
|
activityTrail: [...activityTrail],
|
|
@@ -1384,6 +1406,7 @@ export async function readSSEStreamRaw(
|
|
|
1384
1406
|
tabId: string | undefined,
|
|
1385
1407
|
onUpdate: (content: ContentPart[]) => void,
|
|
1386
1408
|
onSeq?: (seq: number) => void,
|
|
1409
|
+
options?: SSEStreamOptions,
|
|
1387
1410
|
): Promise<void> {
|
|
1388
1411
|
const reader = body.getReader();
|
|
1389
1412
|
const decoder = new TextDecoder();
|
|
@@ -1444,7 +1467,7 @@ export async function readSSEStreamRaw(
|
|
|
1444
1467
|
ev,
|
|
1445
1468
|
now,
|
|
1446
1469
|
);
|
|
1447
|
-
if (isMeaningfulProgressEvent(ev, actionPreparationProgress)) {
|
|
1470
|
+
if (isMeaningfulProgressEvent(ev, actionPreparationProgress, options)) {
|
|
1448
1471
|
sawProgressEvent = true;
|
|
1449
1472
|
lastMeaningfulEventAt = now;
|
|
1450
1473
|
}
|
|
@@ -1502,7 +1525,9 @@ export async function readSSEStreamRaw(
|
|
|
1502
1525
|
: { reason: "stream_ended", activityTrail: [...activityTrail] },
|
|
1503
1526
|
);
|
|
1504
1527
|
}
|
|
1505
|
-
if (
|
|
1528
|
+
if (
|
|
1529
|
+
hasStalledPreparingAction(preparingActionState, Date.now(), options)
|
|
1530
|
+
) {
|
|
1506
1531
|
onUpdate(contentSnapshot(content));
|
|
1507
1532
|
throw new AgentAutoContinueSignal({
|
|
1508
1533
|
reason: "no_progress",
|
|
@@ -7346,6 +7346,9 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7346
7346
|
setResponseStatus(event, 404);
|
|
7347
7347
|
return { error: "Run not found" };
|
|
7348
7348
|
}
|
|
7349
|
+
const runClaim = await readBackgroundRunClaim(runId).catch(
|
|
7350
|
+
() => null,
|
|
7351
|
+
);
|
|
7349
7352
|
const query = getQuery(event);
|
|
7350
7353
|
const after = parseInt(String(query.after ?? "0"), 10) || 0;
|
|
7351
7354
|
|
|
@@ -7358,6 +7361,11 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7358
7361
|
setResponseHeader(event, "Content-Type", "text/event-stream");
|
|
7359
7362
|
setResponseHeader(event, "Cache-Control", "no-cache");
|
|
7360
7363
|
setResponseHeader(event, "Connection", "keep-alive");
|
|
7364
|
+
setResponseHeader(
|
|
7365
|
+
event,
|
|
7366
|
+
"X-Dispatch-Mode",
|
|
7367
|
+
runClaim?.dispatchMode ?? "foreground",
|
|
7368
|
+
);
|
|
7361
7369
|
return stream;
|
|
7362
7370
|
}
|
|
7363
7371
|
|