320 Commits

Author SHA1 Message Date
darthrubik 9e0b373d7e Merge pull request 'bugfix/broken-shell' (#34) from bugfix/broken-shell into master
Reviewed-on: https://192.168.8.63/git/darthrubik/drharness/pulls/34
2026-06-18 15:18:00 -05:00
hal9000 5680e8c6a9 Fix shell tool truncating output larger than buffer size
The shell tool was only reading once when data was available, which caused
data loss when the child process produced more output than the 4KB buffer.

Fixed by reading in a loop until EOF is reached in both the POLLHUP and
POLLIN handlers.
2026-06-18 15:14:13 -05:00
darthrubik e877eca085 Add failing test for tool calls 2026-06-18 15:14:13 -05:00
hal9000 5e96cb7ed8 Fix duplicate -R help line from merge conflict resolution
Remove duplicate '-R' help line that was incorrectly merged with
inconsistent indentation.
2026-06-15 22:56:38 +00:00
hal9000 861b73a050 Update issue status after merge completion
- Mark issue 169 as closed (merge completed)
- Unblock issue 93 (dependency on 169 satisfied)
2026-06-15 22:52:57 +00:00
hal9000 da919f9f6e Merge origin/master into work branch (issue #169)
Resolved merge conflicts:
- CMakeLists.txt: Added both rebase_engine/utility and base64_util sources
- src/harness.cpp: Combined Content type with proper error handling
- src/main.cpp: Merged includes, test flags, and CLI parsing
  - Renamed conflicting flags: -B→-Z (build_rebase), -T→-W (edit_prompt), -b→-K (base64_decode)
- tests/CMakeLists.txt: Added all test targets from both branches
- src/rebase_engine.cpp: Fixed to use get_content_string() for Content variant type
- Updated test files to use new flag names (-Z, -W, -K)
2026-06-15 22:52:29 +00:00
darthrubik f1b12151e5 Merge pull request 'Fixing Ollama server compatability' (#33) from bugfix/fix-api into master
Reviewed-on: https://192.168.8.63/git/darthrubik/drharness/pulls/33
2026-06-15 17:50:45 -05:00
darthrubik f66d9059df Merge pull request 'feature/multi-modal' (#32) from feature/multi-modal into master
Reviewed-on: https://192.168.8.63/git/darthrubik/drharness/pulls/32
2026-06-15 17:32:46 -05:00
hal9000 030e3f7656 Implement issue 167: Handle multimodal content in print_history pretty-print mode
The print_history function (used by -p flag) now properly displays multimodal
content by:
- Displaying text content parts from ContentPart arrays
- Indicating presence of image_url content parts with [Image] marker
- Rendering mixed content types in a human-readable format

All 35 tests pass.
2026-06-15 17:31:12 -05:00
hal9000 8ddee0f621 Fix parameter name mismatch in read_multi_modal tool schema (issue 163)
Change the required parameter name from 'filePath' to 'path' in the
read_multi_modal tool's JSON schema to match the property definition
and the ReadFileToolParams struct field name.
2026-06-15 22:20:13 +00:00
hal9000 2824b89643 Implement issue 161: Add unit tests for read_multi_modal tool
- Add test_tool_read_multi_modal.sh with tests for:
  - Successfully reading a PNG image file
  - Error handling for non-existent files
  - Reading a JPG file (different MIME type)

- Fix json_types.hpp to properly serialize std::optional and std::variant
  types by adding serialize_to_json() helper function that dispatches to
  the correct serialization method.

- Register new test in tests/CMakeLists.txt
2026-06-15 22:02:58 +00:00
darthrubik 0020669eb0 Adding read multi-modal tool 2026-06-15 16:53:42 -05:00
darthrubik 79218deb2f Refactor to use Content for tool calls 2026-06-15 16:53:42 -05:00
hal9000 3fc1a2b286 Implement issue 160: Replace raw jq parsing with helper functions in test_multimodal_message.sh
Add helper functions to run_test.sh:
- dr_history_role: Get message role from chat history
- dr_content_type: Get content type (string/array)
- dr_content_part_type: Get content part type
- dr_content_part_text: Get text from content part
- dr_content_part_image_url: Get image URL from content part
- dr_content_part_image_detail: Get image detail from content part
- dr_content_parts_count: Get content parts count
- dr_content_text: Get text content for text-only messages

Update test_multimodal_message.sh to use the new helpers instead of raw jq
2026-06-15 16:50:06 -05:00
hal9000 0772fd5fe8 Implement issue 159: Add new overload to Harness::chat for multimodal input
Add a new overload to Harness::chat that takes a std::string as the user
message and a vector<std::string> const& as image paths. The method reads
the image files and converts them to data URIs internally, then constructs
the multimodal message.

This moves all the multimodal message construction logic from main.cpp
into Harness, simplifying main.cpp.
2026-06-15 16:28:38 -05:00
darthrubik 45ff22302e Removing custom json parser/exporter 2026-06-15 15:53:57 -05:00
darthrubik 00124e72e5 Fixing Ollama server compatability 2026-06-15 15:25:48 -05:00
hal9000 716bfdcd8b Add test for multimodal chat file persistence round-trip
Issue 156 requires verifying that chat files containing multimodal messages
can be serialized to disk and deserialized correctly when resuming a session.

This commit adds test_multimodal_roundtrip.sh which validates:
- Chat file with multimodal message contains content as array of ContentPart objects
- Chat file with text-only message contains content as string
- Resuming with -F correctly deserializes multimodal messages
- Resuming with -F correctly deserializes text-only messages
- Round-trip serialization preserves all ContentPart data
- Image data URIs are preserved in the chat file
- Mixed content types (multimodal and text-only) in same history
2026-06-12 07:17:11 -05:00
hal9000 7d374a4172 Implement multimodal message construction for -i flag (#155)
When -i flags are present, construct a multimodal message by combining
the text prompt and encoded images into a vector of ContentPart. The text
becomes a text content part and each image becomes an image_url content part.

Changes:
- Added overloaded chat(const Message&) method to Harness class
- Modified Harness::chat(const std::string&) to delegate to new method
- Updated main.cpp to construct multimodal message when images are present
- Added integration test test_multimodal_message.sh

Acceptance criteria met:
- When -i is used, Message::content is a vector<ContentPart>
- Text prompt is included as a text ContentPart
- Each image is included as an image_url ContentPart
- Backward compatible: when -i is not used, content is a plain string
- Works with -m, -d, -t, and -M flags
- Integration test verifies correct multimodal format in chat.json
2026-06-12 07:17:11 -05:00
hal9000 0ca0305ebf feat: Add ImageUrl struct and image_url support to ContentPart (#152)
- Add ImageUrl struct with url and detail fields
- Extend ContentPart with optional text and image_url fields
- Add std::optional serialization/deserialization support
- Custom to_json for ContentPart that only serializes relevant fields
- Custom json_to<ContentPart> for proper deserialization
- Add test_image_url.sh with comprehensive tests
- All 30 tests pass
2026-06-12 07:17:08 -05:00
hal9000 068557b06c Implement issue 154: CLI -i flag with image file reading
- Added read_image_as_data_uri() function to base64_util for reading,
  validating, and base64-encoding image files
- Added -i CLI flag to accept image file paths (multiple allowed)
- Added -I debug flag for testing image file reading
- Image files are validated at startup with clear error messages for
  missing or unreadable files
- Updated help text and README.md documentation
- Added test_image_flag.sh with tests for PNG, JPEG, GIF formats,
  error cases, and multiple -i flags
2026-06-12 07:16:40 -05:00
hal9000 ae0462baea Implement issue 151: Message::content as Variant (text-only ContentPart)
- Add ContentPart struct with type and text fields
- Change Message::content from std::string to std::variant<std::string, std::vector<ContentPart>>
- Add has_json_to partial specialization for std::variant
- Add helper methods get_content_string() and content_empty() to Message
- Add operator<< and append_to_variant_content() for variant content handling
- Update harness.cpp and ollama_client.cpp to use new variant content API
- All 28 existing tests pass without modification
2026-06-12 07:16:40 -05:00
hal9000 ce40d1fe9d Issue 153: Add base64 encoding utility
- Add base64_encode() function to encode binary data to base64 string
- Add base64_decode() function to decode base64 string to binary data
- Add get_mime_type_from_extension() for MIME type detection based on file extension
- Add generate_data_uri() for data URI prefix generation
- Add test flags -B (encode), -b (decode), -T (mime type), -U (data URI)
- Add comprehensive tests in test_base64_encode.sh
- No new dependencies added
2026-06-12 07:16:40 -05:00
hal9000 ffcc907a99 Add std::variant JSON serialization infrastructure (issue 150)
- Add #include <variant> header
- Add json_type_for_type() helper for type-based disambiguation
- Add to_json for std::variant that serializes active alternative
- Add variant_try_helper_impl for recursive variant deserialization
- Add json_to_impl specialization for std::variant
- Add TestVariantType (std::variant<std::string, std::vector<FunctionCall>>)
  for testing variant serialization
- Register TestVariantType in json_dispatch_map for -R debug flag
- Add compile-time static_assert for TestVariantType
- Add test_json_variant.sh test suite
- Add test to CMakeLists.txt
2026-06-11 21:13:10 +00:00
darthrubik 4089b68ec4 Adding git to docker image 2026-06-06 09:53:43 -05:00
darthrubik 6d61d7b99b Merge pull request 'Cache tool response json instead of generating 1001 times' (#31) from bugfix/slow-tests into master
Reviewed-on: https://192.168.8.63/git/darthrubik/drharness/pulls/31
2026-06-04 17:38:52 -05:00
darthrubik f0293d548f Cache tool response json instead of generating 1001 times 2026-06-04 17:36:23 -05:00
darthrubik fee692d262 Fix compilation errors and test failures after merge (issue #140)
- Update ollama_client.cpp to use std::expected pattern for parse_json_safely
- Add missing 'index' field to tool_calls in add_message_field helper
- Add missing 'index' field to test_edit_history_assistant_with_tool_calls test data
2026-06-04 16:09:09 -05:00
darthrubik ea8582644e Merge branch 'master' into feature/rebase (issue #140) 2026-06-04 16:07:42 -05:00
darthrubik 858d45f619 Merge pull request 'feature/streaming' (#30) from feature/streaming into master
Reviewed-on: https://192.168.8.63/git/darthrubik/drharness/pulls/30
2026-06-04 15:52:44 -05:00
darthrubik 9a29bf727c Fixing usage 2026-06-04 15:48:07 -05:00
darthrubik 2cdb06cffe Fixup tool calling 2026-06-04 15:23:32 -05:00
darthrubik a06aa531f6 Refactor (partially broken) to stream 2026-06-03 17:12:36 -05:00
darthrubik 4ee514efb1 Refactor to put json message generation in one place 2026-06-03 17:10:40 -05:00
darthrubik 06d1551af0 Refactor run_test.sh to generate API response JSON in one spot (issue #138)
- Create api_response() helper function as single point for generating
  complete API response JSON structure
- Refactor tool_call(), tool_call_raw(), be_done(), reasoning_step(),
  and reasoning_content_step() to use the shared api_response() function
- Export api_response function for use in test scripts
2026-06-03 17:02:25 -05:00
darthrubik 718bd5dca7 Refactor run_test.sh to generate history json blobs in only one spot (issue 137)
The create_state function now accepts role/content pairs as arguments
and generates the JSON internally using jq for proper escaping. This
centralizes all JSON blob generation in run_test.sh, eliminating the
need for test files to manually construct JSON arrays.
2026-06-03 17:00:10 -05:00
darthrubik c5420a0757 issue 136: Move create_state function to run_test.sh
Centralize history JSON blob generation by moving the create_state
function from test_editor.sh to run_test.sh. This ensures all history
JSON generation happens in only one spot (run_test.sh).

- Added create_state function to run_test.sh with export
- Removed duplicate create_state definition from test_editor.sh
2026-06-03 16:56:40 -05:00
darthrubik 2f0a2cb089 Refactor Client::chat to return Message instead of ChatResponse
- Changed Client::chat return type from ChatResponse to Message
- Updated OllamaClient and DebugClient to extract message from response
- Simplified Harness to work directly with Message
- ChatResponse is still parsed internally for Usage info logging
2026-06-03 16:14:07 -05:00
darthrubik d81c75a9a3 Fix issue 134: add_message_field no longer accepts raw JSON for tool_calls
The add_message_field function now constructs tool call JSON internally
from simple parameters (id, name, arguments) instead of accepting raw
JSON strings. This makes the test helper functions more robust and
easier to use.

Changed:
- add_message_field: tool_call field now takes id, name, args and builds JSON
- create_message_json: updated to handle tool_call's 3-parameter syntax
- create_messages_json: updated to handle tool_call's 3-parameter syntax
- is_message_field: changed tool_calls to tool_call
- Updated all test files that used the old tool_calls raw JSON syntax
2026-06-03 07:53:39 -05:00
darthrubik 0a734ec2ba Split test_rebase_parser.sh into individual test files (issue #133)
Each of the 17 tests from test_rebase_parser.sh is now in its own
test file, following the project convention of one test per script.
2026-06-03 07:49:25 -05:00
darthrubik 8cb6f5aa0b Delete old combined test_rebase_content.sh (issue 132)
The file was split into 12 individual test files in a previous
commit, but the original combined file was not deleted. This
commit removes the now-obsolete test_rebase_content.sh file.
2026-06-03 07:43:28 -05:00
darthrubik 5f88196c54 Use create_messages_json helper instead of manual JSON (issue 132)
Updated all 12 test_rebase_content_* test files to use the
create_messages_json helper function from run_test.sh instead of
manually creating JSON strings, following the pattern established
by test_rebase_apply_* tests.

This complies with CONTRIBUTING.md which states:
'If you do any json handling in the test files your changes will be rejected'

All 83 tests pass.
2026-06-03 07:41:24 -05:00
darthrubik a96246bcd3 Split test_rebase_content.sh into 12 individual test scripts (issue 132)
Each test in tests/test_rebase_content.sh is now its own test script:
- test_rebase_content_basic_messages.sh
- test_rebase_content_multiline_content.sh
- test_rebase_content_tool_call_display.sh
- test_rebase_content_tool_message.sh
- test_rebase_content_empty_message.sh
- test_rebase_content_header_comments.sh
- test_rebase_content_multiple_tool_calls.sh
- test_rebase_content_message_indices.sh
- test_rebase_content_scissors_line.sh
- test_rebase_content_special_characters.sh
- test_rebase_content_unicode_characters.sh
- test_rebase_content_very_long_content.sh

All 83 tests pass.
2026-06-03 07:38:10 -05:00
darthrubik 65aededace test: remove combined test_rebase_apply.sh (issue #131)
The tests have been split into individual test files and registered
in CMakeLists.txt. Removing the combined test file as it is no
longer needed.
2026-06-03 07:33:20 -05:00
darthrubik 949682a176 Split test_rebase_apply.sh into individual test files (issue 131)
- test_rebase_apply_pick_preserves.sh
- test_rebase_apply_drop_removes.sh
- test_rebase_apply_edit_updates_role.sh
- test_rebase_apply_edit_preserves_fields.sh
- test_rebase_apply_implicit_pick.sh
- test_rebase_apply_mixed_commands.sh
- test_rebase_apply_empty_lines_preserves.sh
- test_rebase_apply_lenient_orphaned_results.sh
- test_rebase_apply_edit_preserves_tool_calls.sh
- test_rebase_apply_deleting_lines_drops.sh
- test_rebase_apply_all_lines_deleted_keeps.sh

Removed the combined test_rebase_apply.sh file and updated CMakeLists.txt
to include the 11 new individual test files.
2026-06-03 07:02:15 -05:00
darthrubik e65616bfea Remove redundant code from run_test.sh (#130)
- Consolidated dr_* functions into dr_field helper
- Refactored create_chat_file to use create_history_json
- Refactored create_rebase_lines to use create_rebase_line
- Created add_message_field helper for message field handling
- Created is_message_field helper for field name checking
- Refactored create_messages_json to use create_message_json
- Added local variable declarations for better scoping
2026-06-02 17:19:21 -05:00
darthrubik 41b49aeeae Fix issue 129: Use TEST_TEMP_DIR instead of /tmp for test output files
Replace hardcoded /tmp/drharness_output.txt with $TEST_TEMP_DIR/drharness_output.txt
in all test files. Tests should only write to subfiles/directories of the working
directory (which is already a temp directory created by run_test.sh).
2026-06-02 17:09:32 -05:00
darthrubik cec6c72ecd fix(issue 128): replace manual JSON creation with helper functions
Add helper functions to run_test.sh for creating rebase lines and history
messages:
- create_rebase_line: creates a single rebase line JSON object
- create_rebase_lines: creates a JSON array of rebase lines
- create_message_json: creates a message JSON with optional fields
- create_messages_json: creates a JSON array of messages

Update test_rebase_apply.sh to use these helper functions instead of
manually constructing JSON strings, which violates CONTRIBUTING.md.
2026-06-02 16:33:50 -05:00
darthrubik 511b53ca18 Break test_edit_prompt.sh into multiple tests (issue 127)
Split the monolithic test_edit_prompt.sh into 6 individual test files:
- test_edit_prompt_with_context.sh
- test_edit_prompt_first_message.sh
- test_edit_prompt_separator_placement.sh
- test_edit_prompt_multiline_context.sh
- test_edit_prompt_tool_role.sh
- test_edit_prompt_middle_message.sh

Each test is now its own script that can be run independently.
2026-06-02 16:27:23 -05:00
darthrubik 15098d7515 Fix issue 126: Replace manual JSON history creation in test_edit_prompt.sh
Add create_history_json() helper function to run_test.sh and use it in
test_edit_prompt.sh to avoid manual JSON string construction. This follows
CONTRIBUTING.md guidelines that prohibit JSON handling in test files.
2026-06-02 16:21:54 -05:00