Osprey Integration#
ARIEL is not a standalone search engine — it is a capability within Osprey’s agent orchestration system. When a user asks a question like “What happened with the RF cavity last week?”, Osprey’s task classifier routes the request to the logbook_search capability, which invokes the ARIELSearchService and returns structured results that the response generator uses to produce a cited answer. This page documents how that integration works: the capability class, the context it produces, the prompt builder that customizes agent behavior, and the error classification that drives recovery strategies.
Integration Architecture#
User Query
↓
Task Classifier (uses ClassifierGuide)
↓ routes to logbook_search
Orchestrator (uses OrchestratorGuide)
↓ plans: [time_range_parsing → logbook_search → respond]
LogbookSearchCapability.execute()
├── get TIME_RANGE context (soft constraint)
├── build ARIELSearchRequest
└── call ARIELSearchService.search()
↓
LogbookSearchResultsContext
↓
RespondCapability → User Response
The flow begins when the task classifier determines that a user query involves historical logbook data. The classifier uses a TaskClassifierGuide — a set of labeled examples that teach the LLM which queries should activate this capability. Once classified, the orchestrator creates an execution plan. If the query contains time references (“last week”, “in January”), the plan includes a time_range_parsing step before the logbook search; otherwise, the search runs without a time filter. The LogbookSearchCapability executes the search and stores the results as a LogbookSearchResultsContext, which the RespondCapability uses to generate the final user-facing response.
The logbook_search Capability#
The LogbookSearchCapability bridges Osprey’s orchestration layer with the ARIELSearchService. It is registered as a built-in capability and auto-discovered by the registry.
Name |
|
Provides |
|
Requires |
|
Description |
Search and query historical logbook entries. Use when the user asks about past events, equipment history, operational incidents, or wants to find specific logbook entries by keyword or time period. |
Execution flow:
Get time range — calls
get_required_contexts(constraint_mode="soft")to retrieve anyTIME_RANGEcontext produced by an earlier planning step. If no time range was parsed, the search runs unfiltered.Build request — extracts the user’s query from the task objective and constructs an
ARIELSearchRequestwithmode=RAGand an optionaltime_rangetuple.Get service — calls
get_ariel_search_service()to obtain the singletonARIELSearchServiceinstance (lazily initialized fromconfig.yml).Execute search — invokes
service.search()with the request parameters. The service routes through the RAG pipeline by default: retrieve → fuse → assemble → generate.Store context — wraps the
ARIELSearchResultin aLogbookSearchResultsContextand stores it for downstream capabilities.
Source: src/osprey/capabilities/logbook_search.py
LogbookSearchResultsContext#
The capability produces a LogbookSearchResultsContext — a frozen dataclass that extends CapabilityContext.
Field |
Type |
Description |
|---|---|---|
|
|
Matching entries, ranked by relevance |
|
|
RAG-generated answer (if RAG was used) |
|
|
Entry IDs cited in the answer |
|
|
Search modes invoked (e.g., |
|
|
Original query text |
|
|
Whether a time filter was used |
|
|
|
|
``get_summary()`` returns both metadata (entry count, search modes, time filter) and content (the RAG answer, source IDs, and entry previews truncated to 200 characters). This follows the same pattern as PythonResultContext — including actual content in the summary ensures the RespondCapability has enough material to generate a meaningful user response without needing to access the full context object.
``get_access_details(key)`` provides instructions for other capabilities to access the results programmatically, following the standard context.LOGBOOK_SEARCH_RESULTS.<key> access pattern.
Orchestrator & Classifier Guides#
The logbook_search capability provides two guidance objects that teach Osprey’s LLM-based planner and classifier how to use it. Both are loaded from the prompt builder system, which allows facility-specific customization.
The OrchestratorGuide teaches the planning LLM when and how to include logbook search in execution plans.
Default instructions (from DefaultLogbookSearchPromptBuilder):
Plan
logbook_searchwhen users ask about facility history, past incidents, equipment behavior, or operational proceduresUse descriptive context keys:
ls_<topic>(e.g.,ls_injector_failures,ls_rf_trips)Plan
time_range_parsingbeforelogbook_searchwhen the query contains time referencesThe internal ReAct agent automatically selects the best search strategy
Examples included in the guide:
Semantic: “Search logbook for historical injector failure incidents” (with optional TIME_RANGE input)
Keyword: “Find logbook entries containing ‘BTS chicane alignment’” (no dependencies)
RAG: “Answer: How do we typically handle RF trips?” (generates cited answer)
The TaskClassifierGuide teaches the routing LLM which queries should activate this capability.
Examples:
Query |
Result |
Reason |
|---|---|---|
“What happened last time the injector failed?” |
True |
Request for historical incident information |
“Find entries about BTS chicane alignment” |
True |
Explicit request to search logbook entries |
“What is the current beam energy?” |
False |
Request for live data, not historical search |
“How do we typically handle RF trips?” |
True |
Operational knowledge documented in logs |
“Set the quadrupole current to 5A” |
False |
Control action, not logbook search |
“Show me beam loss events from January” |
True |
Historical entries with time filter |
“What did the night shift report about the vacuum issue?” |
True |
Operational shift report from logbook |
“How does the accelerator work?” |
False |
General physics question, not logbook search |
Customizing guides:
To provide facility-specific guidance, create a custom prompt builder that extends DefaultLogbookSearchPromptBuilder and override get_orchestrator_guide() or get_classifier_guide(). Register it through your application’s prompt configuration. See Prompt Customization for details.
Collaboration Welcome
If you write a custom prompt builder with classifier examples or orchestrator instructions tuned to your facility, consider opening a pull request so other sites can benefit from your improvements. Additional classifier examples improve routing accuracy for all users.
Service Factory & Prompt Builder Details
The DefaultLogbookSearchPromptBuilder provides the default orchestrator and classifier guidance for the logbook_search capability. It extends FrameworkPromptBuilder and is loaded automatically through the prompt builder system.
|
|
|
“You are a facility logbook search expert that finds relevant historical entries.” |
|
Instructions for search intent analysis, strategy selection, and citation requirements. |
|
Returns the |
|
Returns the |
Fallback behavior: If the prompt builder system is unavailable (e.g., in a minimal deployment without a registry), the LogbookSearchCapability falls back to built-in default guides defined in _default_orchestrator_guide() and _default_classifier_guide(). These provide the same core guidance without the extended examples.
Source: src/osprey/prompts/defaults/logbook_search.py
The get_ariel_search_service() function in osprey.services.ariel_search.capability provides a singleton ARIELSearchService instance. The service is lazily initialized from config.yml on first access and reused for subsequent calls.
from osprey.services.ariel_search.capability import get_ariel_search_service
service = await get_ariel_search_service()
async with service:
result = await service.search(query="RF cavity fault")
Lifecycle: The singleton is created once per process. In the web interface, the create_app() factory manages its own service instance through the FastAPI lifespan. For cleanup in tests, use close_ariel_service() (closes the connection pool) or reset_ariel_service() (resets without closing).
Source: src/osprey/services/ariel_search/capability.py
Error Classification#
The classify_error() static method maps ARIEL exceptions to structured ErrorClassification objects that drive Osprey’s recovery system. Each classification includes a severity level and an actionable user_message that helps users resolve common setup issues.
Exception |
Severity |
User Guidance |
|---|---|---|
|
CRITICAL |
“Run |
|
CRITICAL |
“Run |
|
RETRIABLE |
“Database query error, retrying…” |
|
CRITICAL |
“Embedding model unavailable. Disable semantic search if not needed.” |
|
CRITICAL |
Includes the specific |
Other exceptions |
CRITICAL |
Includes |
The severity level determines how Osprey handles the error: CRITICAL errors are surfaced to the user immediately with the guidance message, while RETRIABLE errors trigger automatic retry with backoff.
Exception Hierarchy
All ARIEL exceptions inherit from ARIELException, which carries a message, an ErrorCategory, and optional technical_details. The is_retriable property returns True for DATABASE and EMBEDDING categories.
Exception |
Category |
Description |
|---|---|---|
|
DATABASE |
Unable to connect to the ARIEL PostgreSQL database |
|
DATABASE |
A database query failed during execution |
|
EMBEDDING |
Embedding model failed to generate vectors |
|
SEARCH |
A search operation failed during execution |
|
INGESTION |
Data ingestion failed during processing |
|
INGESTION |
Requested ingestion adapter is not registered |
|
CONFIGURATION |
ARIEL configuration is invalid |
|
CONFIGURATION |
Attempted to use a module that is not enabled |
|
TIMEOUT |
Search execution exceeded the configured timeout |
Source: src/osprey/services/ariel_search/exceptions.py · API Reference
See Also#
- Data Ingestion
How data gets into the system — facility adapters, enhancement modules, and database schema
- Search Modes
Search module and pipeline architecture
- Web Interface
Web interface architecture and REST API
- Built-in Capabilities
Built-in capabilities reference
- Prompt Customization
Prompt builder customization
- ARIEL Search Service
Full API reference for ARIEL classes