aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ollama.tsx113
1 files changed, 96 insertions, 17 deletions
diff --git a/src/ollama.tsx b/src/ollama.tsx
index 7da5f8f..4451beb 100644
--- a/src/ollama.tsx
+++ b/src/ollama.tsx
@@ -119,17 +119,21 @@ async function promptLLM(prompt: string) {
prompt: prompt,
stream: false,
}),
- })
+ });
if (!response.ok) {
- logseq.App.showMsg("Coudln't fulfill request make sure that ollama service is running and make sure there is no typo in host or model name")
- throw new Error("Error in Ollama request: " + response.statusText)
+ logseq.App.showMsg("Couldn't fulfill request. Make sure Ollama service is running and there are no typos in host or model name.");
+ throw new Error("Error in Ollama request: " + response.statusText);
}
+
const data = await response.json();
- return data.response;
+ // Remove any <think>…</think> blocks in the response
+ const filteredResponse = data.response.replace(/<think>[\s\S]*?<\/think>/g, '');
+
+ return filteredResponse;
} catch (e: any) {
- console.error("ERROR: ", e)
- logseq.App.showMsg("Coudln't fulfill request make sure that ollama service is running and make sure there is no typo in host or model name")
+ console.error("ERROR: ", e);
+ logseq.App.showMsg("Couldn't fulfill request. Make sure Ollama service is running and there are no typos in host or model name.");
}
}
@@ -302,20 +306,95 @@ export async function convertToFlashCardCurrentBlock() {
export async function DivideTaskIntoSubTasks(uuid: string, content: string) {
try {
- const block = await logseq.Editor.insertBlock(uuid, "✅ Genearting todos ...", { before: false })
- let i = 0;
- const response = await promptLLM(`Divide this task into subtasks with numbers: ${content} `)
- for (const todo of response.split("\n")) {
- if (i == 0) {
- await logseq.Editor.updateBlock(block!.uuid, `TODO ${todo.slice(3)} `)
- } else {
- await logseq.Editor.insertBlock(uuid, `TODO ${todo.slice(3)} `, { before: false })
+ // 1) Insert initial placeholder block.
+ const placeholderBlock = await logseq.Editor.insertBlock(
+ uuid,
+ "✅ Generating todos ...",
+ { before: false }
+ );
+ if (!placeholderBlock) {
+ throw new Error("Could not insert the placeholder block.");
+ }
+
+ // 2) Fetch LLM response
+ const response = await promptLLM(
+ `Divide this task into subtasks with numbers respond with multilevel nested markdown format, no dot notation, one subtask per line, plain text only.: ${content}`
+ );
+
+ // 3) Split on newlines, ignoring empty lines
+ const lines = response
+ .split("\n")
+ .map((line: string) => line.replace(/\r$/, "")) // remove trailing \r if present
+ .filter((line: string) => line.trim().length > 0);
+
+ // If there's nothing, do nothing
+ if (!lines.length) return;
+
+ // 4) Update the placeholder block with the very first line
+ // preserving its entire text (no slicing or removal).
+ // Prepend “TODO ” as in your original code structure.
+ await logseq.Editor.updateBlock(
+ placeholderBlock.uuid,
+ `TODO ${lines[0]}`
+ );
+
+ // If there was only one line, we’re done
+ if (lines.length === 1) return;
+
+ // 5) Now set up stack-based nesting for the rest:
+ // stack top is always the most recent block at a particular level.
+ // We'll treat the placeholder block as level=0
+ const stack = [{ uuid: placeholderBlock.uuid, level: 0 }];
+
+ // Helper: Determine indent-based nesting level.
+ // Adjust baseIndent if your model uses different spacing for sub-levels.
+ function getIndentLevel(line: string): number {
+ const firstCharIndex = line.search(/\S/);
+ // no non-whitespace => treat as top-level
+ if (firstCharIndex < 0) {
+ return 0;
+ }
+ // e.g. baseIndent=2 → each 2 leading spaces => +1 nesting level
+ const baseIndent = 3;
+ return Math.floor(firstCharIndex / baseIndent);
+ }
+
+ // 6) Process remaining lines to handle nesting
+ for (let i = 1; i < lines.length; i++) {
+ const rawLine = lines[i];
+
+ // figure out “level” from indentation
+ const level = getIndentLevel(rawLine);
+
+ // pop the stack until we find a block whose level is < current level
+ while (stack.length > 0 && stack[stack.length - 1].level >= level) {
+ stack.pop();
+ }
+
+ // if the stack is empty (all popped), fallback to the placeholder:
+ if (stack.length === 0) {
+ stack.push({ uuid: placeholderBlock.uuid, level: 0 });
+ }
+
+ // top of stack is the parent block where we create a child
+ const parent = stack[stack.length - 1];
+
+ // Insert a child block. Trim only leading spaces from the line’s text so we keep the numbering/content
+ const trimmedText = rawLine.replace(/^\s+/, "");
+ const newBlock = await logseq.Editor.insertBlock(
+ parent.uuid,
+ `TODO ${trimmedText}`,
+ { sibling: false }
+ );
+
+ if (newBlock) {
+ // push newly inserted block at the correct level
+ stack.push({ uuid: newBlock.uuid, level });
}
- i++;
}
} catch (e: any) {
- logseq.App.showMsg(e.toString(), 'warning')
- console.error(e)
+ logseq.App.showMsg(e.toString(), "warning");
+ console.error(e);
}
}