Skip to content

Commit c83f09b

Browse files
committed
ai should use main chat, not side chat; also misc improvements
1 parent 6aa5e4f commit c83f09b

File tree

9 files changed

+69
-21
lines changed

9 files changed

+69
-21
lines changed

src/packages/frontend/chat/actions.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -486,8 +486,17 @@ export class ChatActions extends Actions<ChatState> {
486486
scrollToBottom = (index: number = -1) => {
487487
if (this.syncdb == null) return;
488488
// this triggers scroll behavior in the chat-log component.
489-
this.setState({ scrollToBottom: null }); // no-op, but necessary to trigger a change
490-
this.setState({ scrollToBottom: index });
489+
// no-op, but necessary to trigger a change
490+
this.frameTreeActions.set_frame_data({
491+
id: this.frameId,
492+
scrollToBottom: null,
493+
});
494+
setTimeout(() => {
495+
this.frameTreeActions.set_frame_data({
496+
id: this.frameId,
497+
scrollToBottom: index,
498+
});
499+
}, 1);
491500
};
492501

493502
set_uploading = (is_uploading: boolean): void => {
@@ -796,13 +805,13 @@ export class ChatActions extends Actions<ChatState> {
796805
}
797806
}
798807

799-
// FIXME: these scrollToBottoms are a good idea, but they need an index number – not the date/timestamp
800-
// this.scrollToBottom(reply_to?.valueOf());
801808
let content: string = "";
802809
let halted = false;
803810

804811
chatStream.on("token", (token) => {
805-
if (halted || this.syncdb == null) return;
812+
if (halted || this.syncdb == null) {
813+
return;
814+
}
806815

807816
// we check if user clicked on the "stop generating" button
808817
const cur = this.syncdb.get_one({ event: "chat", date });
@@ -834,7 +843,6 @@ export class ChatActions extends Actions<ChatState> {
834843
if (token == null) {
835844
this.chatStreams.delete(id);
836845
this.syncdb.commit();
837-
// this.scrollToBottom(reply_to?.valueOf());
838846
}
839847
});
840848

@@ -864,7 +872,6 @@ export class ChatActions extends Actions<ChatState> {
864872
};
865873
this.syncdb.set(msg);
866874
this.syncdb.commit();
867-
// this.scrollToBottom(reply_to?.valueOf());
868875
});
869876
};
870877

src/packages/frontend/chat/chat-log.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ interface Props {
4343
filterRecentH?;
4444
selectedHashtags;
4545
disableFilters?: boolean;
46+
scrollToBottom?: null | number | undefined;
4647
}
4748

