npcsh 1.1.18__tar.gz → 1.1.20__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.
Files changed (153) hide show
  1. {npcsh-1.1.18/npcsh.egg-info → npcsh-1.1.20}/PKG-INFO +21 -14
  2. {npcsh-1.1.18 → npcsh-1.1.20}/README.md +20 -13
  3. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/_state.py +19 -7
  4. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/benchmark/npcsh_agent.py +47 -16
  5. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/config.py +1 -0
  6. npcsh-1.1.20/npcsh/diff_viewer.py +452 -0
  7. npcsh-1.1.20/npcsh/npc_team/jinxs/bin/config_tui.jinx +300 -0
  8. npcsh-1.1.20/npcsh/npc_team/jinxs/bin/jinxs.jinx +407 -0
  9. npcsh-1.1.20/npcsh/npc_team/jinxs/bin/kg.jinx +941 -0
  10. npcsh-1.1.20/npcsh/npc_team/jinxs/bin/memories.jinx +317 -0
  11. npcsh-1.1.20/npcsh/npc_team/jinxs/bin/models.jinx +343 -0
  12. npcsh-1.1.20/npcsh/npc_team/jinxs/bin/nql.jinx +471 -0
  13. npcsh-1.1.20/npcsh/npc_team/jinxs/bin/setup.jinx +241 -0
  14. npcsh-1.1.20/npcsh/npc_team/jinxs/bin/sync.jinx +223 -0
  15. npcsh-1.1.20/npcsh/npc_team/jinxs/bin/team.jinx +504 -0
  16. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/incognide/add_tab.jinx +1 -1
  17. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/incognide/close_pane.jinx +1 -1
  18. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/incognide/close_tab.jinx +1 -1
  19. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/incognide/confirm.jinx +1 -1
  20. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/incognide/focus_pane.jinx +1 -1
  21. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/incognide/list_panes.jinx +1 -1
  22. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/incognide/navigate.jinx +1 -1
  23. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/incognide/notify.jinx +1 -1
  24. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/incognide/open_pane.jinx +1 -1
  25. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/incognide/read_pane.jinx +1 -1
  26. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/incognide/run_terminal.jinx +1 -1
  27. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/incognide/send_message.jinx +1 -1
  28. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/incognide/split_pane.jinx +1 -1
  29. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/incognide/switch_npc.jinx +1 -1
  30. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/incognide/switch_tab.jinx +1 -1
  31. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/incognide/write_file.jinx +1 -1
  32. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/incognide/zen_mode.jinx +1 -1
  33. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/core/search/db_search.jinx +1 -1
  34. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/core/search/file_search.jinx +1 -1
  35. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/core/search/kg_search.jinx +1 -1
  36. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/core/search/mem_search.jinx +1 -1
  37. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/core/search/web_search.jinx +1 -1
  38. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/research/paper_search.jinx +1 -1
  39. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/research/semantic_scholar.jinx +1 -1
  40. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/modes/alicanto.jinx +1 -1
  41. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/modes/arxiv.jinx +1 -1
  42. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/modes/corca.jinx +1 -1
  43. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/modes/guac.jinx +4 -6
  44. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/modes/plonk.jinx +1 -1
  45. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/modes/pti.jinx +1 -1
  46. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/modes/reattach.jinx +1 -1
  47. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/modes/spool.jinx +1 -1
  48. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/modes/wander.jinx +1 -1
  49. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/routes.py +8 -2
  50. {npcsh-1.1.18 → npcsh-1.1.20/npcsh.egg-info}/PKG-INFO +21 -14
  51. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh.egg-info/SOURCES.txt +8 -1
  52. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh.egg-info/entry_points.txt +7 -0
  53. {npcsh-1.1.18 → npcsh-1.1.20}/setup.py +1 -1
  54. npcsh-1.1.18/npcsh/npc_team/jinxs/bin/nql.jinx +0 -141
  55. npcsh-1.1.18/npcsh/npc_team/jinxs/bin/sync.jinx +0 -230
  56. npcsh-1.1.18/npcsh/npc_team/jinxs/lib/utils/jinxs.jinx +0 -331
  57. {npcsh-1.1.18 → npcsh-1.1.20}/LICENSE +0 -0
  58. {npcsh-1.1.18 → npcsh-1.1.20}/MANIFEST.in +0 -0
  59. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/__init__.py +0 -0
  60. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/alicanto.py +0 -0
  61. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/benchmark/__init__.py +0 -0
  62. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/benchmark/runner.py +0 -0
  63. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/benchmark/templates/install-npcsh.sh.j2 +0 -0
  64. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/build.py +0 -0
  65. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/completion.py +0 -0
  66. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/conversation_viewer.py +0 -0
  67. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/corca.py +0 -0
  68. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/execution.py +0 -0
  69. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/guac.py +0 -0
  70. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/mcp_helpers.py +0 -0
  71. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/mcp_server.py +0 -0
  72. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc.py +0 -0
  73. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/alicanto.npc +0 -0
  74. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/alicanto.png +0 -0
  75. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/corca.npc +0 -0
  76. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/corca.png +0 -0
  77. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/corca_example.png +0 -0
  78. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/frederic.npc +0 -0
  79. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/frederic4.png +0 -0
  80. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/guac.npc +0 -0
  81. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/guac.png +0 -0
  82. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/bin/benchmark.jinx +0 -0
  83. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/bin/roll.jinx +0 -0
  84. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/bin/sample.jinx +0 -0
  85. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/bin/vixynt.jinx +0 -0
  86. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/incognide/incognide.jinx +0 -0
  87. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/browser/browser_action.jinx +0 -0
  88. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/browser/browser_screenshot.jinx +0 -0
  89. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/browser/close_browser.jinx +0 -0
  90. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/browser/open_browser.jinx +0 -0
  91. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/computer_use/click.jinx +0 -0
  92. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/computer_use/key_press.jinx +0 -0
  93. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/computer_use/launch_app.jinx +0 -0
  94. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/computer_use/screenshot.jinx +0 -0
  95. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/computer_use/trigger.jinx +0 -0
  96. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/computer_use/type_text.jinx +0 -0
  97. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/computer_use/wait.jinx +0 -0
  98. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/core/chat.jinx +0 -0
  99. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/core/cmd.jinx +0 -0
  100. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/core/compress.jinx +0 -0
  101. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/core/edit_file.jinx +0 -0
  102. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/core/load_file.jinx +0 -0
  103. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/core/ots.jinx +0 -0
  104. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/core/paste.jinx +0 -0
  105. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/core/python.jinx +0 -0
  106. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/core/search/mem_review.jinx +0 -0
  107. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/core/search.jinx +0 -0
  108. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/core/sh.jinx +0 -0
  109. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/core/sleep.jinx +0 -0
  110. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/core/sql.jinx +0 -0
  111. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/orchestration/convene.jinx +0 -0
  112. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/orchestration/delegate.jinx +0 -0
  113. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/utils/build.jinx +0 -0
  114. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/utils/compile.jinx +0 -0
  115. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/utils/help.jinx +0 -0
  116. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/utils/init.jinx +0 -0
  117. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/utils/serve.jinx +0 -0
  118. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/utils/set.jinx +0 -0
  119. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/utils/shh.jinx +0 -0
  120. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/utils/switch.jinx +0 -0
  121. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/utils/switches.jinx +0 -0
  122. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/utils/teamviz.jinx +0 -0
  123. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/utils/usage.jinx +0 -0
  124. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/lib/utils/verbose.jinx +0 -0
  125. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/jinxs/modes/yap.jinx +0 -0
  126. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/kadiefa.npc +0 -0
  127. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/kadiefa.png +0 -0
  128. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/npcsh.ctx +0 -0
  129. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/npcsh_sibiji.png +0 -0
  130. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/plonk.npc +0 -0
  131. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/plonk.png +0 -0
  132. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/plonkjr.npc +0 -0
  133. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/plonkjr.png +0 -0
  134. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/sibiji.npc +0 -0
  135. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/sibiji.png +0 -0
  136. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/spool.png +0 -0
  137. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npc_team/yap.png +0 -0
  138. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/npcsh.py +0 -0
  139. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/parsing.py +0 -0
  140. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/plonk.py +0 -0
  141. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/pti.py +0 -0
  142. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/spool.py +0 -0
  143. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/ui.py +0 -0
  144. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/wander.py +0 -0
  145. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh/yap.py +0 -0
  146. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh.egg-info/dependency_links.txt +0 -0
  147. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh.egg-info/requires.txt +0 -0
  148. {npcsh-1.1.18 → npcsh-1.1.20}/npcsh.egg-info/top_level.txt +0 -0
  149. {npcsh-1.1.18 → npcsh-1.1.20}/project/__init__.py +0 -0
  150. {npcsh-1.1.18 → npcsh-1.1.20}/setup.cfg +0 -0
  151. {npcsh-1.1.18 → npcsh-1.1.20}/tests/test_config.py +0 -0
  152. {npcsh-1.1.18 → npcsh-1.1.20}/tests/test_jinxs.py +0 -0
  153. {npcsh-1.1.18 → npcsh-1.1.20}/tests/test_tool_routing.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: npcsh
