@agent-native/core 0.196.0 → 0.196.1-nightly-20260928204657

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 (51) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +1 -1
  3. package/corpus/templates/clips/actions/create-recording.ts +1 -1
  4. package/corpus/templates/clips/actions/lib/auto-title-candidates.ts +42 -0
  5. package/corpus/templates/clips/actions/lib/create-recording-schema.ts +1 -1
  6. package/corpus/templates/clips/actions/lib/transcript-text.ts +16 -0
  7. package/corpus/templates/clips/actions/list-ai-requests.ts +49 -31
  8. package/corpus/templates/clips/actions/list-recordings.ts +2 -4
  9. package/corpus/templates/clips/actions/list-transactional-email-ai-requests.ts +12 -6
  10. package/corpus/templates/clips/actions/regenerate-title.ts +4 -1
  11. package/corpus/templates/clips/actions/request-transcript.ts +1 -1
  12. package/corpus/templates/clips/actions/save-browser-transcript.ts +1 -1
  13. package/corpus/templates/clips/app/components/editable-recording-title.tsx +1 -1
  14. package/corpus/templates/clips/app/components/library/recording-card.tsx +1 -1
  15. package/corpus/templates/clips/app/hooks/use-auto-title.ts +194 -219
  16. package/corpus/templates/clips/app/routes/_app.r.$recordingId.tsx +2 -1
  17. package/corpus/templates/clips/app/routes/share.$shareId.tsx +1 -1
  18. package/corpus/templates/clips/changelog/2026-09-28-clip-share-previews-show-a-branded-image-while-the-recording.md +6 -0
  19. package/corpus/templates/clips/server/lib/slack-unfurls.ts +2 -0
  20. package/corpus/templates/clips/server/lib/transactional-email-store.ts +42 -2
  21. package/corpus/templates/clips/server/routes/api/thumbnail/[recordingId].get.ts +27 -15
  22. package/corpus/templates/clips/shared/ai-request-status.ts +6 -0
  23. package/corpus/templates/clips/shared/share-meta.ts +2 -27
  24. package/corpus/templates/clips/{actions/lib → shared}/title-source.ts +9 -2
  25. package/corpus/templates/slides/changelog/2026-09-28-typing-in-slides-agent-chat-keeps-every-character-in-order.md +6 -0
  26. package/corpus/templates/slides/scripts/edit-fidelity/README.md +11 -2
  27. package/corpus/templates/slides/scripts/edit-fidelity/run.ts +135 -4
  28. package/dist/agent/production-agent.js +2 -0
  29. package/dist/agent/run-manager.d.ts +2 -0
  30. package/dist/agent/run-manager.js +9 -2
  31. package/dist/agent/thread-data-builder.d.ts +1 -0
  32. package/dist/agent/thread-data-builder.js +148 -0
  33. package/dist/chat-threads/store.d.ts +1 -0
  34. package/dist/chat-threads/store.js +244 -21
  35. package/dist/client/AgentKitAssistantChat.js +23 -12
  36. package/dist/client/chat/agentkit-agent-native.js +409 -8
  37. package/dist/client/chat/agentkit-protocol.js +3 -0
  38. package/dist/collab/awareness.d.ts +2 -2
  39. package/dist/collab/struct-routes.d.ts +1 -1
  40. package/dist/notifications/routes.d.ts +1 -1
  41. package/dist/observability/routes.d.ts +6 -6
  42. package/dist/org/handlers.d.ts +1 -1
  43. package/dist/resources/handlers.d.ts +1 -1
  44. package/dist/secrets/routes.d.ts +4 -4
  45. package/dist/server/agent-chat-plugin.d.ts +2 -0
  46. package/dist/server/agent-chat-plugin.js +12 -7
  47. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  48. package/dist/server/agent-engine-ollama-models-route.d.ts +2 -2
  49. package/dist/server/realtime-token.d.ts +1 -1
  50. package/dist/sharing/actions/list-resource-shares.d.ts +1 -1
  51. package/package.json +2 -2
