@agent-native/core 0.100.0 → 0.100.2

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.
Files changed (68) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +14 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/client/AssistantChat.tsx +4 -0
  5. package/corpus/core/src/client/composer/PromptComposer.tsx +4 -0
  6. package/corpus/core/src/client/composer/TiptapComposer.tsx +30 -3
  7. package/corpus/core/src/integrations/webhook-handler.ts +4 -2
  8. package/corpus/core/src/secrets/crypto.ts +98 -47
  9. package/corpus/core/src/secrets/index.ts +2 -1
  10. package/corpus/core/src/secrets/schema.ts +3 -0
  11. package/corpus/core/src/secrets/storage.ts +164 -31
  12. package/corpus/templates/assets/app/components/layout/Layout.tsx +4 -0
  13. package/corpus/templates/assets/app/hooks/use-navigation-state.ts +3 -1
  14. package/corpus/templates/assets/changelog/2026-07-13-assets-keeps-the-right-chat-sidebar-closed-when-the-full-pag.md +6 -0
  15. package/corpus/templates/calendar/AGENTS.md +9 -0
  16. package/corpus/templates/calendar/actions/list-events.ts +659 -44
  17. package/corpus/templates/calendar/changelog/2026-07-13-calendar-inventory-reads-report-source-coverage.md +6 -0
  18. package/corpus/templates/calendar/server/lib/calendar-connector-catalog.ts +8 -0
  19. package/corpus/templates/calendar/server/lib/google-calendar.ts +173 -51
  20. package/corpus/templates/calendar/server/lib/ical-fetcher.ts +13 -2
  21. package/corpus/templates/calendar/server/plugins/agent-chat.ts +5 -3
  22. package/corpus/templates/calendar/shared/api.ts +2 -0
  23. package/corpus/templates/mail/AGENTS.md +12 -0
  24. package/corpus/templates/mail/actions/list-emails.ts +486 -4
  25. package/corpus/templates/mail/changelog/2026-07-13-coverage-aware-connected-inbox-inventory.md +6 -0
  26. package/corpus/templates/mail/server/db/schema.ts +17 -0
  27. package/corpus/templates/mail/server/lib/google-auth.ts +33 -5
  28. package/corpus/templates/mail/server/lib/inventory-cursor.ts +406 -0
  29. package/corpus/templates/mail/server/lib/list-inbox-emails.ts +21 -2
  30. package/corpus/templates/mail/server/lib/mail-connector-catalog.ts +8 -0
  31. package/corpus/templates/mail/server/plugins/agent-chat.ts +4 -9
  32. package/corpus/templates/mail/server/plugins/db.ts +20 -0
  33. package/dist/client/AssistantChat.d.ts +2 -0
  34. package/dist/client/AssistantChat.d.ts.map +1 -1
  35. package/dist/client/AssistantChat.js +2 -2
  36. package/dist/client/AssistantChat.js.map +1 -1
  37. package/dist/client/composer/PromptComposer.d.ts +2 -0
  38. package/dist/client/composer/PromptComposer.d.ts.map +1 -1
  39. package/dist/client/composer/PromptComposer.js +2 -2
  40. package/dist/client/composer/PromptComposer.js.map +1 -1
  41. package/dist/client/composer/TiptapComposer.d.ts +3 -1
  42. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  43. package/dist/client/composer/TiptapComposer.js +20 -5
  44. package/dist/client/composer/TiptapComposer.js.map +1 -1
  45. package/dist/collab/struct-routes.d.ts +1 -1
  46. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  47. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  48. package/dist/integrations/webhook-handler.js +3 -2
  49. package/dist/integrations/webhook-handler.js.map +1 -1
  50. package/dist/notifications/routes.d.ts +3 -3
  51. package/dist/resources/handlers.d.ts +2 -2
  52. package/dist/secrets/crypto.d.ts +35 -13
  53. package/dist/secrets/crypto.d.ts.map +1 -1
  54. package/dist/secrets/crypto.js +78 -41
  55. package/dist/secrets/crypto.js.map +1 -1
  56. package/dist/secrets/index.d.ts.map +1 -1
  57. package/dist/secrets/index.js +2 -1
  58. package/dist/secrets/index.js.map +1 -1
  59. package/dist/secrets/schema.d.ts +20 -1
  60. package/dist/secrets/schema.d.ts.map +1 -1
  61. package/dist/secrets/schema.js +3 -0
  62. package/dist/secrets/schema.js.map +1 -1
  63. package/dist/secrets/storage.d.ts +7 -7
  64. package/dist/secrets/storage.d.ts.map +1 -1
  65. package/dist/secrets/storage.js +121 -30
  66. package/dist/secrets/storage.js.map +1 -1
  67. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  68. package/package.json +1 -1
