@agent-native/core 0.210.1-nightly-20261020093350 → 0.210.1

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 (59) hide show
  1. package/dist/a2a/server.js +2 -1
  2. package/dist/agent/contain-principal.js +2 -3
  3. package/dist/agent/engine/ai-sdk-engine.js +29 -20
  4. package/dist/agent/engine/anthropic-engine.js +10 -1
  5. package/dist/agent/engine/builder-engine.js +28 -14
  6. package/dist/agent/engine/types.d.ts +11 -0
  7. package/dist/agent/engine/types.js +8 -0
  8. package/dist/agent/execution-fence.d.ts +5 -0
  9. package/dist/agent/execution-fence.js +15 -0
  10. package/dist/agent/harness/background.js +28 -7
  11. package/dist/agent/production-agent.d.ts +4 -3
  12. package/dist/agent/production-agent.js +20 -3
  13. package/dist/agent/run-manager.d.ts +9 -2
  14. package/dist/agent/run-manager.js +290 -43
  15. package/dist/agent/run-store.d.ts +3 -2
  16. package/dist/agent/run-store.fencing.worker.js +19 -1
  17. package/dist/agent/run-store.js +228 -68
  18. package/dist/chat-threads/schema-migrations.js +8 -0
  19. package/dist/chat-threads/store.d.ts +33 -0
  20. package/dist/chat-threads/store.js +151 -16
  21. package/dist/collab/routes.d.ts +1 -1
  22. package/dist/collab/struct-routes.d.ts +1 -1
  23. package/dist/db/schema-snapshot.generated.js +2 -1
  24. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  25. package/dist/localization/core-messages/supplemental/ar-SA.js +1 -0
  26. package/dist/localization/core-messages/supplemental/de-DE.js +1 -0
  27. package/dist/localization/core-messages/supplemental/en-US.js +1 -0
  28. package/dist/localization/core-messages/supplemental/es-ES.js +1 -0
  29. package/dist/localization/core-messages/supplemental/fr-FR.js +1 -0
  30. package/dist/localization/core-messages/supplemental/hi-IN.js +1 -0
  31. package/dist/localization/core-messages/supplemental/ja-JP.js +1 -0
  32. package/dist/localization/core-messages/supplemental/ko-KR.js +1 -0
  33. package/dist/localization/core-messages/supplemental/pt-BR.js +1 -0
  34. package/dist/localization/core-messages/supplemental/zh-CN.js +1 -0
  35. package/dist/localization/core-messages/supplemental/zh-TW.js +1 -0
  36. package/dist/localization/default-messages.d.ts +14 -0
  37. package/dist/localization/default-messages.js +15 -1
  38. package/dist/localization/mcp-settings-messages.d.ts +1 -0
  39. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  40. package/dist/mcp-client/actions/get-managed-mcp-oauth-readiness.d.ts +5 -0
  41. package/dist/mcp-client/actions/get-managed-mcp-oauth-readiness.js +17 -0
  42. package/dist/mcp-client/oauth-routes.d.ts +3 -0
  43. package/dist/mcp-client/oauth-routes.js +15 -4
  44. package/dist/notifications/routes.d.ts +3 -3
  45. package/dist/org/index.d.ts +1 -1
  46. package/dist/progress/routes.d.ts +1 -1
  47. package/dist/provider-api/actions/custom-provider-registration.d.ts +8 -8
  48. package/dist/provider-api/actions/provider-api.d.ts +10 -10
  49. package/dist/secrets/register-framework-secrets.js +25 -0
  50. package/dist/secrets/routes.d.ts +6 -6
  51. package/dist/server/action-discovery.js +6 -0
  52. package/dist/server/agent-chat-plugin.js +100 -16
  53. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  54. package/dist/server/agent-engine-default-model-route.d.ts +1 -1
  55. package/dist/server/agent-teams.d.ts +3 -0
  56. package/dist/server/agent-teams.js +192 -30
  57. package/dist/server/google-oauth.d.ts +4 -1
  58. package/dist/server/google-oauth.js +4 -2
  59. package/package.json +4 -4
@@ -1432,12 +1432,15 @@ function queuedSubmissionReceiptFromRow(row) {
1432
1432
  ...(typeof row.submitted_run_id === "string"
1433
1433
  ? { submittedRunId: row.submitted_run_id }
1434
1434
  : {}),
1435
+ ...(typeof row.interrupt_run_id === "string"
1436
+ ? { interruptRunId: row.interrupt_run_id }
1437
+ : {}),
1435
1438
  ...(row.retry_after != null ? { retryAfter: Number(row.retry_after) } : {}),
1436
1439
  createdAt: Number(row.created_at),
1437
1440
  updatedAt: Number(row.updated_at),
1438
1441
  };
1439
1442
  }
