replicas-cli 0.2.455 → 0.2.457
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.mjs +449 -91
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -7730,29 +7730,51 @@ function getClaudePartialMessageStreamId(event) {
|
|
|
7730
7730
|
if (event.type !== CLAUDE_PARTIAL_MESSAGE_EVENT_TYPE) return null;
|
|
7731
7731
|
return typeof event.payload.streamId === "string" && event.payload.streamId ? event.payload.streamId : null;
|
|
7732
7732
|
}
|
|
7733
|
-
|
|
7734
|
-
const streamId = getClaudePartialMessageStreamId(event);
|
|
7735
|
-
if (streamId) {
|
|
7736
|
-
return `${CLAUDE_PARTIAL_MESSAGE_EVENT_TYPE}:${streamId}`;
|
|
7737
|
-
}
|
|
7738
|
-
const normalize = (input) => {
|
|
7739
|
-
if (Array.isArray(input)) return input.map(normalize);
|
|
7740
|
-
if (input && typeof input === "object") {
|
|
7741
|
-
const entries = Object.entries(input).sort(([a], [b]) => a.localeCompare(b)).map(([key, val]) => [key, normalize(val)]);
|
|
7742
|
-
return Object.fromEntries(entries);
|
|
7743
|
-
}
|
|
7744
|
-
return input;
|
|
7745
|
-
};
|
|
7746
|
-
try {
|
|
7747
|
-
return JSON.stringify(normalize(event));
|
|
7748
|
-
} catch {
|
|
7749
|
-
return String(event);
|
|
7750
|
-
}
|
|
7751
|
-
}
|
|
7733
|
+
var ACCEPTED_USER_MESSAGE_SOURCE = "replicas-chat-turn-accepted";
|
|
7752
7734
|
var USER_MESSAGE_ID_PAYLOAD_KEY = "replicasMessageId";
|
|
7753
7735
|
var CODEX_ASP_ITEM_ID_PAYLOAD_KEY = "codexAspItemId";
|
|
7736
|
+
var CODEX_ASP_TRANSCRIPT_UPDATED_EVENT_TYPE = "codex-asp-transcript-updated";
|
|
7754
7737
|
var CODEX_QUOTA_STATUS_EVENT_TYPE = "codex-quota-status";
|
|
7755
7738
|
var CHAT_INTERRUPTED_EVENT_TYPE = "replicas-interrupted";
|
|
7739
|
+
var CHAT_GOAL_EVENT_TYPE = "chat-goal";
|
|
7740
|
+
var CHAT_GOAL_STATUSES = [
|
|
7741
|
+
"active",
|
|
7742
|
+
"paused",
|
|
7743
|
+
"blocked",
|
|
7744
|
+
"usageLimited",
|
|
7745
|
+
"budgetLimited",
|
|
7746
|
+
"complete"
|
|
7747
|
+
];
|
|
7748
|
+
function isChatGoalStatus(value) {
|
|
7749
|
+
return typeof value === "string" && CHAT_GOAL_STATUSES.some((status) => status === value);
|
|
7750
|
+
}
|
|
7751
|
+
function coerceChatGoalPayload(payload) {
|
|
7752
|
+
const goal = payload.goal;
|
|
7753
|
+
if (goal === null || goal === void 0) return null;
|
|
7754
|
+
if (typeof goal !== "object") return null;
|
|
7755
|
+
const candidate = goal;
|
|
7756
|
+
const threadId = candidate.threadId;
|
|
7757
|
+
const objective = candidate.objective;
|
|
7758
|
+
const status = candidate.status;
|
|
7759
|
+
const tokensUsed = candidate.tokensUsed;
|
|
7760
|
+
const timeUsedSeconds = candidate.timeUsedSeconds;
|
|
7761
|
+
const createdAt = candidate.createdAt;
|
|
7762
|
+
const updatedAt = candidate.updatedAt;
|
|
7763
|
+
const tokenBudget = candidate.tokenBudget ?? null;
|
|
7764
|
+
if (typeof threadId !== "string" || typeof objective !== "string" || !isChatGoalStatus(status) || typeof tokensUsed !== "number" || typeof timeUsedSeconds !== "number" || typeof createdAt !== "string" || typeof updatedAt !== "string" || tokenBudget !== null && typeof tokenBudget !== "number") {
|
|
7765
|
+
return null;
|
|
7766
|
+
}
|
|
7767
|
+
return {
|
|
7768
|
+
threadId,
|
|
7769
|
+
objective,
|
|
7770
|
+
status,
|
|
7771
|
+
tokenBudget,
|
|
7772
|
+
tokensUsed,
|
|
7773
|
+
timeUsedSeconds,
|
|
7774
|
+
createdAt,
|
|
7775
|
+
updatedAt
|
|
7776
|
+
};
|
|
7777
|
+
}
|
|
7756
7778
|
|
|
7757
7779
|
// ../shared/src/credentials/types.ts
|
|
7758
7780
|
var CREDENTIAL_SCOPE = {
|
|
@@ -10056,7 +10078,7 @@ function formatTurnElapsed(ms) {
|
|
|
10056
10078
|
}
|
|
10057
10079
|
|
|
10058
10080
|
// ../shared/src/cli-version.ts
|
|
10059
|
-
var CLI_VERSION = "0.2.
|
|
10081
|
+
var CLI_VERSION = "0.2.457";
|
|
10060
10082
|
|
|
10061
10083
|
// ../shared/src/version.ts
|
|
10062
10084
|
function compareVersions(v1, v2) {
|
|
@@ -24651,6 +24673,90 @@ function normalizeCodexAspTranscriptStatus(status, failed = false) {
|
|
|
24651
24673
|
if (status === "completed") return "completed";
|
|
24652
24674
|
return "in_progress";
|
|
24653
24675
|
}
|
|
24676
|
+
function isCodexAspTranscript(value) {
|
|
24677
|
+
if (!isRecord(value)) return false;
|
|
24678
|
+
return typeof value.threadId === "string" && typeof value.updatedAt === "string" && Array.isArray(value.turns);
|
|
24679
|
+
}
|
|
24680
|
+
function isCodexAspTranscriptDelta(value) {
|
|
24681
|
+
if (!isRecord(value)) return false;
|
|
24682
|
+
if (typeof value.threadId !== "string" || typeof value.updatedAt !== "string" || !Array.isArray(value.turns) || value.reset !== void 0 && value.reset !== null && !isCodexAspTranscript(value.reset)) {
|
|
24683
|
+
return false;
|
|
24684
|
+
}
|
|
24685
|
+
return value.turns.every((turn) => isRecord(turn) && typeof turn.id === "string" && typeof turn.status === "string" && typeof turn.startedAt === "string" && (turn.completedAt === null || typeof turn.completedAt === "string") && Array.isArray(turn.items) && turn.items.every((item) => isRecord(item) && typeof item.id === "string" && (item.item === void 0 || isRecord(item.item) && typeof item.item.type === "string" && typeof item.item.id === "string" && typeof item.item.timestamp === "string") && (item.appendText === void 0 || typeof item.appendText === "string") && (item.appendOutput === void 0 || typeof item.appendOutput === "string")));
|
|
24686
|
+
}
|
|
24687
|
+
function appendCodexAspTranscriptField(current, append) {
|
|
24688
|
+
return append === void 0 ? current : `${current ?? ""}${append}`;
|
|
24689
|
+
}
|
|
24690
|
+
function patchCodexAspTranscriptItem(current, delta) {
|
|
24691
|
+
const base = delta.item ?? current;
|
|
24692
|
+
if (!base) {
|
|
24693
|
+
return null;
|
|
24694
|
+
}
|
|
24695
|
+
if (base.type === "agentMessage" && delta.appendText !== void 0) {
|
|
24696
|
+
return {
|
|
24697
|
+
...base,
|
|
24698
|
+
text: appendCodexAspTranscriptField(base.text, delta.appendText) ?? ""
|
|
24699
|
+
};
|
|
24700
|
+
}
|
|
24701
|
+
if ((base.type === "commandExecution" || base.type === "fileChange") && delta.appendOutput !== void 0) {
|
|
24702
|
+
return {
|
|
24703
|
+
...base,
|
|
24704
|
+
output: appendCodexAspTranscriptField(base.output, delta.appendOutput)
|
|
24705
|
+
};
|
|
24706
|
+
}
|
|
24707
|
+
return base;
|
|
24708
|
+
}
|
|
24709
|
+
function applyCodexAspTranscriptDelta(current, delta) {
|
|
24710
|
+
if (!delta) return current ?? null;
|
|
24711
|
+
if (delta.reset === null) {
|
|
24712
|
+
return null;
|
|
24713
|
+
}
|
|
24714
|
+
const base = delta.reset ?? (current?.threadId === delta.threadId ? current : {
|
|
24715
|
+
threadId: delta.threadId,
|
|
24716
|
+
updatedAt: delta.updatedAt,
|
|
24717
|
+
turns: []
|
|
24718
|
+
});
|
|
24719
|
+
const turns = base.turns.map((turn) => ({
|
|
24720
|
+
...turn,
|
|
24721
|
+
items: [...turn.items]
|
|
24722
|
+
}));
|
|
24723
|
+
for (const turnDelta of delta.turns) {
|
|
24724
|
+
let turn = turns.find((candidate) => candidate.id === turnDelta.id);
|
|
24725
|
+
if (!turn) {
|
|
24726
|
+
turn = {
|
|
24727
|
+
id: turnDelta.id,
|
|
24728
|
+
status: turnDelta.status,
|
|
24729
|
+
startedAt: turnDelta.startedAt,
|
|
24730
|
+
completedAt: turnDelta.completedAt,
|
|
24731
|
+
items: []
|
|
24732
|
+
};
|
|
24733
|
+
turns.push(turn);
|
|
24734
|
+
} else {
|
|
24735
|
+
turn.status = turnDelta.status;
|
|
24736
|
+
turn.startedAt = turnDelta.startedAt;
|
|
24737
|
+
turn.completedAt = turnDelta.completedAt;
|
|
24738
|
+
}
|
|
24739
|
+
for (const itemDelta of turnDelta.items) {
|
|
24740
|
+
const itemIndex = turn.items.findIndex((item) => item.id === itemDelta.id);
|
|
24741
|
+
const patched = patchCodexAspTranscriptItem(turn.items[itemIndex], itemDelta);
|
|
24742
|
+
if (!patched) continue;
|
|
24743
|
+
if (itemIndex === -1) {
|
|
24744
|
+
turn.items.push(patched);
|
|
24745
|
+
} else {
|
|
24746
|
+
turn.items[itemIndex] = patched;
|
|
24747
|
+
}
|
|
24748
|
+
}
|
|
24749
|
+
}
|
|
24750
|
+
turns.sort((a, b) => Date.parse(a.startedAt) - Date.parse(b.startedAt));
|
|
24751
|
+
for (const turn of turns) {
|
|
24752
|
+
turn.items.sort((a, b) => (a.sequence ?? Number.MAX_SAFE_INTEGER) - (b.sequence ?? Number.MAX_SAFE_INTEGER) || Date.parse(a.timestamp) - Date.parse(b.timestamp));
|
|
24753
|
+
}
|
|
24754
|
+
return {
|
|
24755
|
+
threadId: delta.threadId,
|
|
24756
|
+
updatedAt: delta.updatedAt,
|
|
24757
|
+
turns
|
|
24758
|
+
};
|
|
24759
|
+
}
|
|
24654
24760
|
|
|
24655
24761
|
// ../shared/src/routes/workspaces.ts
|
|
24656
24762
|
var WORKSPACE_STATUSES = ["active", "sleeping", "archived", "preparing", "error"];
|
|
@@ -24970,8 +25076,25 @@ function parseSkillName(tool, input) {
|
|
|
24970
25076
|
const skillName = parsedInput.skill ?? parsedInput.name;
|
|
24971
25077
|
return typeof skillName === "string" && skillName ? skillName : null;
|
|
24972
25078
|
}
|
|
25079
|
+
function parseSkillFilePath(input) {
|
|
25080
|
+
const parsedInput = typeof input === "string" ? safeJsonParse(input, null) : input;
|
|
25081
|
+
if (!isRecord(parsedInput)) return null;
|
|
25082
|
+
const path6 = [parsedInput.path, parsedInput.filePath, parsedInput.file_path].find((value) => typeof value === "string" && value.length > 0);
|
|
25083
|
+
if (!path6) return null;
|
|
25084
|
+
const parts = path6.split(/[\\/]+/).filter(Boolean);
|
|
25085
|
+
if (parts.length < 2) return null;
|
|
25086
|
+
if (parts[parts.length - 1].toLowerCase() !== "skill.md") return null;
|
|
25087
|
+
const skillName = parts[parts.length - 2];
|
|
25088
|
+
return skillName && skillName.toLowerCase() !== "skills" ? skillName : null;
|
|
25089
|
+
}
|
|
25090
|
+
function skillNameFromToolCall(tool, input) {
|
|
25091
|
+
const directSkillName = parseSkillName(tool, input);
|
|
25092
|
+
if (directSkillName) return directSkillName;
|
|
25093
|
+
if (typeof tool !== "string" || !["read", "read_file", "readfile"].includes(tool.toLowerCase())) return null;
|
|
25094
|
+
return parseSkillFilePath(input);
|
|
25095
|
+
}
|
|
24973
25096
|
function createCallDisplayMessage(message) {
|
|
24974
|
-
const skillName = message.server.toLowerCase() === "skills" ? message.tool :
|
|
25097
|
+
const skillName = message.server.toLowerCase() === "skills" ? message.tool : skillNameFromToolCall(message.tool, message.input);
|
|
24975
25098
|
if (skillName === null) return { ...message, type: "tool_call" };
|
|
24976
25099
|
return {
|
|
24977
25100
|
id: message.id,
|
|
@@ -24997,6 +25120,49 @@ function areUserMessagesWithinMatchWindow(a, b) {
|
|
|
24997
25120
|
return a.content === b.content && Math.abs(parseTimestampMs(a.timestamp) - parseTimestampMs(b.timestamp)) <= USER_MESSAGE_MATCH_GRACE_PERIOD_MS;
|
|
24998
25121
|
}
|
|
24999
25122
|
|
|
25123
|
+
// ../shared/src/agent-event-utils.ts
|
|
25124
|
+
function getUserMessage(event) {
|
|
25125
|
+
return event.type === "event_msg" && event.payload.type === "user_message" && typeof event.payload.message === "string" ? event.payload.message : null;
|
|
25126
|
+
}
|
|
25127
|
+
function getUserMessageId(event) {
|
|
25128
|
+
const messageId = event.payload[USER_MESSAGE_ID_PAYLOAD_KEY];
|
|
25129
|
+
return typeof messageId === "string" ? messageId : null;
|
|
25130
|
+
}
|
|
25131
|
+
function getUserMessageItemId(event) {
|
|
25132
|
+
const itemId = event.payload[CODEX_ASP_ITEM_ID_PAYLOAD_KEY];
|
|
25133
|
+
return typeof itemId === "string" ? itemId : null;
|
|
25134
|
+
}
|
|
25135
|
+
function areSameUserMessageEvents(a, b) {
|
|
25136
|
+
const aMessage = getUserMessage(a);
|
|
25137
|
+
const bMessage = getUserMessage(b);
|
|
25138
|
+
if (!aMessage || aMessage !== bMessage) return false;
|
|
25139
|
+
const aMessageId = getUserMessageId(a);
|
|
25140
|
+
const bMessageId = getUserMessageId(b);
|
|
25141
|
+
if (aMessageId || bMessageId) return aMessageId === bMessageId;
|
|
25142
|
+
const aItemId = getUserMessageItemId(a);
|
|
25143
|
+
const bItemId = getUserMessageItemId(b);
|
|
25144
|
+
if (aItemId || bItemId) return aItemId === bItemId;
|
|
25145
|
+
return areUserMessagesWithinMatchWindow(
|
|
25146
|
+
{ content: aMessage, timestamp: a.timestamp },
|
|
25147
|
+
{ content: bMessage, timestamp: b.timestamp }
|
|
25148
|
+
);
|
|
25149
|
+
}
|
|
25150
|
+
function mergeAgentEvents(primary, supplemental, options) {
|
|
25151
|
+
const merged = [...primary];
|
|
25152
|
+
const { areDuplicates, mergeEvent } = options;
|
|
25153
|
+
for (const event of supplemental) {
|
|
25154
|
+
const existingIndex = merged.findIndex((existing) => areDuplicates(existing, event));
|
|
25155
|
+
if (existingIndex === -1) {
|
|
25156
|
+
merged.push(event);
|
|
25157
|
+
continue;
|
|
25158
|
+
}
|
|
25159
|
+
if (mergeEvent) {
|
|
25160
|
+
merged[existingIndex] = mergeEvent(merged[existingIndex], event);
|
|
25161
|
+
}
|
|
25162
|
+
}
|
|
25163
|
+
return merged;
|
|
25164
|
+
}
|
|
25165
|
+
|
|
25000
25166
|
// ../shared/src/display-message/parsers/codex-parser.ts
|
|
25001
25167
|
function getStatusFromExitCode(exitCode) {
|
|
25002
25168
|
return exitCode === 0 ? "completed" : "failed";
|
|
@@ -25573,6 +25739,15 @@ function parsePiEvents(events) {
|
|
|
25573
25739
|
for (const event of events) {
|
|
25574
25740
|
if (event.type === "event_msg" && event.payload.type === "user_message" && typeof event.payload.message === "string") {
|
|
25575
25741
|
messages.push({ id: `pi-user-${event.timestamp}-${messages.length}`, type: "user", content: event.payload.message, timestamp: event.timestamp });
|
|
25742
|
+
if (typeof event.payload.skillName === "string" && event.payload.skillName) {
|
|
25743
|
+
messages.push({
|
|
25744
|
+
id: `pi-skill-${event.timestamp}-${messages.length}`,
|
|
25745
|
+
type: "skill",
|
|
25746
|
+
skillName: event.payload.skillName,
|
|
25747
|
+
status: "completed",
|
|
25748
|
+
timestamp: event.timestamp
|
|
25749
|
+
});
|
|
25750
|
+
}
|
|
25576
25751
|
continue;
|
|
25577
25752
|
}
|
|
25578
25753
|
if (event.type === "pi-error") {
|
|
@@ -26401,6 +26576,16 @@ function messageForItem(item) {
|
|
|
26401
26576
|
timestamp: item.timestamp
|
|
26402
26577
|
};
|
|
26403
26578
|
}
|
|
26579
|
+
function skillMessagesForItem(item) {
|
|
26580
|
+
if (item.type !== "userMessage" || !item.skillNames) return [];
|
|
26581
|
+
return item.skillNames.filter((skillName) => skillName.trim().length > 0).map((skillName, index) => ({
|
|
26582
|
+
id: `skill-${item.id}-${index}`,
|
|
26583
|
+
type: "skill",
|
|
26584
|
+
skillName,
|
|
26585
|
+
status: "completed",
|
|
26586
|
+
timestamp: item.timestamp
|
|
26587
|
+
}));
|
|
26588
|
+
}
|
|
26404
26589
|
function stableString(value) {
|
|
26405
26590
|
if (value === void 0) return "";
|
|
26406
26591
|
if (typeof value !== "object" || value === null) return String(value);
|
|
@@ -26458,6 +26643,7 @@ function parseCodexAspTranscript(transcript) {
|
|
|
26458
26643
|
if (message) {
|
|
26459
26644
|
messages.push(message);
|
|
26460
26645
|
}
|
|
26646
|
+
messages.push(...skillMessagesForItem(item));
|
|
26461
26647
|
}
|
|
26462
26648
|
return messages;
|
|
26463
26649
|
}
|
|
@@ -33766,7 +33952,31 @@ function useGenerateWorkspaceName() {
|
|
|
33766
33952
|
// ../shared/src/hooks/useWorkspaceEngine.ts
|
|
33767
33953
|
import { useCallback as useCallback4 } from "react";
|
|
33768
33954
|
import { useQuery as useQuery2, useMutation as useMutation2 } from "@tanstack/react-query";
|
|
33769
|
-
|
|
33955
|
+
|
|
33956
|
+
// ../shared/src/workspace-chat.ts
|
|
33957
|
+
import { queryOptions } from "@tanstack/react-query";
|
|
33958
|
+
var workspaceChatKeys = {
|
|
33959
|
+
chats: (workspaceId) => ["workspace-chats", workspaceId],
|
|
33960
|
+
allChats: (workspaceId) => ["workspace-all-chats", workspaceId],
|
|
33961
|
+
histories: (workspaceId) => ["chat-history", workspaceId],
|
|
33962
|
+
history: (workspaceId, chatId) => ["chat-history", workspaceId, chatId],
|
|
33963
|
+
queues: (workspaceId) => ["chat-queue", workspaceId],
|
|
33964
|
+
queue: (workspaceId, chatId) => ["chat-queue", workspaceId, chatId]
|
|
33965
|
+
};
|
|
33966
|
+
function workspaceChatsQueryOptions({
|
|
33967
|
+
workspaceId,
|
|
33968
|
+
fetchChats,
|
|
33969
|
+
enabled = true,
|
|
33970
|
+
staleTime = 6e4
|
|
33971
|
+
}) {
|
|
33972
|
+
return queryOptions({
|
|
33973
|
+
queryKey: workspaceChatKeys.chats(workspaceId),
|
|
33974
|
+
queryFn: fetchChats,
|
|
33975
|
+
enabled: Boolean(workspaceId) && enabled,
|
|
33976
|
+
staleTime
|
|
33977
|
+
});
|
|
33978
|
+
}
|
|
33979
|
+
function upsertWorkspaceChat(chats, chat) {
|
|
33770
33980
|
const existingIndex = chats.findIndex((item) => item.id === chat.id);
|
|
33771
33981
|
if (existingIndex === -1) {
|
|
33772
33982
|
return [chat, ...chats].sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
@@ -33775,7 +33985,7 @@ function upsertChat(chats, chat) {
|
|
|
33775
33985
|
next[existingIndex] = chat;
|
|
33776
33986
|
return next.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
33777
33987
|
}
|
|
33778
|
-
function
|
|
33988
|
+
function patchWorkspaceChat(chats, chatId, patch) {
|
|
33779
33989
|
let changed = false;
|
|
33780
33990
|
const next = chats.map((chat) => {
|
|
33781
33991
|
if (chat.id !== chatId) return chat;
|
|
@@ -33784,21 +33994,229 @@ function patchChat(chats, chatId, patch) {
|
|
|
33784
33994
|
});
|
|
33785
33995
|
return changed ? next.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt)) : chats;
|
|
33786
33996
|
}
|
|
33997
|
+
function isAcceptedUserMessage(event) {
|
|
33998
|
+
return getUserMessage(event) !== null && event.payload.source === ACCEPTED_USER_MESSAGE_SOURCE;
|
|
33999
|
+
}
|
|
34000
|
+
function areDuplicateUserMessages(a, b) {
|
|
34001
|
+
if (areSameUserMessageEvents(a, b)) return true;
|
|
34002
|
+
const aMessage = getUserMessage(a);
|
|
34003
|
+
const bMessage = getUserMessage(b);
|
|
34004
|
+
if (!aMessage || aMessage !== bMessage) return false;
|
|
34005
|
+
const aAccepted = isAcceptedUserMessage(a);
|
|
34006
|
+
const bAccepted = isAcceptedUserMessage(b);
|
|
34007
|
+
return aAccepted !== bAccepted ? areUserMessagesWithinMatchWindow(
|
|
34008
|
+
{ content: aMessage, timestamp: a.timestamp },
|
|
34009
|
+
{ content: bMessage, timestamp: b.timestamp }
|
|
34010
|
+
) : false;
|
|
34011
|
+
}
|
|
34012
|
+
function areDuplicateWorkspaceChatEvents(a, b) {
|
|
34013
|
+
const aPartialStreamId = getClaudePartialMessageStreamId(a);
|
|
34014
|
+
const bPartialStreamId = getClaudePartialMessageStreamId(b);
|
|
34015
|
+
return aPartialStreamId !== null && aPartialStreamId === bPartialStreamId || JSON.stringify(a) === JSON.stringify(b) || areDuplicateUserMessages(a, b);
|
|
34016
|
+
}
|
|
34017
|
+
function mergeWorkspaceChatHistoryEvents(primary, supplemental) {
|
|
34018
|
+
return mergeAgentEvents(primary, supplemental, {
|
|
34019
|
+
areDuplicates: areDuplicateWorkspaceChatEvents,
|
|
34020
|
+
mergeEvent: (current, candidate) => getClaudePartialMessageStreamId(candidate) !== null ? candidate : current
|
|
34021
|
+
});
|
|
34022
|
+
}
|
|
34023
|
+
function isSameChatSender(a, b) {
|
|
34024
|
+
return a.senderUserId === b.senderUserId && a.recordedAt === b.recordedAt;
|
|
34025
|
+
}
|
|
34026
|
+
function codexAspTranscriptUpdateFromEvent(event) {
|
|
34027
|
+
if (event.type !== CODEX_ASP_TRANSCRIPT_UPDATED_EVENT_TYPE) return null;
|
|
34028
|
+
const { payload } = event;
|
|
34029
|
+
const updatedAt = payload.updatedAt;
|
|
34030
|
+
const transcript = payload.transcript;
|
|
34031
|
+
const transcriptDelta = payload.transcriptDelta;
|
|
34032
|
+
if (typeof updatedAt !== "string" || transcript !== null && !isCodexAspTranscript(transcript) || transcriptDelta !== void 0 && !isCodexAspTranscriptDelta(transcriptDelta)) {
|
|
34033
|
+
return null;
|
|
34034
|
+
}
|
|
34035
|
+
const threadId = typeof payload.threadId === "string" ? payload.threadId : void 0;
|
|
34036
|
+
return {
|
|
34037
|
+
updatedAt,
|
|
34038
|
+
transcript,
|
|
34039
|
+
...transcriptDelta ? { transcriptDelta } : {},
|
|
34040
|
+
...threadId ? { threadId } : {}
|
|
34041
|
+
};
|
|
34042
|
+
}
|
|
34043
|
+
function patchCachedChats(queryClient2, workspaceId, chatId, patch) {
|
|
34044
|
+
for (const queryKey of [
|
|
34045
|
+
workspaceChatKeys.chats(workspaceId),
|
|
34046
|
+
workspaceChatKeys.allChats(workspaceId)
|
|
34047
|
+
]) {
|
|
34048
|
+
queryClient2.setQueryData(
|
|
34049
|
+
queryKey,
|
|
34050
|
+
(current) => current ? {
|
|
34051
|
+
...current,
|
|
34052
|
+
chats: patchWorkspaceChat(current.chats, chatId, patch)
|
|
34053
|
+
} : current
|
|
34054
|
+
);
|
|
34055
|
+
}
|
|
34056
|
+
}
|
|
34057
|
+
function applyWorkspaceChatEvent(queryClient2, workspaceId, event, options = {}) {
|
|
34058
|
+
if (event.type === "chat.created" || event.type === "chat.updated") {
|
|
34059
|
+
const { chat } = event.payload;
|
|
34060
|
+
queryClient2.setQueryData(
|
|
34061
|
+
workspaceChatKeys.allChats(workspaceId),
|
|
34062
|
+
(current) => current ? { ...current, chats: upsertWorkspaceChat(current.chats, chat) } : current
|
|
34063
|
+
);
|
|
34064
|
+
if (chat.parentChatId === null && !options.skipRootChatUpsert) {
|
|
34065
|
+
queryClient2.setQueryData(
|
|
34066
|
+
workspaceChatKeys.chats(workspaceId),
|
|
34067
|
+
(current) => ({
|
|
34068
|
+
...current ?? {},
|
|
34069
|
+
chats: upsertWorkspaceChat(current?.chats ?? [], chat),
|
|
34070
|
+
deletedChats: (current?.deletedChats ?? []).filter((item) => item.id !== chat.id)
|
|
34071
|
+
})
|
|
34072
|
+
);
|
|
34073
|
+
}
|
|
34074
|
+
return "chat-list-changed";
|
|
34075
|
+
}
|
|
34076
|
+
if (event.type === "chat.deleted") {
|
|
34077
|
+
queryClient2.setQueryData(workspaceChatKeys.chats(workspaceId), (current) => {
|
|
34078
|
+
if (!current) return current;
|
|
34079
|
+
const deletedChat = event.payload.chat;
|
|
34080
|
+
return {
|
|
34081
|
+
...current,
|
|
34082
|
+
chats: current.chats.filter((chat) => chat.id !== event.payload.chatId),
|
|
34083
|
+
deletedChats: deletedChat?.deletedAt ? [
|
|
34084
|
+
deletedChat,
|
|
34085
|
+
...(current.deletedChats ?? []).filter((chat) => chat.id !== deletedChat.id)
|
|
34086
|
+
] : (current.deletedChats ?? []).filter((chat) => chat.id !== event.payload.chatId)
|
|
34087
|
+
};
|
|
34088
|
+
});
|
|
34089
|
+
queryClient2.setQueryData(
|
|
34090
|
+
workspaceChatKeys.allChats(workspaceId),
|
|
34091
|
+
(current) => current ? {
|
|
34092
|
+
...current,
|
|
34093
|
+
chats: current.chats.filter((chat) => chat.id !== event.payload.chatId)
|
|
34094
|
+
} : current
|
|
34095
|
+
);
|
|
34096
|
+
queryClient2.removeQueries({
|
|
34097
|
+
queryKey: workspaceChatKeys.history(workspaceId, event.payload.chatId)
|
|
34098
|
+
});
|
|
34099
|
+
return "chat-list-changed";
|
|
34100
|
+
}
|
|
34101
|
+
if (event.type === "chat.turn.accepted") {
|
|
34102
|
+
if (event.payload.queued) {
|
|
34103
|
+
queryClient2.invalidateQueries({
|
|
34104
|
+
queryKey: workspaceChatKeys.queue(workspaceId, event.payload.chatId)
|
|
34105
|
+
});
|
|
34106
|
+
return "queue-changed";
|
|
34107
|
+
}
|
|
34108
|
+
const sender = event.payload.sender;
|
|
34109
|
+
const acceptedEvent = event.payload.event;
|
|
34110
|
+
if (sender || acceptedEvent) {
|
|
34111
|
+
queryClient2.setQueryData(
|
|
34112
|
+
workspaceChatKeys.history(workspaceId, event.payload.chatId),
|
|
34113
|
+
(current) => ({
|
|
34114
|
+
...current ?? { thread_id: null },
|
|
34115
|
+
events: acceptedEvent ? mergeWorkspaceChatHistoryEvents(current?.events ?? [], [acceptedEvent]) : current?.events ?? [],
|
|
34116
|
+
senders: sender ? [
|
|
34117
|
+
...(current?.senders ?? []).filter(
|
|
34118
|
+
(candidate) => !isSameChatSender(candidate, sender)
|
|
34119
|
+
),
|
|
34120
|
+
sender
|
|
34121
|
+
] : current?.senders
|
|
34122
|
+
})
|
|
34123
|
+
);
|
|
34124
|
+
}
|
|
34125
|
+
patchCachedChats(queryClient2, workspaceId, event.payload.chatId, {
|
|
34126
|
+
processing: true,
|
|
34127
|
+
awaitingInput: false,
|
|
34128
|
+
updatedAt: event.ts
|
|
34129
|
+
});
|
|
34130
|
+
return "chat-list-changed";
|
|
34131
|
+
}
|
|
34132
|
+
if (event.type === "chat.turn.started") {
|
|
34133
|
+
queryClient2.setQueryData(
|
|
34134
|
+
workspaceChatKeys.queue(workspaceId, event.payload.chatId),
|
|
34135
|
+
(current) => current ? {
|
|
34136
|
+
...current,
|
|
34137
|
+
queue: current.queue.filter((message) => message.id !== event.payload.messageId)
|
|
34138
|
+
} : current
|
|
34139
|
+
);
|
|
34140
|
+
queryClient2.invalidateQueries({
|
|
34141
|
+
queryKey: workspaceChatKeys.queue(workspaceId, event.payload.chatId)
|
|
34142
|
+
});
|
|
34143
|
+
patchCachedChats(queryClient2, workspaceId, event.payload.chatId, {
|
|
34144
|
+
processing: true,
|
|
34145
|
+
awaitingInput: false,
|
|
34146
|
+
updatedAt: event.ts
|
|
34147
|
+
});
|
|
34148
|
+
const history = queryClient2.getQueryData(
|
|
34149
|
+
workspaceChatKeys.history(workspaceId, event.payload.chatId)
|
|
34150
|
+
);
|
|
34151
|
+
if (!history?.events.some((candidate) => getUserMessageId(candidate) === event.payload.messageId)) {
|
|
34152
|
+
queryClient2.invalidateQueries({
|
|
34153
|
+
queryKey: workspaceChatKeys.history(workspaceId, event.payload.chatId)
|
|
34154
|
+
});
|
|
34155
|
+
}
|
|
34156
|
+
return "chat-list-changed";
|
|
34157
|
+
}
|
|
34158
|
+
if (event.type === "chat.turn.delta") {
|
|
34159
|
+
const historyKey = workspaceChatKeys.history(workspaceId, event.payload.chatId);
|
|
34160
|
+
const transcriptUpdate = codexAspTranscriptUpdateFromEvent(event.payload.event);
|
|
34161
|
+
if (transcriptUpdate) {
|
|
34162
|
+
queryClient2.setQueryData(historyKey, (current) => {
|
|
34163
|
+
const transcript = transcriptUpdate.transcriptDelta ? applyCodexAspTranscriptDelta(
|
|
34164
|
+
current?.codexAspTranscript ?? transcriptUpdate.transcript ?? null,
|
|
34165
|
+
transcriptUpdate.transcriptDelta
|
|
34166
|
+
) : transcriptUpdate.transcript ?? current?.codexAspTranscript ?? null;
|
|
34167
|
+
return {
|
|
34168
|
+
...current ?? { events: [] },
|
|
34169
|
+
thread_id: current?.thread_id ?? transcript?.threadId ?? transcriptUpdate.threadId ?? null,
|
|
34170
|
+
codexAspTranscript: transcript
|
|
34171
|
+
};
|
|
34172
|
+
});
|
|
34173
|
+
return "turn-delta";
|
|
34174
|
+
}
|
|
34175
|
+
queryClient2.setQueryData(historyKey, (current) => ({
|
|
34176
|
+
...current ?? { thread_id: null },
|
|
34177
|
+
events: mergeWorkspaceChatHistoryEvents(current?.events ?? [], [event.payload.event]),
|
|
34178
|
+
goal: event.payload.event.type === CHAT_GOAL_EVENT_TYPE ? coerceChatGoalPayload(event.payload.event.payload) : current?.goal
|
|
34179
|
+
}));
|
|
34180
|
+
return "turn-delta";
|
|
34181
|
+
}
|
|
34182
|
+
if (event.type === "chat.turn.completed" || event.type === "chat.interrupted") {
|
|
34183
|
+
patchCachedChats(queryClient2, workspaceId, event.payload.chatId, {
|
|
34184
|
+
processing: getTerminalChatProcessing(event),
|
|
34185
|
+
awaitingInput: false,
|
|
34186
|
+
isAuthRetrying: false,
|
|
34187
|
+
updatedAt: event.ts
|
|
34188
|
+
});
|
|
34189
|
+
queryClient2.invalidateQueries({
|
|
34190
|
+
queryKey: workspaceChatKeys.history(workspaceId, event.payload.chatId)
|
|
34191
|
+
});
|
|
34192
|
+
queryClient2.invalidateQueries({
|
|
34193
|
+
queryKey: workspaceChatKeys.queue(workspaceId, event.payload.chatId)
|
|
34194
|
+
});
|
|
34195
|
+
queryClient2.invalidateQueries({
|
|
34196
|
+
queryKey: workspaceChatKeys.allChats(workspaceId)
|
|
34197
|
+
});
|
|
34198
|
+
return "turn-completed";
|
|
34199
|
+
}
|
|
34200
|
+
return null;
|
|
34201
|
+
}
|
|
34202
|
+
|
|
34203
|
+
// ../shared/src/hooks/useWorkspaceEngine.ts
|
|
33787
34204
|
function useWorkspaceChats(workspaceId) {
|
|
33788
34205
|
const auth = useReplicasAuth();
|
|
33789
34206
|
const orgFetch = useOrgFetch();
|
|
33790
|
-
return useQuery2(
|
|
33791
|
-
|
|
33792
|
-
|
|
33793
|
-
|
|
33794
|
-
|
|
33795
|
-
|
|
34207
|
+
return useQuery2(
|
|
34208
|
+
workspaceChatsQueryOptions({
|
|
34209
|
+
workspaceId,
|
|
34210
|
+
fetchChats: () => orgFetch(`/v1/workspaces/${workspaceId}/chats`)
|
|
34211
|
+
}),
|
|
34212
|
+
auth.queryClient
|
|
34213
|
+
);
|
|
33796
34214
|
}
|
|
33797
34215
|
function useChatHistory(workspaceId, chatId) {
|
|
33798
34216
|
const auth = useReplicasAuth();
|
|
33799
34217
|
const orgFetch = useOrgFetch();
|
|
33800
34218
|
return useQuery2({
|
|
33801
|
-
queryKey:
|
|
34219
|
+
queryKey: workspaceChatKeys.history(workspaceId, chatId),
|
|
33802
34220
|
queryFn: () => orgFetch(`/v1/workspaces/${workspaceId}/chats/${chatId}/history`),
|
|
33803
34221
|
enabled: !!workspaceId && !!chatId
|
|
33804
34222
|
}, auth.queryClient);
|
|
@@ -33875,67 +34293,7 @@ function useWorkspaceEvents(workspaceId, enabled = true) {
|
|
|
33875
34293
|
const qc = auth.queryClient;
|
|
33876
34294
|
const handleEvent = useCallback4((event) => {
|
|
33877
34295
|
if (!workspaceId) return;
|
|
33878
|
-
|
|
33879
|
-
if (event.type === "chat.created" || event.type === "chat.updated") {
|
|
33880
|
-
if (event.payload.chat.parentChatId === null) {
|
|
33881
|
-
qc.setQueryData(chatsKey, (current) => {
|
|
33882
|
-
if (!current) return { chats: [event.payload.chat] };
|
|
33883
|
-
return { chats: upsertChat(current.chats, event.payload.chat) };
|
|
33884
|
-
});
|
|
33885
|
-
}
|
|
33886
|
-
return;
|
|
33887
|
-
}
|
|
33888
|
-
if (event.type === "chat.deleted") {
|
|
33889
|
-
qc.setQueryData(chatsKey, (current) => {
|
|
33890
|
-
if (!current) return current;
|
|
33891
|
-
return { chats: current.chats.filter((chat) => chat.id !== event.payload.chatId) };
|
|
33892
|
-
});
|
|
33893
|
-
qc.removeQueries({ queryKey: ["chat-history", workspaceId, event.payload.chatId] });
|
|
33894
|
-
return;
|
|
33895
|
-
}
|
|
33896
|
-
if (event.type === "chat.turn.accepted") {
|
|
33897
|
-
if (!event.payload.queued) {
|
|
33898
|
-
qc.setQueryData(chatsKey, (current) => {
|
|
33899
|
-
if (!current) return current;
|
|
33900
|
-
return { chats: patchChat(current.chats, event.payload.chatId, { processing: true, updatedAt: event.ts }) };
|
|
33901
|
-
});
|
|
33902
|
-
}
|
|
33903
|
-
return;
|
|
33904
|
-
}
|
|
33905
|
-
if (event.type === "chat.turn.started") {
|
|
33906
|
-
qc.setQueryData(chatsKey, (current) => {
|
|
33907
|
-
if (!current) return current;
|
|
33908
|
-
return { chats: patchChat(current.chats, event.payload.chatId, { processing: true, updatedAt: event.ts }) };
|
|
33909
|
-
});
|
|
33910
|
-
return;
|
|
33911
|
-
}
|
|
33912
|
-
if (event.type === "chat.turn.completed" || event.type === "chat.interrupted") {
|
|
33913
|
-
qc.setQueryData(chatsKey, (current) => {
|
|
33914
|
-
if (!current) return current;
|
|
33915
|
-
return { chats: patchChat(current.chats, event.payload.chatId, { processing: getTerminalChatProcessing(event), updatedAt: event.ts }) };
|
|
33916
|
-
});
|
|
33917
|
-
qc.invalidateQueries({ queryKey: ["chat-history", workspaceId, event.payload.chatId] });
|
|
33918
|
-
return;
|
|
33919
|
-
}
|
|
33920
|
-
if (event.type === "chat.turn.delta") {
|
|
33921
|
-
qc.setQueryData(
|
|
33922
|
-
["chat-history", workspaceId, event.payload.chatId],
|
|
33923
|
-
(current) => {
|
|
33924
|
-
const incomingSignature = getEventSignature(event.payload.event);
|
|
33925
|
-
if (!current) {
|
|
33926
|
-
return { thread_id: null, events: [event.payload.event] };
|
|
33927
|
-
}
|
|
33928
|
-
const existingIndex = current.events.findIndex((e) => getEventSignature(e) === incomingSignature);
|
|
33929
|
-
if (existingIndex !== -1) {
|
|
33930
|
-
const events = current.events.slice();
|
|
33931
|
-
events[existingIndex] = event.payload.event;
|
|
33932
|
-
return { ...current, events };
|
|
33933
|
-
}
|
|
33934
|
-
return { ...current, events: [...current.events, event.payload.event] };
|
|
33935
|
-
}
|
|
33936
|
-
);
|
|
33937
|
-
return;
|
|
33938
|
-
}
|
|
34296
|
+
if (applyWorkspaceChatEvent(qc, workspaceId, event)) return;
|
|
33939
34297
|
if (event.type === "repo.status.changed") {
|
|
33940
34298
|
qc.setQueryData(["workspace-status", workspaceId, false], (current) => {
|
|
33941
34299
|
if (!current) return current;
|