Skip to content

Commit 0f51a85

Browse files
fix: Rename list_skills to skills_discover and fix linting errors
- Update __all__ export from list_skills to skills_discover - Fix docstring examples to use correct function name - Update test imports and test function to use skills_discover - Fix all whitespace and import formatting issues in tests - Update test to be async and mock correct methods
1 parent b15dfe3 commit 0f51a85

3 files changed

Lines changed: 53 additions & 51 deletions

File tree

src/nexus_client/langgraph/prompt.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from nexus_client.langgraph.client import _get_nexus_client
1313

1414
__all__ = [
15-
"list_skills",
15+
"skills_discover",
1616
"get_prompt_context",
1717
]
1818

@@ -74,19 +74,19 @@ async def skills_discover(
7474
7575
Examples:
7676
>>> from langchain_core.runnables import RunnableConfig
77-
>>> from nexus_client.langgraph.prompt import list_skills
77+
>>> from nexus_client.langgraph.prompt import skills_discover
7878
>>>
7979
>>> config = RunnableConfig(metadata={
8080
... "x_auth": "Bearer sk-your-api-key",
8181
... "nexus_server_url": "http://localhost:8080"
8282
... })
8383
>>>
8484
>>> # Get subscribed skills (default)
85-
>>> result = await list_skills(config)
85+
>>> result = await skills_discover(config)
8686
>>> print(f"Found {result['count']} skills")
8787
>>>
8888
>>> # Get all available skills
89-
>>> result = await list_skills(config, filter="available")
89+
>>> result = await skills_discover(config, filter="all")
9090
>>> print(f"Found {result['count']} available skills")
9191
"""
9292
try:

tests/test_langgraph_tools.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
if HAS_LANGGRAPH:
1616
from nexus_client import RemoteNexusFS
17-
from nexus_client.langgraph import get_nexus_tools, list_skills
17+
from nexus_client.langgraph import get_nexus_tools, skills_discover
1818
from nexus_client.langgraph.client import _get_nexus_client
1919

2020

@@ -79,33 +79,34 @@ def test_get_nexus_client_from_state(self):
7979

8080

8181
@pytest.mark.skipif(not HAS_LANGGRAPH, reason="LangGraph dependencies not installed")
82-
class TestListSkills:
83-
"""Test list_skills function."""
82+
class TestSkillsDiscover:
83+
"""Test skills_discover function."""
8484

85-
def test_list_skills(self):
86-
"""Test list_skills function."""
85+
@pytest.mark.asyncio
86+
async def test_skills_discover(self):
87+
"""Test skills_discover function."""
8788
config = RunnableConfig(
8889
metadata={
8990
"x_auth": "Bearer sk-test-key",
9091
"nexus_server_url": "http://localhost:8080",
9192
}
9293
)
9394

94-
# Mock the client to avoid actual RPC calls
95-
# Need to patch both _get_nexus_client and the client's skills_list method
96-
with patch("nexus_client.langgraph.tools._get_nexus_client") as mock_get_client:
97-
mock_client = Mock(spec=RemoteNexusFS)
98-
mock_client.skills_list.return_value = {
95+
# Mock the async client to avoid actual RPC calls
96+
# Need to patch _get_nexus_client and the client's skills_discover method
97+
with patch("nexus_client.langgraph.prompt._get_nexus_client") as mock_get_client:
98+
mock_client = Mock()
99+
mock_client.skills_discover.return_value = {
99100
"skills": [{"name": "test-skill", "description": "Test"}],
100101
"count": 1,
101102
}
102103
mock_get_client.return_value = mock_client
103104

104-
result = list_skills(config)
105+
result = await skills_discover(config)
105106
assert "skills" in result
106107
assert "count" in result
107108
assert result["count"] == 1
108-
# Verify the client was created and skills_list was called
109-
mock_get_client.assert_called_once_with(config, None)
110-
mock_client.skills_list.assert_called_once_with(tier=None, include_metadata=True)
109+
# Verify the client was created and skills_discover was called
110+
mock_get_client.assert_called_once()
111+
mock_client.skills_discover.assert_called_once_with(filter="subscribed")
111112

tests/test_read_file_path_parsing.py

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,203 +1,204 @@
11
"""Unit tests for read_file path parsing with spaces."""
2-
import pytest
32
import shlex
43

4+
import pytest
5+
56

67
def parse_read_cmd(read_cmd: str) -> tuple[str, str, int | None, int | None]:
78
"""
89
Parse read command and extract path, command, and optional line numbers.
910
This mirrors the logic in tools.py read_file function.
10-
11+
1112
Returns:
1213
(command, path, start_line, end_line)
1314
"""
1415
parts = shlex.split(read_cmd.strip())
1516
if not parts:
1617
raise ValueError("Empty command")
17-
18+
1819
start_line = None
1920
end_line = None
20-
21+
2122
if parts[0] in ["cat", "less"]:
2223
command = parts[0]
2324
if len(parts) < 2:
2425
raise ValueError(f"Missing file path for {command}")
25-
26+
2627
# Handle unquoted paths with spaces
2728
path_parts = []
2829
remaining_parts = []
29-
30+
3031
for i, part in enumerate(parts[1:], 1):
3132
try:
3233
int(part)
3334
remaining_parts = parts[i:]
3435
break
3536
except ValueError:
3637
path_parts.append(part)
37-
38+
3839
path = " ".join(path_parts)
39-
40+
4041
if remaining_parts:
4142
if len(remaining_parts) >= 1:
4243
start_line = int(remaining_parts[0])
4344
if len(remaining_parts) >= 2:
4445
end_line = int(remaining_parts[1])
4546
else:
4647
command = "cat"
47-
48+
4849
path_parts = []
4950
remaining_parts = []
50-
51+
5152
for i, part in enumerate(parts):
5253
try:
5354
int(part)
5455
remaining_parts = parts[i:]
5556
break
5657
except ValueError:
5758
path_parts.append(part)
58-
59+
5960
path = " ".join(path_parts) if path_parts else parts[0]
60-
61+
6162
if remaining_parts:
6263
if len(remaining_parts) >= 1:
6364
start_line = int(remaining_parts[0])
6465
if len(remaining_parts) >= 2:
6566
end_line = int(remaining_parts[1])
66-
67+
6768
return command, path, start_line, end_line
6869

6970

7071
class TestReadFilePathParsing:
7172
"""Test suite for read_file path parsing with various scenarios."""
72-
73+
7374
def test_simple_cat(self):
7475
"""Test simple cat command without spaces."""
7576
cmd, path, start, end = parse_read_cmd("cat /workspace/file.txt")
7677
assert cmd == "cat"
7778
assert path == "/workspace/file.txt"
7879
assert start is None
7980
assert end is None
80-
81+
8182
def test_simple_less(self):
8283
"""Test simple less command without spaces."""
8384
cmd, path, start, end = parse_read_cmd("less /workspace/file.txt")
8485
assert cmd == "less"
8586
assert path == "/workspace/file.txt"
8687
assert start is None
8788
assert end is None
88-
89+
8990
def test_no_command_defaults_to_cat(self):
9091
"""Test that omitting command defaults to cat."""
9192
cmd, path, start, end = parse_read_cmd("/workspace/file.txt")
9293
assert cmd == "cat"
9394
assert path == "/workspace/file.txt"
9495
assert start is None
9596
assert end is None
96-
97+
9798
def test_cat_with_start_line(self):
9899
"""Test cat command with start line number."""
99100
cmd, path, start, end = parse_read_cmd("cat /workspace/file.txt 10")
100101
assert cmd == "cat"
101102
assert path == "/workspace/file.txt"
102103
assert start == 10
103104
assert end is None
104-
105+
105106
def test_cat_with_start_and_end_lines(self):
106107
"""Test cat command with start and end line numbers."""
107108
cmd, path, start, end = parse_read_cmd("cat /workspace/file.txt 10 20")
108109
assert cmd == "cat"
109110
assert path == "/workspace/file.txt"
110111
assert start == 10
111112
assert end == 20
112-
113+
113114
def test_no_command_with_line_numbers(self):
114115
"""Test path without command but with line numbers."""
115116
cmd, path, start, end = parse_read_cmd("/workspace/file.txt 10 20")
116117
assert cmd == "cat"
117118
assert path == "/workspace/file.txt"
118119
assert start == 10
119120
assert end == 20
120-
121+
121122
def test_unquoted_path_with_spaces(self):
122123
"""Test unquoted path containing spaces."""
123124
cmd, path, start, end = parse_read_cmd("less /path/Procare Oct25 cash transactions.md")
124125
assert cmd == "less"
125126
assert path == "/path/Procare Oct25 cash transactions.md"
126127
assert start is None
127128
assert end is None
128-
129+
129130
def test_unquoted_path_with_one_space(self):
130131
"""Test unquoted path with single space."""
131132
cmd, path, start, end = parse_read_cmd("cat /workspace/my file.txt")
132133
assert cmd == "cat"
133134
assert path == "/workspace/my file.txt"
134135
assert start is None
135136
assert end is None
136-
137+
137138
def test_no_command_unquoted_spaces(self):
138139
"""Test path without command containing spaces."""
139140
cmd, path, start, end = parse_read_cmd("/workspace/my file with spaces.txt")
140141
assert cmd == "cat"
141142
assert path == "/workspace/my file with spaces.txt"
142143
assert start is None
143144
assert end is None
144-
145+
145146
def test_spaces_with_line_numbers(self):
146147
"""Test unquoted path with spaces AND line numbers."""
147148
cmd, path, start, end = parse_read_cmd("cat /workspace/my file.txt 1 100")
148149
assert cmd == "cat"
149150
assert path == "/workspace/my file.txt"
150151
assert start == 1
151152
assert end == 100
152-
153+
153154
def test_spaces_with_start_line_only(self):
154155
"""Test unquoted path with spaces and start line."""
155156
cmd, path, start, end = parse_read_cmd("less /path/Procare Oct25 transactions.md 50")
156157
assert cmd == "less"
157158
assert path == "/path/Procare Oct25 transactions.md"
158159
assert start == 50
159160
assert end is None
160-
161+
161162
def test_no_command_spaces_and_lines(self):
162163
"""Test no command with spaces and line numbers."""
163164
cmd, path, start, end = parse_read_cmd("/workspace/my file.txt 5 15")
164165
assert cmd == "cat"
165166
assert path == "/workspace/my file.txt"
166167
assert start == 5
167168
assert end == 15
168-
169+
169170
def test_quoted_path_with_spaces(self):
170171
"""Test quoted path with spaces (backwards compatibility)."""
171172
cmd, path, start, end = parse_read_cmd('cat "/workspace/my file.txt"')
172173
assert cmd == "cat"
173174
assert path == "/workspace/my file.txt"
174175
assert start is None
175176
assert end is None
176-
177+
177178
def test_quoted_complex_path(self):
178179
"""Test quoted path with complex filename."""
179180
cmd, path, start, end = parse_read_cmd('less "/path/Procare Oct25 cash transactions.md"')
180181
assert cmd == "less"
181182
assert path == "/path/Procare Oct25 cash transactions.md"
182183
assert start is None
183184
assert end is None
184-
185+
185186
def test_quoted_path_with_line_numbers(self):
186187
"""Test quoted path with line numbers."""
187188
cmd, path, start, end = parse_read_cmd('"/workspace/my file.txt" 10 20')
188189
assert cmd == "cat"
189190
assert path == "/workspace/my file.txt"
190191
assert start == 10
191192
assert end == 20
192-
193+
193194
def test_virtual_parsed_file(self):
194195
"""Test virtual _parsed.{ext}.md file path."""
195196
cmd, path, start, end = parse_read_cmd("cat /path/file_parsed.pdf.md")
196197
assert cmd == "cat"
197198
assert path == "/path/file_parsed.pdf.md"
198199
assert start is None
199200
assert end is None
200-
201+
201202
def test_long_tenant_path_with_spaces(self):
202203
"""Test long tenant/user path with spaces in filename."""
203204
input_cmd = "less /tenant:smooth-flame-13/user:xxx/workspace/ws_personal_b37483e0b292/Procare Oct25 cash transactions 9.28-11.1.25_parsed.xlsx.md"
@@ -206,17 +207,17 @@ def test_long_tenant_path_with_spaces(self):
206207
assert path == "/tenant:smooth-flame-13/user:xxx/workspace/ws_personal_b37483e0b292/Procare Oct25 cash transactions 9.28-11.1.25_parsed.xlsx.md"
207208
assert start is None
208209
assert end is None
209-
210+
210211
def test_empty_command_raises_error(self):
211212
"""Test that empty command raises ValueError."""
212213
with pytest.raises(ValueError, match="Empty command"):
213214
parse_read_cmd("")
214-
215+
215216
def test_cat_without_path_raises_error(self):
216217
"""Test that cat without path raises ValueError."""
217218
with pytest.raises(ValueError, match="Missing file path"):
218219
parse_read_cmd("cat")
219-
220+
220221
def test_less_without_path_raises_error(self):
221222
"""Test that less without path raises ValueError."""
222223
with pytest.raises(ValueError, match="Missing file path"):

0 commit comments

Comments
 (0)