mini-coder 0.5.11 → 0.5.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/submit.ts CHANGED
@@ -18,8 +18,7 @@ import {
18
18
  } from "./index.ts";
19
19
  import { parseInput } from "./input.ts";
20
20
  import {
21
- addMessageToContextTokens,
22
- addMessageToStats,
21
+ appendConversationMessage,
23
22
  appendMessage,
24
23
  appendPromptHistory,
25
24
  filterModelMessages,
@@ -254,26 +253,9 @@ export function queueResolvedInput(
254
253
  function handleAgentEvent(event: AgentEvent, state: AppState): void {
255
254
  switch (event.type) {
256
255
  case "user_message":
257
- state.messages.push(event.message);
258
- state.contextTokens = addMessageToContextTokens(
259
- state.contextTokens,
260
- event.message,
261
- );
262
- break;
263
256
  case "assistant_message":
264
- state.messages.push(event.message);
265
- state.stats = addMessageToStats(state.stats, event.message);
266
- state.contextTokens = addMessageToContextTokens(
267
- state.contextTokens,
268
- event.message,
269
- );
270
- break;
271
257
  case "tool_result":
272
- state.messages.push(event.message);
273
- state.contextTokens = addMessageToContextTokens(
274
- state.contextTokens,
275
- event.message,
276
- );
258
+ appendConversationMessage(state, event.message);
277
259
  break;
278
260
  case "text_delta":
279
261
  case "thinking_delta":
@@ -329,11 +311,7 @@ export async function submitResolvedInput(
329
311
  } satisfies UserMessage;
330
312
 
331
313
  const turn = appendMessage(state.db, session.id, userMessage);
332
- state.messages.push(userMessage);
333
- state.contextTokens = addMessageToContextTokens(
334
- state.contextTokens,
335
- userMessage,
336
- );
314
+ appendConversationMessage(state, userMessage);
337
315
  hooks?.onUserMessage?.(state);
338
316
 
339
317
  const systemPrompt = buildPrompt(state);
package/src/text.ts ADDED
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Shared text-shaping helpers.
3
+ *
4
+ * @module
5
+ */
6
+
7
+ /**
8
+ * Collapse whitespace runs to single spaces and trim the ends.
9
+ *
10
+ * @param text - Raw text to normalize.
11
+ * @returns The collapsed single-line text.
12
+ */
13
+ export function collapseWhitespace(text: string): string {
14
+ return text.replace(/\s+/g, " ").trim();
15
+ }
16
+
17
+ /**
18
+ * Collapse whitespace into a single line, returning `null` when nothing remains.
19
+ *
20
+ * @param text - Raw text to normalize.
21
+ * @returns Collapsed text, or `null` when the result is empty.
22
+ */
23
+ export function collapseWhitespaceToNull(text: string): string | null {
24
+ const collapsed = collapseWhitespace(text);
25
+ return collapsed.length > 0 ? collapsed : null;
26
+ }
27
+
28
+ /**
29
+ * Join only `text` blocks from multipart content into one space-separated string.
30
+ *
31
+ * @param content - Multipart content blocks.
32
+ * @returns Concatenated text-block content.
33
+ */
34
+ export function joinTextBlocks<T extends { type: string }>(
35
+ content: readonly T[],
36
+ ): string {
37
+ return content
38
+ .flatMap((block) => {
39
+ return block.type === "text" &&
40
+ "text" in block &&
41
+ typeof block.text === "string"
42
+ ? [block.text]
43
+ : [];
44
+ })
45
+ .join(" ");
46
+ }
47
+
48
+ /**
49
+ * Truncate text with an ellipsis from the start or end.
50
+ *
51
+ * @param text - Text to truncate.
52
+ * @param maxChars - Maximum visible characters including the ellipsis.
53
+ * @param side - Which side to truncate from.
54
+ * @returns Truncated text when needed.
55
+ */
56
+ export function truncateText(
57
+ text: string,
58
+ maxChars: number,
59
+ side: "start" | "end" = "end",
60
+ ): string {
61
+ if (text.length <= maxChars) {
62
+ return text;
63
+ }
64
+ if (maxChars <= 1) {
65
+ return "…";
66
+ }
67
+ if (side === "start") {
68
+ return `…${text.slice(text.length - (maxChars - 1))}`;
69
+ }
70
+ return `${text.slice(0, maxChars - 1)}…`;
71
+ }
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Shared helpers for built-in tool implementations.
3
+ *
4
+ * @module
5
+ */
6
+
7
+ import type {
8
+ ImageContent,
9
+ Static,
10
+ TextContent,
11
+ Tool,
12
+ ToolCall,
13
+ TSchema,
14
+ } from "@mariozechner/pi-ai";
15
+ import { validateToolArguments } from "@mariozechner/pi-ai";
16
+
17
+ /**
18
+ * Result from executing a tool.
19
+ *
20
+ * Content blocks carry either text or image data. The agent loop maps these
21
+ * directly into pi-ai tool-result content.
22
+ */
23
+ export interface ToolExecResult {
24
+ /** Content blocks for the tool result. */
25
+ content: (TextContent | ImageContent)[];
26
+ /** Whether the execution encountered an error. */
27
+ isError: boolean;
28
+ }
29
+
30
+ /**
31
+ * Build a text-only tool result.
32
+ *
33
+ * @param text - Message text to return in the tool result.
34
+ * @param isError - Whether the result represents a tool error.
35
+ * @returns Text-only tool result content.
36
+ */
37
+ export function textResult(text: string, isError: boolean): ToolExecResult {
38
+ return { content: [{ type: "text", text }], isError };
39
+ }
40
+
41
+ /**
42
+ * Detect which line ending a text blob uses.
43
+ *
44
+ * @param content - Text to inspect.
45
+ * @returns The first detected line ending, or `null` when the text is single-line.
46
+ */
47
+ export function detectLineEnding(content: string): "\n" | "\r\n" | null {
48
+ if (content.includes("\r\n")) {
49
+ return "\r\n";
50
+ }
51
+ if (content.includes("\n")) {
52
+ return "\n";
53
+ }
54
+ return null;
55
+ }
56
+
57
+ /**
58
+ * Normalize line endings to a specific style.
59
+ *
60
+ * @param content - Text to normalize.
61
+ * @param lineEnding - Target line ending sequence.
62
+ * @returns Text using only the requested line ending style.
63
+ */
64
+ export function normalizeLineEndings(
65
+ content: string,
66
+ lineEnding: "\n" | "\r\n",
67
+ ): string {
68
+ if (lineEnding === "\r\n") {
69
+ return content.replace(/\r?\n/g, "\r\n");
70
+ }
71
+ return content.replace(/\r\n/g, "\n");
72
+ }
73
+
74
+ /**
75
+ * Validate and coerce built-in tool arguments against a typed TypeBox schema.
76
+ *
77
+ * @param tool - Built-in tool definition.
78
+ * @param args - Raw parsed tool-call arguments from the model.
79
+ * @returns Validated arguments typed from the tool schema.
80
+ */
81
+ export function validateBuiltinToolArgs<TParameters extends TSchema>(
82
+ tool: Tool<TParameters>,
83
+ args: Record<string, unknown>,
84
+ ): Static<TParameters> {
85
+ return validateToolArguments(tool, {
86
+ type: "toolCall",
87
+ id: tool.name,
88
+ name: tool.name,
89
+ arguments: args,
90
+ } satisfies ToolCall) as Static<TParameters>;
91
+ }