@agent-native/core 0.167.0 → 0.167.4
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/templates/analytics/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/assets/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/brain/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/calendar/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/chat/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/clips/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/clips/CHANGELOG.md +1 -0
- package/corpus/templates/clips/app/routes/download.tsx +78 -131
- package/corpus/templates/content/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/crm/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/design/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/dispatch/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/factory/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/forms/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/macros/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/mail/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/plan/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/slides/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/tasks/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/dist/changelog/parse.js +219 -8
- package/dist/chat-threads/store.d.ts +7 -0
- package/dist/chat-threads/store.js +15 -0
- package/dist/client/AgentPanel.d.ts +5 -1
- package/dist/client/AgentPanel.js +8 -8
- package/dist/client/AssistantChat.d.ts +3 -1
- package/dist/client/AssistantChat.js +22 -6
- package/dist/client/MultiTabAssistantChat.d.ts +3 -1
- package/dist/client/MultiTabAssistantChat.js +5 -4
- package/dist/client/agent-page/AgentJobsTab.js +39 -6
- package/dist/client/agent-page/AutomationScheduleDialog.d.ts +10 -1
- package/dist/client/agent-page/AutomationScheduleDialog.js +3 -2
- package/dist/client/agent-page/ScheduledTriggerNotice.d.ts +22 -0
- package/dist/client/agent-page/ScheduledTriggerNotice.js +84 -0
- package/dist/client/agent-page/scheduled-trigger-state.d.ts +28 -0
- package/dist/client/agent-page/scheduled-trigger-state.js +10 -0
- package/dist/client/agent-page/use-jobs.d.ts +7 -0
- package/dist/client/agent-page/use-jobs.js +14 -0
- package/dist/client/blocks/library/diagram.config.d.ts +4 -1
- package/dist/client/blocks/library/diagram.js +1 -1
- package/dist/client/chat/run-recovery.js +15 -7
- package/dist/client/use-chat-threads.d.ts +7 -0
- package/dist/client/use-chat-threads.js +144 -40
- package/dist/deploy/build.d.ts +5 -0
- package/dist/deploy/build.js +12 -1
- package/dist/framework-tools.js +1 -0
- package/dist/jobs/actions/get-scheduled-trigger-status.d.ts +13 -0
- package/dist/jobs/actions/get-scheduled-trigger-status.js +21 -0
- package/dist/localization/default-messages.d.ts +14 -0
- package/dist/localization/default-messages.js +14 -0
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/provider-api/actions/custom-provider-registration.d.ts +4 -4
- package/dist/provider-api/actions/provider-api.d.ts +13 -13
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/action-discovery.js +4 -0
- package/dist/server/agent-chat/recurring-jobs-runtime.d.ts +42 -1
- package/dist/server/agent-chat/recurring-jobs-runtime.js +102 -9
- package/dist/server/agent-chat-plugin.d.ts +3 -1
- package/dist/server/agent-chat-plugin.js +115 -24
- package/dist/server/attribution.d.ts +29 -0
- package/dist/server/attribution.js +68 -0
- package/dist/server/auth.js +58 -15
- package/dist/server/better-auth-instance.js +16 -4
- package/dist/server/identity-sso.js +14 -2
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/request-context.d.ts +8 -0
- package/dist/server/request-context.js +4 -0
- package/dist/templates/chat/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/dist/templates/default/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/dist/templates/headless/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/dist/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/dist/vite/client.js +10 -0
- package/docs/content/deployment.mdx +3 -1
- package/docs/content/recurring-jobs.mdx +6 -0
- package/package.json +2 -2
- package/src/templates/chat/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +11 -0
|
@@ -3,12 +3,13 @@ import { agentNativePath } from "./api-path.js";
|
|
|
3
3
|
const ACTIVE_THREAD_KEY = "agent-chat-active-thread";
|
|
4
4
|
const THREADS_UPDATED_EVENT = "agent-chat:threads-updated";
|
|
5
5
|
const THREADS_PAGE_SIZE = 50;
|
|
6
|
-
async function fetchThreadListPage(apiUrl, offset, includeExternal) {
|
|
6
|
+
async function fetchThreadListPage(apiUrl, offset, includeExternal, scope) {
|
|
7
7
|
const params = new URLSearchParams();
|
|
8
8
|
if (offset > 0)
|
|
9
9
|
params.set("offset", String(offset));
|
|
10
10
|
if (includeExternal)
|
|
11
11
|
params.set("includeExternal", "1");
|
|
12
|
+
appendChatThreadScopeParams(params, scope);
|
|
12
13
|
const query = params.toString();
|
|
13
14
|
return fetch(`${apiUrl}/threads${query ? `?${query}` : ""}`).then(async (res) => {
|
|
14
15
|
if (!res.ok)
|
|
@@ -22,9 +23,12 @@ async function fetchThreadListPage(apiUrl, offset, includeExternal) {
|
|
|
22
23
|
* the caller must not collapse: the thread (found), `null` (the server denies it
|
|
23
24
|
* exists), and `undefined` (unreachable — nothing was learned).
|
|
24
25
|
*/
|
|
25
|
-
async function fetchThreadById(apiUrl, id) {
|
|
26
|
+
async function fetchThreadById(apiUrl, id, scope) {
|
|
26
27
|
try {
|
|
27
|
-
const
|
|
28
|
+
const params = new URLSearchParams();
|
|
29
|
+
appendChatThreadScopeParams(params, scope);
|
|
30
|
+
const query = params.toString();
|
|
31
|
+
const res = await fetch(`${apiUrl}/threads/${encodeURIComponent(id)}${query ? `?${query}` : ""}`);
|
|
28
32
|
if (res.status === 404)
|
|
29
33
|
return null;
|
|
30
34
|
if (!res.ok)
|
|
@@ -35,6 +39,20 @@ async function fetchThreadById(apiUrl, id) {
|
|
|
35
39
|
return undefined;
|
|
36
40
|
}
|
|
37
41
|
}
|
|
42
|
+
export function appendChatThreadScopeParams(params, scope) {
|
|
43
|
+
if (!scope)
|
|
44
|
+
return;
|
|
45
|
+
params.set("scopeType", scope.type);
|
|
46
|
+
params.set("scopeId", scope.id);
|
|
47
|
+
}
|
|
48
|
+
function withChatThreadScope(url, scope) {
|
|
49
|
+
const params = new URLSearchParams();
|
|
50
|
+
appendChatThreadScopeParams(params, scope);
|
|
51
|
+
const query = params.toString();
|
|
52
|
+
if (!query)
|
|
53
|
+
return url;
|
|
54
|
+
return `${url}${url.includes("?") ? "&" : "?"}${query}`;
|
|
55
|
+
}
|
|
38
56
|
function emitThreadsUpdated() {
|
|
39
57
|
if (typeof window === "undefined")
|
|
40
58
|
return;
|
|
@@ -91,6 +109,12 @@ function threadCanStayVisibleInScope(threadScope, currentScope) {
|
|
|
91
109
|
return true;
|
|
92
110
|
return scopesMatch(threadScope, currentScope);
|
|
93
111
|
}
|
|
112
|
+
function threadCanStayVisibleInHistory(threadScope, currentScope, isolateHistoryByScope = false) {
|
|
113
|
+
if (!isolateHistoryByScope) {
|
|
114
|
+
return threadCanStayVisibleInScope(threadScope, currentScope);
|
|
115
|
+
}
|
|
116
|
+
return scopesMatch(threadScope, currentScope);
|
|
117
|
+
}
|
|
94
118
|
function nextThreadTitle(currentTitle, incomingTitle, incomingPreview, source = "extracted", options = {}) {
|
|
95
119
|
if (options.preserveUserTitle && currentTitle)
|
|
96
120
|
return currentTitle;
|
|
@@ -109,6 +133,12 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
109
133
|
const autoCreate = options?.autoCreate !== false;
|
|
110
134
|
const restoreActiveThread = options?.restoreActiveThread !== false;
|
|
111
135
|
const includeExternal = options?.includeExternal === true;
|
|
136
|
+
const isolateHistoryByScope = options?.isolateHistoryByScope === true;
|
|
137
|
+
const isolateHistory = isolateHistoryByScope && Boolean(scope);
|
|
138
|
+
const historyScope = useMemo(() => (isolateHistory && scope ? { type: scope.type, id: scope.id } : null), [isolateHistory, scope?.id, scope?.type]);
|
|
139
|
+
const historyScopeKey = historyScope
|
|
140
|
+
? `${historyScope.type}:${historyScope.id}`
|
|
141
|
+
: null;
|
|
112
142
|
const routeControlsActiveThread = options?.routeThreadId !== undefined;
|
|
113
143
|
const routeThreadId = normalizeThreadId(options?.routeThreadId);
|
|
114
144
|
// Each (storageKey, scope) pair gets its own active-thread localStorage key
|
|
@@ -170,6 +200,7 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
170
200
|
? new Set([initialActiveThreadRef.current.id])
|
|
171
201
|
: new Set());
|
|
172
202
|
const optimisticThreadScopesRef = useRef(new Map());
|
|
203
|
+
const knownThreadScopesRef = useRef(new Map());
|
|
173
204
|
const pendingPinnedAtRef = useRef(new Map());
|
|
174
205
|
const pendingArchivedAtRef = useRef(new Map());
|
|
175
206
|
const userRenamedThreadIdsRef = useRef(new Set());
|
|
@@ -215,6 +246,9 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
215
246
|
if (optimisticThreadScopesRef.current.has(id)) {
|
|
216
247
|
return optimisticThreadScopesRef.current.get(id) ?? null;
|
|
217
248
|
}
|
|
249
|
+
if (knownThreadScopesRef.current.has(id)) {
|
|
250
|
+
return knownThreadScopesRef.current.get(id) ?? null;
|
|
251
|
+
}
|
|
218
252
|
return undefined;
|
|
219
253
|
}, []);
|
|
220
254
|
// Add a client-generated thread to the local list optimistically.
|
|
@@ -290,7 +324,7 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
290
324
|
if (currentThreadScope === undefined) {
|
|
291
325
|
return;
|
|
292
326
|
}
|
|
293
|
-
if (
|
|
327
|
+
if (threadCanStayVisibleInHistory(currentThreadScope, scopeRef.current, isolateHistory)) {
|
|
294
328
|
persistedKeyRef.current = activeThreadKey;
|
|
295
329
|
return;
|
|
296
330
|
}
|
|
@@ -308,7 +342,7 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
308
342
|
if (nextActiveThreadId) {
|
|
309
343
|
const savedScope = readKnownThreadScope(nextActiveThreadId);
|
|
310
344
|
if (savedScope !== undefined &&
|
|
311
|
-
!
|
|
345
|
+
!threadCanStayVisibleInHistory(savedScope, scopeRef.current, isolateHistory)) {
|
|
312
346
|
nextActiveThreadId = null;
|
|
313
347
|
}
|
|
314
348
|
}
|
|
@@ -356,7 +390,7 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
356
390
|
const requestId = ++latestFetchRequestRef.current;
|
|
357
391
|
try {
|
|
358
392
|
const offset = options?.append ? nextThreadsOffsetRef.current : 0;
|
|
359
|
-
const loaded = await fetchThreadListPage(apiUrl, offset, includeExternal);
|
|
393
|
+
const loaded = await fetchThreadListPage(apiUrl, offset, includeExternal, historyScope);
|
|
360
394
|
if (requestId !== latestFetchRequestRef.current)
|
|
361
395
|
return undefined;
|
|
362
396
|
if (!loaded) {
|
|
@@ -365,6 +399,9 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
365
399
|
}
|
|
366
400
|
return;
|
|
367
401
|
}
|
|
402
|
+
for (const thread of loaded) {
|
|
403
|
+
knownThreadScopesRef.current.set(thread.id, thread.scope ?? null);
|
|
404
|
+
}
|
|
368
405
|
setThreadsLoadError(null);
|
|
369
406
|
if (!options?.append) {
|
|
370
407
|
nextThreadsOffsetRef.current = loaded.length;
|
|
@@ -373,8 +410,11 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
373
410
|
nextThreadsOffsetRef.current += loaded.length;
|
|
374
411
|
}
|
|
375
412
|
setHasMoreThreads(loaded.length >= THREADS_PAGE_SIZE);
|
|
413
|
+
const visibleLoaded = isolateHistory
|
|
414
|
+
? loaded.filter((thread) => threadCanStayVisibleInHistory(thread.scope, historyScope, isolateHistory))
|
|
415
|
+
: loaded;
|
|
376
416
|
setThreads((prev) => {
|
|
377
|
-
const loadedIds = new Set(
|
|
417
|
+
const loadedIds = new Set(visibleLoaded.map((t) => t.id));
|
|
378
418
|
// Preserve any optimistic threads we've created this session that
|
|
379
419
|
// haven't shown up in the server list yet — the server only learns
|
|
380
420
|
// about a thread when the user actually sends a message and the
|
|
@@ -387,13 +427,15 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
387
427
|
// and get preserved forever instead of disappearing once archived.
|
|
388
428
|
const optimisticOnly = prev.filter((t) => newlyCreatedRef.current.has(t.id) &&
|
|
389
429
|
!loadedIds.has(t.id) &&
|
|
390
|
-
!t.archivedAt
|
|
430
|
+
!t.archivedAt &&
|
|
431
|
+
(!isolateHistory ||
|
|
432
|
+
threadCanStayVisibleInHistory(t.scope, historyScope, isolateHistory)));
|
|
391
433
|
// Reconcile each server thread against our local copy. If the local
|
|
392
434
|
// copy has a newer updatedAt or higher messageCount, keep those
|
|
393
435
|
// fields — the server probably hasn't observed the user's latest
|
|
394
436
|
// send yet, and naively replacing makes the recent-chats list
|
|
395
437
|
// visibly jump back to older timestamps right after a send.
|
|
396
|
-
const merged =
|
|
438
|
+
const merged = visibleLoaded.map((server) => {
|
|
397
439
|
const local = prev.find((t) => t.id === server.id);
|
|
398
440
|
if (!local)
|
|
399
441
|
return server;
|
|
@@ -438,7 +480,7 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
438
480
|
}
|
|
439
481
|
return [...optimisticOnly, ...merged];
|
|
440
482
|
});
|
|
441
|
-
return
|
|
483
|
+
return visibleLoaded;
|
|
442
484
|
}
|
|
443
485
|
catch {
|
|
444
486
|
if (requestId !== latestFetchRequestRef.current)
|
|
@@ -448,7 +490,28 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
448
490
|
}
|
|
449
491
|
return undefined;
|
|
450
492
|
}
|
|
451
|
-
}, [apiUrl, includeExternal]);
|
|
493
|
+
}, [apiUrl, historyScope, includeExternal, isolateHistory]);
|
|
494
|
+
const loadedHistoryScopeKeyRef = useRef(historyScopeKey);
|
|
495
|
+
useEffect(() => {
|
|
496
|
+
if (loadedHistoryScopeKeyRef.current === historyScopeKey)
|
|
497
|
+
return;
|
|
498
|
+
loadedHistoryScopeKeyRef.current = historyScopeKey;
|
|
499
|
+
if (!isolateHistoryByScope)
|
|
500
|
+
return;
|
|
501
|
+
nextThreadsOffsetRef.current = 0;
|
|
502
|
+
setHasMoreThreads(false);
|
|
503
|
+
setThreadsLoadError(null);
|
|
504
|
+
setThreads((prev) => prev.filter((thread) => !isolateHistory ||
|
|
505
|
+
threadCanStayVisibleInHistory(thread.scope, historyScope, isolateHistory)));
|
|
506
|
+
setIsLoading(true);
|
|
507
|
+
void fetchThreads().finally(() => setIsLoading(false));
|
|
508
|
+
}, [
|
|
509
|
+
fetchThreads,
|
|
510
|
+
historyScope,
|
|
511
|
+
historyScopeKey,
|
|
512
|
+
isolateHistory,
|
|
513
|
+
isolateHistoryByScope,
|
|
514
|
+
]);
|
|
452
515
|
const loadMoreThreads = useCallback(async () => {
|
|
453
516
|
if (isLoadingMoreThreads || !hasMoreThreads)
|
|
454
517
|
return;
|
|
@@ -509,8 +572,11 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
509
572
|
// One page, so absence from it is not absence from the server — this is what
|
|
510
573
|
// separates an older real thread from an unavailable saved id below.
|
|
511
574
|
const restoredThread = lookupRestored && !restoredOnPage
|
|
512
|
-
? await fetchThreadById(apiUrl, restoredId)
|
|
575
|
+
? await fetchThreadById(apiUrl, restoredId, historyScope)
|
|
513
576
|
: restoredOnPage;
|
|
577
|
+
if (restoredThread) {
|
|
578
|
+
knownThreadScopesRef.current.set(restoredThread.id, restoredThread.scope ?? null);
|
|
579
|
+
}
|
|
514
580
|
if (restoredThread === undefined && lookupRestored && !restoredOnPage) {
|
|
515
581
|
// Lookup unreachable. Reclassifying now would stamp this thread with the
|
|
516
582
|
// current scope on a guess; leave it untouched for the next mount.
|
|
@@ -519,7 +585,7 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
519
585
|
}
|
|
520
586
|
const restoredIsUnavailable = restoredThread === null && lookupRestored && !restoredOnPage;
|
|
521
587
|
const restoredBelongsElsewhere = Boolean(restoredThread &&
|
|
522
|
-
!
|
|
588
|
+
!threadCanStayVisibleInHistory(restoredThread.scope ?? null, scopeRef.current, isolateHistory));
|
|
523
589
|
// A missing saved id is stale local UI state on a normal home surface,
|
|
524
590
|
// not a reason to show an error above a fresh composer. Preserve it for
|
|
525
591
|
// explicit routes and list-only readers, where the caller still owns
|
|
@@ -587,6 +653,8 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
587
653
|
fetchThreads,
|
|
588
654
|
addOptimisticThread,
|
|
589
655
|
autoCreate,
|
|
656
|
+
historyScope,
|
|
657
|
+
isolateHistory,
|
|
590
658
|
routeControlsActiveThread,
|
|
591
659
|
routeThreadId,
|
|
592
660
|
]);
|
|
@@ -641,7 +709,7 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
641
709
|
// list right away.
|
|
642
710
|
const detachThread = useCallback(async (threadId) => {
|
|
643
711
|
try {
|
|
644
|
-
const res = await fetch(`${apiUrl}/threads/${encodeURIComponent(threadId)}`, {
|
|
712
|
+
const res = await fetch(withChatThreadScope(`${apiUrl}/threads/${encodeURIComponent(threadId)}`, historyScope), {
|
|
645
713
|
method: "PUT",
|
|
646
714
|
headers: { "Content-Type": "application/json" },
|
|
647
715
|
body: JSON.stringify({ scope: null }),
|
|
@@ -652,14 +720,42 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
652
720
|
await fetchThreads();
|
|
653
721
|
return;
|
|
654
722
|
}
|
|
655
|
-
|
|
723
|
+
knownThreadScopesRef.current.set(threadId, null);
|
|
656
724
|
optimisticThreadScopesRef.current.set(threadId, null);
|
|
725
|
+
const wasActive = activeThreadIdRef.current === threadId;
|
|
726
|
+
if (isolateHistory) {
|
|
727
|
+
setThreads((prev) => prev.filter((thread) => thread.id !== threadId &&
|
|
728
|
+
threadCanStayVisibleInHistory(thread.scope, historyScope, isolateHistory)));
|
|
729
|
+
if (wasActive) {
|
|
730
|
+
const remaining = threadsRef.current.filter((thread) => thread.id !== threadId &&
|
|
731
|
+
threadCanStayVisibleInHistory(thread.scope, historyScope, isolateHistory));
|
|
732
|
+
if (remaining.length > 0) {
|
|
733
|
+
setActiveThreadId(remaining[0].id);
|
|
734
|
+
}
|
|
735
|
+
else if (autoCreate) {
|
|
736
|
+
void createThread();
|
|
737
|
+
}
|
|
738
|
+
else {
|
|
739
|
+
setActiveThreadId(null);
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
else {
|
|
744
|
+
setThreads((prev) => prev.map((t) => (t.id === threadId ? { ...t, scope: null } : t)));
|
|
745
|
+
}
|
|
657
746
|
emitThreadsUpdated();
|
|
658
747
|
}
|
|
659
748
|
catch {
|
|
660
749
|
await fetchThreads().catch(() => { });
|
|
661
750
|
}
|
|
662
|
-
}, [
|
|
751
|
+
}, [
|
|
752
|
+
apiUrl,
|
|
753
|
+
autoCreate,
|
|
754
|
+
createThread,
|
|
755
|
+
fetchThreads,
|
|
756
|
+
historyScope,
|
|
757
|
+
isolateHistory,
|
|
758
|
+
]);
|
|
663
759
|
const pinThread = useCallback(async (threadId, pinned) => {
|
|
664
760
|
const previousPinnedAt = threadsRef.current.find((t) => t.id === threadId)?.pinnedAt ?? null;
|
|
665
761
|
const previousUpdatedAt = threadsRef.current.find((t) => t.id === threadId)?.updatedAt ?? null;
|
|
@@ -680,7 +776,7 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
680
776
|
};
|
|
681
777
|
setThreads((prev) => prev.map((t) => (t.id === threadId ? { ...t, pinnedAt } : t)));
|
|
682
778
|
try {
|
|
683
|
-
const res = await fetch(`${apiUrl}/threads/${encodeURIComponent(threadId)}/pin`, {
|
|
779
|
+
const res = await fetch(withChatThreadScope(`${apiUrl}/threads/${encodeURIComponent(threadId)}/pin`, historyScope), {
|
|
684
780
|
method: "POST",
|
|
685
781
|
headers: { "Content-Type": "application/json" },
|
|
686
782
|
body: JSON.stringify({ pinned }),
|
|
@@ -701,7 +797,7 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
701
797
|
await fetchThreads();
|
|
702
798
|
return false;
|
|
703
799
|
}
|
|
704
|
-
}, [apiUrl, fetchThreads]);
|
|
800
|
+
}, [apiUrl, fetchThreads, historyScope]);
|
|
705
801
|
const archiveThread = useCallback(async (threadId) => {
|
|
706
802
|
const previousArchivedAt = threadsRef.current.find((t) => t.id === threadId)?.archivedAt ?? null;
|
|
707
803
|
const previousUpdatedAt = threadsRef.current.find((t) => t.id === threadId)?.updatedAt ?? null;
|
|
@@ -726,7 +822,7 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
726
822
|
};
|
|
727
823
|
setThreads((prev) => prev.map((t) => (t.id === threadId ? { ...t, archivedAt } : t)));
|
|
728
824
|
try {
|
|
729
|
-
const res = await fetch(`${apiUrl}/threads/${encodeURIComponent(threadId)}/archive`, {
|
|
825
|
+
const res = await fetch(withChatThreadScope(`${apiUrl}/threads/${encodeURIComponent(threadId)}/archive`, historyScope), {
|
|
730
826
|
method: "POST",
|
|
731
827
|
headers: { "Content-Type": "application/json" },
|
|
732
828
|
body: JSON.stringify({ archived: true }),
|
|
@@ -750,7 +846,7 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
750
846
|
await fetchThreads();
|
|
751
847
|
return false;
|
|
752
848
|
}
|
|
753
|
-
}, [apiUrl, fetchThreads]);
|
|
849
|
+
}, [apiUrl, fetchThreads, historyScope]);
|
|
754
850
|
const renameThread = useCallback(async (threadId, title) => {
|
|
755
851
|
const nextTitle = title.replace(/\s+/g, " ").trim().slice(0, 160);
|
|
756
852
|
if (!nextTitle)
|
|
@@ -768,7 +864,7 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
768
864
|
markUserRenamedThread(threadId);
|
|
769
865
|
setThreads((prev) => prev.map((t) => (t.id === threadId ? { ...t, title: nextTitle } : t)));
|
|
770
866
|
try {
|
|
771
|
-
const res = await fetch(`${apiUrl}/threads/${encodeURIComponent(threadId)}/rename`, {
|
|
867
|
+
const res = await fetch(withChatThreadScope(`${apiUrl}/threads/${encodeURIComponent(threadId)}/rename`, historyScope), {
|
|
772
868
|
method: "POST",
|
|
773
869
|
headers: { "Content-Type": "application/json" },
|
|
774
870
|
body: JSON.stringify({ title: nextTitle }),
|
|
@@ -786,7 +882,13 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
786
882
|
await fetchThreads();
|
|
787
883
|
return false;
|
|
788
884
|
}
|
|
789
|
-
}, [
|
|
885
|
+
}, [
|
|
886
|
+
apiUrl,
|
|
887
|
+
clearUserRenamedThread,
|
|
888
|
+
fetchThreads,
|
|
889
|
+
historyScope,
|
|
890
|
+
markUserRenamedThread,
|
|
891
|
+
]);
|
|
790
892
|
const isNewThread = useCallback((id) => newlyCreatedRef.current.has(id), []);
|
|
791
893
|
const switchThread = useCallback((id) => {
|
|
792
894
|
persistActiveThreadId(id);
|
|
@@ -794,7 +896,7 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
794
896
|
}, [persistActiveThreadId]);
|
|
795
897
|
const removeThread = useCallback(async (id) => {
|
|
796
898
|
try {
|
|
797
|
-
await fetch(`${apiUrl}/threads/${encodeURIComponent(id)}`, {
|
|
899
|
+
await fetch(withChatThreadScope(`${apiUrl}/threads/${encodeURIComponent(id)}`, historyScope), {
|
|
798
900
|
method: "DELETE",
|
|
799
901
|
});
|
|
800
902
|
emitThreadsUpdated();
|
|
@@ -816,7 +918,7 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
816
918
|
createThread();
|
|
817
919
|
}
|
|
818
920
|
}
|
|
819
|
-
}, [apiUrl, clearUserRenamedThread, createThread]);
|
|
921
|
+
}, [apiUrl, clearUserRenamedThread, createThread, historyScope]);
|
|
820
922
|
// Reads scope through refs so this callback survives every setThreads. Scope
|
|
821
923
|
// rides only on creation: a periodic save must never move an existing thread
|
|
822
924
|
// between resources, however stale this client's guess is.
|
|
@@ -828,7 +930,7 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
828
930
|
const preserveUserTitle = userRenamedThreadIdsRef.current.has(id);
|
|
829
931
|
const title = nextThreadTitle(localThread?.title, data.title, data.preview, titleSource, { preserveUserTitle });
|
|
830
932
|
const payload = { ...threadDataPayload, title };
|
|
831
|
-
let response = await fetch(`${apiUrl}/threads/${encodeURIComponent(id)}`, {
|
|
933
|
+
let response = await fetch(withChatThreadScope(`${apiUrl}/threads/${encodeURIComponent(id)}`, historyScope), {
|
|
832
934
|
method: "PUT",
|
|
833
935
|
headers: { "Content-Type": "application/json" },
|
|
834
936
|
body: JSON.stringify(payload),
|
|
@@ -837,7 +939,7 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
837
939
|
// client-created thread, so no agent run has created its SQL row yet.
|
|
838
940
|
// Materialize that row idempotently and retry the same full save.
|
|
839
941
|
if (response.status === 404) {
|
|
840
|
-
const created = await fetch(`${apiUrl}/threads`, {
|
|
942
|
+
const created = await fetch(withChatThreadScope(`${apiUrl}/threads`, historyScope), {
|
|
841
943
|
method: "POST",
|
|
842
944
|
headers: { "Content-Type": "application/json" },
|
|
843
945
|
body: JSON.stringify({
|
|
@@ -848,7 +950,7 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
848
950
|
});
|
|
849
951
|
if (!created.ok)
|
|
850
952
|
return;
|
|
851
|
-
response = await fetch(`${apiUrl}/threads/${encodeURIComponent(id)}`, {
|
|
953
|
+
response = await fetch(withChatThreadScope(`${apiUrl}/threads/${encodeURIComponent(id)}`, historyScope), {
|
|
852
954
|
method: "PUT",
|
|
853
955
|
headers: { "Content-Type": "application/json" },
|
|
854
956
|
body: JSON.stringify(payload),
|
|
@@ -894,7 +996,7 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
894
996
|
});
|
|
895
997
|
}
|
|
896
998
|
catch { }
|
|
897
|
-
}, [apiUrl, readKnownThreadScope]);
|
|
999
|
+
}, [apiUrl, historyScope, readKnownThreadScope]);
|
|
898
1000
|
const generateTitle = useCallback(async (threadId, message) => {
|
|
899
1001
|
try {
|
|
900
1002
|
const res = await fetch(`${apiUrl}/generate-title`, {
|
|
@@ -923,7 +1025,7 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
923
1025
|
const fallbackForkFromSnapshot = async (source) => {
|
|
924
1026
|
const title = source.title ? `${source.title} (fork)` : "";
|
|
925
1027
|
const createdAt = Date.now();
|
|
926
|
-
const createRes = await fetch(`${apiUrl}/threads`, {
|
|
1028
|
+
const createRes = await fetch(withChatThreadScope(`${apiUrl}/threads`, historyScope), {
|
|
927
1029
|
method: "POST",
|
|
928
1030
|
headers: { "Content-Type": "application/json" },
|
|
929
1031
|
body: JSON.stringify({
|
|
@@ -934,7 +1036,7 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
934
1036
|
});
|
|
935
1037
|
if (!createRes.ok)
|
|
936
1038
|
return null;
|
|
937
|
-
const saveRes = await fetch(`${apiUrl}/threads/${encodeURIComponent(id)}`, {
|
|
1039
|
+
const saveRes = await fetch(withChatThreadScope(`${apiUrl}/threads/${encodeURIComponent(id)}`, historyScope), {
|
|
938
1040
|
method: "PUT",
|
|
939
1041
|
headers: { "Content-Type": "application/json" },
|
|
940
1042
|
body: JSON.stringify({
|
|
@@ -962,7 +1064,7 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
962
1064
|
const source = sourceSnapshot && sourceSnapshot.messageCount > 0
|
|
963
1065
|
? { ...sourceSnapshot, scope: localScope }
|
|
964
1066
|
: undefined;
|
|
965
|
-
const res = await fetch(`${apiUrl}/threads/${encodeURIComponent(sourceId)}/fork`, {
|
|
1067
|
+
const res = await fetch(withChatThreadScope(`${apiUrl}/threads/${encodeURIComponent(sourceId)}/fork`, historyScope), {
|
|
966
1068
|
method: "POST",
|
|
967
1069
|
headers: { "Content-Type": "application/json" },
|
|
968
1070
|
body: JSON.stringify({ id, ...(source ? { source } : {}) }),
|
|
@@ -1003,25 +1105,27 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
1003
1105
|
console.error(`[chat] fork threw for ${sourceId}:`, err);
|
|
1004
1106
|
return null;
|
|
1005
1107
|
}
|
|
1006
|
-
}, [apiUrl]);
|
|
1108
|
+
}, [apiUrl, historyScope]);
|
|
1007
1109
|
const searchThreads = useCallback(async (query) => {
|
|
1008
1110
|
try {
|
|
1009
1111
|
const params = new URLSearchParams({ q: query });
|
|
1010
1112
|
if (includeExternal)
|
|
1011
1113
|
params.set("includeExternal", "1");
|
|
1114
|
+
appendChatThreadScopeParams(params, historyScope);
|
|
1012
1115
|
const res = await fetch(`${apiUrl}/threads?${params.toString()}`);
|
|
1013
1116
|
if (!res.ok)
|
|
1014
1117
|
return [];
|
|
1015
1118
|
const data = await res.json();
|
|
1016
|
-
return data.threads ?? []
|
|
1119
|
+
return (data.threads ?? []).filter((thread) => !isolateHistory ||
|
|
1120
|
+
threadCanStayVisibleInHistory(thread.scope, historyScope, isolateHistory));
|
|
1017
1121
|
}
|
|
1018
1122
|
catch {
|
|
1019
1123
|
return [];
|
|
1020
1124
|
}
|
|
1021
|
-
}, [apiUrl, includeExternal]);
|
|
1125
|
+
}, [apiUrl, historyScope, includeExternal, isolateHistory]);
|
|
1022
1126
|
const getThreadShareState = useCallback(async (threadId) => {
|
|
1023
1127
|
try {
|
|
1024
|
-
const res = await fetch(`${apiUrl}/threads/${encodeURIComponent(threadId)}/share
|
|
1128
|
+
const res = await fetch(withChatThreadScope(`${apiUrl}/threads/${encodeURIComponent(threadId)}/share`, historyScope));
|
|
1025
1129
|
if (!res.ok)
|
|
1026
1130
|
return null;
|
|
1027
1131
|
const data = await res.json();
|
|
@@ -1030,10 +1134,10 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
1030
1134
|
catch {
|
|
1031
1135
|
return null;
|
|
1032
1136
|
}
|
|
1033
|
-
}, [apiUrl]);
|
|
1137
|
+
}, [apiUrl, historyScope]);
|
|
1034
1138
|
const createThreadShareLink = useCallback(async (threadId) => {
|
|
1035
1139
|
try {
|
|
1036
|
-
const res = await fetch(`${apiUrl}/threads/${encodeURIComponent(threadId)}/share`, { method: "POST" });
|
|
1140
|
+
const res = await fetch(withChatThreadScope(`${apiUrl}/threads/${encodeURIComponent(threadId)}/share`, historyScope), { method: "POST" });
|
|
1037
1141
|
if (!res.ok)
|
|
1038
1142
|
return null;
|
|
1039
1143
|
const data = await res.json();
|
|
@@ -1044,10 +1148,10 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
1044
1148
|
catch {
|
|
1045
1149
|
return null;
|
|
1046
1150
|
}
|
|
1047
|
-
}, [apiUrl]);
|
|
1151
|
+
}, [apiUrl, historyScope]);
|
|
1048
1152
|
const revokeThreadShareLink = useCallback(async (threadId) => {
|
|
1049
1153
|
try {
|
|
1050
|
-
const res = await fetch(`${apiUrl}/threads/${encodeURIComponent(threadId)}/share`, { method: "DELETE" });
|
|
1154
|
+
const res = await fetch(withChatThreadScope(`${apiUrl}/threads/${encodeURIComponent(threadId)}/share`, historyScope), { method: "DELETE" });
|
|
1051
1155
|
if (!res.ok)
|
|
1052
1156
|
return null;
|
|
1053
1157
|
const data = await res.json();
|
|
@@ -1056,7 +1160,7 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
|
|
|
1056
1160
|
catch {
|
|
1057
1161
|
return null;
|
|
1058
1162
|
}
|
|
1059
|
-
}, [apiUrl]);
|
|
1163
|
+
}, [apiUrl, historyScope]);
|
|
1060
1164
|
const refreshThreads = useCallback(() => {
|
|
1061
1165
|
fetchThreads();
|
|
1062
1166
|
}, [fetchThreads]);
|
package/dist/deploy/build.d.ts
CHANGED
|
@@ -101,6 +101,11 @@ export declare function isDurableBackgroundDeployEnabled(): boolean;
|
|
|
101
101
|
export declare const NETLIFY_INTEGRATION_RECOVERY_FUNCTION_NAME = "server-integration-recovery";
|
|
102
102
|
export declare function isIntegrationDurableDispatchDeployEnabled(): boolean;
|
|
103
103
|
export declare const NETLIFY_RECURRING_JOBS_FUNCTION_NAME = "agent-native-recurring-jobs";
|
|
104
|
+
/**
|
|
105
|
+
* Routed through the same resolver that produces the runtime marker, so the gate
|
|
106
|
+
* that emits the scheduled function and the value the deployed app reports
|
|
107
|
+
* cannot drift: a build that skips the emit always ships `"disabled"`.
|
|
108
|
+
*/
|
|
104
109
|
export declare function isRecurringJobsDeployEnabled(): boolean;
|
|
105
110
|
/**
|
|
106
111
|
* Keep-warm is opt-in because a once-a-minute wake prevents autosuspend on
|
package/dist/deploy/build.js
CHANGED
|
@@ -24,6 +24,7 @@ import { INTEGRATION_RECOVERY_RUNTIME_MARKER, INTEGRATION_RETRY_SWEEP_PATH, INTE
|
|
|
24
24
|
import { isValidCron } from "../jobs/cron.js";
|
|
25
25
|
import { RECURRING_JOBS_SWEEP_PATH, RECURRING_JOBS_SWEEP_TOKEN_SUBJECT, } from "../jobs/scheduler-dispatch.js";
|
|
26
26
|
import { findWorkspaceRoot as findAgentNativeWorkspaceRoot } from "../scripts/utils.js";
|
|
27
|
+
import { RECURRING_JOBS_BUILD_MARKER_ENV_VAR, resolveRecurringJobsBuildMarker, } from "../server/agent-chat/recurring-jobs-runtime.js";
|
|
27
28
|
import { normalizeAppBasePath } from "../server/app-base-path.js";
|
|
28
29
|
import { DEFAULT_SPECULATION_RULES_PATH, resolveSsrCacheHeaders, resolveSsrCacheKeyHeaders, SSR_QUERY_CACHE_KEY_HEADER, } from "../shared/cache-control.js";
|
|
29
30
|
import { mcpEmbedStaticAssetRouteRules } from "../shared/mcp-embed-headers.js";
|
|
@@ -2407,8 +2408,13 @@ function isTruthyEnv(name) {
|
|
|
2407
2408
|
function isDisabledByEnv(name) {
|
|
2408
2409
|
return isTruthyEnv(name);
|
|
2409
2410
|
}
|
|
2411
|
+
/**
|
|
2412
|
+
* Routed through the same resolver that produces the runtime marker, so the gate
|
|
2413
|
+
* that emits the scheduled function and the value the deployed app reports
|
|
2414
|
+
* cannot drift: a build that skips the emit always ships `"disabled"`.
|
|
2415
|
+
*/
|
|
2410
2416
|
export function isRecurringJobsDeployEnabled() {
|
|
2411
|
-
return
|
|
2417
|
+
return resolveRecurringJobsBuildMarker(process.env) === "enabled";
|
|
2412
2418
|
}
|
|
2413
2419
|
/**
|
|
2414
2420
|
* Keep-warm is opt-in because a once-a-minute wake prevents autosuspend on
|
|
@@ -3887,6 +3893,11 @@ export function resolveNitroBuildReplacements(env = process.env, deploymentEnvir
|
|
|
3887
3893
|
// well as in the Vite server bundle.
|
|
3888
3894
|
"process.env.AGENT_NATIVE_RELEASE_MIGRATIONS": JSON.stringify(env.AGENT_NATIVE_RELEASE_MIGRATIONS?.trim() || ""),
|
|
3889
3895
|
"process.env.AGENT_NATIVE_BUILD_DEPLOY_CONTEXT": JSON.stringify(env.CONTEXT?.trim() || env.NETLIFY_CONTEXT?.trim() || ""),
|
|
3896
|
+
// Whether the recurring-jobs scheduled function exists is decided HERE, by
|
|
3897
|
+
// the build env. `scheduledTriggerAvailability` cannot re-derive it later —
|
|
3898
|
+
// a pipeline that sets the kill switch only for the build leaves no runtime
|
|
3899
|
+
// trace of it — so hand the decision to the runtime explicitly.
|
|
3900
|
+
[`process.env.${RECURRING_JOBS_BUILD_MARKER_ENV_VAR}`]: JSON.stringify(resolveRecurringJobsBuildMarker(env)),
|
|
3890
3901
|
...(configuredDeploymentEnvironment
|
|
3891
3902
|
? {
|
|
3892
3903
|
"process.env.AGENT_NATIVE_DEPLOYMENT_ENVIRONMENT": JSON.stringify(configuredDeploymentEnvironment),
|
package/dist/framework-tools.js
CHANGED
|
@@ -126,6 +126,7 @@ export const CORE_ACTION_GROUPS = {
|
|
|
126
126
|
"manage-recurring-job": "automation",
|
|
127
127
|
"run-automation-now": "automation",
|
|
128
128
|
"list-automation-runs": "automation",
|
|
129
|
+
"get-scheduled-trigger-status": "automation",
|
|
129
130
|
"list-automations": "automation",
|
|
130
131
|
"manage-automation": "automation",
|
|
131
132
|
"get-usage-alerts": "automation",
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ScheduledTriggerAvailability } from "../../server/agent-chat/recurring-jobs-runtime.js";
|
|
2
|
+
export type ScheduledTriggerStatus = ScheduledTriggerAvailability;
|
|
3
|
+
/**
|
|
4
|
+
* Read surface for "will a schedule-triggered automation actually fire here".
|
|
5
|
+
*
|
|
6
|
+
* A separate action rather than a field on `list-automations` / `list-recurring-jobs`:
|
|
7
|
+
* both of those return bare arrays that several callers map over directly, so
|
|
8
|
+
* adding a sibling field means an envelope and a breaking change at every call
|
|
9
|
+
* site. This is deploy-scoped rather than per-automation data anyway — it never
|
|
10
|
+
* varies by row — so it caches independently and for much longer.
|
|
11
|
+
*/
|
|
12
|
+
declare const _default: import("../../action.js").ActionDefinition<Record<string, never>, ScheduledTriggerAvailability>;
|
|
13
|
+
export default _default;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { defineAction } from "../../action.js";
|
|
3
|
+
import { scheduledTriggerAvailability, } from "../../server/agent-chat/recurring-jobs-runtime.js";
|
|
4
|
+
/**
|
|
5
|
+
* Read surface for "will a schedule-triggered automation actually fire here".
|
|
6
|
+
*
|
|
7
|
+
* A separate action rather than a field on `list-automations` / `list-recurring-jobs`:
|
|
8
|
+
* both of those return bare arrays that several callers map over directly, so
|
|
9
|
+
* adding a sibling field means an envelope and a breaking change at every call
|
|
10
|
+
* site. This is deploy-scoped rather than per-automation data anyway — it never
|
|
11
|
+
* varies by row — so it caches independently and for much longer.
|
|
12
|
+
*/
|
|
13
|
+
export default defineAction({
|
|
14
|
+
description: "Report whether schedule-triggered automations can actually fire in this deploy, and which driver (or missing driver) decides that. Used by the Agent Automations page to warn that a schedule will never run.",
|
|
15
|
+
agentTool: false,
|
|
16
|
+
schema: z.object({}),
|
|
17
|
+
http: { method: "GET" },
|
|
18
|
+
readOnly: true,
|
|
19
|
+
parallelSafe: true,
|
|
20
|
+
run: async () => scheduledTriggerAvailability(),
|
|
21
|
+
});
|
|
@@ -667,6 +667,20 @@ declare const messages: {
|
|
|
667
667
|
organization: string;
|
|
668
668
|
settingsSummary: string;
|
|
669
669
|
openAutomations: string;
|
|
670
|
+
nextRunNeverScheduler: string;
|
|
671
|
+
nextRunSchedulerUnknown: string;
|
|
672
|
+
nextRunSchedulerUnknownNoDate: string;
|
|
673
|
+
scheduleUnknownTitle: string;
|
|
674
|
+
scheduleUnknownDetail: string;
|
|
675
|
+
scheduleUnavailableTitle: string;
|
|
676
|
+
scheduleUnavailableLocalTitle: string;
|
|
677
|
+
scheduleUnavailableDisabled: string;
|
|
678
|
+
scheduleUnavailableNoScheduler: string;
|
|
679
|
+
scheduleUnavailableLocal: string;
|
|
680
|
+
scheduleUnavailableDisabledFix: string;
|
|
681
|
+
scheduleUnavailableLocalFix: string;
|
|
682
|
+
scheduleUnavailableFixLabel: string;
|
|
683
|
+
scheduleUnavailableFixLabelOpen: string;
|
|
670
684
|
};
|
|
671
685
|
share: {
|
|
672
686
|
titleWithResource: string;
|
|
@@ -673,6 +673,20 @@ const messages = {
|
|
|
673
673
|
organization: "Organization",
|
|
674
674
|
settingsSummary: "Manage scheduled and event-triggered agent tasks together from the Automations page.",
|
|
675
675
|
openAutomations: "Open Automations",
|
|
676
|
+
nextRunNeverScheduler: "Never — no scheduler in this deploy",
|
|
677
|
+
nextRunSchedulerUnknown: "{{date}} — unconfirmed, the scheduler check failed",
|
|
678
|
+
nextRunSchedulerUnknownNoDate: "Unknown — the scheduler check failed",
|
|
679
|
+
scheduleUnknownTitle: "Couldn't check whether schedules run here",
|
|
680
|
+
scheduleUnknownDetail: "The scheduler status check failed, so the next run times below are unconfirmed. Reload to check again.",
|
|
681
|
+
scheduleUnavailableTitle: "Schedules won't run in this deploy",
|
|
682
|
+
scheduleUnavailableLocalTitle: "Schedules don't run in local development",
|
|
683
|
+
scheduleUnavailableDisabled: "This app was built with recurring jobs turned off, so no scheduled automation will fire. Event-triggered automations and Run now still work.",
|
|
684
|
+
scheduleUnavailableNoScheduler: "This hosting target has no durable scheduler, so no scheduled automation will fire. Event-triggered automations and Run now still work.",
|
|
685
|
+
scheduleUnavailableLocal: "Schedules stay off on a dev machine unless you opt in. Event-triggered automations and Run now still work.",
|
|
686
|
+
scheduleUnavailableDisabledFix: "To enable recurring jobs, set AGENT_NATIVE_DISABLE_RECURRING_JOBS=false in the build environment.",
|
|
687
|
+
scheduleUnavailableLocalFix: "Set AGENT_NATIVE_ENABLE_LOCAL_RECURRING_JOBS=true to run schedules on this machine.",
|
|
688
|
+
scheduleUnavailableFixLabel: "Show more",
|
|
689
|
+
scheduleUnavailableFixLabelOpen: "Show less",
|
|
676
690
|
},
|
|
677
691
|
share: {
|
|
678
692
|
titleWithResource: 'Share "{{title}}"',
|