1440
- const QUEUED_SUBMISSION_COLUMNS = `thread_id, message_id, state, actor_email, actor_auth_user_id, actor_identity_authenticated_at_ms, actor_name, actor_org_id, actor_org_scope, actor_anonymous, payload_hash, payload_json, submitted_run_id, retry_after, created_at, updated_at`;
1443
+ const QUEUED_SUBMISSION_COLUMNS = `thread_id, message_id, state, actor_email, actor_auth_user_id, actor_identity_authenticated_at_ms, actor_name, actor_org_id, actor_org_scope, actor_anonymous, payload_hash, payload_json, submitted_run_id, interrupt_run_id, retry_after, created_at, updated_at`;
1441
1444
  async function readQueuedSubmissionReceipt(db, threadId, messageId, options = {}) {
1442
1445
  const { rows } = await db.execute({
1443
1446
  sql: `SELECT ${QUEUED_SUBMISSION_COLUMNS} FROM agent_chat_submission_inbox WHERE thread_id = ? AND message_id = ?${options.forUpdate ? " FOR UPDATE" : ""}`,
@@ -1522,7 +1525,7 @@ export async function markQueuedSubmissionSubmitted(tx, input) {
1522
1525
  throw new QueuedSubmissionAdmissionError("queued_message_id_terminal", messageId);
1523
1526
  }
1524
1527
  const update = await tx.execute({
1525
- sql: `UPDATE agent_chat_submission_inbox SET state = 'submitted', submitted_run_id = COALESCE(?, submitted_run_id), retry_after = NULL, updated_at = ? WHERE thread_id = ? AND message_id = ? AND state = 'queued'`,
1528
+ sql: `UPDATE agent_chat_submission_inbox SET state = 'submitted', submitted_run_id = COALESCE(?, submitted_run_id), interrupt_run_id = NULL, retry_after = NULL, updated_at = ? WHERE thread_id = ? AND message_id = ? AND state = 'queued'`,
1526
1529
  args: [runId ?? null, Date.now(), threadId, messageId],
1527
1530
  });
1528
1531
  if (update.rowsAffected > 0)
@@ -1593,6 +1596,34 @@ export async function blockQueuedSubmissionReceipt(threadId, messageId, options
1593
1596
  });
1594
1597
  return result?.receiptUpdated === true;
1595
1598
  }
1599
+ async function mutateQueuedSubmissionInterruptRun(input, operation) {
1600
+ const result = await mutateThreadQueuedMessages(input.threadId, {
1601
+ type: operation === "record" ? "recordInterruptRun" : "clearInterruptRun",
1602
+ messageId: input.messageId,
1603
+ runId: input.runId,
1604
+ claimId: input.claimId,
1605
+ });
1606
+ return result?.receiptUpdated === true;
1607
+ }
1608
+ /** Persist the active run before interrupting it so a later inbox claim can finish the abort. */
1609
+ export async function recordQueuedSubmissionInterruptRun(input) {
1610
+ return mutateQueuedSubmissionInterruptRun(input, "record");
1611
+ }
1612
+ /** Renews a live interruption claim before its recorded run is aborted. */
1613
+ export async function renewQueuedSubmissionInterruptClaim(input) {
1614
+ const result = await mutateThreadQueuedMessages(input.threadId, {
1615
+ type: "renewClaim",
1616
+ messageId: input.messageId,
1617
+ runId: input.runId,
1618
+ claimId: input.claimId,
1619
+ });
1620
+ return (result?.claimLost !== true &&
1621
+ result?.claimedMessage?.promotionClaim?.id === input.claimId);
1622
+ }
1623
+ /** Clear a recorded interruption only after its turn abort is durable. */
1624
+ export async function clearQueuedSubmissionInterruptRun(input) {
1625
+ return mutateQueuedSubmissionInterruptRun(input, "clear");
1626
+ }
1596
1627
  const QUEUED_MESSAGE_CLAIM_TTL_MS = 60_000;
1597
1628
  function receiptMutationOwnsPromotionClaim(message, claimId, now) {
1598
1629
  const claim = message?.promotionClaim;
@@ -1875,6 +1906,36 @@ export async function mutateThreadQueuedMessages(threadId, mutation, options = {
1875
1906
  }
1876
1907
  break;
1877
1908
  }
1909
+ case "recordInterruptRun":
1910
+ case "clearInterruptRun": {
1911
+ receiptClaimMessage = current.find((message) => message.id === mutation.messageId);
1912
+ if (!receiptMutationOwnsPromotionClaim(receiptClaimMessage, mutation.claimId, Date.now())) {
1913
+ response = { claimBusy: true };
1914
+ }
1915
+ break;
1916
+ }
1917
+ case "renewClaim": {
1918
+ const index = current.findIndex((message) => message.id === mutation.messageId);
1919
+ const message = index >= 0 ? current[index] : undefined;
1920
+ const now = Date.now();
1921
+ if (!message ||
1922
+ queuedSubmissionExpired(message, now) ||
1923
+ !receiptMutationOwnsPromotionClaim(message, mutation.claimId, now)) {
1924
+ response = { claimLost: true };
1925
+ break;
1926
+ }
1927
+ const claimedMessage = {
1928
+ ...message,
1929
+ promotionClaim: {
1930
+ id: mutation.claimId,
1931
+ expiresAt: now + QUEUED_MESSAGE_CLAIM_TTL_MS,
1932
+ },
1933
+ };
1934
+ queuedMessages = [...current];
1935
+ queuedMessages[index] = claimedMessage;
1936
+ response = { claimedMessage };
1937
+ break;
1938
+ }
1878
1939
  case "release": {
1879
1940
  const index = current.findIndex((message) => message.id === mutation.messageId);
1880
1941
  const message = current[index];
@@ -1902,19 +1963,93 @@ export async function mutateThreadQueuedMessages(threadId, mutation, options = {
1902
1963
  }
1903
1964
  return true;
1904
1965
  }
1905
- : mutation.type === "retryReceipt" ||
1906
- mutation.type === "blockReceipt"
1907
- ? async () => {
1908
- const ownsClaim = receiptMutationOwnsPromotionClaim(receiptClaimMessage, mutation.claimId, Date.now());
1909
- if (!ownsClaim && result)
1910
- result.claimBusy = true;
1911
- return ownsClaim;
1966
+ : mutation.type === "renewClaim"
1967
+ ? async (tx) => {
1968
+ const receipt = await readQueuedSubmissionReceipt(tx, threadId, mutation.messageId);
1969
+ if (result?.claimLost === true ||
1970
+ receipt?.state !== "queued" ||
1971
+ receipt.interruptRunId !== mutation.runId) {
1972
+ if (result) {
1973
+ result.claimLost = true;
1974
+ result.claimedMessage = undefined;
1975
+ }
1976
+ return false;
1977
+ }
1978
+ return true;
1912
1979
  }
1913
- : undefined,
1980
+ : mutation.type === "recordInterruptRun" ||
1981
+ mutation.type === "clearInterruptRun"
1982
+ ? async (tx) => {
1983
+ const ownsClaim = receiptMutationOwnsPromotionClaim(receiptClaimMessage, mutation.claimId, Date.now());
1984
+ if (!ownsClaim) {
1985
+ if (result)
1986
+ result.claimBusy = true;
1987
+ return false;
1988
+ }
1989
+ const receipt = await readQueuedSubmissionReceipt(tx, threadId, mutation.messageId);
1990
+ return (receipt?.state === "queued" &&
1991
+ (!receipt.interruptRunId ||
1992
+ receipt.interruptRunId === mutation.runId));
1993
+ }
1994
+ : mutation.type === "retryReceipt" ||
1995
+ mutation.type === "blockReceipt"
1996
+ ? async () => {
1997
+ const ownsClaim = receiptMutationOwnsPromotionClaim(receiptClaimMessage, mutation.claimId, Date.now());
1998
+ if (!ownsClaim && result)
1999
+ result.claimBusy = true;
2000
+ return ownsClaim;
2001
+ }
2002
+ : undefined,
1914
2003
  afterUpdate: async (tx) => {
1915
2004
  if (!result)
1916
2005
  return;
1917
- if (mutation.type === "retryReceipt" ||
2006
+ if (mutation.type === "recordInterruptRun" ||
2007
+ mutation.type === "clearInterruptRun") {
2008
+ const receipt = await readQueuedSubmissionReceipt(tx, threadId, mutation.messageId, { forUpdate: true });
2009
+ if (!receipt || receipt.state !== "queued") {
2010
+ result.receiptUpdated = false;
2011
+ return;
2012
+ }
2013
+ if (mutation.type === "recordInterruptRun") {
2014
+ if (receipt.interruptRunId &&
2015
+ receipt.interruptRunId !== mutation.runId) {
2016
+ result.receiptUpdated = false;
2017
+ return;
2018
+ }
2019
+ const updated = await tx.execute({
2020
+ sql: `UPDATE agent_chat_submission_inbox
2021
+ SET interrupt_run_id = ?, updated_at = ?
2022
+ WHERE thread_id = ? AND message_id = ? AND state = 'queued'
2023
+ AND (interrupt_run_id IS NULL OR interrupt_run_id = ?)`,
2024
+ args: [
2025
+ mutation.runId,
2026
+ Date.now(),
2027
+ threadId,
2028
+ mutation.messageId,
2029
+ mutation.runId,
2030
+ ],
2031
+ });
2032
+ result.receiptUpdated = updated.rowsAffected === 1;
2033
+ return;
2034
+ }
2035
+ if (!receipt.interruptRunId) {
2036
+ result.receiptUpdated = true;
2037
+ return;
2038
+ }
2039
+ if (receipt.interruptRunId !== mutation.runId) {
2040
+ result.receiptUpdated = false;
2041
+ return;
2042
+ }
2043
+ const updated = await tx.execute({
2044
+ sql: `UPDATE agent_chat_submission_inbox
2045
+ SET interrupt_run_id = NULL, updated_at = ?
2046
+ WHERE thread_id = ? AND message_id = ? AND state = 'queued'
2047
+ AND interrupt_run_id = ?`,
2048
+ args: [Date.now(), threadId, mutation.messageId, mutation.runId],
2049
+ });
2050
+ result.receiptUpdated = updated.rowsAffected === 1;
2051
+ }
2052
+ else if (mutation.type === "retryReceipt" ||
1918
2053
  mutation.type === "blockReceipt") {
1919
2054
  if (!receiptMutationOwnsPromotionClaim(receiptClaimMessage, mutation.claimId, Date.now())) {
1920
2055
  result.claimBusy = true;
@@ -1931,7 +2066,7 @@ export async function mutateThreadQueuedMessages(threadId, mutation, options = {
1931
2066
  ],
1932
2067
  })
1933
2068
  : await tx.execute({
1934
- sql: `UPDATE agent_chat_submission_inbox SET state = 'blocked', retry_after = NULL, updated_at = ? WHERE thread_id = ? AND message_id = ? AND state = 'queued'`,
2069
+ sql: `UPDATE agent_chat_submission_inbox SET state = 'blocked', interrupt_run_id = NULL, retry_after = NULL, updated_at = ? WHERE thread_id = ? AND message_id = ? AND state = 'queued'`,
1935
2070
  args: [Date.now(), threadId, mutation.messageId],
1936
2071
  });
1937
2072
  result.receiptUpdated = updated.rowsAffected === 1;
@@ -2010,7 +2145,7 @@ export async function mutateThreadQueuedMessages(threadId, mutation, options = {
2010
2145
  }
2011
2146
  if (mutation.type === "remove" && !result.promotionBusy) {
2012
2147
  await tx.execute({
2013
- sql: `UPDATE agent_chat_submission_inbox SET state = ?, retry_after = NULL, updated_at = ? WHERE thread_id = ? AND message_id = ? AND state = 'queued'`,
2148
+ sql: `UPDATE agent_chat_submission_inbox SET state = ?, interrupt_run_id = NULL, retry_after = NULL, updated_at = ? WHERE thread_id = ? AND message_id = ? AND state = 'queued'`,
2014
2149
  args: [
2015
2150
  removedReceiptState,
2016
2151
  Date.now(),
@@ -2021,7 +2156,7 @@ export async function mutateThreadQueuedMessages(threadId, mutation, options = {
2021
2156
  }
2022
2157
  else if (mutation.type === "claim" && result.submissionExpired) {
2023
2158
  await tx.execute({
2024
- sql: `UPDATE agent_chat_submission_inbox SET state = 'expired', retry_after = NULL, updated_at = ? WHERE thread_id = ? AND message_id = ? AND state = 'queued'`,
2159
+ sql: `UPDATE agent_chat_submission_inbox SET state = 'expired', interrupt_run_id = NULL, retry_after = NULL, updated_at = ? WHERE thread_id = ? AND message_id = ? AND state = 'queued'`,
2025
2160
  args: [Date.now(), threadId, mutation.messageId],
2026
2161
  });
2027
2162
  }
@@ -2030,7 +2165,7 @@ export async function mutateThreadQueuedMessages(threadId, mutation, options = {
2030
2165
  assertQueuedSubmissionReceiptSnapshotMatches(currentReceipt, mutation.receipt);
2031
2166
  if (result.receiptConflict) {
2032
2167
  const blocked = await tx.execute({
2033
- sql: `UPDATE agent_chat_submission_inbox SET state = 'blocked', retry_after = NULL, updated_at = ? WHERE thread_id = ? AND message_id = ? AND state = 'queued'`,
2168
+ sql: `UPDATE agent_chat_submission_inbox SET state = 'blocked', interrupt_run_id = NULL, retry_after = NULL, updated_at = ? WHERE thread_id = ? AND message_id = ? AND state = 'queued'`,
2034
2169
  args: [Date.now(), threadId, mutation.receipt.messageId],
2035
2170
  });
2036
2171
  if (blocked.rowsAffected !== 1) {
@@ -2040,7 +2175,7 @@ export async function mutateThreadQueuedMessages(threadId, mutation, options = {
2040
2175
  }
2041
2176
  else if (result.submissionExpired) {
2042
2177
  const expired = await tx.execute({
2043
- sql: `UPDATE agent_chat_submission_inbox SET state = 'expired', retry_after = NULL, updated_at = ? WHERE thread_id = ? AND message_id = ? AND state = 'queued'`,
2178
+ sql: `UPDATE agent_chat_submission_inbox SET state = 'expired', interrupt_run_id = NULL, retry_after = NULL, updated_at = ? WHERE thread_id = ? AND message_id = ? AND state = 'queued'`,
2044
2179
  args: [Date.now(), threadId, mutation.receipt.messageId],
2045
2180
  });
2046
2181
  if (expired.rowsAffected !== 1) {
@@ -21,8 +21,8 @@ export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import
21
21
  }>>;
22
22
  export declare const postCollabText: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
23
23
  ok?: undefined;
24
- text?: undefined;
25
24
  error: string;
25
+ text?: undefined;
26
26
  } | {
27
27
  error?: undefined;
28
28
  ok: boolean;
@@ -1,6 +1,6 @@
1
1
  export declare const postCollabJson: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
2
- ok?: undefined;
3
2
  error: string;
3
+ ok?: undefined;
4
4
  } | {
5
5
  error?: undefined;
6
6
  ok: boolean;
@@ -17,7 +17,7 @@ export const SCHEMA_SNAPSHOT = {
17
17
  'CREATE TABLE "a2a_tasks" (\n "id" text NOT NULL,\n "context_id" text,\n "status_state" text DEFAULT \'submitted\'::text NOT NULL,\n "status_message" text,\n "status_timestamp" text NOT NULL,\n "history" text DEFAULT \'[]\'::text NOT NULL,\n "artifacts" text DEFAULT \'[]\'::text NOT NULL,\n "metadata" text,\n "owner_email" text,\n "owner_scope" text DEFAULT \'\'::text NOT NULL,\n "idempotency_key" text,\n "created_at" bigint NOT NULL,\n "updated_at" bigint NOT NULL\n);',
18
18
  'CREATE TABLE "account" (\n "id" text NOT NULL,\n "account_id" text NOT NULL,\n "provider_id" text NOT NULL,\n "user_id" text NOT NULL,\n "access_token" text,\n "refresh_token" text,\n "id_token" text,\n "access_token_expires_at" timestamp with time zone,\n "refresh_token_expires_at" timestamp with time zone,\n "scope" text,\n "password" text,\n "created_at" timestamp with time zone NOT NULL,\n "updated_at" timestamp with time zone NOT NULL\n);',
19
19
  'CREATE TABLE "agent_audit_log" (\n "id" text NOT NULL,\n "created_at" bigint NOT NULL,\n "action" text NOT NULL,\n "caller" text NOT NULL,\n "actor_kind" text NOT NULL,\n "actor_email" text,\n "org_id" text,\n "thread_id" text,\n "turn_id" text,\n "target_type" text,\n "target_id" text,\n "status" text DEFAULT \'success\'::text NOT NULL,\n "summary" text,\n "input" text,\n "error_code" text,\n "owner_email" text,\n "visibility" text DEFAULT \'private\'::text NOT NULL,\n "run_id" text,\n "task_id" text,\n "parent_task_id" text,\n "source_kind" text,\n "source_platform" text,\n "source_id" text,\n "source_url" text,\n "network_protocol" text,\n "network_id" text,\n "network_peer" text,\n "app" text,\n "reported_client_name" text,\n "reported_client_version" text,\n "oauth_client_id" text,\n "approval" text\n);',
20
- 'CREATE TABLE "agent_chat_submission_inbox" (\n "thread_id" text NOT NULL,\n "message_id" text NOT NULL,\n "state" text NOT NULL,\n "actor_email" text NOT NULL,\n "actor_auth_user_id" text,\n "actor_identity_authenticated_at_ms" bigint,\n "actor_name" text,\n "actor_org_id" text,\n "actor_org_scope" text,\n "actor_anonymous" boolean DEFAULT false NOT NULL,\n "payload_hash" text NOT NULL,\n "payload_json" text NOT NULL,\n "interrupt_active_run" boolean DEFAULT false NOT NULL,\n "submitted_run_id" text,\n "queue_order" bigint DEFAULT nextval(\'agent_chat_submission_inbox_queue_order_seq\'::regclass) NOT NULL,\n "move_to_top_at" bigint,\n "retry_after" bigint,\n "created_at" bigint NOT NULL,\n "updated_at" bigint NOT NULL\n);',
20
+ 'CREATE TABLE "agent_chat_submission_inbox" (\n "thread_id" text NOT NULL,\n "message_id" text NOT NULL,\n "state" text NOT NULL,\n "actor_email" text NOT NULL,\n "actor_auth_user_id" text,\n "actor_identity_authenticated_at_ms" bigint,\n "actor_name" text,\n "actor_org_id" text,\n "actor_org_scope" text,\n "actor_anonymous" boolean DEFAULT false NOT NULL,\n "payload_hash" text NOT NULL,\n "payload_json" text NOT NULL,\n "interrupt_active_run" boolean DEFAULT false NOT NULL,\n "submitted_run_id" text,\n "queue_order" bigint DEFAULT nextval(\'agent_chat_submission_inbox_queue_order_seq\'::regclass) NOT NULL,\n "move_to_top_at" bigint,\n "retry_after" bigint,\n "created_at" bigint NOT NULL,\n "updated_at" bigint NOT NULL,\n "interrupt_run_id" text\n);',
21
21
  'CREATE TABLE "agent_checkpoints" (\n "id" text NOT NULL,\n "thread_id" text NOT NULL,\n "run_id" text,\n "commit_sha" text NOT NULL,\n "message" text DEFAULT \'\'::text NOT NULL,\n "created_at" bigint NOT NULL\n);',
22
22
  'CREATE TABLE "agent_eval_datasets" (\n "id" text NOT NULL,\n "name" text NOT NULL,\n "description" text DEFAULT \'\'::text NOT NULL,\n "entries" text DEFAULT \'[]\'::text NOT NULL,\n "created_at" bigint NOT NULL,\n "updated_at" bigint NOT NULL,\n "user_id" text,\n "idempotency_key" text\n);',
23
23
  'CREATE TABLE "agent_evals" (\n "id" text NOT NULL,\n "run_id" text NOT NULL,\n "thread_id" text,\n "user_id" text,\n "eval_type" text NOT NULL,\n "criteria" text NOT NULL,\n "score" real DEFAULT 0 NOT NULL,\n "reasoning" text,\n "metadata" text,\n "created_at" bigint NOT NULL\n);',
@@ -946,6 +946,7 @@ export const SCHEMA_SNAPSHOT = {
946
946
  "chat-thread-durable-submission-inbox",
947
947
  "953882e24b68e4fb",
948
948
  ],
949
+ ["chat_threads", "chat-thread-inbox-interrupt-replay", "904890f43aebd9fe"],
949
950
  ["chat_threads", "chat-thread-shares-notified-at", "f2a3dce63fe66310"],
950
951
  ["chat_threads", "chat-threads-base-tables", "bfeaaa8ca4af1288"],
951
952
  [
@@ -33,9 +33,9 @@ declare const _default: import("../../action.js").ActionDefinition<{
33
33
  idempotencyKey: string;
34
34
  deleted: boolean;
35
35
  } | {
36
+ id?: undefined;
36
37
  error: string;
37
38
  url?: undefined;
38
- id?: undefined;
39
39
  provider?: undefined;
40
40
  configured?: undefined;
41
41
  } | {
@@ -45,8 +45,8 @@ declare const _default: import("../../action.js").ActionDefinition<{
45
45
  configured?: undefined;
46
46
  error?: undefined;
47
47
  } | {
48
- url?: undefined;
49
48
  id?: undefined;
49
+ url?: undefined;
50
50
  provider?: undefined;
51
51
  error: string;
52
52
  configured: boolean;
@@ -89,6 +89,7 @@ export const mcpSettingsMessages = {
89
89
  mcpOpenConnectPage: "فتح صفحة الاتصال الكاملة",
90
90
  mcpIdentityError: "تعذّر تحميل تفاصيل الاتصال لهذا التطبيق.",
91
91
  mcpRetry: "إعادة المحاولة",
92
+ mcpOAuthBackToApp: "العودة إلى التطبيق",
92
93
  mcpConnect: mcpConnectMessages,
93
94
  };
94
95
  export const privacySettingsMessages = {
@@ -89,6 +89,7 @@ export const mcpSettingsMessages = {
89
89
  mcpOpenConnectPage: "Vollständige Verbindungsseite öffnen",
90
90
  mcpIdentityError: "Die Verbindungsdetails dieser App konnten nicht geladen werden.",
91
91
  mcpRetry: "Erneut versuchen",
92
+ mcpOAuthBackToApp: "Zurück zur App",
92
93
  mcpConnect: mcpConnectMessages,
93
94
  };
94
95
  export const privacySettingsMessages = {
@@ -89,6 +89,7 @@ export const mcpSettingsMessages = {
89
89
  mcpOpenConnectPage: "Open full connect page",
90
90
  mcpIdentityError: "Couldn't load this app's connection details.",
91
91
  mcpRetry: "Try again",
92
+ mcpOAuthBackToApp: "Back to app",
92
93
  mcpConnect: mcpConnectMessages,
93
94
  };
94
95
  export const privacySettingsMessages = {
@@ -89,6 +89,7 @@ export const mcpSettingsMessages = {
89
89
  mcpOpenConnectPage: "Abrir página completa de conexión",
90
90
  mcpIdentityError: "No se pudieron cargar los datos de conexión de esta app.",
91
91
  mcpRetry: "Reintentar",
92
+ mcpOAuthBackToApp: "Volver a la app",
92
93
  mcpConnect: mcpConnectMessages,
93
94
  };
94
95
  export const privacySettingsMessages = {
@@ -89,6 +89,7 @@ export const mcpSettingsMessages = {
89
89
  mcpOpenConnectPage: "Ouvrir la page complète de connexion",
90
90
  mcpIdentityError: "Impossible de charger les informations de connexion de cette app.",
91
91
  mcpRetry: "Réessayer",
92
+ mcpOAuthBackToApp: "Retour à l’application",
92
93
  mcpConnect: mcpConnectMessages,
93
94
  };
94
95
  export const privacySettingsMessages = {
@@ -89,6 +89,7 @@ export const mcpSettingsMessages = {
89
89
  mcpOpenConnectPage: "पूरी कनेक्शन पेज खोलें",
90
90
  mcpIdentityError: "इस ऐप की कनेक्शन जानकारी लोड नहीं हो सकी।",
91
91
  mcpRetry: "फिर से कोशिश करें",
92
+ mcpOAuthBackToApp: "ऐप पर वापस जाएँ",
92
93
  mcpConnect: mcpConnectMessages,
93
94
  };
94
95
  export const privacySettingsMessages = {
@@ -89,6 +89,7 @@ export const mcpSettingsMessages = {
89
89
  mcpOpenConnectPage: "完全な接続ページを開く",
90
90
  mcpIdentityError: "このアプリの接続情報を読み込めませんでした。",
91
91
  mcpRetry: "再試行",
92
+ mcpOAuthBackToApp: "アプリに戻る",
92
93
  mcpConnect: mcpConnectMessages,
93
94
  };
94
95
  export const privacySettingsMessages = {
@@ -89,6 +89,7 @@ export const mcpSettingsMessages = {
89
89
  mcpOpenConnectPage: "전체 연결 페이지 열기",
90
90
  mcpIdentityError: "이 앱의 연결 정보를 불러오지 못했습니다.",
91
91
  mcpRetry: "다시 시도",
92
+ mcpOAuthBackToApp: "앱으로 돌아가기",
92
93
  mcpConnect: mcpConnectMessages,
93
94
  };
94
95
  export const privacySettingsMessages = {
@@ -89,6 +89,7 @@ export const mcpSettingsMessages = {
89
89
  mcpOpenConnectPage: "Abrir página completa de conexão",
90
90
  mcpIdentityError: "Não foi possível carregar os dados de conexão deste app.",
91
91
  mcpRetry: "Tentar novamente",
92
+ mcpOAuthBackToApp: "Voltar ao app",
92
93
  mcpConnect: mcpConnectMessages,
93
94
  };
94
95
  export const privacySettingsMessages = {
@@ -89,6 +89,7 @@ export const mcpSettingsMessages = {
89
89
  mcpOpenConnectPage: "打开完整连接页面",
90
90
  mcpIdentityError: "无法加载此应用的连接信息。",
91
91
  mcpRetry: "重试",
92
+ mcpOAuthBackToApp: "返回应用",
92
93
  mcpConnect: mcpConnectMessages,
93
94
  };
94
95
  export const privacySettingsMessages = {
@@ -89,6 +89,7 @@ export const mcpSettingsMessages = {
89
89
  mcpOpenConnectPage: "開啟完整連線頁面",
90
90
  mcpIdentityError: "無法載入此應用程式的連線資訊。",
91
91
  mcpRetry: "重試",
92
+ mcpOAuthBackToApp: "返回應用程式",
92
93
  mcpConnect: mcpConnectMessages,
93
94
  };
94
95
  export const privacySettingsMessages = {
@@ -1454,6 +1454,20 @@ declare const messages: {
1454
1454
  providerSetupFormDescription: string;
1455
1455
  continueToConnect: string;
1456
1456
  setupTitle: string;
1457
+ hubspot: {
1458
+ setupTitle: string;
1459
+ dialogDescription: string;
1460
+ workspaceSetupStatus: string;
1461
+ setupChecking: string;
1462
+ setupUnavailable: string;
1463
+ setupUnavailableDescription: string;
1464
+ ownerSetupDescription: string;
1465
+ memberSetupDescription: string;
1466
+ noWorkspaceDescription: string;
1467
+ configureWorkspaceCredentials: string;
1468
+ refreshSetupStatus: string;
1469
+ retrySetupStatus: string;
1470
+ };
1457
1471
  personal: string;
1458
1472
  personalConnection: string;
1459
1473
  organization: string;
@@ -1378,6 +1378,20 @@ const messages = {
1378
1378
  providerSetupFormDescription: "Complete provider setup before connecting your account.",
1379
1379
  continueToConnect: "Connect my account",
1380
1380
  setupTitle: "Connect {{name}}",
1381
+ hubspot: {
1382
+ setupTitle: "Set up HubSpot MCP",
1383
+ dialogDescription: "A workspace owner configures HubSpot MCP once. Each member then connects their own account.",
1384
+ workspaceSetupStatus: "Workspace setup required",
1385
+ setupChecking: "Checking workspace setup…",
1386
+ setupUnavailable: "Setup status unavailable",
1387
+ setupUnavailableDescription: "Couldn't check the workspace OAuth settings. Try again.",
1388
+ ownerSetupDescription: "Create a HubSpot MCP Auth App, then add its client ID and secret in Agent-Native settings → API keys.",
1389
+ memberSetupDescription: "Ask a workspace owner to create a HubSpot MCP Auth App and add its client ID and secret in Agent-Native settings → API keys. You can connect your own HubSpot account after setup.",
1390
+ noWorkspaceDescription: "Join a workspace before connecting HubSpot MCP.",
1391
+ configureWorkspaceCredentials: "Add workspace credentials",
1392
+ refreshSetupStatus: "Check again",
1393
+ retrySetupStatus: "Retry",
1394
+ },
1381
1395
  personal: "Personal",
1382
1396
  personalConnection: "Personal connection",
1383
1397
  organization: "Organization",
@@ -1540,7 +1554,7 @@ const messages = {
1540
1554
  hubspot: {
1541
1555
  description: "Search and update HubSpot CRM records through its integration.",
1542
1556
  useCase: "CRM, contacts, companies, deals, tickets, customer analytics",
1543
- setupNote: "When a workspace-managed HubSpot MCP Auth App is configured, any member can connect a personal HubSpot account with OAuth and PKCE. Otherwise, create the app in the HubSpot Developer Platform before connecting; the existing HubSpot OAuth connector remains available to app actions.",
1557
+ setupNote: "Each person connects their own HubSpot account after a workspace owner configures the HubSpot MCP Auth App.",
1544
1558
  },
1545
1559
  pylon: {
1546
1560
  description: "Search and update Pylon support data.",
@@ -77,6 +77,7 @@ export interface McpSettingsMessages {
77
77
  mcpOpenConnectPage: string;
78
78
  mcpIdentityError: string;
79
79
  mcpRetry: string;
80
+ mcpOAuthBackToApp: string;
80
81
  mcpConnect: McpConnectMessages;
81
82
  }
82
83
  export declare const MCP_SETTINGS_MESSAGES: Record<BuiltinLocaleCode, McpSettingsMessages>;
@@ -140,13 +140,13 @@ export declare function screenMemoryMcpToolDefinitions(): ({
140
140
  clientHint?: undefined;
141
141
  timestamp?: undefined;
142
142
  chapterId?: undefined;
143
- count?: undefined;
144
143
  startAt?: undefined;
145
144
  endAt?: undefined;
146
145
  reason?: undefined;
147
146
  includeMicrophone?: undefined;
148
147
  includeSystemAudio?: undefined;
149
148
  requestId?: undefined;
149
+ count?: undefined;
150
150
  };
151
151
  required?: undefined;
152
152
  };
@@ -171,13 +171,13 @@ export declare function screenMemoryMcpToolDefinitions(): ({
171
171
  clientHint?: undefined;
172
172
  timestamp?: undefined;
173
173
  chapterId?: undefined;
174
- count?: undefined;
175
174
  startAt?: undefined;
176
175
  endAt?: undefined;
177
176
  reason?: undefined;
178
177
  includeMicrophone?: undefined;
179
178
  includeSystemAudio?: undefined;
180
179
  requestId?: undefined;
180
+ count?: undefined;
181
181
  };
182
182
  required?: undefined;
183
183
  };
@@ -196,13 +196,13 @@ export declare function screenMemoryMcpToolDefinitions(): ({
196
196
  clientHint?: undefined;
197
197
  timestamp?: undefined;
198
198
  chapterId?: undefined;
199
- count?: undefined;
200
199
  startAt?: undefined;
201
200
  endAt?: undefined;
202
201
  reason?: undefined;
203
202
  includeMicrophone?: undefined;
204
203
  includeSystemAudio?: undefined;
205
204
  requestId?: undefined;
205
+ count?: undefined;
206
206
  };
207
207
  required?: undefined;
208
208
  };
@@ -231,13 +231,13 @@ export declare function screenMemoryMcpToolDefinitions(): ({
231
231
  };
232
232
  timestamp?: undefined;
233
233
  chapterId?: undefined;
234
- count?: undefined;
235
234
  startAt?: undefined;
236
235
  endAt?: undefined;
237
236
  reason?: undefined;
238
237
  includeMicrophone?: undefined;
239
238
  includeSystemAudio?: undefined;
240
239
  requestId?: undefined;
240
+ count?: undefined;
241
241
  };
242
242
  };
243
243
  } | {
@@ -260,12 +260,12 @@ export declare function screenMemoryMcpToolDefinitions(): ({
260
260
  description: string;
261
261
  };
262
262
  chapterId?: undefined;
263
- count?: undefined;
264
263
  startAt?: undefined;
265
264
  endAt?: undefined;
266
265
  includeMicrophone?: undefined;
267
266
  includeSystemAudio?: undefined;
268
267
  requestId?: undefined;
268
+ count?: undefined;
269
269
  };
270
270
  };
271
271
  } | {
@@ -317,7 +317,6 @@ export declare function screenMemoryMcpToolDefinitions(): ({
317
317
  clientHint?: undefined;
318
318
  timestamp?: undefined;
319
319
  chapterId?: undefined;
320
- count?: undefined;
321
320
  startAt: {
322
321
  type: string;
323
322
  description: string;
@@ -337,6 +336,7 @@ export declare function screenMemoryMcpToolDefinitions(): ({
337
336
  type: string;
338
337
  };
339
338
  requestId?: undefined;
339
+ count?: undefined;
340
340
  };
341
341
  };
342
342
  } | {
@@ -352,7 +352,6 @@ export declare function screenMemoryMcpToolDefinitions(): ({
352
352
  clientHint?: undefined;
353
353
  timestamp?: undefined;
354
354
  chapterId?: undefined;
355
- count?: undefined;
356
355
  startAt?: undefined;
357
356
  endAt?: undefined;
358
357
  reason?: undefined;
@@ -361,6 +360,7 @@ export declare function screenMemoryMcpToolDefinitions(): ({
361
360
  requestId: {
362
361
  type: string;
363
362
  };
363
+ count?: undefined;
364
364
  };
365
365
  };
366
366
  })[];
@@ -0,0 +1,5 @@
1
+ export type ManagedMcpOAuthReadiness = {
2
+ hubspot: "configured" | "missing";
3
+ };
4
+ declare const _default: import("../../action.js").ActionDefinition<Record<string, never>, ManagedMcpOAuthReadiness>;
5
+ export default _default;
@@ -0,0 +1,17 @@
1
+ import { z } from "zod";
2
+ import { defineAction, fail } from "../../action.js";
3
+ import { resolveManagedMcpOAuthClient } from "../oauth-routes.js";
4
+ export default defineAction({
5
+ description: "Check whether the workspace has the managed HubSpot MCP OAuth client configured. Returns status only; never returns credential values.",
6
+ schema: z.object({}),
7
+ http: { method: "GET" },
8
+ agentTool: false,
9
+ toolCallable: false,
10
+ run: async (_args, ctx) => {
11
+ if (!ctx?.userEmail || !ctx.requestHeaders) {
12
+ fail("Not authenticated.", { statusCode: 401 });
13
+ }
14
+ const client = await resolveManagedMcpOAuthClient(new URL("https://mcp.hubspot.com"));
15
+ return { hubspot: client ? "configured" : "missing" };
16
+ },
17
+ });
@@ -57,6 +57,9 @@ export declare function resolveMcpOAuthStartError(error: unknown): {
57
57
  export declare function mcpOAuthStartFailureResponse(event: H3Event, failure: {
58
58
  status: number;
59
59
  body: McpOAuthStartErrorBody;
60
+ }, htmlOptions?: {
61
+ backHref?: string;
62
+ backLabel?: string;
60
63
  }): Response | Record<string, unknown>;
61
64
  export declare function wantsHtmlResponse(event: H3Event): boolean;
62
65
  export declare function resolveMcpOAuthScope(serverUrl: URL, requestedScope: unknown, options?: {