agentic-cli 0.3.0__tar.gz → 0.3.2__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.
Files changed (110) hide show
  1. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/.gitignore +4 -0
  2. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/CHANGELOG.md +44 -0
  3. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/PKG-INFO +88 -4
  4. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/README.md +87 -3
  5. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/environment.yml +1 -0
  6. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/examples/research_demo/agents.py +18 -1
  7. agentic_cli-0.3.2/examples/research_demo/app.py +81 -0
  8. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/examples/research_demo/commands.py +11 -22
  9. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/examples/research_demo/settings.py +4 -4
  10. agentic_cli-0.3.2/examples/webfetch_demo.py +312 -0
  11. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/pyproject.toml +1 -1
  12. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/__init__.py +3 -2
  13. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/cli/__init__.py +6 -0
  14. agentic_cli-0.3.2/src/agentic_cli/cli/app.py +460 -0
  15. agentic_cli-0.3.2/src/agentic_cli/cli/message_processor.py +348 -0
  16. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/cli/settings.py +8 -0
  17. agentic_cli-0.3.2/src/agentic_cli/cli/workflow_controller.py +328 -0
  18. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/config.py +58 -14
  19. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/hitl/approval.py +8 -0
  20. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/hitl/checkpoints.py +19 -0
  21. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/knowledge_base/sources.py +113 -3
  22. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/memory/manager.py +11 -0
  23. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/planning/task_graph.py +90 -0
  24. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/settings_persistence.py +30 -20
  25. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/tools/__init__.py +13 -3
  26. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/tools/planning_tools.py +1 -1
  27. agentic_cli-0.3.2/src/agentic_cli/tools/search.py +261 -0
  28. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/tools/standard.py +174 -25
  29. agentic_cli-0.3.2/src/agentic_cli/tools/webfetch/__init__.py +44 -0
  30. agentic_cli-0.3.2/src/agentic_cli/tools/webfetch/converter.py +66 -0
  31. agentic_cli-0.3.2/src/agentic_cli/tools/webfetch/fetcher.py +178 -0
  32. agentic_cli-0.3.2/src/agentic_cli/tools/webfetch/robots.py +75 -0
  33. agentic_cli-0.3.2/src/agentic_cli/tools/webfetch/summarizer.py +50 -0
  34. agentic_cli-0.3.2/src/agentic_cli/tools/webfetch/validator.py +129 -0
  35. agentic_cli-0.3.2/src/agentic_cli/tools/webfetch_tool.py +142 -0
  36. agentic_cli-0.3.2/src/agentic_cli/workflow/adk/__init__.py +20 -0
  37. agentic_cli-0.3.2/src/agentic_cli/workflow/adk/llm_event_logger.py +371 -0
  38. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/workflow/adk_manager.py +123 -79
  39. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/workflow/base_manager.py +104 -14
  40. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/workflow/context.py +17 -0
  41. agentic_cli-0.3.2/src/agentic_cli/workflow/events.py +467 -0
  42. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/workflow/langgraph/manager.py +81 -86
  43. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/workflow/langgraph_manager.py +0 -2
  44. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/workflow/settings.py +18 -2
  45. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/tests/test_knowledge_base.py +249 -0
  46. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/tests/test_langgraph.py +2 -2
  47. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/tests/test_planning.py +1 -1
  48. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/tests/test_tools.py +233 -0
  49. agentic_cli-0.3.2/tests/test_webfetch.py +742 -0
  50. agentic_cli-0.3.0/examples/research_demo/app.py +0 -233
  51. agentic_cli-0.3.0/src/agentic_cli/cli/app.py +0 -837
  52. agentic_cli-0.3.0/src/agentic_cli/workflow/adk/__init__.py +0 -18
  53. agentic_cli-0.3.0/src/agentic_cli/workflow/events.py +0 -253
  54. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/LICENSE +0 -0
  55. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/examples/hello_agent.py +0 -0
  56. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/examples/hello_langgraph.py +0 -0
  57. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/examples/research_demo/README.md +0 -0
  58. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/examples/research_demo/__init__.py +0 -0
  59. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/examples/research_demo/__main__.py +0 -0
  60. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/examples/research_demo/tools.py +0 -0
  61. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/requirements-dev.txt +0 -0
  62. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/requirements.txt +0 -0
  63. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/cli/builtin_commands.py +0 -0
  64. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/cli/commands.py +0 -0
  65. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/cli/settings_command.py +0 -0
  66. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/cli/settings_introspection.py +0 -0
  67. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/config_mixins.py +0 -0
  68. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/hitl/__init__.py +0 -0
  69. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/hitl/config.py +0 -0
  70. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/knowledge_base/__init__.py +0 -0
  71. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/knowledge_base/embeddings.py +0 -0
  72. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/knowledge_base/manager.py +0 -0
  73. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/knowledge_base/models.py +0 -0
  74. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/knowledge_base/vector_store.py +0 -0
  75. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/logging.py +0 -0
  76. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/memory/__init__.py +0 -0
  77. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/memory/longterm.py +0 -0
  78. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/memory/tools.py +0 -0
  79. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/memory/working.py +0 -0
  80. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/persistence/__init__.py +0 -0
  81. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/persistence/artifacts.py +0 -0
  82. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/persistence/session.py +0 -0
  83. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/planning/__init__.py +0 -0
  84. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/resolvers.py +0 -0
  85. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/tools/executor.py +0 -0
  86. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/tools/file_ops.py +0 -0
  87. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/tools/hitl_tools.py +0 -0
  88. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/tools/memory_tools.py +0 -0
  89. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/tools/registry.py +0 -0
  90. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/tools/shell.py +0 -0
  91. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/workflow/__init__.py +0 -0
  92. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/workflow/config.py +0 -0
  93. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/workflow/langgraph/__init__.py +0 -0
  94. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/workflow/langgraph/persistence/__init__.py +0 -0
  95. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/workflow/langgraph/persistence/checkpointers.py +0 -0
  96. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/workflow/langgraph/persistence/stores.py +0 -0
  97. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/workflow/langgraph/state.py +0 -0
  98. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/workflow/langgraph/tools/__init__.py +0 -0
  99. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/workflow/langgraph/tools/file_search.py +0 -0
  100. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/workflow/langgraph/tools/shell.py +0 -0
  101. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/workflow/langgraph_state.py +0 -0
  102. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/src/agentic_cli/workflow/thinking.py +0 -0
  103. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/tests/__init__.py +0 -0
  104. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/tests/conftest.py +0 -0
  105. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/tests/test_commands.py +0 -0
  106. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/tests/test_config.py +0 -0
  107. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/tests/test_hitl.py +0 -0
  108. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/tests/test_memory.py +0 -0
  109. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/tests/test_persistence.py +0 -0
  110. {agentic_cli-0.3.0 → agentic_cli-0.3.2}/tests/test_workflow.py +0 -0
