@agent-native/core 0.207.0 → 0.207.1-nightly-20261011212936

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 (40) hide show
  1. package/dist/agent/thread-data-builder.d.ts +1 -0
  2. package/dist/agent/thread-data-builder.js +220 -45
  3. package/dist/automation/index.d.ts +1 -1
  4. package/dist/chat-threads/store.d.ts +1 -0
  5. package/dist/chat-threads/store.js +1 -0
  6. package/dist/cli/connect.d.ts +1 -0
  7. package/dist/cli/connect.js +8 -3
  8. package/dist/client/chat/agentkit-agent-native.js +133 -54
  9. package/dist/client/chat/runtime.js +61 -2
  10. package/dist/client/onboarding/first-run-status.js +0 -4
  11. package/dist/collab/routes.d.ts +1 -1
  12. package/dist/collab/struct-routes.d.ts +1 -1
  13. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  14. package/dist/mcp/agent-connected.d.ts +13 -0
  15. package/dist/mcp/agent-connected.js +63 -0
  16. package/dist/mcp/connect-app-label.d.ts +11 -0
  17. package/dist/mcp/connect-app-label.js +33 -0
  18. package/dist/mcp/connect-route.js +41 -33
  19. package/dist/mcp/connect-store.d.ts +6 -1
  20. package/dist/mcp/connect-store.js +10 -2
  21. package/dist/mcp/oauth-route.js +17 -5
  22. package/dist/mcp/oauth-store.d.ts +2 -0
  23. package/dist/mcp/oauth-store.js +5 -1
  24. package/dist/notifications/routes.d.ts +1 -1
  25. package/dist/org/index.d.ts +2 -2
  26. package/dist/progress/routes.d.ts +1 -1
  27. package/dist/provider-api/actions/custom-provider-registration.d.ts +9 -9
  28. package/dist/provider-api/actions/provider-api.d.ts +11 -11
  29. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  30. package/dist/server/agent-chat-plugin.js +1 -1
  31. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  32. package/dist/server/agent-engine-default-model-route.d.ts +2 -2
  33. package/dist/server/realtime-token.d.ts +1 -1
  34. package/dist/server/transcribe-voice.d.ts +1 -1
  35. package/dist/shared/mcp-connect-content.d.ts +1 -0
  36. package/dist/shared/mcp-connect-content.js +3 -0
  37. package/dist/sharing/actions/list-resource-shares.d.ts +1 -1
  38. package/dist/tracking/registry.d.ts +1 -0
  39. package/dist/tracking/registry.js +1 -1
  40. package/package.json +4 -4
@@ -105,6 +105,7 @@ export interface MergeThreadDataOptions {
105
105
  preserveExistingQueuedMessages?: boolean;
106
106
  preserveExistingTopLevelKeys?: boolean;
107
107
  onAnnotationConflict?: (conflict: ThreadAnnotationSnapshotConflict) => void;
108
+ trustedRunSequenceResetIds?: ReadonlySet<string>;
108
109
  }
