npcsh 1.0.36__tar.gz → 1.0.37__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.
- {npcsh-1.0.36 → npcsh-1.0.37}/PKG-INFO +1 -1
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/_state.py +1 -9
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/mcp_server.py +119 -7
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh.egg-info/PKG-INFO +1 -1
- {npcsh-1.0.36 → npcsh-1.0.37}/setup.py +2 -2
- {npcsh-1.0.36 → npcsh-1.0.37}/LICENSE +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/README.md +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/__init__.py +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/alicanto.py +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/corca.py +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/guac.py +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/mcp_helpers.py +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc.py +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/alicanto.npc +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/alicanto.png +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/corca.npc +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/corca.png +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/foreman.npc +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/frederic.npc +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/frederic4.png +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/guac.png +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/jinxs/bash_executer.jinx +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/jinxs/edit_file.jinx +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/jinxs/image_generation.jinx +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/jinxs/internet_search.jinx +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/jinxs/python_executor.jinx +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/jinxs/screen_cap.jinx +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/kadiefa.npc +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/kadiefa.png +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/npcsh.ctx +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/npcsh_sibiji.png +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/plonk.npc +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/plonk.png +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/plonkjr.npc +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/plonkjr.png +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/sibiji.npc +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/sibiji.png +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/spool.png +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npc_team/yap.png +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/npcsh.py +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/plonk.py +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/pti.py +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/routes.py +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/spool.py +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/wander.py +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh/yap.py +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh.egg-info/SOURCES.txt +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh.egg-info/dependency_links.txt +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh.egg-info/entry_points.txt +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh.egg-info/requires.txt +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/npcsh.egg-info/top_level.txt +0 -0
- {npcsh-1.0.36 → npcsh-1.0.37}/setup.cfg +0 -0
|
@@ -2458,18 +2458,10 @@ def setup_shell() -> Tuple[CommandHistory, Team, Optional[NPC]]:
|
|
|
2458
2458
|
|
|
2459
2459
|
|
|
2460
2460
|
|
|
2461
|
-
from npcpy.memory.memory_processor import
|
|
2461
|
+
from npcpy.memory.memory_processor import memory_approval_ui
|
|
2462
2462
|
from npcpy.ft.memory_trainer import MemoryTrainer
|
|
2463
2463
|
from npcpy.llm_funcs import get_facts
|
|
2464
2464
|
|
|
2465
|
-
_memory_queue = None
|
|
2466
|
-
|
|
2467
|
-
def get_memory_queue(command_history):
|
|
2468
|
-
global _memory_queue
|
|
2469
|
-
if _memory_queue is None:
|
|
2470
|
-
_memory_queue = MemoryApprovalQueue(command_history)
|
|
2471
|
-
_memory_queue.start_background_processing()
|
|
2472
|
-
return _memory_queue
|
|
2473
2465
|
|
|
2474
2466
|
def format_memory_context(memory_examples):
|
|
2475
2467
|
if not memory_examples:
|
|
@@ -14,6 +14,7 @@ from typing import Optional, Dict, Any, List, Union, Callable
|
|
|
14
14
|
from mcp.server.fastmcp import FastMCP
|
|
15
15
|
import importlib
|
|
16
16
|
|
|
17
|
+
from sqlalchemy import text
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
import os
|
|
@@ -46,14 +47,129 @@ mcp = FastMCP("npcsh_mcp")
|
|
|
46
47
|
DEFAULT_WORKSPACE = os.path.join(os.getcwd(), "workspace")
|
|
47
48
|
os.makedirs(DEFAULT_WORKSPACE, exist_ok=True)
|
|
48
49
|
|
|
50
|
+
@mcp.tool()
|
|
51
|
+
async def add_memory(
|
|
52
|
+
npc_name: str,
|
|
53
|
+
team_name: str,
|
|
54
|
+
content: str,
|
|
55
|
+
memory_type: str = "observation",
|
|
56
|
+
directory_path: str = None
|
|
57
|
+
) -> str:
|
|
58
|
+
"""
|
|
59
|
+
Add a memory entry to the database.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
npc_name: Name of the NPC this memory belongs to
|
|
63
|
+
team_name: Name of the team the NPC belongs to
|
|
64
|
+
content: The memory content to store
|
|
65
|
+
memory_type: Type of memory (observation, preference, achievement, etc.)
|
|
66
|
+
directory_path: Directory path context (defaults to current working directory)
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
Success message with memory ID or error message
|
|
70
|
+
"""
|
|
71
|
+
if directory_path is None:
|
|
72
|
+
directory_path = os.getcwd()
|
|
73
|
+
|
|
74
|
+
try:
|
|
75
|
+
from npcpy.memory.command_history import generate_message_id
|
|
76
|
+
message_id = generate_message_id()
|
|
77
|
+
|
|
78
|
+
memory_id = command_history.add_memory_to_database(
|
|
79
|
+
message_id=message_id,
|
|
80
|
+
conversation_id='mcp_direct',
|
|
81
|
+
npc=npc_name,
|
|
82
|
+
team=team_name,
|
|
83
|
+
directory_path=directory_path,
|
|
84
|
+
initial_memory=content,
|
|
85
|
+
status='active',
|
|
86
|
+
model=None,
|
|
87
|
+
provider=None
|
|
88
|
+
)
|
|
89
|
+
return f"Memory created successfully with ID: {memory_id}"
|
|
90
|
+
except Exception as e:
|
|
91
|
+
return f"Error creating memory: {str(e)}"
|
|
49
92
|
|
|
50
93
|
@mcp.tool()
|
|
51
|
-
async def
|
|
94
|
+
async def search_memory(
|
|
95
|
+
query: str,
|
|
96
|
+
npc_name: str = None,
|
|
97
|
+
team_name: str = None,
|
|
98
|
+
directory_path: str = None,
|
|
99
|
+
status_filter: str = None,
|
|
100
|
+
limit: int = 10
|
|
101
|
+
) -> str:
|
|
102
|
+
"""
|
|
103
|
+
Search memories in the database.
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
query: Search query text
|
|
107
|
+
npc_name: Filter by specific NPC (optional)
|
|
108
|
+
team_name: Filter by specific team (optional)
|
|
109
|
+
directory_path: Filter by directory path (optional)
|
|
110
|
+
status_filter: Filter by memory status (active, archived, etc.)
|
|
111
|
+
limit: Maximum number of results to return
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
JSON string of matching memories or error message
|
|
115
|
+
"""
|
|
116
|
+
if directory_path is None:
|
|
117
|
+
directory_path = os.getcwd()
|
|
118
|
+
|
|
119
|
+
try:
|
|
120
|
+
results = command_history.search_memory(
|
|
121
|
+
query=query,
|
|
122
|
+
npc=npc_name,
|
|
123
|
+
team=team_name,
|
|
124
|
+
directory_path=directory_path,
|
|
125
|
+
status_filter=status_filter,
|
|
126
|
+
limit=limit
|
|
127
|
+
)
|
|
128
|
+
return json.dumps(results, indent=2)
|
|
129
|
+
except Exception as e:
|
|
130
|
+
return f"Error searching memories: {str(e)}"
|
|
131
|
+
|
|
132
|
+
@mcp.tool()
|
|
133
|
+
async def query_npcsh_database(sql_query: str) -> str:
|
|
134
|
+
"""
|
|
135
|
+
Execute a SQL query against the npcsh_history.db database.
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
sql_query: SQL query to execute (SELECT statements only for safety)
|
|
139
|
+
|
|
140
|
+
Returns:
|
|
141
|
+
JSON string of query results or error message
|
|
142
|
+
"""
|
|
143
|
+
# Safety check - only allow SELECT queries
|
|
144
|
+
if not sql_query.strip().upper().startswith('SELECT'):
|
|
145
|
+
return "Error: Only SELECT queries are allowed for safety"
|
|
146
|
+
|
|
147
|
+
try:
|
|
148
|
+
with command_history.engine.connect() as conn:
|
|
149
|
+
result = conn.execute(text(sql_query))
|
|
150
|
+
rows = result.fetchall()
|
|
151
|
+
|
|
152
|
+
if not rows:
|
|
153
|
+
return "Query executed successfully but returned no results"
|
|
154
|
+
|
|
155
|
+
# Convert to list of dictionaries
|
|
156
|
+
columns = result.keys()
|
|
157
|
+
results = []
|
|
158
|
+
for row in rows:
|
|
159
|
+
row_dict = dict(zip(columns, row))
|
|
160
|
+
results.append(row_dict)
|
|
161
|
+
|
|
162
|
+
return json.dumps(results, indent=2, default=str)
|
|
163
|
+
except Exception as e:
|
|
164
|
+
return f"Database query error: {str(e)}"
|
|
165
|
+
@mcp.tool()
|
|
166
|
+
async def run_server_command(command: str, wd: str) -> str:
|
|
52
167
|
"""
|
|
53
168
|
Run a terminal command in the workspace.
|
|
54
169
|
|
|
55
170
|
Args:
|
|
56
171
|
command: The shell command to run
|
|
172
|
+
wd: The working directory to run the command in
|
|
57
173
|
|
|
58
174
|
Returns:
|
|
59
175
|
The command output or an error message.
|
|
@@ -61,7 +177,7 @@ async def run_server_command(command: str) -> str:
|
|
|
61
177
|
try:
|
|
62
178
|
result = subprocess.run(
|
|
63
179
|
command,
|
|
64
|
-
cwd=
|
|
180
|
+
cwd=wd,
|
|
65
181
|
shell=True,
|
|
66
182
|
capture_output=True,
|
|
67
183
|
text=True,
|
|
@@ -147,11 +263,7 @@ print("Loading tools from npcpy modules...")
|
|
|
147
263
|
|
|
148
264
|
|
|
149
265
|
def register_selected_npcpy_tools():
|
|
150
|
-
tools = [
|
|
151
|
-
abstract,
|
|
152
|
-
extract_facts,
|
|
153
|
-
zoom_in,
|
|
154
|
-
execute_llm_command,
|
|
266
|
+
tools = [
|
|
155
267
|
gen_image,
|
|
156
268
|
load_file_contents,
|
|
157
269
|
capture_screenshot,
|
|
@@ -78,7 +78,7 @@ extra_files = package_files("npcsh/npc_team/")
|
|
|
78
78
|
|
|
79
79
|
setup(
|
|
80
80
|
name="npcsh",
|
|
81
|
-
version="1.0.
|
|
81
|
+
version="1.0.37",
|
|
82
82
|
packages=find_packages(exclude=["tests*"]),
|
|
83
83
|
install_requires=base_requirements, # Only install base requirements by default
|
|
84
84
|
extras_require={
|
|
@@ -96,7 +96,7 @@ setup(
|
|
|
96
96
|
"pti=npcsh.pti:main",
|
|
97
97
|
"guac=npcsh.guac:main",
|
|
98
98
|
"wander=npcsh.wander:main",
|
|
99
|
-
"spool=npcsh.spool:main",
|
|
99
|
+
"spool=npcsh.spool:main",
|
|
100
100
|
],
|
|
101
101
|
},
|
|
102
102
|
author="Christopher Agostino",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|