diff --git a/docs/showcase/examples.json b/docs/showcase/examples.json index a9f1908f0..872f59bc5 100644 --- a/docs/showcase/examples.json +++ b/docs/showcase/examples.json @@ -21,6 +21,27 @@ "generated_by": "uat-tester", "generated_at": "2026-04-07" }, + { + "title": "REPL and Actor Run: Interactive AI Sessions from the Terminal", + "category": "cli-tools", + "path": "cli-tools/repl-and-actor-run.md", + "feature": "Interactive REPL and single-shot actor run commands", + "commands": [ + "agents repl", + "agents repl --help", + "agents actor run openai/gpt-4o \"Say hello\"", + "agents actor run --help", + "agents actor run local/demo-assistant \"What is the capital of France?\" --config my-assistant.yaml", + "agents actor run local/demo-assistant \"What is the capital of France?\" --config my-assistant.yaml --output answer.txt", + "agents actor run local/demo-assistant \"Write a haiku about mountains\" --config my-assistant.yaml --temperature 0.9", + "agents actor run local/demo-assistant \"I'm working on a Python project\" --config my-assistant.yaml --context my-session --context-dir /tmp/my-contexts", + "agents actor run local/demo-assistant \"What are best practices for error handling?\" --config my-assistant.yaml --context my-session --context-dir /tmp/my-contexts" + ], + "complexity": "intermediate", + "educational_value": "high", + "generated_by": "uat-tester", + "generated_at": "2026-04-07" + }, { "title": "Managing AI Actors with the CleverAgents CLI", "category": "cli-tools", diff --git a/features/showcase_repl_actor_run.feature b/features/showcase_repl_actor_run.feature new file mode 100644 index 000000000..d608d098e --- /dev/null +++ b/features/showcase_repl_actor_run.feature @@ -0,0 +1,80 @@ +Feature: REPL and Actor Run CLI Showcase Documentation + The showcase documentation for REPL and actor run CLI commands + should be properly registered and accessible. + + Scenario: Showcase markdown file exists + Given the showcase directory exists + When I check for the REPL and actor run showcase file + Then the file should exist at "docs/showcase/cli-tools/repl-and-actor-run.md" + + Scenario: Showcase is registered in examples.json + Given the examples.json file exists + When I check for the REPL and actor run showcase entry + Then the entry should have title "REPL and Actor Run: Interactive AI Sessions from the Terminal" + And the entry should have category "cli-tools" + And the entry should have path "cli-tools/repl-and-actor-run.md" + And the entry should have complexity "intermediate" + + Scenario: Showcase has required commands documented + Given the showcase markdown file exists + When I check the documented commands + Then the file should contain "agents repl" + And the file should contain "agents actor run" + And the file should contain "agents repl --help" + And the file should contain "agents actor run --help" + + Scenario: Showcase has REPL section + Given the showcase markdown file exists + When I check the content structure + Then the file should contain "Part 1: The Interactive REPL" + And the file should contain ":help" + And the file should contain ":exit" + And the file should contain "!!" + + Scenario: Showcase has Actor Run section + Given the showcase markdown file exists + When I check the content structure + Then the file should contain "Part 2: Single-Shot Actor Run" + And the file should contain "--config" + And the file should contain "--output" + And the file should contain "--temperature" + And the file should contain "--context" + + Scenario: Showcase has real output examples + Given the showcase markdown file exists + When I check for verified output + Then the file should contain "Actual Output:" + And the file should contain "verified" + + Scenario: Examples.json has valid JSON structure + Given the examples.json file exists + When I parse the JSON + Then the JSON should be valid + And the JSON should have "examples" key + And the JSON should have "categories" key + + Scenario: Showcase entry has all required fields + Given the examples.json file exists + When I check the REPL and actor run entry + Then the entry should have "title" field + And the entry should have "category" field + And the entry should have "path" field + And the entry should have "feature" field + And the entry should have "commands" field + And the entry should have "complexity" field + And the entry should have "educational_value" field + + Scenario: Showcase commands list is not empty + Given the examples.json file exists + When I check the REPL and actor run entry + Then the commands list should have at least 5 items + And the commands should include "agents repl" + And the commands should include "agents actor run" + + Scenario: Showcase file has proper markdown formatting + Given the showcase markdown file exists + When I check the markdown structure + Then the file should start with a heading + And the file should have multiple sections + And the file should have code blocks + And the file should have proper link formatting diff --git a/features/steps/showcase_repl_actor_run_steps.py b/features/steps/showcase_repl_actor_run_steps.py new file mode 100644 index 000000000..f5cb1c17e --- /dev/null +++ b/features/steps/showcase_repl_actor_run_steps.py @@ -0,0 +1,206 @@ +"""Steps for REPL and Actor Run CLI Showcase Documentation tests.""" + +import json +import os +from pathlib import Path +from typing import Any + +from behave import given, when, then + + +@given("the showcase directory exists") +def step_showcase_directory_exists(context: Any) -> None: + """Verify the showcase directory exists.""" + showcase_dir = Path("docs/showcase") + assert showcase_dir.exists(), f"Showcase directory not found at {showcase_dir}" + context.showcase_dir = showcase_dir + + +@given("the examples.json file exists") +def step_examples_json_exists(context: Any) -> None: + """Verify examples.json exists.""" + examples_file = Path("docs/showcase/examples.json") + assert examples_file.exists(), f"examples.json not found at {examples_file}" + context.examples_file = examples_file + + # Load the JSON for later use + with open(examples_file, "r") as f: + context.examples_data = json.load(f) + + +@given("the showcase markdown file exists") +def step_showcase_markdown_exists(context: Any) -> None: + """Verify the showcase markdown file exists.""" + markdown_file = Path("docs/showcase/cli-tools/repl-and-actor-run.md") + assert markdown_file.exists(), f"Showcase markdown not found at {markdown_file}" + context.markdown_file = markdown_file + + # Load the content for later use + with open(markdown_file, "r") as f: + context.markdown_content = f.read() + + +@when("I check for the REPL and actor run showcase file") +def step_check_showcase_file(context: Any) -> None: + """Check for the showcase file.""" + context.file_path = Path("docs/showcase/cli-tools/repl-and-actor-run.md") + + +@then('the file should exist at "{path}"') +def step_file_exists_at_path(context: Any, path: str) -> None: + """Verify file exists at the given path.""" + file_path = Path(path) + assert file_path.exists(), f"File not found at {path}" + + +@when("I check for the REPL and actor run showcase entry") +def step_check_showcase_entry(context: Any) -> None: + """Check for the showcase entry in examples.json.""" + examples = context.examples_data.get("examples", []) + + # Find the REPL and actor run entry + context.repl_entry = None + for example in examples: + if "repl-and-actor-run" in example.get("path", ""): + context.repl_entry = example + break + + assert context.repl_entry is not None, "REPL and actor run entry not found in examples.json" + + +@then('the entry should have title "{title}"') +def step_entry_has_title(context: Any, title: str) -> None: + """Verify entry has the expected title.""" + assert context.repl_entry["title"] == title, \ + f"Expected title '{title}', got '{context.repl_entry['title']}'" + + +@then('the entry should have category "{category}"') +def step_entry_has_category(context: Any, category: str) -> None: + """Verify entry has the expected category.""" + assert context.repl_entry["category"] == category, \ + f"Expected category '{category}', got '{context.repl_entry['category']}'" + + +@then('the entry should have path "{path}"') +def step_entry_has_path(context: Any, path: str) -> None: + """Verify entry has the expected path.""" + assert context.repl_entry["path"] == path, \ + f"Expected path '{path}', got '{context.repl_entry['path']}'" + + +@then('the entry should have complexity "{complexity}"') +def step_entry_has_complexity(context: Any, complexity: str) -> None: + """Verify entry has the expected complexity.""" + assert context.repl_entry["complexity"] == complexity, \ + f"Expected complexity '{complexity}', got '{context.repl_entry['complexity']}'" + + +@when("I check the documented commands") +def step_check_documented_commands(context: Any) -> None: + """Check the documented commands in the markdown.""" + pass # Content is already loaded in context.markdown_content + + +@then('the file should contain "{text}"') +def step_file_contains_text(context: Any, text: str) -> None: + """Verify the file contains the given text.""" + assert text in context.markdown_content, \ + f"Text '{text}' not found in markdown file" + + +@when("I check the content structure") +def step_check_content_structure(context: Any) -> None: + """Check the content structure.""" + pass # Content is already loaded + + +@when("I check for verified output") +def step_check_verified_output(context: Any) -> None: + """Check for verified output in the markdown.""" + pass # Content is already loaded + + +@when("I parse the JSON") +def step_parse_json(context: Any) -> None: + """Parse the JSON file.""" + # Already parsed in the given step + pass + + +@then("the JSON should be valid") +def step_json_is_valid(context: Any) -> None: + """Verify the JSON is valid.""" + assert isinstance(context.examples_data, dict), "JSON is not a valid dictionary" + + +@then('the JSON should have "{key}" key') +def step_json_has_key(context: Any, key: str) -> None: + """Verify the JSON has the given key.""" + assert key in context.examples_data, f"Key '{key}' not found in JSON" + + +@when("I check the REPL and actor run entry") +def step_check_repl_entry(context: Any) -> None: + """Check the REPL and actor run entry.""" + # Already done in previous step + pass + + +@then('the entry should have "{field}" field') +def step_entry_has_field(context: Any, field: str) -> None: + """Verify entry has the given field.""" + assert field in context.repl_entry, \ + f"Field '{field}' not found in entry" + + +@then("the commands list should have at least {count:d} items") +def step_commands_list_has_items(context: Any, count: int) -> None: + """Verify the commands list has at least the given number of items.""" + commands = context.repl_entry.get("commands", []) + assert len(commands) >= count, \ + f"Expected at least {count} commands, got {len(commands)}" + + +@then('the commands should include "{command}"') +def step_commands_include(context: Any, command: str) -> None: + """Verify the commands list includes the given command.""" + commands = context.repl_entry.get("commands", []) + assert command in commands, \ + f"Command '{command}' not found in commands list" + + +@when("I check the markdown structure") +def step_check_markdown_structure(context: Any) -> None: + """Check the markdown structure.""" + pass # Content is already loaded + + +@then("the file should start with a heading") +def step_file_starts_with_heading(context: Any) -> None: + """Verify the file starts with a heading.""" + assert context.markdown_content.startswith("#"), \ + "Markdown file should start with a heading" + + +@then("the file should have multiple sections") +def step_file_has_multiple_sections(context: Any) -> None: + """Verify the file has multiple sections.""" + heading_count = context.markdown_content.count("\n#") + assert heading_count >= 3, \ + f"Expected at least 3 sections, found {heading_count}" + + +@then("the file should have code blocks") +def step_file_has_code_blocks(context: Any) -> None: + """Verify the file has code blocks.""" + assert "```" in context.markdown_content, \ + "Markdown file should have code blocks" + + +@then("the file should have proper link formatting") +def step_file_has_proper_links(context: Any) -> None: + """Verify the file has proper link formatting.""" + # Check for markdown link format [text](url) + assert "[" in context.markdown_content and "](" in context.markdown_content, \ + "Markdown file should have proper link formatting"