4849
export function ChatLog({
@@ -57,9 +58,9 @@ export function ChatLog({
5758
filterRecentH,
5859
selectedHashtags: selectedHashtags0,
5960
disableFilters,
61+
scrollToBottom,
6062
}: Props) {
6163
const messages = useRedux(["messages"], project_id, path) as ChatMessages;
62-
const scrollToBottom = useRedux(["scrollToBottom"], project_id, path);
6364
const llm_cost_reply: [number, number] = useRedux(
6465
["llm_cost_reply"],
6566
project_id,

src/packages/frontend/chat/chatroom.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ export function ChatRoom({
9090
const search = desc.get("data-search") ?? "";
9191
const filterRecentH: number = desc.get("data-filterRecentH") ?? 0;
9292
const selectedHashtags = desc.get("data-selectedHashtags");
93+
const scrollToBottom = desc.get("data-scrollToBottom") ?? null;
9394

9495
const messages = useEditor("messages");
9596
const [filterRecentHCustom, setFilterRecentHCustom] = useState<string>("");
@@ -331,6 +332,7 @@ export function ChatRoom({
331332
search={search}
332333
filterRecentH={filterRecentH}
333334
selectedHashtags={selectedHashtags}
335+
scrollToBottom={scrollToBottom}
334336
/>
335337
{render_preview_message()}
336338
</div>

src/packages/frontend/chat/get-actions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export default async function getChatActions(
1414
width: number = 0.7
1515
): Promise<ChatActions> {
1616
const projectActions = redux.getProjectActions(project_id);
17-
projectActions.open_chat({ path: path, width });
17+
projectActions.open_chat({ path, width });
1818
const start = Date.now();
1919

2020
while (Date.now() - start <= 1000 * maxWaitSeconds) {

src/packages/frontend/chat/side-chat.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export default function SideChat({
4848
const input: string = useRedux(["input"], project_id, path);
4949
const search = desc?.get("data-search") ?? "";
5050
const selectedHashtags = desc?.get("data-selectedHashtags");
51+
const scrollToBottom = desc.get("data-scrollToBottom") ?? null;
5152
const addCollab: boolean = useRedux(["add_collab"], project_id, path);
5253
const is_uploading = useRedux(["is_uploading"], project_id, path);
5354
const project_map = useTypedRedux("projects", "project_map");
@@ -188,6 +189,7 @@ export default function SideChat({
188189
search={search}
189190
selectedHashtags={selectedHashtags}
190191
disableFilters={disableFilters}
192+
scrollToBottom={scrollToBottom}
191193
/>
192194
</div>
193195

src/packages/frontend/editors/markdown-input/component.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,13 @@ import "@cocalc/frontend/codemirror/init";
4848

4949
export const BLURED_STYLE: CSSProperties = {
5050
border: "1px solid rgb(204,204,204)", // focused will be rgb(112, 178, 230);
51+
borderRadius: "5px",
5152
} as const;
5253

5354
export const FOCUSED_STYLE: CSSProperties = {
5455
outline: "none !important",
5556
boxShadow: "0px 0px 5px #719ECE",
57+
borderRadius: "5px",
5658
border: "1px solid #719ECE",
5759
} as const;
5860

src/packages/frontend/frame-editors/chat-editor/actions.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import { handleSyncDBChange, initFromSyncDB } from "@cocalc/frontend/chat/sync";
2222
import { redux_name } from "@cocalc/frontend/app-framework";
2323
import { aux_file } from "@cocalc/util/misc";
2424

25+
const FRAME_TYPE = "chatroom";
26+
2527
type ChatEditorState = CodeEditorState & ChatState;
2628

2729
export class Actions extends CodeEditorActions<ChatEditorState> {
@@ -59,6 +61,12 @@ export class Actions extends CodeEditorActions<ChatEditorState> {
5961
if (this.chatActions[frameId] != null) {
6062
return this.chatActions[frameId];
6163
}
64+
65+
if (this._get_frame_type(frameId) != FRAME_TYPE) {
66+
// if frame is not of type FRAME_TYPE, no chat actions are defined
67+
return;
68+
}
69+
6270
const syncdb = this._syncstring;
6371
const auxPath = this.auxPath + frameId;
6472
const reduxName = redux_name(this.project_id, auxPath);
@@ -111,7 +119,7 @@ export class Actions extends CodeEditorActions<ChatEditorState> {
111119
}
112120

113121
_raw_default_frame_tree(): FrameTree {
114-
return { type: "chatroom" };
122+
return { type: FRAME_TYPE };
115123
}
116124

117125
async export_to_markdown(): Promise<void> {

src/packages/frontend/frame-editors/llm/create-chat.ts

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { capitalize } from "@cocalc/util/misc";
55
import { Actions, CodeEditorState } from "../code-editor/actions";
66
import { AI_ASSIST_TAG } from "./consts";
77
import { modelToMention } from "./llm-selector";
8+
import type { ChatActions } from "@cocalc/frontend/chat/actions";
9+
import type { Actions as ChatEditorActions } from "@cocalc/frontend/frame-editors/chat-editor/actions";
810

911
export interface Options {
1012
codegen?: boolean;
@@ -29,11 +31,27 @@ export default async function createChat({
2931

3032
const { message } = await createChatMessage(actions, frameId, options, input);
3133

32-
const chatActions = await getChatActions(
33-
actions.redux,
34-
actions.project_id,
35-
actions.path,
36-
);
34+
let chatActions: ChatActions | undefined;
35+
if (actions.path.endsWith(".sage-chat")) {
36+
// a full chatroom (not a different doc type)
37+
chatActions = (actions as ChatEditorActions).getChatActions(frameId);
38+
if (chatActions == null) {
39+
const id = actions.show_focused_frame_of_type("chatroom");
40+
chatActions = (actions as ChatEditorActions).getChatActions(id);
41+
if (chatActions == null) {
42+
console.warn("Bug getting chatroom");
43+
// this should be impossible -- fallback to side chat.
44+
}
45+
}
46+
}
47+
if (chatActions == null) {
48+
// get side chat-specific actions
49+
chatActions = await getChatActions(
50+
actions.redux,
51+
actions.project_id,
52+
actions.path,
53+
);
54+
}
3755

3856
await chatActions.sendChat({
3957
input: message,
@@ -43,7 +61,9 @@ export default async function createChat({
4361

4462
chatActions.scrollToBottom();
4563
// scroll to bottom again *after* the message starts getting responded to.
64+
// Don't scroll too much though, since user wants to actual stop and READ.
4665
setTimeout(() => chatActions.scrollToBottom(), 1000);
66+
setTimeout(() => chatActions.scrollToBottom(), 3000);
4767
}
4868

4969
export async function createChatMessage(

src/packages/frontend/frame-editors/llm/title-bar-button.tsx

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ export default function LanguageModelTitleBarButton({
173173
setShowDialog,
174174
noLabel,
175175
}: Props) {
176+
const noContext = path?.endsWith(".sage-chat");
176177
const intl = useIntl();
177178
const is_cocalc_com = useTypedRedux("customize", "is_cocalc_com");
178179
const [error, setError] = useState<string>("");
@@ -231,12 +232,17 @@ export default function LanguageModelTitleBarButton({
231232
if (showDialog) {
232233
setScope(getScope(id, actions));
233234
restoreCommand();
234-
inputRef.current?.focus();
235+
setTimeout(() => inputRef.current?.focus(), 10);
235236
}
236237
}, [showDialog]);
237238

238239
useEffect(() => {
239-
if (showDialog && scope && actions != null) {
240+
if (
241+
showDialog &&
242+
scope &&
243+
actions != null &&
244+
!noContext
245+
) {
240246
const c = actions.languageModelGetContext(id, scope);
241247
setContext(c);
242248
}
@@ -296,8 +302,8 @@ export default function LanguageModelTitleBarButton({
296302
}`,
297303
);
298304
},
299-
1000,
300-
{ leading: false, trailing: true },
305+
500,
306+
{ leading: true, trailing: true },
301307
);
302308

303309
useAsyncEffect(doUpdateMessage, [
@@ -446,7 +452,7 @@ export default function LanguageModelTitleBarButton({
446452
}
447453

448454
function renderShowOptions() {
449-
if (!showOptions || path.endsWith(".sage-chat")) {
455+
if (!showOptions || noContext) {
450456
return;
451457
}
452458

@@ -580,7 +586,7 @@ export default function LanguageModelTitleBarButton({
580586

581587
function renderContent() {
582588
return (
583-
<Space direction="vertical" style={{ width: "800px", maxWidth: "90vw" }}>
589+
<Space direction="vertical" style={{ width: "800px", maxWidth: "50vw" }}>
584590
<Paragraph>
585591
Describe what you want the language model{" "}
586592
<LLMNameLink model={model} /> to do. Be specific!

0 commit comments

Comments
 (0)