lithe-cli 0.6.2__tar.gz → 0.6.3__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lithe-cli
3
- Version: 0.6.2
3
+ Version: 0.6.3
4
4
  Summary: Command-line interface for the lithe agent kernel: chat, one-shot runs, undo, and run inspection.
5
5
  License: MIT License
6
6
 
@@ -99,12 +99,12 @@ $ lithe run "总结 README.md 的要点,存到 SUMMARY.md"
99
99
  ⚒ read_file 读取 README.md
100
100
  ✓ 已读取 README.md(120 行) 0.1s
101
101
  ⚒ write_file 写入 SUMMARY.md
102
- ✓ 写入 SUMMARY.md 0.0s
102
+ ✓ 写入 SUMMARY.md(+12 行,新建) 0.0s
103
103
  已把要点写入 SUMMARY.md。
104
104
  ── done · steps 3 · tokens 2100 · cost 0.0042
105
105
  ```
106
106
 
107
- 修改已有文件时,助手优先调用 `edit_file` 或 `apply_patch` 做局部更新;只有新建文件或需要整体替换时才使用 `write_file`。工具调用界面只显示工具名、文件路径等摘要,不再展开完整参数。
107
+ 修改已有文件时,助手优先调用 `edit_file` 或 `apply_patch` 做局部更新;只有新建文件或需要整体替换时才使用 `write_file`。工具调用界面只显示工具名、文件路径等摘要,文件写入/编辑的结果带 `+N -M 行` 的行数变化提示(lithe 0.9.10 起由内核统计)。
108
108
 
109
109
  `--stream` streams tokens as they generate; `-v` adds per-call
110
110
  usage/context gauges; `--max-steps` caps the tool loop;
@@ -122,8 +122,8 @@ into the console:
122
122
  │ 把 a.txt 改成三行待办清单 ││ ● 完成 · 0.2s │
123
123
  │ ◆ update_todos ││ 步骤 2/35 · 0.2s │
124
124
  │ ✓ 任务清单已更新(3 条) 0.0s ││ ✓ update_todos 0.0s│
125
- │ ◆ edit_file · 局部修改 a.txt ││ ✓ edit_file 0.0s │
126
- │ ✓ 已修改 a.txt 0.0s ││ ◆ 待办 1/3 │
125
+ │ ◆ edit_file · 局部修改 a.txt ││ ✓ edit_file 0.0s │
126
+ │ ✓ 编辑 a.txt(+3 -1 行) 0.0s ││ ◆ 待办 1/3 │
127
127
  │ 已完成。 ││ [~] 修改 a.txt │
128
128
  │ ││ ◆ 会话用量 │
129
129
  │ ││ 输入 1,024 · 输出 216│
@@ -132,14 +132,16 @@ into the console:
132
132
  │ ││ 上下文 1,024 / 128,000 (0.8%)│
133
133
  ╰─────────────────────────────────────╯╰────────────────────╯
134
134
  lithe ❯ _
135
- ● 完成 · step 2/35 · 1,240 tok · $0.0021 Enter 发送 · /help 命令
135
+ ● 完成 · 0.2s Enter 发送 · F2 侧栏 · /help 命令
136
136
  ```
137
137
 
138
138
  The left pane is the conversation (task, compact tool-call summaries
139
- and outcomes, and the streaming assistant reply). The right sidebar shows
140
- run status, recent tools, todos, session-wide cumulative input/output/
141
- cached tokens and cost, plus the latest model-call context length and
142
- window percentage. The two panes are separate windows — selecting text
139
+ and outcomes — file edits land with `+N -M 行` counts — and the
140
+ streaming assistant reply). The right sidebar shows run status, recent
141
+ tools, todos, session-wide cumulative input/output/cached tokens and
142
+ cost, plus the latest model-call context length and window percentage;
143
+ usage numbers live only there, the bottom bar keeps status and key
144
+ hints. The two panes are separate windows — selecting text
143
145
  in one never captures the other — and the conversation scrolls: mouse
