Compare commits
No commits in common. "215d320e9ebde9dfe8eff76a700c63b5ca83b03f" and "c36e5654ed20c43764a25340de1e727028d7068f" have entirely different histories.
215d320e9e
...
c36e5654ed
|
|
@ -32,7 +32,7 @@ export const Editor = () => {
|
|||
|
||||
const handleScratchpadInput = useInputCallback((text: string) => {
|
||||
if (!currentStory) return;
|
||||
dispatch({ type: 'EDIT_SCRATCHPAD', id: currentStory.id, text });
|
||||
dispatch({ type: 'EDIT_STORY', id: currentStory.id, text });
|
||||
}, [currentStory?.id]);
|
||||
|
||||
const handleTabChange = (tab: Tab) => {
|
||||
|
|
|
|||
|
|
@ -131,28 +131,7 @@ const DEFAULT_STATE: IState = {
|
|||
model: null,
|
||||
enableThinking: false,
|
||||
bannedTokens: [],
|
||||
systemInstruction: `You are a creative writing assistant. Help the user develop their story by writing engaging content, maintaining consistency with the established characters, settings, and plot. Follow the user's instructions while staying true to the story's tone and style.
|
||||
|
||||
Write using markdown to highlight special parts.
|
||||
Supported markdown subset:
|
||||
- *italic*
|
||||
- **bold**
|
||||
- "quotes"
|
||||
- \`monospace\`
|
||||
- # Header 1
|
||||
- ## Header 2
|
||||
- ### Header 3
|
||||
- > blockquote
|
||||
- Tables
|
||||
- Ordered lists
|
||||
- Unordered lists (only with \`- \` markers)
|
||||
- Only top-level lists (no nesting)
|
||||
|
||||
Show the chapters with \`# Chapter\` headers.
|
||||
Add important details not yet ready to be included in the story to the scratchpad: character motivations, hidden plot points, etc.
|
||||
You **must** use \`edit_text\` tool to write to the story.
|
||||
Keep the reports after editing concise to save token budget, just say "Done" with minimal to no thinking.
|
||||
The most actual state of the story is provided below, use it as ground truth.`,
|
||||
systemInstruction: `You are a creative writing assistant. Help the user develop their story by writing engaging content, maintaining consistency with the established characters, settings, and plot. Follow the user's instructions while staying true to the story's tone and style.`,
|
||||
};
|
||||
|
||||
// ─── Reducer ─────────────────────────────────────────────────────────────────
|
||||
|
|
|
|||
|
|
@ -334,43 +334,48 @@ export namespace Tools {
|
|||
return 'Error: No story selected';
|
||||
}
|
||||
|
||||
const target = args.target ?? 'story';
|
||||
const isScratchpad = target === 'scratchpad';
|
||||
const currentText = isScratchpad ? (appState.currentStory.scratchpad ?? '') : appState.currentStory.text;
|
||||
const tab = isScratchpad ? 'scratchpad' : 'story';
|
||||
|
||||
const dispatchEdit = (text: string) => appState.dispatch(
|
||||
isScratchpad
|
||||
? { type: 'EDIT_SCRATCHPAD', id: appState.currentStory!.id, text }
|
||||
: { type: 'EDIT_STORY', id: appState.currentStory!.id, text }
|
||||
);
|
||||
|
||||
// Append mode: when old_text is not provided, append new_text
|
||||
// Append mode: when old_text is not provided, append new_text to the story
|
||||
if (args.old_text == null) {
|
||||
dispatchEdit(currentText + '\n' + args.new_text);
|
||||
appState.dispatch({ type: 'SET_CURRENT_TAB', id: appState.currentStory.id, tab });
|
||||
return `Text appended to ${target} successfully`;
|
||||
appState.dispatch({
|
||||
type: 'EDIT_STORY',
|
||||
id: appState.currentStory.id,
|
||||
text: appState.currentStory.text + '\n' + args.new_text,
|
||||
});
|
||||
appState.dispatch({
|
||||
type: 'SET_CURRENT_TAB',
|
||||
id: appState.currentStory.id,
|
||||
tab: 'story'
|
||||
});
|
||||
return 'Text appended to story successfully';
|
||||
}
|
||||
|
||||
// Replace mode
|
||||
const occurrences = currentText.split(args.old_text).length - 1;
|
||||
// Replace mode: find and replace old_text with new_text in story
|
||||
const source = appState.currentStory.text;
|
||||
const occurrences = source.split(args.old_text).length - 1;
|
||||
if (occurrences === 0) {
|
||||
return `Error: old_text not found in ${target}`;
|
||||
return 'Error: old_text not found in story';
|
||||
}
|
||||
if (occurrences > 1 && !args.replace_all) {
|
||||
return `Error: old_text appears multiple times in ${target}`;
|
||||
return 'Error: old_text appears multiple times in story';
|
||||
}
|
||||
|
||||
dispatchEdit(currentText.replaceAll(args.old_text, args.new_text));
|
||||
appState.dispatch({ type: 'SET_CURRENT_TAB', id: appState.currentStory.id, tab });
|
||||
return `${target.charAt(0).toUpperCase() + target.slice(1)} edited successfully`;
|
||||
appState.dispatch({
|
||||
type: 'EDIT_STORY',
|
||||
id: appState.currentStory.id,
|
||||
text: appState.currentStory.text.replaceAll(args.old_text, args.new_text),
|
||||
});
|
||||
appState.dispatch({
|
||||
type: 'SET_CURRENT_TAB',
|
||||
id: appState.currentStory.id,
|
||||
tab: 'story'
|
||||
});
|
||||
return 'Story edited successfully';
|
||||
},
|
||||
description: "Replace or append text in the story or scratchpad. When old_text is omitted, appends new_text to the end. Case-sensitive.",
|
||||
description: "Replace text in the story. When old_text is omitted, appends new_text to the story's end. Case-sensitive.",
|
||||
parameters: Type.Object({
|
||||
new_text: Type.String({ description: 'The new text to replace old_text with, or to append if old_text is omitted' }),
|
||||
old_text: Type.Optional(Type.String({ description: 'The text to find and replace. If omitted, new_text will be appended' })),
|
||||
replace_all: Type.Optional(Type.Boolean({ description: 'If true, replace all occurrences of old_text' })),
|
||||
target: Type.Optional(Type.Enum(['story', 'scratchpad'] as const, { description: 'Which text to edit: "story" (default) or "scratchpad"' })),
|
||||
}),
|
||||
}),
|
||||
'grep': tool({
|
||||
|
|
|
|||
Loading…
Reference in New Issue