@@ -256,28 +256,253 @@ function normalizeForkSourceSnapshot(source) {
256
256
  catch {
257
257
  return null;
258
258
  }
259
- const repoMessageCount = Array.isArray(parsed.messages)
260
- ? parsed.messages.length
261
- : 0;
262
- if (repoMessageCount <= 0)
259
+ const messageCount = countThreadMessages(parsed, 0);
260
+ if (messageCount <= 0)
263
261
  return null;
264
262
  return {
265
263
  threadData: JSON.stringify(parsed),
266
264
  title: typeof source.title === "string" ? source.title : "",
267
265
  preview: typeof source.preview === "string" ? source.preview : "",
268
- messageCount: repoMessageCount,
266
+ messageCount,
267
+ ...(typeof source.fromMessageId === "string"
268
+ ? { fromMessageId: source.fromMessageId }
269
+ : {}),
269
270
  ...(Object.prototype.hasOwnProperty.call(source, "scope")
270
271
  ? { scope: source.scope ?? null }
271
272
  : {}),
272
273
  };
273
274
  }
275
+ function countThreadMessages(value, fallback) {
276
+ const repo = normalizeThreadRepository(value);
277
+ if (!repo || typeof repo !== "object")
278
+ return fallback;
279
+ const repoMessageCount = Array.isArray(repo.messages)
280
+ ? repo.messages.length
281
+ : undefined;
282
+ const agentKitMessageCount = Array.isArray(repo.agentKit?.messages)
283
+ ? repo.agentKit.messages.length
284
+ : undefined;
285
+ if (repoMessageCount === undefined && agentKitMessageCount === undefined) {
286
+ return fallback;
287
+ }
288
+ return Math.max(repoMessageCount ?? 0, agentKitMessageCount ?? 0);
289
+ }
290
+ function forkThreadData(threadData, forkId, fromMessageId) {
291
+ const parsed = normalizeThreadRepository(JSON.parse(threadData));
292
+ const repository = parsed && typeof parsed === "object" && !Array.isArray(parsed)
293
+ ? parsed
294
+ : undefined;
295
+ const agentKit = repository?.agentKit;
296
+ if (!agentKit || typeof agentKit !== "object" || Array.isArray(agentKit)) {
297
+ return threadData;
298
+ }
299
+ const agentKitRecord = agentKit;
300
+ const asRecord = (value) => value && typeof value === "object" && !Array.isArray(value)
301
+ ? value
302
+ : undefined;
303
+ const repositoryMessages = Array.isArray(repository.messages)
304
+ ? repository.messages
305
+ : [];
306
+ const protocolMessages = Array.isArray(agentKitRecord.messages)
307
+ ? agentKitRecord.messages
308
+ : [];
309
+ const messageId = (value) => {
310
+ const outer = asRecord(value);
311
+ const message = asRecord(outer?.message) ?? outer;
312
+ return typeof message?.id === "string" ? message.id : undefined;
313
+ };
314
+ const messageIds = new Set();
315
+ if (fromMessageId) {
316
+ for (const messages of [repositoryMessages, protocolMessages]) {
317
+ const throughIndex = messages.findIndex((message) => messageId(message) === fromMessageId);
318
+ if (throughIndex >= 0) {
319
+ for (const message of messages.slice(0, throughIndex + 1)) {
320
+ const id = messageId(message);
321
+ if (id)
322
+ messageIds.add(id);
323
+ }
324
+ }
325
+ }
326
+ if (!messageIds.has(fromMessageId)) {
327
+ throw new Error(`Unknown message for fork: ${fromMessageId}`);
328
+ }
329
+ }
330
+ else {
331
+ for (const message of [...repositoryMessages, ...protocolMessages]) {
332
+ const id = messageId(message);
333
+ if (id)
334
+ messageIds.add(id);
335
+ }
336
+ }
337
+ const events = Array.isArray(agentKitRecord.events)
338
+ ? agentKitRecord.events
339
+ : [];
340
+ const runs = Array.isArray(agentKitRecord.runs) ? agentKitRecord.runs : [];
341
+ const eventBoundaries = new Map();
342
+ for (const rawEvent of events) {
343
+ const event = asRecord(rawEvent);
344
+ const message = asRecord(event?.message);
345
+ const messageId = typeof event?.messageId === "string"
346
+ ? event.messageId
347
+ : typeof message?.id === "string"
348
+ ? message.id
349
+ : undefined;
350
+ if (event?.type === "message.completed" &&
351
+ typeof event?.runId === "string" &&
352
+ typeof event.sequence === "number" &&
353
+ messageId &&
354
+ messageIds.has(messageId)) {
355
+ eventBoundaries.set(event.runId, Math.max(eventBoundaries.get(event.runId) ?? 0, event.sequence));
356
+ }
357
+ }
358
+ for (const rawRun of runs) {
359
+ const run = asRecord(rawRun);
360
+ if (typeof run?.id === "string" &&
361
+ typeof run.activeMessageId === "string" &&
362
+ messageIds.has(run.activeMessageId) &&
363
+ typeof run.lastSequence === "number") {
364
+ eventBoundaries.set(run.id, Math.max(eventBoundaries.get(run.id) ?? 0, run.lastSequence));
365
+ }
366
+ }
367
+ const retainedRunIds = new Set(eventBoundaries.keys());
368
+ const nonterminalRunIds = new Set(runs.flatMap((rawRun) => {
369
+ const run = asRecord(rawRun);
370
+ return typeof run?.id === "string" &&
371
+ (run.status === "queued" ||
372
+ run.status === "running" ||
373
+ run.status === "awaiting_approval" ||
374
+ run.status === "awaiting_input")
375
+ ? [run.id]
376
+ : [];
377
+ }));
378
+ const activeMessageIds = new Set(runs.flatMap((rawRun) => {
379
+ const run = asRecord(rawRun);
380
+ return typeof run?.id === "string" &&
381
+ nonterminalRunIds.has(run.id) &&
382
+ typeof run.activeMessageId === "string"
383
+ ? [run.activeMessageId]
384
+ : [];
385
+ }));
386
+ const retainedMessageId = (value) => {
387
+ const id = messageId(value);
388
+ return Boolean(id && messageIds.has(id));
389
+ };
390
+ const remapThreadId = (value) => value && typeof value === "object" && !Array.isArray(value)
391
+ ? { ...value, threadId: forkId }
392
+ : value;
393
+ return JSON.stringify({
394
+ ...repository,
395
+ ...(Array.isArray(repository.messages)
396
+ ? { messages: repositoryMessages.filter(retainedMessageId) }
397
+ : {}),
398
+ agentKit: {
399
+ ...agentKitRecord,
400
+ ...(Array.isArray(agentKitRecord.messages)
401
+ ? {
402
+ messages: agentKitRecord.messages
403
+ .filter(retainedMessageId)
404
+ .map((message) => {
405
+ const record = asRecord(message);
406
+ return typeof record.id === "string" &&
407
+ activeMessageIds.has(record.id) &&
408
+ record.status === "streaming"
409
+ ? { ...record, status: "complete" }
410
+ : record;
411
+ }),
412
+ }
413
+ : {}),
414
+ ...(Array.isArray(agentKitRecord.events)
415
+ ? {
416
+ events: events.flatMap((rawEvent) => {
417
+ const event = asRecord(rawEvent);
418
+ const runId = event?.runId;
419
+ const boundary = typeof runId === "string"
420
+ ? eventBoundaries.get(runId)
421
+ : undefined;
422
+ if (typeof runId !== "string" ||
423
+ boundary === undefined ||
424
+ typeof event?.sequence !== "number" ||
425
+ event.sequence > boundary) {
426
+ return [];
427
+ }
428
+ if (nonterminalRunIds.has(runId) &&
429
+ (event.type === "activity.started" ||
430
+ event.type === "activity.updated")) {
431
+ const activity = asRecord(event.activity);
432
+ if (activity?.status === "running") {
433
+ return [
434
+ {
435
+ ...event,
436
+ type: "activity.completed",
437
+ activity: { ...activity, status: "cancelled" },
438
+ threadId: forkId,
439
+ },
440
+ ];
441
+ }
442
+ }
443
+ return [remapThreadId(rawEvent)];
444
+ }),
445
+ }
446
+ : {}),
447
+ ...(Array.isArray(agentKitRecord.runs)
448
+ ? {
449
+ runs: runs.flatMap((rawRun) => {
450
+ const run = asRecord(rawRun);
451
+ if (typeof run?.id !== "string" || !retainedRunIds.has(run.id)) {
452
+ return [];
453
+ }
454
+ const copied = {
455
+ ...run,
456
+ threadId: forkId,
457
+ };
458
+ if (nonterminalRunIds.has(run.id)) {
459
+ copied.status = "cancelled";
460
+ delete copied.activeMessageId;
461
+ }
462
+ return [copied];
463
+ }),
464
+ }
465
+ : {}),
466
+ ...(fromMessageId && Array.isArray(agentKitRecord.toolCalls)
467
+ ? {
468
+ toolCalls: agentKitRecord.toolCalls.filter((rawToolCall) => {
469
+ const toolCall = asRecord(rawToolCall);
470
+ if (typeof toolCall?.messageId === "string") {
471
+ return messageIds.has(toolCall.messageId);
472
+ }
473
+ return (typeof toolCall?.runId === "string" &&
474
+ retainedRunIds.has(toolCall.runId));
475
+ }),
476
+ }
477
+ : {}),
478
+ ...(Array.isArray(agentKitRecord.widgets)
479
+ ? {
480
+ widgets: agentKitRecord.widgets.filter((widget) => {
481
+ const record = asRecord(widget);
482
+ return (typeof record?.messageId === "string" &&
483
+ messageIds.has(record.messageId));
484
+ }),
485
+ }
486
+ : {}),
487
+ ...(Array.isArray(agentKitRecord.annotations)
488
+ ? {
489
+ annotations: agentKitRecord.annotations.filter((annotation) => {
490
+ const record = asRecord(annotation);
491
+ return (typeof record?.messageId === "string" &&
492
+ messageIds.has(record.messageId));
493
+ }),
494
+ }
495
+ : {}),
496
+ ...(fromMessageId ? { suggestions: [] } : {}),
497
+ activeRunIds: [],
498
+ },
499
+ });
500
+ }
274
501
  function deriveMessageCount(threadData, fallback) {
275
502
  if (typeof threadData !== "string" || !threadData.trim())
276
503
  return fallback;
277
504
  try {
278
- const repo = normalizeThreadRepository(JSON.parse(threadData));
279
- if (Array.isArray(repo.messages))
280
- return repo.messages.length;
505
+ return countThreadMessages(JSON.parse(threadData), fallback);
281
506
  }
282
507
  catch {
283
508
  // Keep the stored count if the JSON blob is malformed.
@@ -485,18 +710,17 @@ export async function forkThread(sourceId, ownerEmail, opts) {
485
710
  }
486
711
  else if (snapshot &&
487
712
  source.ownerEmail === ownerEmail &&
488
- snapshot.messageCount > source.messageCount) {
489
- // The source row exists but the in-memory snapshot is fresher — the agent
490
- // run flushed an older state to SQL, but the tab has additional unflushed
491
- // messages. Overlay the snapshot before cloning so the fork captures the
492
- // latest user-visible content. Guard with messageCount > stored to avoid
493
- // clobbering a fresher persisted row with a stale snapshot from another
494
- // tab.
713
+ (snapshot.fromMessageId || snapshot.messageCount > source.messageCount)) {
714
+ // Message-scoped forks intentionally carry a truncated snapshot even when
715
+ // the persisted source has later messages; full forks only overlay fresher
716
+ // client snapshots.
495
717
  source = {
496
718
  ...source,
497
719
  threadData: snapshot.threadData,
498
720
  title: snapshot.title || source.title,
499
- preview: snapshot.preview || source.preview,
721
+ preview: snapshot.fromMessageId
722
+ ? snapshot.preview
723
+ : snapshot.preview || source.preview,
500
724
  messageCount: snapshot.messageCount,
501
725
  };
502
726
  }
@@ -505,6 +729,7 @@ export async function forkThread(sourceId, ownerEmail, opts) {
505
729
  return null;
506
730
  }
507
731
  const id = opts?.id ?? generateId();
732
+ const threadData = forkThreadData(source.threadData, id, snapshot?.fromMessageId);
508
733
  const now = Date.now();
509
734
  const title = source.title ? `${source.title} (fork)` : "";
510
735
  const client = getDbExec();
@@ -516,7 +741,7 @@ export async function forkThread(sourceId, ownerEmail, opts) {
516
741
  ownerEmail,
517
742
  title,
518
743
  source.preview,
519
- source.threadData,
744
+ threadData,
520
745
  source.messageCount,
521
746
  now,
522
747
  now,
@@ -534,7 +759,7 @@ export async function forkThread(sourceId, ownerEmail, opts) {
534
759
  ownerEmail,
535
760
  title,
536
761
  preview: source.preview,
537
- threadData: source.threadData,
762
+ threadData,
538
763
  messageCount: source.messageCount,
539
764
  createdAt: now,
540
765
  updatedAt: now,
@@ -787,9 +1012,7 @@ export async function updateThreadData(id, threadData, title, preview, messageCo
787
1012
  preserveExistingTopLevelKeys: options.preserveExistingTopLevelKeys ?? true,
788
1013
  });
789
1014
  nextThreadData = JSON.stringify(merged);
790
- if (Array.isArray(merged.messages)) {
791
- nextMessageCount = merged.messages.length;
792
- }
1015
+ nextMessageCount = countThreadMessages(merged, messageCount);
793
1016
  }
794
1017
  catch {
795
1018
  // Keep the caller's serialized value if either JSON blob is malformed.
@@ -1,4 +1,5 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { hasActiveAgentRuns, } from "@agent-native/agentkit";
2
3
  import { AgentKitChat, AgentKitComposer, AgentApprovalPrompt, AgentMessageView, useAgentKit, useAgentKitControl, useAgentThread, } from "@agent-native/agentkit/react";
3
4
  import { AgentKitRoot } from "@agent-native/agentkit/react/root";
4
5
  import { AgentSuggestionBar, agentSuggestionPrompt, } from "@agent-native/toolkit/composer";
@@ -577,7 +578,7 @@ export const AgentKitAssistantChat = forwardRef(function AgentKitAssistantChat(p
577
578
  }, children: history ? (_jsx(AgentKitHistoryProvider, { history: history, children: _jsx(AgentKitDevCheckpointProvider, { apiUrl: props.apiUrl ?? agentNativePath("/_agent-native/agent-chat"), children: _jsx(AgentKitAssistantChatBody, { ...props, threadId: threadId, handoffSnapshot: handoffSnapshot, getThreadSnapshot: getThreadSnapshot, threadRestore: threadRestore, retryThreadRestore: retryThreadRestore, onThreadRestoreLoaded: onThreadRestoreLoaded, ref: ref }) }) })) : (_jsx(AgentKitDevCheckpointProvider, { apiUrl: props.apiUrl ?? agentNativePath("/_agent-native/agent-chat"), children: _jsx(AgentKitAssistantChatBody, { ...props, threadId: threadId, handoffSnapshot: handoffSnapshot, getThreadSnapshot: getThreadSnapshot, threadRestore: threadRestore, retryThreadRestore: retryThreadRestore, onThreadRestoreLoaded: onThreadRestoreLoaded, ref: ref }) })) }) }) }));