109
110
  export interface ThreadAnnotationSnapshotConflict {
110
111
  messageId: string;
@@ -1582,13 +1582,18 @@ export function foldThreadRunSuggestions(repo, run) {
1582
1582
  ? previous.runs
1583
1583
  : [];
1584
1584
  const oldRun = runs.find((entry) => entry.id === run.runId);
1585
- const previousSequence = oldRun &&
1586
- Number.isSafeInteger(oldRun.lastSequence) &&
1587
- oldRun.lastSequence >= 0
1588
- ? oldRun.lastSequence
1589
- : 0;
1590
- // Runtime event sequence numbers and AgentKit protocol cursors are separate.
1591
- const lastSequence = previousSequence;
1585
+ const committedSnapshots = previous._eventRunSnapshotCommits?.[run.runId];
1586
+ const protocolSequences = [
1587
+ previous._eventRunWatermarks?.[run.runId],
1588
+ ...(Array.isArray(committedSnapshots)
1589
+ ? committedSnapshots.map((snapshot) => snapshot?.lastSequence)
1590
+ : []),
1591
+ ];
1592
+ const lastSequence = protocolSequences.reduce((maximum, sequence) => typeof sequence === "number" &&
1593
+ Number.isSafeInteger(sequence) &&
1594
+ sequence >= 0
1595
+ ? Math.max(maximum, sequence)
1596
+ : maximum, 0);
1592
1597
  const snapshot = {
1593
1598
  ...oldRun,
1594
1599
  id: run.runId,
@@ -1653,6 +1658,7 @@ function mergeAgentKitEvents(existing, incoming, replacedRunIds = new Set(), sta
1653
1658
  Number.isFinite(merged[index].sequence)
1654
1659
  ? merged[index].sequence
1655
1660
  : Number.NaN,
1661
+ sequenceEnd: getAgentKitEventSequenceEnd(merged[index]),
1656
1662
  }));
1657
1663
  runEvents.sort((left, right) => {
1658
1664
  if (Number.isFinite(left.sequence) &&
@@ -1662,12 +1668,142 @@ function mergeAgentKitEvents(existing, incoming, replacedRunIds = new Set(), sta
1662
1668
  }
1663
1669
  return left.order - right.order;
1664
1670
  });
1665
- runPositions.forEach((index, order) => {
1666
- merged[index] = { ...runEvents[order].event, sequence: order + 1 };
1667
- });
1671
+ let nextSequence = 1;
1672
+ for (const [order, { event, sequenceEnd, sequence },] of runEvents.entries()) {
1673
+ const index = runPositions[order];
1674
+ if (index === undefined)
1675
+ continue;
1676
+ const span = Number.isSafeInteger(sequenceEnd) &&
1677
+ Number.isSafeInteger(sequence) &&
1678
+ sequenceEnd >= sequence
1679
+ ? sequenceEnd - sequence + 1
1680
+ : 1;
1681
+ if (event?.type === "x-agent-native.persisted-event-omission-range") {
1682
+ const payload = event.payload &&
1683
+ typeof event.payload === "object" &&
1684
+ !Array.isArray(event.payload)
1685
+ ? event.payload
1686
+ : {};
1687
+ merged[index] = {
1688
+ ...event,
1689
+ sequence: nextSequence,
1690
+ payload: {
1691
+ ...payload,
1692
+ lastSequence: nextSequence + span - 1,
1693
+ },
1694
+ };
1695
+ }
1696
+ else {
1697
+ merged[index] = { ...event, sequence: nextSequence };
1698
+ }
1699
+ nextSequence += span;
1700
+ }
1668
1701
  }
1669
1702
  return merged;
1670
1703
  }
