openWrittenDocument.test.ts4.3 KBView on GitHub /**
* The one rule for a document the agent just wrote: show it if the panel is IDLE, never if the
* user already has something open there.
*
* These are mostly negative tests, and deliberately so. The behaviour this replaced was a
* `display-document` tool the agent called by hand, which took the panel whenever it fired —
* so the thing worth pinning is not that a doc can open, it is that a doc opening cannot take
* away what the user was reading.
*/
import { openWrittenDocumentIfPanelIdle } from '@/modules/cedar-os/src/store/agentConnection/responseProcessors/openWrittenDocument';
import { DEFAULT_THREAD_ID } from '@/store/messages/MessageTypes';
import { useCedarStore } from '@/store/CedarStore';
const T1 = DEFAULT_THREAD_ID;
const T2 = 'thread-2';
function seed() {
useCedarStore.setState((state) => ({
...state,
threadMap: {
[T1]: { id: T1, messages: [], selectedArtifact: null },
[T2]: { id: T2, messages: [], selectedArtifact: null },
},
mainThreadId: T1,
activeThreadId: T1,
messages: [],
conversationOpenFile: null,
}));
}
const store = () => useCedarStore.getState();
describe('a written document opens only into an idle panel', () => {
beforeEach(seed);
it('opens a standalone doc when nothing is open', () => {
openWrittenDocumentIfPanelIdle(store(), {
documentId: 'doc_1',
path: 'thread/thread-1/decagon-research',
threadId: T1,
});
expect(store().getDisplayArtifact()).toEqual({ kind: 'file', id: 'doc_1' });
});
it('leaves an open conversation alone — the chip is how the user gets to the doc', () => {
store().setSelectedArtifact({ kind: 'conversation', id: 'conv_a' });
openWrittenDocumentIfPanelIdle(store(), {
documentId: 'doc_1',
path: 'thread/thread-1/decagon-research',
threadId: T1,
});
expect(store().getDisplayArtifact()).toEqual({ kind: 'conversation', id: 'conv_a' });
});
it('leaves an open document alone too — a second write must not swap what is on screen', () => {
store().setSelectedArtifact({ kind: 'file', id: 'doc_already_open' });
openWrittenDocumentIfPanelIdle(store(), {
documentId: 'doc_2',
path: 'user/notes/scratch',
threadId: T1,
});
expect(store().getDisplayArtifact()).toEqual({ kind: 'file', id: 'doc_already_open' });
});
it('a conversation-scoped doc opens inside its conversation, not as a bare file', () => {
openWrittenDocumentIfPanelIdle(store(), {
documentId: 'doc_3',
path: 'conversation/conv_x/research/pricing',
threadId: T1,
});
expect(store().activeConversationId).toBe('conv_x');
expect(store().conversationOpenFile).toBe('doc_3');
});
it('ignores a buffer doc — a tool-output dump is not a deliverable', () => {
openWrittenDocumentIfPanelIdle(store(), {
documentId: 'doc_4',
path: 'thread/thread-1/buffer/web-search',
threadId: T1,
});
expect(store().getDisplayArtifact()).toBeNull();
});
it('a background thread cannot redraw the panel in front of the user', () => {
// T2 is idle, but T1 is the chat being looked at and it has a conversation open.
store().setSelectedArtifact({ kind: 'conversation', id: 'conv_a' });
openWrittenDocumentIfPanelIdle(store(), {
documentId: 'doc_5',
path: 'user/notes/other',
threadId: T1,
});
expect(store().getDisplayArtifact()).toEqual({ kind: 'conversation', id: 'conv_a' });
});
it("a background thread cannot fill the active thread's IDLE panel either", () => {
// The case the check above misses: nothing is open, so "is the panel free" says yes — but
// the write came from T2, and `setSelectedArtifact` writes the ACTIVE thread's slot, so
// T2's document would land in front of a user who is reading T1.
openWrittenDocumentIfPanelIdle(store(), {
documentId: 'doc_6',
path: 'user/notes/background',
threadId: T2,
});
expect(store().getDisplayArtifact()).toBeNull();
});
it('a conversation-scoped write from a background thread does not move the user either', () => {
openWrittenDocumentIfPanelIdle(store(), {
documentId: 'doc_7',
path: 'conversation/conv_y/research/pricing',
threadId: T2,
});
expect(store().activeConversationId).not.toBe('conv_y');
expect(store().conversationOpenFile).toBeNull();
});
});