feat: add psagentai agent with deployment and configuration

Initial project setup including the main agent script, configuration
files, profile JSON state, systemd service unit, startup script,
deployment documentation, and Python dependencies.

Includes .env, venv/, and __pycache__/ which should likely be
excluded via .gitignore to avoid committing secrets and artifacts.
This commit is contained in:
2026-10-25 17:05:13 -03:00
commit 6b3b6541a7
3792 changed files with 805563 additions and 0 deletions
@@ -0,0 +1,193 @@
from __future__ import annotations
import sys as _sys
from typing import Any as _Any
from typing_extensions import Sentinel
from ._pydantic_core import (
ArgsKwargs,
MultiHostUrl,
PydanticCustomError,
PydanticKnownError,
PydanticOmit,
PydanticSerializationError,
PydanticSerializationUnexpectedValue,
PydanticUndefined,
PydanticUndefinedType,
PydanticUseDefault,
SchemaError,
SchemaSerializer,
SchemaValidator,
Some,
TzInfo,
Url,
ValidationError,
__version__,
from_json,
to_json,
to_jsonable_python,
)
from .core_schema import CoreConfig, CoreSchema, CoreSchemaType, ErrorType
if _sys.version_info < (3, 11):
from typing_extensions import NotRequired as _NotRequired
else:
from typing import NotRequired as _NotRequired
if _sys.version_info < (3, 12):
from typing_extensions import TypedDict as _TypedDict
else:
from typing import TypedDict as _TypedDict
__all__ = [
'__version__',
'UNSET',
'CoreConfig',
'CoreSchema',
'CoreSchemaType',
'SchemaValidator',
'SchemaSerializer',
'Some',
'Url',
'MultiHostUrl',
'ArgsKwargs',
'PydanticUndefined',
'PydanticUndefinedType',
'SchemaError',
'ErrorDetails',
'InitErrorDetails',
'ValidationError',
'PydanticCustomError',
'PydanticKnownError',
'PydanticOmit',
'PydanticUseDefault',
'PydanticSerializationError',
'PydanticSerializationUnexpectedValue',
'TzInfo',
'to_json',
'from_json',
'to_jsonable_python',
]
class ErrorDetails(_TypedDict):
type: str
"""
The type of error that occurred, this is an identifier designed for
programmatic use that will change rarely or never.
`type` is unique for each error message, and can hence be used as an identifier to build custom error messages.
"""
loc: tuple[int | str, ...]
"""Tuple of strings and ints identifying where in the schema the error occurred."""
msg: str
"""A human readable error message."""
input: _Any
"""The input data at this `loc` that caused the error."""
ctx: _NotRequired[dict[str, _Any]]
"""
Values which are required to render the error message, and could hence be useful in rendering custom error messages.
Also useful for passing custom error data forward.
"""
url: _NotRequired[str]
"""
The documentation URL giving information about the error. No URL is available if
a [`PydanticCustomError`][pydantic_core.PydanticCustomError] is used.
"""
class InitErrorDetails(_TypedDict):
type: str | PydanticCustomError
"""The type of error that occurred, this should be a "slug" identifier that changes rarely or never."""
loc: _NotRequired[tuple[int | str, ...]]
"""Tuple of strings and ints identifying where in the schema the error occurred."""
input: _Any
"""The input data at this `loc` that caused the error."""
ctx: _NotRequired[dict[str, _Any]]
"""
Values which are required to render the error message, and could hence be useful in rendering custom error messages.
Also useful for passing custom error data forward.
"""
class ErrorTypeInfo(_TypedDict):
"""
Gives information about errors.
"""
type: ErrorType
"""The type of error that occurred, this should be a "slug" identifier that changes rarely or never."""
message_template_python: str
"""String template to render a human readable error message from using context, when the input is Python."""
example_message_python: str
"""Example of a human readable error message, when the input is Python."""
message_template_json: _NotRequired[str]
"""String template to render a human readable error message from using context, when the input is JSON data."""
example_message_json: _NotRequired[str]
"""Example of a human readable error message, when the input is JSON data."""
example_context: dict[str, _Any] | None
"""Example of context values."""
class MultiHostHost(_TypedDict):
"""
A host part of a multi-host URL.
"""
username: str | None
"""The username part of this host, or `None`."""
password: str | None
"""The password part of this host, or `None`."""
host: str | None
"""The host part of this host, or `None`."""
port: int | None
"""The port part of this host, or `None`."""
MISSING = Sentinel('MISSING')
"""
/// version-added | v2.12
///
/// version-changed | v2.14
The `MISSING` sentinel is no longer experimental.
///
The `MISSING` sentinel is a singleton indicating a field value was not provided during validation.
This singleton can be used as a default value, as an alternative to `None` when it has an explicit
meaning. During serialization, any field with `MISSING` as a value is excluded from the output.
At runtime, the `MISSING` sentinel is implemented as a [`sentinel`](https://docs.python.org/3.15/library/functions.html#sentinel) instance.
```python
from pydantic import MISSING, BaseModel
class Configuration(BaseModel):
timeout: int | None | MISSING = MISSING
# configuration defaults, stored somewhere else:
defaults = {'timeout': 200}
conf = Configuration()
# `timeout` is excluded from the serialization output:
conf.model_dump()
# {}
# The `MISSING` value doesn't appear in the JSON Schema:
Configuration.model_json_schema()['properties']['timeout']
#> {'anyOf': [{'type': 'integer'}, {'type': 'null'}], 'title': 'Timeout'}
# `is` can be used to discriminate between the sentinel and other values:
timeout = conf.timeout if conf.timeout is not MISSING else defaults['timeout']
```
!!! note
When [applying constraints](./fields.md#field-constraints) to a union containing the `MISSING` sentinel,
such constraints are automatically applied to the remaining type(s) of the union.
"""
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,34 @@
from typing import final
from pydantic_core.core_schema import CoreSchema, DefinitionReferenceSchema
__all__ = ['MissingDefinitionError', 'gather_schemas_for_cleaning']
@final
class MissingDefinitionError(LookupError):
"""A reference was pointing to a non-existing core schema."""
def __init__(self, schema_reference: str, /) -> None: ...
@property
def schema_reference(self) -> str: ...
def gather_schemas_for_cleaning(
schema: CoreSchema, definitions: dict[str, CoreSchema]
) -> tuple[dict[str, DefinitionReferenceSchema | None], list[CoreSchema]]:
"""Traverse the core schema and definitions and return the necessary information for schema cleaning.
During the core schema traversing, any `'definition-ref'` schema is:
- Validated: the reference must point to an existing definition. If this is not the case, a
`MissingDefinitionError` exception is raised.
- Stored in the context: the actual reference is stored in the context. Depending on whether
the `'definition-ref'` schema is encountered more than once, the schema itself is also
saved in the context to be inlined (i.e. replaced by the definition it points to).
Returns a `(collected_references, deferred_discriminator_schemas)` tuple:
- `collected_references`: the collected definition references. If a definition reference schema
can be inlined, it means that there is only one in the whole core schema. As such, it is stored
as the value. Otherwise, the value is set to `None`.
- `deferred_discriminator_schemas`: the list of core schemas having the discriminator application deferred.
"""
File diff suppressed because it is too large Load Diff