feat: snip a region into chat, and make links clickable (#14)
This commit was merged in pull request #14.
This commit is contained in:
+28
-3
@@ -1,5 +1,6 @@
|
||||
import { imageSource } from "./attachments";
|
||||
import { repairCodeBlocks } from "./code";
|
||||
import type { ChatTurn, ThreadMessage } from "./types";
|
||||
import type { Attachment, ChatTurn, ThreadMessage } from "./types";
|
||||
|
||||
/**
|
||||
* Markdown rendering for the detail panel.
|
||||
@@ -22,6 +23,24 @@ import type { ChatTurn, ThreadMessage } from "./types";
|
||||
|
||||
export const STREAMING_CURSOR = "▍";
|
||||
|
||||
/**
|
||||
* Renders attachments as markdown images.
|
||||
*
|
||||
* Vicinae does resolve a local file: `MdImage.qml` draws it block-level and
|
||||
* centred, uses the alt text as an italic caption underneath, and caps the
|
||||
* height at 200px no matter what is asked for. So this is a thumbnail rather
|
||||
* than something readable, which is why the action panel also offers Open
|
||||
* Screenshot for the full image.
|
||||
*
|
||||
* The alt text is short on purpose. Whatever is here is drawn centred under the
|
||||
* image, so a sentence reads as a stray line of prose floating in the middle of
|
||||
* the pane. It is also the only thing left if the file has since been deleted,
|
||||
* which is why it is not empty.
|
||||
*/
|
||||
export function renderAttachments(attachments: Attachment[]): string {
|
||||
return attachments.map((attachment) => `})`).join("\n\n");
|
||||
}
|
||||
|
||||
/** Which optional sections the transcript includes. Driven by preferences. */
|
||||
export interface TranscriptOptions {
|
||||
showToolCalls: boolean;
|
||||
@@ -49,7 +68,12 @@ function renderTools(message: ThreadMessage): string {
|
||||
|
||||
function renderMessage(message: ThreadMessage, options: TranscriptOptions): string {
|
||||
// The question is identified by its styling alone.
|
||||
if (message.role === "user") return quote(message.text);
|
||||
if (message.role === "user") {
|
||||
const images = renderAttachments(message.attachments);
|
||||
const asked = quote(message.text);
|
||||
|
||||
return images ? `${asked}\n\n${images}` : asked;
|
||||
}
|
||||
|
||||
// While a tool is running there is no answer text yet, so the activity line
|
||||
// stands in and the user can see what Lam is actually doing.
|
||||
@@ -138,9 +162,10 @@ export function sessionToPlainText(turns: ChatTurn[]): string {
|
||||
return turns
|
||||
.map((turn) => {
|
||||
const question = `**You**\n\n${turn.prompt}`;
|
||||
const attached = turn.attachments.length > 0 ? "\n\n_(screenshot attached)_" : "";
|
||||
const answer = turn.response.trim() || (turn.error ? "" : "_(no response)_");
|
||||
const failure = turn.error ? `\n\n**[error]** ${turn.error}` : "";
|
||||
return `${question}\n\n**Lam**\n\n${answer}${failure}`;
|
||||
return `${question}${attached}\n\n**Lam**\n\n${answer}${failure}`;
|
||||
})
|
||||
.join("\n\n---\n\n");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user