144
146
  wheel, PageUp/PageDown, Home/End (a new turn jumps back to the output).
145
147
  F2 or `/sidebar` hides the status pane so a reply can be copied from a
@@ -56,12 +56,12 @@ $ lithe run "总结 README.md 的要点,存到 SUMMARY.md"
56
56
  ⚒ read_file 读取 README.md
57
57
  ✓ 已读取 README.md(120 行) 0.1s
58
58
  ⚒ write_file 写入 SUMMARY.md
59
- ✓ 写入 SUMMARY.md 0.0s
59
+ ✓ 写入 SUMMARY.md(+12 行,新建) 0.0s
60
60
  已把要点写入 SUMMARY.md。
61
61
  ── done · steps 3 · tokens 2100 · cost 0.0042
62
62
  ```
63
63
 
64
- 修改已有文件时,助手优先调用 `edit_file` 或 `apply_patch` 做局部更新;只有新建文件或需要整体替换时才使用 `write_file`。工具调用界面只显示工具名、文件路径等摘要,不再展开完整参数。
64
+ 修改已有文件时,助手优先调用 `edit_file` 或 `apply_patch` 做局部更新;只有新建文件或需要整体替换时才使用 `write_file`。工具调用界面只显示工具名、文件路径等摘要,文件写入/编辑的结果带 `+N -M 行` 的行数变化提示(lithe 0.9.10 起由内核统计)。
65
65
 
66
66
  `--stream` streams tokens as they generate; `-v` adds per-call
67
67
  usage/context gauges; `--max-steps` caps the tool loop;
@@ -79,8 +79,8 @@ into the console:
79
79
  │ 把 a.txt 改成三行待办清单 ││ ● 完成 · 0.2s │
80
80
  │ ◆ update_todos ││ 步骤 2/35 · 0.2s │
81
81
  │ ✓ 任务清单已更新(3 条) 0.0s ││ ✓ update_todos 0.0s│
82
- │ ◆ edit_file · 局部修改 a.txt ││ ✓ edit_file 0.0s │
83
- │ ✓ 已修改 a.txt 0.0s ││ ◆ 待办 1/3 │
82
+ │ ◆ edit_file · 局部修改 a.txt ││ ✓ edit_file 0.0s │
83
+ │ ✓ 编辑 a.txt(+3 -1 行) 0.0s ││ ◆ 待办 1/3 │
84
84
  │ 已完成。 ││ [~] 修改 a.txt │
85
85
  │ ││ ◆ 会话用量 │
86
86
  │ ││ 输入 1,024 · 输出 216│
@@ -89,14 +89,16 @@ into the console:
89
89
  │ ││ 上下文 1,024 / 128,000 (0.8%)│
90
90
  ╰─────────────────────────────────────╯╰────────────────────╯
91
91
  lithe ❯ _
92
- ● 完成 · step 2/35 · 1,240 tok · $0.0021 Enter 发送 · /help 命令
92
+ ● 完成 · 0.2s Enter 发送 · F2 侧栏 · /help 命令
93
93
  ```
94
94
 
95
95
  The left pane is the conversation (task, compact tool-call summaries
96
- and outcomes, and the streaming assistant reply). The right sidebar shows
97
- run status, recent tools, todos, session-wide cumulative input/output/
98
- cached tokens and cost, plus the latest model-call context length and
99
- window percentage. The two panes are separate windows — selecting text
96
+ and outcomes — file edits land with `+N -M 行` counts — and the
97
+ streaming assistant reply). The right sidebar shows run status, recent
98
+ tools, todos, session-wide cumulative input/output/cached tokens and
99
+ cost, plus the latest model-call context length and window percentage;
100
+ usage numbers live only there, the bottom bar keeps status and key
101
+ hints. The two panes are separate windows — selecting text
100
102
  in one never captures the other — and the conversation scrolls: mouse
101
103
  wheel, PageUp/PageDown, Home/End (a new turn jumps back to the output).
102
104
  F2 or `/sidebar` hides the status pane so a reply can be copied from a
