API Reference
This section is generated from the Python source tree with mkdocstrings.
Configuration
tuochat.config
Configuration loading for tuochat.
Loads settings from TOML config files with env var overrides. Supports XDG paths on Linux, standard paths on macOS/Windows.
GitLabConfig
dataclass
GitLab connection settings.
OpenRouterConfig
dataclass
OpenRouter connection settings (optional alternative to Duo).
effective_models()
Return the model rotation list, falling back to model when empty.
JiraConfig
dataclass
Jira connection settings (optional extra).
effective_deployment()
Return explicit deployment or infer from host.
ChatConfig
dataclass
Chat behavior settings.
NotificationsConfig
dataclass
Notification behavior settings.
PersonalizationConfig
dataclass
Optional first-request personalization settings.
ClassificationConfig
dataclass
Document classification settings used by classification workflows.
RecordsConfig
dataclass
Records-keeping and retention settings for saved conversation files.
WarnWordsConfig
dataclass
Optional case-insensitive phrase warnings.
PickerConfig
dataclass
Controls how interactive item pickers behave in the CLI.
mode
"auto" — adapt based on list size and blind_mode (default) "paged" — always page through items in chunks "ask_one" — present one item at a time (accessible, screen-reader friendly)
list_threshold
In "auto" mode, lists with this many items or fewer are shown all at once.
prefilter_threshold
In "auto" mode, lists larger than this prompt for a substring filter before displaying. Has no effect in "paged" or "ask_one" modes.
page_size
Number of items shown per page in "paged" and "auto" (large-list) modes.
SecurityConfig
dataclass
Security-related startup settings.
FeaturesConfig
dataclass
Lightweight feature flags for incubating behavior.
GuiConfig
dataclass
GUI font and visual theme settings.
WebAttachConfig
dataclass
Settings for the /web and /web-preview attachment commands.
TuochatConfig
dataclass
Top-level configuration.
db_path
property
Path to the SQLite database.
config_file
property
Path to the config file.
custom_instructions_dir
property
Directory containing custom instruction files.
skills_dir
property
Directory containing skill files.
templates_dir
property
Directory containing prompt template files.
validate()
Return a list of validation warnings (empty = valid).
redacted()
Return config as a dict with the token redacted.
default_gitlab_user_agent()
Return the default GitLab-facing user agent for this client.
config_dir()
Return the platform-appropriate config directory.
data_dir()
Return the platform-appropriate data directory.
log_dir()
Return the platform-appropriate log directory.
normalize_jira_host(host)
Normalize a Jira host to a stable HTTPS origin without a trailing slash.
normalize_gitlab_host(host)
Normalize a GitLab host to a stable HTTPS origin without a trailing slash.
parse_env_line(line)
Parse a single .env line supporting optional export prefixes.
load_dotenv(dotenv_path=None, *, override=False)
Load environment variables from a .env file using only stdlib.
redact_token(token)
Redact a token for display, showing only first 8 chars.
load_config(config_path=None)
Load configuration from TOML file with env var overrides.
Priority (highest to lowest): 1. Environment variables (TUOCHAT_GITLAB_HOST, TUOCHAT_GITLAB_TOKEN) 2. Config file specified by TUOCHAT_CONFIG env var 3. Config file at the platform-default location 4. Built-in defaults
write_default_config(config_path=None, *, force=False)
Create a starter config file and return its path.
render_config(cfg)
Render a config object to TOML.
save_config(cfg, config_path=None)
Write a config object to disk and return its path.
apply_toml(cfg, data)
Apply parsed TOML data to a config object.
Models
tuochat.models
Domain models for tuochat.
Plain dataclasses representing conversations, messages, and usage. Serializable to/from dicts for JSON and sqlite storage.
Role
Bases: str, Enum
Message role.
MessageStatus
Bases: str, Enum
Message completion status.
Message
dataclass
A single message in a conversation.
to_dict()
Serialize to a dict.
from_dict(data)
classmethod
Deserialize from a dict.
Conversation
dataclass
A chat conversation (collection of messages).
to_dict()
Serialize to a dict (without messages).
to_record()
Serialize a conversation including messages for JSON round-tripping.
from_dict(data)
classmethod
Deserialize from a dict (without messages).
from_record(data)
classmethod
Deserialize a conversation including messages from JSON-friendly data.
add_message(role, content, **kwargs)
Create and append a message to this conversation.
auto_title(first_user_text=None)
Generate a title from the first user message.
Pass first_user_text to use the raw user input rather than the stored message content (which may include attachment payloads).
Usage
dataclass
Token usage record for a single message exchange.
to_dict()
Serialize to a dict.
from_dict(data)
classmethod
Deserialize from a dict.
ConversationSearchResult
dataclass
A full-text search match for a conversation.
GitLab integration
tuochat.gitlab_client
GitLab metadata client — separate from the Duo chat transport.
Wraps python-gitlab for resource discovery (projects, groups). Never touches the Duo API; that lives in provider/duo.py.
GitLabMetaClient
Thin wrapper around python-gitlab for resource discovery.
list_projects(*, limit=30, membership=True)
Return up to limit projects the current user is a member of.
list_groups(*, limit=30)
Return up to limit groups the current user belongs to.
search_projects(query, *, limit=20)
Search for projects matching query.
get_project_by_path(path)
Look up a single project by its namespace path (e.g. 'group/repo').
get_project(project_id)
Return the raw python-gitlab Project object, or None on failure.
list_issues(project_id, *, limit=20, state='opened')
Return a list of issue dicts {iid, title, state, url, description} for project_id.
get_issue(project_id, iid)
Fetch a single issue by project-local IID.
list_mrs(project_id, *, limit=20, state='opened')
Return a list of MR dicts {iid, title, state, url, description, source_branch, target_branch}.
get_mr(project_id, iid)
Fetch a single MR by project-local IID.
get_file_content(project_id, file_path, ref='HEAD')
Return decoded text content of a repository file, or None on failure.
list_pipelines(project_id, *, limit=10)
Return recent pipeline dicts {id, status, ref, web_url, created_at} for project_id.
list_tree(project_id, path='', ref='HEAD', *, limit=50)
List repository tree entries (files and directories) at path.
get_gitlab_module()
Import gitlab, raising ImportError with a helpful message if missing.
build_meta_client(cfg)
Construct a GitLabMetaClient from the active config.
Resource descriptors
tuochat.resources
GitLab resource descriptor — normalized representation of a selectable resource.
A ResourceDescriptor is the single shared type for anything a user can pick
and attach to a Duo chat session as the active resource_id. It carries
just enough display metadata so the REPL can render it cleanly without
making additional API calls.
ResourceDescriptor
dataclass
A normalized resource that can be passed to Duo as resource_id.
resource_descriptor_from_project(project)
Build a ResourceDescriptor from a python-gitlab Project object.
resource_descriptor_from_group(group)
Build a ResourceDescriptor from a python-gitlab Group object.
Serialization helpers
tuochat.serialization
json_loads(s)
Load JSON from string or bytes.
json_dumps(obj, indent=False, sort_keys=False, default=None, ensure_ascii=False)
Dump object to JSON string.
json_dumps_bytes(obj, indent=False, sort_keys=False, default=None, ensure_ascii=False)
Dump object to JSON bytes.
toml_load(f)
Load TOML from file-like object.
toml_loads(s)
Load TOML from string.
Persistence
Conversation store
tuochat.persistence.store
SQLite persistence for conversations and messages.
Uses only stdlib sqlite3. Schema is versioned with a simple migration table.
ConversationStore
SQLite-backed storage for conversations and messages.
conn
property
Return the SQLite connection for the current thread.
migrate()
Apply schema migrations.
ensure_message_index()
Ensure the full-text index exists and can answer searches.
rebuild_message_index()
Rebuild the FTS index from the canonical messages table.
close()
Close the database connection.
save_conversation(conv)
Insert or update a conversation.
get_conversation(conv_id)
Load a conversation by ID (without messages).
list_conversations(limit=50, *, archived=False)
List conversations ordered by most recently updated.
list_archived_conversations(limit=50)
List archived conversations ordered by most recently updated.
list_expired_conversations(cutoff_iso, limit=100)
List conversations older than the given ISO timestamp.
delete_conversation(conv_id)
Delete a conversation and its messages.
set_conversation_archived(conv_id, archived)
Set archived status for a conversation.
unarchive_all_conversations()
Unarchive every archived conversation.
save_message(msg)
Insert or update a message.
get_messages(conv_id)
Get all messages for a conversation, ordered by creation time.
search_conversations(query, *, limit=20, title_filter=None, updated_after=None, updated_before=None)
Search conversation messages with optional title and date filters.
save_usage(usage)
Record token usage.
get_weekly_usage(week_start_iso)
Return aggregated token usage since the given ISO timestamp (week start).
Returns a dict with keys: input_tokens, output_tokens, total_tokens, turns. The caller is responsible for computing the week_start_iso (Sunday 00:00 UTC).
save_observability_row(row)
Insert one Duo response observability row.
get_observability_rows(since_iso)
Fetch raw observability rows since the given UTC ISO timestamp.
get_observability_rollups(since_iso)
Return daily rollup objects for the observability surfaces.
Triggers lazy retention cleanup before reading.
cleanup_observability_retention(days=30)
Delete observability rows older than days days. Idempotent.
save_error_log_entry(recorded_at, level, level_name, logger_name, message, exc_type, exc_value, exc_traceback, filename, lineno, func_name)
Insert one error log entry.
get_error_log_entries(limit=500, min_level=logging.WARNING)
Fetch error log entries at or above min_level, newest first.
Triggers lazy retention cleanup before reading.
delete_error_log_entry(entry_id)
Delete a single error log entry by id. Returns True if a row was deleted.
clear_error_log()
Delete all error log entries. Returns the count deleted.
cleanup_error_log_retention(days=30)
Delete error log entries older than days days. Idempotent.
export_markdown(conv_id)
Export a conversation as markdown.
NullConversationStore
Read-only no-op store used when local writes are disabled.
close()
Close the store.
save_conversation(conv)
No-op conversation save.
get_conversation(conv_id)
No saved conversations exist while writes are disabled.
list_conversations(limit=50, *, archived=False)
Return no conversations.
list_archived_conversations(limit=50)
Return no archived conversations.
list_expired_conversations(cutoff_iso, limit=100)
Return no expired conversations.
delete_conversation(conv_id)
Deletion is unavailable while writes are disabled.
set_conversation_archived(conv_id, archived)
Archiving is unavailable while writes are disabled.
unarchive_all_conversations()
No archived conversations exist.
save_message(msg)
No-op message save.
get_messages(conv_id)
Return no persisted messages.
search_conversations(query, *, limit=20, title_filter=None, updated_after=None, updated_before=None)
Return no search results.
save_usage(usage)
No-op usage save.
get_weekly_usage(week_start_iso)
Return empty usage totals.
save_observability_row(row)
No-op: observability is unavailable while writes are disabled.
get_observability_rows(since_iso)
No observability rows while writes are disabled.
get_observability_rollups(since_iso)
No observability rollups while writes are disabled.
cleanup_observability_retention(days=30)
No-op cleanup while writes are disabled.
save_error_log_entry(recorded_at, level, level_name, logger_name, message, exc_type, exc_value, exc_traceback, filename, lineno, func_name)
No-op: error logging unavailable while writes are disabled.
get_error_log_entries(limit=500, min_level=logging.WARNING)
Return no error log entries while writes are disabled.
delete_error_log_entry(entry_id)
Deletion unavailable while writes are disabled.
clear_error_log()
No-op clear while writes are disabled.
cleanup_error_log_retention(days=30)
No-op cleanup while writes are disabled.
export_markdown(conv_id)
No exports are available without local persistence.
Archive helpers
tuochat.persistence.archive
Conversation archiving — filesystem I/O, no terminal output.
BagitCheckResult
dataclass
Validation status for one saved conversation archive.
conversation_archive_root(cfg)
Return the root directory used for conversation archives.
workspace_tuochat_root()
Return the cwd-local runtime directory used by write-here mode.
ensure_workspace_gitignore(root)
Ensure workspace-local archive files stay ignored without touching the repo root.
find_enclosing_git_dir(start)
Return the git directory for the current workspace when one is discoverable.
ensure_repo_exclude_ignores_workspace_tuochat(root)
Ignore the workspace runtime folder without editing the tracked root .gitignore.
write_here_mode_enabled(cfg)
Return whether cwd write-here behavior is enabled for this session.
safety_check_extension_enabled(cfg)
Return whether extracted files should keep the safety .check suffix.
path_is_filesystem_root(path)
Return whether a path points at a filesystem root.
conversation_archive_dir(cfg, conv, *, create=True)
Return the filesystem directory used for a conversation archive.
conversation_payload_dir(cfg, conv, *, create=True)
Return the payload directory used inside a conversation archive.
conversation_markdown_path(cfg, conv, *, create=True)
Return the markdown transcript path for a conversation archive.
parse_iso_datetime(value)
Parse an ISO timestamp, tolerating missing values.
archive_date_prefix(conv)
Return the date prefix for a conversation archive directory.
find_archive_dir_for_conversation(root, conversation_id)
Find an existing archive directory for the given conversation id.
allocate_archive_dir(root, conv)
Allocate a stable date-sequence archive directory for a conversation.
sanitize_relative_output_path(name)
Return a filesystem-safe relative path for extracted output.
write_here_target_path(name)
Return a safe cwd-relative target path, or None when the hint is unsafe.
unique_path(path, *, content=None)
Pick a non-clobbering path, reusing an existing file when the content matches.
numbered_path(path)
Pick a non-clobbering path by numbering when the target already exists.
format_generated_header_text(cfg, header_date)
Render the configured generated-file header text.
commentize_header(path, text)
Convert header text into the appropriate comment syntax for a path.
apply_generated_file_header(path, content, cfg, *, header_date)
Prepend the configured generated-file header when enabled.
filename_hint_from_block(info, content)
Infer a filename from a fenced block info string, trying many common LLM styles.
Recognised forms (in priority order):
python:password_manager.py colon-joined lang:pathpython password_manager.py space-separated second token
python title="password_manager.py" attribute (title/filename/file/name/path/source)python {filename="..."} JSX / Pandoc brace attributes
{.python filename="..."} Pandoc class+attr path/to/file.py bare path as the whole info string
Inside-block first-line comment hints are handled separately via FILENAME_HINT_RE.
filename_hint_before_block(text, block_start)
Infer a filename from the nearby lines immediately before a fenced block.
extract_filename_hint_from_line(line)
Extract a likely filename hint from a single nearby markdown line.
strip_markdown_filename_formatting(line)
Remove common markdown wrappers around a bare filename hint.
is_likely_filename_hint(candidate)
Return whether a nearby line looks like a standalone filename or path.
extension_for_language(language)
Map a fenced code language to a likely file extension.
normalize_extracted_output_path(path, *, language, cfg)
Normalize extracted code output names and apply the safety .check suffix when configured.
restore_markdown_inner_fences(content)
Convert the markdown-in-markdown tilde workaround back to triple-backtick fences.
should_restore_markdown_inner_fences(path, *, language)
Return whether extracted content should restore markdown inner fences.
is_bagit_tag_file(path)
Return whether the path is BagIt metadata rather than conversation payload.
ensure_archive_payload_layout(archive_dir)
Ensure a conversation archive stores payload files in a BagIt-style data directory.
load_bagit_module()
Return the optional bagit module when installed.
bag_info_for_conversation(conv, *, classification=None, user=None)
Build BagIt metadata for a conversation archive.
write_bagit_tag_file(path, values)
Write a BagIt tag file in the simple key-value format bagit expects.
initialize_bagit_archive(bagit_module, archive_dir, bag_info)
Create BagIt metadata for an archive that is not yet a bag.
sync_bagit_metadata(archive_dir, conv, *, classification=None, user=None, bagit_module=None)
Refresh BagIt metadata and manifests when bagit is available.
refresh_archive_bagit_metadata(cfg, conversations_by_id=None, *, user=None, bagit_module=None)
Refresh BagIt metadata for every saved conversation archive under the active root.
check_archive_bagit_status(cfg, *, bagit_module=None)
Report whether saved conversation archives still validate against BagIt metadata.
detect_partial_code_fence(content)
Return (language_hint, partial_content, name_hint) when the response ends mid-fence.
A partial fence is one that opens (lang) but the response text ends before
the closing ( on its own line) appears. Returns (None, None, None) when no
unclosed fence is detected.
normalize_escaped_fences(content)
Normalize LLM-escaped backtick fences to standard triple-backtick fences.
Some LLMs escape their own code fences (e.g. " `python foo.py") when the
user prompt itself contains triple-backtick fences, to avoid breaking markdown
rendering. This converts them back to proper triple-backtick fences so that
FENCED_BLOCK_RE can match them.
extract_code_files(conv_dir, conv, cfg, *, approve_write=None)
Extract assistant fenced code blocks to sibling files.
render_conversation_markdown(conv, *, conv_dir=None, extracted_files=None, classification=None, user=None, os_user=None, gitlab_user=None, retention_years=0, retention_label='')
Render a conversation as markdown with optional file references.
sync_conversation_artifacts(cfg, conv, *, classification=None, approve_write=None)
Persist a conversation as markdown plus extracted fenced files.
Sandbox
tuochat.sandbox.api
Public entry point: resolve engine, dispatch to adapter, return CodeOutput.
code_interpreter_runtime_details()
Return installed sandbox-runtime details for doctor and GUI surfaces.
resolve_language(tag)
Normalize a fenced-block info string to a supported language name.
resolve_js_adapter()
Return the best available JS adapter, following preference order.
resolve_lua_adapter()
Return the Lua adapter or raise ImportError.
get_adapter(language)
Return an adapter instance for the given language.
run_code(request)
Execute sandboxed code and return a CodeOutput.
This is the single public entry point for the sandbox package.
available_languages()
Return the list of languages with an installed runtime.
CLI entrypoint
tuochat.cli.entrypoint
Lightweight CLI entrypoint focused on fast parser startup.
build_parser()
Build the root argparse parser without importing the full REPL stack.
global_options_from_args(args)
Translate argparse output into global options.
load_config(config_path=None)
Load config from the requested path or default locations.
load_config_with_cli_overrides(config_path=None)
Load config from the requested path or default locations.
main(argv=None)
CLI entrypoint.