@axhub/acp 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +4 -0
- package/.next/build-manifest.json +3 -3
- package/.next/fallback-build-manifest.json +3 -3
- package/.next/next-minimal-server.js.nft.json +1 -1
- package/.next/next-server.js.nft.json +1 -1
- package/.next/routes-manifest.json +28 -0
- package/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +2 -2
- package/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/api/acp/capabilities/route.js +5 -3
- package/.next/server/app/api/acp/capabilities/route.js.nft.json +1 -1
- package/.next/server/app/api/acp/commands/route.js +1 -1
- package/.next/server/app/api/acp/commands/route.js.nft.json +1 -1
- package/.next/server/app/api/acp/runtime/route.js.nft.json +1 -1
- package/.next/server/app/api/chat/cancel/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/chat/cancel/route/build-manifest.json +9 -0
- package/.next/server/app/api/chat/cancel/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/chat/cancel/route.js +11 -0
- package/.next/server/app/api/chat/cancel/route.js.nft.json +1 -0
- package/.next/server/app/api/chat/cancel/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/chat/resume/[streamId]/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/chat/resume/[streamId]/route/build-manifest.json +9 -0
- package/.next/server/app/api/chat/resume/[streamId]/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/chat/resume/[streamId]/route.js +11 -0
- package/.next/server/app/api/chat/resume/[streamId]/route.js.nft.json +1 -0
- package/.next/server/app/api/chat/resume/[streamId]/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/chat/route.js +5 -3
- package/.next/server/app/api/chat/route.js.nft.json +1 -1
- package/.next/server/app/api/conversations/[threadId]/messages/route.js +4 -2
- package/.next/server/app/api/conversations/[threadId]/messages/route.js.nft.json +1 -1
- package/.next/server/app/api/conversations/[threadId]/route.js +2 -2
- package/.next/server/app/api/conversations/[threadId]/route.js.nft.json +1 -1
- package/.next/server/app/api/conversations/[threadId]/runtime/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/conversations/[threadId]/runtime/route/build-manifest.json +9 -0
- package/.next/server/app/api/conversations/[threadId]/runtime/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/conversations/[threadId]/runtime/route.js +11 -0
- package/.next/server/app/api/conversations/[threadId]/runtime/route.js.nft.json +1 -0
- package/.next/server/app/api/conversations/[threadId]/runtime/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/conversations/route.js +2 -2
- package/.next/server/app/api/conversations/route.js.nft.json +1 -1
- package/.next/server/app/api/local-files/image/route.js.nft.json +1 -1
- package/.next/server/app/api/local-files/open/route.js.nft.json +1 -1
- package/.next/server/app/api/output-artifacts/thread/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/output-artifacts/thread/route/build-manifest.json +9 -0
- package/.next/server/app/api/output-artifacts/thread/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/output-artifacts/thread/route.js +8 -0
- package/.next/server/app/api/output-artifacts/thread/route.js.nft.json +1 -0
- package/.next/server/app/api/output-artifacts/thread/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/output-artifacts/workspace/route.js +1 -1
- package/.next/server/app/api/output-artifacts/workspace/route.js.nft.json +1 -1
- package/.next/server/app/api/tools/image-generation/files/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/tools/image-generation/records/route.js.nft.json +1 -1
- package/.next/server/app/api/tools/user-choice/route.js.nft.json +1 -1
- package/.next/server/app/favicon.ico/route.js.nft.json +1 -1
- package/.next/server/app/page.js +2 -2
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/session/[provider]/[sessionId]/page.js +1 -1
- package/.next/server/app/session/[provider]/[sessionId]/page.js.nft.json +1 -1
- package/.next/server/app/session/[provider]/[sessionId]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/thread/[threadId]/page.js +1 -1
- package/.next/server/app/thread/[threadId]/page.js.nft.json +1 -1
- package/.next/server/app/thread/[threadId]/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +4 -0
- package/.next/server/chunks/0zjb_server_app_api_conversations_[threadId]_runtime_route_actions_08lhdqs.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__04pn6ap._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0aovkxs._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0c.r6ru._.js +76 -0
- package/.next/server/chunks/[root-of-the-server]__0gmxr~m._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0iokgmz._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0j-lxr4._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0lbwo2g._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0ly6hop._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0ml.1wa._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0o2epta._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0os92l7._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0tmhg7j._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0txmfnw._.js +2 -2
- package/.next/server/chunks/[root-of-the-server]__0wo0b8z._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0xh8d4~._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0zmyki-._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0zn3~pq._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__13xepwb._.js +3 -0
- package/.next/server/chunks/_0_9_730._.js +107 -0
- package/.next/server/chunks/_0gx~6n6._.js +107 -0
- package/.next/server/chunks/_next-internal_server_app_api_chat_cancel_route_actions_0hdg4o_.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_chat_resume_[streamId]_route_actions_12ynw6q.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_output-artifacts_thread_route_actions_04~2mo7.js +3 -0
- package/.next/server/chunks/lib_conversations_store_ts_0gzcj38._.js +4 -4
- package/.next/server/chunks/node_modules_0nyqhq8._.js +3 -0
- package/.next/server/chunks/ssr/{[root-of-the-server]__0piffp7._.js → [root-of-the-server]__09wwymw._.js} +2 -2
- package/.next/server/chunks/ssr/{[root-of-the-server]__0488vn3._.js → [root-of-the-server]__0n6oe29._.js} +1 -1
- package/.next/server/chunks/ssr/{[root-of-the-server]__0icm-_h._.js → [root-of-the-server]__0niwg81._.js} +2 -2
- package/.next/server/chunks/ssr/_03.pm1z._.js +18 -16
- package/.next/server/chunks/ssr/_0txwi90._.js +1 -1
- package/.next/server/chunks/ssr/lib_conversations_store_ts_0-pd6d3._.js +2 -2
- package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_forbidden_0ghu-f7.js +1 -1
- package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_02suzhc.js +2 -2
- package/.next/server/functions-config-manifest.json +3 -0
- package/.next/server/instrumentation.js.nft.json +1 -1
- package/.next/server/middleware-build-manifest.js +3 -3
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/static/chunks/0btc2281yau9i.js +104 -0
- package/.next/static/chunks/0c~b2_-vk17t5.css +1 -0
- package/README.md +2 -2
- package/dist/components/assistant-ui/acp-command-menu.mjs +42 -9
- package/dist/components/assistant-ui/acp-elicitation-option-list.mjs +1 -1
- package/dist/components/assistant-ui/file.mjs +2 -2
- package/dist/components/assistant-ui/image-generation-settings-dialog.mjs +25 -6
- package/dist/components/assistant-ui/image.mjs +2 -2
- package/dist/components/assistant-ui/markdown-text.mjs +3 -3
- package/dist/components/assistant-ui/thread/composer.d.ts +1 -1
- package/dist/components/assistant-ui/thread/composer.mjs +37 -3
- package/dist/components/assistant-ui/thread/context-chips.mjs +3 -2
- package/dist/components/assistant-ui/thread/index.mjs +1 -1
- package/dist/components/assistant-ui/thread/message-list.mjs +1 -1
- package/dist/components/assistant-ui/thread/messages.mjs +2 -2
- package/dist/components/assistant-ui/thread-list.d.ts +8 -2
- package/dist/components/assistant-ui/thread-list.mjs +80 -7
- package/dist/components/assistant-ui/threadlist-sidebar.d.ts +4 -1
- package/dist/components/assistant-ui/threadlist-sidebar.mjs +2 -2
- package/dist/components/assistant-ui/tool-fallback.d.ts +1 -1
- package/dist/components/assistant-ui/tool-fallback.mjs +48 -11
- package/dist/components/tool-ui/option-list.d.ts +2 -1
- package/dist/components/tool-ui/option-list.mjs +4 -4
- package/dist/lib/acp2aisdk/client-context.d.ts +6 -0
- package/dist/lib/acp2aisdk/client-context.mjs +43 -7
- package/dist/lib/acp2aisdk/commands.mjs +5 -20
- package/dist/lib/acp2aisdk/context.d.ts +4 -0
- package/dist/lib/acp2aisdk/errors.d.ts +2 -0
- package/dist/lib/acp2aisdk/errors.mjs +37 -0
- package/dist/lib/acp2aisdk/index.d.ts +7 -0
- package/dist/lib/acp2aisdk/index.mjs +110 -34
- package/dist/lib/acp2aisdk/provider-compat.mjs +4 -2
- package/dist/lib/acp2aisdk/resumable-ui-stream.d.ts +11 -0
- package/dist/lib/acp2aisdk/resumable-ui-stream.mjs +323 -0
- package/dist/lib/acp2aisdk/runtime-message-filter.d.ts +6 -0
- package/dist/lib/acp2aisdk/runtime-message-filter.mjs +22 -0
- package/dist/lib/acp2aisdk/runtime-persistence.d.ts +21 -0
- package/dist/lib/acp2aisdk/runtime-persistence.mjs +135 -0
- package/dist/lib/acp2aisdk/session-store.mjs +7 -1
- package/dist/lib/acp2aisdk/skill-command-cache.mjs +1 -1
- package/dist/lib/api/client.d.ts +51 -4
- package/dist/lib/api/client.mjs +35 -4
- package/dist/lib/api/cors.mjs +7 -1
- package/dist/lib/api/http-response.d.ts +2 -0
- package/dist/lib/api/http-response.mjs +22 -0
- package/dist/lib/conversations/client-adapter.d.ts +1 -0
- package/dist/lib/conversations/client-adapter.mjs +158 -51
- package/dist/lib/conversations/provider-message-loader.d.ts +7 -0
- package/dist/lib/conversations/provider-message-loader.mjs +99 -0
- package/dist/lib/conversations/runtime-message-recovery.d.ts +9 -0
- package/dist/lib/conversations/runtime-message-recovery.mjs +95 -0
- package/dist/lib/conversations/store.d.ts +2 -2
- package/dist/lib/conversations/store.mjs +49 -149
- package/dist/lib/conversations/title-text.d.ts +3 -0
- package/dist/lib/conversations/title-text.mjs +81 -0
- package/dist/lib/conversations/types.d.ts +12 -1
- package/dist/lib/local-image-files.mjs +9 -1
- package/dist/lib/local-image-paths.mjs +31 -6
- package/dist/lib/output-artifacts/thread.d.ts +22 -0
- package/dist/lib/output-artifacts/thread.mjs +47 -0
- package/dist/lib/output-artifacts/workspace.mjs +6 -2
- package/dist/lib/provider-history/codex.mjs +5 -30
- package/dist/public-api/server.d.ts +1 -1
- package/dist/public-api/server.mjs +1 -1
- package/dist/tools/image-generation/client.mjs +6 -4
- package/dist/tools/image-generation/server.mjs +3 -1
- package/dist/tools/image-generation/shared.d.ts +1 -0
- package/dist/tools/image-generation/shared.mjs +4 -0
- package/dist/tools/image-generation/ui-detail.mjs +66 -2
- package/dist/tools/user-choice/ui.mjs +66 -30
- package/package.json +2 -1
- package/.next/server/chunks/[root-of-the-server]__04xq..~._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__07sxz4_._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0dwg3fr._.js +0 -178
- package/.next/server/chunks/[root-of-the-server]__0eanzwb._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0gqx~5k._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0~mtsby._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__10-n4io._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__10g507v._.js +0 -3
- package/.next/static/chunks/0zftsky7gte_9.js +0 -102
- package/.next/static/chunks/1610ha42i.fl~.css +0 -1
- /package/.next/static/{mbk_N5Gs4ZJg3lciRL6ya → Kri5x_Y9TwyCw9FEY15ME}/_buildManifest.js +0 -0
- /package/.next/static/{mbk_N5Gs4ZJg3lciRL6ya → Kri5x_Y9TwyCw9FEY15ME}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{mbk_N5Gs4ZJg3lciRL6ya → Kri5x_Y9TwyCw9FEY15ME}/_ssgManifest.js +0 -0
|
@@ -30,7 +30,7 @@ export const MessageError = () => {
|
|
|
30
30
|
export const AssistantMessage = () => {
|
|
31
31
|
const ACTION_BAR_PT = "pt-1.5";
|
|
32
32
|
const ACTION_BAR_HEIGHT = `-mb-7.5 min-h-7.5 ${ACTION_BAR_PT}`;
|
|
33
|
-
return (_jsxs(MessagePrimitive.Root, { "data-slot": "aui_assistant-message-root", "data-role": "assistant", className: "fade-in slide-in-from-bottom-1 relative animate-in duration-150 [contain-intrinsic-size:auto_300px] [content-visibility:auto]", children: [_jsxs("div", { "data-slot": "aui_assistant-message-content", className: "wrap-break-word px-
|
|
33
|
+
return (_jsxs(MessagePrimitive.Root, { "data-slot": "aui_assistant-message-root", "data-role": "assistant", className: "fade-in slide-in-from-bottom-1 relative animate-in duration-150 [contain-intrinsic-size:auto_300px] [content-visibility:auto]", children: [_jsxs("div", { "data-slot": "aui_assistant-message-content", className: "wrap-break-word px-1.5 text-sm text-foreground leading-[1.6] md:px-2 md:text-base md:leading-relaxed [&>[data-slot=image-root]]:my-2", children: [_jsx(MessagePrimitive.Parts, { children: ({ part }) => {
|
|
34
34
|
var _a;
|
|
35
35
|
if (part.type === "text")
|
|
36
36
|
return _jsx(MarkdownText, {});
|
|
@@ -57,7 +57,7 @@ export const UserMessage = () => {
|
|
|
57
57
|
const isInternalUserChoiceResult = useAuiState((state) => state.message.content.some((part) => part.type === "text" && isUserChoiceResultMessageText(part.text)));
|
|
58
58
|
if (isInternalUserChoiceResult)
|
|
59
59
|
return null;
|
|
60
|
-
return (_jsxs(MessagePrimitive.Root, { "data-slot": "aui_user-message-root", className: "fade-in slide-in-from-bottom-1 grid animate-in auto-rows-auto grid-cols-[minmax(72px,1fr)_auto] content-start gap-y-2 px-2 duration-150 [contain-intrinsic-size:auto_60px] [content-visibility:auto] [&:where(>*)]:col-start-2", "data-role": "user", children: [_jsx(UserMessageAttachments, {}), _jsxs("div", { className: "aui-user-message-content-wrapper relative col-start-2 min-w-0", children: [_jsx("div", { className: "aui-user-message-content wrap-break-word peer rounded-2xl bg-muted px-
|
|
60
|
+
return (_jsxs(MessagePrimitive.Root, { "data-slot": "aui_user-message-root", className: "fade-in slide-in-from-bottom-1 grid animate-in auto-rows-auto grid-cols-[minmax(72px,1fr)_auto] content-start gap-y-2 px-2 duration-150 [contain-intrinsic-size:auto_60px] [content-visibility:auto] [&:where(>*)]:col-start-2", "data-role": "user", children: [_jsx(UserMessageAttachments, {}), _jsxs("div", { className: "aui-user-message-content-wrapper relative col-start-2 min-w-0", children: [_jsx("div", { className: "aui-user-message-content wrap-break-word peer rounded-2xl bg-muted px-3.5 py-2 text-sm text-foreground leading-[1.55] md:px-4 md:py-2.5 md:text-base md:leading-normal empty:hidden [&>[data-slot=image-root]]:my-2", children: _jsx(MessagePrimitive.Parts, { components: { Image: ImageMessage, File } }) }), _jsx("div", { className: "aui-user-action-bar-wrapper absolute start-0 top-1/2 -translate-x-full -translate-y-1/2 pe-2 peer-empty:hidden rtl:translate-x-full", children: _jsx(UserActionBar, {}) })] }), _jsx(BranchPicker, { "data-slot": "aui_user-branch-picker", className: "col-span-full col-start-1 row-start-3 -me-1 justify-end" })] }));
|
|
61
61
|
};
|
|
62
62
|
export const UserActionBar = () => {
|
|
63
63
|
return (_jsx(ActionBarPrimitive.Root, { hideWhenRunning: true, autohide: "not-last", className: "aui-user-action-bar-root flex flex-col items-end", children: _jsx(ActionBarPrimitive.Edit, { asChild: true, children: _jsx(TooltipIconButton, { tooltip: "\u7F16\u8F91", className: "aui-user-action-edit p-4", children: _jsx(PencilIcon, {}) }) }) }));
|
|
@@ -1,2 +1,8 @@
|
|
|
1
|
-
import type
|
|
2
|
-
|
|
1
|
+
import { type FC, type MouseEventHandler } from "react";
|
|
2
|
+
type ThreadListProps = {
|
|
3
|
+
openInNewWindowHref?: string | null;
|
|
4
|
+
localNewThreadHref?: string | null;
|
|
5
|
+
onNewThreadClick?: MouseEventHandler<HTMLButtonElement>;
|
|
6
|
+
};
|
|
7
|
+
export declare const ThreadList: FC<ThreadListProps>;
|
|
8
|
+
export {};
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { AuiIf, ThreadListItemMorePrimitive, ThreadListItemPrimitive, ThreadListPrimitive, } from "@assistant-ui/react";
|
|
3
|
-
import { ArchiveIcon, MoreHorizontalIcon, PlusIcon, SettingsIcon, TrashIcon, } from "lucide-react";
|
|
3
|
+
import { AuiIf, ThreadListItemMorePrimitive, ThreadListItemPrimitive, ThreadListPrimitive, useAui, useAuiState, } from "@assistant-ui/react";
|
|
4
|
+
import { ArchiveIcon, ExternalLinkIcon, MoreHorizontalIcon, PlusIcon, SettingsIcon, TrashIcon, } from "lucide-react";
|
|
5
|
+
import { useEffect, useMemo, useRef, useState, } from "react";
|
|
4
6
|
import { ImageGenerationSettingsDialog } from "./image-generation-settings-dialog.mjs";
|
|
5
7
|
import { Button } from "../ui/button.mjs";
|
|
6
8
|
import { Skeleton } from "../ui/skeleton.mjs";
|
|
9
|
+
import { acpApiClient } from "../../lib/api/client.mjs";
|
|
7
10
|
const THREAD_LIST_SKELETON_ITEMS = [
|
|
8
11
|
"thread-list-skeleton-1",
|
|
9
12
|
"thread-list-skeleton-2",
|
|
@@ -11,11 +14,12 @@ const THREAD_LIST_SKELETON_ITEMS = [
|
|
|
11
14
|
"thread-list-skeleton-4",
|
|
12
15
|
"thread-list-skeleton-5",
|
|
13
16
|
];
|
|
14
|
-
export const ThreadList = () => {
|
|
15
|
-
return (_jsxs(ThreadListPrimitive.Root, { className: "aui-root aui-thread-list-root flex w-full min-w-0 flex-col gap-1", children: [_jsx(ThreadListNew, {}), _jsx(AuiIf, { condition: (s) => s.threads.isLoading && s.threads.threadIds.length === 0, children: _jsx(ThreadListSkeleton, {}) }), _jsxs(AuiIf, { condition: (s) => !s.threads.isLoading || s.threads.threadIds.length > 0, children: [_jsx(ThreadListPrimitive.Items, { children: () => _jsx(ThreadListItem, {}) }), _jsx(AuiIf, { condition: (s) => s.threads.hasMore, children: _jsx(ThreadListLoadMore, {}) })] })] }));
|
|
17
|
+
export const ThreadList = ({ openInNewWindowHref, localNewThreadHref, onNewThreadClick, }) => {
|
|
18
|
+
return (_jsxs(ThreadListPrimitive.Root, { className: "aui-root aui-thread-list-root flex w-full min-w-0 flex-col gap-1", children: [_jsx(ThreadListRuntimeRefresh, {}), _jsx(ThreadListNew, { openInNewWindowHref: openInNewWindowHref, localNewThreadHref: localNewThreadHref, onNewThreadClick: onNewThreadClick }), _jsx(AuiIf, { condition: (s) => s.threads.isLoading && s.threads.threadIds.length === 0, children: _jsx(ThreadListSkeleton, {}) }), _jsxs(AuiIf, { condition: (s) => !s.threads.isLoading || s.threads.threadIds.length > 0, children: [_jsx(ThreadListPrimitive.Items, { children: () => _jsx(ThreadListItem, {}) }), _jsx(AuiIf, { condition: (s) => s.threads.hasMore, children: _jsx(ThreadListLoadMore, {}) })] })] }));
|
|
16
19
|
};
|
|
17
|
-
const ThreadListNew = () => {
|
|
18
|
-
|
|
20
|
+
const ThreadListNew = ({ openInNewWindowHref, localNewThreadHref, onNewThreadClick, }) => {
|
|
21
|
+
const newThreadButton = (_jsxs(Button, { variant: "ghost", className: "aui-thread-list-new h-9 w-full min-w-0 justify-start gap-2 rounded-lg px-3 text-sm hover:bg-muted", onClick: onNewThreadClick, children: [_jsx(PlusIcon, { className: "size-4" }), _jsx("span", { className: "truncate", children: "\u65B0\u5EFA\u5BF9\u8BDD" })] }));
|
|
22
|
+
return (_jsxs("div", { className: "aui-thread-list-top-actions mb-2 flex flex-col gap-1", children: [_jsx(ImageGenerationSettingsDialog, { trigger: _jsxs(Button, { type: "button", variant: "ghost", className: "aui-thread-list-settings h-9 w-full min-w-0 justify-start gap-2 rounded-lg px-3 text-sm hover:bg-muted data-[state=open]:bg-muted", children: [_jsx(SettingsIcon, { className: "size-4" }), _jsx("span", { className: "truncate", children: "\u8BBE\u7F6E" })] }) }), localNewThreadHref ? (newThreadButton) : (_jsx(ThreadListPrimitive.New, { asChild: true, children: newThreadButton })), openInNewWindowHref ? (_jsx(Button, { asChild: true, variant: "ghost", className: "aui-thread-list-open-window h-9 w-full min-w-0 justify-start gap-2 rounded-lg px-3 text-sm hover:bg-muted", children: _jsxs("a", { href: openInNewWindowHref, target: "_blank", rel: "noopener noreferrer", children: [_jsx(ExternalLinkIcon, { className: "size-4" }), _jsx("span", { className: "truncate", children: "\u65B0\u7A97\u53E3\u6253\u5F00" })] }) })) : null] }));
|
|
19
23
|
};
|
|
20
24
|
const ThreadListSkeleton = () => {
|
|
21
25
|
return (_jsx("div", { className: "flex flex-col gap-1", children: THREAD_LIST_SKELETON_ITEMS.map((item) => (_jsx("div", { role: "status", "aria-label": "\u6B63\u5728\u52A0\u8F7D\u5BF9\u8BDD", className: "aui-thread-list-skeleton-wrapper flex h-9 items-center px-3", children: _jsx(Skeleton, { className: "aui-thread-list-skeleton h-4 w-full" }) }, item))) }));
|
|
@@ -24,7 +28,76 @@ const ThreadListLoadMore = () => {
|
|
|
24
28
|
return (_jsx(ThreadListPrimitive.LoadMore, { asChild: true, children: _jsxs(Button, { variant: "ghost", className: "aui-thread-list-load-more h-9 justify-center rounded-lg px-3 text-muted-foreground text-sm hover:bg-muted hover:text-foreground", children: [_jsx(AuiIf, { condition: (s) => !s.threads.isLoadingMore, children: "\u52A0\u8F7D\u66F4\u591A" }), _jsx(AuiIf, { condition: (s) => s.threads.isLoadingMore, children: "\u6B63\u5728\u52A0\u8F7D..." })] }) }));
|
|
25
29
|
};
|
|
26
30
|
const ThreadListItem = () => {
|
|
27
|
-
return (_jsxs(ThreadListItemPrimitive.Root, { className: "aui-thread-list-item group/thread-list-item flex h-9 w-full min-w-0 items-center rounded-lg transition-colors hover:bg-muted focus-visible:bg-muted focus-visible:outline-none data-active:bg-muted", children: [
|
|
31
|
+
return (_jsxs(ThreadListItemPrimitive.Root, { className: "aui-thread-list-item group/thread-list-item flex h-9 w-full min-w-0 items-center rounded-lg transition-colors hover:bg-muted focus-visible:bg-muted focus-visible:outline-none data-active:bg-muted", children: [_jsxs(ThreadListItemPrimitive.Trigger, { className: "aui-thread-list-item-trigger flex h-full min-w-0 flex-1 items-center px-3 text-start text-sm", children: [_jsx("span", { className: "aui-thread-list-item-title min-w-0 flex-1 truncate", children: _jsx(ThreadListItemPrimitive.Title, { fallback: "\u65B0\u5BF9\u8BDD" }) }), _jsx(ThreadListItemRunStatus, {})] }), _jsx(ThreadListItemMore, {})] }));
|
|
32
|
+
};
|
|
33
|
+
function getCustomString(custom, key) {
|
|
34
|
+
const value = custom === null || custom === void 0 ? void 0 : custom[key];
|
|
35
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
36
|
+
}
|
|
37
|
+
function getRunDisplayState(runState) {
|
|
38
|
+
return runState === "queued" || runState === "running" ? "running" : null;
|
|
39
|
+
}
|
|
40
|
+
const ThreadListRuntimeRefresh = () => {
|
|
41
|
+
const aui = useAui();
|
|
42
|
+
const isRunning = useAuiState((state) => state.thread.isRunning);
|
|
43
|
+
const previousIsRunningRef = useRef(isRunning);
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
const wasRunning = previousIsRunningRef.current;
|
|
46
|
+
previousIsRunningRef.current = isRunning;
|
|
47
|
+
if (!wasRunning || isRunning)
|
|
48
|
+
return;
|
|
49
|
+
void aui
|
|
50
|
+
.threads()
|
|
51
|
+
.reload()
|
|
52
|
+
.catch(() => { });
|
|
53
|
+
}, [aui, isRunning]);
|
|
54
|
+
return null;
|
|
55
|
+
};
|
|
56
|
+
const ThreadListItemRunStatus = () => {
|
|
57
|
+
const remoteId = useAuiState((state) => state.threadListItem.remoteId);
|
|
58
|
+
const custom = useAuiState((state) => state.threadListItem.custom);
|
|
59
|
+
const isCurrentThread = useAuiState((state) => state.threads.mainThreadId === state.threadListItem.id);
|
|
60
|
+
const currentThreadIsRunning = useAuiState((state) => state.thread.isRunning);
|
|
61
|
+
const workspacePath = getCustomString(custom, "workspacePath");
|
|
62
|
+
const currentRunSignal = isCurrentThread ? currentThreadIsRunning : null;
|
|
63
|
+
const [displayState, setDisplayState] = useState(null);
|
|
64
|
+
const [refreshToken, setRefreshToken] = useState(0);
|
|
65
|
+
const previousRuntimeRefreshRef = useRef(`${isCurrentThread}:${currentRunSignal}`);
|
|
66
|
+
const runtimeRequest = useMemo(() => ({ refreshToken, remoteId, workspacePath }), [refreshToken, remoteId, workspacePath]);
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
const signature = `${isCurrentThread}:${currentRunSignal}`;
|
|
69
|
+
if (previousRuntimeRefreshRef.current === signature)
|
|
70
|
+
return;
|
|
71
|
+
previousRuntimeRefreshRef.current = signature;
|
|
72
|
+
if (isCurrentThread)
|
|
73
|
+
setRefreshToken((value) => value + 1);
|
|
74
|
+
}, [isCurrentThread, currentRunSignal]);
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
let cancelled = false;
|
|
77
|
+
if (!runtimeRequest.remoteId) {
|
|
78
|
+
setDisplayState(null);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
void acpApiClient
|
|
82
|
+
.getConversationRuntime(runtimeRequest.remoteId, runtimeRequest.workspacePath)
|
|
83
|
+
.then((runtime) => {
|
|
84
|
+
var _a;
|
|
85
|
+
if (cancelled)
|
|
86
|
+
return;
|
|
87
|
+
setDisplayState(getRunDisplayState((_a = runtime.metadata) === null || _a === void 0 ? void 0 : _a.runState));
|
|
88
|
+
})
|
|
89
|
+
.catch(() => {
|
|
90
|
+
if (!cancelled)
|
|
91
|
+
setDisplayState(null);
|
|
92
|
+
});
|
|
93
|
+
return () => {
|
|
94
|
+
cancelled = true;
|
|
95
|
+
};
|
|
96
|
+
}, [runtimeRequest]);
|
|
97
|
+
const isRunning = displayState === "running";
|
|
98
|
+
if (!isRunning)
|
|
99
|
+
return null;
|
|
100
|
+
return (_jsx("span", { className: "aui-thread-list-item-run-status ms-2 inline-flex size-3 shrink-0 items-center justify-center", role: "img", "aria-label": "\u5BF9\u8BDD\u8FD0\u884C\u4E2D", title: "\u5BF9\u8BDD\u8FD0\u884C\u4E2D", children: _jsx("span", { className: "block size-3 animate-spin rounded-full border border-foreground/70 border-t-transparent motion-reduce:animate-none" }) }));
|
|
28
101
|
};
|
|
29
102
|
const ThreadListItemMore = () => {
|
|
30
103
|
return (_jsxs(ThreadListItemMorePrimitive.Root, { children: [_jsx(ThreadListItemMorePrimitive.Trigger, { asChild: true, children: _jsxs(Button, { variant: "ghost", size: "icon", className: "aui-thread-list-item-more me-0 h-7 w-0 overflow-hidden p-0 opacity-0 transition-[width,margin,opacity,background-color,color] group-hover/thread-list-item:me-2 group-hover/thread-list-item:w-7 group-hover/thread-list-item:opacity-100 group-focus-within/thread-list-item:me-2 group-focus-within/thread-list-item:w-7 group-focus-within/thread-list-item:opacity-100 data-[state=open]:me-2 data-[state=open]:w-7 data-[state=open]:bg-accent data-[state=open]:opacity-100", children: [_jsx(MoreHorizontalIcon, { className: "size-4" }), _jsx("span", { className: "sr-only", children: "\u66F4\u591A\u9009\u9879" })] }) }), _jsxs(ThreadListItemMorePrimitive.Content, { side: "bottom", align: "start", className: "aui-thread-list-item-more-content z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md", children: [_jsx(ThreadListItemPrimitive.Archive, { asChild: true, children: _jsxs(ThreadListItemMorePrimitive.Item, { className: "aui-thread-list-item-more-item flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground", children: [_jsx(ArchiveIcon, { className: "size-4" }), "\u5F52\u6863"] }) }), _jsx(ThreadListItemPrimitive.Delete, { asChild: true, children: _jsxs(ThreadListItemMorePrimitive.Item, { className: "aui-thread-list-item-more-item flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-destructive text-sm outline-none hover:bg-destructive/10 hover:text-destructive focus:bg-destructive/10 focus:text-destructive", children: [_jsx(TrashIcon, { className: "size-4" }), "\u5220\u9664"] }) })] })] }));
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type * as React from "react";
|
|
2
2
|
import { Sidebar } from "../ui/sidebar";
|
|
3
|
-
export declare function ThreadListSidebar({ workspacePath, workspaceTitle, ...props }: React.ComponentProps<typeof Sidebar> & {
|
|
3
|
+
export declare function ThreadListSidebar({ workspacePath, workspaceTitle, openInNewWindowHref, localNewThreadHref, onNewThreadClick, ...props }: React.ComponentProps<typeof Sidebar> & {
|
|
4
4
|
workspacePath?: string | null;
|
|
5
5
|
workspaceTitle?: string | null;
|
|
6
|
+
openInNewWindowHref?: string | null;
|
|
7
|
+
localNewThreadHref?: string | null;
|
|
8
|
+
onNewThreadClick?: React.MouseEventHandler<HTMLButtonElement>;
|
|
6
9
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -25,8 +25,8 @@ function getPathBasename(path) {
|
|
|
25
25
|
return (_a = parts[parts.length - 1]) !== null && _a !== void 0 ? _a : normalizedPath;
|
|
26
26
|
}
|
|
27
27
|
export function ThreadListSidebar(_a) {
|
|
28
|
-
var { workspacePath, workspaceTitle } = _a, props = __rest(_a, ["workspacePath", "workspaceTitle"]);
|
|
28
|
+
var { workspacePath, workspaceTitle, openInNewWindowHref, localNewThreadHref, onNewThreadClick } = _a, props = __rest(_a, ["workspacePath", "workspaceTitle", "openInNewWindowHref", "localNewThreadHref", "onNewThreadClick"]);
|
|
29
29
|
const projectPath = (workspacePath === null || workspacePath === void 0 ? void 0 : workspacePath.trim()) || "当前项目";
|
|
30
30
|
const projectTitle = (workspaceTitle === null || workspaceTitle === void 0 ? void 0 : workspaceTitle.trim()) || getPathBasename(projectPath);
|
|
31
|
-
return (_jsxs(Sidebar, Object.assign({}, props, { children: [_jsx(SidebarHeader, { className: "aui-sidebar-header mb-2 border-b", children: _jsxs("div", { className: "aui-sidebar-header-content flex items-center justify-between", children: [_jsx(SidebarMenu, { className: "min-w-0 flex-1", children: _jsx(SidebarMenuItem, { children: _jsx(SidebarMenuButton, { size: "lg", asChild: true, children: _jsxs("div", { children: [_jsx(FolderIcon, { className: "aui-sidebar-header-icon size-4" }), _jsxs("div", { className: "aui-sidebar-header-heading me-2 min-w-0 space-y-1 leading-none", children: [_jsx("span", { className: "aui-sidebar-header-title block min-w-0 truncate font-semibold", title: projectTitle, children: projectTitle }), _jsx("span", { className: "aui-sidebar-header-description block min-w-0 truncate text-sidebar-foreground/60 text-xs", title: projectPath, children: projectPath })] })] }) }) }) }), _jsx(ThemeToggle, {})] }) }), _jsx(SidebarContent, { className: "aui-sidebar-content overflow-hidden px-0", children: _jsx(ScrollArea, { className: "aui-thread-list-scroll-area min-h-0 flex-1", children: _jsx("div", { className: "aui-thread-list-scroll-content w-full min-w-0 px-2", children: _jsx(ThreadList, {}) }) }) }), _jsx(SidebarRail, {})] })));
|
|
31
|
+
return (_jsxs(Sidebar, Object.assign({}, props, { children: [_jsx(SidebarHeader, { className: "aui-sidebar-header mb-2 border-b", children: _jsxs("div", { className: "aui-sidebar-header-content flex items-center justify-between", children: [_jsx(SidebarMenu, { className: "min-w-0 flex-1", children: _jsx(SidebarMenuItem, { children: _jsx(SidebarMenuButton, { size: "lg", asChild: true, children: _jsxs("div", { children: [_jsx(FolderIcon, { className: "aui-sidebar-header-icon size-4" }), _jsxs("div", { className: "aui-sidebar-header-heading me-2 min-w-0 space-y-1 leading-none", children: [_jsx("span", { className: "aui-sidebar-header-title block min-w-0 truncate font-semibold", title: projectTitle, children: projectTitle }), _jsx("span", { className: "aui-sidebar-header-description block min-w-0 truncate text-sidebar-foreground/60 text-xs", title: projectPath, children: projectPath })] })] }) }) }) }), _jsx(ThemeToggle, {})] }) }), _jsx(SidebarContent, { className: "aui-sidebar-content overflow-hidden px-0", children: _jsx(ScrollArea, { className: "aui-thread-list-scroll-area min-h-0 flex-1", children: _jsx("div", { className: "aui-thread-list-scroll-content w-full min-w-0 px-2", children: _jsx(ThreadList, { openInNewWindowHref: openInNewWindowHref, localNewThreadHref: localNewThreadHref, onNewThreadClick: onNewThreadClick }) }) }) }), _jsx(SidebarRail, {})] })));
|
|
32
32
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ToolCallMessagePartComponent, ToolCallMessagePartStatus } from "@assistant-ui/react";
|
|
2
2
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../ui/collapsible";
|
|
3
3
|
export type ToolFallbackRootProps = Omit<React.ComponentProps<typeof Collapsible>, "open" | "onOpenChange"> & {
|
|
4
4
|
open?: boolean;
|
|
@@ -11,30 +11,67 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
11
11
|
return t;
|
|
12
12
|
};
|
|
13
13
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
-
import { useScrollLock, } from "@assistant-ui/react";
|
|
15
14
|
import { AlertCircleIcon, CheckIcon, ChevronDownIcon, LoaderIcon, XCircleIcon, } from "lucide-react";
|
|
16
|
-
import { memo, useCallback, useRef, useState } from "react";
|
|
15
|
+
import { memo, useCallback, useEffect, useRef, useState, } from "react";
|
|
17
16
|
import { AcpToolContentBlocks } from "./acp-tool-content.mjs";
|
|
18
17
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "../ui/collapsible.mjs";
|
|
19
18
|
import { cn } from "../../lib/utils.mjs";
|
|
20
19
|
const ANIMATION_DURATION = 200;
|
|
20
|
+
function useScrollPositionLock(animatedElementRef, animationDuration) {
|
|
21
|
+
const scrollContainerRef = useRef(null);
|
|
22
|
+
const cleanupRef = useRef(null);
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
return () => { var _a; return (_a = cleanupRef.current) === null || _a === void 0 ? void 0 : _a.call(cleanupRef); };
|
|
25
|
+
}, []);
|
|
26
|
+
return useCallback(() => {
|
|
27
|
+
var _a;
|
|
28
|
+
(_a = cleanupRef.current) === null || _a === void 0 ? void 0 : _a.call(cleanupRef);
|
|
29
|
+
if (!scrollContainerRef.current) {
|
|
30
|
+
let element = animatedElementRef.current;
|
|
31
|
+
while (element) {
|
|
32
|
+
const { overflowY } = getComputedStyle(element);
|
|
33
|
+
if (overflowY === "auto" || overflowY === "scroll") {
|
|
34
|
+
scrollContainerRef.current = element;
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
element = element.parentElement;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const scrollContainer = scrollContainerRef.current;
|
|
41
|
+
if (!scrollContainer)
|
|
42
|
+
return;
|
|
43
|
+
const scrollPosition = scrollContainer.scrollTop;
|
|
44
|
+
const resetPosition = () => {
|
|
45
|
+
scrollContainer.scrollTop = scrollPosition;
|
|
46
|
+
};
|
|
47
|
+
scrollContainer.addEventListener("scroll", resetPosition);
|
|
48
|
+
const timeoutId = window.setTimeout(() => {
|
|
49
|
+
scrollContainer.removeEventListener("scroll", resetPosition);
|
|
50
|
+
cleanupRef.current = null;
|
|
51
|
+
}, animationDuration);
|
|
52
|
+
cleanupRef.current = () => {
|
|
53
|
+
window.clearTimeout(timeoutId);
|
|
54
|
+
scrollContainer.removeEventListener("scroll", resetPosition);
|
|
55
|
+
};
|
|
56
|
+
}, [animatedElementRef, animationDuration]);
|
|
57
|
+
}
|
|
21
58
|
function ToolFallbackRoot(_a) {
|
|
22
59
|
var { className, open: controlledOpen, onOpenChange: controlledOnOpenChange, defaultOpen = false, children } = _a, props = __rest(_a, ["className", "open", "onOpenChange", "defaultOpen", "children"]);
|
|
23
60
|
const collapsibleRef = useRef(null);
|
|
24
61
|
const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
|
|
25
|
-
const
|
|
62
|
+
const lockScrollPosition = useScrollPositionLock(collapsibleRef, ANIMATION_DURATION);
|
|
26
63
|
const isControlled = controlledOpen !== undefined;
|
|
27
64
|
const isOpen = isControlled ? controlledOpen : uncontrolledOpen;
|
|
28
65
|
const handleOpenChange = useCallback((open) => {
|
|
29
66
|
if (!open) {
|
|
30
|
-
|
|
67
|
+
lockScrollPosition();
|
|
31
68
|
}
|
|
32
69
|
if (!isControlled) {
|
|
33
70
|
setUncontrolledOpen(open);
|
|
34
71
|
}
|
|
35
72
|
controlledOnOpenChange === null || controlledOnOpenChange === void 0 ? void 0 : controlledOnOpenChange(open);
|
|
36
|
-
}, [
|
|
37
|
-
return (_jsx(Collapsible, Object.assign({ ref: collapsibleRef, "data-slot": "tool-fallback-root", open: isOpen, onOpenChange: handleOpenChange, className: cn("aui-tool-fallback-root group/tool-fallback-root my-2
|
|
73
|
+
}, [lockScrollPosition, isControlled, controlledOnOpenChange]);
|
|
74
|
+
return (_jsx(Collapsible, Object.assign({ ref: collapsibleRef, "data-slot": "tool-fallback-root", open: isOpen, onOpenChange: handleOpenChange, className: cn("aui-tool-fallback-root group/tool-fallback-root my-2 w-full rounded-lg border py-2.5 first:mt-0 last:mb-0 md:my-2.5 md:py-3", className), style: {
|
|
38
75
|
"--animation-duration": `${ANIMATION_DURATION}ms`,
|
|
39
76
|
} }, props, { children: children })));
|
|
40
77
|
}
|
|
@@ -59,23 +96,23 @@ function ToolFallbackTrigger(_a) {
|
|
|
59
96
|
const Icon = statusIconMap[statusType];
|
|
60
97
|
const label = isCancelled ? "已取消工具" : "已使用工具";
|
|
61
98
|
const toolLabel = _jsx("b", { children: toolName });
|
|
62
|
-
return (_jsxs(CollapsibleTrigger, Object.assign({ "data-slot": "tool-fallback-trigger", "aria-label": `${label}: ${toolName}`, className: cn("aui-tool-fallback-trigger group/trigger flex w-full items-center gap-2 px-
|
|
99
|
+
return (_jsxs(CollapsibleTrigger, Object.assign({ "data-slot": "tool-fallback-trigger", "aria-label": `${label}: ${toolName}`, className: cn("aui-tool-fallback-trigger group/trigger flex w-full items-center gap-2 px-3 text-[13px] transition-colors md:px-4 md:text-sm", className) }, props, { children: [_jsx(Icon, { "data-slot": "tool-fallback-trigger-icon", className: cn("aui-tool-fallback-trigger-icon size-3.5 shrink-0 md:size-4", isCancelled && "text-muted-foreground", isRunning && "animate-spin") }), _jsxs("span", { "data-slot": "tool-fallback-trigger-label", className: cn("aui-tool-fallback-trigger-label-wrapper relative min-w-0 flex-1 text-start leading-snug", isCancelled && "text-muted-foreground line-through"), title: toolName, children: [_jsx("span", { className: "aui-tool-fallback-trigger-label line-clamp-2 break-words", children: toolLabel }), isRunning && (_jsx("span", { "aria-hidden": true, "data-slot": "tool-fallback-trigger-shimmer", className: "aui-tool-fallback-trigger-shimmer shimmer pointer-events-none absolute inset-0 line-clamp-2 break-words motion-reduce:animate-none", children: toolLabel }))] }), _jsx(ChevronDownIcon, { "data-slot": "tool-fallback-trigger-chevron", className: cn("aui-tool-fallback-trigger-chevron size-3.5 shrink-0 md:size-4", "transition-transform duration-(--animation-duration) ease-out", "group-data-[state=closed]/trigger:-rotate-90", "group-data-[state=open]/trigger:rotate-0") })] })));
|
|
63
100
|
}
|
|
64
101
|
function ToolFallbackContent(_a) {
|
|
65
102
|
var { className, children } = _a, props = __rest(_a, ["className", "children"]);
|
|
66
|
-
return (_jsx(CollapsibleContent, Object.assign({ "data-slot": "tool-fallback-content", className: cn("aui-tool-fallback-content relative overflow-hidden text-
|
|
103
|
+
return (_jsx(CollapsibleContent, Object.assign({ "data-slot": "tool-fallback-content", className: cn("aui-tool-fallback-content relative overflow-hidden text-[13px] outline-none md:text-sm", "group/collapsible-content ease-out", "data-[state=closed]:animate-collapsible-up", "data-[state=open]:animate-collapsible-down", "data-[state=closed]:fill-mode-forwards", "data-[state=closed]:pointer-events-none", "data-[state=open]:duration-(--animation-duration)", "data-[state=closed]:duration-(--animation-duration)", className) }, props, { children: _jsx("div", { className: "mt-2.5 flex flex-col gap-2 border-t pt-2 md:mt-3", children: children }) })));
|
|
67
104
|
}
|
|
68
105
|
function ToolFallbackArgs(_a) {
|
|
69
106
|
var { argsText, className } = _a, props = __rest(_a, ["argsText", "className"]);
|
|
70
107
|
if (!argsText)
|
|
71
108
|
return null;
|
|
72
|
-
return (_jsx("div", Object.assign({ "data-slot": "tool-fallback-args", className: cn("aui-tool-fallback-args px-4", className) }, props, { children: _jsx("pre", { className: "aui-tool-fallback-args-value max-h-40 overflow-auto rounded-md bg-muted/30 px-3 py-2 font-mono text-xs leading-relaxed whitespace-pre-wrap break-words", children: argsText }) })));
|
|
109
|
+
return (_jsx("div", Object.assign({ "data-slot": "tool-fallback-args", className: cn("aui-tool-fallback-args px-3 md:px-4", className) }, props, { children: _jsx("pre", { className: "aui-tool-fallback-args-value max-h-40 overflow-auto rounded-md bg-muted/30 px-3 py-2 font-mono text-xs leading-relaxed whitespace-pre-wrap break-words", children: argsText }) })));
|
|
73
110
|
}
|
|
74
111
|
function ToolFallbackResult(_a) {
|
|
75
112
|
var { result, className } = _a, props = __rest(_a, ["result", "className"]);
|
|
76
113
|
if (result === undefined)
|
|
77
114
|
return null;
|
|
78
|
-
return (_jsxs("div", Object.assign({ "data-slot": "tool-fallback-result", className: cn("aui-tool-fallback-result border-t border-dashed px-
|
|
115
|
+
return (_jsxs("div", Object.assign({ "data-slot": "tool-fallback-result", className: cn("aui-tool-fallback-result border-t border-dashed px-3 pt-2 md:px-4", className) }, props, { children: [_jsx("p", { className: "aui-tool-fallback-result-header font-semibold", children: "\u7ED3\u679C\uFF1A" }), _jsx("pre", { className: "aui-tool-fallback-result-content max-h-56 overflow-auto rounded-md bg-muted/30 px-3 py-2 font-mono text-xs leading-relaxed whitespace-pre-wrap break-words", children: result === null
|
|
79
116
|
? "无结构化结果"
|
|
80
117
|
: typeof result === "string"
|
|
81
118
|
? result
|
|
@@ -95,7 +132,7 @@ function ToolFallbackError(_a) {
|
|
|
95
132
|
return null;
|
|
96
133
|
const isCancelled = status.reason === "cancelled";
|
|
97
134
|
const headerText = isCancelled ? "取消原因:" : "错误:";
|
|
98
|
-
return (_jsxs("div", Object.assign({ "data-slot": "tool-fallback-error", className: cn("aui-tool-fallback-error px-4", className) }, props, { children: [_jsx("p", { className: "aui-tool-fallback-error-header font-semibold text-muted-foreground", children: headerText }), _jsx("p", { className: "aui-tool-fallback-error-reason text-muted-foreground", children: errorText })] })));
|
|
135
|
+
return (_jsxs("div", Object.assign({ "data-slot": "tool-fallback-error", className: cn("aui-tool-fallback-error px-3 md:px-4", className) }, props, { children: [_jsx("p", { className: "aui-tool-fallback-error-header font-semibold text-muted-foreground", children: headerText }), _jsx("p", { className: "aui-tool-fallback-error-reason text-muted-foreground", children: errorText })] })));
|
|
99
136
|
}
|
|
100
137
|
const ToolFallbackImpl = ({ toolName, argsText, result, status, toolCallId, }) => {
|
|
101
138
|
const effectiveStatus = getEffectiveToolStatus(status, result);
|
|
@@ -29,6 +29,7 @@ export type OptionListProps = {
|
|
|
29
29
|
isActionDisabled?: (actionId: string, value: string | string[] | null) => boolean;
|
|
30
30
|
allowCustomInput?: boolean;
|
|
31
31
|
customInputLabel?: string;
|
|
32
|
+
showRecommendedBadge?: boolean;
|
|
32
33
|
className?: string;
|
|
33
34
|
};
|
|
34
|
-
export declare function OptionList({ id, options, selectionMode, value, defaultValue, choice, minSelections, maxSelections, actions, onChange, onAction, onBeforeAction, isActionDisabled, allowCustomInput, customInputLabel, className, }: OptionListProps): import("react/jsx-runtime").JSX.Element;
|
|
35
|
+
export declare function OptionList({ id, options, selectionMode, value, defaultValue, choice, minSelections, maxSelections, actions, onChange, onAction, onBeforeAction, isActionDisabled, allowCustomInput, customInputLabel, showRecommendedBadge, className, }: OptionListProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -18,9 +18,9 @@ function arrayToValue(value, selectionMode) {
|
|
|
18
18
|
return (_a = value[0]) !== null && _a !== void 0 ? _a : null;
|
|
19
19
|
}
|
|
20
20
|
export function OptionList({ id, options, selectionMode = "multi", value, defaultValue, choice, minSelections = 1, maxSelections, actions = [
|
|
21
|
-
{ id: "confirm", label: "确认" },
|
|
22
21
|
{ id: "cancel", label: "取消", variant: "outline" },
|
|
23
|
-
|
|
22
|
+
{ id: "confirm", label: "确认" },
|
|
23
|
+
], onChange, onAction, onBeforeAction, isActionDisabled, allowCustomInput = false, customInputLabel = "自定义", showRecommendedBadge = true, className, }) {
|
|
24
24
|
const isControlled = value !== undefined;
|
|
25
25
|
const isReceipt = choice !== undefined;
|
|
26
26
|
const [internalValue, setInternalValue] = useState(valueToArray(defaultValue));
|
|
@@ -152,10 +152,10 @@ export function OptionList({ id, options, selectionMode = "multi", value, defaul
|
|
|
152
152
|
: "border-border bg-card hover:bg-muted/60", (option.disabled || isReceipt) &&
|
|
153
153
|
"cursor-default opacity-80 hover:bg-card", hasDescription ? "items-start" : "items-center"), children: [_jsx("span", { className: cn("flex size-4 shrink-0 items-center justify-center rounded-full border", selected
|
|
154
154
|
? "border-primary bg-primary text-primary-foreground"
|
|
155
|
-
: "border-muted-foreground/30 text-transparent", hasDescription && "mt-0.5"), children: _jsx(CheckIcon, { className: "size-3" }) }), option.icon && (_jsx("span", { className: cn("shrink-0 text-muted-foreground", hasDescription && "mt-0.5"), children: option.icon })), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block break-words font-medium leading-5", children: option.label }), option.description && (_jsx("span", { className: "mt-0.5 block break-words text-muted-foreground text-xs leading-5", children: option.description })), option.recommended && (_jsx("span", { className: "mt-1 inline-flex rounded-sm bg-primary/10 px-1.5 py-0.5 font-medium text-primary text-xs", children: "\u63A8\u8350" }))] })] }, option.id));
|
|
155
|
+
: "border-muted-foreground/30 text-transparent", hasDescription && "mt-0.5"), children: _jsx(CheckIcon, { className: "size-3" }) }), option.icon && (_jsx("span", { className: cn("shrink-0 text-muted-foreground", hasDescription && "mt-0.5"), children: option.icon })), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block break-words font-medium leading-5", children: option.label }), option.description && (_jsx("span", { className: "mt-0.5 block break-words text-muted-foreground text-xs leading-5", children: option.description })), showRecommendedBadge && option.recommended && (_jsx("span", { className: "mt-1 inline-flex rounded-sm bg-primary/10 px-1.5 py-0.5 font-medium text-primary text-xs", children: "\u63A8\u8350" }))] })] }, option.id));
|
|
156
156
|
}) }), allowCustomInput && selectedSet.has(CUSTOM_OPTION_ID) && !isReceipt && (_jsx(Input, { className: "mt-2", placeholder: customInputLabel, value: customText, onChange: handleCustomTextChange })), !isReceipt && actions.length > 0 && (_jsx("div", { className: "mt-3 flex flex-wrap justify-end gap-2", children: actions.map((action) => {
|
|
157
157
|
var _a;
|
|
158
|
-
const selectedValue =
|
|
158
|
+
const selectedValue = actionValue;
|
|
159
159
|
return (_jsx(Button, { type: "button", size: "sm", variant: (_a = action.variant) !== null && _a !== void 0 ? _a : "default", disabled: action.disabled ||
|
|
160
160
|
(action.id === "confirm" && !isValidSelection) ||
|
|
161
161
|
(isActionDisabled === null || isActionDisabled === void 0 ? void 0 : isActionDisabled(action.id, selectedValue)), onClick: () => void handleAction(action), children: action.label }, action.id));
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { type PropsWithChildren } from "react";
|
|
2
2
|
import type { AcpBuiltinToolSettings, AcpProviderKey } from "./";
|
|
3
3
|
import { type ContextBundleV2, type ContextItem, type ContextItemKind, type ContextOperationResult } from "./context";
|
|
4
|
+
import { type ImageGenerationRuntimeSettings } from "../../tools/image-generation/shared";
|
|
4
5
|
type BuiltinToolSettingsUpdater = unknown | ((current: unknown) => unknown);
|
|
6
|
+
type ImageGenerationSettingsUpdater = ImageGenerationRuntimeSettings | null | ((current: ImageGenerationRuntimeSettings | null) => ImageGenerationRuntimeSettings | null);
|
|
5
7
|
export type AcpUiRuntimeContext = {
|
|
6
8
|
provider: AcpProviderKey;
|
|
7
9
|
model: string | null;
|
|
@@ -13,12 +15,16 @@ export type AcpUiRuntimeContext = {
|
|
|
13
15
|
permissionMode: string;
|
|
14
16
|
workspacePath: string | null;
|
|
15
17
|
builtinToolSettings: AcpBuiltinToolSettings;
|
|
18
|
+
runtimeBuiltinToolSettings: AcpBuiltinToolSettings;
|
|
19
|
+
hostImageGenerationSettings: ImageGenerationRuntimeSettings | null;
|
|
16
20
|
contextBundle: ContextBundleV2;
|
|
17
21
|
setProvider: (value: string | null) => void;
|
|
18
22
|
setModel: (value: string | null) => void;
|
|
19
23
|
setModeId: (value: string | null) => void;
|
|
20
24
|
setThoughtLevel: (value: string | null) => void;
|
|
21
25
|
setBuiltinToolSettings: (toolId: string, value: BuiltinToolSettingsUpdater) => void;
|
|
26
|
+
setHostImageGenerationSettings: (value: ImageGenerationSettingsUpdater) => ImageGenerationRuntimeSettings | null;
|
|
27
|
+
clearHostImageGenerationSettings: () => ImageGenerationRuntimeSettings | null;
|
|
22
28
|
syncModel: (value: string | null) => void;
|
|
23
29
|
syncModeId: (value: string | null) => void;
|
|
24
30
|
syncThoughtLevel: (value: string | null) => void;
|
|
@@ -4,6 +4,7 @@ import { createContext, useCallback, useContext, useEffect, useMemo, useRef, use
|
|
|
4
4
|
import { createContextBundle, filterContextBundle, } from "./context.mjs";
|
|
5
5
|
import { normalizeAcpProvider } from "./provider-registry.mjs";
|
|
6
6
|
import { readStoredBuiltinToolSettings, storeBuiltinToolSettings, updateClientBuiltinToolSettings, } from "../../tools/client-registry.mjs";
|
|
7
|
+
import { IMAGE_GENERATION_TOOL_ID, mergeImageGenerationRuntimeSettings, normalizeImageGenerationRuntimeSettings, } from "../../tools/image-generation/shared.mjs";
|
|
7
8
|
const DEFAULT_PROVIDER = "codex";
|
|
8
9
|
const DEFAULT_PERMISSION_MODE = "bypassPermissions";
|
|
9
10
|
const AcpUiContext = createContext(null);
|
|
@@ -51,6 +52,14 @@ function emitContextChanged(context, change) {
|
|
|
51
52
|
detail: { context, change },
|
|
52
53
|
}));
|
|
53
54
|
}
|
|
55
|
+
function mergeHostBuiltinToolSettings(storedSettings, hostImageGenerationSettings) {
|
|
56
|
+
if (!hostImageGenerationSettings)
|
|
57
|
+
return storedSettings;
|
|
58
|
+
return updateClientBuiltinToolSettings(storedSettings, IMAGE_GENERATION_TOOL_ID, (current) => {
|
|
59
|
+
var _a;
|
|
60
|
+
return (_a = mergeImageGenerationRuntimeSettings(current, hostImageGenerationSettings)) !== null && _a !== void 0 ? _a : current;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
54
63
|
export function AcpUiProvider({ children, workspacePath, defaultProvider, }) {
|
|
55
64
|
const [provider, setProviderState] = useState(() => normalizeAcpProvider(defaultProvider !== null && defaultProvider !== void 0 ? defaultProvider : DEFAULT_PROVIDER));
|
|
56
65
|
const [model, setModelState] = useState(null);
|
|
@@ -60,14 +69,19 @@ export function AcpUiProvider({ children, workspacePath, defaultProvider, }) {
|
|
|
60
69
|
const [explicitModeId, setExplicitModeIdState] = useState(null);
|
|
61
70
|
const [explicitThoughtLevel, setExplicitThoughtLevelState] = useState(null);
|
|
62
71
|
const [builtinToolSettings, setBuiltinToolSettingsState] = useState({});
|
|
72
|
+
const [hostImageGenerationSettings, setHostImageGenerationSettingsState] = useState(null);
|
|
63
73
|
const [contextBundle, setContextBundleState] = useState(() => createContextBundle());
|
|
64
74
|
const contextBundleRef = useRef(contextBundle);
|
|
75
|
+
const builtinToolSettingsRef = useRef(builtinToolSettings);
|
|
76
|
+
const hostImageGenerationSettingsRef = useRef(hostImageGenerationSettings);
|
|
65
77
|
const setContextBundle = useCallback((next) => {
|
|
66
78
|
contextBundleRef.current = next;
|
|
67
79
|
setContextBundleState(next);
|
|
68
80
|
}, []);
|
|
69
81
|
useEffect(() => {
|
|
70
|
-
|
|
82
|
+
const stored = readStoredBuiltinToolSettings();
|
|
83
|
+
builtinToolSettingsRef.current = stored;
|
|
84
|
+
setBuiltinToolSettingsState(stored);
|
|
71
85
|
}, []);
|
|
72
86
|
const normalize = useCallback((value) => {
|
|
73
87
|
const normalized = String(value !== null && value !== void 0 ? value : "").trim();
|
|
@@ -103,11 +117,24 @@ export function AcpUiProvider({ children, workspacePath, defaultProvider, }) {
|
|
|
103
117
|
setExplicitThoughtLevelState(normalized);
|
|
104
118
|
}, [normalize]);
|
|
105
119
|
const setBuiltinToolSettings = useCallback((toolId, next) => {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
120
|
+
const updated = updateClientBuiltinToolSettings(builtinToolSettingsRef.current, toolId, next);
|
|
121
|
+
builtinToolSettingsRef.current = updated;
|
|
122
|
+
storeBuiltinToolSettings(updated);
|
|
123
|
+
setBuiltinToolSettingsState(updated);
|
|
124
|
+
}, []);
|
|
125
|
+
const setHostImageGenerationSettings = useCallback((next) => {
|
|
126
|
+
const rawNext = typeof next === "function"
|
|
127
|
+
? next(hostImageGenerationSettingsRef.current)
|
|
128
|
+
: next;
|
|
129
|
+
const normalized = normalizeImageGenerationRuntimeSettings(rawNext);
|
|
130
|
+
hostImageGenerationSettingsRef.current = normalized;
|
|
131
|
+
setHostImageGenerationSettingsState(normalized);
|
|
132
|
+
return normalized;
|
|
133
|
+
}, []);
|
|
134
|
+
const clearHostImageGenerationSettings = useCallback(() => {
|
|
135
|
+
hostImageGenerationSettingsRef.current = null;
|
|
136
|
+
setHostImageGenerationSettingsState(null);
|
|
137
|
+
return null;
|
|
111
138
|
}, []);
|
|
112
139
|
const syncModel = useCallback((next) => setModelState(normalize(next)), [normalize]);
|
|
113
140
|
const syncModeId = useCallback((next) => setModeIdState(normalize(next)), [normalize]);
|
|
@@ -174,7 +201,7 @@ export function AcpUiProvider({ children, workspacePath, defaultProvider, }) {
|
|
|
174
201
|
if (current.items.length === 0)
|
|
175
202
|
return null;
|
|
176
203
|
const consumed = current;
|
|
177
|
-
const next = createChangedBundle(
|
|
204
|
+
const next = createChangedBundle(consumed.items.filter((item) => item.pinned === true));
|
|
178
205
|
setContextBundle(next);
|
|
179
206
|
emitContextChanged(next, {
|
|
180
207
|
operation: "consume",
|
|
@@ -183,6 +210,7 @@ export function AcpUiProvider({ children, workspacePath, defaultProvider, }) {
|
|
|
183
210
|
});
|
|
184
211
|
return consumed;
|
|
185
212
|
}, [setContextBundle]);
|
|
213
|
+
const mergedBuiltinToolSettings = useMemo(() => mergeHostBuiltinToolSettings(builtinToolSettings, hostImageGenerationSettings), [builtinToolSettings, hostImageGenerationSettings]);
|
|
186
214
|
const value = useMemo(() => ({
|
|
187
215
|
provider,
|
|
188
216
|
model,
|
|
@@ -194,12 +222,16 @@ export function AcpUiProvider({ children, workspacePath, defaultProvider, }) {
|
|
|
194
222
|
permissionMode: DEFAULT_PERMISSION_MODE,
|
|
195
223
|
workspacePath: normalize(workspacePath !== null && workspacePath !== void 0 ? workspacePath : null),
|
|
196
224
|
builtinToolSettings,
|
|
225
|
+
runtimeBuiltinToolSettings: mergedBuiltinToolSettings,
|
|
226
|
+
hostImageGenerationSettings,
|
|
197
227
|
contextBundle,
|
|
198
228
|
setProvider,
|
|
199
229
|
setModel,
|
|
200
230
|
setModeId,
|
|
201
231
|
setThoughtLevel,
|
|
202
232
|
setBuiltinToolSettings,
|
|
233
|
+
setHostImageGenerationSettings,
|
|
234
|
+
clearHostImageGenerationSettings,
|
|
203
235
|
syncModel,
|
|
204
236
|
syncModeId,
|
|
205
237
|
syncThoughtLevel,
|
|
@@ -215,10 +247,13 @@ export function AcpUiProvider({ children, workspacePath, defaultProvider, }) {
|
|
|
215
247
|
consumeContextBundle,
|
|
216
248
|
contextBundle,
|
|
217
249
|
builtinToolSettings,
|
|
250
|
+
clearHostImageGenerationSettings,
|
|
218
251
|
explicitModeId,
|
|
219
252
|
explicitModel,
|
|
220
253
|
explicitThoughtLevel,
|
|
221
254
|
getContextBundle,
|
|
255
|
+
hostImageGenerationSettings,
|
|
256
|
+
mergedBuiltinToolSettings,
|
|
222
257
|
model,
|
|
223
258
|
modeId,
|
|
224
259
|
normalize,
|
|
@@ -229,6 +264,7 @@ export function AcpUiProvider({ children, workspacePath, defaultProvider, }) {
|
|
|
229
264
|
setModel,
|
|
230
265
|
setProvider,
|
|
231
266
|
setBuiltinToolSettings,
|
|
267
|
+
setHostImageGenerationSettings,
|
|
232
268
|
syncModeId,
|
|
233
269
|
syncModel,
|
|
234
270
|
syncThoughtLevel,
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
|
-
import os from "node:os";
|
|
3
2
|
import path from "node:path";
|
|
4
|
-
const SKILL_ROOTS = [
|
|
5
|
-
{ scope: "user", relativePath: [".codex", "skills"] },
|
|
6
|
-
{ scope: "system", relativePath: [".codex", "skills", ".system"] },
|
|
7
|
-
];
|
|
8
3
|
function normalizeText(value) {
|
|
9
4
|
return typeof value === "string" ? value.trim() : "";
|
|
10
5
|
}
|
|
@@ -102,20 +97,10 @@ async function listSkillsFromRoot(rootPath, scope) {
|
|
|
102
97
|
}
|
|
103
98
|
export async function listAcpUiCommands({ workspacePath, } = {}) {
|
|
104
99
|
const normalizedWorkspacePath = normalizeText(workspacePath);
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
scope: "project",
|
|
111
|
-
},
|
|
112
|
-
]
|
|
113
|
-
: []),
|
|
114
|
-
...SKILL_ROOTS.map((root) => ({
|
|
115
|
-
rootPath: path.join(os.homedir(), ...root.relativePath),
|
|
116
|
-
scope: root.scope,
|
|
117
|
-
})),
|
|
118
|
-
];
|
|
119
|
-
const commandGroups = await Promise.all(roots.map((root) => listSkillsFromRoot(root.rootPath, root.scope)));
|
|
100
|
+
if (!normalizedWorkspacePath)
|
|
101
|
+
return [];
|
|
102
|
+
const commandGroups = await Promise.all([
|
|
103
|
+
listSkillsFromRoot(path.join(normalizedWorkspacePath, ".agents", "skills"), "project"),
|
|
104
|
+
]);
|
|
120
105
|
return uniqueCommands(commandGroups.flat()).sort((left, right) => left.name.localeCompare(right.name));
|
|
121
106
|
}
|
|
@@ -20,6 +20,8 @@ export type TextRange = {
|
|
|
20
20
|
export type ContextFileItem = {
|
|
21
21
|
kind: "file";
|
|
22
22
|
id?: string;
|
|
23
|
+
hidden?: boolean;
|
|
24
|
+
pinned?: boolean;
|
|
23
25
|
path: string;
|
|
24
26
|
name?: string;
|
|
25
27
|
mimeType?: string;
|
|
@@ -58,6 +60,8 @@ export type ContextAnnotationTarget = {
|
|
|
58
60
|
export type ContextAnnotationItem = {
|
|
59
61
|
kind: "annotation";
|
|
60
62
|
id?: string;
|
|
63
|
+
hidden?: boolean;
|
|
64
|
+
pinned?: boolean;
|
|
61
65
|
body: string;
|
|
62
66
|
target: ContextAnnotationTarget;
|
|
63
67
|
title?: string;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const AGENT_STDERR_MARKER = "\n[agent stderr]\n";
|
|
2
|
+
const LEADING_AGENT_STDERR_MARKER = "[agent stderr]\n";
|
|
3
|
+
const CODEX_MCP_STARTUP_UNKNOWN_SUBMISSION_RE = /\bWARN\s+codex_acp::thread:\s+Received event for unknown submission ID:\s*(?:[0-9a-f-]+)?\s*McpStartup(?:Update|Complete)\(/;
|
|
4
|
+
function isIgnoredAgentStderrLine(line) {
|
|
5
|
+
return CODEX_MCP_STARTUP_UNKNOWN_SUBMISSION_RE.test(line);
|
|
6
|
+
}
|
|
7
|
+
function filterAgentStderr(stderrText) {
|
|
8
|
+
return stderrText
|
|
9
|
+
.split("\n")
|
|
10
|
+
.filter((line) => !isIgnoredAgentStderrLine(line))
|
|
11
|
+
.join("\n")
|
|
12
|
+
.trim();
|
|
13
|
+
}
|
|
14
|
+
export function sanitizeAcpErrorMessage(message) {
|
|
15
|
+
const normalized = message.replace(/\r\n/g, "\n");
|
|
16
|
+
let prefix = normalized;
|
|
17
|
+
let stderrText = null;
|
|
18
|
+
const markerIndex = normalized.indexOf(AGENT_STDERR_MARKER);
|
|
19
|
+
if (markerIndex >= 0) {
|
|
20
|
+
prefix = normalized.slice(0, markerIndex);
|
|
21
|
+
stderrText = normalized.slice(markerIndex + AGENT_STDERR_MARKER.length);
|
|
22
|
+
}
|
|
23
|
+
else if (normalized.startsWith(LEADING_AGENT_STDERR_MARKER)) {
|
|
24
|
+
prefix = "";
|
|
25
|
+
stderrText = normalized.slice(LEADING_AGENT_STDERR_MARKER.length);
|
|
26
|
+
}
|
|
27
|
+
if (stderrText === null)
|
|
28
|
+
return normalized;
|
|
29
|
+
const filteredStderr = filterAgentStderr(stderrText);
|
|
30
|
+
const trimmedPrefix = prefix.trim();
|
|
31
|
+
if (!filteredStderr)
|
|
32
|
+
return trimmedPrefix || "Internal error";
|
|
33
|
+
return `${trimmedPrefix}\n[agent stderr]\n${filteredStderr}`.trim();
|
|
34
|
+
}
|
|
35
|
+
export function acpErrorToMessage(error) {
|
|
36
|
+
return sanitizeAcpErrorMessage(error instanceof Error ? error.message : String(error));
|
|
37
|
+
}
|