Compare commits
4 Commits
f5479690f9
...
9803512c0b
| Author | SHA1 | Date |
|---|---|---|
|
|
9803512c0b | |
|
|
77e3983d5e | |
|
|
df5077e107 | |
|
|
3db25c5af3 |
|
|
@ -78,6 +78,8 @@
|
||||||
|
|
||||||
.hr {
|
.hr {
|
||||||
border: none;
|
border: none;
|
||||||
border-top: 1px solid var(--hrColor, #555);
|
border-bottom: 1px solid var(--hrColor, #555);
|
||||||
margin: 0.5em 0;
|
margin: 0.5em 0;
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
@ -41,7 +41,7 @@ export const parseTable = (table: string): string => {
|
||||||
|
|
||||||
export const highlight = (message: string, keepMarkup = true): string => {
|
export const highlight = (message: string, keepMarkup = true): string => {
|
||||||
let resultHTML = '';
|
let resultHTML = '';
|
||||||
const tokenRegex = /(\*\*?|"|```|`|(?:^|\n)#{1,3} |(?:^|\n)> |\n)/g;
|
const tokenRegex = /(\*{1,3}|"|```|`|(?:^|\n)#{1,3} |(?:^|\n)> |\n)|---/g;
|
||||||
const headerRegex = /#{1,3} $/;
|
const headerRegex = /#{1,3} $/;
|
||||||
const blockquoteRegex = /> $/;
|
const blockquoteRegex = /> $/;
|
||||||
const stack: string[] = [];
|
const stack: string[] = [];
|
||||||
|
|
@ -116,7 +116,9 @@ export const highlight = (message: string, keepMarkup = true): string => {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isClose) {
|
if (token === '***' || token === '---') {
|
||||||
|
resultHTML += `<span class="${styles.hr}">${keepToken ? token : ''}</span>`;
|
||||||
|
} else if (isClose) {
|
||||||
stack.pop();
|
stack.pop();
|
||||||
resultHTML += `${keepToken ? token : ''}</span>`;
|
resultHTML += `${keepToken ? token : ''}</span>`;
|
||||||
} else if (token === '*') {
|
} else if (token === '*') {
|
||||||
|
|
@ -147,7 +149,6 @@ export const highlight = (message: string, keepMarkup = true): string => {
|
||||||
|
|
||||||
if (!keepMarkup) {
|
if (!keepMarkup) {
|
||||||
resultHTML = resultHTML.replace(/((?:(?:^|\n)\|.+)+)/g, match => parseTable(match));
|
resultHTML = resultHTML.replace(/((?:(?:^|\n)\|.+)+)/g, match => parseTable(match));
|
||||||
resultHTML = resultHTML.replace(/(^|\n)---(\n|$)/g, (_, pre, post) => `${pre}<hr class="${styles.hr}">${post}`);
|
|
||||||
resultHTML = resultHTML.replace(/((?:(?:^|\n)[-+] .+)+)/g, match => parseList(match, false));
|
resultHTML = resultHTML.replace(/((?:(?:^|\n)[-+] .+)+)/g, match => parseList(match, false));
|
||||||
resultHTML = resultHTML.replace(/((?:(?:^|\n)\d+\. .+)+)/g, match => parseList(match, true));
|
resultHTML = resultHTML.replace(/((?:(?:^|\n)\d+\. .+)+)/g, match => parseList(match, true));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import { Sparkles, ChevronsRight } from "lucide-preact";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { ContentEditable } from "@common/components/ContentEditable";
|
import { ContentEditable } from "@common/components/ContentEditable";
|
||||||
|
|
||||||
const CONTINUE_PROMPT = "Continue the story forward.\nUse `edit_text` tool in append mode to add new text to the story.";
|
const CONTINUE_PROMPT = "Continue the story forward.\nUse `edit_text` tool in append mode to add new text to the story.\nWait for the approval after adding.";
|
||||||
|
|
||||||
interface RoleHeaderProps {
|
interface RoleHeaderProps {
|
||||||
message: ChatMessage;
|
message: ChatMessage;
|
||||||
|
|
@ -92,10 +92,14 @@ export const ChatSidebar = () => {
|
||||||
|
|
||||||
const countTokens = async () => {
|
const countTokens = async () => {
|
||||||
try {
|
try {
|
||||||
const messages: LLM.ChatMessage[] = [];
|
const messages: ChatMessage[] = [];
|
||||||
|
|
||||||
if (input.trim()) {
|
if (input.trim()) {
|
||||||
messages.push({ role: 'user', content: input.trim() });
|
messages.push({
|
||||||
|
id: crypto.randomUUID(),
|
||||||
|
role: 'user',
|
||||||
|
content: input.trim(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const chatRequest = Prompt.compilePrompt(appStateRef.current, messages);
|
const chatRequest = Prompt.compilePrompt(appStateRef.current, messages);
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ export enum LocationScale {
|
||||||
Room = 'room',
|
Room = 'room',
|
||||||
House = 'house',
|
House = 'house',
|
||||||
Street = 'street',
|
Street = 'street',
|
||||||
|
Village = 'village',
|
||||||
City = 'city',
|
City = 'city',
|
||||||
Region = 'region',
|
Region = 'region',
|
||||||
Country = 'country',
|
Country = 'country',
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import LLM from "./llm";
|
import LLM from "./llm";
|
||||||
import Chapters from "./chapters";
|
import Chapters from "./chapters";
|
||||||
import { type AppState, CharacterRole } from "../contexts/state";
|
import { type AppState, CharacterRole, type ChatMessage } from "../contexts/state";
|
||||||
import { Tools } from "./tools";
|
import { Tools } from "./tools";
|
||||||
|
|
||||||
namespace Prompt {
|
namespace Prompt {
|
||||||
|
|
@ -313,7 +313,7 @@ namespace Prompt {
|
||||||
return parts.join('\n\n');
|
return parts.join('\n\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function compilePrompt(state: AppState, newMessages: LLM.ChatMessage[] = []): LLM.ChatCompletionRequest | null {
|
export function compilePrompt(state: AppState, newMessages: ChatMessage[] = []): LLM.ChatCompletionRequest | null {
|
||||||
const { currentStory, model, enableThinking } = state;
|
const { currentStory, model, enableThinking } = state;
|
||||||
|
|
||||||
if (!currentStory || !model) {
|
if (!currentStory || !model) {
|
||||||
|
|
@ -332,12 +332,21 @@ namespace Prompt {
|
||||||
storyTokenBudget = model.max_context - otherTokens;
|
storyTokenBudget = model.max_context - otherTokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
const messages: LLM.ChatMessage[] = [
|
const messages: ChatMessage[] = [
|
||||||
{ role: 'system', content: formatSystemPrompt(state, storyTokenBudget) },
|
{
|
||||||
|
id: crypto.randomUUID(),
|
||||||
|
role: 'system',
|
||||||
|
content: formatSystemPrompt(state, storyTokenBudget),
|
||||||
|
},
|
||||||
...currentStory.chatMessages,
|
...currentStory.chatMessages,
|
||||||
];
|
];
|
||||||
|
|
||||||
messages.push(...newMessages);
|
const presentMessages = new Set(messages.map(m => m.id));
|
||||||
|
for (const newMessage of newMessages) {
|
||||||
|
if (!presentMessages.has(newMessage.id)) {
|
||||||
|
messages.push(newMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
model: model.id,
|
model: model.id,
|
||||||
|
|
|
||||||
|
|
@ -399,10 +399,10 @@ export namespace Tools {
|
||||||
dispatchEdit(currentText + '\n' + args.new_text);
|
dispatchEdit(currentText + '\n' + args.new_text);
|
||||||
appState.dispatch({ type: 'SET_CURRENT_TAB', id: appState.currentStory.id, tab });
|
appState.dispatch({ type: 'SET_CURRENT_TAB', id: appState.currentStory.id, tab });
|
||||||
let message = cropped
|
let message = cropped
|
||||||
? `Added text:\n${args.new_text.split('\n').filter(l => l.trim()).map(l => '> ' + l).join('\n')}\n\nWarning: The rest was cropped due to ${LINES_LIMIT} lines limit! Write less next time.`
|
? `Added text:\n${args.new_text.split('\n').filter(l => l.trim()).map(l => '> ' + l).join('\n')}\n\nNote: The rest was cropped due to ${LINES_LIMIT} lines limit!`
|
||||||
: `Text appended to ${target} successfully.`;
|
: `Text appended to ${target} successfully.`;
|
||||||
|
|
||||||
message += `\nNote: you can't continue until user's approval, stop.`
|
message += `\nNote: you can't continue nor add more text until user's approval. Stop any attempts and wait.`
|
||||||
|
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue