the lists re-read when the agent changes something
an agent deleted two proxy hosts and both stayed on screen. the person had the answer in the transcript and a stale list six inches above it — which is the one thing a chat beside a list has to get right, and the reason it is beside the list at all. so the chat panel bumps the refresh channel when a turn ran tools, and every section re-reads. gated on hadToolCalls: a turn that only talked changed nothing, and re-reading after every sentence would put six requests behind every reply. the channel is renamed with it. it was proxy-manager:connection-changed, named after its only publisher; it has two now and the second is the bigger one, so it says what it MEANS — something at NPM changed, read it again. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Officer-Session: 656f5c85-e49a-4f1f-b9f3-042a04b4d043
This commit is contained in:
+28
-5
@@ -1,4 +1,6 @@
|
||||
import { useCallback } from 'react';
|
||||
import { ChatPanelWrapper, ChatHeader } from 'officerdev';
|
||||
import { useNpmChanged } from './channel';
|
||||
|
||||
/**
|
||||
* A chat, sitting under the two lists.
|
||||
@@ -37,11 +39,32 @@ const CHAT_CONTEXT = { context: 'plugin', contextId: 'proxy-manager' } as const;
|
||||
* behaviour. Mounting the composer directly meant reimplementing all of that or going without it, which is
|
||||
* what this panel was doing.
|
||||
*/
|
||||
export const ChatPanel = ({ panelId }: { panelId: string }) => (
|
||||
<div className="flex h-full min-h-0 flex-col">
|
||||
<ChatPanelWrapper panelId={panelId} chatContext={CHAT_CONTEXT} />
|
||||
</div>
|
||||
);
|
||||
export const ChatPanel = ({ panelId }: { panelId: string }) => {
|
||||
const [, npmChanged] = useNpmChanged();
|
||||
|
||||
/**
|
||||
* A turn that ran tools may have changed NPM, so every list on this screen re-reads.
|
||||
*
|
||||
* This is the whole reason the panel is worth having beside the lists rather than in `/chat`. An agent
|
||||
* deleted two proxy hosts on 2026-08-25 and both stayed on screen afterwards, because nothing told the
|
||||
* panels — the person had the answer in the transcript and a stale list six inches above it.
|
||||
*
|
||||
* Gated on `hadToolCalls`, which is the only discrimination that matters: a turn that only talked
|
||||
* changed nothing, and re-reading after every sentence would put six requests behind every reply.
|
||||
*/
|
||||
const onTurnComplete = useCallback(
|
||||
(hadToolCalls: boolean) => {
|
||||
if (hadToolCalls) npmChanged();
|
||||
},
|
||||
[npmChanged],
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="flex h-full min-h-0 flex-col">
|
||||
<ChatPanelWrapper panelId={panelId} chatContext={CHAT_CONTEXT} onTurnComplete={onTurnComplete} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* The panel's header: the conversation picker, scoped to this plugin's directory.
|
||||
|
||||
Reference in New Issue
Block a user