@invergent/agent-chat-react 2.18.0 → 2.18.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/dist/index.cjs +74 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +75 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -13851,7 +13851,8 @@ var WORKSPACE_MUTATING_TOOLS = /* @__PURE__ */ new Set([
|
|
|
13851
13851
|
"write_file",
|
|
13852
13852
|
"patch",
|
|
13853
13853
|
"execute_code",
|
|
13854
|
-
"browser_screenshot"
|
|
13854
|
+
"browser_screenshot",
|
|
13855
|
+
"office_edit"
|
|
13855
13856
|
]);
|
|
13856
13857
|
var AGENT_CHAT_LISTENED_EVENTS = [
|
|
13857
13858
|
"user.message",
|
|
@@ -13901,7 +13902,8 @@ var AGENT_CHAT_LISTENED_EVENTS = [
|
|
|
13901
13902
|
"worker.failed",
|
|
13902
13903
|
"thread.proposed",
|
|
13903
13904
|
"office.conflict",
|
|
13904
|
-
"office.save_failed"
|
|
13905
|
+
"office.save_failed",
|
|
13906
|
+
"stream.live"
|
|
13905
13907
|
];
|
|
13906
13908
|
var AGENT_CHAT_LISTENED_EVENT_SET = new Set(
|
|
13907
13909
|
AGENT_CHAT_LISTENED_EVENTS
|
|
@@ -14147,7 +14149,9 @@ function createInitialAgentChatState(options = {}) {
|
|
|
14147
14149
|
viewMode: options.viewMode ?? "simple",
|
|
14148
14150
|
researchSources: [],
|
|
14149
14151
|
deviceWait: null,
|
|
14150
|
-
officeEvents: {}
|
|
14152
|
+
officeEvents: {},
|
|
14153
|
+
live: false,
|
|
14154
|
+
officeAutoOpen: null
|
|
14151
14155
|
};
|
|
14152
14156
|
}
|
|
14153
14157
|
function applyAgentChatEvent(state, event) {
|
|
@@ -14165,6 +14169,9 @@ function applyAgentChatEvent(state, event) {
|
|
|
14165
14169
|
case "user.message":
|
|
14166
14170
|
// A project coordinator's follow-up to its thread: shown as the thread reads it, its header saying whose it is.
|
|
14167
14171
|
case "coordinator.message":
|
|
14172
|
+
if (event.type === "user.message" && PLATFORM_NOTES.has(stringValue2(event.data.synthetic))) {
|
|
14173
|
+
return nextState;
|
|
14174
|
+
}
|
|
14168
14175
|
return withMessages(
|
|
14169
14176
|
{ ...nextState, terminal: false, stopped: false, isRunning: true },
|
|
14170
14177
|
applyUserMessage(nextState.messages, event.eventId, event.data)
|
|
@@ -14335,17 +14342,22 @@ function applyAgentChatEvent(state, event) {
|
|
|
14335
14342
|
return applyLlmResponse(nextState, event);
|
|
14336
14343
|
case "llm.thinking":
|
|
14337
14344
|
return applyLlmThinking(nextState, event);
|
|
14345
|
+
case "stream.live":
|
|
14346
|
+
return { ...nextState, live: true };
|
|
14338
14347
|
case "tool.call":
|
|
14339
14348
|
return applyToolCall(nextState, event);
|
|
14340
14349
|
case "tool.result": {
|
|
14341
14350
|
const toolCallId = stringValue2(event.data.tool_call_id);
|
|
14342
|
-
const toolName = findToolNameById(nextState.messages, toolCallId);
|
|
14343
14351
|
const messages = applyToolResult(nextState.messages, event.data);
|
|
14352
|
+
const call = findToolCallById(messages, toolCallId);
|
|
14353
|
+
const toolName = call?.toolName ?? null;
|
|
14344
14354
|
const mutatesWorkspace = toolName !== null && WORKSPACE_MUTATING_TOOLS.has(toolName);
|
|
14355
|
+
const officePath = nextState.live && call?.toolName === "office_edit" && !toolCallFailed(call) ? officeEditPath(call.args) : null;
|
|
14345
14356
|
const withResult = {
|
|
14346
14357
|
...nextState,
|
|
14347
14358
|
messages,
|
|
14348
|
-
workspaceRefreshKey: mutatesWorkspace ? nextState.workspaceRefreshKey + 1 : nextState.workspaceRefreshKey
|
|
14359
|
+
workspaceRefreshKey: mutatesWorkspace ? nextState.workspaceRefreshKey + 1 : nextState.workspaceRefreshKey,
|
|
14360
|
+
officeAutoOpen: officePath ? { path: officePath, eventId: event.eventId } : nextState.officeAutoOpen
|
|
14349
14361
|
};
|
|
14350
14362
|
return collectResearchSource(withResult, toolName, event.data);
|
|
14351
14363
|
}
|
|
@@ -14482,6 +14494,7 @@ function typedBehindTheClear(messages, answers) {
|
|
|
14482
14494
|
}
|
|
14483
14495
|
return messages.slice(first);
|
|
14484
14496
|
}
|
|
14497
|
+
var PLATFORM_NOTES = /* @__PURE__ */ new Set(["checkin", "checkin_opener", "outreach_opener"]);
|
|
14485
14498
|
function applyUserMessage(messages, eventId, data) {
|
|
14486
14499
|
const content = stringValue2(data.content);
|
|
14487
14500
|
const images = parseUserMessageImages(data.images);
|
|
@@ -14547,6 +14560,22 @@ function parseUserMessageAttachments(raw) {
|
|
|
14547
14560
|
}
|
|
14548
14561
|
return out.length > 0 ? out : void 0;
|
|
14549
14562
|
}
|
|
14563
|
+
function officeEditPath(args) {
|
|
14564
|
+
try {
|
|
14565
|
+
const path = JSON.parse(args)?.path;
|
|
14566
|
+
return typeof path === "string" ? path.replace(/^__WORKSPACE__\//, "") || null : null;
|
|
14567
|
+
} catch {
|
|
14568
|
+
return null;
|
|
14569
|
+
}
|
|
14570
|
+
}
|
|
14571
|
+
function toolCallFailed(call) {
|
|
14572
|
+
if (call.status === "error") return true;
|
|
14573
|
+
try {
|
|
14574
|
+
return JSON.parse(call.result ?? "")?.error != null;
|
|
14575
|
+
} catch {
|
|
14576
|
+
return false;
|
|
14577
|
+
}
|
|
14578
|
+
}
|
|
14550
14579
|
function onComputer(event) {
|
|
14551
14580
|
return event.data.computer === true ? { computer: true } : {};
|
|
14552
14581
|
}
|
|
@@ -15401,11 +15430,11 @@ function hasUserAfterIndex(messages, idx) {
|
|
|
15401
15430
|
}
|
|
15402
15431
|
return false;
|
|
15403
15432
|
}
|
|
15404
|
-
function
|
|
15433
|
+
function findToolCallById(messages, toolCallId) {
|
|
15405
15434
|
if (!toolCallId) return null;
|
|
15406
15435
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
15407
15436
|
const tc = messages[i]?.toolCalls?.find((c) => c.id === toolCallId);
|
|
15408
|
-
if (tc) return tc
|
|
15437
|
+
if (tc) return tc;
|
|
15409
15438
|
}
|
|
15410
15439
|
return null;
|
|
15411
15440
|
}
|
|
@@ -15586,7 +15615,7 @@ function useAgentChatRuntime({
|
|
|
15586
15615
|
stream.addEventListener(eventType, (messageEvent) => {
|
|
15587
15616
|
if (streamRef.current !== stream) return;
|
|
15588
15617
|
const data = parseEventData(messageEvent.data);
|
|
15589
|
-
const eventId = messageEvent.lastEventId ? Number(messageEvent.lastEventId) : 0;
|
|
15618
|
+
const eventId = eventType === "stream.live" ? 0 : messageEvent.lastEventId ? Number(messageEvent.lastEventId) : 0;
|
|
15590
15619
|
setState(
|
|
15591
15620
|
(prev) => applyRuntimeEvent(prev, {
|
|
15592
15621
|
type: eventType,
|
|
@@ -19535,6 +19564,13 @@ function OfficeEditorPane({ adapter, sessionId, path, view, officeEvent, onClose
|
|
|
19535
19564
|
const notice = officeEvent && officeEvent.eventId > openedAfter ? officeEvent : null;
|
|
19536
19565
|
const [reopenedFor, setReopenedFor] = react.useState(0);
|
|
19537
19566
|
if (notice?.type === "office.conflict" && notice.eventId !== reopenedFor) setReopenedFor(notice.eventId);
|
|
19567
|
+
const paneRef = react.useRef(null);
|
|
19568
|
+
const [fullScreen, setFullScreen] = react.useState(false);
|
|
19569
|
+
react.useEffect(() => {
|
|
19570
|
+
const follow = () => setFullScreen(document.fullscreenElement === paneRef.current);
|
|
19571
|
+
document.addEventListener("fullscreenchange", follow);
|
|
19572
|
+
return () => document.removeEventListener("fullscreenchange", follow);
|
|
19573
|
+
}, []);
|
|
19538
19574
|
react.useEffect(() => {
|
|
19539
19575
|
let cancelled = false;
|
|
19540
19576
|
let editor = null;
|
|
@@ -19563,6 +19599,7 @@ function OfficeEditorPane({ adapter, sessionId, path, view, officeEvent, onClose
|
|
|
19563
19599
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
19564
19600
|
"aside",
|
|
19565
19601
|
{
|
|
19602
|
+
ref: paneRef,
|
|
19566
19603
|
"data-testid": "file-preview-panel",
|
|
19567
19604
|
className: "flex h-full min-h-0 w-full flex-col overflow-hidden border-l border-line bg-card",
|
|
19568
19605
|
children: [
|
|
@@ -19580,6 +19617,17 @@ function OfficeEditorPane({ adapter, sessionId, path, view, officeEvent, onClose
|
|
|
19580
19617
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.DownloadIcon, { className: "size-4" })
|
|
19581
19618
|
}
|
|
19582
19619
|
),
|
|
19620
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
19621
|
+
"button",
|
|
19622
|
+
{
|
|
19623
|
+
type: "button",
|
|
19624
|
+
onClick: () => void (fullScreen ? document.exitFullscreen() : paneRef.current?.requestFullscreen()),
|
|
19625
|
+
"aria-label": fullScreen ? "Exit full screen" : "Full screen",
|
|
19626
|
+
title: fullScreen ? "Exit full screen" : "Full screen",
|
|
19627
|
+
className: "shrink-0 rounded p-0.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
19628
|
+
children: fullScreen ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Minimize2Icon, { className: "size-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Maximize2Icon, { className: "size-4" })
|
|
19629
|
+
}
|
|
19630
|
+
),
|
|
19583
19631
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
19584
19632
|
"button",
|
|
19585
19633
|
{
|
|
@@ -20351,10 +20399,16 @@ function isSubAgentSession(session) {
|
|
|
20351
20399
|
if (session.channel && _SUB_AGENT_CHANNELS.has(session.channel)) return true;
|
|
20352
20400
|
return false;
|
|
20353
20401
|
}
|
|
20402
|
+
function isProjectThread(session) {
|
|
20403
|
+
return session?.config?.workstream_role === "thread";
|
|
20404
|
+
}
|
|
20354
20405
|
function readOnlyReasonForSession(session) {
|
|
20355
20406
|
if (isScheduledRunSession(session)) {
|
|
20356
20407
|
return { readOnly: true, reason: "Scheduled run is read-only" };
|
|
20357
20408
|
}
|
|
20409
|
+
if (isProjectThread(session)) {
|
|
20410
|
+
return { readOnly: false };
|
|
20411
|
+
}
|
|
20358
20412
|
if (isSubAgentSession(session)) {
|
|
20359
20413
|
return {
|
|
20360
20414
|
readOnly: true,
|
|
@@ -20424,11 +20478,13 @@ function AgentChat({
|
|
|
20424
20478
|
setOpenPane(null);
|
|
20425
20479
|
setFilesOpen(false);
|
|
20426
20480
|
}, [runtime.viewMode]);
|
|
20481
|
+
const officeAutoOpened = react.useRef(/* @__PURE__ */ new Set());
|
|
20427
20482
|
react.useEffect(() => {
|
|
20428
20483
|
setFilesOpen(false);
|
|
20429
20484
|
setWorkspacePath(null);
|
|
20430
20485
|
setPreviewPath(null);
|
|
20431
20486
|
setOpenPane(null);
|
|
20487
|
+
officeAutoOpened.current.clear();
|
|
20432
20488
|
}, [sessionId]);
|
|
20433
20489
|
const readOnly = readOnlyReasonForSession(runtime.session);
|
|
20434
20490
|
const boardAvailable = whiteboardEnabled && isBoardSession(runtime.session);
|
|
@@ -20511,6 +20567,16 @@ function AgentChat({
|
|
|
20511
20567
|
setOpenPane("file");
|
|
20512
20568
|
setMobileView("file");
|
|
20513
20569
|
}, []);
|
|
20570
|
+
const officeAutoOpen = runtime.state.officeAutoOpen;
|
|
20571
|
+
react.useEffect(() => {
|
|
20572
|
+
if (!officeAutoOpen || !isOfficeDocument(officeAutoOpen.path)) return;
|
|
20573
|
+
if (openPane === "file" && previewPath !== null && previewPath !== officeAutoOpen.path) return;
|
|
20574
|
+
if (officeAutoOpened.current.has(officeAutoOpen.path)) return;
|
|
20575
|
+
officeAutoOpened.current.add(officeAutoOpen.path);
|
|
20576
|
+
setWorkspacePath(officeAutoOpen.path);
|
|
20577
|
+
setPreviewPath(officeAutoOpen.path);
|
|
20578
|
+
setOpenPane("file");
|
|
20579
|
+
}, [officeAutoOpen?.eventId]);
|
|
20514
20580
|
const handleSelectedPathChange = react.useCallback((path) => {
|
|
20515
20581
|
setWorkspacePath(path);
|
|
20516
20582
|
if (path === null) setPreviewPath(null);
|