@@ -46,3 +46,7 @@ CLAUDE.md
46
46
  plans/
47
47
  docs/
48
48
  changes/
49
+ .research_demo/
50
+
51
+ # Git worktrees
52
+ .worktrees/
@@ -5,6 +5,50 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.3.2] - 2026-02-01
9
+
10
+ ### Added
11
+
12
+ - **Web Fetch Tool**: Full-featured web content fetching with LLM summarization
13
+ - HTML-to-Markdown conversion with html2text
14
+ - Robots.txt compliance checking
15
+ - SSRF protection and URL validation
16
+ - Caching and redirect handling
17
+ - **Web Search Tool**: Pluggable web search with backend abstraction
18
+ - **arXiv Integration**: Enhanced arXiv search with rate limiting, caching, advanced query options, and paper analysis tools
19
+ - **LLM Event Logging**: Debug logging for model interactions
20
+ - **Task Progress Events**: `verbose_thinking` setting for detailed task progress display
21
+
22
+ ### Changed
23
+
24
+ - **CLI Architecture Refactoring**:
25
+ - Extracted `WorkflowController` and `MessageProcessor` from `BaseCLIApp` for better separation of concerns
26
+ - Added `background_init` context manager to `WorkflowController`
27
+ - Added public query methods to managers to reduce command-workflow coupling
28
+ - **BaseWorkflowManager**: Moved shared implementations from ADK/LangGraph managers to base class
29
+ - **Code Quality**: Added enums for string literals, improved `TaskGraph` encapsulation
30
+ - **Settings**: Use app-specific paths and generic settings application
31
+
32
+ ### Fixed
33
+
34
+ - Circular import in workflow module
35
+ - Web search tool integration issues
36
+ - arXiv cache unbounded growth (added size limit)
37
+ - Webfetch redirect response structure alignment with spec
38
+
39
+ ## [0.3.1] - 2026-01-28
40
+
41
+ ### Added
42
+
43
+ - **Task Progress Display**: Thinking box now shows dynamic task progress with status icons (◐ ☐ ✓ ✗)
44
+ - `TASK_PROGRESS` event type for signaling task graph updates
45
+ - `TaskGraph.to_compact_display()` for condensed status display
46
+
47
+ ### Changed
48
+
49
+ - **Background Initialization**: Workflow manager now initializes services in background, eliminating first-message lag
50
+ - Simplified LangGraph imports - removed `_import_langgraph` helper in favor of direct imports
51
+
8
52
  ## [0.3.0] - 2025-01-27