@@ -1,3 +1,3 @@
1
1
  """lithe-cli: the command-line interface for the lithe agent kernel."""
2
2
 
3
- __version__ = "0.6.2"
3
+ __version__ = "0.6.3"
@@ -450,13 +450,9 @@ def body_layout(state: TuiState, width: int, height: int):
450
450
 
451
451
 
452
452
  def compose_footer(state: TuiState, width: int, running_hint: str) -> list:
453
+ """Status + key hints only; usage lives in the sidebar, not down here."""
453
454
  dot = f"class:foot class:{_status_class(state.status)}"
454
- total_tokens = state.tokens + state._turn_tokens
455
- total_cost = state.cost + state._turn_cost
456
- left = (
457
- f" ● {state.status} · step {state.step}/{state.max_steps}"
458
- f" · {total_tokens:,} tok · ${total_cost:.4f}"
459
- )
455
+ left = f" ● {state.status} "
460
456
  room = width - display_width(running_hint) - display_width(left) - 2
461
457
  text = left + (" " * max(1, room)) if room >= 1 else truncate(left, width - display_width(running_hint) - 1)
462
458
  return [(dot, " "), ("class:foot", pad(text, width - display_width(running_hint))), ("class:foot", running_hint)]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lithe-cli
3
- Version: 0.6.2
3
+ Version: 0.6.3
4
4
  Summary: Command-line interface for the lithe agent kernel: chat, one-shot runs, undo, and run inspection.
5
5
  License: MIT License
6
6
 
@@ -99,12 +99,12 @@ $ lithe run "总结 README.md 的要点,存到 SUMMARY.md"
99
99
  ⚒ read_file 读取 README.md
100
100
  ✓ 已读取 README.md(120 行) 0.1s
101
101
  ⚒ write_file 写入 SUMMARY.md
102
- ✓ 写入 SUMMARY.md 0.0s
102
+ ✓ 写入 SUMMARY.md(+12 行,新建) 0.0s
103
103
  已把要点写入 SUMMARY.md。
104
104
  ── done · steps 3 · tokens 2100 · cost 0.0042
105
105
  ```
106
106
 
107
- 修改已有文件时,助手优先调用 `edit_file` 或 `apply_patch` 做局部更新;只有新建文件或需要整体替换时才使用 `write_file`。工具调用界面只显示工具名、文件路径等摘要,不再展开完整参数。
107
+ 修改已有文件时,助手优先调用 `edit_file` 或 `apply_patch` 做局部更新;只有新建文件或需要整体替换时才使用 `write_file`。工具调用界面只显示工具名、文件路径等摘要,文件写入/编辑的结果带 `+N -M 行` 的行数变化提示(lithe 0.9.10 起由内核统计)。
108
108
 
109
109
  `--stream` streams tokens as they generate; `-v` adds per-call
110
110
  usage/context gauges; `--max-steps` caps the tool loop;
@@ -122,8 +122,8 @@ into the console:
122
122
  │ 把 a.txt 改成三行待办清单 ││ ● 完成 · 0.2s │
123
123
  │ ◆ update_todos ││ 步骤 2/35 · 0.2s │
124
124
  │ ✓ 任务清单已更新(3 条) 0.0s ││ ✓ update_todos 0.0s│
125
- │ ◆ edit_file · 局部修改 a.txt ││ ✓ edit_file 0.0s │
126
- │ ✓ 已修改 a.txt 0.0s ││ ◆ 待办 1/3 │
125
+ │ ◆ edit_file · 局部修改 a.txt ││ ✓ edit_file 0.0s │
126
+ │ ✓ 编辑 a.txt(+3 -1 行) 0.0s ││ ◆ 待办 1/3 │
127
127
  │ 已完成。 ││ [~] 修改 a.txt │
128
128
  │ ││ ◆ 会话用量 │
129
129
  │ ││ 输入 1,024 · 输出 216│
@@ -132,14 +132,16 @@ into the console:
132
132
  │ ││ 上下文 1,024 / 128,000 (0.8%)│
133
133
  ╰─────────────────────────────────────╯╰────────────────────╯
134
134
  lithe ❯ _
135
- ● 完成 · step 2/35 · 1,240 tok · $0.0021 Enter 发送 · /help 命令
135
+ ● 完成 · 0.2s Enter 发送 · F2 侧栏 · /help 命令
136
136
  ```