@@ -0,0 +1,406 @@
1
+ import { createHash } from "node:crypto";
2
+
3
+ import { and, eq, gt, lt, or, sql } from "drizzle-orm";
4
+
5
+ import { getDb } from "../db/index.js";
6
+ import { mailInventoryCursors } from "../db/schema.js";
7
+
8
+ const TTL_MS = 10 * 60 * 1000;
9
+ const CLAIM_TTL_MS = 60 * 1000;
10
+ const PAGE_ITEMS_BUDGET_BYTES = 12 * 1024;
11
+
12
+ export interface MailInventoryItem {
13
+ id: string;
14
+ threadId: string;
15
+ accountEmail: string;
16
+ date: string;
17
+ from: { name?: string; email: string };
18
+ subject: string;
19
+ isUnread: boolean;
20
+ isStarred?: boolean;
21
+ messageCount: number;
22
+ unreadCount: number;
23
+ snippet?: string;
24
+ }
25
+
26
+ export interface MailInventoryError {
27
+ code: string;
28
+ message: string;
29
+ retryable: boolean;
30
+ }
31
+
32
+ export interface MailInventoryAccountState {
33
+ accountEmail: string;
34
+ status: "ok" | "error";
35
+ error?: MailInventoryError;
36
+ providerPageToken?: string;
37
+ exhausted: boolean;
38
+ pending: MailInventoryItem[];
39
+ emittedCount: number;
40
+ /** Unique rows discovered so coverage remains visible before emission. */
41
+ knownCount?: number;
42
+ /** Account-local thread ids already emitted by an earlier output page. */
43
+ emittedThreadIds?: string[];
44
+ }
45
+
46
+ export interface MailInventoryCursorState {
47
+ queryFingerprint: string;
48
+ requestedAccounts: string[] | null;
49
+ accounts: MailInventoryAccountState[];
50
+ firstPage: boolean;
51
+ }
52
+
53
+ export interface MailInventoryCursorClaim {
54
+ id: string;
55
+ claimId: string;
56
+ ownerEmail: string;
57
+ queryFingerprint: string;
58
+ version: number;
59
+ state: MailInventoryCursorState;
60
+ }
61
+
62
+ export interface MailInventoryFetchResult {
63
+ items: MailInventoryItem[];
64
+ errors: Record<string, MailInventoryError>;
65
+ nextPageTokens: Record<string, string>;
66
+ }
67
+
68
+ function stableValue(value: unknown): unknown {
69
+ if (Array.isArray(value)) return value.map(stableValue);
70
+ if (value && typeof value === "object") {
71
+ return Object.fromEntries(
72
+ Object.entries(value as Record<string, unknown>)
73
+ .sort(([a], [b]) => a.localeCompare(b))
74
+ .map(([key, child]) => [key, stableValue(child)]),
75
+ );
76
+ }
77
+ return value;
78
+ }
79
+
80
+ export function inventoryQueryFingerprint(input: unknown): string {
81
+ return createHash("sha256")
82
+ .update(JSON.stringify(stableValue(input)))
83
+ .digest("hex");
84
+ }
85
+
86
+ export function compareInventoryItems(
87
+ a: MailInventoryItem,
88
+ b: MailInventoryItem,
89
+ ): number {
90
+ const date = new Date(b.date).getTime() - new Date(a.date).getTime();
91
+ if (date) return date;
92
+ const account = a.accountEmail.localeCompare(b.accountEmail);
93
+ if (account) return account;
94
+ const thread = a.threadId.localeCompare(b.threadId);
95
+ if (thread) return thread;
96
+ return a.id.localeCompare(b.id);
97
+ }
98
+
99
+ function dedupeAndSort(items: MailInventoryItem[]): MailInventoryItem[] {
100
+ const unique = new Map<string, MailInventoryItem>();
101
+ for (const item of items) {
102
+ const key = `${item.accountEmail.toLowerCase()}:${item.threadId}`;
103
+ const current = unique.get(key);
104
+ if (!current || compareInventoryItems(item, current) < 0) {
105
+ unique.set(key, item);
106
+ }
107
+ }
108
+ return [...unique.values()].sort(compareInventoryItems);
109
+ }
110
+
111
+ function applyFetch(
112
+ states: MailInventoryAccountState[],
113
+ result: MailInventoryFetchResult,
114
+ ): void {
115
+ const byAccount = new Map<string, MailInventoryItem[]>();
116
+ for (const item of result.items) {
117
+ const key = item.accountEmail.toLowerCase();
118
+ const accountItems = byAccount.get(key) ?? [];
119
+ accountItems.push(item);
120
+ byAccount.set(key, accountItems);
121
+ }
122
+
123
+ for (const state of states) {
124
+ const key = state.accountEmail.toLowerCase();
125
+ const error = result.errors[key];
126
+ if (error) {
127
+ state.status = "error";
128
+ state.error = error;
129
+ state.exhausted = true;
130
+ state.providerPageToken = undefined;
131
+ continue;
132
+ }
133
+ const emitted = new Set(state.emittedThreadIds ?? []);
134
+ const before = new Set(
135
+ state.pending.map((item) => item.threadId).concat([...emitted]),
136
+ );
137
+ const additions = (byAccount.get(key) ?? []).filter(
138
+ (item) => !before.has(item.threadId),
139
+ );
140
+ state.knownCount =
141
+ (state.knownCount ?? state.emittedCount) + additions.length;
142
+ state.pending = dedupeAndSort([...state.pending, ...additions]);
143
+ state.providerPageToken = result.nextPageTokens[key];
144
+ state.exhausted = !state.providerPageToken;
145
+ }
146
+ }
147
+
148
+ export async function buildMailInventoryPage(
149
+ state: MailInventoryCursorState,
150
+ limit: number,
151
+ fetch: (
152
+ accounts: Array<{ accountEmail: string; pageToken?: string }>,
153
+ ) => Promise<MailInventoryFetchResult>,
154
+ ): Promise<{ items: MailInventoryItem[]; hasMore: boolean }> {
155
+ const pageLimit = Math.max(1, Math.min(Math.floor(limit), 100));
156
+ const refillCounts = new Map<string, number>();
157
+ const refillFrontiers = async () => {
158
+ while (true) {
159
+ const needsFetch = state.accounts.filter(
160
+ (account) =>
161
+ account.status === "ok" &&
162
+ account.pending.length === 0 &&
163
+ !account.exhausted,
164
+ );
165
+ if (needsFetch.length === 0) return;
166
+ const fetchable = needsFetch.filter((account) => {
167
+ const key = account.accountEmail.toLowerCase();
168
+ const count = refillCounts.get(key) ?? 0;
169
+ if (count < 4) {
170
+ refillCounts.set(key, count + 1);
171
+ return true;
172
+ }
173
+ account.status = "error";
174
+ account.error = {
175
+ code: "pagination_limit",
176
+ message:
177
+ "Mail pagination did not expose a row frontier within four provider pages.",
178
+ retryable: true,
179
+ };
180
+ account.exhausted = true;
181
+ account.providerPageToken = undefined;
182
+ return false;
183
+ });
184
+ if (fetchable.length === 0) continue;
185
+ const prior = fetchable.map((account) => ({
186
+ account,
187
+ token: account.providerPageToken,
188
+ }));
189
+ applyFetch(
190
+ fetchable,
191
+ await fetch(
192
+ fetchable.map((account) => ({
193
+ accountEmail: account.accountEmail,
194
+ pageToken: account.providerPageToken,
195
+ })),
196
+ ),
197
+ );
198
+ for (const { account, token } of prior) {
199
+ if (
200
+ account.status === "ok" &&
201
+ !account.exhausted &&
202
+ account.pending.length === 0 &&
203
+ account.providerPageToken === token
204
+ ) {
205
+ throw new Error(
206
+ `Mail provider pagination made no progress for ${account.accountEmail}.`,
207
+ );
208
+ }
209
+ }
210
+ }
211
+ };
212
+
213
+ const page: MailInventoryItem[] = [];
214
+ const emittedKeys = new Set<string>();
215
+ let pageBytes = 2; // JSON array brackets
216
+ const emit = (
217
+ account: MailInventoryAccountState,
218
+ item: MailInventoryItem,
219
+ ) => {
220
+ const key = `${item.accountEmail.toLowerCase()}:${item.threadId}`;
221
+ if (emittedKeys.has(key)) return;
222
+ emittedKeys.add(key);
223
+ page.push(item);
224
+ account.emittedCount += 1;
225
+ account.emittedThreadIds = [
226
+ ...(account.emittedThreadIds ?? []),
227
+ item.threadId,
228
+ ];
229
+ };
230
+
231
+ while (page.length < pageLimit) {
232
+ // A global merge is only safe when every live account has a known
233
+ // frontier. Refill an emptied account before emitting an older candidate
234
+ // from another account; otherwise an unseen newer provider row can be
235
+ // skipped across the page boundary.
236
+ await refillFrontiers();
237
+ const candidates = state.accounts
238
+ .filter((account) => account.pending.length > 0)
239
+ .map((account) => ({ account, item: account.pending[0] }))
240
+ .sort((a, b) => compareInventoryItems(a.item, b.item));
241
+ if (candidates.length === 0) {
242
+ break;
243
+ }
244
+ const winner = candidates[0];
245
+ const itemBytes = new TextEncoder().encode(
246
+ JSON.stringify(winner.item),
247
+ ).byteLength;
248
+ if (
249
+ page.length > 0 &&
250
+ pageBytes + itemBytes + 1 > PAGE_ITEMS_BUDGET_BYTES
251
+ ) {
252
+ break;
253
+ }
254
+ winner.account.pending.shift();
255
+ emit(winner.account, winner.item);
256
+ pageBytes += itemBytes + (page.length > 1 ? 1 : 0);
257
+ }
258
+
259
+ page.sort(compareInventoryItems);
260
+ state.firstPage = false;
261
+ return {
262
+ items: page,
263
+ hasMore: state.accounts.some(
264
+ (account) => account.pending.length > 0 || !account.exhausted,
265
+ ),
266
+ };
267
+ }
268
+
269
+ export async function createInventoryCursor(
270
+ ownerEmail: string,
271
+ state: MailInventoryCursorState,
272
+ ): Promise<string> {
273
+ const now = Date.now();
274
+ const id = crypto.randomUUID();
275
+ await getDb()
276
+ .insert(mailInventoryCursors)
277
+ .values({
278
+ id,
279
+ ownerEmail,
280
+ queryFingerprint: state.queryFingerprint,
281
+ state: JSON.stringify(state),
282
+ version: 1,
283
+ expiresAt: now + TTL_MS,
284
+ updatedAt: now,
285
+ });
286
+ await getDb()
287
+ .delete(mailInventoryCursors)
288
+ .where(lt(mailInventoryCursors.expiresAt, now));
289
+ return id;
290
+ }
291
+
292
+ /**
293
+ * Atomically leases a cursor without consuming it. Provider work happens only
294
+ * after this short-lived CAS. Failures can release the lease; success settles
295
+ * it into a distinct successor id (or deletes it at exhaustion).
296
+ */
297
+ export async function claimInventoryCursor(
298
+ ownerEmail: string,
299
+ id: string,
300
+ queryFingerprint: string,
301
+ ): Promise<MailInventoryCursorClaim | null> {
302
+ const now = Date.now();
303
+ const claimId = crypto.randomUUID();
304
+ const staleBefore = now - CLAIM_TTL_MS;
305
+ const rows = await getDb()
306
+ .update(mailInventoryCursors)
307
+ .set({ claimId, claimedAt: now, updatedAt: now })
308
+ .where(
309
+ and(
310
+ eq(mailInventoryCursors.id, id),
311
+ eq(mailInventoryCursors.ownerEmail, ownerEmail),
312
+ eq(mailInventoryCursors.queryFingerprint, queryFingerprint),
313
+ gt(mailInventoryCursors.expiresAt, now),
314
+ or(
315
+ sql`${mailInventoryCursors.claimId} IS NULL`,
316
+ lt(mailInventoryCursors.claimedAt, staleBefore),
317
+ ),
318
+ ),
319
+ )
320
+ .returning({
321
+ state: mailInventoryCursors.state,
322
+ expiresAt: mailInventoryCursors.expiresAt,
323
+ version: mailInventoryCursors.version,
324
+ });
325
+ const row = rows[0];
326
+ if (!row || row.expiresAt <= now) return null;
327
+ try {
328
+ return {
329
+ id,
330
+ claimId,
331
+ ownerEmail,
332
+ queryFingerprint,
333
+ version: row.version,
334
+ state: JSON.parse(row.state) as MailInventoryCursorState,
335
+ };
336
+ } catch {
337
+ await releaseInventoryCursorClaim({
338
+ id,
339
+ claimId,
340
+ ownerEmail,
341
+ queryFingerprint,
342
+ version: row.version,
343
+ state: {} as MailInventoryCursorState,
344
+ });
345
+ return null;
346
+ }
347
+ }
348
+
349
+ export async function releaseInventoryCursorClaim(
350
+ claim: MailInventoryCursorClaim,
351
+ ): Promise<void> {
352
+ await getDb()
353
+ .update(mailInventoryCursors)
354
+ .set({ claimId: null, claimedAt: null, updatedAt: Date.now() })
355
+ .where(
356
+ and(
357
+ eq(mailInventoryCursors.id, claim.id),
358
+ eq(mailInventoryCursors.ownerEmail, claim.ownerEmail),
359
+ eq(mailInventoryCursors.queryFingerprint, claim.queryFingerprint),
360
+ eq(mailInventoryCursors.version, claim.version),
361
+ eq(mailInventoryCursors.claimId, claim.claimId),
362
+ ),
363
+ );
364
+ }
365
+
366
+ /** Atomically consumes a leased id and optionally creates its successor. */
367
+ export async function settleInventoryCursorClaim(
368
+ claim: MailInventoryCursorClaim,
369
+ state: MailInventoryCursorState,
370
+ hasMore: boolean,
371
+ ): Promise<string | undefined> {
372
+ const db = getDb();
373
+ const successorId = hasMore ? crypto.randomUUID() : undefined;
374
+ const now = Date.now();
375
+ return db.transaction(async (tx: any) => {
376
+ const consumed = await tx
377
+ .delete(mailInventoryCursors)
378
+ .where(
379
+ and(
380
+ eq(mailInventoryCursors.id, claim.id),
381
+ eq(mailInventoryCursors.ownerEmail, claim.ownerEmail),
382
+ eq(mailInventoryCursors.queryFingerprint, claim.queryFingerprint),
383
+ eq(mailInventoryCursors.version, claim.version),
384
+ eq(mailInventoryCursors.claimId, claim.claimId),
385
+ ),
386
+ )
387
+ .returning({ id: mailInventoryCursors.id });
388
+ if (consumed.length !== 1) {
389
+ throw new Error("Inventory cursor lease was lost before settlement.");
390
+ }
391
+ if (successorId) {
392
+ await tx.insert(mailInventoryCursors).values({
393
+ id: successorId,
394
+ ownerEmail: claim.ownerEmail,
395
+ queryFingerprint: claim.queryFingerprint,
396
+ state: JSON.stringify(state),
397
+ version: claim.version + 1,
398
+ claimId: null,
399
+ claimedAt: null,
400
+ expiresAt: now + TTL_MS,
401
+ updatedAt: now,
402
+ });
403
+ }
404
+ return successorId;
405
+ });
406
+ }
@@ -45,7 +45,11 @@ export interface ListInboxEmailsParams {
45
45
  pageTokens?: Record<string, string>;
46
46
  threadFormat?: "full" | "metadata" | "minimal";
47
47
  threadCandidateLimit?: number;
48
+ /** Disable the extra recent-message candidate pass for bounded inventory. */
49
+ includeRecentMessageCandidates?: boolean;
48
50
  accountTokens: ListInboxEmailsAccountToken[];
51
+ /** Selected account ids are forwarded to Gmail before token refresh. */
52
+ accountEmails?: string[];
49
53
  labelMap: Map<string, string>;
50
54
  }