9
53
 
10
54
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentic-cli
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: A framework for building domain-specific agentic CLI applications
5
5
  Project-URL: Homepage, https://github.com/shoom1/agentic-cli
6
6
  Project-URL: Repository, https://github.com/shoom1/agentic-cli
@@ -48,7 +48,7 @@ Agentic CLI provides the core infrastructure for building interactive CLI applic
48
48
  - **Pluggable Orchestration**: Choose between Google ADK or LangGraph for agent workflows
49
49
  - **Rich Terminal UI**: Thinking boxes, markdown rendering, and streaming responses via `thinking-prompt`
50
50
  - **Declarative Agents**: Define agents with simple configuration objects
51
- - **Built-in Tools**: Python execution, knowledge base search, web search
51
+ - **Built-in Tools**: Python execution, knowledge base, web search, web fetch, arXiv search
52
52
  - **Session Persistence**: Save and restore conversation sessions
53
53
  - **Type-safe Configuration**: Settings management with pydantic-settings
54
54
 
@@ -60,6 +60,8 @@ Agentic CLI provides the core infrastructure for building interactive CLI applic
60
60
  │ - Terminal UI (thinking-prompt) │
61
61
  │ - Command registry (/help, /status, /clear, etc.) │
62
62
  │ - Message history │
63
+ │ - Background initialization (no first-message lag) │
64
+ │ - Task progress display in thinking box │
63
65
  └─────────────────────────────────────────────────────────────────────┘
64
66
 
65
67
 
@@ -249,6 +251,10 @@ class MySettings(BaseSettings):
249
251
  | `orchestrator` | `AGENTIC_ORCHESTRATOR` | "adk" | Orchestrator: adk or langgraph |
250
252
  | `workspace_dir` | `AGENTIC_WORKSPACE_DIR` | ~/.agentic | Storage directory |
251
253
  | `log_level` | `AGENTIC_LOG_LEVEL` | "warning" | Logging level |
254
+ | `tavily_api_key` | `TAVILY_API_KEY` | None | Tavily API key for web search |
255
+ | `brave_api_key` | `BRAVE_API_KEY` | None | Brave Search API key |
256
+ | `search_backend` | `AGENTIC_SEARCH_BACKEND` | Auto | Web search provider (tavily/brave) |
257
+ | `webfetch_model` | `AGENTIC_WEBFETCH_MODEL` | Auto | Model for web content summarization |
252
258
 
253
259
  ### Settings Context
254
260
 
@@ -363,6 +369,59 @@ np.mean(data)
363
369
 
364
370
  Allowed modules: numpy, pandas, scipy, math, json, datetime, collections, itertools, re, random
365
371
 