578
579
  });
579
580
  const AgentKitAssistantChatBody = forwardRef(function AgentKitAssistantChatBody(props, ref) {
580
- const { threadId, requestComposerFocus } = useAgentKit();
581
+ const { controller, threadId, requestComposerFocus } = useAgentKit();
581
582
  const control = useAgentKitControl(threadId);
582
583
  const thread = useAgentThread(threadId);
583
584
  const history = useOptionalAgentKitHistory();
@@ -701,7 +702,8 @@ const AgentKitAssistantChatBody = forwardRef(function AgentKitAssistantChatBody(
701
702
  const latestAssistant = useMemo(() => [...thread.messages]
702
703
  .reverse()
703
704
  .find((message) => message.role === "assistant"), [thread.messages]);
704
- const isRunning = thread.activeRunIds.length > 0;
705
+ const isRunning = hasActiveAgentRuns(thread);
706
+ const isThreadRunning = useCallback(() => hasActiveAgentRuns(controller.getThread(threadId)), [controller, threadId]);
705
707
  useEffect(() => {
706
708
  if (previousPrefillRevisionRef.current === prefillRevision)
707
709
  return;
@@ -1541,7 +1543,7 @@ const AgentKitAssistantChatBody = forwardRef(function AgentKitAssistantChatBody(
1541
1543
  thread.queuedMessages,
1542
1544
  threadId,
1543
1545
  ]);
1544
- const send = useCallback(async (text, images, options) => submit(text, [], [], { intent: isRunning ? "queued" : "immediate" }, {
1546
+ const send = useCallback(async (text, images, options) => submit(text, [], [], { intent: isThreadRunning() ? "queued" : "immediate" }, {
1545
1547
  ...options,
1546
1548
  attachments: [
1547
1549
  ...(options?.attachments ?? []),
@@ -1551,9 +1553,9 @@ const AgentKitAssistantChatBody = forwardRef(function AgentKitAssistantChatBody(
1551
1553
  url,
1552
1554
  })),
1553
1555
  ],
1554
- }), [isRunning, submit]);
1556
+ }), [isThreadRunning, submit]);
1555
1557
  const sendRecoveryMessage = useCallback(async (text, recoveryAction, images, attachments, references, recoveryOptions) => {
1556
- return submit(text, [], [], { intent: isRunning ? "queued" : "immediate" }, {
1558
+ return submit(text, [], [], { intent: isThreadRunning() ? "queued" : "immediate" }, {
1557
1559
  hideUserMessage: true,
1558
1560
  recoveryAction,
1559
1561
  recoveryReferences: references,
@@ -1567,7 +1569,7 @@ const AgentKitAssistantChatBody = forwardRef(function AgentKitAssistantChatBody(
1567
1569
  })),
1568
1570
  ],
1569
1571
  });
1570
- }, [isRunning, submit]);
1572
+ }, [isThreadRunning, submit]);
1571
1573
  const resumeIntegrationPrompt = useCallback((message) => {
1572
1574
  if (props.isActiveComposer === false)
1573
1575
  return;
@@ -1576,10 +1578,10 @@ const AgentKitAssistantChatBody = forwardRef(function AgentKitAssistantChatBody(
1576
1578
  });
1577
1579
  }, [props.isActiveComposer, props.tabId, send, threadId]);
1578
1580
  const submitSuggestion = useCallback((prompt) => void submit(prompt, [], [], {
1579
- intent: isRunning ? "queued" : "immediate",
1581
+ intent: isThreadRunning() ? "queued" : "immediate",
1580
1582
  }).catch((error) => {
1581
1583
  dispatchSetupRequiredEvent(error, props.tabId, threadId);
1582
- }), [isRunning, props.tabId, submit, threadId]);
1584
+ }), [isThreadRunning, props.tabId, submit, threadId]);
1583
1585
  const retryDeferredSubmission = useCallback(async () => {
1584
1586
  if (!deferredProviderSubmissionFailureId)
1585
1587
  return;
@@ -1659,7 +1661,7 @@ const AgentKitAssistantChatBody = forwardRef(function AgentKitAssistantChatBody(
1659
1661
  url,
1660
1662
  })),
1661
1663
  }),
