Skip to content

Commit 09a9a2c

Browse files
committed
Added fall back for demo, test fixes, and timeouts
1 parent 87c4626 commit 09a9a2c

File tree

4 files changed

+96
-38
lines changed

4 files changed

+96
-38
lines changed

demo/app.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@
1616

1717
# Add sidebar with options
1818
st.sidebar.title("Settings")
19-
service_type = st.sidebar.radio("Select AI Service", ["ollama", "groq"])
19+
service_type = st.sidebar.radio("Select AI Service", ["ollama", "jan"])
2020
max_chars = st.sidebar.slider("Max Characters", 20, 150, 75)
2121
ollama_model = st.sidebar.text_input("Ollama Model", "llama3.1")
22-
groq_model = st.sidebar.text_input("Groq Model", "llama-3.1-70b-versatile")
2322

2423
# Main content
2524
git_diff = st.text_area("Paste your git diff here:", height=300)
@@ -34,7 +33,6 @@
3433
max_chars=max_chars,
3534
service_type=service_type,
3635
ollama_model=ollama_model,
37-
groq_model=groq_model,
3836
)
3937

4038
# Display results

demo/run.sh

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,31 @@ trap stopRunningProcess EXIT TERM
2222

2323
# Add streamlit to dependencies for the demo
2424
pip install streamlit
25+
pip install -e .
26+
27+
# First look for app.py in the same directory as this script
28+
SCRIPT_DIR="$(dirname "$0")"
29+
APP_PATH="$SCRIPT_DIR/app.py"
30+
31+
# Fall back to original path if not found
32+
if [ ! -f "$APP_PATH" ]; then
33+
echo "Looking for app.py in ${HOME}/blueprint/demo/"
34+
APP_PATH="${HOME}/blueprint/demo/app.py"
35+
36+
# Finally try current directory
37+
if [ ! -f "$APP_PATH" ]; then
38+
echo "Looking for app.py in current directory"
39+
APP_PATH="./app.py"
40+
41+
if [ ! -f "$APP_PATH" ]; then
42+
echo "Error: Could not find app.py in any location"
43+
exit 1
44+
fi
45+
fi
46+
fi
2547

26-
streamlit run ${HOME}/blueprint/demo/app.py &
27-
APP_ID=${!}
48+
echo "Found app.py at: $APP_PATH"
49+
streamlit run "$APP_PATH" &
50+
APP_PID=$!
2851

29-
wait ${APP_ID}
52+
wait $APP_PID

src/blueprint/ai_service.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ def _query_jan(self, prompt: str) -> str:
9292

9393
try:
9494
self.logger.debug("Making POST request to Jan AI API")
95-
response = requests.post(url, headers=headers, json=data)
95+
# Add timeout parameter to prevent hanging
96+
response = requests.post(url, headers=headers, json=data, timeout=60)
9697
self.logger.debug(
9798
f"Received response with status code: {response.status_code}"
9899
)
@@ -111,9 +112,15 @@ def _query_jan(self, prompt: str) -> str:
111112

112113
content = result["choices"][0]["message"]["content"]
113114
return content
115+
except requests.exceptions.ConnectionError as e:
116+
self.logger.error(f"Error connecting to Jan AI API: {e}")
117+
raise Exception("Error connecting to Jan AI: Is Jan AI running on localhost:1337?")
118+
except requests.exceptions.Timeout as e:
119+
self.logger.error(f"Jan AI API request timed out: {e}")
120+
raise Exception("Jan AI request timed out. Service may be overloaded.")
114121
except Exception as e:
115122
self.logger.error(f"Error querying Jan AI API: {e}")
116-
raise Exception(f"Error querying Jan AI API: {e}")
123+
raise Exception(f"Error with Jan AI: {str(e)[:100]}")
117124