372
+ #### Web Search
373
+
374
+ Search the web using pluggable backends (Tavily or Brave):
375
+
376
+ ```python
377
+ from agentic_cli.tools import web_search
378
+
379
+ # Use as agent tool
380
+ agent = AgentConfig(
381
+ name="researcher",
382
+ tools=[web_search],
383
+ )
384
+
385
+ # Or call directly
386
+ results = web_search("Python async programming", max_results=5)
387
+ # Returns: {"results": [{"title": "...", "url": "...", "snippet": "..."}], ...}
388
+ ```
389
+
390
+ Backends auto-select based on available API keys. Set `TAVILY_API_KEY` or `BRAVE_API_KEY`.
391
+
392
+ #### Web Fetch
393
+
394
+ Fetch web content and summarize with LLM:
395
+
396
+ ```python
397
+ from agentic_cli.tools import web_fetch
398
+
399
+ result = web_fetch(
400
+ url="https://example.com/article",
401
+ prompt="Extract the main points from this article",
402
+ )
403
+ # Returns: {"url": "...", "summary": "...", "content_length": ...}
404
+ ```
405
+
406
+ Features: URL validation, robots.txt compliance, SSRF protection, content caching.
407
+
408
+ #### ArXiv Search
409
+
410
+ Search and analyze academic papers:
411
+
412
+ ```python
413
+ from agentic_cli.tools import search_arxiv, fetch_arxiv_paper, analyze_arxiv_paper
414
+
415
+ # Search papers
416
+ results = search_arxiv("transformer attention", max_results=10, categories=["cs.CL"])
417
+
418
+ # Fetch paper details
419
+ paper = fetch_arxiv_paper("1706.03762") # "Attention Is All You Need"
420
+
421
+ # Analyze with LLM
422
+ analysis = await analyze_arxiv_paper("1706.03762", "Summarize the key contributions")
423
+ ```
424
+
366
425
  #### KnowledgeBaseManager
367
426
 
368
427
  Semantic search over documents:
@@ -430,6 +489,7 @@ WorkflowEvent types for UI integration:
430
489
  | `CODE_EXECUTION` | Code execution result | outcome |
431
490
  | `ERROR` | Error message | recoverable, error_code |
432
491
  | `USER_INPUT_REQUIRED` | Tool needs user input | request_id, prompt |
492
+ | `TASK_PROGRESS` | Task graph update | current_task_description, progress |
433
493
 
434
494
  ### Processing Events
435
495
 
@@ -445,12 +505,31 @@ async for event in manager.process(message, user_id="user1"):
445
505
  print(f"Result: {event.metadata['result']}")
446
506
  ```
447
507
 
508
+ ### Task Progress Display
509
+
510
+ When using a task graph for planning, the CLI thinking box dynamically shows task progress:
511
+
512
+ ```
513
+ Calling: search_web
514
+ ─── Tasks: 2/5 ───
515
+ ◐ Researching topic
516
+ ☐ Analyzing results
517
+ ☐ Writing summary
518
+ ```
519
+
520
+ Status icons:
521
+ - `◐` In progress
522
+ - `☐` Pending
523
+ - `✓` Completed
524
+ - `✗` Failed
525
+
448
526
  ## Examples
449
527
 
450
528
  See the `examples/` directory for complete working examples:
451
529
 
452
530
  - **hello_agent.py** - Simple assistant using Google ADK
453
531
  - **hello_langgraph.py** - Same assistant using LangGraph orchestration
532
+ - **webfetch_demo.py** - Web fetching and summarization demo
454
533
  - **research_demo/** - Full-featured research assistant with memory, planning, and file operations
455
534
 
456
535
  Run examples:
@@ -491,7 +570,9 @@ agentic-cli/
491
570
  │ ├── config.py # BaseSettings, SettingsContext
492
571
  │ ├── cli/
493
572
  │ │ ├── app.py # BaseCLIApp
494
- │ │ └── commands.py # Command, CommandRegistry
573
+ │ │ ├── commands.py # Command, CommandRegistry
574
+ │ │ ├── workflow_controller.py # Workflow orchestration
575
+ │ │ └── message_processor.py # Event stream processing
495
576
  │ ├── workflow/
496
577
  │ │ ├── events.py # WorkflowEvent, EventType
497
578
  │ │ ├── config.py # AgentConfig
@@ -502,12 +583,15 @@ agentic-cli/
502
583
  │ │ ├── persistence/ # Checkpointers and stores
503
584
  │ │ └── tools/ # Shell, file search tools
504
585
  │ ├── tools/
505
- │ │ └── executor.py # SafePythonExecutor
586
+ │ │ ├── executor.py # SafePythonExecutor
587
+ │ │ ├── search.py # Web search (Tavily, Brave)
588
+ │ │ └── webfetch/ # Web content fetching
506
589
  │ └── knowledge_base/
507
590
  │ └── manager.py # KnowledgeBaseManager
508
591
  ├── examples/
509
592
  │ ├── hello_agent.py
510
593
  │ ├── hello_langgraph.py
594
+ │ ├── webfetch_demo.py
511
595
  │ └── research_demo/ # Full-featured example
512
596
  └── tests/
513
597
  ```