137
137
 
138
138
  The left pane is the conversation (task, compact tool-call summaries
139
- and outcomes, and the streaming assistant reply). The right sidebar shows
140
- run status, recent tools, todos, session-wide cumulative input/output/
141
- cached tokens and cost, plus the latest model-call context length and
142
- window percentage. The two panes are separate windows — selecting text
139
+ and outcomes — file edits land with `+N -M 行` counts — and the
140
+ streaming assistant reply). The right sidebar shows run status, recent
141
+ tools, todos, session-wide cumulative input/output/cached tokens and
142
+ cost, plus the latest model-call context length and window percentage;
143
+ usage numbers live only there, the bottom bar keeps status and key
144
+ hints. The two panes are separate windows — selecting text
143
145
  in one never captures the other — and the conversation scrolls: mouse
144
146
  wheel, PageUp/PageDown, Home/End (a new turn jumps back to the output).
145
147
  F2 or `/sidebar` hides the status pane so a reply can be copied from a
@@ -1,4 +1,4 @@
1
- lithe>=0.9.8
1
+ lithe>=0.9.10
2
2
  prompt-toolkit>=3.0.38
3
3
 
4
4
  [dev]
@@ -9,7 +9,7 @@ description = "Command-line interface for the lithe agent kernel: chat, one-shot
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
11
11
  requires-python = ">=3.10"
12
- dependencies = ["lithe>=0.9.8", "prompt-toolkit>=3.0.38"]
12
+ dependencies = ["lithe>=0.9.10", "prompt-toolkit>=3.0.38"]
13
13
  keywords = ["agent", "llm", "react", "cli", "tool-calling"]
14
14
  classifiers = [
15
15
  "Development Status :: 4 - Beta",
@@ -672,6 +672,33 @@ def _pty_drain(fd) -> bytes:
672
672
  return out
673
673
 
674
674
 
675
+ def test_footer_does_not_duplicate_sidebar_usage():
676
+ from lithe_cli.tui import TuiState, compose_footer
677
+
678
+ state = TuiState("m", "/ws", 5)
679
+ state.on_event({"type": "done", "status": "done", "steps": 3, "tokens": 120, "cost": 0.5})
680
+ line = "".join(f[1] for f in compose_footer(state, 100, " hint "))
681
+ assert "完成" in line
682
+ assert "tok" not in line and "$" not in line and "step" not in line
683
+
684
+
685
+ def test_file_tools_report_line_delta_in_feed(tmp_path):
686
+ script = [
687
+ {"tool_calls": [_tc("write_file", {"path": "a.txt", "content": "hi"}, "c1")]},
688
+ {"tool_calls": [_tc("edit_file",
689
+ {"path": "a.txt", "old_text": "hi", "new_text": "hi\nyo"}, "c2")]},
690
+ {"content": "完成"},
691
+ ]
692
+ cfg = make_config(tmp_path, script)
693
+ seen = []
694
+ rid, done, _ = asyncio.run(execute(cfg, "编辑 a.txt", on_event=seen.append))
695
+ assert done["status"] == "done"
696
+ summaries = [e.get("summary", "") for e in seen if e["type"] == "tool_result"]
697
+ assert any("写入 a.txt(+1 行,新建)" in s for s in summaries)
698
+ assert any("编辑 a.txt(+1 行)" in s for s in summaries)
699
+ assert (cfg.workspace_dir / "a.txt").read_text(encoding="utf-8") == "hi\nyo"
700
+
701
+
675
702
  def test_fullscreen_app_scrolls_and_toggles_sidebar():
676
703
  code = """
677
704
  import asyncio
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes