@jrkropp/codex-js 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/README.md +2 -2
- package/dist/ClientNotification-B6-FhXQf.d.ts +5 -0
- package/dist/DynamicToolCallResponse-82DFjES2.d.ts +8 -0
- package/dist/DynamicToolSpec-CfnhqAYK.d.ts +29 -0
- package/dist/PermissionsRequestApprovalResponse-DxzPPDRb.d.ts +55 -0
- package/dist/ProviderStatusBanner-BlP6lzwE.d.ts +441 -0
- package/dist/ServerRequest-B5cKVJjr.d.ts +2181 -0
- package/dist/{session-DPhHN7RZ.d.ts → ThreadResumeResponse-DvmE1juU.d.ts} +3 -306
- package/dist/ToolRequestUserInputQuestion-CeZa5X1J.d.ts +23 -0
- package/dist/ToolRequestUserInputResponse-zcPLwbiK.d.ts +17 -0
- package/dist/TurnSteerResponse-0kBCfplh.d.ts +209 -0
- package/dist/WebSearchToolConfig-D3ep0625.d.ts +18 -0
- package/dist/chat-runtime-9RkXHC_w.d.ts +382 -0
- package/dist/chunk-2DZRMCI2.js +1258 -0
- package/dist/chunk-2DZRMCI2.js.map +1 -0
- package/dist/chunk-4DPLJPB5.js +396 -0
- package/dist/chunk-4DPLJPB5.js.map +1 -0
- package/dist/chunk-5JMJ6OI5.js +3 -0
- package/dist/chunk-5JMJ6OI5.js.map +1 -0
- package/dist/chunk-6ZMJ34KE.js +1153 -0
- package/dist/chunk-6ZMJ34KE.js.map +1 -0
- package/dist/chunk-CGBS37IU.js +128 -0
- package/dist/chunk-CGBS37IU.js.map +1 -0
- package/dist/chunk-DCMKA2A6.js +18 -0
- package/dist/chunk-DCMKA2A6.js.map +1 -0
- package/dist/chunk-DYLHN3HG.js +937 -0
- package/dist/chunk-DYLHN3HG.js.map +1 -0
- package/dist/{chunk-SVK6PLGO.js → chunk-LWQNX4LI.js} +12009 -18768
- package/dist/chunk-LWQNX4LI.js.map +1 -0
- package/dist/{chunk-JLDH4U5L.js → chunk-NCI4MAWZ.js} +317 -1967
- package/dist/chunk-NCI4MAWZ.js.map +1 -0
- package/dist/chunk-O44XP7LH.js +214 -0
- package/dist/chunk-O44XP7LH.js.map +1 -0
- package/dist/chunk-PST3ZWX2.js +555 -0
- package/dist/chunk-PST3ZWX2.js.map +1 -0
- package/dist/chunk-SYPHCDRD.js +1133 -0
- package/dist/chunk-SYPHCDRD.js.map +1 -0
- package/dist/chunk-V4BMZWBM.js +2401 -0
- package/dist/chunk-V4BMZWBM.js.map +1 -0
- package/dist/chunk-W7S6HFCQ.js +1983 -0
- package/dist/chunk-W7S6HFCQ.js.map +1 -0
- package/dist/chunk-YHVCFD2D.js +117 -0
- package/dist/chunk-YHVCFD2D.js.map +1 -0
- package/dist/chunk-Z63UPBS3.js +152 -0
- package/dist/chunk-Z63UPBS3.js.map +1 -0
- package/dist/client/index.d.ts +16 -4
- package/dist/client/index.js +13 -1
- package/dist/codex-rs/app-server/index.d.ts +161 -0
- package/dist/codex-rs/app-server/index.js +13 -0
- package/dist/codex-rs/app-server/index.js.map +1 -0
- package/dist/codex-rs/app-server-protocol/index.d.ts +1722 -0
- package/dist/codex-rs/app-server-protocol/index.js +6 -0
- package/dist/codex-rs/app-server-protocol/index.js.map +1 -0
- package/dist/codex-rs/app-server-protocol/protocol.d.ts +19 -0
- package/dist/codex-rs/app-server-protocol/protocol.js +4 -0
- package/dist/codex-rs/app-server-protocol/protocol.js.map +1 -0
- package/dist/codex-rs/codex-api/index.d.ts +104 -0
- package/dist/codex-rs/codex-api/index.js +11 -0
- package/dist/codex-rs/codex-api/index.js.map +1 -0
- package/dist/codex-rs/config/index.d.ts +88 -0
- package/dist/codex-rs/config/index.js +4 -0
- package/dist/codex-rs/config/index.js.map +1 -0
- package/dist/codex-rs/core/config/index.d.ts +61 -0
- package/dist/codex-rs/core/config/index.js +5 -0
- package/dist/codex-rs/core/config/index.js.map +1 -0
- package/dist/codex-rs/core/index.d.ts +1393 -0
- package/dist/codex-rs/core/index.js +11 -0
- package/dist/codex-rs/core/index.js.map +1 -0
- package/dist/codex-rs/model-provider/index.d.ts +2 -0
- package/dist/codex-rs/model-provider/index.js +4 -0
- package/dist/codex-rs/model-provider/index.js.map +1 -0
- package/dist/codex-rs/models-manager/index.d.ts +2 -0
- package/dist/codex-rs/models-manager/index.js +4 -0
- package/dist/codex-rs/models-manager/index.js.map +1 -0
- package/dist/codex-rs/parity.d.ts +26 -0
- package/dist/codex-rs/parity.js +3 -0
- package/dist/codex-rs/parity.js.map +1 -0
- package/dist/codex-rs/thread-store/index.d.ts +5 -0
- package/dist/codex-rs/thread-store/index.js +4 -0
- package/dist/codex-rs/thread-store/index.js.map +1 -0
- package/dist/codex-rs/unsupported.d.ts +15 -0
- package/dist/codex-rs/unsupported.js +22 -0
- package/dist/codex-rs/unsupported.js.map +1 -0
- package/dist/codex-rs/utils/output-truncation.d.ts +21 -0
- package/dist/codex-rs/utils/output-truncation.js +4 -0
- package/dist/codex-rs/utils/output-truncation.js.map +1 -0
- package/dist/codex-rs/utils/string.d.ts +7 -0
- package/dist/codex-rs/utils/string.js +3 -0
- package/dist/codex-rs/utils/string.js.map +1 -0
- package/dist/common-CTyph5x8.d.ts +40 -0
- package/dist/event-mapping-CbISdQ1D.d.ts +43 -0
- package/dist/history-CfM-4V7b.d.ts +1654 -0
- package/dist/index-77U_Oc-a.d.ts +63 -0
- package/dist/index-CoDZosq0.d.ts +261 -0
- package/dist/index.d.ts +18 -7
- package/dist/index.js +16 -2
- package/dist/lib-nXlaKiS-.d.ts +48 -0
- package/dist/live-thread-BMvlflzM.d.ts +30 -0
- package/dist/merge-B_AWVmnI.d.ts +24 -0
- package/dist/mod-DYVLSWO4.d.ts +91 -0
- package/dist/plan-mode-Cv6KWb_S.d.ts +14 -0
- package/dist/proposed-plan-DpN1ma0Y.d.ts +53 -0
- package/dist/protocol-mpBcYHrm.d.ts +1655 -0
- package/dist/react/index.d.ts +56 -48
- package/dist/react/index.js +16 -2
- package/dist/{remote-_6TDvg-g.d.ts → remote-ClZbq9KN.d.ts} +3 -1
- package/dist/rendered-thread-AOxw3V5b.d.ts +29 -0
- package/dist/responses_websocket-BhxSgCzK.d.ts +183 -0
- package/dist/runtime-Cm6ml53h.d.ts +528 -0
- package/dist/server/index.d.ts +29 -2416
- package/dist/server/index.js +13 -1
- package/dist/session-BRYzi8OT.d.ts +46 -0
- package/dist/shadcn/index.d.ts +1 -1
- package/dist/{sidebar-DT2XoitN.d.ts → sidebar-DMMij22z.d.ts} +1 -1
- package/dist/spec_plan_types-CmsJ-Tfn.d.ts +260 -0
- package/dist/{store-GYldc9EJ.d.ts → store-AGRxhgQ3.d.ts} +2 -1
- package/dist/t3code/apps/web/components/chat.d.ts +508 -0
- package/dist/t3code/apps/web/components/chat.js +12 -0
- package/dist/t3code/apps/web/components/chat.js.map +1 -0
- package/dist/t3code/apps/web/index.d.ts +12 -0
- package/dist/t3code/apps/web/index.js +13 -0
- package/dist/t3code/apps/web/index.js.map +1 -0
- package/dist/testing/index.d.ts +9 -91
- package/dist/testing/index.js +13 -1
- package/dist/thread-history-builder-zW0zeqcS.d.ts +58 -0
- package/dist/thread_event_store-C0zYzukG.d.ts +77 -0
- package/dist/types-BTeabLYr.d.ts +126 -0
- package/package.json +152 -88
- package/dist/chat-runtime-D7wu_KbX.d.ts +0 -747
- package/dist/chunk-JLDH4U5L.js.map +0 -1
- package/dist/chunk-SVK6PLGO.js.map +0 -1
- package/dist/index-CB9la6xE.d.ts +0 -112
- package/dist/thread_event_store-B9CoQUIA.d.ts +0 -3868
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { memo, useState, useMemo, useCallback, useRef, useEffect, useLayoutEffect, forwardRef, useImperativeHandle, Suspense, createContext, Children, isValidElement, useContext
|
|
4
|
-
import { ChevronRightIcon, FolderIcon, FolderClosedIcon, FileIcon, CheckIcon, UserRoundIcon, BoxIcon, BotIcon, SparklesIcon, ArchiveIcon, MessageSquarePlusIcon, ChevronDownIcon, EllipsisIcon, LockOpenIcon, PenLineIcon, LockIcon, ListTodoIcon, StarIcon, Clock3Icon, SearchIcon, ChevronLeftIcon, XIcon, GlobeIcon, ImageIcon, LightbulbIcon, SettingsIcon, FileDiffIcon, TerminalIcon, PaperclipIcon, CopyIcon, InfoIcon, TriangleAlertIcon, CheckCircleIcon, AlertCircleIcon } from 'lucide-react';
|
|
1
|
+
import { defaultModelsManager, resolveReasoningEffortForModel } from './chunk-PST3ZWX2.js';
|
|
2
|
+
import { ChevronRightIcon, FolderIcon, FolderClosedIcon, FileIcon, CheckIcon, UserRoundIcon, BoxIcon, BotIcon, SparklesIcon, ArchiveIcon, MessageSquarePlusIcon, ChevronDownIcon, EllipsisIcon, LockOpenIcon, PenLineIcon, LockIcon, ListTodoIcon, StarIcon, Clock3Icon, SearchIcon, ChevronLeftIcon, XIcon, GlobeIcon, ImageIcon, LightbulbIcon, SettingsIcon, FileDiffIcon, TerminalIcon, PaperclipIcon, CopyIcon, MicIcon, CircleAlertIcon, InfoIcon, TriangleAlertIcon, CheckCircleIcon, AlertCircleIcon } from 'lucide-react';
|
|
3
|
+
import { memo, useState, useMemo, useCallback, useRef, useEffect, useLayoutEffect, forwardRef, useImperativeHandle, Suspense, createContext, Children, isValidElement, useContext } from 'react';
|
|
5
4
|
import { cva } from 'class-variance-authority';
|
|
6
5
|
import { Slot, DropdownMenu as DropdownMenu$1, Tooltip as Tooltip$1, Popover as Popover$1, Separator as Separator$1 } from 'radix-ui';
|
|
7
6
|
import { clsx } from 'clsx';
|
|
@@ -22,91 +21,6 @@ import { LegendList } from '@legendapp/list/react';
|
|
|
22
21
|
import ReactMarkdown, { defaultUrlTransform } from 'react-markdown';
|
|
23
22
|
import remarkGfm from 'remark-gfm';
|
|
24
23
|
|
|
25
|
-
function createLocalDispatchSnapshot(threadState) {
|
|
26
|
-
return {
|
|
27
|
-
errorCount: threadState?.errors.length ?? 0,
|
|
28
|
-
itemIds: threadTurnItemIds(threadState),
|
|
29
|
-
runningTurnIds: [...threadState?.activeTurnIds ?? []],
|
|
30
|
-
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
function hasServerAcknowledgedLocalDispatch(input) {
|
|
34
|
-
const localDispatch = input.localDispatch;
|
|
35
|
-
if (!localDispatch) {
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
if (input.hasPendingRequest || Boolean(input.runtimeError)) {
|
|
39
|
-
return true;
|
|
40
|
-
}
|
|
41
|
-
const runningTurnIds = input.threadState?.activeTurnIds ?? [];
|
|
42
|
-
if (runningTurnIds.some(
|
|
43
|
-
(turnId) => !localDispatch.runningTurnIds.includes(turnId)
|
|
44
|
-
)) {
|
|
45
|
-
return true;
|
|
46
|
-
}
|
|
47
|
-
if (threadTurnItemIds(input.threadState).some(
|
|
48
|
-
(itemId) => !localDispatch.itemIds.includes(itemId)
|
|
49
|
-
)) {
|
|
50
|
-
return true;
|
|
51
|
-
}
|
|
52
|
-
return (input.threadState?.errors.length ?? 0) > localDispatch.errorCount;
|
|
53
|
-
}
|
|
54
|
-
function useLocalDispatchState(input) {
|
|
55
|
-
const [localDispatch, setLocalDispatch] = useState(null);
|
|
56
|
-
const beginLocalDispatch = useCallback(() => {
|
|
57
|
-
setLocalDispatch(
|
|
58
|
-
(current) => current ?? createLocalDispatchSnapshot(input.threadState)
|
|
59
|
-
);
|
|
60
|
-
}, [input.threadState]);
|
|
61
|
-
const resetLocalDispatch = useCallback(() => {
|
|
62
|
-
setLocalDispatch(null);
|
|
63
|
-
}, []);
|
|
64
|
-
const serverAcknowledgedLocalDispatch = useMemo(
|
|
65
|
-
() => hasServerAcknowledgedLocalDispatch({
|
|
66
|
-
hasPendingRequest: input.hasPendingRequest,
|
|
67
|
-
localDispatch,
|
|
68
|
-
runtimeError: input.runtimeError,
|
|
69
|
-
threadState: input.threadState
|
|
70
|
-
}),
|
|
71
|
-
[
|
|
72
|
-
input.hasPendingRequest,
|
|
73
|
-
input.runtimeError,
|
|
74
|
-
input.threadState,
|
|
75
|
-
localDispatch
|
|
76
|
-
]
|
|
77
|
-
);
|
|
78
|
-
return {
|
|
79
|
-
beginLocalDispatch,
|
|
80
|
-
isSendBusy: localDispatch !== null && !serverAcknowledgedLocalDispatch,
|
|
81
|
-
localDispatch,
|
|
82
|
-
localDispatchStartedAt: localDispatch?.startedAt ?? null,
|
|
83
|
-
resetLocalDispatch,
|
|
84
|
-
serverAcknowledgedLocalDispatch
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
function deriveActiveWorkStartedAt(input) {
|
|
88
|
-
if (!input.isWorking) {
|
|
89
|
-
return null;
|
|
90
|
-
}
|
|
91
|
-
return input.sendStartedAt ?? input.runtimeStartedAt;
|
|
92
|
-
}
|
|
93
|
-
function deriveAssistantStreaming(threadState) {
|
|
94
|
-
if (!threadState || threadState.activeTurnIds.length === 0) {
|
|
95
|
-
return false;
|
|
96
|
-
}
|
|
97
|
-
const activeTurnIds = new Set(threadState.activeTurnIds);
|
|
98
|
-
return threadState.turns.some(
|
|
99
|
-
(turn) => activeTurnIds.has(turn.id) && turn.items.some(
|
|
100
|
-
(item) => item.type === "agentMessage" && item.text.length > 0
|
|
101
|
-
)
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
function deriveChatLifecycleWorkingState(input) {
|
|
105
|
-
return Boolean(input.threadState?.activeTurnIds.length) || input.isSendBusy || input.connectionStatus === "connecting" || input.connectionStatus === "reconnecting";
|
|
106
|
-
}
|
|
107
|
-
function threadTurnItemIds(threadState) {
|
|
108
|
-
return threadState?.turns.flatMap((turn) => turn.items.map((item) => item.id)) ?? [];
|
|
109
|
-
}
|
|
110
24
|
function cn(...inputs) {
|
|
111
25
|
return twMerge(clsx(inputs));
|
|
112
26
|
}
|
|
@@ -952,12 +866,16 @@ var PROJECT_MENTION_SIGIL = "@";
|
|
|
952
866
|
var LEGACY_PROJECT_MENTION_SIGIL = "$";
|
|
953
867
|
var SKILL_MENTION_SIGIL = "$";
|
|
954
868
|
var TOOL_MENTION_SIGIL = PROJECT_MENTION_SIGIL;
|
|
869
|
+
var PLUGIN_TEXT_MENTION_SIGIL = PROJECT_MENTION_SIGIL;
|
|
955
870
|
function isMentionNameChar(byte) {
|
|
956
871
|
return byte >= 48 && byte <= 57 || byte >= 65 && byte <= 90 || byte >= 97 && byte <= 122 || byte === 95 || byte === 45;
|
|
957
872
|
}
|
|
958
873
|
function mentionToken(name) {
|
|
959
874
|
return `${PROJECT_MENTION_SIGIL}${name}`;
|
|
960
875
|
}
|
|
876
|
+
function legacyMentionToken(name) {
|
|
877
|
+
return `${LEGACY_PROJECT_MENTION_SIGIL}${name}`;
|
|
878
|
+
}
|
|
961
879
|
function skillToken(name) {
|
|
962
880
|
return `${SKILL_MENTION_SIGIL}${name}`;
|
|
963
881
|
}
|
|
@@ -1247,6 +1165,9 @@ function replaceTextRange(text, rangeStart, rangeEnd, replacement) {
|
|
|
1247
1165
|
text: nextText
|
|
1248
1166
|
};
|
|
1249
1167
|
}
|
|
1168
|
+
function parseStandaloneComposerSlashCommand(text) {
|
|
1169
|
+
return text.trim().match(/^\/([a-z][a-z0-9-]*)$/)?.[1] ?? null;
|
|
1170
|
+
}
|
|
1250
1171
|
|
|
1251
1172
|
// src/upstream/t3code/apps/web/src/lib/searchRanking.ts
|
|
1252
1173
|
function normalizeSearchQuery(input, options) {
|
|
@@ -1911,13 +1832,19 @@ var CompactComposerControlsMenu = memo(
|
|
|
1911
1832
|
] });
|
|
1912
1833
|
}
|
|
1913
1834
|
);
|
|
1835
|
+
|
|
1836
|
+
// src/upstream/t3code/apps/web/src/components/chat/composer-footer-layout.ts
|
|
1837
|
+
var COMPOSER_FOOTER_COMPACT_BREAKPOINT_PX = 620;
|
|
1914
1838
|
var COMPOSER_FOOTER_WIDE_ACTIONS_COMPACT_BREAKPOINT_PX = 780;
|
|
1915
1839
|
var COMPOSER_PRIMARY_ACTIONS_COMPACT_BREAKPOINT_PX = COMPOSER_FOOTER_WIDE_ACTIONS_COMPACT_BREAKPOINT_PX;
|
|
1916
1840
|
function shouldUseCompactComposerFooter(width, options) {
|
|
1917
|
-
const breakpoint = COMPOSER_FOOTER_WIDE_ACTIONS_COMPACT_BREAKPOINT_PX ;
|
|
1841
|
+
const breakpoint = options?.hasWideActions ? COMPOSER_FOOTER_WIDE_ACTIONS_COMPACT_BREAKPOINT_PX : COMPOSER_FOOTER_COMPACT_BREAKPOINT_PX;
|
|
1918
1842
|
return width !== null && width < breakpoint;
|
|
1919
1843
|
}
|
|
1920
1844
|
function shouldUseCompactComposerPrimaryActions(width, options) {
|
|
1845
|
+
if (!options?.hasWideActions) {
|
|
1846
|
+
return false;
|
|
1847
|
+
}
|
|
1921
1848
|
return width !== null && width < COMPOSER_PRIMARY_ACTIONS_COMPACT_BREAKPOINT_PX;
|
|
1922
1849
|
}
|
|
1923
1850
|
var ComposerMentionNode = class _ComposerMentionNode extends DecoratorNode {
|
|
@@ -4248,6 +4175,7 @@ function createMemoryStorage() {
|
|
|
4248
4175
|
}
|
|
4249
4176
|
};
|
|
4250
4177
|
}
|
|
4178
|
+
var composerFooterHasWideActions = true;
|
|
4251
4179
|
var defaultComposerPlaceholder = "Ask anything, @tag files/folders, or use / to show available commands";
|
|
4252
4180
|
var runtimeModeConfig = {
|
|
4253
4181
|
"approval-required": {
|
|
@@ -4608,8 +4536,12 @@ var ChatComposer = forwardRef(function ChatComposer2({
|
|
|
4608
4536
|
}
|
|
4609
4537
|
const measureCompactness = () => {
|
|
4610
4538
|
const width = composerForm.clientWidth;
|
|
4611
|
-
const footerCompact = shouldUseCompactComposerFooter(width
|
|
4612
|
-
|
|
4539
|
+
const footerCompact = shouldUseCompactComposerFooter(width, {
|
|
4540
|
+
hasWideActions: composerFooterHasWideActions
|
|
4541
|
+
});
|
|
4542
|
+
const primaryActionsCompact = footerCompact && shouldUseCompactComposerPrimaryActions(width, {
|
|
4543
|
+
hasWideActions: composerFooterHasWideActions
|
|
4544
|
+
});
|
|
4613
4545
|
return { footerCompact, primaryActionsCompact };
|
|
4614
4546
|
};
|
|
4615
4547
|
const initialCompactness = measureCompactness();
|
|
@@ -5868,6 +5800,20 @@ function buildOptimisticUserMessageTurnItem(input) {
|
|
|
5868
5800
|
]
|
|
5869
5801
|
};
|
|
5870
5802
|
}
|
|
5803
|
+
function mergeOptimisticUserMessageTurnItems(items, optimisticMessages) {
|
|
5804
|
+
if (optimisticMessages.length === 0) {
|
|
5805
|
+
return [...items];
|
|
5806
|
+
}
|
|
5807
|
+
const serverUserMessageIds = new Set(
|
|
5808
|
+
items.flatMap(
|
|
5809
|
+
(item) => item.type === "UserMessage" ? [item.id] : []
|
|
5810
|
+
)
|
|
5811
|
+
);
|
|
5812
|
+
const pendingOptimisticMessages = optimisticMessages.filter(
|
|
5813
|
+
(message) => !serverUserMessageIds.has(message.id)
|
|
5814
|
+
);
|
|
5815
|
+
return pendingOptimisticMessages.length > 0 ? [...pendingOptimisticMessages, ...items] : [...items];
|
|
5816
|
+
}
|
|
5871
5817
|
function resolveAssistantMessageCopyState(input) {
|
|
5872
5818
|
const text = normalizeCopyText(input.text ?? "");
|
|
5873
5819
|
return {
|
|
@@ -6025,6 +5971,34 @@ function visibleTimelineWorkEntries(input) {
|
|
|
6025
5971
|
hiddenCount: input.entries.length - maxVisible
|
|
6026
5972
|
};
|
|
6027
5973
|
}
|
|
5974
|
+
function messagesTimelineFingerprint(rows) {
|
|
5975
|
+
const last = rows.at(-1);
|
|
5976
|
+
if (!last) {
|
|
5977
|
+
return "empty";
|
|
5978
|
+
}
|
|
5979
|
+
if (last.kind === "message" && last.item.type === "AgentMessage") {
|
|
5980
|
+
const text = last.item.content.map((part) => part.text).join("");
|
|
5981
|
+
return `${rows.length}:${last.id}:${text.length}:${last.item.phase ?? "done"}:${last.completedAt ?? ""}`;
|
|
5982
|
+
}
|
|
5983
|
+
if (last.kind === "proposed-plan") {
|
|
5984
|
+
return `${rows.length}:${last.id}:${last.item.text.length}`;
|
|
5985
|
+
}
|
|
5986
|
+
if (last.kind === "work") {
|
|
5987
|
+
const lastEntry = last.groupedEntries.at(-1);
|
|
5988
|
+
return `${rows.length}:${last.id}:${last.groupedEntries.length}:${lastEntry?.status ?? ""}`;
|
|
5989
|
+
}
|
|
5990
|
+
return `${rows.length}:${last.id}`;
|
|
5991
|
+
}
|
|
5992
|
+
function turnItemTextForCopy(item) {
|
|
5993
|
+
switch (item.type) {
|
|
5994
|
+
case "AgentMessage":
|
|
5995
|
+
return normalizeCopyText(item.content.map((part) => part.text).join("\n\n"));
|
|
5996
|
+
case "Plan":
|
|
5997
|
+
return normalizeCopyText(item.text);
|
|
5998
|
+
default:
|
|
5999
|
+
return null;
|
|
6000
|
+
}
|
|
6001
|
+
}
|
|
6028
6002
|
function isAssistantCredentialError(message) {
|
|
6029
6003
|
return /OpenAI API key|OpenAI platform credentials|OpenAI credential|Saved OpenAI credentials/i.test(
|
|
6030
6004
|
message
|
|
@@ -6581,6 +6555,17 @@ function normalizePlanMarkdownForExport(planMarkdown) {
|
|
|
6581
6555
|
return `${planMarkdown.trimEnd()}
|
|
6582
6556
|
`;
|
|
6583
6557
|
}
|
|
6558
|
+
function downloadPlanAsTextFile(filename, contents) {
|
|
6559
|
+
const blob = new Blob([contents], { type: "text/markdown;charset=utf-8" });
|
|
6560
|
+
const url = URL.createObjectURL(blob);
|
|
6561
|
+
const anchor = document.createElement("a");
|
|
6562
|
+
anchor.href = url;
|
|
6563
|
+
anchor.download = filename;
|
|
6564
|
+
anchor.click();
|
|
6565
|
+
window.setTimeout(() => {
|
|
6566
|
+
URL.revokeObjectURL(url);
|
|
6567
|
+
}, 0);
|
|
6568
|
+
}
|
|
6584
6569
|
var ProposedPlanCard = memo(function ProposedPlanCard2({
|
|
6585
6570
|
planMarkdown
|
|
6586
6571
|
}) {
|
|
@@ -7425,6 +7410,164 @@ var ChatView = memo(function ChatView2({
|
|
|
7425
7410
|
}
|
|
7426
7411
|
);
|
|
7427
7412
|
});
|
|
7413
|
+
var ComposerPendingApprovalActions = memo(
|
|
7414
|
+
function ComposerPendingApprovalActions2({
|
|
7415
|
+
isResponding,
|
|
7416
|
+
requestId,
|
|
7417
|
+
onRespondToApproval
|
|
7418
|
+
}) {
|
|
7419
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7420
|
+
/* @__PURE__ */ jsx(
|
|
7421
|
+
Button,
|
|
7422
|
+
{
|
|
7423
|
+
size: "sm",
|
|
7424
|
+
variant: "ghost",
|
|
7425
|
+
disabled: isResponding,
|
|
7426
|
+
onClick: () => void onRespondToApproval(requestId, "cancel"),
|
|
7427
|
+
children: "Cancel turn"
|
|
7428
|
+
}
|
|
7429
|
+
),
|
|
7430
|
+
/* @__PURE__ */ jsx(
|
|
7431
|
+
Button,
|
|
7432
|
+
{
|
|
7433
|
+
size: "sm",
|
|
7434
|
+
variant: "destructive",
|
|
7435
|
+
disabled: isResponding,
|
|
7436
|
+
onClick: () => void onRespondToApproval(requestId, "decline"),
|
|
7437
|
+
children: "Decline"
|
|
7438
|
+
}
|
|
7439
|
+
),
|
|
7440
|
+
/* @__PURE__ */ jsx(
|
|
7441
|
+
Button,
|
|
7442
|
+
{
|
|
7443
|
+
size: "sm",
|
|
7444
|
+
variant: "outline",
|
|
7445
|
+
disabled: isResponding,
|
|
7446
|
+
onClick: () => void onRespondToApproval(requestId, "acceptForSession"),
|
|
7447
|
+
children: "Always allow this session"
|
|
7448
|
+
}
|
|
7449
|
+
),
|
|
7450
|
+
/* @__PURE__ */ jsx(
|
|
7451
|
+
Button,
|
|
7452
|
+
{
|
|
7453
|
+
size: "sm",
|
|
7454
|
+
variant: "default",
|
|
7455
|
+
disabled: isResponding,
|
|
7456
|
+
onClick: () => void onRespondToApproval(requestId, "accept"),
|
|
7457
|
+
children: "Approve once"
|
|
7458
|
+
}
|
|
7459
|
+
)
|
|
7460
|
+
] });
|
|
7461
|
+
}
|
|
7462
|
+
);
|
|
7463
|
+
var ComposerPendingApprovalPanel = memo(
|
|
7464
|
+
function ComposerPendingApprovalPanel2({
|
|
7465
|
+
approval,
|
|
7466
|
+
pendingCount
|
|
7467
|
+
}) {
|
|
7468
|
+
const approvalSummary = approval.requestKind === "command" ? "Command approval requested" : approval.requestKind === "file-read" ? "File-read approval requested" : "File-change approval requested";
|
|
7469
|
+
return /* @__PURE__ */ jsx("div", { className: "px-4 py-3.5 sm:px-5 sm:py-4", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
7470
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm uppercase tracking-[0.2em]", children: "PENDING APPROVAL" }),
|
|
7471
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-sm", children: approvalSummary }),
|
|
7472
|
+
pendingCount > 1 ? /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground text-xs", children: [
|
|
7473
|
+
"1/",
|
|
7474
|
+
pendingCount
|
|
7475
|
+
] }) : null
|
|
7476
|
+
] }) });
|
|
7477
|
+
}
|
|
7478
|
+
);
|
|
7479
|
+
|
|
7480
|
+
// src/upstream/t3code/apps/web/src/components/composerInlineChip.ts
|
|
7481
|
+
var COMPOSER_INLINE_CHIP_CLASS_NAME = "inline-flex max-w-full select-none items-center gap-1 rounded-md border border-border/70 bg-accent/40 px-1.5 py-px font-medium text-[12px] leading-[1.1] text-foreground align-middle";
|
|
7482
|
+
var COMPOSER_INLINE_CHIP_ICON_CLASS_NAME = "size-3.5 shrink-0 opacity-85";
|
|
7483
|
+
var COMPOSER_INLINE_CHIP_LABEL_CLASS_NAME = "truncate select-none leading-tight";
|
|
7484
|
+
var COMPOSER_INLINE_SKILL_CHIP_CLASS_NAME = "inline-flex max-w-full select-none items-center gap-1 rounded-md border border-fuchsia-500/25 bg-fuchsia-500/12 px-1.5 py-px font-medium text-[12px] leading-[1.1] text-fuchsia-700 align-middle dark:text-fuchsia-300";
|
|
7485
|
+
var COMPOSER_INLINE_CHIP_DISMISS_BUTTON_CLASS_NAME = "ml-0.5 inline-flex size-3.5 shrink-0 cursor-pointer items-center justify-center rounded-sm text-muted-foreground/72 transition-colors hover:bg-foreground/6 hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring";
|
|
7486
|
+
function TerminalContextInlineChip(props) {
|
|
7487
|
+
const { expired = false, label, tooltipText } = props;
|
|
7488
|
+
return /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
7489
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
7490
|
+
"span",
|
|
7491
|
+
{
|
|
7492
|
+
className: cn(
|
|
7493
|
+
COMPOSER_INLINE_CHIP_CLASS_NAME,
|
|
7494
|
+
expired && "border-destructive/35 bg-destructive/8 text-destructive"
|
|
7495
|
+
),
|
|
7496
|
+
"data-terminal-context-expired": expired ? "true" : void 0,
|
|
7497
|
+
children: [
|
|
7498
|
+
/* @__PURE__ */ jsx(
|
|
7499
|
+
TerminalIcon,
|
|
7500
|
+
{
|
|
7501
|
+
"aria-hidden": "true",
|
|
7502
|
+
className: cn(
|
|
7503
|
+
COMPOSER_INLINE_CHIP_ICON_CLASS_NAME,
|
|
7504
|
+
"size-3.5",
|
|
7505
|
+
expired && "opacity-100"
|
|
7506
|
+
)
|
|
7507
|
+
}
|
|
7508
|
+
),
|
|
7509
|
+
/* @__PURE__ */ jsx("span", { className: COMPOSER_INLINE_CHIP_LABEL_CLASS_NAME, children: label })
|
|
7510
|
+
]
|
|
7511
|
+
}
|
|
7512
|
+
) }),
|
|
7513
|
+
/* @__PURE__ */ jsx(TooltipContent, { className: "max-w-80 whitespace-pre-wrap leading-tight", side: "top", children: tooltipText })
|
|
7514
|
+
] });
|
|
7515
|
+
}
|
|
7516
|
+
function formatTerminalContextLabel(context) {
|
|
7517
|
+
return context.label?.trim() || `Terminal ${context.id}`;
|
|
7518
|
+
}
|
|
7519
|
+
function isTerminalContextExpired(context) {
|
|
7520
|
+
return typeof context.expiresAt === "number" && context.expiresAt <= Date.now();
|
|
7521
|
+
}
|
|
7522
|
+
function ComposerPendingTerminalContextChip({
|
|
7523
|
+
context
|
|
7524
|
+
}) {
|
|
7525
|
+
const label = formatTerminalContextLabel(context);
|
|
7526
|
+
const expired = isTerminalContextExpired(context);
|
|
7527
|
+
const tooltipText = expired ? `Terminal context expired. Remove and re-add ${label} to include it in your message.` : context.text;
|
|
7528
|
+
return /* @__PURE__ */ jsx(
|
|
7529
|
+
TerminalContextInlineChip,
|
|
7530
|
+
{
|
|
7531
|
+
expired,
|
|
7532
|
+
label,
|
|
7533
|
+
tooltipText
|
|
7534
|
+
}
|
|
7535
|
+
);
|
|
7536
|
+
}
|
|
7537
|
+
function ComposerPendingTerminalContexts({
|
|
7538
|
+
className,
|
|
7539
|
+
contexts
|
|
7540
|
+
}) {
|
|
7541
|
+
if (contexts.length === 0) {
|
|
7542
|
+
return null;
|
|
7543
|
+
}
|
|
7544
|
+
return /* @__PURE__ */ jsx("div", { className: cn("flex flex-wrap gap-1.5", className), children: contexts.map((context) => /* @__PURE__ */ jsx(ComposerPendingTerminalContextChip, { context }, context.id)) });
|
|
7545
|
+
}
|
|
7546
|
+
function getComposerProviderState(input) {
|
|
7547
|
+
const promptEffort = input.modelOptions?.find((option) => option.name === "effort")?.value ?? null;
|
|
7548
|
+
return {
|
|
7549
|
+
modelOptionsForDispatch: input.modelOptions ?? void 0,
|
|
7550
|
+
promptEffort,
|
|
7551
|
+
provider: input.provider
|
|
7552
|
+
};
|
|
7553
|
+
}
|
|
7554
|
+
function renderProviderTraitsMenuContent(_input) {
|
|
7555
|
+
return null;
|
|
7556
|
+
}
|
|
7557
|
+
function renderProviderTraitsPicker(input) {
|
|
7558
|
+
if (!input.onEffortChange) {
|
|
7559
|
+
return null;
|
|
7560
|
+
}
|
|
7561
|
+
const effortValue = input.modelOptions?.find((option) => option.name === "effort")?.value ?? "medium";
|
|
7562
|
+
const effort = isCodexReasoningEffort(effortValue) ? effortValue : "medium";
|
|
7563
|
+
return /* @__PURE__ */ jsx(
|
|
7564
|
+
TraitsPicker,
|
|
7565
|
+
{
|
|
7566
|
+
effort,
|
|
7567
|
+
onEffortChange: input.onEffortChange
|
|
7568
|
+
}
|
|
7569
|
+
);
|
|
7570
|
+
}
|
|
7428
7571
|
|
|
7429
7572
|
// src/upstream/t3code/apps/web/src/components/chat/composer-realtime-conversation.logic.ts
|
|
7430
7573
|
function isRealtimeConversationLive(phase) {
|
|
@@ -7499,1885 +7642,92 @@ var RecordingMeterState = class {
|
|
|
7499
7642
|
return this.history.join("");
|
|
7500
7643
|
}
|
|
7501
7644
|
};
|
|
7502
|
-
|
|
7503
|
-
|
|
7504
|
-
|
|
7505
|
-
|
|
7506
|
-
|
|
7507
|
-
|
|
7508
|
-
|
|
7509
|
-
|
|
7510
|
-
|
|
7511
|
-
|
|
7512
|
-
|
|
7513
|
-
|
|
7514
|
-
|
|
7515
|
-
|
|
7516
|
-
|
|
7517
|
-
|
|
7518
|
-
|
|
7519
|
-
|
|
7520
|
-
|
|
7521
|
-
|
|
7522
|
-
|
|
7523
|
-
|
|
7524
|
-
|
|
7525
|
-
|
|
7526
|
-
|
|
7527
|
-
|
|
7528
|
-
|
|
7529
|
-
|
|
7530
|
-
|
|
7531
|
-
|
|
7532
|
-
|
|
7533
|
-
|
|
7534
|
-
|
|
7535
|
-
|
|
7536
|
-
|
|
7537
|
-
|
|
7538
|
-
|
|
7539
|
-
|
|
7540
|
-
|
|
7541
|
-
|
|
7542
|
-
|
|
7543
|
-
|
|
7544
|
-
|
|
7545
|
-
|
|
7546
|
-
|
|
7547
|
-
|
|
7548
|
-
|
|
7549
|
-
|
|
7550
|
-
|
|
7551
|
-
|
|
7552
|
-
|
|
7553
|
-
|
|
7554
|
-
|
|
7645
|
+
var ComposerRealtimeConversationControl = memo(
|
|
7646
|
+
function ComposerRealtimeConversationControl2({
|
|
7647
|
+
compact,
|
|
7648
|
+
disabled = false,
|
|
7649
|
+
preserveComposerFocusOnPointerDown = false,
|
|
7650
|
+
realtimeConversation
|
|
7651
|
+
}) {
|
|
7652
|
+
const state = getRealtimeConversationControlState(realtimeConversation);
|
|
7653
|
+
const pointerFocusProps = preserveComposerFocusOnPointerDown ? { onPointerDown: preventPointerFocus2 } : void 0;
|
|
7654
|
+
return /* @__PURE__ */ jsxs(
|
|
7655
|
+
Button,
|
|
7656
|
+
{
|
|
7657
|
+
type: "button",
|
|
7658
|
+
variant: "ghost",
|
|
7659
|
+
size: compact ? "icon-sm" : "sm",
|
|
7660
|
+
className: cn(
|
|
7661
|
+
"shrink-0 text-muted-foreground/80 hover:text-foreground",
|
|
7662
|
+
state.isActive && "text-primary hover:text-primary",
|
|
7663
|
+
state.isBusy && "animate-pulse"
|
|
7664
|
+
),
|
|
7665
|
+
...pointerFocusProps,
|
|
7666
|
+
"aria-label": state.label,
|
|
7667
|
+
"aria-pressed": state.isActive,
|
|
7668
|
+
"data-realtime-conversation-phase": realtimeConversation.phase,
|
|
7669
|
+
disabled: disabled || realtimeConversation.disabled || state.isBusy,
|
|
7670
|
+
title: state.title,
|
|
7671
|
+
onClick: state.action === "stop" ? realtimeConversation.onStop : realtimeConversation.onStart,
|
|
7672
|
+
children: [
|
|
7673
|
+
state.isBusy ? /* @__PURE__ */ jsx(
|
|
7674
|
+
"svg",
|
|
7675
|
+
{
|
|
7676
|
+
width: "14",
|
|
7677
|
+
height: "14",
|
|
7678
|
+
viewBox: "0 0 14 14",
|
|
7679
|
+
fill: "none",
|
|
7680
|
+
className: "animate-spin",
|
|
7681
|
+
"aria-hidden": "true",
|
|
7682
|
+
children: /* @__PURE__ */ jsx(
|
|
7683
|
+
"circle",
|
|
7684
|
+
{
|
|
7685
|
+
cx: "7",
|
|
7686
|
+
cy: "7",
|
|
7687
|
+
r: "5.5",
|
|
7688
|
+
stroke: "currentColor",
|
|
7689
|
+
strokeWidth: "1.5",
|
|
7690
|
+
strokeLinecap: "round",
|
|
7691
|
+
strokeDasharray: "20 12"
|
|
7692
|
+
}
|
|
7693
|
+
)
|
|
7694
|
+
}
|
|
7695
|
+
) : /* @__PURE__ */ jsx(MicIcon, { "aria-hidden": "true" }),
|
|
7696
|
+
/* @__PURE__ */ jsx("span", { className: compact ? "sr-only" : "hidden sm:inline", children: state.isActive ? "Live voice" : "Realtime" })
|
|
7697
|
+
]
|
|
7555
7698
|
}
|
|
7556
|
-
|
|
7699
|
+
);
|
|
7557
7700
|
}
|
|
7558
|
-
|
|
7559
|
-
|
|
7560
|
-
|
|
7561
|
-
|
|
7562
|
-
|
|
7701
|
+
);
|
|
7702
|
+
var preventPointerFocus2 = (event) => {
|
|
7703
|
+
event.preventDefault();
|
|
7704
|
+
};
|
|
7705
|
+
var ProviderStatusBanner = memo(function ProviderStatusBanner2({
|
|
7706
|
+
status
|
|
7707
|
+
}) {
|
|
7708
|
+
if (!status || status.status === "ready" || status.status === "disabled") {
|
|
7709
|
+
return null;
|
|
7563
7710
|
}
|
|
7564
|
-
|
|
7565
|
-
}
|
|
7566
|
-
|
|
7567
|
-
|
|
7568
|
-
|
|
7569
|
-
|
|
7570
|
-
|
|
7571
|
-
|
|
7572
|
-
|
|
7573
|
-
|
|
7574
|
-
|
|
7575
|
-
|
|
7576
|
-
const [activeRuntimeStartedAt, setActiveRuntimeStartedAt] = useState(
|
|
7577
|
-
null
|
|
7578
|
-
);
|
|
7579
|
-
const activeRuntimeStartedAtRef = useRef(null);
|
|
7580
|
-
const localDispatchStartedAtRef = useRef(null);
|
|
7581
|
-
const pendingComposerSendRef = useRef(null);
|
|
7582
|
-
const sendInFlightRef = useRef(false);
|
|
7583
|
-
const threadStoreRef = useRef(
|
|
7584
|
-
options.initialState?.thread?.id === threadId ? ThreadEventStore.fromThread(options.initialState.thread) : null
|
|
7585
|
-
);
|
|
7586
|
-
const threadSnapshotRef = useRef(threadSnapshot);
|
|
7587
|
-
const activeEventsIteratorRef = useRef(null);
|
|
7588
|
-
const lifecycleGenerationRef = useRef(0);
|
|
7589
|
-
const lifecycleKeyRef = useRef(null);
|
|
7590
|
-
const subscriptionAbortRef = useRef(null);
|
|
7591
|
-
const appServerSession = useMemo(
|
|
7592
|
-
() => new AppServerSession(options.appServer),
|
|
7593
|
-
[options.appServer]
|
|
7594
|
-
);
|
|
7595
|
-
const lifecycleKey = `${threadId}:${options.connectOnMount === false ? "draft" : "server"}`;
|
|
7596
|
-
if (lifecycleKeyRef.current !== lifecycleKey) {
|
|
7597
|
-
lifecycleKeyRef.current = lifecycleKey;
|
|
7598
|
-
lifecycleGenerationRef.current += 1;
|
|
7599
|
-
}
|
|
7600
|
-
const visibleRuntimeError = runtimeError?.threadId === threadId ? runtimeError.message : null;
|
|
7601
|
-
const closeActiveSubscription = useCallback(() => {
|
|
7602
|
-
subscriptionAbortRef.current?.abort();
|
|
7603
|
-
subscriptionAbortRef.current = null;
|
|
7604
|
-
const iterator = activeEventsIteratorRef.current;
|
|
7605
|
-
activeEventsIteratorRef.current = null;
|
|
7606
|
-
void iterator?.return?.();
|
|
7607
|
-
}, []);
|
|
7608
|
-
const visibleOptimisticUserMessages = useMemo(
|
|
7609
|
-
() => optimisticUserMessages.filter((message) => message.threadId === threadId).map((message) => message.item),
|
|
7610
|
-
[optimisticUserMessages, threadId]
|
|
7611
|
-
);
|
|
7612
|
-
const setProtocolConnectionStatus = useCallback(
|
|
7613
|
-
(status) => {
|
|
7614
|
-
const store = threadStoreRef.current;
|
|
7615
|
-
if (!store) {
|
|
7616
|
-
return;
|
|
7617
|
-
}
|
|
7618
|
-
const snapshot = store.setConnectionStatus(status);
|
|
7619
|
-
threadSnapshotRef.current = snapshot;
|
|
7620
|
-
setThreadSnapshot(snapshot);
|
|
7621
|
-
},
|
|
7622
|
-
[]
|
|
7623
|
-
);
|
|
7624
|
-
const hasPendingRequest = Boolean(threadSnapshot?.pendingRequests.length);
|
|
7625
|
-
const {
|
|
7626
|
-
beginLocalDispatch,
|
|
7627
|
-
isSendBusy,
|
|
7628
|
-
localDispatchStartedAt,
|
|
7629
|
-
resetLocalDispatch,
|
|
7630
|
-
serverAcknowledgedLocalDispatch
|
|
7631
|
-
} = useLocalDispatchState({
|
|
7632
|
-
hasPendingRequest,
|
|
7633
|
-
runtimeError: visibleRuntimeError,
|
|
7634
|
-
threadState: threadSnapshot
|
|
7635
|
-
});
|
|
7636
|
-
useEffect(() => {
|
|
7637
|
-
threadSnapshotRef.current = threadSnapshot;
|
|
7638
|
-
options.onState?.(threadSnapshot);
|
|
7639
|
-
}, [options, threadSnapshot]);
|
|
7640
|
-
useEffect(() => {
|
|
7641
|
-
activeRuntimeStartedAtRef.current = activeRuntimeStartedAt;
|
|
7642
|
-
}, [activeRuntimeStartedAt]);
|
|
7643
|
-
useEffect(() => {
|
|
7644
|
-
localDispatchStartedAtRef.current = localDispatchStartedAt;
|
|
7645
|
-
}, [localDispatchStartedAt]);
|
|
7646
|
-
const removeOptimisticUserMessage = useCallback((itemId) => {
|
|
7647
|
-
setOptimisticUserMessages(
|
|
7648
|
-
(current) => current.filter((message) => message.item.id !== itemId)
|
|
7649
|
-
);
|
|
7650
|
-
}, []);
|
|
7651
|
-
const restorePendingComposerSend = useCallback(() => {
|
|
7652
|
-
const pendingComposerSend = pendingComposerSendRef.current;
|
|
7653
|
-
if (!pendingComposerSend) {
|
|
7654
|
-
return;
|
|
7655
|
-
}
|
|
7656
|
-
removeOptimisticUserMessage(pendingComposerSend.optimisticItemId);
|
|
7657
|
-
pendingComposerSend.restore?.();
|
|
7658
|
-
}, [removeOptimisticUserMessage]);
|
|
7659
|
-
const handleRuntimeError = useCallback(
|
|
7660
|
-
(error) => {
|
|
7661
|
-
options.onRuntimeError?.(error);
|
|
7662
|
-
if (options.isRecoverableConnectionError?.(error) && !pendingComposerSendRef.current) {
|
|
7663
|
-
resetLocalDispatch();
|
|
7664
|
-
setActiveRuntimeStartedAt(null);
|
|
7665
|
-
setIsSending(false);
|
|
7666
|
-
setProtocolConnectionStatus("error");
|
|
7667
|
-
return;
|
|
7668
|
-
}
|
|
7669
|
-
setRuntimeError({ message: error.message, threadId });
|
|
7670
|
-
if (pendingComposerSendRef.current) {
|
|
7671
|
-
if (!pendingComposerSendRef.current.serverUserMessageAcknowledged) {
|
|
7672
|
-
restorePendingComposerSend();
|
|
7673
|
-
}
|
|
7674
|
-
pendingComposerSendRef.current = null;
|
|
7675
|
-
sendInFlightRef.current = false;
|
|
7676
|
-
setIsSending(false);
|
|
7677
|
-
resetLocalDispatch();
|
|
7678
|
-
setActiveRuntimeStartedAt(null);
|
|
7679
|
-
}
|
|
7680
|
-
setProtocolConnectionStatus("error");
|
|
7681
|
-
},
|
|
7682
|
-
[
|
|
7683
|
-
options,
|
|
7684
|
-
resetLocalDispatch,
|
|
7685
|
-
restorePendingComposerSend,
|
|
7686
|
-
setProtocolConnectionStatus,
|
|
7687
|
-
threadId
|
|
7688
|
-
]
|
|
7689
|
-
);
|
|
7690
|
-
const handleSubmittedUserMessage = useCallback(
|
|
7691
|
-
(state) => {
|
|
7692
|
-
const pendingComposerSend = pendingComposerSendRef.current;
|
|
7693
|
-
if (pendingComposerSend) {
|
|
7694
|
-
pendingComposerSendRef.current = {
|
|
7695
|
-
...pendingComposerSend,
|
|
7696
|
-
serverUserMessageAcknowledged: true
|
|
7697
|
-
};
|
|
7698
|
-
}
|
|
7699
|
-
sendInFlightRef.current = false;
|
|
7700
|
-
setIsSending(false);
|
|
7701
|
-
options.onThreadListChanged?.();
|
|
7702
|
-
options.onSubmittedUserMessage?.(state);
|
|
7703
|
-
pendingComposerSendRef.current = null;
|
|
7704
|
-
},
|
|
7705
|
-
[options]
|
|
7706
|
-
);
|
|
7707
|
-
const handleThreadStarted = useCallback(
|
|
7708
|
-
(state) => {
|
|
7709
|
-
const runtimeStartedAt = activeRuntimeStartedAtRef.current ?? localDispatchStartedAtRef.current ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
7710
|
-
setActiveRuntimeStartedAt((current) => current ?? runtimeStartedAt);
|
|
7711
|
-
if (pendingComposerSendRef.current) {
|
|
7712
|
-
pendingComposerSendRef.current = null;
|
|
7713
|
-
sendInFlightRef.current = false;
|
|
7714
|
-
setIsSending(false);
|
|
7715
|
-
options.onThreadListChanged?.();
|
|
7716
|
-
}
|
|
7717
|
-
options.onThreadStarted?.(state);
|
|
7718
|
-
},
|
|
7719
|
-
[options]
|
|
7720
|
-
);
|
|
7721
|
-
const applyServerNotification = useCallback(
|
|
7722
|
-
(notification) => {
|
|
7723
|
-
const store = threadStoreRef.current;
|
|
7724
|
-
if (!store) {
|
|
7725
|
-
return;
|
|
7726
|
-
}
|
|
7727
|
-
const next = store.applyNotification(notification);
|
|
7728
|
-
threadSnapshotRef.current = next;
|
|
7729
|
-
setThreadSnapshot(next);
|
|
7730
|
-
if (notification.method === "item/completed" && notification.params.item.type === "userMessage") {
|
|
7731
|
-
window.setTimeout(() => handleSubmittedUserMessage(next), 0);
|
|
7732
|
-
}
|
|
7733
|
-
if (threadEventSnapshotHasStarted(next)) {
|
|
7734
|
-
window.setTimeout(() => handleThreadStarted(next), 0);
|
|
7735
|
-
}
|
|
7736
|
-
},
|
|
7737
|
-
[handleSubmittedUserMessage, handleThreadStarted]
|
|
7738
|
-
);
|
|
7739
|
-
const applyServerRequest = useCallback(
|
|
7740
|
-
(request) => {
|
|
7741
|
-
const store = threadStoreRef.current;
|
|
7742
|
-
if (!store) {
|
|
7743
|
-
return;
|
|
7744
|
-
}
|
|
7745
|
-
const next = store.applyRequest(request);
|
|
7746
|
-
threadSnapshotRef.current = next;
|
|
7747
|
-
setThreadSnapshot(next);
|
|
7748
|
-
},
|
|
7749
|
-
[]
|
|
7750
|
-
);
|
|
7751
|
-
const connectThread = useCallback(
|
|
7752
|
-
async (input = {}) => {
|
|
7753
|
-
const generation = lifecycleGenerationRef.current;
|
|
7754
|
-
const isCurrentLifecycle = (abortController2) => !abortController2.signal.aborted && lifecycleGenerationRef.current === generation;
|
|
7755
|
-
closeActiveSubscription();
|
|
7756
|
-
const abortController = new AbortController();
|
|
7757
|
-
subscriptionAbortRef.current = abortController;
|
|
7758
|
-
try {
|
|
7759
|
-
setRuntimeError(null);
|
|
7760
|
-
let resumeThread = null;
|
|
7761
|
-
if (options.buildThreadStartParams) {
|
|
7762
|
-
const response = await appServerSession.threadStart(
|
|
7763
|
-
options.buildThreadStartParams({ threadId })
|
|
7764
|
-
);
|
|
7765
|
-
resumeThread = response.thread;
|
|
7766
|
-
} else {
|
|
7767
|
-
const response = await appServerSession.threadResume({ threadId });
|
|
7768
|
-
resumeThread = response.thread;
|
|
7769
|
-
}
|
|
7770
|
-
if (!isCurrentLifecycle(abortController)) {
|
|
7771
|
-
return;
|
|
7772
|
-
}
|
|
7773
|
-
const currentSnapshot = threadSnapshotRef.current;
|
|
7774
|
-
const handoffSnapshot = currentSnapshot?.thread?.id === threadId && threadEventSnapshotHasStarted(currentSnapshot) ? currentSnapshot : options.initialState?.thread?.id === threadId ? options.initialState : null;
|
|
7775
|
-
const shouldDeferVisibleResumeSnapshot = Boolean(pendingComposerSendRef.current) && !handoffSnapshot && currentSnapshot === null;
|
|
7776
|
-
const handoffWorkStartedAt = activeRuntimeStartedAtRef.current ?? localDispatchStartedAtRef.current;
|
|
7777
|
-
if (handoffWorkStartedAt) {
|
|
7778
|
-
setActiveRuntimeStartedAt((current) => current ?? handoffWorkStartedAt);
|
|
7779
|
-
}
|
|
7780
|
-
if (!handoffSnapshot) {
|
|
7781
|
-
threadStoreRef.current = ThreadEventStore.fromThread(resumeThread);
|
|
7782
|
-
}
|
|
7783
|
-
const storedThread = options.threadReader ? await options.threadReader.readThread({
|
|
7784
|
-
thread_id: threadId,
|
|
7785
|
-
include_archived: false,
|
|
7786
|
-
include_history: false
|
|
7787
|
-
}) : storedThreadFromAppServerThread(resumeThread);
|
|
7788
|
-
const tokenUsageReplay = options.threadReader ? await storedTokenUsageReplayNotification({
|
|
7789
|
-
thread: resumeThread,
|
|
7790
|
-
threadId,
|
|
7791
|
-
threadReader: options.threadReader
|
|
7792
|
-
}) : null;
|
|
7793
|
-
if (!isCurrentLifecycle(abortController)) {
|
|
7794
|
-
return;
|
|
7795
|
-
}
|
|
7796
|
-
setActiveThread(storedThread);
|
|
7797
|
-
options.onActiveThread?.(storedThread);
|
|
7798
|
-
const store = threadStoreRef.current ?? ThreadEventStore.fromThread(resumeThread);
|
|
7799
|
-
threadStoreRef.current = store;
|
|
7800
|
-
if (tokenUsageReplay) {
|
|
7801
|
-
store.applyNotification(tokenUsageReplay);
|
|
7802
|
-
}
|
|
7803
|
-
const nextSnapshot = store.setConnectionStatus(
|
|
7804
|
-
input.force ? "reconnecting" : "connecting"
|
|
7805
|
-
);
|
|
7806
|
-
if (!shouldDeferVisibleResumeSnapshot) {
|
|
7807
|
-
threadSnapshotRef.current = nextSnapshot;
|
|
7808
|
-
setThreadSnapshot(nextSnapshot);
|
|
7809
|
-
if (threadEventSnapshotHasStarted(nextSnapshot)) {
|
|
7810
|
-
window.setTimeout(() => handleThreadStarted(nextSnapshot), 0);
|
|
7811
|
-
}
|
|
7812
|
-
}
|
|
7813
|
-
const events = appServerSession.events();
|
|
7814
|
-
if (!events) {
|
|
7815
|
-
setProtocolConnectionStatus("connected");
|
|
7816
|
-
return;
|
|
7817
|
-
}
|
|
7818
|
-
if (shouldDeferVisibleResumeSnapshot) {
|
|
7819
|
-
store.setConnectionStatus("connected");
|
|
7820
|
-
} else {
|
|
7821
|
-
setProtocolConnectionStatus("connected");
|
|
7822
|
-
}
|
|
7823
|
-
const iterator = events[Symbol.asyncIterator]();
|
|
7824
|
-
activeEventsIteratorRef.current = iterator;
|
|
7825
|
-
void (async () => {
|
|
7826
|
-
try {
|
|
7827
|
-
while (true) {
|
|
7828
|
-
const result = await iterator.next();
|
|
7829
|
-
if (!isCurrentLifecycle(abortController)) {
|
|
7830
|
-
return;
|
|
7831
|
-
}
|
|
7832
|
-
if (result.done) {
|
|
7833
|
-
break;
|
|
7834
|
-
}
|
|
7835
|
-
applyAppServerEvent(result.value, {
|
|
7836
|
-
applyServerNotification,
|
|
7837
|
-
applyServerRequest,
|
|
7838
|
-
onServerRequest: options.onServerRequest
|
|
7839
|
-
});
|
|
7840
|
-
}
|
|
7841
|
-
if (isCurrentLifecycle(abortController)) {
|
|
7842
|
-
setProtocolConnectionStatus("closed");
|
|
7843
|
-
}
|
|
7844
|
-
} catch (error) {
|
|
7845
|
-
if (isCurrentLifecycle(abortController)) {
|
|
7846
|
-
handleRuntimeError(
|
|
7847
|
-
error instanceof Error ? error : new Error("Codex chat connection failed.")
|
|
7848
|
-
);
|
|
7849
|
-
}
|
|
7850
|
-
} finally {
|
|
7851
|
-
if (activeEventsIteratorRef.current === iterator) {
|
|
7852
|
-
activeEventsIteratorRef.current = null;
|
|
7853
|
-
}
|
|
7854
|
-
}
|
|
7855
|
-
})();
|
|
7856
|
-
} catch (error) {
|
|
7857
|
-
if (isCurrentLifecycle(abortController)) {
|
|
7858
|
-
handleRuntimeError(
|
|
7859
|
-
error instanceof Error ? error : new Error("Codex chat could not connect.")
|
|
7860
|
-
);
|
|
7861
|
-
}
|
|
7711
|
+
const providerLabel = status.displayName?.trim() || (status.driver ? formatProviderDriverKindLabel(status.driver) : "Codex");
|
|
7712
|
+
const defaultMessage = status.status === "error" ? `${providerLabel} provider is unavailable.` : `${providerLabel} provider has limited availability.`;
|
|
7713
|
+
const title = `${providerLabel} provider status`;
|
|
7714
|
+
return /* @__PURE__ */ jsx("div", { className: "mx-auto max-w-3xl pt-3", children: /* @__PURE__ */ jsxs(Alert, { variant: status.status === "error" ? "destructive" : "default", children: [
|
|
7715
|
+
/* @__PURE__ */ jsx(CircleAlertIcon, { "aria-hidden": "true" }),
|
|
7716
|
+
/* @__PURE__ */ jsx(AlertTitle, { children: title }),
|
|
7717
|
+
/* @__PURE__ */ jsx(
|
|
7718
|
+
AlertDescription,
|
|
7719
|
+
{
|
|
7720
|
+
className: "line-clamp-3",
|
|
7721
|
+
title: status.message ?? defaultMessage,
|
|
7722
|
+
children: status.message ?? defaultMessage
|
|
7862
7723
|
}
|
|
7863
|
-
},
|
|
7864
|
-
[
|
|
7865
|
-
appServerSession,
|
|
7866
|
-
applyServerNotification,
|
|
7867
|
-
applyServerRequest,
|
|
7868
|
-
closeActiveSubscription,
|
|
7869
|
-
handleRuntimeError,
|
|
7870
|
-
handleThreadStarted,
|
|
7871
|
-
options,
|
|
7872
|
-
setProtocolConnectionStatus,
|
|
7873
|
-
threadId
|
|
7874
|
-
]
|
|
7875
|
-
);
|
|
7876
|
-
useEffect(() => {
|
|
7877
|
-
if (options.connectOnMount === false) {
|
|
7878
|
-
closeActiveSubscription();
|
|
7879
|
-
setActiveThread(null);
|
|
7880
|
-
options.onActiveThread?.(null);
|
|
7881
|
-
setRuntimeError(null);
|
|
7882
|
-
if (!pendingComposerSendRef.current) {
|
|
7883
|
-
setActiveRuntimeStartedAt(null);
|
|
7884
|
-
threadStoreRef.current = null;
|
|
7885
|
-
threadSnapshotRef.current = null;
|
|
7886
|
-
setThreadSnapshot(null);
|
|
7887
|
-
setIsSending(false);
|
|
7888
|
-
}
|
|
7889
|
-
return;
|
|
7890
|
-
}
|
|
7891
|
-
void connectThread({ force: reconnectToken > 0 });
|
|
7892
|
-
return () => {
|
|
7893
|
-
closeActiveSubscription();
|
|
7894
|
-
};
|
|
7895
|
-
}, [closeActiveSubscription, connectThread, options, options.connectOnMount, reconnectToken]);
|
|
7896
|
-
useEffect(() => {
|
|
7897
|
-
if (!threadSnapshot?.turns.length || optimisticUserMessages.length === 0) {
|
|
7898
|
-
return;
|
|
7899
|
-
}
|
|
7900
|
-
const serverUserMessages = threadSnapshot.turns.flatMap(
|
|
7901
|
-
(turn) => turn.items.flatMap(
|
|
7902
|
-
(item) => item.type === "userMessage" ? [
|
|
7903
|
-
{
|
|
7904
|
-
contentFingerprint: protocolUserInputFingerprint(item.content),
|
|
7905
|
-
id: item.id
|
|
7906
|
-
}
|
|
7907
|
-
] : []
|
|
7908
|
-
)
|
|
7909
|
-
);
|
|
7910
|
-
const serverUserMessageIds = new Set(
|
|
7911
|
-
serverUserMessages.map((message) => message.id)
|
|
7912
|
-
);
|
|
7913
|
-
const serverUserMessageFingerprints = new Set(
|
|
7914
|
-
serverUserMessages.map((message) => message.contentFingerprint)
|
|
7915
|
-
);
|
|
7916
|
-
const acknowledgedOptimisticIds = optimisticUserMessages.flatMap((message) => {
|
|
7917
|
-
if (message.threadId !== threadId) {
|
|
7918
|
-
return [];
|
|
7919
|
-
}
|
|
7920
|
-
if (serverUserMessageIds.has(message.item.id)) {
|
|
7921
|
-
return [message.item.id];
|
|
7922
|
-
}
|
|
7923
|
-
return serverUserMessageFingerprints.has(
|
|
7924
|
-
coreUserInputFingerprint(message.item.content)
|
|
7925
|
-
) ? [message.item.id] : [];
|
|
7926
|
-
});
|
|
7927
|
-
if (acknowledgedOptimisticIds.length === 0) {
|
|
7928
|
-
return;
|
|
7929
|
-
}
|
|
7930
|
-
const timerId = window.setTimeout(() => {
|
|
7931
|
-
setOptimisticUserMessages(
|
|
7932
|
-
(current) => current.filter(
|
|
7933
|
-
(message) => !acknowledgedOptimisticIds.includes(message.item.id)
|
|
7934
|
-
)
|
|
7935
|
-
);
|
|
7936
|
-
}, 0);
|
|
7937
|
-
return () => window.clearTimeout(timerId);
|
|
7938
|
-
}, [optimisticUserMessages, threadId, threadSnapshot?.turns]);
|
|
7939
|
-
useEffect(() => {
|
|
7940
|
-
const timerId = window.setTimeout(() => {
|
|
7941
|
-
setOptimisticUserMessages((current) => {
|
|
7942
|
-
const next = current.filter((message) => message.threadId === threadId);
|
|
7943
|
-
return next.length === current.length ? current : next;
|
|
7944
|
-
});
|
|
7945
|
-
}, 0);
|
|
7946
|
-
return () => window.clearTimeout(timerId);
|
|
7947
|
-
}, [threadId]);
|
|
7948
|
-
useEffect(() => {
|
|
7949
|
-
if (!serverAcknowledgedLocalDispatch) {
|
|
7950
|
-
return;
|
|
7951
|
-
}
|
|
7952
|
-
const timerId = window.setTimeout(() => {
|
|
7953
|
-
resetLocalDispatch();
|
|
7954
|
-
sendInFlightRef.current = false;
|
|
7955
|
-
setIsSending(false);
|
|
7956
|
-
}, 0);
|
|
7957
|
-
return () => window.clearTimeout(timerId);
|
|
7958
|
-
}, [resetLocalDispatch, serverAcknowledgedLocalDispatch]);
|
|
7959
|
-
const connectionStatus = threadSnapshot?.connectionStatus ?? "idle";
|
|
7960
|
-
const turnRunning = Boolean(threadSnapshot?.activeTurnIds.length);
|
|
7961
|
-
const assistantStreaming = deriveAssistantStreaming(threadSnapshot);
|
|
7962
|
-
const isWorking = deriveChatLifecycleWorkingState({
|
|
7963
|
-
connectionStatus,
|
|
7964
|
-
isSendBusy,
|
|
7965
|
-
threadState: threadSnapshot
|
|
7966
|
-
});
|
|
7967
|
-
const activeWorkStartedAt = deriveActiveWorkStartedAt({
|
|
7968
|
-
isWorking,
|
|
7969
|
-
runtimeStartedAt: activeRuntimeStartedAt,
|
|
7970
|
-
sendStartedAt: localDispatchStartedAt
|
|
7971
|
-
});
|
|
7972
|
-
useEffect(() => {
|
|
7973
|
-
if (isWorking || activeRuntimeStartedAt === null) {
|
|
7974
|
-
return;
|
|
7975
|
-
}
|
|
7976
|
-
const timerId = window.setTimeout(() => {
|
|
7977
|
-
setActiveRuntimeStartedAt(null);
|
|
7978
|
-
}, 0);
|
|
7979
|
-
return () => window.clearTimeout(timerId);
|
|
7980
|
-
}, [activeRuntimeStartedAt, isWorking]);
|
|
7981
|
-
const resolveServerRequest = useCallback(
|
|
7982
|
-
async (requestId, response) => {
|
|
7983
|
-
try {
|
|
7984
|
-
await appServerSession.resolveServerRequest(requestId, response);
|
|
7985
|
-
return true;
|
|
7986
|
-
} catch (error) {
|
|
7987
|
-
setRuntimeError({
|
|
7988
|
-
message: error instanceof Error ? error.message : "Codex server-request response failed.",
|
|
7989
|
-
threadId
|
|
7990
|
-
});
|
|
7991
|
-
return false;
|
|
7992
|
-
}
|
|
7993
|
-
},
|
|
7994
|
-
[appServerSession, threadId]
|
|
7995
|
-
);
|
|
7996
|
-
const rejectServerRequest = useCallback(
|
|
7997
|
-
async (requestId, error) => {
|
|
7998
|
-
try {
|
|
7999
|
-
await appServerSession.rejectServerRequest(requestId, error);
|
|
8000
|
-
return true;
|
|
8001
|
-
} catch (rejectError) {
|
|
8002
|
-
setRuntimeError({
|
|
8003
|
-
message: rejectError instanceof Error ? rejectError.message : "Codex server-request rejection failed.",
|
|
8004
|
-
threadId
|
|
8005
|
-
});
|
|
8006
|
-
return false;
|
|
8007
|
-
}
|
|
8008
|
-
},
|
|
8009
|
-
[appServerSession, threadId]
|
|
8010
|
-
);
|
|
8011
|
-
const sendComposerMessage = useCallback(
|
|
8012
|
-
async (sendContext, controls, sendOptions = {}) => {
|
|
8013
|
-
if (sendInFlightRef.current || isSending || isSendBusy) {
|
|
8014
|
-
return;
|
|
8015
|
-
}
|
|
8016
|
-
if (sendContext.items.length === 0 && sendContext.files.length === 0) {
|
|
8017
|
-
return;
|
|
8018
|
-
}
|
|
8019
|
-
sendInFlightRef.current = true;
|
|
8020
|
-
setIsSending(true);
|
|
8021
|
-
beginLocalDispatch();
|
|
8022
|
-
try {
|
|
8023
|
-
const imageUrls = await Promise.all(sendContext.files.map(fileToDataUrl));
|
|
8024
|
-
const clientMessageId = defaultId();
|
|
8025
|
-
const turnStartParams = (options.buildTurnStartParams ?? createDefaultTurnStartParams)({
|
|
8026
|
-
clientMessageId,
|
|
8027
|
-
imageUrls,
|
|
8028
|
-
interactionMode: sendOptions.interactionMode,
|
|
8029
|
-
runtimeMode: sendOptions.runtimeMode,
|
|
8030
|
-
sendContext,
|
|
8031
|
-
threadId
|
|
8032
|
-
});
|
|
8033
|
-
const optimisticItemId = optimisticUserMessageIdForClientMessageId(
|
|
8034
|
-
clientMessageId
|
|
8035
|
-
);
|
|
8036
|
-
const optimisticMessage = buildOptimisticUserMessageTurnItem({
|
|
8037
|
-
id: optimisticItemId,
|
|
8038
|
-
imageUrls,
|
|
8039
|
-
items: sendContext.items
|
|
8040
|
-
});
|
|
8041
|
-
pendingComposerSendRef.current = {
|
|
8042
|
-
optimisticItemId,
|
|
8043
|
-
restore: () => controls.restoreComposer(sendContext),
|
|
8044
|
-
serverUserMessageAcknowledged: false,
|
|
8045
|
-
targetThreadId: threadId
|
|
8046
|
-
};
|
|
8047
|
-
await controls.prepareForOptimisticAppend();
|
|
8048
|
-
setOptimisticUserMessages((current) => [
|
|
8049
|
-
...current.filter((message) => message.item.id !== optimisticItemId),
|
|
8050
|
-
{ item: optimisticMessage, threadId }
|
|
8051
|
-
]);
|
|
8052
|
-
controls.clearComposer();
|
|
8053
|
-
options.onThreadListChanged?.();
|
|
8054
|
-
if (options.connectOnMount === false || !threadSnapshotRef.current) {
|
|
8055
|
-
await connectThread({ force: true });
|
|
8056
|
-
}
|
|
8057
|
-
const activeTurnId = currentActiveTurnId(threadSnapshotRef.current);
|
|
8058
|
-
if (activeTurnId) {
|
|
8059
|
-
await appServerSession.turnSteer({
|
|
8060
|
-
expectedTurnId: activeTurnId,
|
|
8061
|
-
input: turnStartParams.input,
|
|
8062
|
-
threadId
|
|
8063
|
-
});
|
|
8064
|
-
} else {
|
|
8065
|
-
await appServerSession.turnStart(turnStartParams);
|
|
8066
|
-
}
|
|
8067
|
-
} catch (error) {
|
|
8068
|
-
restorePendingComposerSend();
|
|
8069
|
-
pendingComposerSendRef.current = null;
|
|
8070
|
-
sendInFlightRef.current = false;
|
|
8071
|
-
resetLocalDispatch();
|
|
8072
|
-
setActiveRuntimeStartedAt(null);
|
|
8073
|
-
setIsSending(false);
|
|
8074
|
-
setRuntimeError({
|
|
8075
|
-
message: error instanceof Error ? error.message : "Codex could not send the message.",
|
|
8076
|
-
threadId
|
|
8077
|
-
});
|
|
8078
|
-
}
|
|
8079
|
-
},
|
|
8080
|
-
[
|
|
8081
|
-
beginLocalDispatch,
|
|
8082
|
-
appServerSession,
|
|
8083
|
-
connectThread,
|
|
8084
|
-
isSendBusy,
|
|
8085
|
-
isSending,
|
|
8086
|
-
options,
|
|
8087
|
-
resetLocalDispatch,
|
|
8088
|
-
restorePendingComposerSend,
|
|
8089
|
-
threadId
|
|
8090
|
-
]
|
|
8091
|
-
);
|
|
8092
|
-
const interrupt = useCallback(async () => {
|
|
8093
|
-
const turnId = currentActiveTurnId(threadSnapshotRef.current);
|
|
8094
|
-
if (!turnId) {
|
|
8095
|
-
setRuntimeError({
|
|
8096
|
-
message: "Codex has no active response to stop.",
|
|
8097
|
-
threadId
|
|
8098
|
-
});
|
|
8099
|
-
return false;
|
|
8100
|
-
}
|
|
8101
|
-
try {
|
|
8102
|
-
await appServerSession.turnInterrupt({ threadId, turnId });
|
|
8103
|
-
} catch (error) {
|
|
8104
|
-
setRuntimeError({
|
|
8105
|
-
message: error instanceof Error ? error.message : "Codex could not stop the active response.",
|
|
8106
|
-
threadId
|
|
8107
|
-
});
|
|
8108
|
-
return false;
|
|
8109
|
-
}
|
|
8110
|
-
if (pendingComposerSendRef.current) {
|
|
8111
|
-
removeOptimisticUserMessage(pendingComposerSendRef.current.optimisticItemId);
|
|
8112
|
-
}
|
|
8113
|
-
pendingComposerSendRef.current = null;
|
|
8114
|
-
sendInFlightRef.current = false;
|
|
8115
|
-
resetLocalDispatch();
|
|
8116
|
-
setActiveRuntimeStartedAt(null);
|
|
8117
|
-
setIsSending(false);
|
|
8118
|
-
return true;
|
|
8119
|
-
}, [appServerSession, removeOptimisticUserMessage, resetLocalDispatch, threadId]);
|
|
8120
|
-
const compact = useCallback(async () => {
|
|
8121
|
-
if (turnRunning || isSending || isSendBusy) {
|
|
8122
|
-
setRuntimeError({
|
|
8123
|
-
message: "Wait for the current response to finish before compacting.",
|
|
8124
|
-
threadId
|
|
8125
|
-
});
|
|
8126
|
-
return false;
|
|
8127
|
-
}
|
|
8128
|
-
try {
|
|
8129
|
-
await appServerSession.threadCompactStart({ threadId });
|
|
8130
|
-
return true;
|
|
8131
|
-
} catch (error) {
|
|
8132
|
-
setRuntimeError({
|
|
8133
|
-
message: error instanceof Error ? error.message : "Codex compact failed.",
|
|
8134
|
-
threadId
|
|
8135
|
-
});
|
|
8136
|
-
return false;
|
|
8137
|
-
}
|
|
8138
|
-
}, [appServerSession, isSendBusy, isSending, threadId, turnRunning]);
|
|
8139
|
-
const reconnect = useCallback(() => {
|
|
8140
|
-
closeActiveSubscription();
|
|
8141
|
-
if (pendingComposerSendRef.current) {
|
|
8142
|
-
removeOptimisticUserMessage(pendingComposerSendRef.current.optimisticItemId);
|
|
8143
|
-
}
|
|
8144
|
-
pendingComposerSendRef.current = null;
|
|
8145
|
-
sendInFlightRef.current = false;
|
|
8146
|
-
setIsSending(false);
|
|
8147
|
-
resetLocalDispatch();
|
|
8148
|
-
setActiveRuntimeStartedAt(null);
|
|
8149
|
-
setRuntimeError(null);
|
|
8150
|
-
setProtocolConnectionStatus("reconnecting");
|
|
8151
|
-
setReconnectToken((current) => current + 1);
|
|
8152
|
-
}, [
|
|
8153
|
-
closeActiveSubscription,
|
|
8154
|
-
removeOptimisticUserMessage,
|
|
8155
|
-
resetLocalDispatch,
|
|
8156
|
-
setProtocolConnectionStatus
|
|
8157
|
-
]);
|
|
8158
|
-
return {
|
|
8159
|
-
activeThread,
|
|
8160
|
-
activeWorkStartedAt,
|
|
8161
|
-
assistantStreaming,
|
|
8162
|
-
compact,
|
|
8163
|
-
connectionStatus,
|
|
8164
|
-
interrupt,
|
|
8165
|
-
isSendBusy,
|
|
8166
|
-
isSending,
|
|
8167
|
-
isWorking,
|
|
8168
|
-
pendingPermissionRequestActive: Boolean(
|
|
8169
|
-
threadSnapshot?.pendingRequests.some(
|
|
8170
|
-
(request) => request.method === "item/permissions/requestApproval"
|
|
8171
|
-
)
|
|
8172
|
-
),
|
|
8173
|
-
pendingUserInputActive: Boolean(
|
|
8174
|
-
threadSnapshot?.pendingRequests.some(
|
|
8175
|
-
(request) => request.method === "item/tool/requestUserInput"
|
|
8176
|
-
)
|
|
8177
|
-
),
|
|
8178
|
-
reconnect,
|
|
8179
|
-
rejectServerRequest,
|
|
8180
|
-
runtimeError: visibleRuntimeError,
|
|
8181
|
-
sendComposerMessage,
|
|
8182
|
-
resolveServerRequest,
|
|
8183
|
-
threadSnapshot,
|
|
8184
|
-
threadId,
|
|
8185
|
-
turnRunning,
|
|
8186
|
-
visibleOptimisticUserMessages
|
|
8187
|
-
};
|
|
8188
|
-
}
|
|
8189
|
-
function normalizeThreadId(threadId) {
|
|
8190
|
-
return typeof threadId === "string" ? asThreadId(threadId) : threadId;
|
|
8191
|
-
}
|
|
8192
|
-
function optimisticUserMessageIdForClientMessageId(clientMessageId) {
|
|
8193
|
-
return `user-${clientMessageId}`;
|
|
8194
|
-
}
|
|
8195
|
-
function fileToDataUrl(file) {
|
|
8196
|
-
const blob = new Blob([file], { type: file.type || "image/png" });
|
|
8197
|
-
return new Promise((resolve, reject) => {
|
|
8198
|
-
const reader = new FileReader();
|
|
8199
|
-
reader.onload = () => resolve(String(reader.result));
|
|
8200
|
-
reader.onerror = () => reject(reader.error ?? new Error("Could not read file."));
|
|
8201
|
-
reader.readAsDataURL(blob);
|
|
8202
|
-
});
|
|
8203
|
-
}
|
|
8204
|
-
function defaultId() {
|
|
8205
|
-
return globalThis.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random()}`;
|
|
8206
|
-
}
|
|
8207
|
-
function currentActiveTurnId(snapshot) {
|
|
8208
|
-
return snapshot?.activeTurnIds.at(-1) ?? null;
|
|
8209
|
-
}
|
|
8210
|
-
function protocolUserInputFingerprint(items) {
|
|
8211
|
-
return JSON.stringify(items.map(protocolUserInputFingerprintPart));
|
|
8212
|
-
}
|
|
8213
|
-
function protocolUserInputFingerprintPart(item) {
|
|
8214
|
-
switch (item.type) {
|
|
8215
|
-
case "text":
|
|
8216
|
-
return { text: item.text, type: "text" };
|
|
8217
|
-
case "image":
|
|
8218
|
-
return { type: "image", url: item.url };
|
|
8219
|
-
case "localImage":
|
|
8220
|
-
return { path: item.path, type: "localImage" };
|
|
8221
|
-
case "skill":
|
|
8222
|
-
return { name: item.name, path: item.path, type: "skill" };
|
|
8223
|
-
case "mention":
|
|
8224
|
-
return { name: item.name, path: item.path, type: "mention" };
|
|
8225
|
-
}
|
|
8226
|
-
}
|
|
8227
|
-
function coreUserInputFingerprint(items) {
|
|
8228
|
-
return JSON.stringify(items.map(coreUserInputFingerprintPart));
|
|
8229
|
-
}
|
|
8230
|
-
function coreUserInputFingerprintPart(item) {
|
|
8231
|
-
switch (item.type) {
|
|
8232
|
-
case "text":
|
|
8233
|
-
return { text: item.text, type: "text" };
|
|
8234
|
-
case "image":
|
|
8235
|
-
return { type: "image", url: item.image_url };
|
|
8236
|
-
case "local_image":
|
|
8237
|
-
return { path: item.path, type: "localImage" };
|
|
8238
|
-
case "skill":
|
|
8239
|
-
return { name: item.name, path: item.path, type: "skill" };
|
|
8240
|
-
case "mention":
|
|
8241
|
-
return { name: item.name, path: item.path, type: "mention" };
|
|
8242
|
-
}
|
|
8243
|
-
}
|
|
8244
|
-
function composerUserInputToProtocolUserInput(item) {
|
|
8245
|
-
switch (item.type) {
|
|
8246
|
-
case "text":
|
|
8247
|
-
return {
|
|
8248
|
-
text: item.text,
|
|
8249
|
-
text_elements: (item.text_elements ?? []).map((element) => ({
|
|
8250
|
-
byteRange: element.byte_range,
|
|
8251
|
-
placeholder: element.placeholder ?? null
|
|
8252
|
-
})),
|
|
8253
|
-
type: "text"
|
|
8254
|
-
};
|
|
8255
|
-
case "image":
|
|
8256
|
-
return { type: "image", url: item.image_url };
|
|
8257
|
-
case "local_image":
|
|
8258
|
-
return { path: item.path, type: "localImage" };
|
|
8259
|
-
case "skill":
|
|
8260
|
-
return { name: item.name, path: item.path, type: "skill" };
|
|
8261
|
-
case "mention":
|
|
8262
|
-
return { name: item.name, path: item.path, type: "mention" };
|
|
8263
|
-
}
|
|
8264
|
-
}
|
|
8265
|
-
async function storedTokenUsageReplayNotification(input) {
|
|
8266
|
-
try {
|
|
8267
|
-
const history = await input.threadReader.loadHistory({
|
|
8268
|
-
thread_id: input.threadId,
|
|
8269
|
-
include_archived: false
|
|
8270
|
-
});
|
|
8271
|
-
return thread_token_usage_updated_notification_from_rollout_items({
|
|
8272
|
-
rolloutItems: history.items,
|
|
8273
|
-
thread: input.thread,
|
|
8274
|
-
threadId: input.threadId
|
|
8275
|
-
});
|
|
8276
|
-
} catch {
|
|
8277
|
-
return null;
|
|
8278
|
-
}
|
|
8279
|
-
}
|
|
8280
|
-
function storedThreadFromAppServerThread(thread) {
|
|
8281
|
-
return {
|
|
8282
|
-
thread_id: asThreadId(thread.id),
|
|
8283
|
-
rollout_path: thread.path ?? null,
|
|
8284
|
-
forked_from_id: thread.forkedFromId ? asThreadId(thread.forkedFromId) : null,
|
|
8285
|
-
preview: thread.preview,
|
|
8286
|
-
name: thread.name,
|
|
8287
|
-
model_provider: thread.modelProvider,
|
|
8288
|
-
model: null,
|
|
8289
|
-
reasoning_effort: null,
|
|
8290
|
-
created_at: new Date(thread.createdAt * 1e3).toISOString(),
|
|
8291
|
-
updated_at: new Date(thread.updatedAt * 1e3).toISOString(),
|
|
8292
|
-
archived_at: null,
|
|
8293
|
-
cwd: thread.cwd,
|
|
8294
|
-
cli_version: thread.cliVersion,
|
|
8295
|
-
source: typeof thread.source === "string" ? thread.source : "custom",
|
|
8296
|
-
thread_source: typeof thread.threadSource === "string" ? thread.threadSource : null,
|
|
8297
|
-
agent_nickname: thread.agentNickname,
|
|
8298
|
-
agent_role: thread.agentRole,
|
|
8299
|
-
git_info: thread.gitInfo,
|
|
8300
|
-
history: null
|
|
8301
|
-
};
|
|
8302
|
-
}
|
|
8303
|
-
function applyAppServerEvent(event, handlers) {
|
|
8304
|
-
switch (event.type) {
|
|
8305
|
-
case "server_notification":
|
|
8306
|
-
handlers.applyServerNotification(event.notification);
|
|
8307
|
-
return;
|
|
8308
|
-
case "server_request":
|
|
8309
|
-
handlers.applyServerRequest(event.request);
|
|
8310
|
-
handlers.onServerRequest?.(event.request);
|
|
8311
|
-
return;
|
|
8312
|
-
case "disconnected":
|
|
8313
|
-
throw new Error(event.message);
|
|
8314
|
-
case "lagged":
|
|
8315
|
-
return;
|
|
8316
|
-
}
|
|
8317
|
-
}
|
|
8318
|
-
|
|
8319
|
-
// src/components/codex-chat-render-state.ts
|
|
8320
|
-
function createCodexChatRenderState({
|
|
8321
|
-
interactionMode = "default",
|
|
8322
|
-
lifecycle,
|
|
8323
|
-
snapshot
|
|
8324
|
-
}) {
|
|
8325
|
-
const activeTurnIds = new Set(snapshot?.activeTurnIds ?? []);
|
|
8326
|
-
const turns = (snapshot?.turns ?? []).map(
|
|
8327
|
-
(turn) => t3TurnFromAppServerTurn(turn, activeTurnIds.has(turn.id))
|
|
8328
|
-
);
|
|
8329
|
-
const pendingRequests = (snapshot?.pendingRequests ?? []).map(codexChatPendingRequest);
|
|
8330
|
-
const pendingDynamicToolCallRequests = pendingRequests.flatMap(
|
|
8331
|
-
(request) => request.kind === "dynamicToolCall" ? [request.compatRequest] : []
|
|
8332
|
-
);
|
|
8333
|
-
const pendingPermissionRequest = pendingRequests.find((request) => request.kind === "permissions") ?? null;
|
|
8334
|
-
const pendingUserInputRequest = pendingRequests.find((request) => request.kind === "userInput") ?? null;
|
|
8335
|
-
const activeTurnStartedAt = lifecycle?.activeWorkStartedAt ?? null;
|
|
8336
|
-
const errors = snapshot?.errors ?? [];
|
|
8337
|
-
const isWorking = lifecycle?.isWorking ?? false;
|
|
8338
|
-
const optimisticUserMessages = lifecycle?.visibleOptimisticUserMessages ?? [];
|
|
8339
|
-
const runtimeError = lifecycle?.runtimeError ?? null;
|
|
8340
|
-
const warnings = snapshot?.warnings ?? [];
|
|
8341
|
-
const activeProposedPlan = findActiveProposedPlan(snapshot);
|
|
8342
|
-
const contextWindow = deriveContextWindowSnapshotFromTokenUsage({
|
|
8343
|
-
tokenUsage: snapshot?.tokenUsage?.tokenUsage,
|
|
8344
|
-
updatedAt: snapshot?.tokenUsage?.updatedAt
|
|
8345
|
-
});
|
|
8346
|
-
const banners = defaultRenderBanners({
|
|
8347
|
-
pendingRequests,
|
|
8348
|
-
runtimeError
|
|
8349
|
-
});
|
|
8350
|
-
return {
|
|
8351
|
-
activeProposedPlan,
|
|
8352
|
-
activeTurnStartedAt,
|
|
8353
|
-
banners,
|
|
8354
|
-
composer: {
|
|
8355
|
-
contextWindow,
|
|
8356
|
-
pendingUserInput: pendingUserInputRequest?.pendingUserInput ?? null,
|
|
8357
|
-
pendingUserInputAdapter: pendingUserInputRequest
|
|
8358
|
-
},
|
|
8359
|
-
errors,
|
|
8360
|
-
interactionMode,
|
|
8361
|
-
items: turns.flatMap((turn) => turn.items),
|
|
8362
|
-
isWorking,
|
|
8363
|
-
optimisticUserMessages,
|
|
8364
|
-
pending_dynamic_tool_call_requests: pendingDynamicToolCallRequests,
|
|
8365
|
-
pendingRequests,
|
|
8366
|
-
pendingPermissionRequest,
|
|
8367
|
-
pendingUserInputRequest,
|
|
8368
|
-
runtimeError,
|
|
8369
|
-
running_turn_ids: snapshot?.activeTurnIds ?? [],
|
|
8370
|
-
showPlanFollowUpPrompt: interactionMode === "plan" && Boolean(activeProposedPlan) && !isWorking && !pendingUserInputRequest,
|
|
8371
|
-
timeline: {
|
|
8372
|
-
activeTurnStartedAt,
|
|
8373
|
-
errors,
|
|
8374
|
-
isWorking,
|
|
8375
|
-
optimisticUserMessages,
|
|
8376
|
-
runtimeError,
|
|
8377
|
-
turns,
|
|
8378
|
-
warnings
|
|
8379
|
-
},
|
|
8380
|
-
turns,
|
|
8381
|
-
warnings
|
|
8382
|
-
};
|
|
8383
|
-
}
|
|
8384
|
-
function findActiveProposedPlan(snapshot) {
|
|
8385
|
-
if (!snapshot) {
|
|
8386
|
-
return null;
|
|
8387
|
-
}
|
|
8388
|
-
for (const turn of [...snapshot.turns].reverse()) {
|
|
8389
|
-
for (const item of [...turn.items].reverse()) {
|
|
8390
|
-
if (item.type !== "plan" || item.text.trim().length === 0) {
|
|
8391
|
-
continue;
|
|
8392
|
-
}
|
|
8393
|
-
return {
|
|
8394
|
-
id: `${turn.id}:${item.id}`,
|
|
8395
|
-
planMarkdown: item.text,
|
|
8396
|
-
title: proposedPlanTitle(item.text),
|
|
8397
|
-
turnId: turn.id
|
|
8398
|
-
};
|
|
8399
|
-
}
|
|
8400
|
-
}
|
|
8401
|
-
return null;
|
|
8402
|
-
}
|
|
8403
|
-
function codexChatPendingRequest(request) {
|
|
8404
|
-
switch (request.method) {
|
|
8405
|
-
case "item/tool/requestUserInput":
|
|
8406
|
-
return {
|
|
8407
|
-
kind: "userInput",
|
|
8408
|
-
itemId: request.params.itemId,
|
|
8409
|
-
pendingUserInput: pendingUserInputFromServerRequest(request),
|
|
8410
|
-
request,
|
|
8411
|
-
requestId: request.id,
|
|
8412
|
-
threadId: request.params.threadId,
|
|
8413
|
-
turnId: request.params.turnId
|
|
8414
|
-
};
|
|
8415
|
-
case "item/permissions/requestApproval":
|
|
8416
|
-
return {
|
|
8417
|
-
kind: "permissions",
|
|
8418
|
-
composerRequest: requestPermissionsFromServerRequest(request),
|
|
8419
|
-
request,
|
|
8420
|
-
requestId: request.id,
|
|
8421
|
-
threadId: request.params.threadId,
|
|
8422
|
-
turnId: request.params.turnId
|
|
8423
|
-
};
|
|
8424
|
-
case "item/tool/call":
|
|
8425
|
-
return {
|
|
8426
|
-
kind: "dynamicToolCall",
|
|
8427
|
-
compatRequest: {
|
|
8428
|
-
arguments: request.params.arguments,
|
|
8429
|
-
call_id: request.params.callId,
|
|
8430
|
-
namespace: request.params.namespace,
|
|
8431
|
-
tool: request.params.tool,
|
|
8432
|
-
turn_id: request.params.turnId
|
|
8433
|
-
},
|
|
8434
|
-
request,
|
|
8435
|
-
requestId: request.id,
|
|
8436
|
-
threadId: request.params.threadId,
|
|
8437
|
-
turnId: request.params.turnId
|
|
8438
|
-
};
|
|
8439
|
-
case "mcpServer/elicitation/request":
|
|
8440
|
-
return {
|
|
8441
|
-
kind: "mcpElicitation",
|
|
8442
|
-
request,
|
|
8443
|
-
requestId: request.id,
|
|
8444
|
-
threadId: request.params.threadId,
|
|
8445
|
-
turnId: request.params.turnId
|
|
8446
|
-
};
|
|
8447
|
-
case "item/commandExecution/requestApproval":
|
|
8448
|
-
return {
|
|
8449
|
-
kind: "commandApproval",
|
|
8450
|
-
request,
|
|
8451
|
-
requestId: request.id,
|
|
8452
|
-
threadId: request.params.threadId,
|
|
8453
|
-
turnId: request.params.turnId
|
|
8454
|
-
};
|
|
8455
|
-
case "item/fileChange/requestApproval":
|
|
8456
|
-
return {
|
|
8457
|
-
kind: "fileChangeApproval",
|
|
8458
|
-
request,
|
|
8459
|
-
requestId: request.id,
|
|
8460
|
-
threadId: request.params.threadId,
|
|
8461
|
-
turnId: request.params.turnId
|
|
8462
|
-
};
|
|
8463
|
-
case "account/chatgptAuthTokens/refresh":
|
|
8464
|
-
return {
|
|
8465
|
-
kind: "chatgptAuthTokensRefresh",
|
|
8466
|
-
request,
|
|
8467
|
-
requestId: request.id,
|
|
8468
|
-
threadId: null,
|
|
8469
|
-
turnId: null
|
|
8470
|
-
};
|
|
8471
|
-
case "applyPatchApproval":
|
|
8472
|
-
return {
|
|
8473
|
-
kind: "applyPatchApproval",
|
|
8474
|
-
request,
|
|
8475
|
-
requestId: request.id,
|
|
8476
|
-
threadId: request.params.conversationId,
|
|
8477
|
-
turnId: null
|
|
8478
|
-
};
|
|
8479
|
-
case "execCommandApproval":
|
|
8480
|
-
return {
|
|
8481
|
-
kind: "execCommandApproval",
|
|
8482
|
-
request,
|
|
8483
|
-
requestId: request.id,
|
|
8484
|
-
threadId: request.params.conversationId,
|
|
8485
|
-
turnId: null
|
|
8486
|
-
};
|
|
8487
|
-
}
|
|
8488
|
-
}
|
|
8489
|
-
function defaultRenderBanners({
|
|
8490
|
-
pendingRequests,
|
|
8491
|
-
runtimeError
|
|
8492
|
-
}) {
|
|
8493
|
-
const banners = [];
|
|
8494
|
-
if (runtimeError) {
|
|
8495
|
-
banners.push({
|
|
8496
|
-
id: "runtime-error",
|
|
8497
|
-
title: "Codex connection interrupted",
|
|
8498
|
-
description: runtimeError,
|
|
8499
|
-
variant: "error",
|
|
8500
|
-
tone: "destructive"
|
|
8501
|
-
});
|
|
8502
|
-
}
|
|
8503
|
-
for (const request of pendingRequests) {
|
|
8504
|
-
if (request.kind === "userInput" || request.kind === "dynamicToolCall") {
|
|
8505
|
-
continue;
|
|
8506
|
-
}
|
|
8507
|
-
if (request.kind === "permissions") {
|
|
8508
|
-
banners.push({
|
|
8509
|
-
id: `request-permissions:${request.requestId}`,
|
|
8510
|
-
request,
|
|
8511
|
-
title: "Permissions requested",
|
|
8512
|
-
description: "Codex requested extra permissions. Approval controls are not available yet, so the request was denied for this turn.",
|
|
8513
|
-
variant: "warning"
|
|
8514
|
-
});
|
|
8515
|
-
continue;
|
|
8516
|
-
}
|
|
8517
|
-
banners.push({
|
|
8518
|
-
id: `server-request:${request.requestId}`,
|
|
8519
|
-
request,
|
|
8520
|
-
title: "Codex needs input",
|
|
8521
|
-
description: `No default renderer is available for ${request.request.method}.`,
|
|
8522
|
-
variant: "warning"
|
|
8523
|
-
});
|
|
8524
|
-
}
|
|
8525
|
-
return banners;
|
|
8526
|
-
}
|
|
8527
|
-
function t3TurnFromAppServerTurn(turn, isActive) {
|
|
8528
|
-
return {
|
|
8529
|
-
completed_at: epochMillis(turn.completedAt),
|
|
8530
|
-
duration_ms: turn.durationMs,
|
|
8531
|
-
error: turn.error ? {
|
|
8532
|
-
additional_details: turn.error.additionalDetails,
|
|
8533
|
-
codex_error_info: turn.error.codexErrorInfo,
|
|
8534
|
-
message: turn.error.message
|
|
8535
|
-
} : null,
|
|
8536
|
-
id: turn.id,
|
|
8537
|
-
items: turn.items.flatMap((item) => t3TurnItemFromThreadItem(item, isActive)),
|
|
8538
|
-
items_view: turn.itemsView === "notLoaded" ? "not_loaded" : turn.itemsView,
|
|
8539
|
-
started_at: epochMillis(turn.startedAt),
|
|
8540
|
-
status: t3TurnStatusFromAppServer(turn.status)
|
|
8541
|
-
};
|
|
8542
|
-
}
|
|
8543
|
-
function t3TurnItemFromThreadItem(item, turnIsActive) {
|
|
8544
|
-
switch (item.type) {
|
|
8545
|
-
case "userMessage":
|
|
8546
|
-
return [
|
|
8547
|
-
{
|
|
8548
|
-
content: item.content.map(coreUserInputFromAppServer),
|
|
8549
|
-
id: item.id,
|
|
8550
|
-
type: "UserMessage"
|
|
8551
|
-
}
|
|
8552
|
-
];
|
|
8553
|
-
case "agentMessage":
|
|
8554
|
-
return [
|
|
8555
|
-
{
|
|
8556
|
-
content: [{ text: item.text, type: "Text" }],
|
|
8557
|
-
id: item.id,
|
|
8558
|
-
memory_citation: item.memoryCitation ? {
|
|
8559
|
-
entries: item.memoryCitation.entries,
|
|
8560
|
-
rolloutIds: item.memoryCitation.threadIds
|
|
8561
|
-
} : null,
|
|
8562
|
-
phase: turnIsActive && item.text.trim().length > 0 ? "streaming" : item.phase,
|
|
8563
|
-
type: "AgentMessage"
|
|
8564
|
-
}
|
|
8565
|
-
];
|
|
8566
|
-
case "plan":
|
|
8567
|
-
return [{ id: item.id, text: item.text, type: "Plan" }];
|
|
8568
|
-
case "reasoning":
|
|
8569
|
-
return [
|
|
8570
|
-
{
|
|
8571
|
-
id: item.id,
|
|
8572
|
-
raw_content: item.content,
|
|
8573
|
-
summary_text: item.summary,
|
|
8574
|
-
type: "Reasoning"
|
|
8575
|
-
}
|
|
8576
|
-
];
|
|
8577
|
-
case "commandExecution":
|
|
8578
|
-
return [
|
|
8579
|
-
{
|
|
8580
|
-
command: [item.command],
|
|
8581
|
-
cwd: item.cwd,
|
|
8582
|
-
duration_ms: item.durationMs,
|
|
8583
|
-
exit_code: item.exitCode,
|
|
8584
|
-
id: item.id,
|
|
8585
|
-
status: item.status === "inProgress" ? "in_progress" : item.status === "declined" ? "cancelled" : item.status,
|
|
8586
|
-
stdout: item.aggregatedOutput ?? "",
|
|
8587
|
-
type: "CommandExecution"
|
|
8588
|
-
}
|
|
8589
|
-
];
|
|
8590
|
-
case "fileChange":
|
|
8591
|
-
return [
|
|
8592
|
-
{
|
|
8593
|
-
auto_approved: false,
|
|
8594
|
-
changes: {},
|
|
8595
|
-
id: item.id,
|
|
8596
|
-
status: item.status === "completed" || item.status === "failed" || item.status === "declined" ? item.status : null,
|
|
8597
|
-
stderr: "",
|
|
8598
|
-
stdout: "",
|
|
8599
|
-
type: "FileChange"
|
|
8600
|
-
}
|
|
8601
|
-
];
|
|
8602
|
-
case "dynamicToolCall":
|
|
8603
|
-
return [
|
|
8604
|
-
{
|
|
8605
|
-
arguments: item.arguments,
|
|
8606
|
-
content_items: item.contentItems,
|
|
8607
|
-
duration: item.durationMs === null ? null : String(item.durationMs),
|
|
8608
|
-
id: item.id,
|
|
8609
|
-
namespace: item.namespace,
|
|
8610
|
-
status: item.status,
|
|
8611
|
-
success: item.success,
|
|
8612
|
-
tool: item.tool,
|
|
8613
|
-
type: "DynamicToolCall"
|
|
8614
|
-
}
|
|
8615
|
-
];
|
|
8616
|
-
case "contextCompaction":
|
|
8617
|
-
return [{ id: item.id, type: "ContextCompaction" }];
|
|
8618
|
-
default:
|
|
8619
|
-
return [];
|
|
8620
|
-
}
|
|
8621
|
-
}
|
|
8622
|
-
function pendingUserInputFromServerRequest(request) {
|
|
8623
|
-
return {
|
|
8624
|
-
itemId: request.params.itemId,
|
|
8625
|
-
questions: request.params.questions.map((question) => {
|
|
8626
|
-
const normalized = normalizePendingUserInputQuestion(question);
|
|
8627
|
-
return {
|
|
8628
|
-
...normalized,
|
|
8629
|
-
options: normalized.options.map((option) => ({ ...option }))
|
|
8630
|
-
};
|
|
8631
|
-
}),
|
|
8632
|
-
requestId: request.id,
|
|
8633
|
-
threadId: request.params.threadId,
|
|
8634
|
-
turnId: request.params.turnId
|
|
8635
|
-
};
|
|
8636
|
-
}
|
|
8637
|
-
function requestPermissionsFromServerRequest(request) {
|
|
8638
|
-
return {
|
|
8639
|
-
call_id: String(request.id),
|
|
8640
|
-
cwd: request.params.cwd,
|
|
8641
|
-
permissions: request.params.permissions,
|
|
8642
|
-
reason: request.params.reason,
|
|
8643
|
-
turn_id: request.params.turnId
|
|
8644
|
-
};
|
|
8645
|
-
}
|
|
8646
|
-
function coreUserInputFromAppServer(input) {
|
|
8647
|
-
if (input.type === "image") {
|
|
8648
|
-
return { image_url: input.url, type: "image" };
|
|
8649
|
-
}
|
|
8650
|
-
if (input.type === "localImage") {
|
|
8651
|
-
return { path: input.path, type: "local_image" };
|
|
8652
|
-
}
|
|
8653
|
-
if (input.type === "text") {
|
|
8654
|
-
return {
|
|
8655
|
-
text: input.text,
|
|
8656
|
-
text_elements: input.text_elements.map((element) => ({
|
|
8657
|
-
byte_range: element.byteRange,
|
|
8658
|
-
placeholder: element.placeholder ?? void 0
|
|
8659
|
-
})),
|
|
8660
|
-
type: "text"
|
|
8661
|
-
};
|
|
8662
|
-
}
|
|
8663
|
-
return {
|
|
8664
|
-
text: input.name,
|
|
8665
|
-
text_elements: [],
|
|
8666
|
-
type: "text"
|
|
8667
|
-
};
|
|
8668
|
-
}
|
|
8669
|
-
function t3TurnStatusFromAppServer(status) {
|
|
8670
|
-
return status === "inProgress" ? "in_progress" : status;
|
|
8671
|
-
}
|
|
8672
|
-
function epochMillis(value) {
|
|
8673
|
-
return typeof value === "number" ? value * 1e3 : null;
|
|
8674
|
-
}
|
|
8675
|
-
function CodexChatView(props) {
|
|
8676
|
-
if (isLifecycleCodexChatViewProps(props)) {
|
|
8677
|
-
return createElement(CodexLifecycleChatView, props);
|
|
8678
|
-
}
|
|
8679
|
-
const { composer, ...chatViewProps } = props;
|
|
8680
|
-
return createElement(
|
|
8681
|
-
TooltipProvider,
|
|
8682
|
-
null,
|
|
8683
|
-
createElement(ChatView, {
|
|
8684
|
-
...chatViewProps,
|
|
8685
|
-
composer: createElement(ChatComposer, composer)
|
|
8686
|
-
})
|
|
8687
|
-
);
|
|
8688
|
-
}
|
|
8689
|
-
function CodexLifecycleChatView({
|
|
8690
|
-
actions,
|
|
8691
|
-
bannerItems = [],
|
|
8692
|
-
className,
|
|
8693
|
-
composerCommands,
|
|
8694
|
-
composerSkills,
|
|
8695
|
-
composerDraftKey,
|
|
8696
|
-
composerRef: externalComposerRef,
|
|
8697
|
-
defaultInteractionMode = "default",
|
|
8698
|
-
defaultRuntimeMode = "full-access",
|
|
8699
|
-
editorAriaLabel,
|
|
8700
|
-
headerLeading,
|
|
8701
|
-
interactionMode,
|
|
8702
|
-
isEnvironmentUnavailable = false,
|
|
8703
|
-
listRef: externalListRef,
|
|
8704
|
-
lifecycle: lifecycleOptions,
|
|
8705
|
-
mentionRefs,
|
|
8706
|
-
modelOptions,
|
|
8707
|
-
placeholder,
|
|
8708
|
-
providerStatus = null,
|
|
8709
|
-
realtimeConversation,
|
|
8710
|
-
renderBannerItems,
|
|
8711
|
-
renderPendingRequest,
|
|
8712
|
-
renderPendingUserInput,
|
|
8713
|
-
renderTimelineExtras,
|
|
8714
|
-
runtimeMode,
|
|
8715
|
-
showInteractionModeToggle = true,
|
|
8716
|
-
showPlanToggle = false,
|
|
8717
|
-
planSidebarLabel = "Plan",
|
|
8718
|
-
planSidebarOpen = false,
|
|
8719
|
-
subtitle,
|
|
8720
|
-
threadKey,
|
|
8721
|
-
title,
|
|
8722
|
-
onCommand,
|
|
8723
|
-
onComposerError,
|
|
8724
|
-
onControlsChange,
|
|
8725
|
-
onInteractionModeChange,
|
|
8726
|
-
onRuntimeModeChange,
|
|
8727
|
-
onTogglePlanSidebar,
|
|
8728
|
-
onImplementProposedPlan,
|
|
8729
|
-
onIsAtEndChange
|
|
8730
|
-
}) {
|
|
8731
|
-
const lifecycle = useCodexChatLifecycle(lifecycleOptions);
|
|
8732
|
-
const [localInteractionMode, setLocalInteractionMode] = useState(defaultInteractionMode);
|
|
8733
|
-
const [localRuntimeMode, setLocalRuntimeMode] = useState(defaultRuntimeMode);
|
|
8734
|
-
const effectiveInteractionMode = interactionMode ?? localInteractionMode;
|
|
8735
|
-
const effectiveRuntimeMode = runtimeMode ?? localRuntimeMode;
|
|
8736
|
-
const setInteractionMode = useCallback(
|
|
8737
|
-
(nextMode) => {
|
|
8738
|
-
if (interactionMode === void 0) {
|
|
8739
|
-
setLocalInteractionMode(nextMode);
|
|
8740
|
-
}
|
|
8741
|
-
onInteractionModeChange?.(nextMode);
|
|
8742
|
-
},
|
|
8743
|
-
[interactionMode, onInteractionModeChange]
|
|
8744
|
-
);
|
|
8745
|
-
const setRuntimeMode = useCallback(
|
|
8746
|
-
(nextMode) => {
|
|
8747
|
-
if (runtimeMode === void 0) {
|
|
8748
|
-
setLocalRuntimeMode(nextMode);
|
|
8749
|
-
}
|
|
8750
|
-
onRuntimeModeChange?.(nextMode);
|
|
8751
|
-
},
|
|
8752
|
-
[runtimeMode, onRuntimeModeChange]
|
|
8753
|
-
);
|
|
8754
|
-
const effectiveThreadKey = threadKey ?? String(lifecycle.threadId);
|
|
8755
|
-
const effectiveComposerDraftKey = composerDraftKey ?? `codex:${String(lifecycle.threadId)}`;
|
|
8756
|
-
const effectiveEditorAriaLabel = editorAriaLabel ?? "Message Codex";
|
|
8757
|
-
const effectivePlaceholder = placeholder ?? "Ask anything, @tag files/folders, or use / to show available commands";
|
|
8758
|
-
const effectiveTitle = title ?? "Codex";
|
|
8759
|
-
const renderState = createCodexChatRenderState({
|
|
8760
|
-
interactionMode: effectiveInteractionMode,
|
|
8761
|
-
lifecycle,
|
|
8762
|
-
snapshot: lifecycle.threadSnapshot
|
|
8763
|
-
});
|
|
8764
|
-
const activeProposedPlan = renderState.activeProposedPlan;
|
|
8765
|
-
const showPlanFollowUpPrompt = renderState.showPlanFollowUpPrompt && Boolean(activeProposedPlan);
|
|
8766
|
-
const pendingUserInput = renderState.composer.pendingUserInputAdapter;
|
|
8767
|
-
const pendingRequestRenderItems = renderPendingRequest ? renderState.pendingRequests.flatMap((request) => {
|
|
8768
|
-
if (request.kind === "userInput") {
|
|
8769
|
-
return [];
|
|
8770
|
-
}
|
|
8771
|
-
const defaultNode = defaultPendingRequestNode(request);
|
|
8772
|
-
const node = renderPendingRequest({
|
|
8773
|
-
defaultNode,
|
|
8774
|
-
reject: (error) => rejectPendingRequest(request, error),
|
|
8775
|
-
request,
|
|
8776
|
-
resolve: (result) => lifecycle.resolveServerRequest(request.requestId, result),
|
|
8777
|
-
state: renderState
|
|
8778
|
-
});
|
|
8779
|
-
if (node === defaultNode) {
|
|
8780
|
-
return [];
|
|
8781
|
-
}
|
|
8782
|
-
return node ? [{ node, request }] : [];
|
|
8783
|
-
}) : [];
|
|
8784
|
-
const customPendingRequestIds = new Set(
|
|
8785
|
-
pendingRequestRenderItems.map(({ request }) => request.requestId)
|
|
8786
|
-
);
|
|
8787
|
-
const customUserInputNode = pendingUserInput ? renderPendingUserInput?.({
|
|
8788
|
-
defaultNode: null,
|
|
8789
|
-
reject: (error) => rejectPendingRequest(pendingUserInput, error),
|
|
8790
|
-
request: pendingUserInput,
|
|
8791
|
-
resolve: (result) => lifecycle.resolveServerRequest(pendingUserInput.requestId, result),
|
|
8792
|
-
state: renderState
|
|
8793
|
-
}) : null;
|
|
8794
|
-
const timelineExtras = renderTimelineExtras?.({ state: renderState });
|
|
8795
|
-
const internalComposerRef = useRef(null);
|
|
8796
|
-
const composerRef = externalComposerRef ?? internalComposerRef;
|
|
8797
|
-
const internalListRef = useRef(null);
|
|
8798
|
-
const listRef = externalListRef ?? internalListRef;
|
|
8799
|
-
const controlsRef = useRef(null);
|
|
8800
|
-
const shouldAutoScrollRef = useRef(true);
|
|
8801
|
-
const [composerNotice, setComposerNotice] = useState(null);
|
|
8802
|
-
const setComposerDraftPrompt = useComposerDraftStore((store) => store.setPrompt);
|
|
8803
|
-
const addComposerDraftImages = useComposerDraftStore((store) => store.addImages);
|
|
8804
|
-
const setNotice = useCallback(
|
|
8805
|
-
(message) => {
|
|
8806
|
-
setComposerNotice(message);
|
|
8807
|
-
onComposerError?.(message);
|
|
8808
|
-
},
|
|
8809
|
-
[onComposerError]
|
|
8810
|
-
);
|
|
8811
|
-
const scheduleStickToBottom = useCallback(() => {
|
|
8812
|
-
controlsRef.current?.scheduleStickToBottom();
|
|
8813
|
-
}, []);
|
|
8814
|
-
function restoreComposer(sendContext) {
|
|
8815
|
-
const snapshot = composerRef.current?.readSnapshot();
|
|
8816
|
-
const composerIsEmpty = !snapshot || snapshot.value.trim().length === 0;
|
|
8817
|
-
if (!composerIsEmpty) {
|
|
8818
|
-
return;
|
|
8819
|
-
}
|
|
8820
|
-
const restoredImages = createComposerImageAttachments(sendContext.files);
|
|
8821
|
-
setComposerDraftPrompt(effectiveComposerDraftKey, sendContext.text);
|
|
8822
|
-
addComposerDraftImages(effectiveComposerDraftKey, restoredImages);
|
|
8823
|
-
composerRef.current?.setDraft({
|
|
8824
|
-
mentionBindings: sendContext.mentionBindings,
|
|
8825
|
-
message: sendContext.text
|
|
8826
|
-
});
|
|
8827
|
-
}
|
|
8828
|
-
async function sendComposerMessage() {
|
|
8829
|
-
const sendContext = composerRef.current?.getSendContext();
|
|
8830
|
-
if (!sendContext) {
|
|
8831
|
-
setNotice("Composer is not ready. Try again.");
|
|
8832
|
-
return;
|
|
8833
|
-
}
|
|
8834
|
-
const activePlan = activeProposedPlan;
|
|
8835
|
-
const shouldSubmitPlanFollowUp = Boolean(activePlan) && showPlanFollowUpPrompt && sendContext.items.length === 0 && sendContext.files.length === 0;
|
|
8836
|
-
const effectiveSendContext = shouldSubmitPlanFollowUp && activePlan ? planImplementationSendContext(sendContext, activePlan) : sendContext;
|
|
8837
|
-
const submitInteractionMode = shouldSubmitPlanFollowUp && activePlan ? resolvePlanFollowUpSubmission({
|
|
8838
|
-
draftText: sendContext.text,
|
|
8839
|
-
planMarkdown: activePlan.planMarkdown
|
|
8840
|
-
}).interactionMode : effectiveInteractionMode;
|
|
8841
|
-
if (effectiveSendContext.items.length === 0 && effectiveSendContext.files.length === 0) {
|
|
8842
|
-
return;
|
|
8843
|
-
}
|
|
8844
|
-
await lifecycle.sendComposerMessage(effectiveSendContext, {
|
|
8845
|
-
clearComposer: () => {
|
|
8846
|
-
composerRef.current?.clear();
|
|
8847
|
-
setNotice(null);
|
|
8848
|
-
},
|
|
8849
|
-
prepareForOptimisticAppend: async () => {
|
|
8850
|
-
shouldAutoScrollRef.current = true;
|
|
8851
|
-
await (controlsRef.current?.prepareForOptimisticAppend?.() ?? listRef.current?.scrollToEnd?.({ animated: false }));
|
|
8852
|
-
},
|
|
8853
|
-
restoreComposer
|
|
8854
|
-
}, { interactionMode: submitInteractionMode, runtimeMode: effectiveRuntimeMode });
|
|
8855
|
-
if (submitInteractionMode !== effectiveInteractionMode) {
|
|
8856
|
-
setInteractionMode(submitInteractionMode);
|
|
8857
|
-
}
|
|
8858
|
-
}
|
|
8859
|
-
const submitPendingUserInput = (response) => {
|
|
8860
|
-
const request = pendingUserInput;
|
|
8861
|
-
if (!request) {
|
|
8862
|
-
setNotice("Codex thread is not connected. Reconnect and try again.");
|
|
8863
|
-
return false;
|
|
8864
|
-
}
|
|
8865
|
-
void lifecycle.resolveServerRequest(request.requestId, response);
|
|
8866
|
-
return true;
|
|
8867
|
-
};
|
|
8868
|
-
const dismissPendingUserInput = () => {
|
|
8869
|
-
const request = pendingUserInput;
|
|
8870
|
-
if (!request) {
|
|
8871
|
-
return;
|
|
8872
|
-
}
|
|
8873
|
-
submitPendingUserInput(buildRequestUserInputResponse(request.pendingUserInput, {}));
|
|
8874
|
-
};
|
|
8875
|
-
function rejectPendingRequest(request, error = "Codex server request was dismissed.") {
|
|
8876
|
-
const jsonRpcError = typeof error === "string" ? { code: -32e3, message: error } : error;
|
|
8877
|
-
return lifecycle.rejectServerRequest(request.requestId, jsonRpcError);
|
|
8878
|
-
}
|
|
8879
|
-
const interrupt = useCallback(() => {
|
|
8880
|
-
void lifecycle.interrupt().then((accepted) => {
|
|
8881
|
-
if (!accepted) {
|
|
8882
|
-
setNotice(
|
|
8883
|
-
"Codex could not stop the active response. Reconnect and try again."
|
|
8884
|
-
);
|
|
8885
|
-
}
|
|
8886
|
-
});
|
|
8887
|
-
}, [lifecycle, setNotice]);
|
|
8888
|
-
const handleCommand = useCallback(
|
|
8889
|
-
(command) => {
|
|
8890
|
-
if (command === "plan") {
|
|
8891
|
-
setInteractionMode("plan");
|
|
8892
|
-
return;
|
|
8893
|
-
}
|
|
8894
|
-
if (command === "default") {
|
|
8895
|
-
setInteractionMode("default");
|
|
8896
|
-
return;
|
|
8897
|
-
}
|
|
8898
|
-
if (command === "compact") {
|
|
8899
|
-
void lifecycle.compact().then((accepted) => {
|
|
8900
|
-
if (!accepted) {
|
|
8901
|
-
setNotice("Codex thread is not connected. Reconnect and try again.");
|
|
8902
|
-
}
|
|
8903
|
-
});
|
|
8904
|
-
return;
|
|
8905
|
-
}
|
|
8906
|
-
onCommand?.(command);
|
|
8907
|
-
},
|
|
8908
|
-
[lifecycle, onCommand, setInteractionMode, setNotice]
|
|
8909
|
-
);
|
|
8910
|
-
const implementProposedPlanInNewThread = useCallback(
|
|
8911
|
-
(plan) => {
|
|
8912
|
-
onImplementProposedPlan?.(plan);
|
|
8913
|
-
},
|
|
8914
|
-
[onImplementProposedPlan]
|
|
8915
|
-
);
|
|
8916
|
-
const lifecycleBannerItems = [...bannerItems];
|
|
8917
|
-
if (composerNotice) {
|
|
8918
|
-
lifecycleBannerItems.push({
|
|
8919
|
-
id: "composer-notice",
|
|
8920
|
-
title: "Composer needs attention",
|
|
8921
|
-
description: composerNotice,
|
|
8922
|
-
variant: "warning",
|
|
8923
|
-
onDismiss: () => setNotice(null)
|
|
8924
|
-
});
|
|
8925
|
-
}
|
|
8926
|
-
if (providerStatus && providerStatus.status !== "ready" && providerStatus.status !== "disabled") {
|
|
8927
|
-
const providerLabel = providerStatus.displayName?.trim() || (providerStatus.driver ? providerStatus.driver.split(/[-_\s]+/g).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ") : "Codex");
|
|
8928
|
-
const description = providerStatus.message ?? (providerStatus.status === "error" ? `${providerLabel} provider is unavailable.` : `${providerLabel} provider has limited availability.`);
|
|
8929
|
-
lifecycleBannerItems.push({
|
|
8930
|
-
description,
|
|
8931
|
-
id: "provider-status",
|
|
8932
|
-
title: `${providerLabel} provider status`,
|
|
8933
|
-
variant: providerStatus.status === "error" ? "error" : "warning"
|
|
8934
|
-
});
|
|
8935
|
-
}
|
|
8936
|
-
lifecycleBannerItems.push(
|
|
8937
|
-
...renderState.banners.filter(
|
|
8938
|
-
(banner) => !banner.request || !customPendingRequestIds.has(banner.request.requestId)
|
|
8939
|
-
).map((banner) => ({
|
|
8940
|
-
...banner,
|
|
8941
|
-
action: banner.id === "runtime-error" ? { label: "Reconnect", onClick: lifecycle.reconnect } : void 0
|
|
8942
|
-
}))
|
|
8943
|
-
);
|
|
8944
|
-
lifecycleBannerItems.push(
|
|
8945
|
-
...pendingRequestRenderItems.map(({ node, request }) => ({
|
|
8946
|
-
id: `custom-pending-request:${request.requestId}`,
|
|
8947
|
-
title: "Codex needs input",
|
|
8948
|
-
description: node,
|
|
8949
|
-
variant: "info"
|
|
8950
|
-
}))
|
|
8951
|
-
);
|
|
8952
|
-
if (customUserInputNode) {
|
|
8953
|
-
lifecycleBannerItems.push({
|
|
8954
|
-
id: `custom-pending-request:${pendingUserInput?.requestId ?? "user-input"}`,
|
|
8955
|
-
title: "Codex needs input",
|
|
8956
|
-
description: customUserInputNode,
|
|
8957
|
-
variant: "info"
|
|
8958
|
-
});
|
|
8959
|
-
}
|
|
8960
|
-
lifecycleBannerItems.push(...renderBannerItems?.(renderState) ?? []);
|
|
8961
|
-
const effectiveActions = showInteractionModeToggle ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8962
|
-
/* @__PURE__ */ jsx(
|
|
8963
|
-
CodexInteractionModeToggle,
|
|
8964
|
-
{
|
|
8965
|
-
mode: effectiveInteractionMode,
|
|
8966
|
-
onChange: setInteractionMode
|
|
8967
|
-
}
|
|
8968
|
-
),
|
|
8969
|
-
actions
|
|
8970
|
-
] }) : actions;
|
|
8971
|
-
const chatView = /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsx(
|
|
8972
|
-
ChatView,
|
|
8973
|
-
{
|
|
8974
|
-
actions: effectiveActions,
|
|
8975
|
-
bannerItems: lifecycleBannerItems,
|
|
8976
|
-
className,
|
|
8977
|
-
headerLeading,
|
|
8978
|
-
listRef,
|
|
8979
|
-
subtitle,
|
|
8980
|
-
threadKey: effectiveThreadKey,
|
|
8981
|
-
timeline: renderState.timeline,
|
|
8982
|
-
title: effectiveTitle,
|
|
8983
|
-
onControlsChange: (controls) => {
|
|
8984
|
-
controlsRef.current = controls;
|
|
8985
|
-
onControlsChange?.(controls);
|
|
8986
|
-
},
|
|
8987
|
-
onIsAtEndChange: (isAtEnd) => {
|
|
8988
|
-
shouldAutoScrollRef.current = isAtEnd;
|
|
8989
|
-
onIsAtEndChange?.(isAtEnd);
|
|
8990
|
-
},
|
|
8991
|
-
composer: /* @__PURE__ */ jsx(
|
|
8992
|
-
ChatComposer,
|
|
8993
|
-
{
|
|
8994
|
-
ref: composerRef,
|
|
8995
|
-
contextWindow: renderState.composer.contextWindow,
|
|
8996
|
-
disabled: Boolean(lifecycle.runtimeError) || lifecycle.connectionStatus === "connecting" || lifecycle.connectionStatus === "reconnecting",
|
|
8997
|
-
draftKey: effectiveComposerDraftKey,
|
|
8998
|
-
editorAriaLabel: effectiveEditorAriaLabel,
|
|
8999
|
-
interactionMode: effectiveInteractionMode,
|
|
9000
|
-
isConnecting: lifecycle.connectionStatus === "connecting" || lifecycle.connectionStatus === "reconnecting",
|
|
9001
|
-
isEnvironmentUnavailable,
|
|
9002
|
-
isRunning: lifecycle.turnRunning,
|
|
9003
|
-
isSending: lifecycle.isSending || lifecycle.isSendBusy,
|
|
9004
|
-
mentionRefs: mentionRefs ?? [],
|
|
9005
|
-
composerCommands,
|
|
9006
|
-
composerSkills,
|
|
9007
|
-
modelOptions,
|
|
9008
|
-
pendingUserInput: customUserInputNode ? null : renderState.composer.pendingUserInput,
|
|
9009
|
-
pendingRequestDisabled: lifecycle.connectionStatus !== "connected",
|
|
9010
|
-
placeholder: effectivePlaceholder,
|
|
9011
|
-
planFollowUpTitle: activeProposedPlan?.title ?? null,
|
|
9012
|
-
planSidebarLabel,
|
|
9013
|
-
planSidebarOpen,
|
|
9014
|
-
realtimeConversation,
|
|
9015
|
-
runtimeMode: effectiveRuntimeMode,
|
|
9016
|
-
showInteractionModeToggle,
|
|
9017
|
-
showPlanFollowUpPrompt,
|
|
9018
|
-
showPlanToggle,
|
|
9019
|
-
onCommand: handleCommand,
|
|
9020
|
-
onComposerError: setNotice,
|
|
9021
|
-
onImplementPlanInNewThread: activeProposedPlan && onImplementProposedPlan ? () => implementProposedPlanInNewThread(activeProposedPlan) : void 0,
|
|
9022
|
-
onToggleInteractionMode: () => setInteractionMode(
|
|
9023
|
-
effectiveInteractionMode === "plan" ? "default" : "plan"
|
|
9024
|
-
),
|
|
9025
|
-
onRuntimeModeChange: setRuntimeMode,
|
|
9026
|
-
onTogglePlanSidebar,
|
|
9027
|
-
onPendingRequestDismiss: dismissPendingUserInput,
|
|
9028
|
-
onPendingRequestSubmit: submitPendingUserInput,
|
|
9029
|
-
onInterrupt: interrupt,
|
|
9030
|
-
scheduleStickToBottom,
|
|
9031
|
-
shouldAutoScrollRef,
|
|
9032
|
-
onSend: () => void sendComposerMessage()
|
|
9033
|
-
}
|
|
9034
|
-
)
|
|
9035
|
-
}
|
|
9036
|
-
) });
|
|
9037
|
-
if (!timelineExtras) {
|
|
9038
|
-
return chatView;
|
|
9039
|
-
}
|
|
9040
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
9041
|
-
chatView,
|
|
9042
|
-
timelineExtras
|
|
9043
|
-
] });
|
|
9044
|
-
}
|
|
9045
|
-
function isLifecycleCodexChatViewProps(props) {
|
|
9046
|
-
return "lifecycle" in props && Boolean(props.lifecycle);
|
|
9047
|
-
}
|
|
9048
|
-
function defaultPendingRequestNode(request) {
|
|
9049
|
-
if (request.kind === "permissions") {
|
|
9050
|
-
return null;
|
|
9051
|
-
}
|
|
9052
|
-
return `No default renderer is available for ${request.request.method}.`;
|
|
9053
|
-
}
|
|
9054
|
-
function CodexInteractionModeToggle({
|
|
9055
|
-
mode,
|
|
9056
|
-
onChange
|
|
9057
|
-
}) {
|
|
9058
|
-
return /* @__PURE__ */ jsxs(
|
|
9059
|
-
"div",
|
|
9060
|
-
{
|
|
9061
|
-
"aria-label": "Interaction mode",
|
|
9062
|
-
className: "flex shrink-0 items-center rounded-md border bg-background p-0.5",
|
|
9063
|
-
role: "group",
|
|
9064
|
-
children: [
|
|
9065
|
-
/* @__PURE__ */ jsx(
|
|
9066
|
-
"button",
|
|
9067
|
-
{
|
|
9068
|
-
"aria-pressed": mode === "default",
|
|
9069
|
-
className: mode === "default" ? "rounded px-2 py-1 font-medium text-foreground text-xs shadow-xs" : "rounded px-2 py-1 text-muted-foreground text-xs hover:text-foreground",
|
|
9070
|
-
type: "button",
|
|
9071
|
-
onClick: () => onChange("default"),
|
|
9072
|
-
children: "Build"
|
|
9073
|
-
}
|
|
9074
|
-
),
|
|
9075
|
-
/* @__PURE__ */ jsx(
|
|
9076
|
-
"button",
|
|
9077
|
-
{
|
|
9078
|
-
"aria-pressed": mode === "plan",
|
|
9079
|
-
className: mode === "plan" ? "rounded px-2 py-1 font-medium text-foreground text-xs shadow-xs" : "rounded px-2 py-1 text-muted-foreground text-xs hover:text-foreground",
|
|
9080
|
-
type: "button",
|
|
9081
|
-
onClick: () => onChange("plan"),
|
|
9082
|
-
children: "Plan"
|
|
9083
|
-
}
|
|
9084
|
-
)
|
|
9085
|
-
]
|
|
9086
|
-
}
|
|
9087
|
-
);
|
|
9088
|
-
}
|
|
9089
|
-
function planImplementationSendContext(sendContext, plan) {
|
|
9090
|
-
const text = buildPlanImplementationPrompt(plan.planMarkdown);
|
|
9091
|
-
return {
|
|
9092
|
-
...sendContext,
|
|
9093
|
-
files: [],
|
|
9094
|
-
items: [{ text, text_elements: [], type: "text" }],
|
|
9095
|
-
text
|
|
9096
|
-
};
|
|
9097
|
-
}
|
|
9098
|
-
|
|
9099
|
-
// src/components/codex-chat.tsx
|
|
9100
|
-
function CodexChat({
|
|
9101
|
-
appServer,
|
|
9102
|
-
buildThreadStartParams,
|
|
9103
|
-
buildTurnStartParams,
|
|
9104
|
-
connectOnMount,
|
|
9105
|
-
initialState,
|
|
9106
|
-
isRecoverableConnectionError,
|
|
9107
|
-
onActiveThread,
|
|
9108
|
-
onRuntimeError,
|
|
9109
|
-
onServerRequest,
|
|
9110
|
-
onState,
|
|
9111
|
-
onSubmittedUserMessage,
|
|
9112
|
-
onThreadListChanged,
|
|
9113
|
-
onThreadStarted,
|
|
9114
|
-
threadId,
|
|
9115
|
-
threadReader,
|
|
9116
|
-
...viewProps
|
|
9117
|
-
}) {
|
|
9118
|
-
const lifecycle = {
|
|
9119
|
-
appServer,
|
|
9120
|
-
buildThreadStartParams,
|
|
9121
|
-
buildTurnStartParams: buildTurnStartParams ?? createDefaultTurnStartParams,
|
|
9122
|
-
connectOnMount,
|
|
9123
|
-
initialState,
|
|
9124
|
-
isRecoverableConnectionError,
|
|
9125
|
-
onActiveThread,
|
|
9126
|
-
onRuntimeError,
|
|
9127
|
-
onServerRequest,
|
|
9128
|
-
onState,
|
|
9129
|
-
onSubmittedUserMessage,
|
|
9130
|
-
onThreadListChanged,
|
|
9131
|
-
onThreadStarted,
|
|
9132
|
-
threadId,
|
|
9133
|
-
threadReader
|
|
9134
|
-
};
|
|
9135
|
-
return createElement(CodexChatView, {
|
|
9136
|
-
...viewProps,
|
|
9137
|
-
lifecycle
|
|
9138
|
-
});
|
|
9139
|
-
}
|
|
9140
|
-
function CodexChatSidebar(props) {
|
|
9141
|
-
return createElement(Sidebar, props);
|
|
9142
|
-
}
|
|
9143
|
-
function CodexChatLayout({
|
|
9144
|
-
children,
|
|
9145
|
-
className,
|
|
9146
|
-
collapsible,
|
|
9147
|
-
defaultOpen,
|
|
9148
|
-
onOpenChange,
|
|
9149
|
-
open,
|
|
9150
|
-
side,
|
|
9151
|
-
sidebar
|
|
9152
|
-
}) {
|
|
9153
|
-
if (!sidebar) {
|
|
9154
|
-
return createElement(Fragment$1, null, children);
|
|
9155
|
-
}
|
|
9156
|
-
return createElement(
|
|
9157
|
-
SidebarProvider,
|
|
9158
|
-
{
|
|
9159
|
-
className,
|
|
9160
|
-
defaultOpen,
|
|
9161
|
-
onOpenChange,
|
|
9162
|
-
open
|
|
9163
|
-
},
|
|
9164
|
-
createElement(CodexChatSidebar, { collapsible, side }, sidebar),
|
|
9165
|
-
createElement(SidebarInset, null, children)
|
|
9166
|
-
);
|
|
9167
|
-
}
|
|
9168
|
-
var CodexChatContext = createContext(null);
|
|
9169
|
-
function CodexChatProvider({
|
|
9170
|
-
appServer,
|
|
9171
|
-
children,
|
|
9172
|
-
threadReader,
|
|
9173
|
-
threadId
|
|
9174
|
-
}) {
|
|
9175
|
-
const runtime = useCodexChat({ appServer, threadReader, threadId });
|
|
9176
|
-
return createElement(
|
|
9177
|
-
CodexChatContext.Provider,
|
|
9178
|
-
{ value: runtime },
|
|
9179
|
-
children
|
|
9180
|
-
);
|
|
9181
|
-
}
|
|
9182
|
-
function useCodexChatRuntime() {
|
|
9183
|
-
const runtime = useContext(CodexChatContext);
|
|
9184
|
-
if (!runtime) {
|
|
9185
|
-
throw new Error("useCodexChatRuntime must be used inside CodexChatProvider.");
|
|
9186
|
-
}
|
|
9187
|
-
return runtime;
|
|
9188
|
-
}
|
|
9189
|
-
function useCodexChat(options) {
|
|
9190
|
-
const [activeThreadId, setActiveThreadId] = useState(options.threadId ?? null);
|
|
9191
|
-
const normalizedThreadId = useMemo(
|
|
9192
|
-
() => activeThreadId ? normalizeThreadId2(activeThreadId) : asThreadId("00000000-0000-4000-8000-000000000000"),
|
|
9193
|
-
[activeThreadId]
|
|
9194
|
-
);
|
|
9195
|
-
const lifecycle = useCodexChatLifecycle({
|
|
9196
|
-
appServer: options.appServer,
|
|
9197
|
-
connectOnMount: activeThreadId !== null,
|
|
9198
|
-
threadId: normalizedThreadId,
|
|
9199
|
-
threadReader: options.threadReader
|
|
9200
|
-
});
|
|
9201
|
-
const threadState = useMemo(
|
|
9202
|
-
() => createCodexChatRenderState({
|
|
9203
|
-
lifecycle,
|
|
9204
|
-
snapshot: lifecycle.threadSnapshot
|
|
9205
|
-
}),
|
|
9206
|
-
[lifecycle]
|
|
9207
|
-
);
|
|
9208
|
-
const error = lifecycle.runtimeError ? new Error(lifecycle.runtimeError) : null;
|
|
9209
|
-
return {
|
|
9210
|
-
error,
|
|
9211
|
-
messages: messagesFromRenderState(threadState),
|
|
9212
|
-
async sendMessage(input) {
|
|
9213
|
-
if (!activeThreadId) {
|
|
9214
|
-
throw new Error("Cannot send a Codex chat message without a thread.");
|
|
9215
|
-
}
|
|
9216
|
-
const sendContext = sendContextFromMessageInput(input);
|
|
9217
|
-
await lifecycle.sendComposerMessage(sendContext, {
|
|
9218
|
-
clearComposer: () => {
|
|
9219
|
-
},
|
|
9220
|
-
prepareForOptimisticAppend: async () => {
|
|
9221
|
-
},
|
|
9222
|
-
restoreComposer: () => {
|
|
9223
|
-
}
|
|
9224
|
-
});
|
|
9225
|
-
},
|
|
9226
|
-
setThread(nextThreadId) {
|
|
9227
|
-
setActiveThreadId(nextThreadId);
|
|
9228
|
-
},
|
|
9229
|
-
status: chatRuntimeStatus(lifecycle, activeThreadId !== null),
|
|
9230
|
-
async stop() {
|
|
9231
|
-
await lifecycle.interrupt();
|
|
9232
|
-
},
|
|
9233
|
-
threadId: activeThreadId,
|
|
9234
|
-
threadSnapshot: lifecycle.threadSnapshot,
|
|
9235
|
-
threadState
|
|
9236
|
-
};
|
|
9237
|
-
}
|
|
9238
|
-
function chatRuntimeStatus(lifecycle, hasThread) {
|
|
9239
|
-
if (!hasThread) {
|
|
9240
|
-
return "idle";
|
|
9241
|
-
}
|
|
9242
|
-
if (lifecycle.runtimeError) {
|
|
9243
|
-
return "error";
|
|
9244
|
-
}
|
|
9245
|
-
if (lifecycle.connectionStatus === "connecting" || lifecycle.connectionStatus === "reconnecting") {
|
|
9246
|
-
return "loading";
|
|
9247
|
-
}
|
|
9248
|
-
if (lifecycle.isSending || lifecycle.isSendBusy) {
|
|
9249
|
-
return "submitting";
|
|
9250
|
-
}
|
|
9251
|
-
if (lifecycle.turnRunning || lifecycle.assistantStreaming) {
|
|
9252
|
-
return "streaming";
|
|
9253
|
-
}
|
|
9254
|
-
return "ready";
|
|
9255
|
-
}
|
|
9256
|
-
function sendContextFromMessageInput(input) {
|
|
9257
|
-
const text = input.text?.trim() ?? "";
|
|
9258
|
-
const files = messageInputFiles(input.files);
|
|
9259
|
-
const fileParts = input.files && !isFileList(input.files) && !isFileArray(input.files) ? input.files : [];
|
|
9260
|
-
const items = [
|
|
9261
|
-
...text ? [{
|
|
9262
|
-
text,
|
|
9263
|
-
text_elements: [],
|
|
9264
|
-
type: "text"
|
|
9265
|
-
}] : [],
|
|
9266
|
-
...fileParts.flatMap(messagePartToComposerItem)
|
|
9267
|
-
];
|
|
9268
|
-
return {
|
|
9269
|
-
effort: defaultCodexReasoningEffort,
|
|
9270
|
-
files,
|
|
9271
|
-
items,
|
|
9272
|
-
mentionBindings: [],
|
|
9273
|
-
model: defaultCodexModel,
|
|
9274
|
-
text
|
|
9275
|
-
};
|
|
9276
|
-
}
|
|
9277
|
-
function messageInputFiles(files) {
|
|
9278
|
-
if (!files) {
|
|
9279
|
-
return [];
|
|
9280
|
-
}
|
|
9281
|
-
if (isFileList(files)) {
|
|
9282
|
-
return Array.from(files);
|
|
9283
|
-
}
|
|
9284
|
-
if (isFileArray(files)) {
|
|
9285
|
-
return files;
|
|
9286
|
-
}
|
|
9287
|
-
return [];
|
|
9288
|
-
}
|
|
9289
|
-
function messagePartToComposerItem(part) {
|
|
9290
|
-
if (part.type === "image") {
|
|
9291
|
-
return [{ image_url: part.url, type: "image" }];
|
|
9292
|
-
}
|
|
9293
|
-
if (part.type === "file") {
|
|
9294
|
-
return [{ path: part.url, type: "local_image" }];
|
|
9295
|
-
}
|
|
9296
|
-
return [];
|
|
9297
|
-
}
|
|
9298
|
-
function isFileList(files) {
|
|
9299
|
-
return typeof FileList !== "undefined" && files instanceof FileList;
|
|
9300
|
-
}
|
|
9301
|
-
function isFileArray(files) {
|
|
9302
|
-
return typeof File !== "undefined" && Array.isArray(files) && files.every((file) => file instanceof File);
|
|
9303
|
-
}
|
|
9304
|
-
function messagesFromRenderState(threadState) {
|
|
9305
|
-
return threadState.items.flatMap((item) => {
|
|
9306
|
-
if (item.type === "UserMessage") {
|
|
9307
|
-
return [
|
|
9308
|
-
{
|
|
9309
|
-
id: item.id,
|
|
9310
|
-
parts: item.content.flatMap(userInputToMessageParts),
|
|
9311
|
-
role: "user"
|
|
9312
|
-
}
|
|
9313
|
-
];
|
|
9314
|
-
}
|
|
9315
|
-
if (item.type === "AgentMessage") {
|
|
9316
|
-
return [
|
|
9317
|
-
{
|
|
9318
|
-
id: item.id,
|
|
9319
|
-
parts: item.content.map((part) => ({
|
|
9320
|
-
type: "text",
|
|
9321
|
-
text: part.text
|
|
9322
|
-
})),
|
|
9323
|
-
role: "assistant"
|
|
9324
|
-
}
|
|
9325
|
-
];
|
|
9326
|
-
}
|
|
9327
|
-
return [];
|
|
9328
|
-
});
|
|
9329
|
-
}
|
|
9330
|
-
function userInputToMessageParts(input) {
|
|
9331
|
-
if (input.type === "text") {
|
|
9332
|
-
return [{ type: "text", text: input.text }];
|
|
9333
|
-
}
|
|
9334
|
-
if (input.type === "image") {
|
|
9335
|
-
return [{ type: "image", url: input.image_url }];
|
|
9336
|
-
}
|
|
9337
|
-
if (input.type === "local_image") {
|
|
9338
|
-
return [{ type: "file", url: input.path }];
|
|
9339
|
-
}
|
|
9340
|
-
return [];
|
|
9341
|
-
}
|
|
9342
|
-
function normalizeThreadId2(threadId) {
|
|
9343
|
-
return typeof threadId === "string" ? asThreadId(threadId) : threadId;
|
|
9344
|
-
}
|
|
9345
|
-
function CodexThread({ children }) {
|
|
9346
|
-
return createElement("div", { "data-codex-thread": "" }, children);
|
|
9347
|
-
}
|
|
9348
|
-
function CodexMessages() {
|
|
9349
|
-
const runtime = useCodexChatRuntime();
|
|
9350
|
-
return createElement(
|
|
9351
|
-
"div",
|
|
9352
|
-
{ "data-codex-messages": "" },
|
|
9353
|
-
runtime.messages.map(
|
|
9354
|
-
(message) => createElement(
|
|
9355
|
-
"div",
|
|
9356
|
-
{ "data-role": message.role, key: message.id },
|
|
9357
|
-
message.parts.filter((part) => part.type === "text").map((part) => part.text).join("\n")
|
|
9358
|
-
)
|
|
9359
7724
|
)
|
|
9360
|
-
);
|
|
9361
|
-
}
|
|
9362
|
-
function
|
|
9363
|
-
|
|
9364
|
-
const sendMessage = useCallback(
|
|
9365
|
-
async (formData) => {
|
|
9366
|
-
const text = String(formData.get("message") ?? "");
|
|
9367
|
-
if (text.trim()) {
|
|
9368
|
-
await runtime.sendMessage({ text });
|
|
9369
|
-
}
|
|
9370
|
-
},
|
|
9371
|
-
[runtime]
|
|
9372
|
-
);
|
|
9373
|
-
return createElement(
|
|
9374
|
-
"form",
|
|
9375
|
-
{ action: sendMessage, "data-codex-composer": "" },
|
|
9376
|
-
createElement("textarea", { name: "message" }),
|
|
9377
|
-
createElement("button", { type: "submit" }, "Send")
|
|
9378
|
-
);
|
|
7725
|
+
] }) });
|
|
7726
|
+
});
|
|
7727
|
+
function formatProviderDriverKindLabel(driver) {
|
|
7728
|
+
return driver.split(/[-_\s]+/g).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
|
|
9379
7729
|
}
|
|
9380
7730
|
|
|
9381
|
-
export {
|
|
9382
|
-
//# sourceMappingURL=chunk-
|
|
9383
|
-
//# sourceMappingURL=chunk-
|
|
7731
|
+
export { AssistantChangedFilesSection, COMPOSER_FOOTER_COMPACT_BREAKPOINT_PX, COMPOSER_FOOTER_WIDE_ACTIONS_COMPACT_BREAKPOINT_PX, COMPOSER_INLINE_CHIP_CLASS_NAME, COMPOSER_INLINE_CHIP_DISMISS_BUTTON_CLASS_NAME, COMPOSER_INLINE_CHIP_ICON_CLASS_NAME, COMPOSER_INLINE_CHIP_LABEL_CLASS_NAME, COMPOSER_INLINE_SKILL_CHIP_CLASS_NAME, COMPOSER_PRIMARY_ACTIONS_COMPACT_BREAKPOINT_PX, ChatComposer, ChatMarkdown, ChatView, CompactComposerControlsMenu, ComposerBannerStack, ComposerCommandMenu, ComposerPendingApprovalActions, ComposerPendingApprovalPanel, ComposerPendingTerminalContextChip, ComposerPendingTerminalContexts, ComposerPendingUserInputPanel, ComposerPlanFollowUpBanner, ComposerPrimaryActions, ComposerPromptEditor, ComposerRealtimeConversationControl, ExpandedImageDialog, LEGACY_PROJECT_MENTION_SIGIL, MAX_VISIBLE_WORK_LOG_ENTRIES, MessagesTimeline, ModelListRow, ModelPickerContent, PLUGIN_TEXT_MENTION_SIGIL, PROJECT_MENTION_SIGIL, ProposedPlanCard, ProviderModelPicker, ProviderStatusBanner, RecordingMeterState, SKILL_MENTION_SIGIL, TIMELINE_WORKING_ROW_ID, TOOL_MENTION_SIGIL, TerminalContextInlineChip, TooltipProvider, TraitsPicker, WORKSPACE_CHAT_MAX_IMAGE_ATTACHMENTS, WORKSPACE_CHAT_MAX_IMAGE_BYTES, assistantComposerDraftKey, buildChangedFilesTree, buildCollapsedProposedPlanPreviewMarkdown, buildExpandedImagePreview, buildModelPickerSearchText, buildOptimisticUserMessageTurnItem, buildPendingUserInputAnswers, buildPlanImplementationPrompt, buildPlanImplementationThreadTitle, buildProposedPlanMarkdownFilename, buildRequestUserInputResponse, changedFilesForFileChangeTurnItem, codexModelOptions, codexReasoningEffortOptions, composerSnapshotUserInputItems, computeStableMessagesTimelineRows, countAnsweredPendingUserInputQuestions, createComposerImageAttachments, createComposerPromptSnapshot, decodeHistoryMentions, defaultCodexModel, defaultCodexProviderInstance, defaultCodexReasoningEffort, deriveComposerSendState, deriveContextWindowSnapshotFromTokenUsage, deriveMessagesTimelineRows, derivePendingUserInputProgress, detectComposerTrigger, downloadPlanAsTextFile, encodeHistoryMentions, filterCodexModelPickerOptions, findLinkedMentions, findNextMentionTokenRange, formatPendingPrimaryActionLabel, formatTerminalContextLabel, getComposerProviderState, getRealtimeConversationControlState, hasNonZeroChangedFileStat, isAcceptedComposerImageFile, isAssistantCredentialError, isCodexReasoningEffort, isMentionNameChar, isRealtimeConversationLive, isTerminalContextExpired, legacyMentionToken, linkedMentionTextElements, mentionBindingRangesForText, mentionBindingsAfterReplacement, mentionToken, mergeOptimisticUserMessageTurnItems, messagesTimelineFingerprint, normalizeMentionBindingsForText, normalizePendingUserInputQuestion, normalizePlanMarkdownForExport, parseLinkedToolMention, parseStandaloneComposerSlashCommand, persistComposerDraftAttachments, prefillComposerState, proposedPlanTitle, readLegacyComposerDraft, renderProviderTraitsMenuContent, renderProviderTraitsPicker, replaceTextRange, resolveAssistantMessageCopyState, resolveCodexModelOption, resolveCodexReasoningEffortForModel, resolveCodexReasoningEffortOption, resolveComposerMenuActiveItemId, resolveDraftEffort, resolveDraftModel, resolvePendingUserInputAnswer, resolvePlanFollowUpSubmission, restoreComposerDraftAttachments, revokeComposerImageAttachments, scoreModelPickerSearch, searchComposerMentionTargets, searchSlashCommandItems, setPendingUserInputCustomAnswer, shouldShowWorkingRow, shouldUseCompactComposerFooter, shouldUseCompactComposerPrimaryActions, skillToken, stripDisplayedPlanMarkdown, summarizeChangedFileStats, timelineWorkEntryForTurnItem, togglePendingUserInputOptionSelection, turnItemTextForCopy, useComposerDraftStore, useComposerThreadDraft, validateComposerImageFiles, visibleTimelineWorkEntries };
|
|
7732
|
+
//# sourceMappingURL=chunk-NCI4MAWZ.js.map
|
|
7733
|
+
//# sourceMappingURL=chunk-NCI4MAWZ.js.map
|