1704
+ function mergeAgentKitEventSnapshotBatch(existing, incoming) {
1705
+ const merged = Array.isArray(existing) ? [...existing] : [];
1706
+ const positions = new Map();
1707
+ merged.forEach((event, index) => {
1708
+ if (typeof event?.id === "string" && !positions.has(event.id)) {
1709
+ positions.set(event.id, index);
1710
+ }
1711
+ });
1712
+ for (const event of Array.isArray(incoming) ? incoming : []) {
1713
+ if (typeof event?.id !== "string") {
1714
+ merged.push(event);
1715
+ continue;
1716
+ }
1717
+ const index = positions.get(event.id);
1718
+ if (index === undefined) {
1719
+ positions.set(event.id, merged.length);
1720
+ merged.push(event);
1721
+ }
1722
+ else {
1723
+ merged[index] = event;
1724
+ }
1725
+ }
1726
+ return merged
1727
+ .map((event, order) => ({
1728
+ event,
1729
+ order,
1730
+ sequence: typeof event?.sequence === "number" && Number.isFinite(event.sequence)
1731
+ ? event.sequence
1732
+ : Number.NaN,
1733
+ }))
1734
+ .sort((left, right) => {
1735
+ if (Number.isFinite(left.sequence) &&
1736
+ Number.isFinite(right.sequence) &&
1737
+ left.sequence !== right.sequence) {
1738
+ return left.sequence - right.sequence;
1739
+ }
1740
+ return left.order - right.order;
1741
+ })
1742
+ .map(({ event }) => event);
1743
+ }
1744
+ const MAX_AGENT_NATIVE_PERSISTED_EVENT_OMISSION_RANGE = 256;
1745
+ function getAgentKitEventSequence(event) {
1746
+ if (!event || typeof event !== "object" || Array.isArray(event)) {
1747
+ return undefined;
1748
+ }
1749
+ const sequence = event.sequence;
1750
+ return typeof sequence === "number" && Number.isSafeInteger(sequence)
1751
+ ? sequence
1752
+ : undefined;
1753
+ }
1754
+ function getAgentKitEventSequenceEnd(event) {
1755
+ const sequence = getAgentKitEventSequence(event);
1756
+ if (sequence === undefined)
1757
+ return undefined;
1758
+ if (!event ||
1759
+ typeof event !== "object" ||
1760
+ event.type !==
1761
+ "x-agent-native.persisted-event-omission-range") {
1762
+ return sequence;
1763
+ }
1764
+ const payload = event.payload;
1765
+ if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
1766
+ return undefined;
1767
+ }
1768
+ const lastSequence = payload.lastSequence;
1769
+ return typeof lastSequence === "number" &&
1770
+ Number.isSafeInteger(lastSequence) &&
1771
+ lastSequence >= sequence &&
1772
+ lastSequence - sequence < MAX_AGENT_NATIVE_PERSISTED_EVENT_OMISSION_RANGE
1773
+ ? lastSequence
1774
+ : undefined;
1775
+ }
1776
+ function hasContiguousAgentKitEventCoverage(events, runId, lastSequence, firstSequence = 1) {
1777
+ const runEvents = events
1778
+ .filter((event) => event !== null &&
1779
+ typeof event === "object" &&
1780
+ !Array.isArray(event) &&
1781
+ event.runId === runId)
1782
+ .map((event, order) => ({
1783
+ event,
1784
+ order,
1785
+ sequence: getAgentKitEventSequence(event),
1786
+ sequenceEnd: getAgentKitEventSequenceEnd(event),
1787
+ }))
1788
+ .sort((left, right) => {
1789
+ if (left.sequence !== undefined &&
1790
+ right.sequence !== undefined &&
1791
+ left.sequence !== right.sequence) {
1792
+ return left.sequence - right.sequence;
1793
+ }
1794
+ return left.order - right.order;
1795
+ });
1796
+ let nextSequence = firstSequence;
1797
+ for (const event of runEvents) {
1798
+ if (event.sequence !== nextSequence ||
1799
+ event.sequenceEnd === undefined ||
1800
+ event.sequenceEnd < event.sequence) {
1801
+ return false;
1802
+ }
1803
+ nextSequence = event.sequenceEnd + 1;
1804
+ }
1805
+ return nextSequence === lastSequence + 1;
1806
+ }
1671
1807
  function mergeAgentKitFullEventSnapshot(existingEvents, incomingEvents, incomingRuns, committedSnapshots) {
1672
1808
  if (!Array.isArray(incomingEvents))
1673
1809
  return undefined;
@@ -1715,16 +1851,7 @@ function mergeAgentKitFullEventSnapshot(existingEvents, incomingEvents, incoming
1715
1851
  if (committedSequence < 0)
1716
1852
  continue;
1717
1853
  const runEvents = incomingEventsByRun.get(runId) ?? [];
1718
- const incomingSequence = Math.max(incomingRunSequences.get(runId) ?? 0, ...runEvents.map((event) => {
1719
- const sequence = event && typeof event === "object"
1720
- ? event.sequence
1721
- : undefined;
1722
- return typeof sequence === "number" &&
1723
- Number.isSafeInteger(sequence) &&
1724
- sequence >= 0
1725
- ? sequence
1726
- : 0;
1727
- }));
1854
+ const incomingSequence = Math.max(incomingRunSequences.get(runId) ?? 0, ...runEvents.map((event) => getAgentKitEventSequenceEnd(event) ?? 0));
1728
1855
  if (runEvents.length === 0 || incomingSequence <= committedSequence) {
1729
1856
  protectedRunIds.add(runId);
1730
1857
  }
@@ -1807,11 +1934,24 @@ function mergeAgentKitEventRunSnapshots(input) {
1807
1934
  const hasCommittedSnapshot = (commits[runId]?.length ?? 0) > 0;
1808
1935
  const committedSequence = Math.max(0, ...(commits[runId] ?? []).map((entry) => entry.lastSequence));
1809
1936
  const knownSequence = Math.max(storedWatermark ?? 0, storedRunSequence ?? 0, committedSequence);
1937
+ if (!input.batches.has(runId) && lastSequence > knownSequence) {
1938
+ const incomingEvents = Array.isArray(input.incomingEvents)
1939
+ ? input.incomingEvents
1940
+ : [];
1941
+ const completeFromStart = hasContiguousAgentKitEventCoverage(incomingEvents, runId, lastSequence);
1942
+ const nextChunk = hasContiguousAgentKitEventCoverage(incomingEvents, runId, lastSequence, knownSequence + 1);
1943
+ if (!completeFromStart && !nextChunk) {
1944
+ throw new TypeError("Agent chat event snapshot did not contain a contiguous sequence range.");
1945
+ }
1946
+ }
1810
1947
  const hasKnownSequence = storedWatermark !== undefined ||
1811
1948
  storedRunSequence !== undefined ||
1812
1949
  hasCommittedSnapshot;
1813
1950
  const hasStoredEvents = previousEvents.some((event) => event?.runId === runId);
1814
1951
  if ((hasKnownSequence && lastSequence < knownSequence) ||
1952
+ (hasKnownSequence &&
1953
+ lastSequence === knownSequence &&
1954
+ !input.incomingReplacements.has(runId)) ||
1815
1955
  (hasCommittedSnapshot && lastSequence <= committedSequence)) {
1816
1956
  staleRunIds.add(runId);
1817
1957
  continue;
@@ -1896,8 +2036,7 @@ function mergeAgentKitEventRunSnapshots(input) {
1896
2036
  const matchingCurrent = current?.lastSequence === batch.lastSequence &&
1897
2037
  current.expectedEventCount === batch.expectedEventCount;
1898
2038
  const batchEvents = incomingEvents.filter((event) => event?.runId === runId);
1899
- const stagedEvents = mergeAgentKitEvents(matchingCurrent ? current.events : [], batchEvents) ??
1900
- [];
2039
+ const stagedEvents = mergeAgentKitEventSnapshotBatch(matchingCurrent ? current.events : [], batchEvents);
1901
2040
  if (stagedEvents.length > batch.expectedEventCount) {
1902
2041
  throw new TypeError("Agent chat event snapshot exceeded its event count.");
1903
2042
  }
@@ -1905,6 +2044,18 @@ function mergeAgentKitEventRunSnapshots(input) {
1905
2044
  throw new TypeError("Agent chat event snapshot ended before all events arrived.");
1906
2045
  }
1907
2046
  if (stagedEvents.length === batch.expectedEventCount) {
2047
+ const lastEventSequence = stagedEvents.reduce((maximum, event) => {
2048
+ const sequence = getAgentKitEventSequenceEnd(event);
2049
+ return sequence !== undefined && sequence >= 0
2050
+ ? Math.max(maximum, sequence)
2051
+ : maximum;
2052
+ }, 0);
2053
+ if (batch.lastSequence !== lastEventSequence) {
2054
+ throw new TypeError(`Agent chat event snapshot cursor ${batch.lastSequence} did not match its last event sequence ${lastEventSequence}.`);
2055
+ }
2056
+ if (!hasContiguousAgentKitEventCoverage(stagedEvents, runId, batch.lastSequence)) {
2057
+ throw new TypeError("Agent chat event snapshot did not include every sequence through its cursor.");
2058
+ }
1908
2059
  events = mergeAgentKitEvents(events, stagedEvents, new Set([runId]));
1909
2060
  watermarks.set(runId, Math.max(knownSequence, batch.lastSequence));
1910
2061
  commits[runId] = [
@@ -2051,7 +2202,7 @@ function mergeAgentKitAnnotations(existing, incoming, replaceMessageIds, removal
2051
2202
  }
2052
2203
  return merged;
2053
2204
  }
2054
- function mergeAgentKitHistory(existing, incoming, promptRunIds, onAnnotationConflict) {
2205
+ function mergeAgentKitHistory(existing, incoming, promptRunIds, onAnnotationConflict, trustedRunSequenceResetIds = new Set()) {
2055
2206
  const incomingIsRecord = incoming !== null &&
2056
2207
  typeof incoming === "object" &&
2057
2208
  !Array.isArray(incoming);
@@ -2062,10 +2213,27 @@ function mergeAgentKitHistory(existing, incoming, promptRunIds, onAnnotationConf
2062
2213
  typeof existing === "object" &&
2063
2214
  !Array.isArray(existing);
2064
2215
  const snapshotDelta = next._snapshotDelta === true;
2065
- const incomingEventRunIds = new Set((Array.isArray(next.events) ? next.events : []).flatMap((event) => typeof event?.runId === "string" ? [event.runId] : []));
2066
- const incomingRunStarts = new Set((Array.isArray(next.events) ? next.events : []).flatMap((event) => typeof event?.runId === "string" && event.sequence === 1
2216
+ const incomingEvents = Array.isArray(next.events) ? next.events : [];
2217
+ for (const event of incomingEvents) {
2218
+ if (event?.type === "x-agent-native.persisted-event-omission-range" &&
2219
+ getAgentKitEventSequenceEnd(event) === undefined) {
2220
+ throw new TypeError(`Agent chat persisted omission ranges must cover at most ${MAX_AGENT_NATIVE_PERSISTED_EVENT_OMISSION_RANGE} event sequences.`);
2221
+ }
2222
+ }
2223
+ const incomingEventRunIds = new Set(incomingEvents.flatMap((event) => typeof event?.runId === "string" ? [event.runId] : []));
2224
+ const incomingRunStarts = new Set(incomingEvents.flatMap((event) => typeof event?.runId === "string" && event.sequence === 1
2067
2225
  ? [event.runId]
2068
2226
  : []));
2227
+ const incomingEventSequences = new Map();
2228
+ for (const event of incomingEvents) {
2229
+ if (typeof event?.runId !== "string") {
2230
+ continue;
2231
+ }
2232
+ const sequenceEnd = getAgentKitEventSequenceEnd(event);
2233
+ if (sequenceEnd === undefined || sequenceEnd < 0)
2234
+ continue;
2235
+ incomingEventSequences.set(event.runId, Math.max(incomingEventSequences.get(event.runId) ?? 0, sequenceEnd));
2236
+ }
2069
2237
  const eventRunSnapshotBatches = new Map();
2070
2238
  for (const batch of Array.isArray(next.eventRunSnapshotBatches)
2071
2239
  ? next.eventRunSnapshotBatches
@@ -2091,27 +2259,25 @@ function mergeAgentKitHistory(existing, incoming, promptRunIds, onAnnotationConf
2091
2259
  }
2092
2260
  }
2093
2261
  const eventRunSnapshotWatermarks = new Map();
2094
- for (const watermark of Array.isArray(next.eventRunSnapshotWatermarks)
2095
- ? next.eventRunSnapshotWatermarks
2096
- : []) {
2097
- if (typeof watermark?.runId === "string" &&
2098
- typeof watermark.lastSequence === "number" &&
2099
- Number.isSafeInteger(watermark.lastSequence) &&
2100
- watermark.lastSequence >= 0 &&
2101
- incomingEventRunIds.has(watermark.runId) &&
2102
- !eventRunSnapshotBatches.has(watermark.runId)) {
2103
- eventRunSnapshotWatermarks.set(watermark.runId, Math.max(eventRunSnapshotWatermarks.get(watermark.runId) ?? 0, watermark.lastSequence));
2262
+ for (const [runId, lastSequence] of incomingEventSequences) {
2263
+ if (incomingEventRunIds.has(runId) && !eventRunSnapshotBatches.has(runId)) {
2264
+ eventRunSnapshotWatermarks.set(runId, lastSequence);
2104
2265
  }
2105
2266
  }
2106
2267
  const eventRunReplacements = new Map();
2107
2268
  for (const replacement of Array.isArray(next.eventRunReplacements)
2108
2269
  ? next.eventRunReplacements
2109
2270
  : []) {
2271
+ const eventSequence = typeof replacement?.runId === "string"
2272
+ ? incomingEventSequences.get(replacement.runId)
2273
+ : undefined;
2110
2274
  if (typeof replacement?.runId === "string" &&
2275
+ incomingRunStarts.has(replacement.runId) &&
2111
2276
  typeof replacement.lastSequence === "number" &&
2112
2277
  Number.isSafeInteger(replacement.lastSequence) &&
2113
2278
  replacement.lastSequence >= 1 &&
2114
- incomingRunStarts.has(replacement.runId) &&
2279
+ eventSequence === replacement.lastSequence &&
2280
+ hasContiguousAgentKitEventCoverage(incomingEvents, replacement.runId, replacement.lastSequence) &&
2115
2281
  !eventRunSnapshotBatches.has(replacement.runId)) {
2116
2282
  eventRunReplacements.set(replacement.runId, Math.max(eventRunReplacements.get(replacement.runId) ?? 0, replacement.lastSequence));
2117
2283
  }
@@ -2214,20 +2380,29 @@ function mergeAgentKitHistory(existing, incoming, promptRunIds, onAnnotationConf
2214
2380
  runs.set(run.id, run);
2215
2381
  continue;
2216
2382
  }
2217
- const richer = newer.lastSequence >= run.lastSequence ? newer : run;
2218
- const statusRun = run.lastSequence > newer.lastSequence
2219
- ? run
2220
- : newer.lastSequence > run.lastSequence
2383
+ const trustedReset = trustedRunSequenceResetIds.has(run.id) && newer.lastSequence === 0;
2384
+ const richer = trustedReset
2385
+ ? newer
2386
+ : newer.lastSequence >= run.lastSequence
2221
2387
  ? newer
2222
- : isTerminalRunStatus(run.status)
2223
- ? run
2224
- : newer;
2388
+ : run;
2389
+ const statusRun = trustedReset
2390
+ ? newer
2391
+ : run.lastSequence > newer.lastSequence
2392
+ ? run
2393
+ : newer.lastSequence > run.lastSequence
2394
+ ? newer
2395
+ : isTerminalRunStatus(run.status)
2396
+ ? run
2397
+ : newer;
2225
2398
  runs.set(run.id, {
2226
2399
  ...run,
2227
2400
  ...newer,
2228
2401
  ...richer,
2229
2402
  metadata: { ...run.metadata, ...newer.metadata, ...richer.metadata },
2230
- lastSequence: Math.max(newer.lastSequence, run.lastSequence),
2403
+ lastSequence: trustedReset
2404
+ ? newer.lastSequence
2405
+ : Math.max(newer.lastSequence, run.lastSequence),
2231
2406
  status: statusRun.status,
2232
2407
  });
2233
2408
  }
@@ -2437,7 +2612,7 @@ export function mergeThreadDataForClientSave(existingRepo, incomingRepo, options
2437
2612
  }
2438
2613
  const promptRunIds = submittedPromptRunIds(existingNormalized?.messages, incomingNormalized?.messages);
2439
2614
  if (merged.agentKit !== undefined) {
2440
- merged.agentKit = mergeAgentKitHistory(existingNormalized?.agentKit, merged.agentKit, promptRunIds, options.onAnnotationConflict);
2615
+ merged.agentKit = mergeAgentKitHistory(existingNormalized?.agentKit, merged.agentKit, promptRunIds, options.onAnnotationConflict, options.trustedRunSequenceResetIds);
2441
2616
  }
2442
2617
  const existingMessages = Array.isArray(existingNormalized?.messages)
2443
2618
  ? existingNormalized.messages
@@ -139,8 +139,8 @@ export declare function createAutomationCallbackHandler(runtime: AutomationRunti
139
139
  duplicate?: undefined;
140
140
  eventId?: undefined;
141
141
  } | {
142
- error?: undefined;
143
142
  accepted: boolean;
144
143
  duplicate: boolean;
145
144
  eventId: string;
145
+ error?: undefined;
146
146
  }>;
@@ -189,6 +189,7 @@ export interface UpdateThreadDataOptions {
189
189
  preserveExistingTopLevelKeys?: boolean;
190
190
  preserveCurrentMetadata?: boolean;
191
191
  preserveCurrentTitleAndPreview?: boolean;
192
+ trustedRunSequenceResetIds?: ReadonlySet<string>;
192
193
  onAnnotationConflict?: (conflict: ThreadAnnotationSnapshotConflict) => void;
193
194
  transformThreadData?: (currentThreadData: string) => string | {
194
195
  threadData: string;
@@ -1124,6 +1124,7 @@ export async function updateThreadData(id, threadData, title, preview, messageCo
1124
1124
  const merged = mergeThreadDataForClientSave(safeCurrentThreadData, parseThreadData(incomingThreadData), {
1125
1125
  preserveExistingQueuedMessages: options.preserveExistingQueuedMessages ?? true,
1126
1126
  preserveExistingTopLevelKeys: options.preserveExistingTopLevelKeys ?? true,
1127
+ trustedRunSequenceResetIds: options.trustedRunSequenceResetIds,
1127
1128
  onAnnotationConflict: (conflict) => annotationConflicts.push(conflict),
1128
1129
  });
1129
1130
  // Client snapshots can predate their upload URL, so inline bytes become a
@@ -57,6 +57,7 @@ export interface ConnectDeps {
57
57
  }
58
58
  export declare function runDeviceFlow(baseUrl: string, appSlug: string, clientArg: string, deps?: ConnectDeps, options?: {
59
59
  fullCatalog?: boolean;
60
+ purpose?: "agent" | "credential";
60
61
  }): Promise<{
61
62
  token?: string;
62
63
  mcpUrl: string;
@@ -329,7 +329,7 @@ async function resolveHostedAppsFromPrompt(deps) {
329
329
  return apps.filter((app) => selected.has(app.name));
330
330
  }
331
331
  function clientArgForDeviceFlow(clients) {
332
- return clients.length === 1 ? clients[0] : "all";
332
+ return clients.join(",");
333
333
  }
334
334
  export function supportsRemoteMcpOAuth(client) {
335
335
  return REMOTE_MCP_OAUTH_CLIENTS.has(client);
@@ -616,6 +616,7 @@ export async function runDeviceFlow(baseUrl, appSlug, clientArg, deps = {}, opti
616
616
  client: clientArg,
617
617
  app: appSlug,
618
618
  ...(options.fullCatalog ? { fullCatalog: true } : {}),
619
+ ...(options.purpose ? { purpose: options.purpose } : {}),
619
620
  });
620
621
  if (status >= 200 && status < 300 && json?.device_code) {
621
622
  start = json;
@@ -1637,7 +1638,9 @@ async function connectOne(rawUrl, parsed, clients, deps) {
1637
1638
  try {
1638
1639
  logOut("");
1639
1640
  logOut(` Minting a publish token for the local Plans server (device flow)…`);
1640
- const grant = await runDeviceFlow(baseUrl, appSlug, "codex", deps);
1641
+ const grant = await runDeviceFlow(baseUrl, appSlug, "codex", deps, {
1642
+ purpose: "credential",
1643
+ });
1641
1644
  if (grant?.token) {
1642
1645
  publishToken = grant.token;
1643
1646
  }
@@ -1781,7 +1784,9 @@ export async function runServiceTokenMint(parsed, deps = {}) {
1781
1784
  logOut("");
1782
1785
  logOut(` Creating org service token "${serviceName}" on ${baseUrl}`);
1783
1786
  logOut(" First, verify it's you (the token will belong to your org)…");
1784
- const grant = await runDeviceFlow(baseUrl, appSlug, "codex", deps);
1787
+ const grant = await runDeviceFlow(baseUrl, appSlug, "codex", deps, {
1788
+ purpose: "credential",
1789
+ });
1785
1790
  if (!grant?.token) {
1786
1791
  logErr(" Could not authenticate (the server returned no bearer token).");
1787
1792
  logErr(" Org service tokens require a deployed app with auth configured.");