@agent-native/core 0.209.2 → 0.209.3-nightly-20261016212700
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/a2a-claims.js +5 -5
- package/dist/agent/context-xray/plugin.js +2 -6
- package/dist/agent/context-xray/schema-store.d.ts +1 -0
- package/dist/agent/context-xray/schema-store.js +7 -0
- package/dist/agent/harness/store.js +3 -0
- package/dist/agent/observational-memory/plugin.js +2 -6
- package/dist/agent/observational-memory/store.js +3 -0
- package/dist/agent/run-store.js +3 -0
- package/dist/agent/tool-approval-store.js +4 -0
- package/dist/automation/index.d.ts +1 -1
- package/dist/chat-threads/store.js +3 -0
- package/dist/client/action-query-cache-context.d.ts +1 -0
- package/dist/client/action-query-cache-context.js +2 -0
- package/dist/client/action-query-cache.d.ts +1 -1
- package/dist/client/action-query-cache.js +34 -15
- package/dist/client/motion-text.css +8 -0
- package/dist/client/motion-text.d.ts +6 -0
- package/dist/client/motion-text.js +154 -29
- package/dist/client/use-action.js +18 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/db/migrations.d.ts +1 -0
- package/dist/db/migrations.js +1 -1
- package/dist/db/runtime-facts.d.ts +7 -0
- package/dist/db/runtime-facts.js +18 -0
- package/dist/db/schema-catalog.js +4 -1
- package/dist/db/store-ledger.test-helpers.d.ts +5 -0
- package/dist/db/store-ledger.test-helpers.js +19 -0
- package/dist/db/store-registry.d.ts +34 -0
- package/dist/db/store-registry.generated.js +13 -0
- package/dist/db/store-registry.js +288 -46
- package/dist/db/versioned-store-migrations.d.ts +14 -0
- package/dist/db/versioned-store-migrations.js +37 -0
- package/dist/db/widen-columns.js +5 -2
- package/dist/extensions/html-shell.js +67 -0
- package/dist/integrations/remote-devices-store.js +3 -0
- package/dist/jobs/run-history.d.ts +3 -2
- package/dist/jobs/run-history.js +5 -5
- package/dist/jobs/scheduler-health.d.ts +3 -2
- package/dist/jobs/scheduler-health.js +5 -5
- package/dist/mcp/build-server.d.ts +3 -0
- package/dist/mcp/build-server.js +24 -7
- package/dist/mcp/server.js +40 -9
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/oauth-tokens/store.js +3 -0
- package/dist/observability/routes.d.ts +4 -4
- package/dist/observability/store.js +4 -0
- package/dist/org/auto-join-domain.js +23 -15
- package/dist/org/context.d.ts +12 -0
- package/dist/org/context.js +27 -19
- package/dist/org/handlers.js +31 -13
- package/dist/org/index.d.ts +2 -1
- package/dist/org/index.js +1 -0
- package/dist/org/plugin.js +2 -4
- package/dist/org/schema-store.d.ts +1 -0
- package/dist/org/schema-store.js +13 -0
- package/dist/provider-api/actions/custom-provider-registration.d.ts +8 -8
- package/dist/provider-api/actions/provider-api.d.ts +9 -9
- package/dist/resources/store.js +5 -2
- package/dist/server/agent-access.js +2 -6
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-engine-default-model-route.d.ts +1 -1
- package/dist/server/auth-plugin.js +2 -6
- package/dist/server/auth.js +22 -2
- package/dist/server/better-auth-migrations.d.ts +4 -2
- package/dist/server/better-auth-migrations.js +18 -6
- package/dist/server/identity-sso-store.js +3 -0
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/release-migrations.d.ts +1 -1
- package/dist/server/release-migrations.js +3 -65
- package/dist/server/release-schema.js +10 -2
- package/dist/server/short-lived-token.d.ts +3 -2
- package/dist/server/short-lived-token.js +3 -2
- package/dist/triggers/actions/manage-automation.d.ts +3 -3
- package/dist/triggers/event-queue.d.ts +4 -2
- package/dist/triggers/event-queue.js +38 -38
- package/dist/usage/alerts-store.js +3 -0
- package/dist/workspace-connections/groups.js +4 -0
- package/dist/workspace-connections/store.js +3 -0
- package/package.json +3 -3
|
@@ -8,6 +8,18 @@ const MOTION_TEXT_UNITS = new Set([
|
|
|
8
8
|
"line",
|
|
9
9
|
"paragraph",
|
|
10
10
|
]);
|
|
11
|
+
const MOTION_TEXT_ORDERS = new Set([
|
|
12
|
+
"left-to-right",
|
|
13
|
+
"right-to-left",
|
|
14
|
+
"center-out",
|
|
15
|
+
"random",
|
|
16
|
+
"top-to-bottom",
|
|
17
|
+
"bottom-to-top",
|
|
18
|
+
]);
|
|
19
|
+
const MOTION_TEXT_ANIMATION_DIRECTIONS = new Set([
|
|
20
|
+
"in",
|
|
21
|
+
"out",
|
|
22
|
+
]);
|
|
11
23
|
const MOTION_TEXT_PROPERTIES = new Set([
|
|
12
24
|
"opacity",
|
|
13
25
|
"translate",
|
|
@@ -61,6 +73,7 @@ const INLINE_TEXT_TAGS = new Set([
|
|
|
61
73
|
]);
|
|
62
74
|
const MAX_TEXT_UNITS = 512;
|
|
63
75
|
const PREVIEW_MESSAGE_TYPES = new Set([
|
|
76
|
+
"motion-preview-duration-request",
|
|
64
77
|
"motion-preview",
|
|
65
78
|
"motion-preview-clear",
|
|
66
79
|
]);
|
|
@@ -137,30 +150,50 @@ export function AgentNativeMotionText({ animation, animations: animationList, pl
|
|
|
137
150
|
if (groupCount > MAX_TEXT_UNITS) {
|
|
138
151
|
throw new Error(`AgentNativeMotionText supports at most ${MAX_TEXT_UNITS} animated units.`);
|
|
139
152
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
153
|
+
const animationSchedules = animations.map((track) => {
|
|
154
|
+
const overlap = track.overlapPercent;
|
|
155
|
+
const durationMs = overlap === undefined
|
|
156
|
+
? track.durationMs
|
|
157
|
+
: track.durationMs /
|
|
158
|
+
(1 + Math.max(0, groupCount - 1) * (1 - overlap / 100));
|
|
159
|
+
const staggerMs = overlap === undefined
|
|
160
|
+
? track.staggerMs
|
|
161
|
+
: durationMs * (1 - overlap / 100);
|
|
162
|
+
const spanMs = (track.delayMs ?? 0) + (groupCount - 1) * staggerMs + durationMs;
|
|
163
|
+
if (!Number.isFinite(spanMs) || spanMs > 120_000) {
|
|
164
|
+
throw new Error("AgentNativeMotionText animation span exceeds the 120000ms runtime limit.");
|
|
165
|
+
}
|
|
166
|
+
return { track, durationMs, staggerMs };
|
|
167
|
+
});
|
|
168
|
+
const orderRanks = textOrderRanks(groupCount, motionTextOrder(primaryAnimation), `${primaryAnimation.targetNodeId}|${hostElement.textContent ?? ""}`);
|
|
143
169
|
const previewAnimations = [];
|
|
144
170
|
try {
|
|
145
|
-
for (const track of
|
|
171
|
+
for (const { track, durationMs, staggerMs } of animationSchedules) {
|
|
146
172
|
for (const entry of elements) {
|
|
147
173
|
if (typeof entry.element.animate !== "function") {
|
|
148
174
|
throw new Error("AgentNativeMotionText requires the Web Animations API.");
|
|
149
175
|
}
|
|
150
|
-
const delayIndex =
|
|
151
|
-
? groupCount - 1 - entry.index
|
|
152
|
-
: entry.index;
|
|
176
|
+
const delayIndex = orderRanks[entry.index] ?? entry.index;
|
|
153
177
|
const easingStyle = track.keyframes.some((keyframe) => isMotionEaseVariableReference(keyframe.ease ?? ""))
|
|
154
178
|
? window.getComputedStyle(entry.element)
|
|
155
179
|
: null;
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
180
|
+
const animationDirection = motionTextAnimationDirection(track);
|
|
181
|
+
const keyframes = (animationDirection === "out"
|
|
182
|
+
? [...track.keyframes].reverse()
|
|
183
|
+
: track.keyframes).map((keyframe, keyframeIndex) => {
|
|
184
|
+
const easingKeyframe = animationDirection === "out" &&
|
|
185
|
+
keyframeIndex < track.keyframes.length - 1
|
|
186
|
+
? track.keyframes[track.keyframes.length - 2 - keyframeIndex]
|
|
187
|
+
: keyframe;
|
|
188
|
+
return {
|
|
189
|
+
offset: animationDirection === "out" ? 1 - keyframe.t : keyframe.t,
|
|
190
|
+
easing: resolveMotionEaseForWebAnimations(easingKeyframe.ease ?? "ease", (name) => easingStyle?.getPropertyValue(name) ?? ""),
|
|
191
|
+
[track.property]: keyframe.value,
|
|
192
|
+
};
|
|
193
|
+
});
|
|
194
|
+
const delay = (track.delayMs ?? 0) + delayIndex * staggerMs;
|
|
162
195
|
const runningAnimation = entry.element.animate(keyframes, {
|
|
163
|
-
duration:
|
|
196
|
+
duration: durationMs,
|
|
164
197
|
delay,
|
|
165
198
|
iterations: playbackMode === "once" ? 1 : Infinity,
|
|
166
199
|
direction: playbackMode === "ping-pong" ? "alternate" : "normal",
|
|
@@ -169,7 +202,7 @@ export function AgentNativeMotionText({ animation, animations: animationList, pl
|
|
|
169
202
|
previewAnimations.push({
|
|
170
203
|
animation: runningAnimation,
|
|
171
204
|
delay,
|
|
172
|
-
durationMs
|
|
205
|
+
durationMs,
|
|
173
206
|
});
|
|
174
207
|
}
|
|
175
208
|
}
|
|
@@ -180,12 +213,21 @@ export function AgentNativeMotionText({ animation, animations: animationList, pl
|
|
|
180
213
|
}
|
|
181
214
|
throw error;
|
|
182
215
|
}
|
|
216
|
+
const textTimelineDurationMs = previewAnimations.reduce((duration, entry) => Math.max(duration, entry.delay + entry.durationMs), 0);
|
|
217
|
+
const previewSpanKey = `react:${primaryAnimation.targetNodeId}`;
|
|
218
|
+
const reportPreviewSpanDuration = (durationMs) => {
|
|
219
|
+
window.parent.postMessage({ type: "motion-preview-span", key: previewSpanKey, durationMs }, "*");
|
|
220
|
+
};
|
|
183
221
|
let isPreviewing = false;
|
|
184
222
|
const handlePreviewMessage = (event) => {
|
|
185
223
|
if (event.source !== window.parent ||
|
|
186
224
|
!isMotionPreviewMessage(event.data)) {
|
|
187
225
|
return;
|
|
188
226
|
}
|
|
227
|
+
if (event.data.type === "motion-preview-duration-request") {
|
|
228
|
+
reportPreviewSpanDuration(textTimelineDurationMs);
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
189
231
|
if (event.data.type === "motion-preview-clear") {
|
|
190
232
|
if (!isPreviewing)
|
|
191
233
|
return;
|
|
@@ -197,28 +239,33 @@ export function AgentNativeMotionText({ animation, animations: animationList, pl
|
|
|
197
239
|
return;
|
|
198
240
|
}
|
|
199
241
|
const t = Number(event.data.t);
|
|
200
|
-
const
|
|
201
|
-
if (!Number.isFinite(t) || !Number.isFinite(
|
|
242
|
+
const requestedTimelineDuration = Number(event.data.durationMs);
|
|
243
|
+
if (!Number.isFinite(t) || !Number.isFinite(requestedTimelineDuration)) {
|
|
202
244
|
return;
|
|
203
|
-
|
|
245
|
+
}
|
|
246
|
+
if (requestedTimelineDuration <= 0)
|
|
204
247
|
return;
|
|
248
|
+
if (textTimelineDurationMs > requestedTimelineDuration) {
|
|
249
|
+
reportPreviewSpanDuration(textTimelineDurationMs);
|
|
250
|
+
}
|
|
205
251
|
if (!isPreviewing) {
|
|
206
252
|
isPreviewing = true;
|
|
207
253
|
for (const entry of previewAnimations)
|
|
208
254
|
entry.animation.pause();
|
|
209
255
|
}
|
|
210
|
-
const timelineTime = Math.max(0, Math.min(1, t)) *
|
|
256
|
+
const timelineTime = Math.max(0, Math.min(1, t)) * requestedTimelineDuration;
|
|
211
257
|
for (const entry of previewAnimations) {
|
|
212
|
-
const elapsed = Math.max(0, timelineTime - entry.delay);
|
|
213
258
|
entry.animation.currentTime =
|
|
214
259
|
playbackMode === "once"
|
|
215
|
-
? Math.min(entry.durationMs,
|
|
216
|
-
:
|
|
260
|
+
? Math.min(entry.delay + entry.durationMs, timelineTime)
|
|
261
|
+
: timelineTime;
|
|
217
262
|
}
|
|
218
263
|
};
|
|
219
264
|
window.addEventListener("message", handlePreviewMessage);
|
|
265
|
+
reportPreviewSpanDuration(textTimelineDurationMs);
|
|
220
266
|
return () => {
|
|
221
267
|
window.removeEventListener("message", handlePreviewMessage);
|
|
268
|
+
reportPreviewSpanDuration(0);
|
|
222
269
|
for (const entry of previewAnimations) {
|
|
223
270
|
entry.animation.cancel();
|
|
224
271
|
}
|
|
@@ -242,14 +289,23 @@ function validateAnimations(animations) {
|
|
|
242
289
|
throw new Error("AgentNativeMotionText requires at least one animation.");
|
|
243
290
|
}
|
|
244
291
|
const first = animations[0];
|
|
292
|
+
const firstOrder = motionTextOrder(first);
|
|
293
|
+
const firstAnimationDirection = motionTextAnimationDirection(first);
|
|
294
|
+
const firstIgnoreSpaces = motionTextIgnoreSpaces(first);
|
|
245
295
|
const properties = new Set();
|
|
246
296
|
for (const animation of animations) {
|
|
247
297
|
validateAnimation(animation);
|
|
248
298
|
if (animation.targetNodeId !== first.targetNodeId ||
|
|
249
299
|
animation.unit !== first.unit ||
|
|
250
300
|
animation.direction !== first.direction ||
|
|
251
|
-
animation
|
|
252
|
-
|
|
301
|
+
motionTextAnimationDirection(animation) !== firstAnimationDirection ||
|
|
302
|
+
motionTextOrder(animation) !== firstOrder ||
|
|
303
|
+
animation.overlapPercent !== first.overlapPercent ||
|
|
304
|
+
(animation.unit === "character" &&
|
|
305
|
+
motionTextIgnoreSpaces(animation) !== firstIgnoreSpaces) ||
|
|
306
|
+
(animation.overlapPercent === undefined &&
|
|
307
|
+
animation.staggerMs !== first.staggerMs)) {
|
|
308
|
+
throw new Error("AgentNativeMotionText animations for one target must share target, unit, direction, animation direction, order, overlap, character whitespace, and fixed stagger settings.");
|
|
253
309
|
}
|
|
254
310
|
if (properties.has(animation.property)) {
|
|
255
311
|
throw new Error(`AgentNativeMotionText property "${animation.property}" is duplicated.`);
|
|
@@ -271,12 +327,36 @@ function validateAnimation(animation) {
|
|
|
271
327
|
if (animation.direction !== "forward" && animation.direction !== "reverse") {
|
|
272
328
|
throw new Error("AgentNativeMotionText direction is unsupported.");
|
|
273
329
|
}
|
|
330
|
+
if (animation.animationDirection !== undefined &&
|
|
331
|
+
!MOTION_TEXT_ANIMATION_DIRECTIONS.has(animation.animationDirection)) {
|
|
332
|
+
throw new Error("AgentNativeMotionText animationDirection is unsupported.");
|
|
333
|
+
}
|
|
334
|
+
if (animation.order !== undefined &&
|
|
335
|
+
!MOTION_TEXT_ORDERS.has(animation.order)) {
|
|
336
|
+
throw new Error("AgentNativeMotionText order is unsupported.");
|
|
337
|
+
}
|
|
338
|
+
if ((animation.order === "top-to-bottom" ||
|
|
339
|
+
animation.order === "bottom-to-top") &&
|
|
340
|
+
animation.unit !== "line" &&
|
|
341
|
+
animation.unit !== "paragraph") {
|
|
342
|
+
throw new Error("AgentNativeMotionText vertical order requires line or paragraph units.");
|
|
343
|
+
}
|
|
344
|
+
if (animation.overlapPercent !== undefined &&
|
|
345
|
+
(!Number.isFinite(animation.overlapPercent) ||
|
|
346
|
+
animation.overlapPercent < 0 ||
|
|
347
|
+
animation.overlapPercent > 100)) {
|
|
348
|
+
throw new Error("AgentNativeMotionText overlapPercent must be between 0 and 100.");
|
|
349
|
+
}
|
|
350
|
+
if (animation.ignoreSpaces !== undefined &&
|
|
351
|
+
typeof animation.ignoreSpaces !== "boolean") {
|
|
352
|
+
throw new Error("AgentNativeMotionText ignoreSpaces must be a boolean.");
|
|
353
|
+
}
|
|
274
354
|
if (!MOTION_TEXT_PROPERTIES.has(animation.property)) {
|
|
275
355
|
throw new Error("AgentNativeMotionText property is unsupported.");
|
|
276
356
|
}
|
|
277
357
|
if (!Number.isFinite(animation.staggerMs) ||
|
|
278
358
|
animation.staggerMs < 0 ||
|
|
279
|
-
animation.staggerMs >
|
|
359
|
+
animation.staggerMs > 120_000) {
|
|
280
360
|
throw new Error("AgentNativeMotionText staggerMs is invalid.");
|
|
281
361
|
}
|
|
282
362
|
if (animation.delayMs !== undefined &&
|
|
@@ -321,7 +401,46 @@ function assignRef(ref, value) {
|
|
|
321
401
|
else if (ref)
|
|
322
402
|
ref.current = value;
|
|
323
403
|
}
|
|
324
|
-
function
|
|
404
|
+
function motionTextAnimationDirection(animation) {
|
|
405
|
+
return animation.animationDirection ?? "in";
|
|
406
|
+
}
|
|
407
|
+
function motionTextOrder(animation) {
|
|
408
|
+
return (animation.order ??
|
|
409
|
+
(animation.direction === "reverse" ? "right-to-left" : "left-to-right"));
|
|
410
|
+
}
|
|
411
|
+
function motionTextIgnoreSpaces(animation) {
|
|
412
|
+
return animation.ignoreSpaces ?? true;
|
|
413
|
+
}
|
|
414
|
+
function textOrderRanks(count, order, seed) {
|
|
415
|
+
const indexes = Array.from({ length: count }, (_, index) => index);
|
|
416
|
+
if (order === "right-to-left" || order === "bottom-to-top") {
|
|
417
|
+
indexes.reverse();
|
|
418
|
+
}
|
|
419
|
+
else if (order === "center-out") {
|
|
420
|
+
const center = (count - 1) / 2;
|
|
421
|
+
indexes.sort((left, right) => Math.abs(left - center) - Math.abs(right - center) || left - right);
|
|
422
|
+
}
|
|
423
|
+
else if (order === "random") {
|
|
424
|
+
let state = 2_166_136_261;
|
|
425
|
+
for (let index = 0; index < seed.length; index += 1) {
|
|
426
|
+
state = Math.imul(state ^ seed.charCodeAt(index), 16_777_619);
|
|
427
|
+
}
|
|
428
|
+
for (let index = indexes.length - 1; index > 0; index -= 1) {
|
|
429
|
+
state = (Math.imul(state, 1_664_525) + 1_013_904_223) >>> 0;
|
|
430
|
+
const swapIndex = state % (index + 1);
|
|
431
|
+
[indexes[index], indexes[swapIndex]] = [
|
|
432
|
+
indexes[swapIndex],
|
|
433
|
+
indexes[index],
|
|
434
|
+
];
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
const ranks = [];
|
|
438
|
+
indexes.forEach((index, rank) => {
|
|
439
|
+
ranks[index] = rank;
|
|
440
|
+
});
|
|
441
|
+
return ranks;
|
|
442
|
+
}
|
|
443
|
+
function textTokens(text, unit, ignoreSpaces) {
|
|
325
444
|
if (unit === "character") {
|
|
326
445
|
const Segmenter = Intl.Segmenter;
|
|
327
446
|
const parts = Segmenter
|
|
@@ -329,7 +448,7 @@ function textTokens(text, unit) {
|
|
|
329
448
|
: Array.from(text);
|
|
330
449
|
return parts.map((part) => ({
|
|
331
450
|
text: part,
|
|
332
|
-
animated: !/^\s+$/u.test(part),
|
|
451
|
+
animated: !ignoreSpaces || !/^\s+$/u.test(part),
|
|
333
452
|
}));
|
|
334
453
|
}
|
|
335
454
|
const Segmenter = Intl.Segmenter;
|
|
@@ -346,7 +465,7 @@ function textTokens(text, unit) {
|
|
|
346
465
|
for (let index = 0; index < chunks.length; index += 1) {
|
|
347
466
|
const chunk = chunks[index];
|
|
348
467
|
if (/^\s+$/u.test(chunk.text)) {
|
|
349
|
-
tokens.push({ text: chunk.text, animated:
|
|
468
|
+
tokens.push({ text: chunk.text, animated: !ignoreSpaces });
|
|
350
469
|
}
|
|
351
470
|
else if (chunk.word) {
|
|
352
471
|
tokens.push({ text: chunk.text, animated: true });
|
|
@@ -379,7 +498,8 @@ function renderTextNodes(node, animation, nextUnitIndex) {
|
|
|
379
498
|
collectTextLeaves(node, textLeaves, { current: 0 });
|
|
380
499
|
const text = textLeaves.map((leaf) => leaf.text).join("");
|
|
381
500
|
const unit = animation.unit === "character" ? "character" : "word";
|
|
382
|
-
const
|
|
501
|
+
const ignoreSpaces = animation.unit === "character" ? motionTextIgnoreSpaces(animation) : true;
|
|
502
|
+
const tokenValues = textTokens(text, unit, ignoreSpaces);
|
|
383
503
|
const tokens = [];
|
|
384
504
|
let tokenOffset = 0;
|
|
385
505
|
for (const token of tokenValues) {
|
|
@@ -455,6 +575,11 @@ function renderTextLeaf(leaf, tokens) {
|
|
|
455
575
|
parts.push(text);
|
|
456
576
|
continue;
|
|
457
577
|
}
|
|
578
|
+
if (/^\s+$/u.test(token.text)) {
|
|
579
|
+
parts.push(text);
|
|
580
|
+
parts.push(_jsx("span", { "aria-hidden": "true", className: "agent-native-motion-text-unit agent-native-motion-text-space-unit", "data-agent-native-motion-text-unit": token.index }, `${token.index}-${start}-space`));
|
|
581
|
+
continue;
|
|
582
|
+
}
|
|
458
583
|
parts.push(_jsx("span", { className: "agent-native-motion-text-unit", "data-agent-native-motion-text-unit": token.index, children: text }, `${token.index}-${start}`));
|
|
459
584
|
}
|
|
460
585
|
return parts;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { hashKey, useQuery, useMutation, useQueryClient, } from "@tanstack/react-query";
|
|
2
|
+
import { useContext } from "react";
|
|
2
3
|
import { ACTION_BATCH_ACTION_NAME } from "../shared/action-batch.js";
|
|
3
4
|
import { ACTION_BROWSER_PERSIST_ALLOW, ACTION_BROWSER_PERSIST_HEADER, } from "../shared/action-browser-persist.js";
|
|
4
5
|
import { ACTION_CHANGE_MARKER_FAILED, ACTION_CHANGE_MARKER_HEADER, } from "../shared/action-change-marker-header.js";
|
|
@@ -6,6 +7,7 @@ import { SLOW_ACTION_RESPONSE_MS } from "../shared/analytics-events.js";
|
|
|
6
7
|
import { ANALYTICS_CLIENT_PLATFORM_HEADER } from "../shared/analytics-platform.js";
|
|
7
8
|
import { actionCircuitRemainingMs, actionErrorCode, actionErrorRetryAfterMs, actionErrorStatus, assertActionCircuitClosed, endsActionPolling, isActionCircuitOpenError, isTerminalActionError, recordActionFailure, resetActionFailureCircuit, resetActionFailureCircuits, } from "./action-failure-circuit.js";
|
|
8
9
|
import { fetchActionGet } from "./action-get-batch.js";
|
|
10
|
+
import { trustedActionQueryCacheBindingPendingContext } from "./action-query-cache-context.js";
|
|
9
11
|
import { ACTION_RESOURCES_META_KEY, actionQueryAffectedByResources, } from "./action-query-scope.js";
|
|
10
12
|
import { getAnalyticsClientPlatform } from "./analytics-platform.js";
|
|
11
13
|
import { getOrCreateAnalyticsSessionId } from "./analytics-session.js";
|
|
@@ -867,8 +869,16 @@ function canBatchActionQueryFetch(query) {
|
|
|
867
869
|
}
|
|
868
870
|
export function useActionQuery(actionName, params, options) {
|
|
869
871
|
const apiDisabled = Boolean(agentNativeApiDisabledReason());
|
|
870
|
-
const { refetchInterval, retry: callerRetry, queryKeyScope, resources, batchRefetches, ...restOptions } = options ?? {};
|
|
872
|
+
const { refetchInterval, retry: callerRetry, enabled: callerEnabled, queryKeyScope, resources, batchRefetches, ...restOptions } = options ?? {};
|
|
871
873
|
const queryKey = ["action", actionName, params, ...(queryKeyScope ?? [])];
|
|
874
|
+
const trustedBindingPending = useContext(trustedActionQueryCacheBindingPendingContext);
|
|
875
|
+
const queryClient = useQueryClient();
|
|
876
|
+
const existingQuery = trustedBindingPending
|
|
877
|
+
? queryClient.getQueryCache().find({ queryKey, exact: true })
|
|
878
|
+
: undefined;
|
|
879
|
+
const deferFetchUntilBound = trustedBindingPending &&
|
|
880
|
+
existingQuery?.state.fetchStatus !== "fetching" &&
|
|
881
|
+
existingQuery?.state.data === undefined;
|
|
872
882
|
const circuitKey = () => hashKey(queryKey);
|
|
873
883
|
return useQuery({
|
|
874
884
|
queryKey,
|
|
@@ -935,6 +945,13 @@ export function useActionQuery(actionName, params, options) {
|
|
|
935
945
|
},
|
|
936
946
|
retryDelay: defaultActionQueryRetryDelay,
|
|
937
947
|
...restOptions,
|
|
948
|
+
enabled: (query) => {
|
|
949
|
+
if (deferFetchUntilBound)
|
|
950
|
+
return false;
|
|
951
|
+
return typeof callerEnabled === "function"
|
|
952
|
+
? callerEnabled(query)
|
|
953
|
+
: callerEnabled !== false;
|
|
954
|
+
},
|
|
938
955
|
...(resources || batchRefetches === false
|
|
939
956
|
? {
|
|
940
957
|
meta: {
|
package/dist/collab/routes.d.ts
CHANGED
|
@@ -13,8 +13,8 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
|
|
|
13
13
|
};
|
|
14
14
|
}>>;
|
|
15
15
|
export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
16
|
-
ok?: undefined;
|
|
17
16
|
error: string;
|
|
17
|
+
ok?: undefined;
|
|
18
18
|
} | {
|
|
19
19
|
error?: undefined;
|
|
20
20
|
ok: boolean;
|
package/dist/db/migrations.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ type NitroPluginDef = (nitroApp: any) => void | Promise<void>;
|
|
|
3
3
|
export declare function isDuplicateColumnError(err: unknown): boolean;
|
|
4
4
|
/** True when the connected Postgres role cannot apply the migration. */
|
|
5
5
|
export declare function isPermissionError(err: unknown): boolean;
|
|
6
|
+
export declare function splitSqlStatements(sql: string): string[];
|
|
6
7
|
export interface RunMigrationsOptions {
|
|
7
8
|
runInServerlessRequest?: boolean;
|
|
8
9
|
table: string;
|
package/dist/db/migrations.js
CHANGED
|
@@ -80,7 +80,7 @@ function isMissingRelationError(err) {
|
|
|
80
80
|
const e = err;
|
|
81
81
|
return (e?.code === "42P01" || /relation .* does not exist/i.test(e?.message ?? ""));
|
|
82
82
|
}
|
|
83
|
-
function splitSqlStatements(sql) {
|
|
83
|
+
export function splitSqlStatements(sql) {
|
|
84
84
|
const out = [];
|
|
85
85
|
let buf = "";
|
|
86
86
|
let i = 0;
|
|
@@ -9,3 +9,10 @@ export declare function retryOnDdlRace<T>(fn: () => Promise<T>): Promise<T>;
|
|
|
9
9
|
* client, so modules that mock `./client.js` keep working.
|
|
10
10
|
*/
|
|
11
11
|
export declare function dbClientGeneration(): number;
|
|
12
|
+
/**
|
|
13
|
+
* True while a store migration runs that the ledger will record once it
|
|
14
|
+
* resolves. Helpers that swallow failures elsewhere must rethrow here, or the
|
|
15
|
+
* ledger records a step that never happened and never retries it.
|
|
16
|
+
*/
|
|
17
|
+
export declare function isRecordingStoreMigration(): boolean;
|
|
18
|
+
export declare function runRecordingStoreMigration<T>(run: () => Promise<T>): Promise<T>;
|
package/dist/db/runtime-facts.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getAsyncLocalStorageCtor } from "../shared/optional-node-builtins.js";
|
|
1
2
|
/**
|
|
2
3
|
* Dependency-free database runtime facts. Kept out of `./client.js` so the
|
|
3
4
|
* store runner does not require every `vi.mock("../db/client.js")` to stub them.
|
|
@@ -39,3 +40,20 @@ export function dbClientGeneration() {
|
|
|
39
40
|
const proc = globalThis.process;
|
|
40
41
|
return proc?.__agentNativePgliteClientGeneration ?? 0;
|
|
41
42
|
}
|
|
43
|
+
const AsyncLocalStorageCtor = getAsyncLocalStorageCtor();
|
|
44
|
+
const recordingStoreMigration = AsyncLocalStorageCtor
|
|
45
|
+
? new AsyncLocalStorageCtor()
|
|
46
|
+
: undefined;
|
|
47
|
+
/**
|
|
48
|
+
* True while a store migration runs that the ledger will record once it
|
|
49
|
+
* resolves. Helpers that swallow failures elsewhere must rethrow here, or the
|
|
50
|
+
* ledger records a step that never happened and never retries it.
|
|
51
|
+
*/
|
|
52
|
+
export function isRecordingStoreMigration() {
|
|
53
|
+
return recordingStoreMigration?.getStore() === true;
|
|
54
|
+
}
|
|
55
|
+
export function runRecordingStoreMigration(run) {
|
|
56
|
+
return recordingStoreMigration
|
|
57
|
+
? recordingStoreMigration.run(true, run)
|
|
58
|
+
: run();
|
|
59
|
+
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* has no `pg_dump`.
|
|
7
7
|
*/
|
|
8
8
|
/** Tables whose rows are migration bookkeeping, dumped with their data. */
|
|
9
|
-
const BOOKKEEPING_TABLE =
|
|
9
|
+
const BOOKKEEPING_TABLE = /^_[a-z0-9_]*migrations(?:_named)?$/;
|
|
10
10
|
async function rows(exec, sql) {
|
|
11
11
|
return (await exec.execute(sql)).rows;
|
|
12
12
|
}
|
|
@@ -21,6 +21,9 @@ function literal(value) {
|
|
|
21
21
|
}
|
|
22
22
|
if (typeof value === "boolean")
|
|
23
23
|
return value ? "TRUE" : "FALSE";
|
|
24
|
+
// Locale-formatted dates do not parse back; ISO 8601 does, in any time zone.
|
|
25
|
+
if (value instanceof Date)
|
|
26
|
+
return `'${value.toISOString()}'`;
|
|
24
27
|
return `'${String(value).replace(/'/g, "''")}'`;
|
|
25
28
|
}
|
|
26
29
|
const COLUMNS_SQL = `
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* For specs that mock `getDbExec()` with a hand-written executor. Outside
|
|
3
|
+
* hosted runtimes a store records its migrations in `_an_store_migrations`
|
|
4
|
+
* (see `store-registry.ts`), so a strict mock sees those statements too.
|
|
5
|
+
* Answer them as an empty ledger: every store then applies its migrations
|
|
6
|
+
* against the mock once per executor, as it did before the ledger.
|
|
7
|
+
*/
|
|
8
|
+
const STORE_LEDGER_STATEMENT = /\b_an_store_migration(?:s|_lock)\b/;
|
|
9
|
+
export function isStoreLedgerStatement(sql) {
|
|
10
|
+
return STORE_LEDGER_STATEMENT.test(sql);
|
|
11
|
+
}
|
|
12
|
+
export function storeLedgerResult(sql) {
|
|
13
|
+
if (!isStoreLedgerStatement(sql))
|
|
14
|
+
return undefined;
|
|
15
|
+
return {
|
|
16
|
+
rows: [],
|
|
17
|
+
rowsAffected: /^\s*(?:INSERT|UPDATE|DELETE)\b/i.test(sql) ? 1 : 0,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* kept only for that.
|
|
14
14
|
*/
|
|
15
15
|
import { type DbExec } from "./client.js";
|
|
16
|
+
import { type MigrationEntry } from "./migrations.js";
|
|
16
17
|
export declare const STORE_MIGRATIONS_TABLE = "_an_store_migrations";
|
|
17
18
|
export interface StoreMigration {
|
|
18
19
|
/** Stable, never renamed: the ledger records it. */
|
|
@@ -24,9 +25,37 @@ export interface StoreMigration {
|
|
|
24
25
|
readonly kind?: "schema" | "data";
|
|
25
26
|
readonly sql?: string | readonly string[];
|
|
26
27
|
readonly run?: (exec: DbExec) => Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* The versioned `runMigrations` entry this migration replaces. A database
|
|
30
|
+
* whose old bookkeeping table already records that entry gets a ledger row
|
|
31
|
+
* (`source = 'legacy'`) instead of running it again.
|
|
32
|
+
*/
|
|
33
|
+
readonly legacy?: LegacyMigrationRef;
|
|
34
|
+
}
|
|
35
|
+
export interface LegacyMigrationRef {
|
|
36
|
+
/** The `runMigrations` table, e.g. `_chat_thread_schema_migrations`. */
|
|
37
|
+
readonly table: string;
|
|
38
|
+
readonly version: number;
|
|
39
|
+
/** Set for named entries, which were gated by name, not version. */
|
|
40
|
+
readonly name?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Where the list ran on main. A release-only list (the default) keeps
|
|
43
|
+
* running only in the release step. A list that also ran at plugin boot
|
|
44
|
+
* runs everywhere: local runtimes import its history once, and hosted apps
|
|
45
|
+
* without release migrations keep running it through `runMigrations` and
|
|
46
|
+
* its old table, exactly as before.
|
|
47
|
+
*/
|
|
48
|
+
readonly ranAtBoot?: boolean;
|
|
49
|
+
/** The original entry, for that hosted `runMigrations` path. */
|
|
50
|
+
readonly entry?: MigrationEntry;
|
|
27
51
|
}
|
|
28
52
|
export interface StoreDefinition {
|
|
29
53
|
readonly id: string;
|
|
54
|
+
/**
|
|
55
|
+
* Stores whose migrations must run first at release, for a migration that
|
|
56
|
+
* reads or alters another store's tables. Registry order is otherwise by id.
|
|
57
|
+
*/
|
|
58
|
+
readonly after?: readonly string[];
|
|
30
59
|
/**
|
|
31
60
|
* Never provision from a request, even for hosted apps that do not migrate
|
|
32
61
|
* at release: the release step (or a versioned list) is the only creator.
|
|
@@ -58,6 +87,11 @@ export declare class SchemaNotMigratedError extends Error {
|
|
|
58
87
|
export declare function schemaIsReleaseOwned(): boolean;
|
|
59
88
|
/** Stable across bundlers; `run` bodies are not hashed because minifiers rewrite them. */
|
|
60
89
|
export declare function migrationChecksum(migration: StoreMigration): string | null;
|
|
90
|
+
/**
|
|
91
|
+
* Registry order with each store's `after` dependencies first. Fails on an
|
|
92
|
+
* unknown id or a cycle rather than guessing an order.
|
|
93
|
+
*/
|
|
94
|
+
export declare function orderStoresForRelease<T extends StoreDefinition>(stores: readonly T[]): T[];
|
|
61
95
|
/**
|
|
62
96
|
* Every registered store's migrations that the ledger does not list. The
|
|
63
97
|
* release step calls this after applying, so a deploy whose ledger disagrees
|
|
@@ -48,6 +48,10 @@ export const FRAMEWORK_STORES = [
|
|
|
48
48
|
"automation_run_history",
|
|
49
49
|
() => import("../jobs/run-history.js").then((m) => m.automationRunHistoryStore),
|
|
50
50
|
],
|
|
51
|
+
[
|
|
52
|
+
"automation_trigger_events",
|
|
53
|
+
() => import("../triggers/event-queue.js").then((m) => m.automationTriggerEventsStore),
|
|
54
|
+
],
|
|
51
55
|
[
|
|
52
56
|
"automation_webhook_tokens",
|
|
53
57
|
() => import("../triggers/webhook-store.js").then((m) => m.automationWebhookTokensStore),
|
|
@@ -56,6 +60,10 @@ export const FRAMEWORK_STORES = [
|
|
|
56
60
|
"awaiting_inputs",
|
|
57
61
|
() => import("../integrations/awaiting-input-store.js").then((m) => m.awaitingInputsStore),
|
|
58
62
|
],
|
|
63
|
+
[
|
|
64
|
+
"better_auth",
|
|
65
|
+
() => import("../server/better-auth-migrations.js").then((m) => m.betterAuthStore),
|
|
66
|
+
],
|
|
59
67
|
[
|
|
60
68
|
"browser_sessions",
|
|
61
69
|
() => import("../browser-sessions/store.js").then((m) => m.browserSessionsStore),
|
|
@@ -80,6 +88,10 @@ export const FRAMEWORK_STORES = [
|
|
|
80
88
|
"computer_approvals",
|
|
81
89
|
() => import("../integrations/computer-supervision-store.js").then((m) => m.computerApprovalsStore),
|
|
82
90
|
],
|
|
91
|
+
[
|
|
92
|
+
"context_xray",
|
|
93
|
+
() => import("../agent/context-xray/schema-store.js").then((m) => m.contextXrayStore),
|
|
94
|
+
],
|
|
83
95
|
[
|
|
84
96
|
"conversation_scopes",
|
|
85
97
|
() => import("../integrations/scope-store.js").then((m) => m.conversationScopesStore),
|
|
@@ -164,6 +176,7 @@ export const FRAMEWORK_STORES = [
|
|
|
164
176
|
"observational_memory",
|
|
165
177
|
() => import("../agent/observational-memory/store.js").then((m) => m.observationalMemoryStore),
|
|
166
178
|
],
|
|
179
|
+
["org", () => import("../org/schema-store.js").then((m) => m.orgStore)],
|
|
167
180
|
[
|
|
168
181
|
"pending_tasks",
|
|
169
182
|
() => import("../integrations/pending-tasks-store.js").then((m) => m.pendingTasksStore),
|