Skip to content

Commit

Permalink
rewrite chat, message, part using tea
Browse files Browse the repository at this point in the history
  • Loading branch information
dlants committed Dec 14, 2024
1 parent 11e639e commit 5a63e1f
Show file tree
Hide file tree
Showing 9 changed files with 408 additions and 403 deletions.
213 changes: 0 additions & 213 deletions rplugin/node/magenta/src/chat.ts

This file was deleted.

90 changes: 90 additions & 0 deletions rplugin/node/magenta/src/chat/chat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import Anthropic from "@anthropic-ai/sdk";
import { ToolResultBlockParam } from "@anthropic-ai/sdk/resources/index.mjs";
import { toMessageParam } from "./part.js";
import { Model as Message, update as updateMessage } from "./message.js";
import { ToolRequest } from "../tools/index.js";
import { Update } from "../tea/tea.js";

export type Role = "user" | "assistant";

export type ChatState =
| {
state: "pending-user-input";
}
| {
state: "streaming-response";
}
| {
state: "awaiting-tool-use";
};

export type Model = {
messages: Message[];
};

export type Msg =
| {
type: "add-message";
role: Role;
content?: string;
}
| {
type: "add-tool-response";
request: ToolRequest;
response: ToolResultBlockParam;
}
| {
type: "clear";
};

export const update: Update<Msg, Model> = (msg, model) => {
switch (msg.type) {
case "add-message": {
let message: Message = {
role: msg.role,
parts: [],
};

if (msg.content) {
const [next] = updateMessage(
{ type: "append-text", text: msg.content },
message,
);
message = next;
}
model.messages.push(message);
return [model];
}
case "add-tool-response": {
let lastMessage = model.messages[model.messages.length - 1];
if (lastMessage.role != "user") {
lastMessage = {
role: "user",
parts: [],
};
model.messages.push(lastMessage);
}

const [next] = updateMessage(
{
type: "add-tool-response",
request: msg.request,
response: msg.response,
},
lastMessage,
);
model.messages.splice(model.messages.length - 1, 1, next);
return [model];
}
case "clear": {
return [{ messages: [] }];
}
}
};

export function getMessages(model: Model): Anthropic.MessageParam[] {
return model.messages.map((msg) => ({
role: msg.role,
content: msg.parts.map(toMessageParam),
}));
}
73 changes: 73 additions & 0 deletions rplugin/node/magenta/src/chat/message.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { ToolResultBlockParam } from "@anthropic-ai/sdk/resources/index.mjs";
import { Model as Part, view as partView } from "./part.js";
import { ToolProcess } from "../tools/types.js";
import { ToolRequest } from "../tools/index.js";
import { Role } from "./chat.js";
import { Dispatch, Update } from "../tea/tea.js";
import { assertUnreachable } from "../utils/assertUnreachable.js";
import { d, View } from "../tea/view.js";

export type Model = {
role: Role;
parts: Part[];
};

export type Msg =
| {
type: "append-text";
text: string;
}
| {
type: "add-tool-use";
request: ToolRequest;
process: ToolProcess;
}
| {
type: "add-tool-response";
request: ToolRequest;
response: ToolResultBlockParam;
};

export const update: Update<Msg, Model> = (msg, model) => {
switch (msg.type) {
case "append-text": {
const lastPart = model.parts[model.parts.length - 1];
if (lastPart.type == "text") {
lastPart.text += msg.text;
} else {
model.parts.push({
type: "text",
text: msg.text,
});
}
break;
}

case "add-tool-use":
model.parts.push({
type: "tool-use",
request: msg.request,
process: msg.process,
});
break;

case "add-tool-response":
model.parts.push({
type: "tool-response",
request: msg.request,
response: msg.response,
});
break;

default:
assertUnreachable(msg);
}
return [model];
};

export const view: View<{ model: Model; dispatch: Dispatch<Msg> }> = ({
model,
}) => d`\
### ${model.role}:
${model.parts.map((part) => partView({ model: part }))}`;
Loading

0 comments on commit 5a63e1f

Please sign in to comment.