npcsh 1.1.20__py3-none-any.whl → 1.1.22__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.
- npcsh/_state.py +15 -76
- npcsh/benchmark/npcsh_agent.py +22 -14
- npcsh/benchmark/templates/install-npcsh.sh.j2 +2 -2
- npcsh/diff_viewer.py +3 -3
- npcsh/mcp_server.py +9 -1
- npcsh/npc_team/alicanto.npc +12 -6
- npcsh/npc_team/corca.npc +0 -1
- npcsh/npc_team/frederic.npc +2 -3
- npcsh/npc_team/jinxs/lib/core/compress.jinx +373 -85
- npcsh/npc_team/jinxs/lib/core/edit_file.jinx +83 -61
- npcsh/npc_team/jinxs/lib/core/search/db_search.jinx +17 -6
- npcsh/npc_team/jinxs/lib/core/search/file_search.jinx +17 -6
- npcsh/npc_team/jinxs/lib/core/search/web_search.jinx +52 -14
- npcsh/npc_team/jinxs/{bin → lib/utils}/benchmark.jinx +2 -2
- npcsh/npc_team/jinxs/{bin → lib/utils}/jinxs.jinx +12 -12
- npcsh/npc_team/jinxs/{bin → lib/utils}/models.jinx +7 -7
- npcsh/npc_team/jinxs/{bin → lib/utils}/setup.jinx +6 -6
- npcsh/npc_team/jinxs/modes/alicanto.jinx +1633 -295
- npcsh/npc_team/jinxs/modes/arxiv.jinx +5 -5
- npcsh/npc_team/jinxs/modes/build.jinx +378 -0
- npcsh/npc_team/jinxs/modes/config_tui.jinx +300 -0
- npcsh/npc_team/jinxs/modes/convene.jinx +597 -0
- npcsh/npc_team/jinxs/modes/corca.jinx +777 -387
- npcsh/npc_team/jinxs/modes/git.jinx +795 -0
- {npcsh-1.1.20.data/data/npcsh/npc_team → npcsh/npc_team/jinxs/modes}/kg.jinx +82 -15
- npcsh/npc_team/jinxs/modes/memories.jinx +414 -0
- npcsh/npc_team/jinxs/{bin → modes}/nql.jinx +10 -21
- npcsh/npc_team/jinxs/modes/papers.jinx +578 -0
- npcsh/npc_team/jinxs/modes/plonk.jinx +503 -308
- npcsh/npc_team/jinxs/modes/reattach.jinx +3 -3
- npcsh/npc_team/jinxs/modes/spool.jinx +3 -3
- npcsh/npc_team/jinxs/{bin → modes}/team.jinx +12 -12
- npcsh/npc_team/jinxs/modes/vixynt.jinx +388 -0
- npcsh/npc_team/jinxs/modes/wander.jinx +454 -181
- npcsh/npc_team/jinxs/modes/yap.jinx +630 -182
- npcsh/npc_team/kadiefa.npc +2 -1
- npcsh/npc_team/sibiji.npc +3 -3
- npcsh/npcsh.py +112 -47
- npcsh/routes.py +4 -1
- npcsh/salmon_simulation.py +0 -0
- npcsh-1.1.22.data/data/npcsh/npc_team/alicanto.jinx +1694 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/alicanto.npc +12 -6
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/arxiv.jinx +5 -5
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/benchmark.jinx +2 -2
- npcsh-1.1.22.data/data/npcsh/npc_team/build.jinx +378 -0
- npcsh-1.1.22.data/data/npcsh/npc_team/compress.jinx +428 -0
- npcsh-1.1.22.data/data/npcsh/npc_team/config_tui.jinx +300 -0
- npcsh-1.1.22.data/data/npcsh/npc_team/corca.jinx +820 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/corca.npc +0 -1
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/db_search.jinx +17 -6
- npcsh-1.1.22.data/data/npcsh/npc_team/edit_file.jinx +119 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/file_search.jinx +17 -6
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/frederic.npc +2 -3
- npcsh-1.1.22.data/data/npcsh/npc_team/git.jinx +795 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/jinxs.jinx +12 -12
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/kadiefa.npc +2 -1
- {npcsh/npc_team/jinxs/bin → npcsh-1.1.22.data/data/npcsh/npc_team}/kg.jinx +82 -15
- npcsh-1.1.22.data/data/npcsh/npc_team/memories.jinx +414 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/models.jinx +7 -7
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/nql.jinx +10 -21
- npcsh-1.1.22.data/data/npcsh/npc_team/papers.jinx +578 -0
- npcsh-1.1.22.data/data/npcsh/npc_team/plonk.jinx +574 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/reattach.jinx +3 -3
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/setup.jinx +6 -6
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/sibiji.npc +3 -3
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/spool.jinx +3 -3
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/team.jinx +12 -12
- npcsh-1.1.22.data/data/npcsh/npc_team/vixynt.jinx +388 -0
- npcsh-1.1.22.data/data/npcsh/npc_team/wander.jinx +728 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/web_search.jinx +52 -14
- npcsh-1.1.22.data/data/npcsh/npc_team/yap.jinx +716 -0
- {npcsh-1.1.20.dist-info → npcsh-1.1.22.dist-info}/METADATA +246 -281
- npcsh-1.1.22.dist-info/RECORD +240 -0
- npcsh-1.1.22.dist-info/entry_points.txt +11 -0
- npcsh/npc_team/jinxs/bin/config_tui.jinx +0 -300
- npcsh/npc_team/jinxs/bin/memories.jinx +0 -317
- npcsh/npc_team/jinxs/bin/vixynt.jinx +0 -122
- npcsh/npc_team/jinxs/lib/core/search/kg_search.jinx +0 -418
- npcsh/npc_team/jinxs/lib/core/search/mem_review.jinx +0 -73
- npcsh/npc_team/jinxs/lib/core/search/mem_search.jinx +0 -388
- npcsh/npc_team/jinxs/lib/core/search.jinx +0 -54
- npcsh/npc_team/jinxs/lib/research/paper_search.jinx +0 -412
- npcsh/npc_team/jinxs/lib/research/semantic_scholar.jinx +0 -386
- npcsh/npc_team/jinxs/lib/utils/build.jinx +0 -65
- npcsh/npc_team/plonkjr.npc +0 -23
- npcsh-1.1.20.data/data/npcsh/npc_team/alicanto.jinx +0 -356
- npcsh-1.1.20.data/data/npcsh/npc_team/build.jinx +0 -65
- npcsh-1.1.20.data/data/npcsh/npc_team/compress.jinx +0 -140
- npcsh-1.1.20.data/data/npcsh/npc_team/config_tui.jinx +0 -300
- npcsh-1.1.20.data/data/npcsh/npc_team/corca.jinx +0 -430
- npcsh-1.1.20.data/data/npcsh/npc_team/edit_file.jinx +0 -97
- npcsh-1.1.20.data/data/npcsh/npc_team/kg_search.jinx +0 -418
- npcsh-1.1.20.data/data/npcsh/npc_team/mem_review.jinx +0 -73
- npcsh-1.1.20.data/data/npcsh/npc_team/mem_search.jinx +0 -388
- npcsh-1.1.20.data/data/npcsh/npc_team/memories.jinx +0 -317
- npcsh-1.1.20.data/data/npcsh/npc_team/paper_search.jinx +0 -412
- npcsh-1.1.20.data/data/npcsh/npc_team/plonk.jinx +0 -379
- npcsh-1.1.20.data/data/npcsh/npc_team/plonkjr.npc +0 -23
- npcsh-1.1.20.data/data/npcsh/npc_team/search.jinx +0 -54
- npcsh-1.1.20.data/data/npcsh/npc_team/semantic_scholar.jinx +0 -386
- npcsh-1.1.20.data/data/npcsh/npc_team/vixynt.jinx +0 -122
- npcsh-1.1.20.data/data/npcsh/npc_team/wander.jinx +0 -455
- npcsh-1.1.20.data/data/npcsh/npc_team/yap.jinx +0 -268
- npcsh-1.1.20.dist-info/RECORD +0 -248
- npcsh-1.1.20.dist-info/entry_points.txt +0 -25
- /npcsh/npc_team/jinxs/lib/{orchestration → core}/convene.jinx +0 -0
- /npcsh/npc_team/jinxs/lib/{orchestration → core}/delegate.jinx +0 -0
- /npcsh/npc_team/jinxs/{bin → lib/core}/sample.jinx +0 -0
- /npcsh/npc_team/jinxs/lib/{core → utils}/chat.jinx +0 -0
- /npcsh/npc_team/jinxs/lib/{core → utils}/cmd.jinx +0 -0
- /npcsh/npc_team/jinxs/{bin → lib/utils}/sync.jinx +0 -0
- /npcsh/npc_team/jinxs/{bin → modes}/roll.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/add_tab.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/alicanto.png +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/browser_action.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/browser_screenshot.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/chat.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/click.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/close_browser.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/close_pane.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/close_tab.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/cmd.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/compile.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/confirm.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/convene.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/corca.png +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/corca_example.png +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/delegate.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/focus_pane.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/frederic4.png +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/guac.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/guac.npc +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/guac.png +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/help.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/incognide.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/init.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/kadiefa.png +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/key_press.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/launch_app.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/list_panes.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/load_file.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/navigate.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/notify.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/npcsh.ctx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/npcsh_sibiji.png +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/open_browser.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/open_pane.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/ots.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/paste.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/plonk.npc +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/plonk.png +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/plonkjr.png +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/pti.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/python.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/read_pane.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/roll.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/run_terminal.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/sample.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/screenshot.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/send_message.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/serve.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/set.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/sh.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/shh.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/sibiji.png +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/sleep.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/split_pane.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/spool.png +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/sql.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/switch.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/switch_npc.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/switch_tab.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/switches.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/sync.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/teamviz.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/trigger.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/type_text.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/usage.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/verbose.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/wait.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/write_file.jinx +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/yap.png +0 -0
- {npcsh-1.1.20.data → npcsh-1.1.22.data}/data/npcsh/npc_team/zen_mode.jinx +0 -0
- {npcsh-1.1.20.dist-info → npcsh-1.1.22.dist-info}/WHEEL +0 -0
- {npcsh-1.1.20.dist-info → npcsh-1.1.22.dist-info}/licenses/LICENSE +0 -0
- {npcsh-1.1.20.dist-info → npcsh-1.1.22.dist-info}/top_level.txt +0 -0
npcsh/_state.py
CHANGED
|
@@ -2537,19 +2537,16 @@ def collect_llm_tools(state: ShellState) -> Tuple[List[Dict[str, Any]], Dict[str
|
|
|
2537
2537
|
elif npc_obj and getattr(npc_obj, "tool_map", None):
|
|
2538
2538
|
tool_map.update(npc_obj.tool_map)
|
|
2539
2539
|
|
|
2540
|
-
# Jinx tools from NPC
|
|
2540
|
+
# Jinx tools from NPC only (NPC.jinxs_dict is already filtered by jinxs_spec
|
|
2541
|
+
# during initialize_jinxs - don't add the full team catalog which overwhelms small models)
|
|
2541
2542
|
aggregated_jinxs: Dict[str, Any] = {}
|
|
2542
2543
|
if npc_obj and getattr(npc_obj, "jinxs_dict", None):
|
|
2543
2544
|
aggregated_jinxs.update(npc_obj.jinxs_dict)
|
|
2544
|
-
if state.team and isinstance(state.team, Team) and getattr(state.team, "jinxs_dict", None):
|
|
2545
|
-
aggregated_jinxs.update({k: v for k, v in state.team.jinxs_dict.items() if k not in aggregated_jinxs})
|
|
2546
2545
|
|
|
2547
2546
|
if aggregated_jinxs:
|
|
2548
2547
|
jinx_catalog: Dict[str, Dict[str, Any]] = {}
|
|
2549
2548
|
if npc_obj and getattr(npc_obj, "jinx_tool_catalog", None):
|
|
2550
2549
|
jinx_catalog.update(npc_obj.jinx_tool_catalog or {})
|
|
2551
|
-
if state.team and isinstance(state.team, Team) and getattr(state.team, "jinx_tool_catalog", None):
|
|
2552
|
-
jinx_catalog.update(state.team.jinx_tool_catalog or {})
|
|
2553
2550
|
if not jinx_catalog:
|
|
2554
2551
|
jinx_catalog = build_jinx_tool_catalog(aggregated_jinxs)
|
|
2555
2552
|
|
|
@@ -2898,6 +2895,14 @@ def process_pipeline_command(
|
|
|
2898
2895
|
tools_for_llm, tool_exec_map = collect_llm_tools(state)
|
|
2899
2896
|
if not tools_for_llm:
|
|
2900
2897
|
tool_capable = False
|
|
2898
|
+
else:
|
|
2899
|
+
# Add tool guidance so model knows to use function calls
|
|
2900
|
+
tool_names = [t['function']['name'] for t in tools_for_llm if 'function' in t]
|
|
2901
|
+
info += (
|
|
2902
|
+
f"\nYou have access to these tools: {', '.join(tool_names)}. "
|
|
2903
|
+
f"You MUST use the function calling interface to invoke them. "
|
|
2904
|
+
f"Do NOT write tool names as text - call them as functions."
|
|
2905
|
+
)
|
|
2901
2906
|
|
|
2902
2907
|
npc_name = (
|
|
2903
2908
|
state.npc.name
|
|
@@ -3444,9 +3449,9 @@ def setup_shell() -> Tuple[CommandHistory, Team, Optional[NPC]]:
|
|
|
3444
3449
|
command_history = CommandHistory(db_path)
|
|
3445
3450
|
|
|
3446
3451
|
if not is_npcsh_initialized():
|
|
3447
|
-
print("
|
|
3452
|
+
print("Setting up npcsh for first use...")
|
|
3448
3453
|
initialize_base_npcs_if_needed(db_path)
|
|
3449
|
-
print("
|
|
3454
|
+
print("Setup complete.")
|
|
3450
3455
|
|
|
3451
3456
|
try:
|
|
3452
3457
|
setup_readline()
|
|
@@ -3458,80 +3463,17 @@ def setup_shell() -> Tuple[CommandHistory, Team, Optional[NPC]]:
|
|
|
3458
3463
|
project_team_path = os.path.abspath(PROJECT_NPC_TEAM_PATH)
|
|
3459
3464
|
global_team_path = os.path.expanduser(DEFAULT_NPC_TEAM_PATH)
|
|
3460
3465
|
|
|
3461
|
-
team_dir = None
|
|
3462
|
-
default_forenpc_name = None
|
|
3463
|
-
global_team_path = os.path.expanduser(DEFAULT_NPC_TEAM_PATH)
|
|
3464
3466
|
if not os.path.exists(global_team_path):
|
|
3465
|
-
print("Global NPC team directory doesn't exist. Initializing...")
|
|
3466
3467
|
initialize_base_npcs_if_needed(db_path)
|
|
3467
3468
|
if os.path.exists(project_team_path):
|
|
3468
3469
|
team_dir = project_team_path
|
|
3469
3470
|
default_forenpc_name = "forenpc"
|
|
3470
3471
|
else:
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
resp = input(f"No npc_team found in {os.getcwd()}. Create a new team here? [Y/n]: ").strip().lower()
|
|
3474
|
-
except (KeyboardInterrupt, EOFError):
|
|
3475
|
-
print("\nAborted.")
|
|
3476
|
-
sys.exit(0)
|
|
3477
|
-
if resp in ("", "y", "yes"):
|
|
3478
|
-
team_dir = project_team_path
|
|
3479
|
-
os.makedirs(team_dir, exist_ok=True)
|
|
3480
|
-
default_forenpc_name = "forenpc"
|
|
3481
|
-
try:
|
|
3482
|
-
forenpc_directive = input(
|
|
3483
|
-
f"Enter a primary directive for {default_forenpc_name} (default: 'You are the forenpc of the team...'): "
|
|
3484
|
-
).strip() or "You are the forenpc of the team, coordinating activities between NPCs on the team, verifying that results from NPCs are high quality and can help to adequately answer user requests."
|
|
3485
|
-
forenpc_model = input("Enter a model for your forenpc (default: llama3.2): ").strip() or "llama3.2"
|
|
3486
|
-
forenpc_provider = input("Enter a provider for your forenpc (default: ollama): ").strip() or "ollama"
|
|
3487
|
-
except (KeyboardInterrupt, EOFError):
|
|
3488
|
-
print("\nAborted.")
|
|
3489
|
-
sys.exit(0)
|
|
3490
|
-
|
|
3491
|
-
with open(os.path.join(team_dir, f"{default_forenpc_name}.npc"), "w") as f:
|
|
3492
|
-
yaml.dump({
|
|
3493
|
-
"name": default_forenpc_name, "primary_directive": forenpc_directive,
|
|
3494
|
-
"model": forenpc_model, "provider": forenpc_provider
|
|
3495
|
-
}, f)
|
|
3496
|
-
|
|
3497
|
-
ctx_path = os.path.join(team_dir, "team.ctx")
|
|
3498
|
-
try:
|
|
3499
|
-
folder_context = input("Enter a short description for this project/team (optional): ").strip()
|
|
3500
|
-
team_ctx_data = {
|
|
3501
|
-
"forenpc": default_forenpc_name,
|
|
3502
|
-
"model": forenpc_model,
|
|
3503
|
-
"provider": forenpc_provider,
|
|
3504
|
-
"context": folder_context if folder_context else None
|
|
3505
|
-
}
|
|
3506
|
-
use_jinxs = input("Use global jinxs folder (g) or copy to this project (c)? [g/c, default: g]: ").strip().lower()
|
|
3507
|
-
except (KeyboardInterrupt, EOFError):
|
|
3508
|
-
print("\nAborted.")
|
|
3509
|
-
sys.exit(0)
|
|
3510
|
-
if use_jinxs == "c":
|
|
3511
|
-
global_jinxs_dir = os.path.expanduser("~/.npcsh/npc_team/jinxs")
|
|
3512
|
-
if os.path.exists(global_jinxs_dir):
|
|
3513
|
-
# Create the 'jinxs' subfolder within the new team's directory
|
|
3514
|
-
destination_jinxs_dir = os.path.join(team_dir, "jinxs")
|
|
3515
|
-
os.makedirs(destination_jinxs_dir, exist_ok=True)
|
|
3516
|
-
shutil.copytree(global_jinxs_dir, destination_jinxs_dir, dirs_exist_ok=True)
|
|
3517
|
-
else:
|
|
3518
|
-
team_ctx_data["use_global_jinxs"] = True
|
|
3519
|
-
with open(ctx_path, "w") as f:
|
|
3520
|
-
yaml.dump(team_ctx_data, f)
|
|
3521
|
-
else:
|
|
3522
|
-
render_markdown('From now on, npcsh will assume you will use the global team when activating from this folder. \n If you change your mind and want to initialize a team, use /init from within npcsh, `npc init` or `rm .npcsh_global` from the current working directory.')
|
|
3523
|
-
with open(".npcsh_global", "w") as f:
|
|
3524
|
-
pass
|
|
3525
|
-
team_dir = global_team_path
|
|
3526
|
-
default_forenpc_name = "sibiji"
|
|
3527
|
-
else:
|
|
3528
|
-
team_dir = global_team_path
|
|
3529
|
-
default_forenpc_name = "sibiji"
|
|
3530
|
-
|
|
3531
|
-
if team_dir is None:
|
|
3472
|
+
# No project team in this directory - use global team.
|
|
3473
|
+
# To create a project team, use /init from within npcsh or `npc init`.
|
|
3532
3474
|
team_dir = global_team_path
|
|
3533
3475
|
default_forenpc_name = "sibiji"
|
|
3534
|
-
|
|
3476
|
+
|
|
3535
3477
|
if not os.path.exists(team_dir):
|
|
3536
3478
|
print(f"Creating team directory: {team_dir}")
|
|
3537
3479
|
os.makedirs(team_dir, exist_ok=True)
|
|
@@ -3548,11 +3490,8 @@ def setup_shell() -> Tuple[CommandHistory, Team, Optional[NPC]]:
|
|
|
3548
3490
|
forenpc_name = team_ctx.get("forenpc", default_forenpc_name)
|
|
3549
3491
|
if forenpc_name is None:
|
|
3550
3492
|
forenpc_name = "sibiji"
|
|
3551
|
-
|
|
3552
|
-
print('forenpc_name:', forenpc_name)
|
|
3553
3493
|
|
|
3554
3494
|
forenpc_path = os.path.join(team_dir, f"{forenpc_name}.npc")
|
|
3555
|
-
print('forenpc_path:', forenpc_path)
|
|
3556
3495
|
|
|
3557
3496
|
team = Team(team_path=team_dir, db_conn=command_history.engine)
|
|
3558
3497
|
|
npcsh/benchmark/npcsh_agent.py
CHANGED
|
@@ -53,11 +53,11 @@ class NpcshAgent(BaseInstalledAgent):
|
|
|
53
53
|
Returns:
|
|
54
54
|
List of ExecInput commands to execute
|
|
55
55
|
"""
|
|
56
|
-
# Wrap the instruction with
|
|
57
|
-
tool_instruction = f"""You have access to
|
|
56
|
+
# Wrap the instruction with tool usage directions and retry logic
|
|
57
|
+
tool_instruction = f"""You have access to tools: edit_file (for writing/creating files), sh (for running shell commands), and python (for running Python code).
|
|
58
58
|
|
|
59
59
|
IMPORTANT RULES:
|
|
60
|
-
1. You MUST
|
|
60
|
+
1. You MUST call these tools using the function calling interface to complete the task. Do NOT write tool names as text - invoke them as function calls.
|
|
61
61
|
2. After implementing a solution, you MUST verify it works by running any provided test scripts.
|
|
62
62
|
3. If a test fails or produces an error, you MUST try a DIFFERENT approach. Do not give up.
|
|
63
63
|
4. Keep trying different approaches until you succeed or have tried at least 10 different solutions.
|
|
@@ -66,13 +66,11 @@ IMPORTANT RULES:
|
|
|
66
66
|
Task: {instruction}
|
|
67
67
|
|
|
68
68
|
WORKFLOW:
|
|
69
|
-
1.
|
|
69
|
+
1. Call edit_file to write code files. Call sh to run commands.
|
|
70
70
|
2. Run any test scripts mentioned in the task
|
|
71
71
|
3. Check the output carefully - look for "PASS", "SUCCESS", "OK" or similar
|
|
72
72
|
4. If the test failed, analyze why and try a completely different approach
|
|
73
|
-
5. Repeat until the test passes
|
|
74
|
-
|
|
75
|
-
Remember: Use edit_file to write code files. Use sh to run commands. VERIFY your solution works before concluding."""
|
|
73
|
+
5. Repeat until the test passes"""
|
|
76
74
|
|
|
77
75
|
escaped_instruction = shlex.quote(tool_instruction)
|
|
78
76
|
model_name = self.model_name
|
|
@@ -146,8 +144,14 @@ Remember: Use edit_file to write code files. Use sh to run commands. VERIFY your
|
|
|
146
144
|
# Using corca NPC which has edit_file tool for writing files
|
|
147
145
|
# Using the npc CLI which supports single-command execution
|
|
148
146
|
# NPCSH_DEFAULT_MODE=agent enables automatic tool execution
|
|
147
|
+
ollama_env = ""
|
|
148
|
+
if npcsh_provider == "ollama":
|
|
149
|
+
ollama_host = os.environ.get("OLLAMA_HOST", "http://host.docker.internal:11434")
|
|
150
|
+
ollama_env = f'OLLAMA_HOST="{ollama_host}" '
|
|
151
|
+
|
|
149
152
|
npcsh_cmd = (
|
|
150
153
|
f'{env_prefix}'
|
|
154
|
+
f'{ollama_env}'
|
|
151
155
|
f'NPCSH_CHAT_MODEL="{model}" '
|
|
152
156
|
f'NPCSH_CHAT_PROVIDER="{npcsh_provider}" '
|
|
153
157
|
f'NPCSH_STREAM_OUTPUT=0 '
|
|
@@ -234,11 +238,11 @@ class NpcshAgentWithNpc(NpcshAgent):
|
|
|
234
238
|
|
|
235
239
|
def create_run_agent_commands(self, instruction: str) -> list:
|
|
236
240
|
"""Create commands using a specific NPC."""
|
|
237
|
-
# Wrap the instruction with
|
|
238
|
-
tool_instruction = f"""You have access to
|
|
241
|
+
# Wrap the instruction with tool usage directions and retry logic
|
|
242
|
+
tool_instruction = f"""You have access to tools: edit_file (for writing/creating files), sh (for running shell commands), and python (for running Python code).
|
|
239
243
|
|
|
240
244
|
IMPORTANT RULES:
|
|
241
|
-
1. You MUST
|
|
245
|
+
1. You MUST call these tools using the function calling interface to complete the task. Do NOT write tool names as text - invoke them as function calls.
|
|
242
246
|
2. After implementing a solution, you MUST verify it works by running any provided test scripts.
|
|
243
247
|
3. If a test fails or produces an error, you MUST try a DIFFERENT approach. Do not give up.
|
|
244
248
|
4. Keep trying different approaches until you succeed or have tried at least 10 different solutions.
|
|
@@ -247,13 +251,11 @@ IMPORTANT RULES:
|
|
|
247
251
|
Task: {instruction}
|
|
248
252
|
|
|
249
253
|
WORKFLOW:
|
|
250
|
-
1.
|
|
254
|
+
1. Call edit_file to write code files. Call sh to run commands.
|
|
251
255
|
2. Run any test scripts mentioned in the task
|
|
252
256
|
3. Check the output carefully - look for "PASS", "SUCCESS", "OK" or similar
|
|
253
257
|
4. If the test failed, analyze why and try a completely different approach
|
|
254
|
-
5. Repeat until the test passes
|
|
255
|
-
|
|
256
|
-
Remember: Use edit_file to write code files. Use sh to run commands. VERIFY your solution works before concluding."""
|
|
258
|
+
5. Repeat until the test passes"""
|
|
257
259
|
|
|
258
260
|
escaped_instruction = shlex.quote(tool_instruction)
|
|
259
261
|
model_name = self.model_name
|
|
@@ -309,8 +311,14 @@ Remember: Use edit_file to write code files. Use sh to run commands. VERIFY your
|
|
|
309
311
|
|
|
310
312
|
# Use specific NPC with --npc flag
|
|
311
313
|
# NPCSH_DEFAULT_MODE=agent enables automatic tool execution
|
|
314
|
+
ollama_env = ""
|
|
315
|
+
if npcsh_provider == "ollama":
|
|
316
|
+
ollama_host = os.environ.get("OLLAMA_HOST", "http://host.docker.internal:11434")
|
|
317
|
+
ollama_env = f'OLLAMA_HOST="{ollama_host}" '
|
|
318
|
+
|
|
312
319
|
npcsh_cmd = (
|
|
313
320
|
f'{env_prefix}'
|
|
321
|
+
f'{ollama_env}'
|
|
314
322
|
f'NPCSH_CHAT_MODEL="{model}" '
|
|
315
323
|
f'NPCSH_CHAT_PROVIDER="{npcsh_provider}" '
|
|
316
324
|
f'NPCSH_STREAM_OUTPUT=0 '
|
|
@@ -14,8 +14,8 @@ fi
|
|
|
14
14
|
|
|
15
15
|
# Install npcsh with lite dependencies (API providers only, no local models)
|
|
16
16
|
# Use --break-system-packages for PEP 668 compliance (Ubuntu 24.04+)
|
|
17
|
-
echo "Installing npcsh[lite]..."
|
|
18
|
-
pip install --quiet --break-system-packages npcsh[lite] || pip install --quiet npcsh[lite]
|
|
17
|
+
echo "Installing npcsh[lite] + ollama..."
|
|
18
|
+
pip install --quiet --break-system-packages npcsh[lite] ollama || pip install --quiet npcsh[lite] ollama
|
|
19
19
|
|
|
20
20
|
# Verify installation
|
|
21
21
|
echo "Verifying npcsh installation..."
|
npcsh/diff_viewer.py
CHANGED
|
@@ -6,7 +6,7 @@ import os
|
|
|
6
6
|
import sys
|
|
7
7
|
import difflib
|
|
8
8
|
from dataclasses import dataclass, field
|
|
9
|
-
from typing import List, Dict,
|
|
9
|
+
from typing import List, Dict, Tuple
|
|
10
10
|
from enum import Enum
|
|
11
11
|
|
|
12
12
|
# Platform-specific imports
|
|
@@ -324,8 +324,8 @@ class DiffViewer:
|
|
|
324
324
|
start = hunk.start_original - 1 + offset
|
|
325
325
|
|
|
326
326
|
# Count removals and additions in this hunk
|
|
327
|
-
removals = [
|
|
328
|
-
additions = [
|
|
327
|
+
removals = [ln[1:] for ln in hunk.lines if ln.startswith('-')]
|
|
328
|
+
additions = [ln[1:] for ln in hunk.lines if ln.startswith('+')]
|
|
329
329
|
|
|
330
330
|
# Remove old lines
|
|
331
331
|
del result_lines[start:start + len(removals)]
|
npcsh/mcp_server.py
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
|
|
2
2
|
"""
|
|
3
|
-
Enhanced MCP server that incorporates functionality from npcpy.routes,
|
|
3
|
+
Enhanced MCP server that incorporates functionality from npcpy.routes,
|
|
4
4
|
npcpy.llm_funcs, and npcpy.npc_compiler as tools.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
+
# When run as a subprocess, Python adds the script directory to sys.path[0].
|
|
8
|
+
# Since this file lives inside the npcsh package, that shadows the package
|
|
9
|
+
# (npcsh.py is found instead of the npcsh/ package). Remove it.
|
|
10
|
+
import sys as _sys, os as _os
|
|
11
|
+
_script_dir = _os.path.dirname(_os.path.abspath(__file__))
|
|
12
|
+
if _script_dir in _sys.path:
|
|
13
|
+
_sys.path.remove(_script_dir)
|
|
14
|
+
|
|
7
15
|
import os
|
|
8
16
|
import subprocess
|
|
9
17
|
import json
|
npcsh/npc_team/alicanto.npc
CHANGED
|
@@ -11,13 +11,19 @@ colors:
|
|
|
11
11
|
top: "255,215,0"
|
|
12
12
|
bottom: "218,165,32"
|
|
13
13
|
primary_directive: |
|
|
14
|
-
You are alicanto,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
You are alicanto, a research agent. You investigate hypotheses through experimentation and evidence gathering.
|
|
15
|
+
Search academic papers to ground your work in existing literature.
|
|
16
|
+
Search the web for data, documentation, and recent findings.
|
|
17
|
+
Write and execute Python code to analyze data, compute statistics, and generate results.
|
|
18
|
+
Use shell commands for data processing and system tasks.
|
|
19
|
+
Create files to record your findings, analyses, and evidence.
|
|
20
|
+
When exploring a hypothesis, gather evidence from multiple sources, analyze it quantitatively where possible, and document what you find.
|
|
21
|
+
Say RESEARCH_COMPLETE when you have sufficient evidence to evaluate your hypothesis.
|
|
18
22
|
jinxs:
|
|
19
|
-
- lib/core/search
|
|
23
|
+
- lib/core/search/web_search
|
|
24
|
+
- lib/core/search/file_search
|
|
25
|
+
- lib/core/search/db_search
|
|
20
26
|
- lib/core/sh
|
|
21
27
|
- lib/core/python
|
|
22
28
|
- lib/core/load_file
|
|
23
|
-
- lib/
|
|
29
|
+
- lib/core/edit_file
|
npcsh/npc_team/corca.npc
CHANGED
npcsh/npc_team/frederic.npc
CHANGED