@@ -9,7 +9,7 @@ Agentic CLI provides the core infrastructure for building interactive CLI applic
9
9
  - **Pluggable Orchestration**: Choose between Google ADK or LangGraph for agent workflows
10
10
  - **Rich Terminal UI**: Thinking boxes, markdown rendering, and streaming responses via `thinking-prompt`
11
11
  - **Declarative Agents**: Define agents with simple configuration objects
12
- - **Built-in Tools**: Python execution, knowledge base search, web search
12
+ - **Built-in Tools**: Python execution, knowledge base, web search, web fetch, arXiv search
13
13
  - **Session Persistence**: Save and restore conversation sessions
14
14
  - **Type-safe Configuration**: Settings management with pydantic-settings
15
15
 
@@ -21,6 +21,8 @@ Agentic CLI provides the core infrastructure for building interactive CLI applic
21
21
  │ - Terminal UI (thinking-prompt) │
22
22
  │ - Command registry (/help, /status, /clear, etc.) │
23
23
  │ - Message history │
24
+ │ - Background initialization (no first-message lag) │
25
+ │ - Task progress display in thinking box │
24
26
  └─────────────────────────────────────────────────────────────────────┘
25
27
 
26
28
 
@@ -210,6 +212,10 @@ class MySettings(BaseSettings):
210
212
  | `orchestrator` | `AGENTIC_ORCHESTRATOR` | "adk" | Orchestrator: adk or langgraph |
211
213
  | `workspace_dir` | `AGENTIC_WORKSPACE_DIR` | ~/.agentic | Storage directory |
212
214
  | `log_level` | `AGENTIC_LOG_LEVEL` | "warning" | Logging level |
215
+ | `tavily_api_key` | `TAVILY_API_KEY` | None | Tavily API key for web search |
216
+ | `brave_api_key` | `BRAVE_API_KEY` | None | Brave Search API key |
217
+ | `search_backend` | `AGENTIC_SEARCH_BACKEND` | Auto | Web search provider (tavily/brave) |
218
+ | `webfetch_model` | `AGENTIC_WEBFETCH_MODEL` | Auto | Model for web content summarization |
213
219
 
214
220
  ### Settings Context
215
221
 
@@ -324,6 +330,59 @@ np.mean(data)
324
330
 
325
331
  Allowed modules: numpy, pandas, scipy, math, json, datetime, collections, itertools, re, random
326
332
 
333
+ #### Web Search
334
+
335
+ Search the web using pluggable backends (Tavily or Brave):
336
+
337
+ ```python
338
+ from agentic_cli.tools import web_search
339
+
340
+ # Use as agent tool
341
+ agent = AgentConfig(
342
+ name="researcher",
343
+ tools=[web_search],
344
+ )
345
+
346
+ # Or call directly
347
+ results = web_search("Python async programming", max_results=5)
348
+ # Returns: {"results": [{"title": "...", "url": "...", "snippet": "..."}], ...}
349
+ ```
350
+
351
+ Backends auto-select based on available API keys. Set `TAVILY_API_KEY` or `BRAVE_API_KEY`.
352
+
353
+ #### Web Fetch
354
+
355
+ Fetch web content and summarize with LLM:
356
+
357
+ ```python
358
+ from agentic_cli.tools import web_fetch
359
+
360
+ result = web_fetch(
361
+ url="https://example.com/article",
362
+ prompt="Extract the main points from this article",
363
+ )
364
+ # Returns: {"url": "...", "summary": "...", "content_length": ...}
365
+ ```
366
+
367
+ Features: URL validation, robots.txt compliance, SSRF protection, content caching.
368
+
369
+ #### ArXiv Search
370
+
371
+ Search and analyze academic papers:
372
+
373
+ ```python
374
+ from agentic_cli.tools import search_arxiv, fetch_arxiv_paper, analyze_arxiv_paper
375
+
376
+ # Search papers
377
+ results = search_arxiv("transformer attention", max_results=10, categories=["cs.CL"])
378
+
379
+ # Fetch paper details
380
+ paper = fetch_arxiv_paper("1706.03762") # "Attention Is All You Need"
381
+
382
+ # Analyze with LLM
383
+ analysis = await analyze_arxiv_paper("1706.03762", "Summarize the key contributions")
384
+ ```
385
+
327
386
  #### KnowledgeBaseManager
328
387
 
329
388
  Semantic search over documents:
@@ -391,6 +450,7 @@ WorkflowEvent types for UI integration:
391
450
  | `CODE_EXECUTION` | Code execution result | outcome |
392
451
  | `ERROR` | Error message | recoverable, error_code |
393
452
  | `USER_INPUT_REQUIRED` | Tool needs user input | request_id, prompt |
453
+ | `TASK_PROGRESS` | Task graph update | current_task_description, progress |
394
454
 
395
455
  ### Processing Events
396
456
 
@@ -406,12 +466,31 @@ async for event in manager.process(message, user_id="user1"):
406
466
  print(f"Result: {event.metadata['result']}")
407
467
  ```
408
468
 
469
+ ### Task Progress Display
470
+
471
+ When using a task graph for planning, the CLI thinking box dynamically shows task progress:
472
+
473
+ ```
474
+ Calling: search_web
475
+ ─── Tasks: 2/5 ───
476
+ ◐ Researching topic
477
+ ☐ Analyzing results
478
+ ☐ Writing summary
479
+ ```
480
+
481
+ Status icons:
482
+ - `◐` In progress
483
+ - `☐` Pending
484
+ - `✓` Completed
485
+ - `✗` Failed
486
+
409
487
  ## Examples
410
488
 
411
489
  See the `examples/` directory for complete working examples:
412
490
 
413
491
  - **hello_agent.py** - Simple assistant using Google ADK
414
492
  - **hello_langgraph.py** - Same assistant using LangGraph orchestration
493
+ - **webfetch_demo.py** - Web fetching and summarization demo
415
494
  - **research_demo/** - Full-featured research assistant with memory, planning, and file operations
416
495
 
417
496
  Run examples:
@@ -452,7 +531,9 @@ agentic-cli/
452
531
  │ ├── config.py # BaseSettings, SettingsContext
453
532
  │ ├── cli/
454
533
  │ │ ├── app.py # BaseCLIApp
455
- │ │ └── commands.py # Command, CommandRegistry
534
+ │ │ ├── commands.py # Command, CommandRegistry
535
+ │ │ ├── workflow_controller.py # Workflow orchestration
536
+ │ │ └── message_processor.py # Event stream processing
456
537
  │ ├── workflow/
457
538
  │ │ ├── events.py # WorkflowEvent, EventType
458
539
  │ │ ├── config.py # AgentConfig
@@ -463,12 +544,15 @@ agentic-cli/
463
544
  │ │ ├── persistence/ # Checkpointers and stores
464
545
  │ │ └── tools/ # Shell, file search tools
465
546
  │ ├── tools/
466
- │ │ └── executor.py # SafePythonExecutor
547
+ │ │ ├── executor.py # SafePythonExecutor
548
+ │ │ ├── search.py # Web search (Tavily, Brave)
549
+ │ │ └── webfetch/ # Web content fetching
467
550
  │ └── knowledge_base/
468
551
  │ └── manager.py # KnowledgeBaseManager
469
552
  ├── examples/
470
553
  │ ├── hello_agent.py
471
554
  │ ├── hello_langgraph.py
555
+ │ ├── webfetch_demo.py
472
556
  │ └── research_demo/ # Full-featured example
473
557
  └── tests/
474
558
  ```
@@ -5,6 +5,7 @@ channels:
5
5
  dependencies:
6
6
  - python=3.12
7
7
  - pip
8
+ - html2text
8
9
  - pip:
9
10
  - -e .
10
11
  - -e .[dev]
@@ -5,7 +5,7 @@ Only app-specific tools (file operations, shell) are defined locally.
5
5
  """
6
6
 
7
7
  from agentic_cli.workflow import AgentConfig
8
- from agentic_cli.tools import memory_tools, planning_tools, hitl_tools
8
+ from agentic_cli.tools import memory_tools, planning_tools, hitl_tools, web_search, search_arxiv, fetch_arxiv_paper, analyze_arxiv_paper
9
9
 
10
10
  # App-specific tools (file operations and shell)
11
11
  from examples.research_demo.tools import (
@@ -47,6 +47,17 @@ RESEARCH_AGENT_PROMPT = """You are a research assistant with memory and planning
47
47
  **Shell Commands**
48
48
  - `run_safe_command(command)` - Run safe shell commands (ls, cat, grep, etc.)
49
49
 