1662
- isRunning: () => thread.activeRunIds.length > 0,
1664
+ isRunning: isThreadRunning,
1663
1665
  hasInFlightWork: () => Object.values(thread.tools).some((tool) => tool.status === "running") ||
1664
1666
  Object.values(thread.activities).some((activity) => activity.status === "running"),
1665
1667
  focusComposer: () => requestComposerFocus(threadId),
@@ -1787,6 +1789,7 @@ function AgentKitSelectionPill({ length, onClear, }) {
1787
1789
  }) }), _jsx("button", { type: "button", "aria-label": t("agentChat.selection.clear"), onClick: onClear, className: "flex h-4 w-4 items-center justify-center rounded text-muted-foreground hover:bg-accent/60 hover:text-foreground", children: _jsx(IconX, { size: 11, "aria-hidden": "true" }) })] }) }));
1788
1790
  }
1789
1791
  function AgentKitTranscript({ children, threadId }) {
1792
+ const { controller } = useAgentKit();
1790
1793
  const surface = useAgentKitSurface();
1791
1794
  const t = useT();
1792
1795
  const thread = useAgentThread(threadId);
@@ -1800,11 +1803,19 @@ function AgentKitTranscript({ children, threadId }) {
1800
1803
  browserTabId: surface.props.browserTabId,
1801
1804
  threadId,
1802
1805
  onSubmitMessage: async ({ message, context }) => {
1803
- await surface.onSubmit(appendAgentChatContextToMessage(message, context), [], [], { intent: surface.isRunning ? "queued" : "immediate" });
1806
+ await surface.onSubmit(appendAgentChatContextToMessage(message, context), [], [], {
1807
+ intent: hasActiveAgentRuns(controller.getThread(threadId))
1808
+ ? "queued"
1809
+ : "immediate",
1810
+ });
1804
1811
  return { delivered: true };
1805
1812
  },
1806
1813
  onSkipMessage: async ({ message, context }) => {
1807
- await surface.onSubmit(appendAgentChatContextToMessage(message, context), [], [], { intent: surface.isRunning ? "queued" : "immediate" });
1814
+ await surface.onSubmit(appendAgentChatContextToMessage(message, context), [], [], {
1815
+ intent: hasActiveAgentRuns(controller.getThread(threadId))
1816
+ ? "queued"
1817
+ : "immediate",
1818
+ });
1808
1819
  return { delivered: true };
1809
1820
  },
1810
1821
  });
@@ -2035,7 +2046,7 @@ function AgentKitMessageSupplement(props) {
2035
2046
  .join("\n");
2036
2047
  const integration = value.role === "assistant" &&
2037
2048
  value.status === "complete" &&
2038
- thread.activeRunIds.length === 0
2049
+ !hasActiveAgentRuns(thread)
2039
2050
  ? findMcpConnectionSuggestionIntegration({
2040
2051
  text,
2041
2052
  contextText,