agent-cli 0.62.0__py3-none-any.whl → 0.63.0__py3-none-any.whl

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.
agent_cli/dev/cli.py CHANGED
@@ -344,6 +344,19 @@ def _launch_editor(path: Path, editor: Editor) -> None:
344
344
  _warn(f"Could not open editor: {e}")
345
345
 
346
346
 
347
+ def _write_prompt_to_worktree(worktree_path: Path, prompt: str) -> Path:
348
+ """Write the prompt to .claude/TASK.md in the worktree.
349
+
350
+ This makes the task description available to the spawned agent
351
+ and provides a record of what was requested.
352
+ """
353
+ claude_dir = worktree_path / ".claude"
354
+ claude_dir.mkdir(parents=True, exist_ok=True)
355
+ task_file = claude_dir / "TASK.md"
356
+ task_file.write_text(prompt + "\n")
357
+ return task_file
358
+
359
+
347
360
  def _format_env_prefix(env: dict[str, str]) -> str:
348
361
  """Format environment variables as shell prefix.
349
362
 
@@ -627,6 +640,11 @@ def new( # noqa: PLR0912, PLR0915
627
640
  # Only warn if user explicitly requested direnv
628
641
  _warn("direnv not installed, skipping .envrc setup")
629
642
 
643
+ # Write prompt to worktree (makes task available to the spawned agent)
644
+ if prompt:
645
+ task_file = _write_prompt_to_worktree(result.path, prompt)
646
+ _success(f"Wrote task to {task_file.relative_to(result.path)}")
647
+
630
648
  # Resolve editor and agent
631
649
  resolved_editor = _resolve_editor(editor, editor_name, default_editor)
632
650
  resolved_agent = _resolve_agent(agent, agent_name, default_agent)
@@ -1039,6 +1057,11 @@ def start_agent(
1039
1057
  if not agent.is_available():
1040
1058
  _error(f"{agent.name} is not installed. Install from: {agent.install_url}")
1041
1059
 
1060
+ # Write prompt to worktree (makes task available to the agent)
1061
+ if prompt:
1062
+ task_file = _write_prompt_to_worktree(wt.path, prompt)
1063
+ _success(f"Wrote task to {task_file.relative_to(wt.path)}")
1064
+
1042
1065
  merged_args = _merge_agent_args(agent, agent_args)
1043
1066
  agent_env = _get_agent_env(agent)
1044
1067
  _info(f"Starting {agent.name} in {wt.path}...")
@@ -47,8 +47,9 @@ agent-cli dev new <branch-name> --agent --prompt-file path/to/prompt.md
47
47
  This creates:
48
48
  1. A new git worktree with its own branch
49
49
  2. Runs project setup (installs dependencies)
50
- 3. Opens a new terminal tab with an AI coding agent
51
- 4. Passes your prompt to the agent
50
+ 3. Saves your prompt to `.claude/TASK.md` in the worktree (for reference)
51
+ 4. Opens a new terminal tab with an AI coding agent
52
+ 5. Passes your prompt to the agent
52
53
 
53
54
  **Important**: Use `--prompt-file` for prompts longer than a single line. The `--prompt` option passes text through the shell, which can cause issues with special characters (exclamation marks, dollar signs, backticks, quotes) in ZSH and other shells. Using `--prompt-file` avoids all shell quoting issues.
54
55
 
@@ -25,6 +25,7 @@ LOGGER = logging.getLogger(__name__)
25
25
 
26
26
  _DEFAULT_MMR_LAMBDA = 0.7
27
27
  _SUMMARY_ROLE = "summary"
28
+ _MIN_MAX_EPSILON = 1e-8 # Avoid division by zero in min-max normalization
28
29
 
29
30
 
30
31
  def gather_relevant_existing_memories(
@@ -135,7 +136,7 @@ def retrieve_memory(
135
136
  include_summary: bool = True,
136
137
  mmr_lambda: float = _DEFAULT_MMR_LAMBDA,
137
138
  recency_weight: float = 0.2,
138
- score_threshold: float = 0.35,
139
+ score_threshold: float | None = None,
139
140
  filters: dict[str, Any] | None = None,
140
141
  ) -> tuple[MemoryRetrieval, list[str]]:
141
142
  """Execute search + rerank + recency + MMR."""
@@ -161,8 +162,15 @@ def retrieve_memory(
161
162
  seen_ids.add(rec_id)
162
163
  raw_candidates.append(rec)
163
164
 
164
- def _sigmoid(x: float) -> float:
165
- return 1.0 / (1.0 + math.exp(-x))
165
+ def _min_max_normalize(scores: list[float]) -> list[float]:
166
+ """Normalize scores to 0-1 range using min-max scaling."""
167
+ if not scores:
168
+ return scores
169
+ min_score = min(scores)
170
+ max_score = max(scores)
171
+ if max_score - min_score < _MIN_MAX_EPSILON:
172
+ return [0.5] * len(scores) # All scores equal
173
+ return [(s - min_score) / (max_score - min_score) for s in scores]
166
174
 
167
175
  def recency_score(meta: MemoryMetadata) -> float:
168
176
  dt = datetime.fromisoformat(meta.created_at)
@@ -176,10 +184,12 @@ def retrieve_memory(
176
184
  if raw_candidates:
177
185
  pairs = [(query, mem.content) for mem in raw_candidates]
178
186
  rr_scores = predict_relevance(reranker_model, pairs)
179
- for mem, rr in zip(raw_candidates, rr_scores, strict=False):
180
- relevance = _sigmoid(rr)
181
- # Filter out low-relevance memories to reduce noise
182
- if relevance < score_threshold:
187
+ # Normalize raw reranker scores to 0-1 range
188
+ normalized_scores = _min_max_normalize(rr_scores)
189
+
190
+ for mem, relevance in zip(raw_candidates, normalized_scores, strict=False):
191
+ # Filter out low-relevance memories if threshold is set
192
+ if score_threshold is not None and relevance < score_threshold:
183
193
  continue
184
194
 
185
195
  recency = recency_score(mem.metadata)
@@ -235,7 +245,7 @@ async def augment_chat_request(
235
245
  include_global: bool = True,
236
246
  mmr_lambda: float = _DEFAULT_MMR_LAMBDA,
237
247
  recency_weight: float = 0.2,
238
- score_threshold: float = 0.35,
248
+ score_threshold: float | None = None,
239
249
  filters: dict[str, Any] | None = None,
240
250
  ) -> tuple[ChatRequest, MemoryRetrieval | None, str, list[str]]:
241
251
  """Retrieve memory context and augment the chat request."""
agent_cli/memory/api.py CHANGED
@@ -30,7 +30,7 @@ def create_app(
30
30
  max_entries: int = 500,
31
31
  mmr_lambda: float = 0.7,
32
32
  recency_weight: float = 0.2,
33
- score_threshold: float = 0.35,
33
+ score_threshold: float | None = None,
34
34
  enable_git_versioning: bool = True,
35
35
  ) -> FastAPI:
36
36
  """Create the FastAPI app for memory-backed chat."""
@@ -49,7 +49,7 @@ class MemoryClient:
49
49
  max_entries: int = 500,
50
50
  mmr_lambda: float = 0.7,
51
51
  recency_weight: float = 0.2,
52
- score_threshold: float = 0.35,
52
+ score_threshold: float | None = None,
53
53
  start_watcher: bool = False,
54
54
  enable_git_versioning: bool = True,
55
55
  ) -> None:
@@ -236,7 +236,7 @@ async def process_chat_request(
236
236
  max_entries: int = _DEFAULT_MAX_ENTRIES,
237
237
  mmr_lambda: float = _DEFAULT_MMR_LAMBDA,
238
238
  recency_weight: float = 0.2,
239
- score_threshold: float = 0.35,
239
+ score_threshold: float | None = None,
240
240
  postprocess_in_background: bool = True,
241
241
  enable_git_versioning: bool = False,
242
242
  filters: dict[str, Any] | None = None,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent-cli
3
- Version: 0.62.0
3
+ Version: 0.63.0
4
4
  Summary: A suite of AI-powered command-line tools for text correction, audio transcription, and voice assistance.
5
5
  Project-URL: Homepage, https://github.com/basnijholt/agent-cli
6
6
  Author-email: Bas Nijholt <bas@nijho.lt>
@@ -37,7 +37,7 @@ agent_cli/core/utils.py,sha256=MHttXeGiM9qGUNxK0s6vAHthh033TDjaruqocdtMMFY,16802
37
37
  agent_cli/core/vad.py,sha256=67-EBjY-pTOf61VhrjVdDXgaNIBwWFFFccYth_1rQmg,6569
38
38
  agent_cli/core/watch.py,sha256=MKgGxxMe0yLlu78-XXqO4ferCpu_ljNr4MAzOMDsuuo,1951
39
39
  agent_cli/dev/__init__.py,sha256=doTYiUFEBpnOxsQA69HQP9AA4QHBN0DjuHSTGRq5Xbg,551
40
- agent_cli/dev/cli.py,sha256=dQwLqrAwLUhg7iAFmlMfdMS60W-WjrWWDD01yxFqrpU,51223
40
+ agent_cli/dev/cli.py,sha256=KH5RYAwJLSArnXDrccDmFN7OV1C9kwLHwoHWIiJfCHQ,52120
41
41
  agent_cli/dev/project.py,sha256=wJMGKTK1rmw8letrV6l6wcLU1fkQQDjCSEixAnsvyaY,18971
42
42
  agent_cli/dev/registry.py,sha256=c6t3ClyRFPvU4GGXJT79-D-qV4FqY7W_7P-tLT7LKZs,1887
43
43
  agent_cli/dev/worktree.py,sha256=Yw8jlhkf8BeKFc6pPEazGXnUIvryvYwbUmYxTluXILs,26916
@@ -64,7 +64,7 @@ agent_cli/dev/editors/sublime.py,sha256=owEfRSMuArSeFKqk-LE2JOXaZy5QlQfHQ-l0I4k2
64
64
  agent_cli/dev/editors/vim.py,sha256=Fo-IQMPVbIiwBdOfmkFxR37f96QW6xc5LV3Pvr3u-b0,1378
65
65
  agent_cli/dev/editors/vscode.py,sha256=GOrl4FwVdDyuSn7t4lglgnVt_T6NtpjLVh1OWBxDMwE,318
66
66
  agent_cli/dev/editors/zed.py,sha256=lRMhdN_SKmHBA1ulx8x-p7Th_0EGSIv6ppAE84xobU4,515
67
- agent_cli/dev/skill/SKILL.md,sha256=Guod9r9in3FFmYeUoXbLCosP3JtnOzssjnJ75NacadU,4347
67
+ agent_cli/dev/skill/SKILL.md,sha256=r_QoJR5VLrsI7h-oopfJ8o89oWM43EHgy8IYYa52q9c,4421
68
68
  agent_cli/dev/skill/examples.md,sha256=ZzCyfudBk4lMR-sz8ER9l5vi6hI3HTeUlvQorRFVol4,16405
69
69
  agent_cli/dev/terminals/__init__.py,sha256=yUTNtvs1Do2hvhx56XxyfI-5HA5mjiv0IbJuuaL9TeE,371
70
70
  agent_cli/dev/terminals/apple_terminal.py,sha256=s7GdxXPgbpSLKK1DUwjNpshQpjR5Nt1QbL_cKPefIRI,2595
@@ -88,13 +88,13 @@ agent_cli/memory/_indexer.py,sha256=iWIRG61g2O4_cUjJYDXe03hkpRO5kVAqOwDeCb7Efu0,
88
88
  agent_cli/memory/_ingest.py,sha256=_WeFLTxrlWKFpyB1KR0tUWLgEq-eevB8ytAgpq6BOlY,13649
89
89
  agent_cli/memory/_persistence.py,sha256=7TsphuYsJfJbp-294IvWmtW98G_Sag9GTm8AUGU9dtQ,5401
90
90
  agent_cli/memory/_prompt.py,sha256=ncvYM5ewLrYRP8KizdFHtPQl2cWYg0SW0VQxA8rz_9E,4667
91
- agent_cli/memory/_retrieval.py,sha256=szQxy1OyjetyvidUsyyijtOiYEXFk21rvBpses9r3Po,9211
91
+ agent_cli/memory/_retrieval.py,sha256=K_2TUcgzfntBARPyf0K6VR3NIgHHJrqGFMP_53Nae_w,9778
92
92
  agent_cli/memory/_store.py,sha256=m9mD1GxjdTXpnyL-X-MIU4cj28unqxJ_azV3kwM8blM,5086
93
93
  agent_cli/memory/_streaming.py,sha256=-WlOPtH61ogCSJKQRpfYHp2gBgIIN6hIJqb5padjmpw,1379
94
94
  agent_cli/memory/_tasks.py,sha256=XgEkN_3NCVQDWafZ_rqazpAE68yQ87x-amnQKMkfPXg,1469
95
- agent_cli/memory/api.py,sha256=sRLvidQeg-ooxHIDHvYkkbGof-CLKvMXjdviyRU12Do,3588
96
- agent_cli/memory/client.py,sha256=QWzY562nLr0OlpOW2vaArzALMWLxy-vv6H-DJgJ08n0,9987
97
- agent_cli/memory/engine.py,sha256=V6QURnnKvvAN4hW8tuGkbgLaMbo4NB7_jdpZg0mC6n0,11649
95
+ agent_cli/memory/api.py,sha256=riaGTOIw7g3KuDNcPtDy9wO44-D1wDtVadRj3RTT10k,3595
96
+ agent_cli/memory/client.py,sha256=XomHhP-hPSoosORkBKSY1dW3gjheFEVqAac0b-tAULo,9994
97
+ agent_cli/memory/engine.py,sha256=rABVC86b5wU1QxY3BM43RhvfDOxoRT7Ddm98BN_qCL4,11656
98
98
  agent_cli/memory/entities.py,sha256=_8wyJz--tNa66CEtSpl2TUN_zeHQvMzm42htnDaOr6g,1219
99
99
  agent_cli/memory/models.py,sha256=KK0wToEf-tXssYVL0hYaJlcADlJ3G2lcSXwo1UmA0VU,2352
100
100
  agent_cli/rag/__init__.py,sha256=suQDSGBUlt4_KNxz2CyVqrJw58e64T3ltfmmg2F8iQY,543
@@ -172,8 +172,8 @@ agent_cli/services/asr.py,sha256=V6SV-USnMhK-0aE-pneiktU4HpmLqenmMb-jZ-_74zU,169
172
172
  agent_cli/services/llm.py,sha256=Kwdo6pbMYI9oykF-RBe1iaL3KsYrNWTLdRSioewmsGQ,7199
173
173
  agent_cli/services/tts.py,sha256=exKo-55_670mx8dQOzVSZkv6aWYLv04SVmBcjOlD458,14772
174
174
  agent_cli/services/wake_word.py,sha256=j6Z8rsGq_vAdRevy9fkXIgLZd9UWfrIsefmTreNmM0c,4575
175
- agent_cli-0.62.0.dist-info/METADATA,sha256=9NRk688EZxkuThkRJOahxw-ZH6Y2yQsVHuYMpK5Qm2A,151909
176
- agent_cli-0.62.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
177
- agent_cli-0.62.0.dist-info/entry_points.txt,sha256=FUv-fB2atLsPUk_RT4zqnZl1coz4_XHFwRALOKOF38s,97
178
- agent_cli-0.62.0.dist-info/licenses/LICENSE,sha256=majJU6S9kC8R8bW39NVBHyv32Dq50FL6TDxECG2WVts,1068
179
- agent_cli-0.62.0.dist-info/RECORD,,
175
+ agent_cli-0.63.0.dist-info/METADATA,sha256=h6K2iJsMSndMhIyJyLa2pPtRmTmZeZvrpbTqsQuqYsA,151909
176
+ agent_cli-0.63.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
177
+ agent_cli-0.63.0.dist-info/entry_points.txt,sha256=FUv-fB2atLsPUk_RT4zqnZl1coz4_XHFwRALOKOF38s,97
178
+ agent_cli-0.63.0.dist-info/licenses/LICENSE,sha256=majJU6S9kC8R8bW39NVBHyv32Dq50FL6TDxECG2WVts,1068
179
+ agent_cli-0.63.0.dist-info/RECORD,,