118125
def _query_ollama(self, prompt: str) -> str:
119126
"""Send query to Ollama API.
@@ -133,7 +140,8 @@ def _query_ollama(self, prompt: str) -> str:
133140

134141
try:
135142
self.logger.debug("Making POST request to Ollama API")
136-
response = requests.post(url, json=data)
143+
# Add timeout parameter to prevent hanging
144+
response = requests.post(url, json=data, timeout=60)
137145
self.logger.debug(
138146
f"Received response with status code: {response.status_code}"
139147
)
@@ -150,6 +158,12 @@ def _query_ollama(self, prompt: str) -> str:
150158
self.logger.debug(f"Full response: {result}")
151159

152160
return result.get("response", "")
161+
except requests.exceptions.ConnectionError as e:
162+
self.logger.error(f"Error connecting to Ollama API: {e}")
163+
raise Exception("Error connecting to Ollama: Is Ollama running on localhost:11434?")
164+
except requests.exceptions.Timeout as e:
165+
self.logger.error(f"Ollama API request timed out: {e}")
166+
raise Exception("Ollama request timed out. Service may be overloaded or model is too large.")
153167
except Exception as e:
154168
self.logger.error(f"Error querying Ollama API: {e}")
155-
raise Exception(f"Error querying Ollama API: {e}")
169+
raise Exception(f"Error with Ollama: {str(e)[:100]}")

tests/unit/test_commit_generator.py

Lines changed: 51 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
get_git_diff,
1313
parse_commit_messages,
1414
query_ai_service,
15-
select_message_with_fzf,
1615
)
16+
from blueprint.cli import select_message_with_fzf
1717

1818
# Global patch for subprocess to prevent any real subprocess calls
1919
subprocess_mock = mock.patch("subprocess.run")
@@ -62,6 +62,35 @@ def mock_input(prompt=None):
6262
monkeypatch.setattr("builtins.input", mock_input)
6363

6464

65+
@pytest.fixture
66+
def sample_ai_response():
67+
"""Sample AI response for testing."""
68+
return """I've analyzed the git diff and summarized the changes.
69+
70+
1. Remove strip() from diff check and add strip() to parsed commit messages
71+
2. Fix string handling in git diff and commit message parsing
72+
3. Improve robustness of git diff checking and commit message parsing"""
73+
74+
75+
@pytest.fixture
76+
def sample_git_diff():
77+
"""Sample git diff for testing."""
78+
return """diff --git a/src/app.py b/src/app.py
79+
index 1234567..abcdefg 100644
80+
--- a/src/app.py
81+
+++ b/src/app.py
82+
@@ -10,7 +10,7 @@ def some_function():
83+
# This is a test function
84+
- x = input().strip()
85+
+ x = input()
86+
return x
87+
88+
@@ -20,7 +20,7 @@ def parse_message(msg):
89+
- return msg
90+
+ return msg.strip()
91+
"""
92+
93+
6594
@mock.patch("subprocess.check_output")
6695
def test_get_git_diff_staged_changes(mock_check_output):
6796
"""Test getting git diff with staged changes."""
@@ -75,7 +104,7 @@ def test_get_git_diff_staged_changes(mock_check_output):
75104

76105
# Assert
77106
assert result == "staged changes diff"
78-
mock_check_output.assert_called_with(["git", "diff", "--cached"], text=True)
107+
mock_check_output.assert_called_with(["git", "diff", "--cached", "--diff-filter=ACMTU"], text=True)
79108
assert mock_check_output.call_count == 1
80109

81110

@@ -96,26 +125,27 @@ def test_get_git_diff_unstaged_changes(mock_check_output):
96125
assert mock_check_output.call_count == 2
97126
mock_check_output.assert_has_calls(
98127
[
99-
mock.call(["git", "diff", "--cached"], text=True),
100-
mock.call(["git", "diff"], text=True),
128+
mock.call(["git", "diff", "--cached", "--diff-filter=ACMTU"], text=True),
129+
mock.call(["git", "diff", "--diff-filter=ACMTU"], text=True),
101130
]
102131
)
103132

104133

105134
@mock.patch("subprocess.check_output")
106-
def test_get_git_diff_max_chars(mock_check_output):
107-
"""Test limiting git diff to max_chars."""
135+
@mock.patch("blueprint.commit_generator.trim_diff")
136+
def test_get_git_diff_max_chars(mock_trim_diff, mock_check_output):
137+
"""Test limiting git diff to max_chars using trim_diff."""
108138
# Setup
109-
mock_check_output.side_effect = [
110-
"a" * 100, # Return a long string
111-
]
112-
139+
mock_check_output.return_value = "a" * 100 # Return a long string
140+
mock_trim_diff.return_value = "a" * 50 # Mocked trimmed output
141+
113142
# Execute
114143
result = get_git_diff(max_chars=50)
115144

116145
# Assert
117-
assert result == "a" * 50 # Should be truncated to 50 chars
118-
assert len(result) == 50
146+
assert result == "a" * 50
147+
# Verify trim_diff was called with the right parameters
148+
mock_trim_diff.assert_called_once_with("a" * 100, 50, False)
119149

120150

121151
@mock.patch("subprocess.check_output")
@@ -142,7 +172,7 @@ def test_query_ai_service_ollama(mock_ai_service):
142172

143173
# Assert
144174
assert result == "AI response"
145-
mock_ai_service.assert_called_with("ollama", model="llama3.1")
175+
mock_ai_service.assert_called_with("ollama", model="llama3.1", debug=False)
146176
mock_instance.query.assert_called_with("test prompt")
147177

148178

@@ -159,13 +189,12 @@ def test_query_ai_service_jan(mock_ai_service):
159189

160190
# Assert
161191
assert result == "AI response"
162-
mock_ai_service.assert_called_with("jan", model="Llama 3.1")
192+
mock_ai_service.assert_called_with("jan", model="Llama 3.1", debug=False)
163193
mock_instance.query.assert_called_with("test prompt")
164194

165-
166195
@mock.patch("blueprint.commit_generator.AIService")
167196
def test_query_ai_service_error(mock_ai_service):
168-
"""Test error handling in query_ai_service."""
197+
"""Test error handling in query_ai_service for Ollama."""
169198
# Setup
170199
mock_instance = mock_ai_service.return_value
171200
mock_instance.query.side_effect = Exception("API error")
@@ -345,11 +374,12 @@ def test_generate_commit_messages(mock_query_ai_service, sample_git_diff):
345374
]
346375
# Verify the prompt includes the specified max characters
347376
assert (
348-
f"Try to fit each commit message in 75 characters"
377+
f"Please keep it under 75 characters per message"
349378
in mock_query_ai_service.call_args[0][0]
350379
)
351380
# Verify the diff is included in the prompt
352-
assert sample_git_diff in mock_query_ai_service.call_args[0][0]
381+
assert "--- BEGIN GIT DIFF ---" in mock_query_ai_service.call_args[0][0]
382+
assert "--- END GIT DIFF ---" in mock_query_ai_service.call_args[0][0]
353383

354384

355385
@mock.patch("blueprint.commit_generator.query_ai_service")
@@ -374,28 +404,21 @@ def test_generate_commit_messages_custom_service(mock_query_ai_service):
374404
assert len(result) == 3
375405
# Check if custom service settings were passed correctly
376406
mock_query_ai_service.assert_called_with(
377-
mock.ANY, "jan", "custom-ollama", "custom-jan"
407+
mock.ANY, "jan", "custom-ollama", "custom-jan", debug=False
378408
)
379409
# Verify the prompt includes the custom max characters
380410
assert (
381-
f"Try to fit each commit message in 100 characters"
411+
f"Please keep it under 100 characters per message"
382412
in mock_query_ai_service.call_args[0][0]
383413
)
384414

385415

386-
@mock.patch("blueprint.commit_generator.select_message_with_fzf")
416+
@mock.patch("blueprint.cli.select_message_with_fzf")
387417
@mock.patch("blueprint.commit_generator.generate_commit_messages")
388418
@mock.patch("blueprint.commit_generator.get_git_diff")
389419
@mock.patch("blueprint.commit_generator.create_commit")
390420
def test_end_to_end_flow(mock_create, mock_get_diff, mock_generate, mock_select):
391421
"""Test the full end-to-end flow with mocked components."""
392-
from blueprint.commit_generator import (
393-
create_commit,
394-
generate_commit_messages,
395-
get_git_diff,
396-
select_message_with_fzf,
397-
)
398-
399422
# Setup
400423
mock_get_diff.return_value = "sample diff"
401424
mock_generate.return_value = ["Message 1", "Message 2", "Message 3"]

0 commit comments

Comments
 (0)