51
55
 
@@ -108,7 +112,9 @@ export async function listInboxEmails(
108
112
  pageTokens,
109
113
  threadFormat,
110
114
  threadCandidateLimit,
115
+ includeRecentMessageCandidates = true,
111
116
  accountTokens,
117
+ accountEmails,
112
118
  labelMap,
113
119
  } = params;
114
120
 
@@ -123,12 +129,25 @@ export async function listInboxEmails(
123
129
  threadFormat,
124
130
  threadCandidateLimit,
125
131
  threadRecentMessageCandidateLimit:
126
- !q && (view === "inbox" || view === "unread")
132
+ includeRecentMessageCandidates &&
133
+ !q &&
134
+ (view === "inbox" || view === "unread")
127
135
  ? DEFAULT_THREAD_RECENT_MESSAGE_CANDIDATE_LIMIT
128
136
  : undefined,
137
+ accountEmails,
129
138
  });
130
139
 
131
- if (messages.length === 0 && errors.length > 0) {
140
+ const failedAccounts = new Set(
141
+ errors.map((error) => error.email.toLowerCase()),
142
+ );
143
+ const everySelectedAccountFailed = [...connectedEmails].every((email) =>
144
+ failedAccounts.has(email),
145
+ );
146
+ if (
147
+ messages.length === 0 &&
148
+ errors.length > 0 &&
149
+ everySelectedAccountFailed
150
+ ) {
132
151
  const isQuotaError = errors.every((e) => isGmailQuotaError(e.error));
133
152
  return {
134
153
  ok: false,
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Deliberately narrow authenticated MCP surface for Mail.
3
+ *
4
+ * External callers may read inbox coverage through list-emails. Other actions
5
+ * remain available through the in-app agent, ask_app, or an explicit
6
+ * full-catalog connection; tool-search alone never makes them callable.
7
+ */
8
+ export const MAIL_CONNECTOR_CATALOG = ["list-emails"] as const;
@@ -6,6 +6,7 @@ import {
6
6
  } from "@agent-native/core/server";
7
7
 
8
8
  import actionsRegistry from "../../.generated/actions-registry.js";
9
+ import { MAIL_CONNECTOR_CATALOG } from "../lib/mail-connector-catalog.js";
9
10
 
10
11
  const INITIAL_TOOL_NAMES = [
11
12
  "view-screen",
@@ -33,6 +34,7 @@ export default createAgentChatPlugin({
33
34
  actions: loadActionsFromStaticRegistry(actionsRegistry),
34
35
  appId: "mail",
35
36
  initialToolNames: INITIAL_TOOL_NAMES,
37
+ connectorCatalog: [...MAIL_CONNECTOR_CATALOG],
36
38
  resolveOrgId: async (event) => {
37
39
  const ctx = await getOrgContext(event);
38
40
  return ctx.orgId;
@@ -90,16 +92,9 @@ export default createAgentChatPlugin({
90
92
 
91
93
  Some less-common tool schemas are loaded on demand. Use tool-search with a specific query when you need a capability that is not already available as a direct tool.
92
94
 
93
- ## Google Connection Check — CRITICAL
95
+ ## Deterministic Mail Reads
94
96
 
95
- BEFORE doing anything else, run view-screen to check if Google is connected.
96
- If view-screen shows 0 emails or indicates Google is not connected:
97
- - Do NOT run list-emails, search-emails, send-email, or any email operation scripts
98
- - Do NOT pretend to have access to emails
99
- - Tell the user: "You need to connect your Google account first. Click the 'Connect Google' button on the main screen to get started."
100
- - You can still answer general questions, but you cannot perform any email operations
101
-
102
- Only proceed with email operations if view-screen confirms real emails are available.
97
+ For deterministic headless email reads, call list-emails directly in inventory/coverage mode. Do not require view-screen as a Google connection preflight: list-emails selects the connected Gmail or synthetic local-mail backend for the user and returns the relevant result. Use view-screen only when the answer depends on visible UI state, such as the active thread, selected message, draft, queue item, or current inbox view. Treat real action errors as the evidence for an unavailable connection; do not infer it from a zero-email screen.
103
98
 
104
99
  Available operations:
105
100
  - List and search emails
@@ -188,6 +188,26 @@ CREATE INDEX IF NOT EXISTS idx_snippets_owner_name ON snippets(owner_email, name
188
188
  sql: `ALTER TABLE queued_email_drafts ADD COLUMN IF NOT EXISTS send_claim_id TEXT;
189
189
  ALTER TABLE queued_email_drafts ADD COLUMN IF NOT EXISTS send_claimed_at ${intType()}`,
190
190
  },
191
+ {
192
+ version: 18,
193
+ name: "mail-inventory-cursors",
194
+ sql: `CREATE TABLE IF NOT EXISTS mail_inventory_cursors (
195
+ id TEXT PRIMARY KEY,
196
+ owner_email TEXT NOT NULL,
197
+ query_fingerprint TEXT NOT NULL,
198
+ state TEXT NOT NULL,
199
+ version ${intType()} NOT NULL DEFAULT 1,
200
+ expires_at ${intType()} NOT NULL,
201
+ updated_at ${intType()} NOT NULL
202
+ );
203
+ CREATE INDEX IF NOT EXISTS idx_mail_inventory_cursors_owner_expiry ON mail_inventory_cursors(owner_email, expires_at);`,
204
+ },
205
+ {
206
+ version: 19,
207
+ name: "mail-inventory-cursor-leases",
208
+ sql: `ALTER TABLE mail_inventory_cursors ADD COLUMN IF NOT EXISTS claim_id TEXT;
209
+ ALTER TABLE mail_inventory_cursors ADD COLUMN IF NOT EXISTS claimed_at ${intType()}`,
210
+ },
191
211
  ],
192
212
  { table: "mail_migrations" },
193
213
  );
@@ -263,6 +263,8 @@ export interface AssistantChatProps {
263
263
  onForkChat?: () => void | boolean | Promise<void | boolean>;
264
264
  /** Override Builder/provider connect routing for embedded hosts. */
265
265
  onConnectProvider?: () => void;
266
+ /** Route local runtime setup through the host's native bridge. */
267
+ onConnectLocalRuntime?: (engine: string) => void;
266
268
  /**
267
269
  * Controls the shared composer + menu. Sidebar keeps the full menu by default;
268
270
  * hosts without the sidebar provider stack can use upload-only.
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantChat.d.ts","sourceRoot":"","sources":["../../src/client/AssistantChat.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AssistantChat.d.ts","sourceRoot":"","sources":["../../src/client/AssistantChat.tsx"],"names":[],"mappings":"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"}
@@ -1265,7 +1265,7 @@ export function useAutoResumeStatus(tabId, forceStopped) {
1265
1265
  }, [clearAutoResume, forceStopped]);
1266
1266
  return { isAutoResuming, clearAutoResume };
1267
1267
  }
1268
- const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateText, suggestions, dynamicSuggestions, threadFooterSlot, emptyStateAddon, showHeader = true, onSwitchToCli, className, apiUrl, tabId, browserTabId, threadId, contextScope, isActiveComposer = true, onMessageCountChange, onSaveThread, onGenerateTitle, composerSlot, onComposerTextChange, composerAreaClassName, composerPlaceholder, missingApiKeySetupLayout = "default", composerLayoutVariant = "default", centerComposerWhenEmpty = false, emptyStateDisplay = "default", composerToolbarSlot, composerExtraActionButton, composerDisabled = false, composerDisabledPlaceholder, isNewThread, onSlashCommand, execMode, onExecModeChange, approvalActions, planModeDisabled, planModeDisabledReason, selectedModel, defaultModel, selectedEffort, availableModels, onModelChange, onEffortChange, imageModelMenu, onForkChat, onConnectProvider, plusMenuMode = "full", providerStatusChecksEnabled = true, loadHistoryRepository, historyReloadKey, externalStreaming = false, }, ref) {
1268
+ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateText, suggestions, dynamicSuggestions, threadFooterSlot, emptyStateAddon, showHeader = true, onSwitchToCli, className, apiUrl, tabId, browserTabId, threadId, contextScope, isActiveComposer = true, onMessageCountChange, onSaveThread, onGenerateTitle, composerSlot, onComposerTextChange, composerAreaClassName, composerPlaceholder, missingApiKeySetupLayout = "default", composerLayoutVariant = "default", centerComposerWhenEmpty = false, emptyStateDisplay = "default", composerToolbarSlot, composerExtraActionButton, composerDisabled = false, composerDisabledPlaceholder, isNewThread, onSlashCommand, execMode, onExecModeChange, approvalActions, planModeDisabled, planModeDisabledReason, selectedModel, defaultModel, selectedEffort, availableModels, onModelChange, onEffortChange, imageModelMenu, onForkChat, onConnectProvider, onConnectLocalRuntime, plusMenuMode = "full", providerStatusChecksEnabled = true, loadHistoryRepository, historyReloadKey, externalStreaming = false, }, ref) {
1269
1269
  const thread = useThread();
1270
1270
  const threadRuntime = useThreadRuntime();
1271
1271
  const t = useT();
@@ -3807,7 +3807,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
3807
3807
  isRunning,
3808
3808
  requestedIntent: options?.intent,
3809
3809
  }), undefined, true)
3810
- : undefined, onSlashCommand: onSlashCommand, execMode: execMode, onExecModeChange: onExecModeChange, planModeDisabled: planModeDisabled, planModeDisabledReason: planModeDisabledReason, selectedModel: selectedModel ?? defaultModel, selectedEffort: selectedEffort, availableModels: availableModels, onModelChange: onModelChange, onEffortChange: onEffortChange, imageModelMenu: imageModelMenu, onConnectProvider: onConnectProvider, toolbarSlot: composerToolbarSlot, contextItems: composerContextItems, onRemoveContextItem: removeComposerContextItem, plusMenuMode: plusMenuMode, layoutVariant: composerLayoutVariant, providerConnectStatusEnabled: providerStatusChecksEnabled, voiceEnabled: true, draftScope: threadId || tabId, interceptBuildRequestsForBuilder: true, onAttachmentError: setComposerError, extraActionButton: contextXRayEnabled ||
3810
+ : undefined, onSlashCommand: onSlashCommand, execMode: execMode, onExecModeChange: onExecModeChange, planModeDisabled: planModeDisabled, planModeDisabledReason: planModeDisabledReason, selectedModel: selectedModel ?? defaultModel, selectedEffort: selectedEffort, availableModels: availableModels, onModelChange: onModelChange, onEffortChange: onEffortChange, imageModelMenu: imageModelMenu, onConnectProvider: onConnectProvider, onConnectLocalRuntime: onConnectLocalRuntime, toolbarSlot: composerToolbarSlot, contextItems: composerContextItems, onRemoveContextItem: removeComposerContextItem, plusMenuMode: plusMenuMode, layoutVariant: composerLayoutVariant, providerConnectStatusEnabled: providerStatusChecksEnabled, voiceEnabled: true, draftScope: threadId || tabId, interceptBuildRequestsForBuilder: true, onAttachmentError: setComposerError, extraActionButton: contextXRayEnabled ||
3811
3811
  composerExtraActionButton ? (_jsxs(_Fragment, { children: [contextXRayEnabled && (_jsx(ContextMeter, { threadId: threadId })), composerExtraActionButton] })) : undefined, stopButton: showRunningInUI ? (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: () => stopActiveRun(), "aria-label": "Stop response", "data-agent-composer-slot": "stop-button", className: "shrink-0 flex h-7 w-7 cursor-pointer items-center justify-center rounded-full bg-primary text-primary-foreground shadow-sm transition-opacity hover:opacity-90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", children: _jsx(IconPlayerStopFilled, { className: "h-3 w-3" }) }) }), _jsx(TooltipContent, { children: "Stop response" })] })) : undefined })] })) }), showMissingKeySetup ? (_jsx(PopoverContent, { side: missingApiKeySetupLayout === "sidebar"
3812
3812
  ? "top"
3813
3813
  : "bottom", align: "center", sideOffset: 8, collisionPadding: 12, "data-agent-native-composer-popover": "true", className: "z-[260] box-border w-[min(calc(100vw-2rem),var(--radix-popover-content-available-width,26rem),26rem)] rounded-lg border-border p-3 shadow-lg", children: _jsx(BuilderSetupContent, { onConnected: handleBuilderConnected, layout: missingApiKeySetupLayout }) })) : null] })] })] }) }) }) }) }) }));