50
+ **Web Search**
51
+ - `web_search(query, max_results)` - Search the web for current information
52
+
53
+ **Academic Search**
54
+ - `search_arxiv(query, max_results, categories, sort_by, sort_order, date_from, date_to)` - Search arXiv for academic papers
55
+ - sort_by: "relevance", "lastUpdatedDate", or "submittedDate"
56
+ - sort_order: "ascending" or "descending"
57
+ - date_from/date_to: filter by date (YYYY-MM-DD format)
58
+ - `fetch_arxiv_paper(arxiv_id)` - Get detailed info about a specific paper by ID
59
+ - `analyze_arxiv_paper(arxiv_id, prompt)` - Analyze a paper with LLM (async)
60
+
50
61
  **Checkpoints**
51
62
  - `create_checkpoint(name, content, content_type)` - Create a review point
52
63
 
@@ -159,6 +170,12 @@ AGENT_CONFIGS = [
159
170
  compare_versions,
160
171
  # App-specific shell tool
161
172
  run_safe_command,
173
+ # Web search
174
+ web_search,
175
+ # Academic search
176
+ search_arxiv,
177
+ fetch_arxiv_paper,
178
+ analyze_arxiv_paper,
162
179
  ],
163
180
  description="Research assistant with memory and planning capabilities",
164
181
  ),
@@ -0,0 +1,81 @@
1
+ """Main application for the Research Demo.
2
+
3
+ Showcases framework features through a research assistant agent
4
+ with memory, planning, file operations, shell commands, and HITL.
5
+
6
+ Feature managers (MemoryManager, TaskGraph, CheckpointManager) are
7
+ auto-created by the workflow manager based on tool requirements.
8
+ """
9
+
10
+ from rich.panel import Panel
11
+ from rich.text import Text
12
+
13
+ from agentic_cli import BaseCLIApp
14
+ from agentic_cli.cli import AppInfo
15
+ from agentic_cli.logging import Loggers
16
+
17
+ from examples.research_demo.agents import AGENT_CONFIGS
18
+ from examples.research_demo.commands import DEMO_COMMANDS
19
+ from examples.research_demo.settings import ResearchDemoSettings, get_settings
20
+
21
+ logger = Loggers.cli()
22
+
23
+
24
+ def _create_app_info() -> AppInfo:
25
+ """Create the application info for the welcome message."""
26
+ text = Text()
27
+ text.append("Research Demo\n\n", style="bold cyan")
28
+ text.append("A research assistant with memory and planning capabilities.\n\n", style="dim")
29
+ text.append("Features:\n", style="bold")
30
+ text.append(" - Working memory (session context)\n", style="dim")
31
+ text.append(" - Long-term memory (persistent learnings)\n", style="dim")
32
+ text.append(" - Task planning (research plans)\n", style="dim")
33
+ text.append(" - File operations (save/compare findings)\n", style="dim")
34
+ text.append(" - Shell commands (safe execution)\n", style="dim")
35
+ text.append("\n")
36
+ text.append("Commands:\n", style="bold")
37
+ text.append(" /memory - Show memory state\n", style="cyan")
38
+ text.append(" /plan - Show task plan\n", style="cyan")
39
+ text.append(" /files - List saved findings\n", style="cyan")
40
+ text.append(" /help - All commands\n", style="cyan")
41
+
42
+ return AppInfo(
43
+ name="Research Demo",
44
+ version="0.1.0",
45
+ welcome_message=lambda: Panel(text, border_style="cyan"),
46
+ echo_thinking=False,
47
+ )
48
+
49
+
50
+ class ResearchDemoApp(BaseCLIApp):
51
+ """Research Demo CLI Application.
52
+
53
+ Demonstrates framework features:
54
+ - Memory: Working memory (session) + Long-term memory (persistent)
55
+ - Planning: Task graphs with dependencies
56
+ - File Operations: Save/read/compare findings
57
+ - Shell Commands: Safe command execution
58
+ - HITL: Checkpoints for review
59
+
60
+ Feature managers are auto-created by the workflow manager based on
61
+ the @requires decorators on framework tools.
62
+ """
63
+
64
+ def __init__(self, settings: ResearchDemoSettings | None = None) -> None:
65
+ super().__init__(
66
+ app_info=_create_app_info(),
67
+ agent_configs=AGENT_CONFIGS,
68
+ settings=settings or get_settings(),
69
+ )
70
+
71
+ def register_commands(self) -> None:
72
+ """Register demo-specific commands."""
73
+ for command_class in DEMO_COMMANDS:
74
+ self.command_registry.register(command_class())
75
+
76
+ def get_ui_setting_keys(self) -> list[str]:
77
+ """Get field names to display in the settings dialog.
78
+
79
+ Includes verbose_thinking in addition to standard settings.
80
+ """
81
+ return ["model", "thinking_effort", "log_activity", "verbose_thinking"]
@@ -46,15 +46,12 @@ class MemoryCommand(Command):
46
46
  working_table.add_column("Tags", style="dim")
