Core Services 
Services encapsulate business logic and provide reusable functionality to pipes. They are managed by the dependency injection container.
Service Classes vs. Configuration Entries 
Service classes are Python implementations that live in packages (for example otai_base.ticket_system_integration.TicketSystemService subclasses). They become usable inside Open Ticket AI when you expose them through the plugin registry.
Service configuration entries live in open_ticket_ai.services inside your YAML configuration. Each entry binds a service class to an identifier, optional constructor parameters, and a dependency-injection scope. Multiple entries can reference the same class while providing different parameters.
Example: Multiple Services Configured at Once 
yaml
open_ticket_ai:
  services:
    jinja_default:
      use: "base:JinjaRenderer"
    otobo_znuny:
      use: "otobo-znuny:OTOBOZnunyTicketSystemService"
      params:
        base_url: "http://example/otobo/nph-genericinterface.pl"
        password: "${OTOBO_PASSWORD}"
    hf_local:
      use: "hf-local:HFClassificationService"
      params:
        model_name: "softoft/otai-queue-de-bert-v1"In this configuration three independent services become available for injection. Pipes select the instance they need by referencing the entry identifier, for example:
yaml
- id: fetch_otobo
  use: "base:FetchTicketsPipe"
  injects:
    ticket_system: "otobo_znuny"Core Service Types 
Ticket Services 
- TicketSystemAdapter: Interface to ticket systems
- TicketFetcher: Retrieves tickets
- TicketUpdater: Updates ticket properties
Classification Services 
- ClassificationService: ML-based classification
- QueueClassifier: Queue assignment logic
- PriorityClassifier: Priority assignment logic
Utility Services 
- TemplateRenderer: Jinja2 template rendering (can be configured in defsfor customization)
- ConfigurationService: Access to configuration
- LoggerFactory: Centralized logging with pluggable backends (stdlib/structlog)
Service Lifecycle and Scopes 
When the application loads configuration it converts each open_ticket_ai.services entry into an InjectableConfig and registers it with the DI container. Every entry yields a distinct injectable instance. If you configure three ticket system services, all three can be injected simultaneously under their identifiers.
Scopes control when those instances are created and reused. Open Ticket AI supports:
- Singleton scope (default) – the container creates one instance per configuration entry and reuses it across the application.
- Transient scope – a new instance is created each time the service is injected.
Choose the scope that matches the service’s statefulness. See the Dependency Injection guide for details about scopes and the Configuration Reference for the services structure.
Creating Custom Services 
- Define service interface
- Implement service
- Register with DI container using the injector module
- Add a configuration entry and inject it into pipes
Service Best Practices 
Do: 
- Keep services focused on single responsibility
- Use interfaces for service contracts
- Make services stateless when possible
- Inject dependencies, don't create them
- Write unit tests for services
Don't: 
- Store execution state in service instances
- Access configuration directly (inject ConfigurationService)
- Create circular dependencies
- Mix business logic with infrastructure concerns
Testing Services 
Services should be unit tested independently from the pipes that use them. Create test instances of services and verify their behavior with test data.