Interfaces
Abstract Base Class interfaces for AI assistant system components.
Overview
This module provides comprehensive ABC-based interfaces that define clear contracts for all AI assistant implementations, replacing loose Protocol approach with explicit abstract methods and built-in validation support. Benefits of ABC Approach: - Explicit Contracts: Each assistant must implement all abstract methods - IDE Support: Better autocomplete and error detection - Runtime Checks: Python enforces implementation of abstract methods - Clear Documentation: Abstract methods document the interface - Type Safety: pyrefly can validate implementations - Extensibility: Easy to add new abstract methods
Classes
AssistantFactory
Abstract factory for creating and managing assistant instances.
Inherits from: ABC
Abstract class
Provides a factory pattern interface for creating assistant providers, checking availability, and managing the lifecycle of assistant instances. This enables dependency injection and testability.
Methods
create_assistant
create_assistant(self, name: str) -> Optional[specify_cli.assistants.interfaces.AssistantProvider]
Create an assistant provider instance by name.
Parameters:
name(str, required) - Unique identifier for the assistant (e.g., "claude", "gemini")
Returns: Optional
The factory should: - Validate the assistant name - Check if the assistant is available - Create and return a properly configured instance - Return None for unknown or unavailable assistants
get_available_assistants
get_available_assistants(self) -> List[str]
Return list of all available assistant names.
Returns: List
is_assistant_available
is_assistant_available(self, name: str) -> bool
Check if a specific assistant is available for creation.
Parameters:
name(str, required) - Assistant name to check
Returns: bool
This should be a fast check that doesn't create the assistant instance.
AssistantProvider
Abstract base class that all AI assistants must implement.
Inherits from: ABC
Abstract class
This interface defines the core contract that every assistant provider must fulfill, including configuration, template injection, validation, and setup instructions. Each assistant implementation must inherit from this class and implement all abstract methods to provide a consistent interface for the registry and template system.
Methods
format_import
format_import(self, current_dir: pathlib.Path, target_file: pathlib.Path) -> str
Format a file import statement for this assistant.
Parameters:
current_dir(Path, required) - Current working directory (where the template is being processed)target_file(Path, required) - Absolute path to the file being imported
Returns: str
get_injection_values
get_injection_values(self) -> Dict[specify_cli.assistants.injection_points.InjectionPointMeta, str]
Return injection point values for template rendering.
Returns: Dict
Must provide all required injection points and may optionally provide enhanced injection points for additional functionality. Required injection points: - assistant_command_prefix: CLI command prefix - assistant_setup_instructions: Human-readable setup steps - assistant_context_file_path: Path to main context file Optional injection points: - assistant_memory_configuration: Memory/constitution content - assistant_review_command: Code review command - assistant_documentation_url: Official documentation URL - assistant_workflow_integration: CI/CD integration details - assistant_custom_commands: Assistant-specific commands
get_setup_instructions
get_setup_instructions(self) -> List[str]
Return step-by-step setup instructions for this assistant.
Returns: List
Provides human-readable instructions that guide users through the complete setup process from installation to configuration. Instructions should cover: - Tool installation (if required) - Authentication/API key setup - Initial configuration - Verification steps
validate_setup
validate_setup(self) -> specify_cli.assistants.interfaces.ValidationResult
Validate that the assistant is properly set up and configured.
Returns: ValidationResult
Performs comprehensive validation of: - Required dependencies and tools - Configuration files and paths - Authentication and API access - Template injection point completeness Validation should check: - CLI tool availability (if required) - Authentication status - Configuration file existence - Required injection points presence - Path accessibility and permissions
Properties
configimports_supported
AssistantRegistry
Abstract registry for managing assistant provider instances.
Inherits from: ABC
Abstract class
Provides a centralized registry pattern for managing active assistant instances, validation, and lifecycle management. Separates instance management from creation concerns.
Methods
clear
clear(self) -> None
Remove all assistants from the registry.
Useful for: - Testing cleanup - Registry reset operations - Memory management in long-running processes
get_all_assistants
get_all_assistants(self) -> List[specify_cli.assistants.interfaces.AssistantProvider]
Get all currently registered assistant instances.
Returns: List
Useful for: - Bulk operations across all assistants - Validation of all registered assistants - Registry inspection and debugging
get_assistant
get_assistant(self, name: str) -> Optional[specify_cli.assistants.interfaces.AssistantProvider]
Retrieve a registered assistant by name.
Parameters:
name(str, required) - Unique identifier for the assistant
Returns: Optional
register_assistant
register_assistant(self, assistant: specify_cli.assistants.interfaces.AssistantProvider) -> None
Register an assistant provider instance in the registry.
Parameters:
assistant(AssistantProvider, required) - Fully configured AssistantProvider instance
The registry should: - Validate the assistant configuration - Store the instance for future retrieval - Handle name conflicts appropriately - Maintain type safety
unregister_assistant
unregister_assistant(self, name: str) -> bool
Remove an assistant from the registry.
Parameters:
name(str, required) - Name of assistant to remove
Returns: bool
validate_all
validate_all(self) -> Dict[str, specify_cli.assistants.interfaces.ValidationResult]
Validate all registered assistants and return comprehensive results.
Returns: Dict
InjectionProvider
Abstract base class that all AI assistants must implement.
Inherits from: ABC
Abstract class
This interface defines the core contract that every assistant provider must fulfill, including configuration, template injection, validation, and setup instructions. Each assistant implementation must inherit from this class and implement all abstract methods to provide a consistent interface for the registry and template system.
Methods
format_import
format_import(self, current_dir: pathlib.Path, target_file: pathlib.Path) -> str
Format a file import statement for this assistant.
Parameters:
current_dir(Path, required) - Current working directory (where the template is being processed)target_file(Path, required) - Absolute path to the file being imported
Returns: str
get_injection_values
get_injection_values(self) -> Dict[specify_cli.assistants.injection_points.InjectionPointMeta, str]
Return injection point values for template rendering.
Returns: Dict
Must provide all required injection points and may optionally provide enhanced injection points for additional functionality. Required injection points: - assistant_command_prefix: CLI command prefix - assistant_setup_instructions: Human-readable setup steps - assistant_context_file_path: Path to main context file Optional injection points: - assistant_memory_configuration: Memory/constitution content - assistant_review_command: Code review command - assistant_documentation_url: Official documentation URL - assistant_workflow_integration: CI/CD integration details - assistant_custom_commands: Assistant-specific commands
get_setup_instructions
get_setup_instructions(self) -> List[str]
Return step-by-step setup instructions for this assistant.
Returns: List
Provides human-readable instructions that guide users through the complete setup process from installation to configuration. Instructions should cover: - Tool installation (if required) - Authentication/API key setup - Initial configuration - Verification steps
validate_setup
validate_setup(self) -> specify_cli.assistants.interfaces.ValidationResult
Validate that the assistant is properly set up and configured.
Returns: ValidationResult
Performs comprehensive validation of: - Required dependencies and tools - Configuration files and paths - Authentication and API access - Template injection point completeness Validation should check: - CLI tool availability (if required) - Authentication status - Configuration file existence - Required injection points presence - Path accessibility and permissions
Properties
configimports_supported
ValidationResult
Pydantic model for validation results with comprehensive status tracking.
Inherits from: BaseModel
Provides structured validation feedback with errors, warnings, and overall status tracking for assistant setup and configuration.
Methods
add_error
add_error(self, error: str) -> 'ValidationResult'
Add a blocking error and mark validation as invalid.
Parameters:
error(str, required)
Returns: ValidationResult
add_warning
add_warning(self, warning: str) -> 'ValidationResult'
Add a non-blocking warning (doesn't affect validity).
Parameters:
warning(str, required)
Returns: ValidationResult
copy
copy(self, *, include: 'AbstractSetIntStr | MappingIntStrAny | None' = None, exclude: 'AbstractSetIntStr | MappingIntStrAny | None' = None, update: 'Dict[str, Any] | None' = None, deep: 'bool' = False) -> 'Self'
Returns a copy of the model.
Parameters:
include(AbstractSetIntStr | MappingIntStrAny | None, optional) - Optional set or mapping specifying which fields to include in the copied model.exclude(AbstractSetIntStr | MappingIntStrAny | None, optional) - Optional set or mapping specifying which fields to exclude in the copied model.update(Dict[str, Any] | None, optional) - Optional dictionary of field-value pairs to override field values in the copied model.deep(bool, optional) - If True, the values of fields that are Pydantic models will be deep-copied. - Default:False
Returns: Self
!!! warning "Deprecated" This method is now deprecated; use model_copy instead. If you need include or exclude, use: python `\{test="skip" lint="skip"\}` data = self.model_dump(include=include, exclude=exclude, round_trip=True) data = `\{**data, **(update or {\}`)} copied = self.model_validate(data)
model_construct
model_construct(_fields_set: 'set[str] | None' = None, **values: 'Any') -> 'Self'
Creates a new instance of the Model class with validated data.
Parameters:
_fields_set(set[str] | None, optional) - A set of field names that were originally explicitly set during instantiation. If provided,values(Any, required) - Trusted or pre-validated data dictionary.
Returns: Self
Creates a new model setting __dict__ and __pydantic_fields_set__ from trusted or pre-validated data. Default values are respected, but no other validation is performed. !!! note model_construct() generally respects the model_config.extra setting on the provided model. That is, if model_config.extra == 'allow', then all extra passed values are added to the model instance's __dict__ and __pydantic_extra__ fields. If model_config.extra == 'ignore' (the default), then all extra passed values are ignored. Because no validation is performed with a call to model_construct(), having model_config.extra == 'forbid' does not result in an error if extra values are passed, but they will be ignored.
model_copy
model_copy(self, *, update: 'Mapping[str, Any] | None' = None, deep: 'bool' = False) -> 'Self'
!!! abstract "Usage Documentation"
Parameters:
update(Mapping[str, Any] | None, optional) - Values to change/add in the new model. Note: the data is not validateddeep(bool, optional) - Set toTrueto make a deep copy of the model. - Default:False
Returns: Self
model_copy Returns a copy of the model. !!! note The underlying instance's [__dict__][object.dict] attribute is copied. This might have unexpected side effects if you store anything in it, on top of the model fields (e.g. the value of [cached properties][functools.cached_property]).
model_dump
model_dump(self, *, mode: "Literal['json', 'python'] | str" = 'python', include: 'IncEx | None' = None, exclude: 'IncEx | None' = None, context: 'Any | None' = None, by_alias: 'bool | None' = None, exclude_unset: 'bool' = False, exclude_defaults: 'bool' = False, exclude_none: 'bool' = False, round_trip: 'bool' = False, warnings: "bool | Literal['none', 'warn', 'error']" = True, fallback: 'Callable[[Any], Any] | None' = None, serialize_as_any: 'bool' = False) -> 'dict[str, Any]'
!!! abstract "Usage Documentation"
Parameters:
mode(Literal[json, python] | str, optional) - The mode in whichto_pythonshould run. - Default:pythoninclude(IncEx | None, optional) - A set of fields to include in the output.exclude(IncEx | None, optional) - A set of fields to exclude from the output.context(Any | None, optional) - Additional context to pass to the serializer.by_alias(bool | None, optional) - Whether to use the field's alias in the dictionary key if defined.exclude_unset(bool, optional) - Whether to exclude fields that have not been explicitly set. - Default:Falseexclude_defaults(bool, optional) - Whether to exclude fields that are set to their default value. - Default:Falseexclude_none(bool, optional) - Whether to exclude fields that have a value ofNone. - Default:Falseround_trip(bool, optional) - If True, dumped values should be valid as input for non-idempotent types such as Json[T]. - Default:Falsewarnings(bool | Literal[none, warn, error], optional) - How to handle serialization errors. False/"none" ignores them, True/"warn" logs errors, - Default:Truefallback(Callable[[Any], Any] | None, optional) - A function to call when an unknown value is encountered. If not provided,serialize_as_any(bool, optional) - Whether to serialize fields with duck-typing serialization behavior. - Default:False
Returns: dict[str, Any]
model_dump Generate a dictionary representation of the model, optionally specifying which fields to include or exclude.
model_dump_json
model_dump_json(self, *, indent: 'int | None' = None, include: 'IncEx | None' = None, exclude: 'IncEx | None' = None, context: 'Any | None' = None, by_alias: 'bool | None' = None, exclude_unset: 'bool' = False, exclude_defaults: 'bool' = False, exclude_none: 'bool' = False, round_trip: 'bool' = False, warnings: "bool | Literal['none', 'warn', 'error']" = True, fallback: 'Callable[[Any], Any] | None' = None, serialize_as_any: 'bool' = False) -> 'str'
!!! abstract "Usage Documentation"
Parameters:
indent(int | None, optional) - Indentation to use in the JSON output. If None is passed, the output will be compact.include(IncEx | None, optional) - Field(s) to include in the JSON output.exclude(IncEx | None, optional) - Field(s) to exclude from the JSON output.context(Any | None, optional) - Additional context to pass to the serializer.by_alias(bool | None, optional) - Whether to serialize using field aliases.exclude_unset(bool, optional) - Whether to exclude fields that have not been explicitly set. - Default:Falseexclude_defaults(bool, optional) - Whether to exclude fields that are set to their default value. - Default:Falseexclude_none(bool, optional) - Whether to exclude fields that have a value ofNone. - Default:Falseround_trip(bool, optional) - If True, dumped values should be valid as input for non-idempotent types such as Json[T]. - Default:Falsewarnings(bool | Literal[none, warn, error], optional) - How to handle serialization errors. False/"none" ignores them, True/"warn" logs errors, - Default:Truefallback(Callable[[Any], Any] | None, optional) - A function to call when an unknown value is encountered. If not provided,serialize_as_any(bool, optional) - Whether to serialize fields with duck-typing serialization behavior. - Default:False
Returns: str
model_dump_json Generates a JSON representation of the model using Pydantic's to_json method.
model_json_schema
model_json_schema(by_alias: 'bool' = True, ref_template: 'str' = '#/$defs/`\{model\}`', schema_generator: 'type[GenerateJsonSchema]' = `<class 'pydantic.json_schema.GenerateJsonSchema'>`, mode: 'JsonSchemaMode' = 'validation') -> 'dict[str, Any]'
Generates a JSON schema for a model class.
Parameters:
by_alias(bool, optional) - Whether to use attribute aliases or not. - Default:Trueref_template(str, optional) - The reference template. - Default:#/$defs/{model}``schema_generator(type[GenerateJsonSchema], optional) - To override the logic used to generate the JSON schema, as a subclass of - Default:pydantic.json_schema.GenerateJsonSchemamode(JsonSchemaMode, optional) - The mode in which to generate the schema. - Default:validation
Returns: dict[str, Any]
model_parametrized_name
model_parametrized_name(params: 'tuple[type[Any], ...]') -> 'str'
Compute the class name for parametrizations of generic classes.
Parameters:
params(tuple[type[Any], ...], required) - Tuple of types of the class. Given a generic class
Returns: str
This method can be overridden to achieve a custom naming scheme for generic BaseModels.
model_post_init
model_post_init(self, context: 'Any', /) -> 'None'
Override this method to perform additional initialization after __init__ and model_construct.
Parameters:
context(Any, required)
This is useful if you want to do some validation that requires the entire model to be initialized.
model_rebuild
model_rebuild(*, force: 'bool' = False, raise_errors: 'bool' = True, _parent_namespace_depth: 'int' = 2, _types_namespace: 'MappingNamespace | None' = None) -> 'bool | None'
Try to rebuild the pydantic-core schema for the model.
Parameters:
force(bool, optional) - Whether to force the rebuilding of the model schema, defaults toFalse. - Default:Falseraise_errors(bool, optional) - Whether to raise errors, defaults toTrue. - Default:True_parent_namespace_depth(int, optional) - The depth level of the parent namespace, defaults to 2. - Default:2_types_namespace(MappingNamespace | None, optional) - The types namespace, defaults toNone.
Returns: bool | None
This may be necessary when one of the annotations is a ForwardRef which could not be resolved during the initial attempt to build the schema, and automatic rebuilding fails.
model_validate
model_validate(obj: 'Any', *, strict: 'bool | None' = None, from_attributes: 'bool | None' = None, context: 'Any | None' = None, by_alias: 'bool | None' = None, by_name: 'bool | None' = None) -> 'Self'
Validate a pydantic model instance.
Parameters:
obj(Any, required) - The object to validate.strict(bool | None, optional) - Whether to enforce types strictly.from_attributes(bool | None, optional) - Whether to extract data from object attributes.context(Any | None, optional) - Additional context to pass to the validator.by_alias(bool | None, optional) - Whether to use the field's alias when validating against the provided input data.by_name(bool | None, optional) - Whether to use the field's name when validating against the provided input data.
Returns: Self
model_validate_json
model_validate_json(json_data: 'str | bytes | bytearray', *, strict: 'bool | None' = None, context: 'Any | None' = None, by_alias: 'bool | None' = None, by_name: 'bool | None' = None) -> 'Self'
!!! abstract "Usage Documentation"
Parameters:
json_data(str | bytes | bytearray, required) - The JSON data to validate.strict(bool | None, optional) - Whether to enforce types strictly.context(Any | None, optional) - Extra variables to pass to the validator.by_alias(bool | None, optional) - Whether to use the field's alias when validating against the provided input data.by_name(bool | None, optional) - Whether to use the field's name when validating against the provided input data.
Returns: Self
JSON Parsing Validate the given JSON data against the Pydantic model.
model_validate_strings
model_validate_strings(obj: 'Any', *, strict: 'bool | None' = None, context: 'Any | None' = None, by_alias: 'bool | None' = None, by_name: 'bool | None' = None) -> 'Self'
Validate the given object with string data against the Pydantic model.
Parameters:
obj(Any, required) - The object containing string data to validate.strict(bool | None, optional) - Whether to enforce types strictly.context(Any | None, optional) - Extra variables to pass to the validator.by_alias(bool | None, optional) - Whether to use the field's alias when validating against the provided input data.by_name(bool | None, optional) - Whether to use the field's name when validating against the provided input data.
Returns: Self
Properties
has_errorshas_warningsmodel_extramodel_fields_set