47
47
 
48
48
  if memory_manager:
49
- working_mem = memory_manager.working
50
- for key in working_mem.list():
51
- entry = working_mem._entries.get(key)
52
- if entry:
53
- value_str = str(entry.value)
54
- if len(value_str) > 50:
55
- value_str = value_str[:50] + "..."
56
- tags_str = ", ".join(entry.tags) if entry.tags else ""
57
- working_table.add_row(key, value_str, tags_str)
49
+ for key, (value, tags) in memory_manager.get_working_entries().items():
50
+ value_str = str(value)
51
+ if len(value_str) > 50:
52
+ value_str = value_str[:50] + "..."
53
+ tags_str = ", ".join(tags) if tags else ""
54
+ working_table.add_row(key, value_str, tags_str)
58
55
 
59
56
  if working_table.row_count == 0:
60
57
  working_table.add_row("(empty)", "", "")
@@ -173,7 +170,7 @@ class ApprovalsCommand(Command):
173
170
  app.session.add_message("system", "Approval manager not initialized")
174
171
  return
175
172
 
176
- pending = approval_manager._pending
173
+ pending = approval_manager.get_pending_requests()
177
174
 
178
175
  if not pending:
179
176
  app.session.add_message("system", "No pending approval requests")
@@ -186,7 +183,7 @@ class ApprovalsCommand(Command):
186
183
  table.add_column("Description", style="white")
187
184
  table.add_column("Risk", style="red")
188
185
 
189
- for request_id, request in pending.items():
186
+ for request in pending:
190
187
  table.add_row(
191
188
  request.id,
192
189
  request.tool,
@@ -218,21 +215,13 @@ class CheckpointsCommand(Command):
218
215
  app.session.add_message("system", "Checkpoint manager not initialized")
219
216
  return
220
217
 
221
- checkpoints = checkpoint_manager._checkpoints
222
- resolved = checkpoint_manager._results
223
-
224
- # Filter to unresolved checkpoints
225
- unresolved = {
226
- cp_id: cp
227
- for cp_id, cp in checkpoints.items()
228
- if cp_id not in resolved
229
- }
218
+ unresolved = checkpoint_manager.get_unresolved()
230
219
 
231
220
  if not unresolved:
232
221
  app.session.add_message("system", "No checkpoints awaiting review")
233
222
  return
234
223
 
235
- for cp_id, checkpoint in unresolved.items():
224
+ for checkpoint in unresolved:
236
225
  content_preview = str(checkpoint.content)
237
226
  if len(content_preview) > 200:
238
227
  content_preview = content_preview[:200] + "..."
@@ -339,7 +328,7 @@ class ClearPlanCommand(Command):
339
328
  task_graph = app.workflow.task_graph if app.workflow else None
340
329
 
341
330
  if task_graph:
342
- task_graph._tasks.clear()
331
+ task_graph.clear()
343
332
  app.session.add_success("Task plan cleared")
344
333
  else:
345
334
  app.session.add_error("Task graph not initialized")
@@ -31,12 +31,12 @@ class ResearchDemoSettings(BaseSettings):
31
31
  app_name: str = Field(default="research_demo")
32
32
  workspace_dir: Path = Field(default=Path.home() / ".research_demo")
33
33
 
34
- # Demo-specific setting with UI metadata
35
- verbose_output: bool = Field(
34
+ # Override verbose_thinking default for concise mode
35
+ verbose_thinking: bool = Field(
36
36
  default=False,
37
- title="Verbose Output",
37
+ title="Verbose Thinking",
38
38
  description="Show detailed thinking output (default: concise mode)",
39
- json_schema_extra={"ui_order": 40},
39
+ json_schema_extra={"ui_order": 35},
40
40
  )
41
41
 
42
42