@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
|
@@ -1,25 +1,48 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { RuntimeAdapterProvider, useAui, useAuiState, useRemoteThreadListRuntime, } from "@assistant-ui/react";
|
|
4
|
-
import { AssistantChatTransport, useChatRuntime, } from "@assistant-ui/react-ai-sdk";
|
|
4
|
+
import { AssistantChatTransport, createResumableSessionStorage, useChatRuntime, } from "@assistant-ui/react-ai-sdk";
|
|
5
5
|
import { lastAssistantMessageIsCompleteWithToolCalls, } from "ai";
|
|
6
6
|
import { createAssistantStream } from "assistant-stream";
|
|
7
|
-
import { useEffect, useMemo, useRef, } from "react";
|
|
7
|
+
import { useCallback, useEffect, useMemo, useRef, } from "react";
|
|
8
8
|
import { ACP_CAPABILITY_REFRESH_EVENT } from "../acp2aisdk/capability-cache.mjs";
|
|
9
9
|
import { getAcpProviderDefaultModeId } from "../acp2aisdk/provider-registry.mjs";
|
|
10
10
|
import { acpApiClient } from "../api/client.mjs";
|
|
11
|
+
import { withoutBodyForNullBodyStatus } from "../api/http-response.mjs";
|
|
11
12
|
import { getEnabledBuiltinToolIds } from "../../tools/client-registry.mjs";
|
|
13
|
+
import { getUserFacingMessageText } from "./title-text.mjs";
|
|
12
14
|
const DEFAULT_PROVIDER = "codex";
|
|
13
15
|
const LOCAL_THREAD_ID_PREFIX = "__LOCALID_";
|
|
14
16
|
const THREAD_LIST_PAGE_SIZE = 50;
|
|
17
|
+
const RESUMABLE_STORAGE_PREFIX = "acp-ui:resumable";
|
|
15
18
|
function createConversationThreadId(provider) {
|
|
16
19
|
const random = typeof crypto !== "undefined" && "randomUUID" in crypto
|
|
17
20
|
? crypto.randomUUID()
|
|
18
21
|
: `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
|
|
19
22
|
return `${provider}-${random}`;
|
|
20
23
|
}
|
|
24
|
+
function sanitizeResumableStoragePart(value) {
|
|
25
|
+
return encodeURIComponent(value || "default");
|
|
26
|
+
}
|
|
27
|
+
function createResumableStorageKey({ workspacePath, provider, threadId, }) {
|
|
28
|
+
return [
|
|
29
|
+
RESUMABLE_STORAGE_PREFIX,
|
|
30
|
+
sanitizeResumableStoragePart(workspacePath),
|
|
31
|
+
sanitizeResumableStoragePart(provider !== null && provider !== void 0 ? provider : DEFAULT_PROVIDER),
|
|
32
|
+
sanitizeResumableStoragePart(threadId),
|
|
33
|
+
].join(":");
|
|
34
|
+
}
|
|
35
|
+
function hasLocalPendingResumableStream({ workspacePath, provider, threadId, }) {
|
|
36
|
+
if (typeof window === "undefined")
|
|
37
|
+
return false;
|
|
38
|
+
return Boolean(window.sessionStorage.getItem(createResumableStorageKey({
|
|
39
|
+
workspacePath,
|
|
40
|
+
provider: provider !== null && provider !== void 0 ? provider : DEFAULT_PROVIDER,
|
|
41
|
+
threadId,
|
|
42
|
+
})));
|
|
43
|
+
}
|
|
21
44
|
function toRemoteMetadata(thread) {
|
|
22
|
-
var _a, _b;
|
|
45
|
+
var _a, _b, _c;
|
|
23
46
|
return {
|
|
24
47
|
remoteId: thread.threadId,
|
|
25
48
|
status: thread.status === "archived" ? "archived" : "regular",
|
|
@@ -30,22 +53,27 @@ function toRemoteMetadata(thread) {
|
|
|
30
53
|
modeId: thread.modeId,
|
|
31
54
|
thoughtLevel: thread.thoughtLevel,
|
|
32
55
|
workspacePath: thread.workspacePath,
|
|
33
|
-
|
|
56
|
+
updatedAt: thread.updatedAt,
|
|
57
|
+
lastActiveAt: (_b = thread.lastActiveAt) !== null && _b !== void 0 ? _b : null,
|
|
58
|
+
providerSessionId: (_c = thread.providerSessionId) !== null && _c !== void 0 ? _c : null,
|
|
34
59
|
},
|
|
35
60
|
};
|
|
36
61
|
}
|
|
37
62
|
function getTextFromThreadMessage(message) {
|
|
38
|
-
|
|
63
|
+
const text = message.content
|
|
39
64
|
.filter((part) => part.type === "text")
|
|
40
65
|
.map((part) => part.text)
|
|
41
66
|
.join(" ")
|
|
42
67
|
.trim();
|
|
68
|
+
return getUserFacingMessageText(text);
|
|
43
69
|
}
|
|
44
70
|
function isRecord(value) {
|
|
45
71
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
46
72
|
}
|
|
47
73
|
function normalizeTitleText(value, maxLength) {
|
|
48
|
-
const title = typeof value === "string"
|
|
74
|
+
const title = typeof value === "string"
|
|
75
|
+
? getUserFacingMessageText(value).replace(/\s+/g, " ").trim()
|
|
76
|
+
: "";
|
|
49
77
|
return (maxLength ? title.slice(0, maxLength) : title).trim();
|
|
50
78
|
}
|
|
51
79
|
function normalizeStoredTitle(value) {
|
|
@@ -78,8 +106,38 @@ function createTitle(messages) {
|
|
|
78
106
|
const firstUserMessage = messages.find((message) => message.role === "user" && getTextFromThreadMessage(message));
|
|
79
107
|
const fallbackText = (firstUserMessage ? getTextFromThreadMessage(firstUserMessage) : "") ||
|
|
80
108
|
getTextFromThreadMessage((_a = messages.find((message) => message.role !== "system")) !== null && _a !== void 0 ? _a : messages[0]);
|
|
81
|
-
|
|
82
|
-
|
|
109
|
+
return normalizeTitleText(fallbackText, 48);
|
|
110
|
+
}
|
|
111
|
+
function shouldStartRunFromAppendMessage(message) {
|
|
112
|
+
var _a;
|
|
113
|
+
return (_a = message.startRun) !== null && _a !== void 0 ? _a : message.role === "user";
|
|
114
|
+
}
|
|
115
|
+
function createAcpCreateMessage(message) {
|
|
116
|
+
var _a, _b;
|
|
117
|
+
const inputParts = [
|
|
118
|
+
...message.content.filter((part) => part.type !== "file"),
|
|
119
|
+
...((_b = (_a = message.attachments) === null || _a === void 0 ? void 0 : _a.flatMap((attachment) => attachment.content.map((part) => (Object.assign(Object.assign({}, part), { filename: attachment.name }))))) !== null && _b !== void 0 ? _b : []),
|
|
120
|
+
];
|
|
121
|
+
const parts = inputParts.map((part) => {
|
|
122
|
+
switch (part.type) {
|
|
123
|
+
case "text":
|
|
124
|
+
return {
|
|
125
|
+
type: "text",
|
|
126
|
+
text: part.text,
|
|
127
|
+
};
|
|
128
|
+
case "image":
|
|
129
|
+
return Object.assign(Object.assign({ type: "file", url: part.image }, (part.filename ? { filename: part.filename } : {})), { mediaType: "image/png" });
|
|
130
|
+
case "file":
|
|
131
|
+
return Object.assign({ type: "file", url: part.data, mediaType: part.mimeType }, (part.filename ? { filename: part.filename } : {}));
|
|
132
|
+
default:
|
|
133
|
+
throw new Error(`Unsupported part type: ${part.type}`);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
return {
|
|
137
|
+
role: message.role,
|
|
138
|
+
parts,
|
|
139
|
+
metadata: message.metadata,
|
|
140
|
+
};
|
|
83
141
|
}
|
|
84
142
|
const AcpSessionTitleSync = () => {
|
|
85
143
|
const aui = useAui();
|
|
@@ -106,10 +164,11 @@ const AcpSessionTitleSync = () => {
|
|
|
106
164
|
return null;
|
|
107
165
|
};
|
|
108
166
|
class RemoteConversationHistoryAdapter {
|
|
109
|
-
constructor(aui, workspacePath,
|
|
167
|
+
constructor(aui, workspacePath, fallbackThreadId, provider) {
|
|
110
168
|
this.aui = aui;
|
|
111
169
|
this.workspacePath = workspacePath;
|
|
112
|
-
this.
|
|
170
|
+
this.fallbackThreadId = fallbackThreadId;
|
|
171
|
+
this.provider = provider;
|
|
113
172
|
}
|
|
114
173
|
async load() {
|
|
115
174
|
return { messages: [] };
|
|
@@ -118,61 +177,67 @@ class RemoteConversationHistoryAdapter {
|
|
|
118
177
|
withFormat(formatAdapter) {
|
|
119
178
|
const aui = this.aui;
|
|
120
179
|
const workspacePath = this.workspacePath;
|
|
121
|
-
const
|
|
122
|
-
const
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
180
|
+
const fallbackThreadId = this.fallbackThreadId;
|
|
181
|
+
const provider = this.provider;
|
|
182
|
+
const getRemoteId = async () => {
|
|
183
|
+
var _a;
|
|
184
|
+
const currentRemoteId = aui.threadListItem().getState().remoteId;
|
|
185
|
+
if (currentRemoteId)
|
|
186
|
+
return currentRemoteId;
|
|
187
|
+
await aui
|
|
188
|
+
.threadListItem()
|
|
189
|
+
.initialize()
|
|
190
|
+
.catch(() => null);
|
|
191
|
+
return (_a = aui.threadListItem().getState().remoteId) !== null && _a !== void 0 ? _a : fallbackThreadId;
|
|
132
192
|
};
|
|
133
193
|
return {
|
|
134
194
|
async load() {
|
|
135
|
-
const remoteId = getRemoteId();
|
|
195
|
+
const remoteId = await getRemoteId();
|
|
136
196
|
if (!remoteId)
|
|
137
197
|
return { messages: [] };
|
|
138
|
-
const repo = await acpApiClient.loadConversationMessages(remoteId, workspacePath, formatAdapter.format
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
198
|
+
const repo = await acpApiClient.loadConversationMessages(remoteId, workspacePath, formatAdapter.format, undefined, {
|
|
199
|
+
hideResumable: hasLocalPendingResumableStream({
|
|
200
|
+
workspacePath,
|
|
201
|
+
provider,
|
|
202
|
+
threadId: remoteId,
|
|
203
|
+
}),
|
|
204
|
+
});
|
|
205
|
+
const messages = repo.messages.map((message) => formatAdapter.decode({
|
|
206
|
+
id: message.id,
|
|
207
|
+
parent_id: message.parent_id,
|
|
208
|
+
format: message.format,
|
|
209
|
+
content: message.content,
|
|
210
|
+
}));
|
|
211
|
+
const externalRepo = {
|
|
143
212
|
headId: repo.headId,
|
|
144
|
-
messages
|
|
145
|
-
id: message.id,
|
|
146
|
-
parent_id: message.parent_id,
|
|
147
|
-
format: message.format,
|
|
148
|
-
content: message.content,
|
|
149
|
-
})),
|
|
213
|
+
messages,
|
|
150
214
|
};
|
|
215
|
+
if (messages.length === 0) {
|
|
216
|
+
aui.thread().import({ messages: [] });
|
|
217
|
+
}
|
|
218
|
+
return externalRepo;
|
|
151
219
|
},
|
|
152
220
|
async append(item) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
await saveItem(remoteId, item, formatAdapter.getId(item.message));
|
|
221
|
+
await aui.threadListItem().initialize();
|
|
222
|
+
void item;
|
|
156
223
|
},
|
|
157
224
|
async update(item, localMessageId) {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
return;
|
|
161
|
-
await saveItem(remoteId, item, localMessageId);
|
|
225
|
+
void item;
|
|
226
|
+
void localMessageId;
|
|
162
227
|
},
|
|
163
228
|
};
|
|
164
229
|
}
|
|
165
230
|
}
|
|
166
|
-
function createHistoryProvider(workspacePath,
|
|
231
|
+
function createHistoryProvider(workspacePath, threadId, provider) {
|
|
167
232
|
const Provider = ({ children }) => {
|
|
168
233
|
const aui = useAui();
|
|
169
|
-
const history = useMemo(() => new RemoteConversationHistoryAdapter(aui, workspacePath,
|
|
234
|
+
const history = useMemo(() => new RemoteConversationHistoryAdapter(aui, workspacePath, threadId, provider), [aui]);
|
|
170
235
|
const adapters = useMemo(() => ({ history }), [history]);
|
|
171
236
|
return (_jsxs(RuntimeAdapterProvider, { adapters: adapters, children: [_jsx(AcpSessionTitleSync, {}), children] }));
|
|
172
237
|
};
|
|
173
238
|
return Provider;
|
|
174
239
|
}
|
|
175
|
-
function createConversationThreadListAdapter(context = {}) {
|
|
240
|
+
function createConversationThreadListAdapter(context = {}, threadId) {
|
|
176
241
|
const conversationBody = (threadId) => {
|
|
177
242
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
178
243
|
const metadata = (_b = (_a = context.getConversationMetadata) === null || _a === void 0 ? void 0 : _a.call(context)) !== null && _b !== void 0 ? _b : {};
|
|
@@ -190,15 +255,23 @@ function createConversationThreadListAdapter(context = {}) {
|
|
|
190
255
|
await acpApiClient.upsertConversation(Object.assign(Object.assign(Object.assign({}, conversationBody(threadId)), patch), { threadId }), context.workspacePath);
|
|
191
256
|
};
|
|
192
257
|
return {
|
|
193
|
-
unstable_Provider: createHistoryProvider(context.workspacePath,
|
|
258
|
+
unstable_Provider: createHistoryProvider(context.workspacePath, threadId, context.provider),
|
|
194
259
|
async list(params) {
|
|
195
260
|
const { threads, nextCursor } = await acpApiClient.listConversations(context.workspacePath, {
|
|
196
261
|
after: params === null || params === void 0 ? void 0 : params.after,
|
|
197
262
|
limit: THREAD_LIST_PAGE_SIZE,
|
|
198
263
|
refreshProvider: false,
|
|
199
264
|
});
|
|
265
|
+
const hasRouteThread = threadId && threads.some((thread) => thread.threadId === threadId);
|
|
266
|
+
const routeThread = threadId && !hasRouteThread
|
|
267
|
+
? await acpApiClient
|
|
268
|
+
.getConversation(threadId, context.workspacePath)
|
|
269
|
+
.then(({ thread }) => thread)
|
|
270
|
+
.catch(() => null)
|
|
271
|
+
: null;
|
|
272
|
+
const allThreads = routeThread ? [routeThread, ...threads] : threads;
|
|
200
273
|
return {
|
|
201
|
-
threads:
|
|
274
|
+
threads: allThreads.map(toRemoteMetadata),
|
|
202
275
|
nextCursor,
|
|
203
276
|
};
|
|
204
277
|
},
|
|
@@ -256,6 +329,7 @@ function dispatchCapabilityRefresh({ provider, threadId, workspacePath, }) {
|
|
|
256
329
|
}));
|
|
257
330
|
}
|
|
258
331
|
export function useConversationChatRuntime({ context, threadId, } = {}) {
|
|
332
|
+
var _a;
|
|
259
333
|
const provider = context === null || context === void 0 ? void 0 : context.provider;
|
|
260
334
|
const model = context === null || context === void 0 ? void 0 : context.model;
|
|
261
335
|
const modeId = context === null || context === void 0 ? void 0 : context.modeId;
|
|
@@ -266,8 +340,18 @@ export function useConversationChatRuntime({ context, threadId, } = {}) {
|
|
|
266
340
|
const explicitThoughtLevel = context === null || context === void 0 ? void 0 : context.explicitThoughtLevel;
|
|
267
341
|
const permissionMode = context === null || context === void 0 ? void 0 : context.permissionMode;
|
|
268
342
|
const workspacePath = context === null || context === void 0 ? void 0 : context.workspacePath;
|
|
269
|
-
const builtinToolSettings = context === null || context === void 0 ? void 0 : context.builtinToolSettings;
|
|
343
|
+
const builtinToolSettings = (_a = context === null || context === void 0 ? void 0 : context.runtimeBuiltinToolSettings) !== null && _a !== void 0 ? _a : context === null || context === void 0 ? void 0 : context.builtinToolSettings;
|
|
270
344
|
const consumeContextBundle = context === null || context === void 0 ? void 0 : context.consumeContextBundle;
|
|
345
|
+
const stagedContextBundlesRef = useRef([]);
|
|
346
|
+
const toCreateMessage = useCallback((message) => {
|
|
347
|
+
if (shouldStartRunFromAppendMessage(message)) {
|
|
348
|
+
const contextBundle = consumeContextBundle === null || consumeContextBundle === void 0 ? void 0 : consumeContextBundle();
|
|
349
|
+
if (contextBundle) {
|
|
350
|
+
stagedContextBundlesRef.current.push(contextBundle);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
return createAcpCreateMessage(message);
|
|
354
|
+
}, [consumeContextBundle]);
|
|
271
355
|
const conversationMetadataRef = useRef({});
|
|
272
356
|
conversationMetadataRef.current = {
|
|
273
357
|
model,
|
|
@@ -280,22 +364,45 @@ export function useConversationChatRuntime({ context, threadId, } = {}) {
|
|
|
280
364
|
workspacePath,
|
|
281
365
|
getConversationMetadata: () => conversationMetadataRef.current,
|
|
282
366
|
}), [provider, permissionMode, workspacePath]);
|
|
283
|
-
const adapter = useMemo(() => createConversationThreadListAdapter(adapterContext), [adapterContext]);
|
|
367
|
+
const adapter = useMemo(() => createConversationThreadListAdapter(adapterContext, threadId), [adapterContext, threadId]);
|
|
284
368
|
return useRemoteThreadListRuntime({
|
|
285
369
|
adapter,
|
|
286
370
|
allowNesting: true,
|
|
287
371
|
threadId,
|
|
288
372
|
runtimeHook: function RuntimeHook() {
|
|
373
|
+
var _a;
|
|
374
|
+
// biome-ignore lint/correctness/useHookAtTopLevel: assistant-ui calls runtimeHook as a runtime component hook.
|
|
375
|
+
const runtimeThreadId = useAuiState((state) => state.threadListItem.id);
|
|
376
|
+
// biome-ignore lint/correctness/useHookAtTopLevel: assistant-ui calls runtimeHook as a runtime component hook.
|
|
377
|
+
const runtimeRemoteId = useAuiState((state) => state.threadListItem.remoteId);
|
|
378
|
+
const activeThreadId = (_a = runtimeRemoteId !== null && runtimeRemoteId !== void 0 ? runtimeRemoteId : threadId) !== null && _a !== void 0 ? _a : runtimeThreadId;
|
|
379
|
+
const activeProvider = provider !== null && provider !== void 0 ? provider : DEFAULT_PROVIDER;
|
|
289
380
|
// biome-ignore lint/correctness/useHookAtTopLevel: assistant-ui calls runtimeHook as a runtime component hook.
|
|
290
381
|
return useChatRuntime({
|
|
291
382
|
sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls,
|
|
383
|
+
toCreateMessage,
|
|
292
384
|
transport: new AssistantChatTransport({
|
|
293
385
|
api: acpApiClient.chatUrl(),
|
|
386
|
+
resumable: {
|
|
387
|
+
storage: createResumableSessionStorage({
|
|
388
|
+
key: createResumableStorageKey({
|
|
389
|
+
workspacePath,
|
|
390
|
+
provider: activeProvider,
|
|
391
|
+
threadId: activeThreadId,
|
|
392
|
+
}),
|
|
393
|
+
}),
|
|
394
|
+
resumeApi: (streamId) => acpApiClient.chatResumeUrl(streamId, {
|
|
395
|
+
threadId: activeThreadId,
|
|
396
|
+
provider: activeProvider,
|
|
397
|
+
workspacePath: workspacePath !== null && workspacePath !== void 0 ? workspacePath : null,
|
|
398
|
+
}),
|
|
399
|
+
},
|
|
294
400
|
fetch: async (input, init) => {
|
|
295
401
|
var _a, _b;
|
|
296
402
|
const response = await fetch(input, init);
|
|
297
|
-
const
|
|
298
|
-
const
|
|
403
|
+
const normalizedResponse = withoutBodyForNullBodyStatus(response);
|
|
404
|
+
const responseProvider = (_b = (_a = normalizedResponse.headers.get("x-acp-provider")) !== null && _a !== void 0 ? _a : provider) !== null && _b !== void 0 ? _b : DEFAULT_PROVIDER;
|
|
405
|
+
const responseThreadId = normalizedResponse.headers.get("x-acp-thread-id");
|
|
299
406
|
const decodedThreadId = responseThreadId
|
|
300
407
|
? decodeURIComponent(responseThreadId)
|
|
301
408
|
: null;
|
|
@@ -306,7 +413,7 @@ export function useConversationChatRuntime({ context, threadId, } = {}) {
|
|
|
306
413
|
workspacePath,
|
|
307
414
|
});
|
|
308
415
|
}
|
|
309
|
-
return
|
|
416
|
+
return normalizedResponse;
|
|
310
417
|
},
|
|
311
418
|
body: () => {
|
|
312
419
|
var _a;
|
|
@@ -319,7 +426,7 @@ export function useConversationChatRuntime({ context, threadId, } = {}) {
|
|
|
319
426
|
workspacePath: workspacePath !== null && workspacePath !== void 0 ? workspacePath : null,
|
|
320
427
|
builtinTools: getEnabledBuiltinToolIds(builtinToolSettings),
|
|
321
428
|
builtinToolSettings,
|
|
322
|
-
context: (_a =
|
|
429
|
+
context: (_a = stagedContextBundlesRef.current.shift()) !== null && _a !== void 0 ? _a : null,
|
|
323
430
|
});
|
|
324
431
|
},
|
|
325
432
|
}),
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ConversationMessageRepository, ConversationRecord } from "./types";
|
|
2
|
+
export declare function loadProviderMessageRepository({ threadId, format, workspacePath, conversation, }: {
|
|
3
|
+
threadId: string;
|
|
4
|
+
format: string | null | undefined;
|
|
5
|
+
workspacePath: string | null | undefined;
|
|
6
|
+
conversation: ConversationRecord | null;
|
|
7
|
+
}): Promise<ConversationMessageRepository>;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { convertTranscriptToMessageRepository, findProviderSession, loadProviderTranscript, } from "../provider-history/index.mjs";
|
|
2
|
+
function errorMessage(error) {
|
|
3
|
+
return error instanceof Error ? error.message : String(error);
|
|
4
|
+
}
|
|
5
|
+
function filterMessagesByFormat(repo, format) {
|
|
6
|
+
return format
|
|
7
|
+
? repo.messages.filter((message) => message.format === format)
|
|
8
|
+
: repo.messages;
|
|
9
|
+
}
|
|
10
|
+
export async function loadProviderMessageRepository({ threadId, format, workspacePath, conversation, }) {
|
|
11
|
+
var _a, _b;
|
|
12
|
+
let providerSession = null;
|
|
13
|
+
let providerSessionError = null;
|
|
14
|
+
const providerSessionId = (_a = conversation === null || conversation === void 0 ? void 0 : conversation.providerSessionId) !== null && _a !== void 0 ? _a : (threadId.includes(":") ? threadId.slice(threadId.indexOf(":") + 1) : null);
|
|
15
|
+
const provider = (_b = conversation === null || conversation === void 0 ? void 0 : conversation.provider) !== null && _b !== void 0 ? _b : threadId.split(":")[0];
|
|
16
|
+
if (!(conversation === null || conversation === void 0 ? void 0 : conversation.sourcePath) && providerSessionId) {
|
|
17
|
+
try {
|
|
18
|
+
providerSession = await findProviderSession(provider, providerSessionId, workspacePath);
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
providerSessionError = errorMessage(error);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (conversation === null || conversation === void 0 ? void 0 : conversation.sourcePath) {
|
|
25
|
+
try {
|
|
26
|
+
const transcript = await loadProviderTranscript({
|
|
27
|
+
provider: conversation.provider,
|
|
28
|
+
sessionId: conversation.providerSessionId,
|
|
29
|
+
sourcePath: conversation.sourcePath,
|
|
30
|
+
});
|
|
31
|
+
const repo = convertTranscriptToMessageRepository(transcript, format !== null && format !== void 0 ? format : "ai-sdk/v6");
|
|
32
|
+
const messages = filterMessagesByFormat(repo, format);
|
|
33
|
+
if (messages.length === 0) {
|
|
34
|
+
return {
|
|
35
|
+
messages: [],
|
|
36
|
+
diagnostic: {
|
|
37
|
+
source: "provider-history",
|
|
38
|
+
error: "Provider transcript had no messages",
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
headId: repo.headId,
|
|
44
|
+
messages,
|
|
45
|
+
diagnostic: { source: "provider-history" },
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
return {
|
|
50
|
+
messages: [],
|
|
51
|
+
diagnostic: {
|
|
52
|
+
source: "provider-history",
|
|
53
|
+
error: errorMessage(error),
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (providerSession === null || providerSession === void 0 ? void 0 : providerSession.sourcePath) {
|
|
59
|
+
try {
|
|
60
|
+
const transcript = await loadProviderTranscript({
|
|
61
|
+
provider: providerSession.provider,
|
|
62
|
+
sessionId: providerSession.sessionId,
|
|
63
|
+
sourcePath: providerSession.sourcePath,
|
|
64
|
+
});
|
|
65
|
+
const repo = convertTranscriptToMessageRepository(transcript, format !== null && format !== void 0 ? format : "ai-sdk/v6");
|
|
66
|
+
const messages = filterMessagesByFormat(repo, format);
|
|
67
|
+
if (messages.length === 0) {
|
|
68
|
+
return {
|
|
69
|
+
messages: [],
|
|
70
|
+
diagnostic: {
|
|
71
|
+
source: "provider-history",
|
|
72
|
+
error: "Provider transcript had no messages",
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
headId: repo.headId,
|
|
78
|
+
messages,
|
|
79
|
+
diagnostic: { source: "provider-history" },
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
return {
|
|
84
|
+
messages: [],
|
|
85
|
+
diagnostic: {
|
|
86
|
+
source: "provider-history",
|
|
87
|
+
error: errorMessage(error),
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
messages: [],
|
|
94
|
+
diagnostic: {
|
|
95
|
+
source: "provider-history",
|
|
96
|
+
error: providerSessionError !== null && providerSessionError !== void 0 ? providerSessionError : "Provider transcript not found",
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ConversationMessageRepository } from "./types";
|
|
2
|
+
export declare const STALE_RUNNING_MESSAGE_MS = 30000;
|
|
3
|
+
export declare const STALE_RUNNING_MESSAGE_ERROR = "Run was interrupted before a resumable assistant stream was available.";
|
|
4
|
+
export declare function getAcpRun(message: unknown): Record<string, unknown> | null;
|
|
5
|
+
export declare function getLivePartialStreamId(message: unknown): string | null;
|
|
6
|
+
export declare function recoverStaleRunningRuntimeMessages<TContent extends Record<string, unknown>>(repository: ConversationMessageRepository<TContent>, nowMs?: number): {
|
|
7
|
+
repository: ConversationMessageRepository<TContent>;
|
|
8
|
+
changed: boolean;
|
|
9
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
export const STALE_RUNNING_MESSAGE_MS = 30000;
|
|
2
|
+
export const STALE_RUNNING_MESSAGE_ERROR = "Run was interrupted before a resumable assistant stream was available.";
|
|
3
|
+
function isRecord(value) {
|
|
4
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
5
|
+
}
|
|
6
|
+
export function getAcpRun(message) {
|
|
7
|
+
if (!isRecord(message))
|
|
8
|
+
return null;
|
|
9
|
+
const metadata = isRecord(message.metadata) ? message.metadata : null;
|
|
10
|
+
const custom = isRecord(metadata === null || metadata === void 0 ? void 0 : metadata.custom) ? metadata.custom : null;
|
|
11
|
+
const acpRun = isRecord(custom === null || custom === void 0 ? void 0 : custom.acpRun) ? custom.acpRun : null;
|
|
12
|
+
return acpRun;
|
|
13
|
+
}
|
|
14
|
+
export function getLivePartialStreamId(message) {
|
|
15
|
+
if (!isRecord(message))
|
|
16
|
+
return null;
|
|
17
|
+
if (message.role !== "assistant")
|
|
18
|
+
return null;
|
|
19
|
+
const acpRun = getAcpRun(message);
|
|
20
|
+
if ((acpRun === null || acpRun === void 0 ? void 0 : acpRun.status) !== "running")
|
|
21
|
+
return null;
|
|
22
|
+
return typeof acpRun.streamId === "string" && acpRun.streamId.trim()
|
|
23
|
+
? acpRun.streamId
|
|
24
|
+
: null;
|
|
25
|
+
}
|
|
26
|
+
function isStaleRunningMessage(message, nowMs) {
|
|
27
|
+
var _a;
|
|
28
|
+
const acpRun = getAcpRun(message.content);
|
|
29
|
+
if ((acpRun === null || acpRun === void 0 ? void 0 : acpRun.status) !== "running")
|
|
30
|
+
return false;
|
|
31
|
+
const updatedAtMs = Date.parse(String((_a = message.updatedAt) !== null && _a !== void 0 ? _a : ""));
|
|
32
|
+
if (!Number.isFinite(updatedAtMs))
|
|
33
|
+
return true;
|
|
34
|
+
return updatedAtMs < nowMs - STALE_RUNNING_MESSAGE_MS;
|
|
35
|
+
}
|
|
36
|
+
function isTerminalRunStatus(value) {
|
|
37
|
+
return value === "completed" || value === "aborted" || value === "error";
|
|
38
|
+
}
|
|
39
|
+
function finalizeTerminalStreamingParts(content) {
|
|
40
|
+
const acpRun = getAcpRun(content);
|
|
41
|
+
if (!isTerminalRunStatus(acpRun === null || acpRun === void 0 ? void 0 : acpRun.status) || !Array.isArray(content.parts)) {
|
|
42
|
+
return { content, changed: false };
|
|
43
|
+
}
|
|
44
|
+
let changed = false;
|
|
45
|
+
const parts = content.parts.map((part) => {
|
|
46
|
+
if (!isRecord(part) ||
|
|
47
|
+
(part.type !== "text" && part.type !== "reasoning") ||
|
|
48
|
+
part.state !== "streaming") {
|
|
49
|
+
return part;
|
|
50
|
+
}
|
|
51
|
+
changed = true;
|
|
52
|
+
return Object.assign(Object.assign({}, part), { state: "done" });
|
|
53
|
+
});
|
|
54
|
+
if (!changed)
|
|
55
|
+
return { content, changed: false };
|
|
56
|
+
return {
|
|
57
|
+
changed: true,
|
|
58
|
+
content: Object.assign(Object.assign({}, content), { parts }),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function markStaleRunningMessage(content, nowMs) {
|
|
62
|
+
const metadata = isRecord(content.metadata) ? content.metadata : {};
|
|
63
|
+
const custom = isRecord(metadata.custom) ? metadata.custom : {};
|
|
64
|
+
const acpRun = isRecord(custom.acpRun) ? custom.acpRun : {};
|
|
65
|
+
return Object.assign(Object.assign({}, content), { metadata: Object.assign(Object.assign({}, metadata), { custom: Object.assign(Object.assign({}, custom), { acpRun: Object.assign(Object.assign({}, acpRun), { status: "aborted", error: typeof acpRun.error === "string" && acpRun.error.trim()
|
|
66
|
+
? acpRun.error
|
|
67
|
+
: STALE_RUNNING_MESSAGE_ERROR, updatedAt: nowMs }) }) }) });
|
|
68
|
+
}
|
|
69
|
+
function recoverRuntimeMessageContent(message, nowMs) {
|
|
70
|
+
const content = isStaleRunningMessage(message, nowMs)
|
|
71
|
+
? markStaleRunningMessage(message.content, nowMs)
|
|
72
|
+
: message.content;
|
|
73
|
+
const finalized = finalizeTerminalStreamingParts(content);
|
|
74
|
+
return {
|
|
75
|
+
content: finalized.content,
|
|
76
|
+
changed: content !== message.content || finalized.changed,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export function recoverStaleRunningRuntimeMessages(repository, nowMs = Date.now()) {
|
|
80
|
+
var _a, _b;
|
|
81
|
+
let changed = false;
|
|
82
|
+
const messages = repository.messages.map((message) => {
|
|
83
|
+
const recovered = recoverRuntimeMessageContent(message, nowMs);
|
|
84
|
+
if (!recovered.changed)
|
|
85
|
+
return message;
|
|
86
|
+
changed = true;
|
|
87
|
+
return Object.assign(Object.assign({}, message), { content: recovered.content });
|
|
88
|
+
});
|
|
89
|
+
if (!changed)
|
|
90
|
+
return { repository, changed: false };
|
|
91
|
+
return {
|
|
92
|
+
changed: true,
|
|
93
|
+
repository: Object.assign(Object.assign({}, repository), { headId: (_b = (_a = messages.at(-1)) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : null, messages }),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AcpRuntimeMetadata } from "../acp2aisdk";
|
|
2
|
-
import type { ConversationListOptions, ConversationListResponse, ConversationMessageRepository, ConversationMessageUpsertRequest, ConversationRecord, ConversationSessionResolution, ConversationUpsertRequest, StoredMessageEntry } from "./types";
|
|
2
|
+
import type { ConversationListOptions, ConversationListResponse, ConversationMessageRepository, ConversationMessageSource, ConversationMessageUpsertRequest, ConversationRecord, ConversationSessionResolution, ConversationUpsertRequest, StoredMessageEntry } from "./types";
|
|
3
3
|
export declare function listConversations(workspacePath?: string | null, options?: ConversationListOptions): Promise<ConversationListResponse>;
|
|
4
4
|
export declare function getConversation(threadId: string, workspacePath?: string | null): Promise<ConversationRecord | null>;
|
|
5
5
|
export declare function resolveConversationByProviderSession({ provider: providerInput, sessionId, workspacePath, }: {
|
|
@@ -11,7 +11,7 @@ export declare function upsertConversation(request: ConversationUpsertRequest):
|
|
|
11
11
|
export declare function renameConversation(threadId: string, title: string, workspacePath?: string | null): Promise<ConversationRecord>;
|
|
12
12
|
export declare function archiveConversation(threadId: string, archived: boolean, workspacePath?: string | null): Promise<ConversationRecord>;
|
|
13
13
|
export declare function deleteConversation(threadId: string, workspacePath?: string | null): Promise<void>;
|
|
14
|
-
export declare function loadConversationMessages(threadId: string, format?: string | null, workspacePath?: string | null): Promise<ConversationMessageRepository>;
|
|
14
|
+
export declare function loadConversationMessages(threadId: string, format?: string | null, workspacePath?: string | null, source?: ConversationMessageSource): Promise<ConversationMessageRepository>;
|
|
15
15
|
export declare function saveConversationMessage(threadId: string, request: ConversationMessageUpsertRequest, workspacePath?: string | null): Promise<StoredMessageEntry>;
|
|
16
16
|
export declare function touchConversationFromRuntime(metadata: AcpRuntimeMetadata): Promise<void>;
|
|
17
17
|
export declare function closeConversationSession(metadata: AcpRuntimeMetadata | null): Promise<void>;
|