miii-agent 0.1.27 → 0.1.29

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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/dist/cli.js +32 -4
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -15,7 +15,7 @@
15
15
  </p>
16
16
 
17
17
  <p align="center">
18
- <img src="demo.gif" alt="miii demo">
18
+ <img src="demo3.gif" alt="miii demo">
19
19
  </p>
20
20
 
21
21
  ---
package/dist/cli.js CHANGED
@@ -199,7 +199,7 @@ async function* chat(entry, model, messages, tools, opts) {
199
199
  model,
200
200
  messages,
201
201
  stream: true,
202
- think: true,
202
+ think: opts?.think ?? true,
203
203
  keep_alive: opts?.keep_alive ?? "10m",
204
204
  options
205
205
  };
@@ -828,9 +828,8 @@ function spillIfLarge(full, label = "output", budget = INLINE_BUDGET) {
828
828
  }
829
829
  const head = Math.floor(budget * HEAD_FRACTION);
830
830
  const tail = budget - head;
831
- const totalLines = full.split("\n").length;
832
831
  const preview = full.slice(0, head) + "\n\u2026\n" + full.slice(-tail);
833
- const notice = path ? `[${label} truncated: ${totalLines} lines / ${full.length} bytes. Full output at ${path} \u2014 read it with read_file offset/limit to see the elided middle.]` : `[${label} truncated to ${budget} bytes; spill to disk failed, middle is lost.]`;
832
+ const notice = path ? `[${label} truncated: ${full.length} bytes. Full output at ${path} \u2014 read it with read_file offset/limit to see the elided middle.]` : `[${label} truncated to ${budget} bytes; spill to disk failed, middle is lost.]`;
834
833
  return `${preview}
835
834
  ${notice}`;
836
835
  }
@@ -1310,6 +1309,8 @@ Ask in a numbered list. One round of questions per turn. Then wait.
1310
1309
  - Use the native function-calling interface as the ONLY channel for tool calls. Never print a tool call as text \u2014 not as JSON, not as a fenced code block, not as \`call:name{...}\`, not in any custom or tagged syntax. Text-form calls do NOT execute; they leak to the user and nothing happens.
1311
1310
  - If you cannot emit a real function call, do not fake one in prose \u2014 answer in plain text instead.
1312
1311
  - After a tool result, move directly to the next tool call or the final answer. Do not restate what the previous tool did.
1312
+ - Every tool call MUST carry a complete, valid arguments object: all required fields present, correct types, valid JSON. Never emit a call with empty, partial, or placeholder arguments.
1313
+ - WRONG (leaks as text, nothing runs): writing \`call:some_tool{"foo":"bar"}\` or a fenced JSON block in your reply. RIGHT: emit it as a native function call with a full arguments object.
1313
1314
 
1314
1315
  # Tools
1315
1316
  You have access to the following tools. Call them via the function-calling interface.
@@ -2585,7 +2586,9 @@ ${convo}`;
2585
2586
  model,
2586
2587
  [{ role: "user", content: prompt }],
2587
2588
  void 0,
2588
- { temperature: 0.2, num_predict: 32 }
2589
+ // Disable thinking + give content room: reasoning models otherwise burn
2590
+ // the whole budget on hidden thinking and emit no title text.
2591
+ { temperature: 0.2, num_predict: 64, think: false }
2589
2592
  )) {
2590
2593
  if (chunk.content) out += chunk.content;
2591
2594
  }
@@ -2596,6 +2599,22 @@ ${convo}`;
2596
2599
  }
2597
2600
  }
2598
2601
 
2602
+ // src/ui/terminalTitle.ts
2603
+ var OSC = "\x1B]2;";
2604
+ var BEL = "\x07";
2605
+ function clean(title) {
2606
+ return title.replace(/[\x00-\x1f\x7f]/g, " ").replace(/\s+/g, " ").trim().slice(0, 80);
2607
+ }
2608
+ function setTerminalTitle(title) {
2609
+ if (!process.stdout.isTTY) return;
2610
+ const text = clean(title);
2611
+ const label = text ? `\u2733 ${text}` : "";
2612
+ process.stdout.write(`${OSC}${label}${BEL}`);
2613
+ }
2614
+ function resetTerminalTitle() {
2615
+ setTerminalTitle("");
2616
+ }
2617
+
2599
2618
  // src/ui/FilePicker.tsx
2600
2619
  import { Box as Box7, Text as Text7 } from "ink";
2601
2620
  import { readdirSync as readdirSync2 } from "fs";
@@ -4376,6 +4395,7 @@ function useKeyboard(opts) {
4376
4395
  setActiveToolResults([]);
4377
4396
  setError(null);
4378
4397
  setSessionId(meta.id);
4398
+ setTerminalTitle(meta.title);
4379
4399
  onResumeSession(meta.id);
4380
4400
  setNotice(`resumed \xB7 ${meta.title}`);
4381
4401
  setState("ready");
@@ -4505,6 +4525,7 @@ function useKeyboard(opts) {
4505
4525
  } else if (trimmed === "/new") {
4506
4526
  if (agentHistory.length) setNotice("session saved");
4507
4527
  setSessionId(newSessionId());
4528
+ resetTerminalTitle();
4508
4529
  hardClear();
4509
4530
  clearSession();
4510
4531
  } else if (trimmed === "/sessions") {
@@ -4688,6 +4709,8 @@ function App() {
4688
4709
  const [updateStatus, setUpdateStatus] = useState5("idle");
4689
4710
  const [providerDown, setProviderDown] = useState5(false);
4690
4711
  const [sessionId, setSessionId] = useState5(() => newSessionId());
4712
+ const sessionIdRef = useRef2(sessionId);
4713
+ sessionIdRef.current = sessionId;
4691
4714
  const [sessions, setSessions] = useState5([]);
4692
4715
  const [notice, setNotice] = useState5(null);
4693
4716
  const [input, setInput] = useState5("");
@@ -4705,6 +4728,7 @@ function App() {
4705
4728
  }
4706
4729
  });
4707
4730
  }, []);
4731
+ useEffect4(() => resetTerminalTitle, []);
4708
4732
  const titledSessions = useRef2(/* @__PURE__ */ new Set());
4709
4733
  useEffect4(() => {
4710
4734
  const history = agent.agentHistory;
@@ -4719,6 +4743,7 @@ function App() {
4719
4743
  try {
4720
4744
  const title = await summarizeConversation(model, snapshot);
4721
4745
  setSessionTitle(id, title);
4746
+ if (id === sessionIdRef.current) setTerminalTitle(title);
4722
4747
  } catch {
4723
4748
  }
4724
4749
  })();
@@ -4915,5 +4940,8 @@ if (cmd === "version" || cmd === "--version" || cmd === "-v") {
4915
4940
  const { runEval: runEval2 } = await Promise.resolve().then(() => (init_run(), run_exports));
4916
4941
  process.exit(await runEval2(rest));
4917
4942
  } else {
4943
+ process.on("exit", () => {
4944
+ if (process.stdout.isTTY) process.stdout.write("\x1B]2;\x07");
4945
+ });
4918
4946
  render(createElement(App));
4919
4947
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "miii-agent",
3
- "version": "0.1.27",
3
+ "version": "0.1.29",
4
4
  "description": "Cursor / Claude Code, but local. An offline AI pair-programmer in your terminal, powered by Ollama. Private by default, free forever.",
5
5
  "type": "module",
6
6
  "bin": {