3
- Version: 1.1.18
3
+ Version: 1.1.20
4
4
  Summary: npcsh is a command-line toolkit for using AI agents in novel ways.
5
5
  Home-page: https://github.com/NPC-Worldwide/npcsh
6
6
  Author: Christopher Agostino
@@ -106,31 +106,38 @@ Dynamic: summary
106
106
  <img src="https://raw.githubusercontent.com/NPC-Worldwide/npcsh/main/npcsh/npcsh.png" alt="npcsh logo" width=600></a>
107
107
  </p>
108
108
 
109
- # NPC Shell
109
+ # npcsh
110
110
 
111
- `npcsh` - a new standard in human-agent interaction. Co-create with agents to build organizations that refine themselves and evolve to your needs.
112
-
113
- The NPC shell is a suite of programs to make use of multi-modal LLMs and agents in novel interactive modes. Based in the command line, use it wherever you work.
114
-
115
- - It is developed to work reliably with small models and performs excellently with the state-of-the-art models from major model providers.
116
- - Fundamentally, the core program of npcsh extends the familiar bash environment with an intelligent layer that lets users seamlessly ask agents questions, run pre-built or custom macros or agents, all without breaking the flow of command-line work.
117
- - Switching between agents is a breeze in `npcsh`, letting you quickly and easily take advantage of a variety of agents (e.g. coding agents versus tool-calling agents versus prompt-based ReACT Flow agents) and personas (e.g. Data scientist, mapmaker with ennui, etc.).
118
- - Project variables and context can be stored in team `.ctx` files. Personas (`.npc`) and Jinja execution templates (`.jinx`) are likewise stored in `yaml` within the global `npcsh` team or your project-specific one, letting you focus on adjusting and engineering context and system prompts iteratively so you can constantly improve your agent team's performance.
111
+ The NPC shell (`npcsh`) makes the most of multi-modal LLMs and agents through a powerful set of simple slash commands and novel interactive modes, all from the comfort of the command line. Build teams of agents and schedule them on jobs, engineer context, and design custom interaction modes and Jinja Execution templates (Jinxs for you and your agents to invoke, all managed scalably for organizations of any size through the NPC data layer.
119
112
 
120
113
  To get started:
114
+ For users who want to mainly use models through APIs (`ollama`, `gemini`, `kimi`, `grok`, `deepseek`, `anthropic`, `openai`, `mistral`, or any others provided by litellm )
121
115
  ```bash
122
- # for users who want to mainly use models through APIs (e.g. , gemini, grok, deepseek, anthropic, openai, mistral, , any others provided by litellm ):
123
116
  pip install 'npcsh[lite]'
124
- # for users who want to use local models (these install diffusers/transformers/torch stack so it is big.):
117
+ ```
118
+ For users who want to use and fine-tune local models (this installs `diffusers`/`transformers`/`torch` stack so it is big):
119
+
120
+ ```bash
125
121
  pip install 'npcsh[local]'
126
- # for users who want to use the voice mode `yap`, see also the OS-specific installation instructions for installing needed system audio libraries
122
+ ```
123
+
124
+
125
+ For users who want to use the voice mode `yap` (see also the OS-specific installation instructions for installing needed system audio libraries)
126
+ ```bash
127
127
  pip install 'npcsh[yap]'
128
128
  ```
129
+
129
130
  Once installed: run
130
131
  ```bash
131
132
  npcsh
132
133
  ```
133
- and you will enter the NPC shell. Additionally, the pip installation includes the following CLI tools available in bash: `npc` cli, `wander`, `spool`, `yap`, and `nql`. Bin jinxs in `npc_team/jinxs/bin/` are automatically registered as CLI commands.
134
+ and you will enter the NPC shell.
135
+
136
+ If you do not have any local models
137
+
138
+
139
+
140
+ Additionally, the pip installation includes the following CLI tools available in bash: `npc` cli, `wander`, `spool`, `yap`, and `nql`. Bin jinxs in `npc_team/jinxs/bin/` are automatically registered as CLI commands.
134
141
 
135
142
 
136
143
  # Usage
@@ -3,31 +3,38 @@
3
3
  <img src="https://raw.githubusercontent.com/NPC-Worldwide/npcsh/main/npcsh/npcsh.png" alt="npcsh logo" width=600></a>
4
4
  </p>
5
5
 
6
- # NPC Shell
6
+ # npcsh
7
7
 
8
- `npcsh` - a new standard in human-agent interaction. Co-create with agents to build organizations that refine themselves and evolve to your needs.
9
-
10
- The NPC shell is a suite of programs to make use of multi-modal LLMs and agents in novel interactive modes. Based in the command line, use it wherever you work.
11
-
12
- - It is developed to work reliably with small models and performs excellently with the state-of-the-art models from major model providers.
13
- - Fundamentally, the core program of npcsh extends the familiar bash environment with an intelligent layer that lets users seamlessly ask agents questions, run pre-built or custom macros or agents, all without breaking the flow of command-line work.
14
- - Switching between agents is a breeze in `npcsh`, letting you quickly and easily take advantage of a variety of agents (e.g. coding agents versus tool-calling agents versus prompt-based ReACT Flow agents) and personas (e.g. Data scientist, mapmaker with ennui, etc.).
15
- - Project variables and context can be stored in team `.ctx` files. Personas (`.npc`) and Jinja execution templates (`.jinx`) are likewise stored in `yaml` within the global `npcsh` team or your project-specific one, letting you focus on adjusting and engineering context and system prompts iteratively so you can constantly improve your agent team's performance.
8
+ The NPC shell (`npcsh`) makes the most of multi-modal LLMs and agents through a powerful set of simple slash commands and novel interactive modes, all from the comfort of the command line. Build teams of agents and schedule them on jobs, engineer context, and design custom interaction modes and Jinja Execution templates (Jinxs for you and your agents to invoke, all managed scalably for organizations of any size through the NPC data layer.
16
9
 
17
10
  To get started:
11
+ For users who want to mainly use models through APIs (`ollama`, `gemini`, `kimi`, `grok`, `deepseek`, `anthropic`, `openai`, `mistral`, or any others provided by litellm )
18
12
  ```bash
19
- # for users who want to mainly use models through APIs (e.g. , gemini, grok, deepseek, anthropic, openai, mistral, , any others provided by litellm ):
20
13
  pip install 'npcsh[lite]'
21
- # for users who want to use local models (these install diffusers/transformers/torch stack so it is big.):
14
+ ```
15
+ For users who want to use and fine-tune local models (this installs `diffusers`/`transformers`/`torch` stack so it is big):
16
+
17
+ ```bash
22
18
  pip install 'npcsh[local]'
23
- # for users who want to use the voice mode `yap`, see also the OS-specific installation instructions for installing needed system audio libraries
19
+ ```
20
+
21
+
22
+ For users who want to use the voice mode `yap` (see also the OS-specific installation instructions for installing needed system audio libraries)
23
+ ```bash
24
24
  pip install 'npcsh[yap]'
25
25
  ```
26
+
26
27
  Once installed: run
27
28
  ```bash
28
29
  npcsh
29
30
  ```
30
- and you will enter the NPC shell. Additionally, the pip installation includes the following CLI tools available in bash: `npc` cli, `wander`, `spool`, `yap`, and `nql`. Bin jinxs in `npc_team/jinxs/bin/` are automatically registered as CLI commands.
31
+ and you will enter the NPC shell.
32
+
33
+ If you do not have any local models
34
+
35
+
36
+
37
+ Additionally, the pip installation includes the following CLI tools available in bash: `npc` cli, `wander`, `spool`, `yap`, and `nql`. Bin jinxs in `npc_team/jinxs/bin/` are automatically registered as CLI commands.
31
38
 
32
39
 
33
40
  # Usage
@@ -125,6 +125,7 @@ from .config import (
125
125
  NPCSH_API_URL,
126
126
  NPCSH_SEARCH_PROVIDER,
127
127
  NPCSH_BUILD_KG,
128
+ NPCSH_EDIT_APPROVAL,
128
129
  setup_npcsh_config,
129
130
  is_npcsh_initialized,
130
131
  set_npcsh_initialized,
@@ -185,6 +186,10 @@ class ShellState:
185
186
  session_start_time: float = field(default_factory=lambda: __import__('time').time())
186
187
  # Logging level: "silent", "normal", "verbose"
187
188
  log_level: str = "normal"
189
+ # Edit approval mode: "off", "interactive", "auto"
190
+ edit_approval: str = NPCSH_EDIT_APPROVAL
191
+ # Pending file edits for approval
192
+ pending_edits: Dict[str, Dict[str, str]] = field(default_factory=dict)
188
193
 
189
194
  def get_model_for_command(self, model_type: str = "chat"):
190
195
  if model_type == "chat":
@@ -271,6 +276,8 @@ CONFIG_KEY_MAP = {
271
276
  "stream": "NPCSH_STREAM_OUTPUT",
272
277
  "apiurl": "NPCSH_API_URL",
273
278
  "buildkg": "NPCSH_BUILD_KG",
279
+ "editapproval": "NPCSH_EDIT_APPROVAL",
280
+ "approval": "NPCSH_EDIT_APPROVAL",
274
281
  }
275
282
 
276
283
 
@@ -315,6 +322,7 @@ def set_npcsh_config_value(key: str, value: str):
315
322
  "NPCSH_BUILD_KG": "build_kg",
316
323
  "NPCSH_API_URL": "api_url",
317
324
  "NPCSH_STREAM_OUTPUT": "stream_output",
325
+ "NPCSH_EDIT_APPROVAL": "edit_approval",
318
326
  }
319
327
  if env_key in field_map:
320
328
  setattr(ShellState, field_map[env_key], parsed_val)
@@ -2752,15 +2760,19 @@ def process_pipeline_command(
2752
2760
  if cmd_to_process.startswith("/"):
2753
2761
  command_name = cmd_to_process.split()[0].lstrip('/')
2754
2762
 
2755
- # Check if this is an interactive mode by looking for the jinx file in modes/
2763
+ # Check if this is an interactive mode
2756
2764
  is_interactive_mode = False
2757
-
2758
- # Check global modes
2759
- global_modes_jinx = os.path.expanduser(f'~/.npcsh/npc_team/jinxs/modes/{command_name}.jinx')
2760
- if os.path.exists(global_modes_jinx):
2765
+
2766
+ # Check if the jinx declares interactive: true
2767
+ if router.is_interactive(command_name):
2761
2768
  is_interactive_mode = True
2762
-
2763
- # Check team modes
2769
+
2770
+ # Also check modes/ directory (legacy)
2771
+ if not is_interactive_mode:
2772
+ global_modes_jinx = os.path.expanduser(f'~/.npcsh/npc_team/jinxs/modes/{command_name}.jinx')
2773
+ if os.path.exists(global_modes_jinx):
2774
+ is_interactive_mode = True
2775
+
2764
2776
  if not is_interactive_mode and state.team and state.team.team_path:
2765
2777
  team_modes_jinx = os.path.join(state.team.team_path, 'jinxs', 'modes', f'{command_name}.jinx')
2766
2778
  if os.path.exists(team_modes_jinx):
@@ -53,14 +53,26 @@ class NpcshAgent(BaseInstalledAgent):
53
53
  Returns:
54
54
  List of ExecInput commands to execute
55
55
  """
56
- # Wrap the instruction with explicit jinx usage directions
56
+ # Wrap the instruction with explicit jinx usage directions and retry logic
57
57
  tool_instruction = f"""You have access to jinxs including edit_file (for writing/creating files), sh (for running shell commands), and python (for running Python code).
58
58
 
59
- IMPORTANT: You MUST use these jinxs to complete the task. Do NOT just output code as text - use the edit_file jinx to actually write files to disk.
59
+ IMPORTANT RULES:
60
+ 1. You MUST use these jinxs to complete the task. Do NOT just output code as text - use the edit_file jinx to actually write files to disk.
61
+ 2. After implementing a solution, you MUST verify it works by running any provided test scripts.
62
+ 3. If a test fails or produces an error, you MUST try a DIFFERENT approach. Do not give up.
63
+ 4. Keep trying different approaches until you succeed or have tried at least 10 different solutions.
64
+ 5. NEVER assume success - always check the actual output of test commands.
60
65
 
61
66
  Task: {instruction}
62
67
 
63
- Remember: Use edit_file to write any code files. Use sh to run shell commands like gcc, make, etc."""
68
+ WORKFLOW:
69
+ 1. Implement your solution using edit_file and sh
70
+ 2. Run any test scripts mentioned in the task
71
+ 3. Check the output carefully - look for "PASS", "SUCCESS", "OK" or similar
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."""
64
76
 
65
77
  escaped_instruction = shlex.quote(tool_instruction)
66
78
  model_name = self.model_name
@@ -90,18 +102,25 @@ Remember: Use edit_file to write any code files. Use sh to run shell commands li
90
102
  # Build environment variables for API keys
91
103
  env_vars = []
92
104
  api_key_map = {
93
- "anthropic": "ANTHROPIC_API_KEY",
94
- "openai": "OPENAI_API_KEY",
95
- "gemini": "GOOGLE_API_KEY",
96
- "google": "GOOGLE_API_KEY",
97
- "deepseek": "DEEPSEEK_API_KEY",
98
- "groq": "GROQ_API_KEY",
99
- "openrouter": "OPENROUTER_API_KEY",
105
+ "anthropic": ["ANTHROPIC_API_KEY"],
106
+ "openai": ["OPENAI_API_KEY"],
107
+ "gemini": ["GOOGLE_API_KEY", "GEMINI_API_KEY"],
108
+ "google": ["GOOGLE_API_KEY", "GEMINI_API_KEY"],
109
+ "deepseek": ["DEEPSEEK_API_KEY"],
110
+ "groq": ["GROQ_API_KEY"],
111
+ "openrouter": ["OPENROUTER_API_KEY"],
100
112
  }
101
113
 
102
- for prov, env_key in api_key_map.items():
103
- if env_key in os.environ:
104
- env_vars.append(f'{env_key}="{os.environ[env_key]}"')
114
+ added_keys = set()
115
+ for prov, env_keys in api_key_map.items():
116
+ for env_key in env_keys:
117
+ if env_key in os.environ:
118
+ # For Gemini, always pass as GOOGLE_API_KEY (what litellm expects)
119
+ target_key = "GOOGLE_API_KEY" if env_key == "GEMINI_API_KEY" else env_key
120
+ if target_key not in added_keys:
121
+ env_vars.append(f'{target_key}="{os.environ[env_key]}"')
122
+ added_keys.add(target_key)
123
+ break
105
124
 
106
125
  env_prefix = " ".join(env_vars) + " " if env_vars else ""
107
126
 
@@ -215,14 +234,26 @@ class NpcshAgentWithNpc(NpcshAgent):
215
234
 
216
235
  def create_run_agent_commands(self, instruction: str) -> list:
217
236
  """Create commands using a specific NPC."""
218
- # Wrap the instruction with explicit jinx usage directions
237
+ # Wrap the instruction with explicit jinx usage directions and retry logic
219
238
  tool_instruction = f"""You have access to jinxs including edit_file (for writing/creating files), sh (for running shell commands), and python (for running Python code).
220
239
 
221
- IMPORTANT: You MUST use these jinxs to complete the task. Do NOT just output code as text - use the edit_file jinx to actually write files to disk.
240
+ IMPORTANT RULES:
241
+ 1. You MUST use these jinxs to complete the task. Do NOT just output code as text - use the edit_file jinx to actually write files to disk.
242
+ 2. After implementing a solution, you MUST verify it works by running any provided test scripts.
243
+ 3. If a test fails or produces an error, you MUST try a DIFFERENT approach. Do not give up.
244
+ 4. Keep trying different approaches until you succeed or have tried at least 10 different solutions.
245
+ 5. NEVER assume success - always check the actual output of test commands.
222
246
 
223
247
  Task: {instruction}
224
248
 
225
- Remember: Use edit_file to write any code files. Use sh to run shell commands like gcc, make, etc."""
249
+ WORKFLOW:
250
+ 1. Implement your solution using edit_file and sh
251
+ 2. Run any test scripts mentioned in the task
252
+ 3. Check the output carefully - look for "PASS", "SUCCESS", "OK" or similar
253
+ 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."""
226
257
 
227
258
  escaped_instruction = shlex.quote(tool_instruction)
228
259
  model_name = self.model_name
@@ -43,6 +43,7 @@ NPCSH_STREAM_OUTPUT = os.environ.get("NPCSH_STREAM_OUTPUT", "0") == "1"
43
43
  NPCSH_API_URL = os.environ.get("NPCSH_API_URL", None)
44
44
  NPCSH_SEARCH_PROVIDER = os.environ.get("NPCSH_SEARCH_PROVIDER", "duckduckgo")
45
45
  NPCSH_BUILD_KG = os.environ.get("NPCSH_BUILD_KG", "1") != "0"
46
+ NPCSH_EDIT_APPROVAL = os.environ.get("NPCSH_EDIT_APPROVAL", "off") # off, interactive, auto
46
47
 
47
48
 
48
49
  def get_shell_config_file() -> str: