@maintainer-pro/ai-cli 0.1.2 → 0.1.3
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/dist/index.cjs +70 -15
- package/dist/index.d.cts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +69 -15
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
WORKING_PROVIDER: () => WORKING_PROVIDER,
|
|
33
34
|
buildClaudeUserPrompt: () => buildClaudeUserPrompt,
|
|
34
35
|
buildConversationPrompt: () => buildConversationPrompt,
|
|
35
36
|
buildCursorPrompt: () => buildCursorPrompt,
|
|
@@ -592,7 +593,9 @@ async function buildPriorConversationsContext(db, options) {
|
|
|
592
593
|
).slice(0, maxConversations) : ranked;
|
|
593
594
|
const blocks = selected.map((c) => {
|
|
594
595
|
const slice = c.messages.length > maxMessages ? c.messages.slice(-maxMessages) : c.messages;
|
|
595
|
-
const lines = slice.filter(
|
|
596
|
+
const lines = slice.filter(
|
|
597
|
+
(m) => (m.role === "user" || m.role === "assistant") && m.provider !== "working" && Boolean(m.content?.trim())
|
|
598
|
+
).map(
|
|
596
599
|
(m) => `${m.role === "user" ? "Human" : "Assistant"}: ${truncate(m.content)}`
|
|
597
600
|
);
|
|
598
601
|
const when = c.updatedAt ? ` (updated ${c.updatedAt.slice(0, 10)})` : "";
|
|
@@ -625,6 +628,18 @@ function createToolValidator(schemas) {
|
|
|
625
628
|
}
|
|
626
629
|
|
|
627
630
|
// src/http/handler.ts
|
|
631
|
+
var WORKING_PROVIDER = "working";
|
|
632
|
+
async function setWorkingMessage(db, conversationId) {
|
|
633
|
+
await db.ensureConversation(conversationId);
|
|
634
|
+
await db.clearWorkingMessages?.(conversationId);
|
|
635
|
+
await db.saveMessage({
|
|
636
|
+
conversationId,
|
|
637
|
+
role: "assistant",
|
|
638
|
+
content: "",
|
|
639
|
+
provider: WORKING_PROVIDER,
|
|
640
|
+
senderType: "ai"
|
|
641
|
+
});
|
|
642
|
+
}
|
|
628
643
|
var SHARED_CONVERSATION_ID = "shared";
|
|
629
644
|
var conversationTurnSeq = /* @__PURE__ */ new Map();
|
|
630
645
|
function beginConversationTurn(conversationId) {
|
|
@@ -697,6 +712,8 @@ function createChatHandler(options) {
|
|
|
697
712
|
}
|
|
698
713
|
},
|
|
699
714
|
async POST(request) {
|
|
715
|
+
let trackedConversationId;
|
|
716
|
+
let trackedTurn = 0;
|
|
700
717
|
try {
|
|
701
718
|
const body = await request.json();
|
|
702
719
|
const conversationId = await resolveSharedConversationId(
|
|
@@ -704,21 +721,16 @@ function createChatHandler(options) {
|
|
|
704
721
|
options,
|
|
705
722
|
body.conversationId
|
|
706
723
|
);
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
if (!conversationId
|
|
724
|
+
trackedConversationId = conversationId;
|
|
725
|
+
if (body.type === "working-clear") {
|
|
726
|
+
if (!conversationId) {
|
|
710
727
|
return Response.json(
|
|
711
|
-
{ error: "conversationId
|
|
728
|
+
{ error: "conversationId is required" },
|
|
712
729
|
{ status: 400 }
|
|
713
730
|
);
|
|
714
731
|
}
|
|
715
|
-
if (options.db) {
|
|
716
|
-
await options.db.
|
|
717
|
-
await options.db.saveMessage({
|
|
718
|
-
conversationId,
|
|
719
|
-
role: "assistant",
|
|
720
|
-
content
|
|
721
|
-
});
|
|
732
|
+
if (options.db?.clearWorkingMessages) {
|
|
733
|
+
await options.db.clearWorkingMessages(conversationId);
|
|
722
734
|
}
|
|
723
735
|
return Response.json({ ok: true, conversationId });
|
|
724
736
|
}
|
|
@@ -766,7 +778,8 @@ function createChatHandler(options) {
|
|
|
766
778
|
);
|
|
767
779
|
persistAttachmentPaths = attachmentPaths;
|
|
768
780
|
}
|
|
769
|
-
const turn = beginConversationTurn(conversationId);
|
|
781
|
+
const turn = beginConversationTurn(conversationId ?? SHARED_CONVERSATION_ID);
|
|
782
|
+
trackedTurn = turn;
|
|
770
783
|
const signal = request.signal;
|
|
771
784
|
if (options.db && conversationId) {
|
|
772
785
|
const latest = messages[messages.length - 1];
|
|
@@ -782,13 +795,26 @@ function createChatHandler(options) {
|
|
|
782
795
|
senderName: body.senderName?.trim() || void 0
|
|
783
796
|
});
|
|
784
797
|
}
|
|
798
|
+
await setWorkingMessage(options.db, conversationId);
|
|
785
799
|
}
|
|
786
800
|
const latestUser = [...messages].reverse().find((m) => m.role === "user");
|
|
787
801
|
const priorConversationsContext = options.db ? await buildPriorConversationsContext(options.db, {
|
|
788
802
|
excludeConversationId: conversationId,
|
|
789
803
|
currentRequest: latestUser?.content ?? ""
|
|
790
804
|
}) : "";
|
|
791
|
-
if (
|
|
805
|
+
if (!isActiveConversationTurn(
|
|
806
|
+
conversationId ?? SHARED_CONVERSATION_ID,
|
|
807
|
+
turn
|
|
808
|
+
)) {
|
|
809
|
+
return Response.json({
|
|
810
|
+
superseded: true,
|
|
811
|
+
conversationId: conversationId ?? null
|
|
812
|
+
});
|
|
813
|
+
}
|
|
814
|
+
if (signal.aborted) {
|
|
815
|
+
if (options.db?.clearWorkingMessages && conversationId) {
|
|
816
|
+
await options.db.clearWorkingMessages(conversationId);
|
|
817
|
+
}
|
|
792
818
|
return Response.json({
|
|
793
819
|
superseded: true,
|
|
794
820
|
conversationId: conversationId ?? null
|
|
@@ -799,7 +825,10 @@ function createChatHandler(options) {
|
|
|
799
825
|
attachmentPaths,
|
|
800
826
|
priorConversationsContext: priorConversationsContext || void 0
|
|
801
827
|
});
|
|
802
|
-
if (!isActiveConversationTurn(
|
|
828
|
+
if (!isActiveConversationTurn(
|
|
829
|
+
conversationId ?? SHARED_CONVERSATION_ID,
|
|
830
|
+
turn
|
|
831
|
+
)) {
|
|
803
832
|
return Response.json({
|
|
804
833
|
superseded: true,
|
|
805
834
|
conversationId: conversationId ?? null
|
|
@@ -811,6 +840,7 @@ function createChatHandler(options) {
|
|
|
811
840
|
}
|
|
812
841
|
if (options.db && conversationId) {
|
|
813
842
|
await options.db.ensureConversation(conversationId);
|
|
843
|
+
await options.db.clearWorkingMessages?.(conversationId);
|
|
814
844
|
await options.db.saveMessage({
|
|
815
845
|
conversationId,
|
|
816
846
|
role: "assistant",
|
|
@@ -834,6 +864,11 @@ function createChatHandler(options) {
|
|
|
834
864
|
});
|
|
835
865
|
} catch (err) {
|
|
836
866
|
console.error("Chat API error:", err);
|
|
867
|
+
if (trackedConversationId && options.db?.clearWorkingMessages && isActiveConversationTurn(trackedConversationId, trackedTurn)) {
|
|
868
|
+
await options.db.clearWorkingMessages(trackedConversationId).catch(
|
|
869
|
+
() => void 0
|
|
870
|
+
);
|
|
871
|
+
}
|
|
837
872
|
return Response.json(
|
|
838
873
|
{
|
|
839
874
|
error: "Sorry about that \u2014 I couldn't finish this right now. Happy to jump on a quick call if you'd like help \u2014 just let us know when works."
|
|
@@ -903,6 +938,16 @@ function createLocalDirectoryStore(baseDir) {
|
|
|
903
938
|
await writeConversation(filePath, existing);
|
|
904
939
|
return message;
|
|
905
940
|
},
|
|
941
|
+
async clearWorkingMessages(conversationId) {
|
|
942
|
+
const filePath = fileFor(conversationId);
|
|
943
|
+
const existing = await readConversation(filePath);
|
|
944
|
+
if (!existing) return;
|
|
945
|
+
const next = existing.messages.filter((m) => m.provider !== "working");
|
|
946
|
+
if (next.length === existing.messages.length) return;
|
|
947
|
+
existing.messages = next;
|
|
948
|
+
existing.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
949
|
+
await writeConversation(filePath, existing);
|
|
950
|
+
},
|
|
906
951
|
async listMessages(conversationId) {
|
|
907
952
|
const existing = await readConversation(fileFor(conversationId));
|
|
908
953
|
return existing?.messages ?? [];
|
|
@@ -1009,6 +1054,15 @@ function createMaintainerProStore(options) {
|
|
|
1009
1054
|
);
|
|
1010
1055
|
return data.message;
|
|
1011
1056
|
},
|
|
1057
|
+
async clearWorkingMessages(conversationId) {
|
|
1058
|
+
await mpFetch(
|
|
1059
|
+
baseUrl,
|
|
1060
|
+
apiKey,
|
|
1061
|
+
`/api/v1/store/conversations/${encodeURIComponent(conversationId)}/messages?provider=working`,
|
|
1062
|
+
{ method: "DELETE" },
|
|
1063
|
+
fetchImpl
|
|
1064
|
+
);
|
|
1065
|
+
},
|
|
1012
1066
|
async listMessages(conversationId) {
|
|
1013
1067
|
const data = await mpFetch(
|
|
1014
1068
|
baseUrl,
|
|
@@ -1090,6 +1144,7 @@ function createMaintainerProStoreFromEnv() {
|
|
|
1090
1144
|
}
|
|
1091
1145
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1092
1146
|
0 && (module.exports = {
|
|
1147
|
+
WORKING_PROVIDER,
|
|
1093
1148
|
buildClaudeUserPrompt,
|
|
1094
1149
|
buildConversationPrompt,
|
|
1095
1150
|
buildCursorPrompt,
|
package/dist/index.d.cts
CHANGED
|
@@ -111,6 +111,8 @@ declare function createToolValidator(schemas: ToolSchemaMap): (toolCall: ToolCal
|
|
|
111
111
|
error: string;
|
|
112
112
|
};
|
|
113
113
|
|
|
114
|
+
/** Stored on assistant rows while a single in-flight AI turn is running. */
|
|
115
|
+
declare const WORKING_PROVIDER = "working";
|
|
114
116
|
/** Minimal persistence contract (file store, SQL, or Maintainer Pro). */
|
|
115
117
|
interface ChatStoreLike {
|
|
116
118
|
ensureConversation(id: string): Promise<void>;
|
|
@@ -133,6 +135,8 @@ interface ChatStoreLike {
|
|
|
133
135
|
senderType?: "client" | "developer" | "ai" | null;
|
|
134
136
|
senderName?: string | null;
|
|
135
137
|
}>>;
|
|
138
|
+
/** Remove in-progress working placeholders (at most one per conversation). */
|
|
139
|
+
clearWorkingMessages?(conversationId: string): Promise<void>;
|
|
136
140
|
/** All conversations under the store (for prior-chat context). */
|
|
137
141
|
listConversations?(): Promise<Array<{
|
|
138
142
|
id: string;
|
|
@@ -141,6 +145,7 @@ interface ChatStoreLike {
|
|
|
141
145
|
role: string;
|
|
142
146
|
content: string;
|
|
143
147
|
createdAt?: string | Date;
|
|
148
|
+
provider?: string | null;
|
|
144
149
|
}>;
|
|
145
150
|
}>>;
|
|
146
151
|
saveToolEvents?(conversationId: string, events: Array<{
|
|
@@ -236,4 +241,4 @@ interface PriorConversationOptions {
|
|
|
236
241
|
*/
|
|
237
242
|
declare function buildPriorConversationsContext(db: ChatStoreLike, options: PriorConversationOptions): Promise<string>;
|
|
238
243
|
|
|
239
|
-
export { type AiCliProviderId, type AiProvider, type AiResponse, type CallAiOptions, type ChatAttachment, type ChatHandlerOptions, type ChatHandlers, type ChatMessage, type ChatSenderType, type ChatStoreLike, type ChatUser, type ClientContext, type LocalStoredMessage, type MaintainerProStoreOptions, type PriorConversationOptions, type ProviderPreference, type ToolCall, type ToolSchemaMap, buildClaudeUserPrompt, buildConversationPrompt, buildCursorPrompt, buildPriorConversationsContext, callAi, commandExists, createAntigravityProvider, createBuiltinProviders, createChatHandler, createClaudeProvider, createCursorProvider, createDefaultSystemPrompt, createLocalDirectoryStore, createMaintainerProStore, createMaintainerProStoreFromEnv, createToolValidator, formatClientContext, getProviderPreference, parseAiResponse, providerLabel, resolveCliBinary, resolveProvider, saveChatAttachments, toNextRoute };
|
|
244
|
+
export { type AiCliProviderId, type AiProvider, type AiResponse, type CallAiOptions, type ChatAttachment, type ChatHandlerOptions, type ChatHandlers, type ChatMessage, type ChatSenderType, type ChatStoreLike, type ChatUser, type ClientContext, type LocalStoredMessage, type MaintainerProStoreOptions, type PriorConversationOptions, type ProviderPreference, type ToolCall, type ToolSchemaMap, WORKING_PROVIDER, buildClaudeUserPrompt, buildConversationPrompt, buildCursorPrompt, buildPriorConversationsContext, callAi, commandExists, createAntigravityProvider, createBuiltinProviders, createChatHandler, createClaudeProvider, createCursorProvider, createDefaultSystemPrompt, createLocalDirectoryStore, createMaintainerProStore, createMaintainerProStoreFromEnv, createToolValidator, formatClientContext, getProviderPreference, parseAiResponse, providerLabel, resolveCliBinary, resolveProvider, saveChatAttachments, toNextRoute };
|
package/dist/index.d.ts
CHANGED
|
@@ -111,6 +111,8 @@ declare function createToolValidator(schemas: ToolSchemaMap): (toolCall: ToolCal
|
|
|
111
111
|
error: string;
|
|
112
112
|
};
|
|
113
113
|
|
|
114
|
+
/** Stored on assistant rows while a single in-flight AI turn is running. */
|
|
115
|
+
declare const WORKING_PROVIDER = "working";
|
|
114
116
|
/** Minimal persistence contract (file store, SQL, or Maintainer Pro). */
|
|
115
117
|
interface ChatStoreLike {
|
|
116
118
|
ensureConversation(id: string): Promise<void>;
|
|
@@ -133,6 +135,8 @@ interface ChatStoreLike {
|
|
|
133
135
|
senderType?: "client" | "developer" | "ai" | null;
|
|
134
136
|
senderName?: string | null;
|
|
135
137
|
}>>;
|
|
138
|
+
/** Remove in-progress working placeholders (at most one per conversation). */
|
|
139
|
+
clearWorkingMessages?(conversationId: string): Promise<void>;
|
|
136
140
|
/** All conversations under the store (for prior-chat context). */
|
|
137
141
|
listConversations?(): Promise<Array<{
|
|
138
142
|
id: string;
|
|
@@ -141,6 +145,7 @@ interface ChatStoreLike {
|
|
|
141
145
|
role: string;
|
|
142
146
|
content: string;
|
|
143
147
|
createdAt?: string | Date;
|
|
148
|
+
provider?: string | null;
|
|
144
149
|
}>;
|
|
145
150
|
}>>;
|
|
146
151
|
saveToolEvents?(conversationId: string, events: Array<{
|
|
@@ -236,4 +241,4 @@ interface PriorConversationOptions {
|
|
|
236
241
|
*/
|
|
237
242
|
declare function buildPriorConversationsContext(db: ChatStoreLike, options: PriorConversationOptions): Promise<string>;
|
|
238
243
|
|
|
239
|
-
export { type AiCliProviderId, type AiProvider, type AiResponse, type CallAiOptions, type ChatAttachment, type ChatHandlerOptions, type ChatHandlers, type ChatMessage, type ChatSenderType, type ChatStoreLike, type ChatUser, type ClientContext, type LocalStoredMessage, type MaintainerProStoreOptions, type PriorConversationOptions, type ProviderPreference, type ToolCall, type ToolSchemaMap, buildClaudeUserPrompt, buildConversationPrompt, buildCursorPrompt, buildPriorConversationsContext, callAi, commandExists, createAntigravityProvider, createBuiltinProviders, createChatHandler, createClaudeProvider, createCursorProvider, createDefaultSystemPrompt, createLocalDirectoryStore, createMaintainerProStore, createMaintainerProStoreFromEnv, createToolValidator, formatClientContext, getProviderPreference, parseAiResponse, providerLabel, resolveCliBinary, resolveProvider, saveChatAttachments, toNextRoute };
|
|
244
|
+
export { type AiCliProviderId, type AiProvider, type AiResponse, type CallAiOptions, type ChatAttachment, type ChatHandlerOptions, type ChatHandlers, type ChatMessage, type ChatSenderType, type ChatStoreLike, type ChatUser, type ClientContext, type LocalStoredMessage, type MaintainerProStoreOptions, type PriorConversationOptions, type ProviderPreference, type ToolCall, type ToolSchemaMap, WORKING_PROVIDER, buildClaudeUserPrompt, buildConversationPrompt, buildCursorPrompt, buildPriorConversationsContext, callAi, commandExists, createAntigravityProvider, createBuiltinProviders, createChatHandler, createClaudeProvider, createCursorProvider, createDefaultSystemPrompt, createLocalDirectoryStore, createMaintainerProStore, createMaintainerProStoreFromEnv, createToolValidator, formatClientContext, getProviderPreference, parseAiResponse, providerLabel, resolveCliBinary, resolveProvider, saveChatAttachments, toNextRoute };
|
package/dist/index.js
CHANGED
|
@@ -533,7 +533,9 @@ async function buildPriorConversationsContext(db, options) {
|
|
|
533
533
|
).slice(0, maxConversations) : ranked;
|
|
534
534
|
const blocks = selected.map((c) => {
|
|
535
535
|
const slice = c.messages.length > maxMessages ? c.messages.slice(-maxMessages) : c.messages;
|
|
536
|
-
const lines = slice.filter(
|
|
536
|
+
const lines = slice.filter(
|
|
537
|
+
(m) => (m.role === "user" || m.role === "assistant") && m.provider !== "working" && Boolean(m.content?.trim())
|
|
538
|
+
).map(
|
|
537
539
|
(m) => `${m.role === "user" ? "Human" : "Assistant"}: ${truncate(m.content)}`
|
|
538
540
|
);
|
|
539
541
|
const when = c.updatedAt ? ` (updated ${c.updatedAt.slice(0, 10)})` : "";
|
|
@@ -566,6 +568,18 @@ function createToolValidator(schemas) {
|
|
|
566
568
|
}
|
|
567
569
|
|
|
568
570
|
// src/http/handler.ts
|
|
571
|
+
var WORKING_PROVIDER = "working";
|
|
572
|
+
async function setWorkingMessage(db, conversationId) {
|
|
573
|
+
await db.ensureConversation(conversationId);
|
|
574
|
+
await db.clearWorkingMessages?.(conversationId);
|
|
575
|
+
await db.saveMessage({
|
|
576
|
+
conversationId,
|
|
577
|
+
role: "assistant",
|
|
578
|
+
content: "",
|
|
579
|
+
provider: WORKING_PROVIDER,
|
|
580
|
+
senderType: "ai"
|
|
581
|
+
});
|
|
582
|
+
}
|
|
569
583
|
var SHARED_CONVERSATION_ID = "shared";
|
|
570
584
|
var conversationTurnSeq = /* @__PURE__ */ new Map();
|
|
571
585
|
function beginConversationTurn(conversationId) {
|
|
@@ -638,6 +652,8 @@ function createChatHandler(options) {
|
|
|
638
652
|
}
|
|
639
653
|
},
|
|
640
654
|
async POST(request) {
|
|
655
|
+
let trackedConversationId;
|
|
656
|
+
let trackedTurn = 0;
|
|
641
657
|
try {
|
|
642
658
|
const body = await request.json();
|
|
643
659
|
const conversationId = await resolveSharedConversationId(
|
|
@@ -645,21 +661,16 @@ function createChatHandler(options) {
|
|
|
645
661
|
options,
|
|
646
662
|
body.conversationId
|
|
647
663
|
);
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
if (!conversationId
|
|
664
|
+
trackedConversationId = conversationId;
|
|
665
|
+
if (body.type === "working-clear") {
|
|
666
|
+
if (!conversationId) {
|
|
651
667
|
return Response.json(
|
|
652
|
-
{ error: "conversationId
|
|
668
|
+
{ error: "conversationId is required" },
|
|
653
669
|
{ status: 400 }
|
|
654
670
|
);
|
|
655
671
|
}
|
|
656
|
-
if (options.db) {
|
|
657
|
-
await options.db.
|
|
658
|
-
await options.db.saveMessage({
|
|
659
|
-
conversationId,
|
|
660
|
-
role: "assistant",
|
|
661
|
-
content
|
|
662
|
-
});
|
|
672
|
+
if (options.db?.clearWorkingMessages) {
|
|
673
|
+
await options.db.clearWorkingMessages(conversationId);
|
|
663
674
|
}
|
|
664
675
|
return Response.json({ ok: true, conversationId });
|
|
665
676
|
}
|
|
@@ -707,7 +718,8 @@ function createChatHandler(options) {
|
|
|
707
718
|
);
|
|
708
719
|
persistAttachmentPaths = attachmentPaths;
|
|
709
720
|
}
|
|
710
|
-
const turn = beginConversationTurn(conversationId);
|
|
721
|
+
const turn = beginConversationTurn(conversationId ?? SHARED_CONVERSATION_ID);
|
|
722
|
+
trackedTurn = turn;
|
|
711
723
|
const signal = request.signal;
|
|
712
724
|
if (options.db && conversationId) {
|
|
713
725
|
const latest = messages[messages.length - 1];
|
|
@@ -723,13 +735,26 @@ function createChatHandler(options) {
|
|
|
723
735
|
senderName: body.senderName?.trim() || void 0
|
|
724
736
|
});
|
|
725
737
|
}
|
|
738
|
+
await setWorkingMessage(options.db, conversationId);
|
|
726
739
|
}
|
|
727
740
|
const latestUser = [...messages].reverse().find((m) => m.role === "user");
|
|
728
741
|
const priorConversationsContext = options.db ? await buildPriorConversationsContext(options.db, {
|
|
729
742
|
excludeConversationId: conversationId,
|
|
730
743
|
currentRequest: latestUser?.content ?? ""
|
|
731
744
|
}) : "";
|
|
732
|
-
if (
|
|
745
|
+
if (!isActiveConversationTurn(
|
|
746
|
+
conversationId ?? SHARED_CONVERSATION_ID,
|
|
747
|
+
turn
|
|
748
|
+
)) {
|
|
749
|
+
return Response.json({
|
|
750
|
+
superseded: true,
|
|
751
|
+
conversationId: conversationId ?? null
|
|
752
|
+
});
|
|
753
|
+
}
|
|
754
|
+
if (signal.aborted) {
|
|
755
|
+
if (options.db?.clearWorkingMessages && conversationId) {
|
|
756
|
+
await options.db.clearWorkingMessages(conversationId);
|
|
757
|
+
}
|
|
733
758
|
return Response.json({
|
|
734
759
|
superseded: true,
|
|
735
760
|
conversationId: conversationId ?? null
|
|
@@ -740,7 +765,10 @@ function createChatHandler(options) {
|
|
|
740
765
|
attachmentPaths,
|
|
741
766
|
priorConversationsContext: priorConversationsContext || void 0
|
|
742
767
|
});
|
|
743
|
-
if (!isActiveConversationTurn(
|
|
768
|
+
if (!isActiveConversationTurn(
|
|
769
|
+
conversationId ?? SHARED_CONVERSATION_ID,
|
|
770
|
+
turn
|
|
771
|
+
)) {
|
|
744
772
|
return Response.json({
|
|
745
773
|
superseded: true,
|
|
746
774
|
conversationId: conversationId ?? null
|
|
@@ -752,6 +780,7 @@ function createChatHandler(options) {
|
|
|
752
780
|
}
|
|
753
781
|
if (options.db && conversationId) {
|
|
754
782
|
await options.db.ensureConversation(conversationId);
|
|
783
|
+
await options.db.clearWorkingMessages?.(conversationId);
|
|
755
784
|
await options.db.saveMessage({
|
|
756
785
|
conversationId,
|
|
757
786
|
role: "assistant",
|
|
@@ -775,6 +804,11 @@ function createChatHandler(options) {
|
|
|
775
804
|
});
|
|
776
805
|
} catch (err) {
|
|
777
806
|
console.error("Chat API error:", err);
|
|
807
|
+
if (trackedConversationId && options.db?.clearWorkingMessages && isActiveConversationTurn(trackedConversationId, trackedTurn)) {
|
|
808
|
+
await options.db.clearWorkingMessages(trackedConversationId).catch(
|
|
809
|
+
() => void 0
|
|
810
|
+
);
|
|
811
|
+
}
|
|
778
812
|
return Response.json(
|
|
779
813
|
{
|
|
780
814
|
error: "Sorry about that \u2014 I couldn't finish this right now. Happy to jump on a quick call if you'd like help \u2014 just let us know when works."
|
|
@@ -844,6 +878,16 @@ function createLocalDirectoryStore(baseDir) {
|
|
|
844
878
|
await writeConversation(filePath, existing);
|
|
845
879
|
return message;
|
|
846
880
|
},
|
|
881
|
+
async clearWorkingMessages(conversationId) {
|
|
882
|
+
const filePath = fileFor(conversationId);
|
|
883
|
+
const existing = await readConversation(filePath);
|
|
884
|
+
if (!existing) return;
|
|
885
|
+
const next = existing.messages.filter((m) => m.provider !== "working");
|
|
886
|
+
if (next.length === existing.messages.length) return;
|
|
887
|
+
existing.messages = next;
|
|
888
|
+
existing.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
889
|
+
await writeConversation(filePath, existing);
|
|
890
|
+
},
|
|
847
891
|
async listMessages(conversationId) {
|
|
848
892
|
const existing = await readConversation(fileFor(conversationId));
|
|
849
893
|
return existing?.messages ?? [];
|
|
@@ -950,6 +994,15 @@ function createMaintainerProStore(options) {
|
|
|
950
994
|
);
|
|
951
995
|
return data.message;
|
|
952
996
|
},
|
|
997
|
+
async clearWorkingMessages(conversationId) {
|
|
998
|
+
await mpFetch(
|
|
999
|
+
baseUrl,
|
|
1000
|
+
apiKey,
|
|
1001
|
+
`/api/v1/store/conversations/${encodeURIComponent(conversationId)}/messages?provider=working`,
|
|
1002
|
+
{ method: "DELETE" },
|
|
1003
|
+
fetchImpl
|
|
1004
|
+
);
|
|
1005
|
+
},
|
|
953
1006
|
async listMessages(conversationId) {
|
|
954
1007
|
const data = await mpFetch(
|
|
955
1008
|
baseUrl,
|
|
@@ -1030,6 +1083,7 @@ function createMaintainerProStoreFromEnv() {
|
|
|
1030
1083
|
return createMaintainerProStore({ baseUrl, apiKey });
|
|
1031
1084
|
}
|
|
1032
1085
|
export {
|
|
1086
|
+
WORKING_PROVIDER,
|
|
1033
1087
|
buildClaudeUserPrompt,
|
|
1034
1088
|
buildConversationPrompt,
|
|
1035
1089
|
buildCursorPrompt,
|