npcsh 1.1.16__py3-none-any.whl → 1.1.17__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 +24 -9
- npcsh/benchmark/__init__.py +22 -0
- npcsh/benchmark/npcsh_agent.py +262 -0
- npcsh/benchmark/runner.py +569 -0
- npcsh/npc_team/jinxs/bin/benchmark.jinx +146 -0
- npcsh/npc_team/jinxs/bin/nql.jinx +7 -7
- npcsh/npc_team/jinxs/bin/roll.jinx +20 -23
- npcsh/npc_team/jinxs/bin/sample.jinx +6 -7
- npcsh/npc_team/jinxs/bin/spool.jinx +4 -4
- npcsh/npc_team/jinxs/bin/sync.jinx +6 -6
- npcsh/npc_team/jinxs/bin/vixynt.jinx +8 -8
- npcsh/npc_team/jinxs/bin/wander.jinx +109 -19
- npcsh/npc_team/jinxs/bin/yap.jinx +5 -5
- npcsh/npc_team/jinxs/incognide/add_tab.jinx +11 -0
- npcsh/npc_team/jinxs/incognide/close_pane.jinx +9 -0
- npcsh/npc_team/jinxs/incognide/close_tab.jinx +10 -0
- npcsh/npc_team/jinxs/incognide/confirm.jinx +10 -0
- npcsh/npc_team/jinxs/incognide/focus_pane.jinx +9 -0
- npcsh/npc_team/jinxs/{npc_studio/npc-studio.jinx → incognide/incognide.jinx} +2 -2
- npcsh/npc_team/jinxs/incognide/list_panes.jinx +8 -0
- npcsh/npc_team/jinxs/incognide/navigate.jinx +10 -0
- npcsh/npc_team/jinxs/incognide/notify.jinx +10 -0
- npcsh/npc_team/jinxs/incognide/open_pane.jinx +13 -0
- npcsh/npc_team/jinxs/incognide/read_pane.jinx +9 -0
- npcsh/npc_team/jinxs/incognide/run_terminal.jinx +10 -0
- npcsh/npc_team/jinxs/incognide/send_message.jinx +10 -0
- npcsh/npc_team/jinxs/incognide/split_pane.jinx +12 -0
- npcsh/npc_team/jinxs/incognide/switch_npc.jinx +10 -0
- npcsh/npc_team/jinxs/incognide/switch_tab.jinx +10 -0
- npcsh/npc_team/jinxs/incognide/write_file.jinx +11 -0
- npcsh/npc_team/jinxs/incognide/zen_mode.jinx +9 -0
- npcsh/npc_team/jinxs/lib/browser/browser_action.jinx +4 -4
- npcsh/npc_team/jinxs/lib/browser/browser_screenshot.jinx +1 -1
- npcsh/npc_team/jinxs/lib/browser/open_browser.jinx +2 -2
- npcsh/npc_team/jinxs/lib/computer_use/click.jinx +2 -2
- npcsh/npc_team/jinxs/lib/computer_use/key_press.jinx +1 -1
- npcsh/npc_team/jinxs/lib/computer_use/launch_app.jinx +1 -1
- npcsh/npc_team/jinxs/lib/computer_use/screenshot.jinx +1 -1
- npcsh/npc_team/jinxs/lib/computer_use/trigger.jinx +2 -2
- npcsh/npc_team/jinxs/lib/computer_use/type_text.jinx +1 -1
- npcsh/npc_team/jinxs/lib/computer_use/wait.jinx +1 -1
- npcsh/npc_team/jinxs/lib/core/chat.jinx +4 -4
- npcsh/npc_team/jinxs/lib/core/cmd.jinx +4 -4
- npcsh/npc_team/jinxs/lib/core/compress.jinx +8 -8
- npcsh/npc_team/jinxs/lib/core/edit_file.jinx +3 -0
- npcsh/npc_team/jinxs/lib/core/ots.jinx +7 -7
- npcsh/npc_team/jinxs/lib/core/search/db_search.jinx +44 -0
- npcsh/npc_team/jinxs/lib/core/search/file_search.jinx +94 -0
- npcsh/npc_team/jinxs/lib/core/search/kg_search.jinx +96 -0
- npcsh/npc_team/jinxs/lib/core/search/mem_search.jinx +80 -0
- npcsh/npc_team/jinxs/lib/core/search/web_search.jinx +51 -0
- npcsh/npc_team/jinxs/lib/core/search.jinx +52 -129
- npcsh/npc_team/jinxs/lib/core/sh.jinx +1 -1
- npcsh/npc_team/jinxs/lib/core/sleep.jinx +7 -7
- npcsh/npc_team/jinxs/lib/core/sql.jinx +7 -7
- npcsh/npc_team/jinxs/lib/orchestration/convene.jinx +7 -7
- npcsh/npc_team/jinxs/lib/orchestration/delegate.jinx +8 -9
- npcsh/npc_team/jinxs/lib/research/arxiv.jinx +2 -2
- npcsh/npc_team/jinxs/lib/research/paper_search.jinx +3 -3
- npcsh/npc_team/jinxs/lib/research/semantic_scholar.jinx +2 -2
- npcsh/npc_team/jinxs/lib/utils/build.jinx +5 -5
- npcsh/npc_team/jinxs/lib/utils/compile.jinx +2 -2
- npcsh/npc_team/jinxs/lib/utils/help.jinx +1 -1
- npcsh/npc_team/jinxs/lib/utils/init.jinx +5 -5
- npcsh/npc_team/jinxs/lib/utils/jinxs.jinx +1 -1
- npcsh/npc_team/jinxs/lib/utils/serve.jinx +2 -2
- npcsh/npc_team/jinxs/lib/utils/set.jinx +2 -2
- npcsh/npc_team/jinxs/lib/utils/switch.jinx +3 -3
- npcsh/npc_team/jinxs/lib/utils/switches.jinx +1 -1
- npcsh/npc_team/jinxs/lib/utils/teamviz.jinx +2 -2
- npcsh/npc_team/sibiji.npc +1 -1
- npcsh/npcsh.py +81 -43
- npcsh-1.1.17.data/data/npcsh/npc_team/add_tab.jinx +11 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/arxiv.jinx +2 -2
- npcsh-1.1.17.data/data/npcsh/npc_team/benchmark.jinx +146 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/browser_action.jinx +4 -4
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/browser_screenshot.jinx +1 -1
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/build.jinx +5 -5
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/chat.jinx +4 -4
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/click.jinx +2 -2
- npcsh-1.1.17.data/data/npcsh/npc_team/close_pane.jinx +9 -0
- npcsh-1.1.17.data/data/npcsh/npc_team/close_tab.jinx +10 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/cmd.jinx +4 -4
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/compile.jinx +2 -2
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/compress.jinx +8 -8
- npcsh-1.1.17.data/data/npcsh/npc_team/confirm.jinx +10 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/convene.jinx +7 -7
- npcsh-1.1.17.data/data/npcsh/npc_team/db_search.jinx +44 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/delegate.jinx +8 -9
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/edit_file.jinx +3 -0
- npcsh-1.1.17.data/data/npcsh/npc_team/file_search.jinx +94 -0
- npcsh-1.1.17.data/data/npcsh/npc_team/focus_pane.jinx +9 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/help.jinx +1 -1
- npcsh-1.1.16.data/data/npcsh/npc_team/npc-studio.jinx → npcsh-1.1.17.data/data/npcsh/npc_team/incognide.jinx +2 -2
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/init.jinx +5 -5
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/jinxs.jinx +1 -1
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/key_press.jinx +1 -1
- npcsh-1.1.17.data/data/npcsh/npc_team/kg_search.jinx +96 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/launch_app.jinx +1 -1
- npcsh-1.1.17.data/data/npcsh/npc_team/list_panes.jinx +8 -0
- npcsh-1.1.17.data/data/npcsh/npc_team/mem_search.jinx +80 -0
- npcsh-1.1.17.data/data/npcsh/npc_team/navigate.jinx +10 -0
- npcsh-1.1.17.data/data/npcsh/npc_team/notify.jinx +10 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/nql.jinx +7 -7
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/open_browser.jinx +2 -2
- npcsh-1.1.17.data/data/npcsh/npc_team/open_pane.jinx +13 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/ots.jinx +7 -7
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/paper_search.jinx +3 -3
- npcsh-1.1.17.data/data/npcsh/npc_team/read_pane.jinx +9 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/roll.jinx +20 -23
- npcsh-1.1.17.data/data/npcsh/npc_team/run_terminal.jinx +10 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/sample.jinx +6 -7
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/screenshot.jinx +1 -1
- npcsh-1.1.17.data/data/npcsh/npc_team/search.jinx +54 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/semantic_scholar.jinx +2 -2
- npcsh-1.1.17.data/data/npcsh/npc_team/send_message.jinx +10 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/serve.jinx +2 -2
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/set.jinx +2 -2
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/sh.jinx +1 -1
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/sibiji.npc +1 -1
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/sleep.jinx +7 -7
- npcsh-1.1.17.data/data/npcsh/npc_team/split_pane.jinx +12 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/spool.jinx +4 -4
- npcsh-1.1.17.data/data/npcsh/npc_team/sql.jinx +16 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/switch.jinx +3 -3
- npcsh-1.1.17.data/data/npcsh/npc_team/switch_npc.jinx +10 -0
- npcsh-1.1.17.data/data/npcsh/npc_team/switch_tab.jinx +10 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/switches.jinx +1 -1
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/sync.jinx +6 -6
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/teamviz.jinx +2 -2
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/trigger.jinx +2 -2
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/type_text.jinx +1 -1
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/vixynt.jinx +8 -8
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/wait.jinx +1 -1
- npcsh-1.1.17.data/data/npcsh/npc_team/wander.jinx +242 -0
- npcsh-1.1.17.data/data/npcsh/npc_team/web_search.jinx +51 -0
- npcsh-1.1.17.data/data/npcsh/npc_team/write_file.jinx +11 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/yap.jinx +5 -5
- npcsh-1.1.17.data/data/npcsh/npc_team/zen_mode.jinx +9 -0
- {npcsh-1.1.16.dist-info → npcsh-1.1.17.dist-info}/METADATA +10 -7
- npcsh-1.1.17.dist-info/RECORD +219 -0
- {npcsh-1.1.16.dist-info → npcsh-1.1.17.dist-info}/entry_points.txt +2 -0
- npcsh-1.1.16.data/data/npcsh/npc_team/search.jinx +0 -131
- npcsh-1.1.16.data/data/npcsh/npc_team/sql.jinx +0 -16
- npcsh-1.1.16.data/data/npcsh/npc_team/wander.jinx +0 -152
- npcsh-1.1.16.dist-info/RECORD +0 -170
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/alicanto.npc +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/alicanto.png +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/close_browser.jinx +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/corca.npc +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/corca.png +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/corca_example.png +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/frederic.npc +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/frederic4.png +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/guac.npc +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/guac.png +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/kadiefa.npc +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/kadiefa.png +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/load_file.jinx +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/npcsh.ctx +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/npcsh_sibiji.png +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/paste.jinx +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/plonk.npc +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/plonk.png +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/plonkjr.npc +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/plonkjr.png +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/python.jinx +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/shh.jinx +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/sibiji.png +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/spool.png +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/usage.jinx +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/verbose.jinx +0 -0
- {npcsh-1.1.16.data → npcsh-1.1.17.data}/data/npcsh/npc_team/yap.png +0 -0
- {npcsh-1.1.16.dist-info → npcsh-1.1.17.dist-info}/WHEEL +0 -0
- {npcsh-1.1.16.dist-info → npcsh-1.1.17.dist-info}/licenses/LICENSE +0 -0
- {npcsh-1.1.16.dist-info → npcsh-1.1.17.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
jinx_name: file_search
|
|
2
|
+
description: Search file contents using RAG (Retrieval Augmented Generation)
|
|
3
|
+
inputs:
|
|
4
|
+
- query: ""
|
|
5
|
+
- file_paths: ""
|
|
6
|
+
- emodel: ""
|
|
7
|
+
- eprovider: ""
|
|
8
|
+
- vector_db_path: ""
|
|
9
|
+
- recursive: "false"
|
|
10
|
+
|
|
11
|
+
steps:
|
|
12
|
+
- name: search_files
|
|
13
|
+
engine: python
|
|
14
|
+
code: |
|
|
15
|
+
import os
|
|
16
|
+
import glob as globmod
|
|
17
|
+
|
|
18
|
+
query = context.get('query', '').strip()
|
|
19
|
+
file_paths_str = context.get('file_paths', '').strip()
|
|
20
|
+
|
|
21
|
+
if not query or not file_paths_str:
|
|
22
|
+
lines = [
|
|
23
|
+
"Usage: /file_search <query> file_paths=<path1,path2,...>",
|
|
24
|
+
"",
|
|
25
|
+
"Options:",
|
|
26
|
+
" file_paths - Comma-separated file paths or glob patterns (required)",
|
|
27
|
+
" emodel - Embedding model",
|
|
28
|
+
" eprovider - Embedding provider",
|
|
29
|
+
" vector_db_path - Path to vector database",
|
|
30
|
+
" recursive - Use recursive glob for patterns (default false)",
|
|
31
|
+
"",
|
|
32
|
+
"Examples:",
|
|
33
|
+
" /file_search how does auth work file_paths=src/*.py",
|
|
34
|
+
" /file_search database schema file_paths=docs/,README.md",
|
|
35
|
+
]
|
|
36
|
+
context['output'] = "\n".join(lines)
|
|
37
|
+
else:
|
|
38
|
+
recursive = context.get('recursive', 'false').lower() == 'true'
|
|
39
|
+
emodel = context.get('emodel') or None
|
|
40
|
+
eprovider = context.get('eprovider') or None
|
|
41
|
+
try:
|
|
42
|
+
emodel = emodel or (state.embedding_model if 'state' in dir() and state else None)
|
|
43
|
+
eprovider = eprovider or (state.embedding_provider if 'state' in dir() and state else None)
|
|
44
|
+
except:
|
|
45
|
+
pass
|
|
46
|
+
vector_db_path = context.get('vector_db_path') or os.path.expanduser("~/.npcsh/npcsh_chroma.db")
|
|
47
|
+
|
|
48
|
+
try:
|
|
49
|
+
resolved_paths = []
|
|
50
|
+
for path_spec in file_paths_str.split(','):
|
|
51
|
+
path_spec = path_spec.strip()
|
|
52
|
+
if not path_spec:
|
|
53
|
+
continue
|
|
54
|
+
expanded = os.path.expanduser(path_spec)
|
|
55
|
+
if '*' in expanded or '?' in expanded:
|
|
56
|
+
if recursive:
|
|
57
|
+
matches = globmod.glob(expanded, recursive=True)
|
|
58
|
+
else:
|
|
59
|
+
matches = globmod.glob(expanded)
|
|
60
|
+
resolved_paths.extend(matches)
|
|
61
|
+
else:
|
|
62
|
+
resolved_paths.append(os.path.abspath(expanded))
|
|
63
|
+
|
|
64
|
+
file_contents = []
|
|
65
|
+
loaded_files = []
|
|
66
|
+
for path in resolved_paths:
|
|
67
|
+
if os.path.isfile(path):
|
|
68
|
+
chunks = load_file_contents(path)
|
|
69
|
+
basename = os.path.basename(path)
|
|
70
|
+
file_contents.extend([basename + ": " + chunk for chunk in chunks])
|
|
71
|
+
loaded_files.append(basename)
|
|
72
|
+
elif os.path.isdir(path):
|
|
73
|
+
for root, dirs, files in os.walk(path):
|
|
74
|
+
for f in files:
|
|
75
|
+
fpath = os.path.join(root, f)
|
|
76
|
+
chunks = load_file_contents(fpath)
|
|
77
|
+
file_contents.extend([f + ": " + chunk for chunk in chunks])
|
|
78
|
+
loaded_files.append(f)
|
|
79
|
+
|
|
80
|
+
if not file_contents:
|
|
81
|
+
context['output'] = "No files found or loaded from: " + file_paths_str
|
|
82
|
+
else:
|
|
83
|
+
result = execute_rag_command(
|
|
84
|
+
command=query,
|
|
85
|
+
vector_db_path=vector_db_path,
|
|
86
|
+
embedding_model=emodel,
|
|
87
|
+
embedding_provider=eprovider,
|
|
88
|
+
file_contents=file_contents
|
|
89
|
+
)
|
|
90
|
+
response = result.get('response', 'No RAG response.')
|
|
91
|
+
context['output'] = "Searched " + str(len(loaded_files)) + " files:\n\n" + response
|
|
92
|
+
except Exception as e:
|
|
93
|
+
import traceback
|
|
94
|
+
context['output'] = "File search error: " + str(e) + "\n" + traceback.format_exc()
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
jinx_name: "init"
|
|
2
2
|
description: "Initialize NPC project"
|
|
3
3
|
inputs:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
- directory: "."
|
|
5
|
+
- templates: ""
|
|
6
|
+
- context: ""
|
|
7
|
+
- model: ""
|
|
8
|
+
- provider: ""
|
|
9
9
|
steps:
|
|
10
10
|
- name: "initialize_project"
|
|
11
11
|
engine: "python"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
jinx_name: jinxs
|
|
2
2
|
description: "Show available jinxs organized by folder. Use /jinxs <path> for details on a specific folder."
|
|
3
3
|
inputs:
|
|
4
|
-
|
|
4
|
+
- path: ""
|
|
5
5
|
steps:
|
|
6
6
|
- name: list_jinxs
|
|
7
7
|
engine: python
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
jinx_name: kg_search
|
|
2
|
+
description: Search the knowledge graph for facts and concepts
|
|
3
|
+
inputs:
|
|
4
|
+
- query: ""
|
|
5
|
+
- type: "facts"
|
|
6
|
+
- concept: ""
|
|
7
|
+
- npc_name: ""
|
|
8
|
+
- team_name: ""
|
|
9
|
+
- db_path: ""
|
|
10
|
+
|
|
11
|
+
steps:
|
|
12
|
+
- name: search_kg
|
|
13
|
+
engine: python
|
|
14
|
+
code: |
|
|
15
|
+
import os
|
|
16
|
+
from npcpy.memory.knowledge_graph import kg_search_facts, kg_list_concepts, kg_get_facts_for_concept, kg_get_all_facts
|
|
17
|
+
|
|
18
|
+
query = context.get('query', '').strip()
|
|
19
|
+
search_type = context.get('type', 'facts').lower()
|
|
20
|
+
concept = context.get('concept', '').strip()
|
|
21
|
+
|
|
22
|
+
if not query and search_type == 'facts' and not concept:
|
|
23
|
+
lines = [
|
|
24
|
+
"Usage: /kg_search <query> [type=facts|concepts|all]",
|
|
25
|
+
"",
|
|
26
|
+
"Options:",
|
|
27
|
+
" type - Search type (facts, concepts, all). Default is facts",
|
|
28
|
+
" concept - Get facts for a specific concept",
|
|
29
|
+
" npc_name - Filter by NPC name",
|
|
30
|
+
" team_name - Filter by team name",
|
|
31
|
+
" db_path - Path to history database",
|
|
32
|
+
"",
|
|
33
|
+
"Examples:",
|
|
34
|
+
" /kg_search python",
|
|
35
|
+
" /kg_search type=concepts",
|
|
36
|
+
" /kg_search concept=coding",
|
|
37
|
+
" /kg_search type=all",
|
|
38
|
+
]
|
|
39
|
+
context['output'] = "\n".join(lines)
|
|
40
|
+
else:
|
|
41
|
+
db_path = context.get('db_path') or os.path.expanduser("~/.npcsh/npcsh_history.db")
|
|
42
|
+
|
|
43
|
+
try:
|
|
44
|
+
cmd_history = CommandHistory(db_path)
|
|
45
|
+
engine = cmd_history.engine
|
|
46
|
+
|
|
47
|
+
team_obj = None
|
|
48
|
+
try:
|
|
49
|
+
team_obj = state.team if 'state' in dir() and state else None
|
|
50
|
+
except:
|
|
51
|
+
pass
|
|
52
|
+
npc_obj = npc if 'npc' in dir() else None
|
|
53
|
+
|
|
54
|
+
if concept:
|
|
55
|
+
facts = kg_get_facts_for_concept(engine, concept, npc=npc_obj, team=team_obj)
|
|
56
|
+
if not facts:
|
|
57
|
+
context['output'] = "No facts found for concept '" + concept + "'"
|
|
58
|
+
else:
|
|
59
|
+
lines = ["Facts for concept '" + concept + "':", ""]
|
|
60
|
+
for i, fact in enumerate(facts, 1):
|
|
61
|
+
lines.append(str(i) + ". " + str(fact))
|
|
62
|
+
context['output'] = "\n".join(lines)
|
|
63
|
+
|
|
64
|
+
elif search_type == 'concepts':
|
|
65
|
+
concepts = kg_list_concepts(engine, npc=npc_obj, team=team_obj)
|
|
66
|
+
if not concepts:
|
|
67
|
+
context['output'] = "No concepts found in knowledge graph."
|
|
68
|
+
else:
|
|
69
|
+
lines = ["Found " + str(len(concepts)) + " concepts:", ""]
|
|
70
|
+
for i, c in enumerate(concepts, 1):
|
|
71
|
+
lines.append(str(i) + ". " + str(c))
|
|
72
|
+
context['output'] = "\n".join(lines)
|
|
73
|
+
|
|
74
|
+
elif search_type == 'all':
|
|
75
|
+
facts = kg_get_all_facts(engine, npc=npc_obj, team=team_obj)
|
|
76
|
+
if not facts:
|
|
77
|
+
context['output'] = "No facts in knowledge graph."
|
|
78
|
+
else:
|
|
79
|
+
lines = ["All facts (" + str(len(facts)) + " total):", ""]
|
|
80
|
+
for i, fact in enumerate(facts, 1):
|
|
81
|
+
lines.append(str(i) + ". " + str(fact))
|
|
82
|
+
context['output'] = "\n".join(lines)
|
|
83
|
+
|
|
84
|
+
else:
|
|
85
|
+
facts = kg_search_facts(engine, query, npc=npc_obj, team=team_obj)
|
|
86
|
+
if not facts:
|
|
87
|
+
context['output'] = "No KG facts found for '" + query + "'"
|
|
88
|
+
else:
|
|
89
|
+
lines = ["Found " + str(len(facts)) + " facts:", ""]
|
|
90
|
+
for i, fact in enumerate(facts, 1):
|
|
91
|
+
lines.append(str(i) + ". " + str(fact))
|
|
92
|
+
context['output'] = "\n".join(lines)
|
|
93
|
+
|
|
94
|
+
except Exception as e:
|
|
95
|
+
import traceback
|
|
96
|
+
context['output'] = "KG search error: " + str(e) + "\n" + traceback.format_exc()
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
jinx_name: mem_search
|
|
2
|
+
description: Search memories (approved, pending, or all)
|
|
3
|
+
inputs:
|
|
4
|
+
- query: ""
|
|
5
|
+
- status: "all"
|
|
6
|
+
- npc_name: ""
|
|
7
|
+
- team_name: ""
|
|
8
|
+
- max_results: "10"
|
|
9
|
+
- db_path: ""
|
|
10
|
+
|
|
11
|
+
steps:
|
|
12
|
+
- name: search_memories
|
|
13
|
+
engine: python
|
|
14
|
+
code: |
|
|
15
|
+
import os
|
|
16
|
+
|
|
17
|
+
query = context.get('query', '').strip()
|
|
18
|
+
if not query:
|
|
19
|
+
lines = [
|
|
20
|
+
"Usage: /mem_search <query> [status=all|approved|pending]",
|
|
21
|
+
"",
|
|
22
|
+
"Options:",
|
|
23
|
+
" status - Filter by status (all, approved, pending). Default is all",
|
|
24
|
+
" npc_name - Filter by NPC name",
|
|
25
|
+
" team_name - Filter by team name",
|
|
26
|
+
" max_results - Max results to return (default 10)",
|
|
27
|
+
" db_path - Path to history database",
|
|
28
|
+
]
|
|
29
|
+
context['output'] = "\n".join(lines)
|
|
30
|
+
else:
|
|
31
|
+
status_filter = context.get('status', 'all').lower()
|
|
32
|
+
npc_name = context.get('npc_name') or (npc.name if npc else None)
|
|
33
|
+
team_name = context.get('team_name') or None
|
|
34
|
+
try:
|
|
35
|
+
team_name = team_name or (state.team.name if 'state' in dir() and state and state.team else None)
|
|
36
|
+
except:
|
|
37
|
+
pass
|
|
38
|
+
max_results = int(context.get('max_results') or 10)
|
|
39
|
+
db_path = context.get('db_path') or os.path.expanduser("~/.npcsh/npcsh_history.db")
|
|
40
|
+
current_path = os.getcwd()
|
|
41
|
+
|
|
42
|
+
try:
|
|
43
|
+
cmd_history = CommandHistory(db_path)
|
|
44
|
+
|
|
45
|
+
if status_filter == 'approved':
|
|
46
|
+
state_obj = state if 'state' in dir() else None
|
|
47
|
+
memories = get_relevant_memories(
|
|
48
|
+
command_history=cmd_history,
|
|
49
|
+
npc_name=npc_name or '__none__',
|
|
50
|
+
team_name=team_name or '__none__',
|
|
51
|
+
path=current_path,
|
|
52
|
+
query=query,
|
|
53
|
+
max_memories=max_results,
|
|
54
|
+
state=state_obj
|
|
55
|
+
)
|
|
56
|
+
else:
|
|
57
|
+
memories = cmd_history.search_memories(
|
|
58
|
+
query=query,
|
|
59
|
+
npc_name=npc_name,
|
|
60
|
+
team_name=team_name,
|
|
61
|
+
status=status_filter if status_filter != 'all' else None,
|
|
62
|
+
limit=max_results
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
if not memories:
|
|
66
|
+
context['output'] = "No memories found for '" + query + "' (status=" + status_filter + ")"
|
|
67
|
+
else:
|
|
68
|
+
lines = ["Found " + str(len(memories)) + " memories (status=" + status_filter + "):", ""]
|
|
69
|
+
for i, mem in enumerate(memories, 1):
|
|
70
|
+
if isinstance(mem, dict):
|
|
71
|
+
ts = mem.get('timestamp', 'unknown')
|
|
72
|
+
content = mem.get('final_memory') or mem.get('initial_memory') or mem.get('content', '')
|
|
73
|
+
status = mem.get('status', '')
|
|
74
|
+
lines.append(str(i) + ". [" + str(ts) + "] (" + status + ") " + str(content))
|
|
75
|
+
else:
|
|
76
|
+
lines.append(str(i) + ". " + str(mem))
|
|
77
|
+
context['output'] = "\n".join(lines)
|
|
78
|
+
except Exception as e:
|
|
79
|
+
import traceback
|
|
80
|
+
context['output'] = "Memory search error: " + str(e) + "\n" + traceback.format_exc()
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
jinx_name: nql
|
|
2
2
|
description: "Run NPC-SQL models with AI-powered transformations. Supports cron scheduling."
|
|
3
3
|
inputs:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
- models_dir: "~/.npcsh/npc_team/models"
|
|
5
|
+
- db: "~/npcsh_history.db"
|
|
6
|
+
- model: ""
|
|
7
|
+
- schema: ""
|
|
8
|
+
- show: ""
|
|
9
|
+
- cron: ""
|
|
10
|
+
- install_cron: ""
|
|
11
11
|
|
|
12
12
|
steps:
|
|
13
13
|
- name: run_nql
|
|
@@ -3,9 +3,9 @@ description: |
|
|
|
3
3
|
Open a browser and navigate to a URL. The browser stays open for follow-up commands.
|
|
4
4
|
Use this to start browser automation.
|
|
5
5
|
inputs:
|
|
6
|
-
|
|
6
|
+
- url:
|
|
7
7
|
description: "URL to navigate to"
|
|
8
|
-
|
|
8
|
+
- browser: "firefox"
|
|
9
9
|
|
|
10
10
|
steps:
|
|
11
11
|
- name: open_browser
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
jinx_name: studio.open_pane
|
|
2
|
+
description: Open a new pane in NPC Studio. Supports editor, terminal, browser, pdf, csv, chat, image, folder, and other content types.
|
|
3
|
+
inputs:
|
|
4
|
+
- type: ""
|
|
5
|
+
- path: ""
|
|
6
|
+
- position: "right"
|
|
7
|
+
steps:
|
|
8
|
+
- name: frontend_action
|
|
9
|
+
engine: python
|
|
10
|
+
code: |
|
|
11
|
+
# This action is executed by the NPC Studio frontend
|
|
12
|
+
# The frontend intercepts studio.* tool calls and handles them directly
|
|
13
|
+
context['output'] = "Action executed by frontend"
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
jinx_name: "ots"
|
|
2
2
|
description: "Take screenshot and analyze with vision model. Usage: /ots <prompt>"
|
|
3
3
|
inputs:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
- prompt
|
|
5
|
+
- image_paths_args: ""
|
|
6
|
+
- vmodel: ""
|
|
7
|
+
- vprovider: ""
|
|
8
8
|
steps:
|
|
9
9
|
- name: "analyze_screenshot_or_image"
|
|
10
10
|
engine: "python"
|
|
@@ -38,10 +38,10 @@ steps:
|
|
|
38
38
|
print(f"📸 Screenshot captured: {screenshot_info.get('filename', os.path.basename(screenshot_info['file_path']))}")
|
|
39
39
|
|
|
40
40
|
if not vision_model:
|
|
41
|
-
vision_model = getattr(current_npc, 'model', '
|
|
42
|
-
|
|
41
|
+
vision_model = getattr(current_npc, 'model', None) or (state.vision_model if state else 'llama3.2')
|
|
42
|
+
|
|
43
43
|
if not vision_provider:
|
|
44
|
-
vision_provider = getattr(current_npc, 'provider', 'ollama')
|
|
44
|
+
vision_provider = getattr(current_npc, 'provider', None) or (state.vision_provider if state else 'ollama')
|
|
45
45
|
|
|
46
46
|
response_data = get_llm_response(
|
|
47
47
|
prompt=user_prompt,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
jinx_name: paper_search
|
|
2
2
|
description: Search for academic papers across multiple sources (Semantic Scholar, arXiv, local datasets)
|
|
3
3
|
inputs:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
- query: ""
|
|
5
|
+
- limit: 10
|
|
6
|
+
- source: "all"
|
|
7
7
|
steps:
|
|
8
8
|
- name: search_papers
|
|
9
9
|
engine: python
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
jinx_name: studio.read_pane
|
|
2
|
+
description: Read the contents of a pane. For editor panes returns file content, for chat panes returns messages, for browser panes returns URL/title.
|
|
3
|
+
inputs:
|
|
4
|
+
- paneId: "active"
|
|
5
|
+
steps:
|
|
6
|
+
- name: frontend_action
|
|
7
|
+
engine: python
|
|
8
|
+
code: |
|
|
9
|
+
context['output'] = "Action executed by frontend"
|
|
@@ -1,47 +1,44 @@
|
|
|
1
1
|
jinx_name: "roll"
|
|
2
2
|
description: "Generate a video from a text prompt."
|
|
3
3
|
inputs:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
- prompt: ""
|
|
5
|
+
- vgmodel: ""
|
|
6
|
+
- vgprovider: ""
|
|
7
|
+
- num_frames: 125
|
|
8
|
+
- width: 256
|
|
9
|
+
- height: 256
|
|
10
|
+
- output_path: "output.mp4"
|
|
11
11
|
steps:
|
|
12
12
|
- name: "generate_video"
|
|
13
13
|
engine: "python"
|
|
14
14
|
code: |
|
|
15
15
|
import traceback
|
|
16
16
|
from npcpy.llm_funcs import gen_video
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
|
|
19
18
|
prompt = context.get('prompt')
|
|
20
|
-
num_frames = int(context.get('num_frames', 125))
|
|
21
|
-
width = int(context.get('width', 256))
|
|
22
|
-
height = int(context.get('height', 256))
|
|
19
|
+
num_frames = int(context.get('num_frames', 125))
|
|
20
|
+
width = int(context.get('width', 256))
|
|
21
|
+
height = int(context.get('height', 256))
|
|
23
22
|
output_path = context.get('output_path')
|
|
24
23
|
video_gen_model = context.get('vgmodel')
|
|
25
24
|
video_gen_provider = context.get('vgprovider')
|
|
26
25
|
output_messages = context.get('messages', [])
|
|
27
26
|
current_npc = context.get('npc')
|
|
28
|
-
|
|
27
|
+
|
|
29
28
|
if not prompt or not prompt.strip():
|
|
30
29
|
context['output'] = "Usage: /roll <your prompt>"
|
|
31
30
|
context['messages'] = output_messages
|
|
32
31
|
exit()
|
|
33
32
|
|
|
34
|
-
# Fallback for model/provider if not explicitly set in Jinx inputs
|
|
35
33
|
if not video_gen_model and current_npc and current_npc.model:
|
|
36
34
|
video_gen_model = current_npc.model
|
|
37
35
|
if not video_gen_provider and current_npc and current_npc.provider:
|
|
38
36
|
video_gen_provider = current_npc.provider
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
video_gen_provider = "diffusers" # Example default
|
|
37
|
+
|
|
38
|
+
if not video_gen_model:
|
|
39
|
+
video_gen_model = "stable-video-diffusion"
|
|
40
|
+
if not video_gen_provider:
|
|
41
|
+
video_gen_provider = "diffusers"
|
|
45
42
|
|
|
46
43
|
try:
|
|
47
44
|
result = gen_video(
|
|
@@ -53,9 +50,9 @@ steps:
|
|
|
53
50
|
width=width,
|
|
54
51
|
height=height,
|
|
55
52
|
output_path=output_path,
|
|
56
|
-
**context.get('api_kwargs', {})
|
|
53
|
+
**context.get('api_kwargs', {})
|
|
57
54
|
)
|
|
58
|
-
|
|
55
|
+
|
|
59
56
|
if isinstance(result, dict):
|
|
60
57
|
context['output'] = result.get('output', 'Video generated.')
|
|
61
58
|
context['messages'] = result.get('messages', output_messages)
|
|
@@ -65,4 +62,4 @@ steps:
|
|
|
65
62
|
except Exception as e:
|
|
66
63
|
traceback.print_exc()
|
|
67
64
|
context['output'] = f"Error generating video: {e}"
|
|
68
|
-
context['messages'] = output_messages
|
|
65
|
+
context['messages'] = output_messages
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
jinx_name: "sample"
|
|
2
2
|
description: "Send a prompt directly to the LLM."
|
|
3
3
|
inputs:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
- prompt: ""
|
|
5
|
+
- model: ""
|
|
6
|
+
- provider: ""
|
|
7
7
|
steps:
|
|
8
8
|
- name: "send_prompt_to_llm"
|
|
9
9
|
engine: "python"
|
|
@@ -28,9 +28,9 @@ steps:
|
|
|
28
28
|
if not llm_provider and current_npc and current_npc.provider:
|
|
29
29
|
llm_provider = current_npc.provider
|
|
30
30
|
|
|
31
|
-
# Final fallbacks
|
|
32
|
-
if not llm_model: llm_model =
|
|
33
|
-
if not llm_provider: llm_provider =
|
|
31
|
+
# Final fallbacks from state
|
|
32
|
+
if not llm_model: llm_model = state.chat_model if state else "llama3.2"
|
|
33
|
+
if not llm_provider: llm_provider = state.chat_provider if state else "ollama"
|
|
34
34
|
|
|
35
35
|
try:
|
|
36
36
|
result = get_llm_response(
|
|
@@ -38,7 +38,6 @@ steps:
|
|
|
38
38
|
model=llm_model,
|
|
39
39
|
provider=llm_provider,
|
|
40
40
|
npc=current_npc,
|
|
41
|
-
**{k:v for k,v in context.items() if k not in ['messages', 'prompt', 'model', 'provider']} # Pass other context
|
|
42
41
|
)
|
|
43
42
|
|
|
44
43
|
if isinstance(result, dict):
|