# https://github.com/TaskingAI/TaskingAI Project Manual

Generated at: 2026-06-24 18:37:30 UTC

## Table of Contents

- [Overview](#page-overview)
- [App](#page-inference-app)
- [App](#page-plugin-app)
- [Models](#page-backend-app-models)

<a id='page-overview'></a>

## Overview

### Related Pages

Related topics: [App](#page-inference-app)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [README.md](https://github.com/TaskingAI/TaskingAI/blob/main/README.md)
- [backend/app/models/assistant/assistant.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/assistant/assistant.py)
- [backend/app/models/assistant/chat.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/assistant/chat.py)
- [backend/app/models/assistant/message.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/assistant/message.py)
- [backend/app/models/model/model.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/model/model.py)
- [backend/app/models/model/provider.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/model/provider.py)
- [backend/app/models/tool/plugin.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/tool/plugin.py)
- [backend/app/models/retrieval/retrieval.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/retrieval/retrieval.py)
- [backend/app/models/retrieval/collection.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/retrieval/collection.py)
- [backend/app/models/retrieval/record.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/retrieval/record.py)
- [backend/app/models/retrieval/chunk.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/retrieval/chunk.py)
- [backend/app/models/auth/apikey.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/auth/apikey.py)
- [inference/app/models/model_schema.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/models/model_schema.py)
- [inference/app/cache/rerank.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/cache/rerank.py)
- [inference/app/routes/text_embedding/schema.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/routes/text_embedding/schema.py)
- [inference/app/routes/rerank/schema.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/routes/rerank/schema.py)
</details>

# Overview

TaskingAI is an open-source **BaaS (Backend-as-a-Service) platform for LLM-powered agents**, designed to bridge the gap between rapid prototyping in a console and scalable production deployments. It offers a unified API surface for working with multiple model providers, plugins/tools, retrieval-augmented generation (RAG), and persistent conversation state — all packaged as a Docker-deployable, FastAPI-based stack (Source: [README.md](https://github.com/TaskingAI/TaskingAI/blob/main/README.md)).

## Purpose and Scope

The platform's stated goal is to address shortcomings in frameworks like LangChain (stateless, externally coupled) and OpenAI's Assistants API (proprietary, per-assistant coupling of tools/retrievals). TaskingAI solves these by:

- **Supporting both stateful and stateless usage patterns** — persistent chat/assistant sessions coexist with OpenAI-compatible one-shot chat completion endpoints (introduced in v0.3.0).
- **Decoupled modular management** — tools, retrievals, and language models are managed independently of any single assistant, enabling multi-tenant reuse.
- **Unified model abstraction** — providers such as OpenAI, Anthropic, Ollama, LM Studio, and a `custom_host` are all exposed through a common schema.
- **Async-first execution** — built on Python FastAPI for high-concurrency inference and orchestration.

(Source: [README.md](https://github.com/TaskingAI/TaskingAI/blob/main/README.md))

## High-Level Architecture

TaskingAI is composed of several cooperating services. The user-facing entry point is a web console; the backend service manages entities (assistants, chats, models, tools, retrievals, API keys) and orchestrates requests; the inference service runs the actual model calls and exposes OpenAI-compatible chat completion, text embedding, and rerank routes; and a plugin runtime hosts bundled tools (e.g., Google search, web reader, QR code, DALL·E 3 image generation).

```mermaid
flowchart LR
    Client[Client SDK / REST API]
    Console[TaskingAI Console]
    Backend[Backend Service<br/>assistants, chats, models,<br/>tools, retrievals, apikeys]
    Inference[Inference Service<br/>chat_completion,<br/>text_embedding, rerank]
    Providers[(Model Providers<br/>OpenAI, Anthropic,<br/>Ollama, LM Studio)]
    Plugins[Plugin Bundles<br/>search, web reader,<br/>DALL·E 3, QR code]
    Store[(Postgres + Redis +<br/>Object Storage)]

    Client --> Backend
    Console --> Backend
    Backend --> Inference
    Backend --> Store
    Inference --> Providers
    Backend --> Plugins
    Inference --> Plugins
```

The split between `backend/` (entity lifecycle, auth, orchestration) and `inference/` (stateless model invocation) is consistent throughout the codebase. For example, the rerank cache loader dynamically imports provider modules such as `providers.<provider_id>.rerank` and caches instantiated `RerankModel` classes per process (Source: [inference/app/cache/rerank.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/cache/rerank.py)).

## Core Domain Models

The backend is organized around a small set of Pydantic entities, each living under `backend/app/models/`:

| Domain | Entity File | Purpose |
|--------|------------|---------|
| Auth | `auth/apikey.py` | Encrypted API keys with masked display (`apikey[:2] + "*" * … + apikey[-2:]`) for project-level access |
| Model | `model/model.py`, `model/provider.py` | Per-tenant model instance bound to a provider and schema; supports `chat_completion`, `text_embedding`, `rerank` types and a `fallbacks` chain |
| Assistant | `assistant/assistant.py` | Configuration of model, memory, `system_prompt_template`, attached `tools` and `retrievals` |
| Chat | `assistant/chat.py` | Stateful session with its own `memory` and metadata, tied to one assistant |
| Message | `assistant/message.py` | Turn in a chat; carries `role`, text `content`, `num_tokens`, and per-message generation logs |
| Tool/Plugin | `tool/plugin.py` | Bundled functions translated into `ChatCompletionFunction` schemas for the LLM |
| Retrieval | `retrieval/retrieval.py`, `collection.py`, `record.py`, `chunk.py` | RAG primitives — `Retrieval` config, `Collection` (vector store), `Record` (source document), `Chunk` (embedded segment) |

The `Model` entity exposes helper predicates used throughout the orchestrator: `is_chat_completion()`, `is_text_embedding()`, `is_rerank()`, `is_custom_host()` (when `provider_id == "custom_host"`), and capability flags like `allow_function_call()` and `allow_streaming()` derived from `properties` (Source: [backend/app/models/model/model.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/model/model.py)). The `Provider` entity advertises supported `model_types` and a `credentials_schema`, allowing the UI to render appropriate input forms (Source: [backend/app/models/model/provider.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/model/provider.py)).

## Inference Subsystem

The `inference/` service is the stateless worker layer. It exposes three route families, each with strongly typed Pydantic schemas:

- **Chat completion** — primary path used by assistants; delegates to provider implementations registered in `providers/<provider_id>/`.
- **Text embedding** — accepts a string or list of strings, optional `proxy`, `custom_headers` (max 16 pairs, key ≤ 64 chars, value ≤ 512 chars), `credentials`/`encrypted_credentials`, and a `TextEmbeddingModelConfiguration` (Source: [inference/app/routes/text_embedding/schema.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/routes/text_embedding/schema.py)).
- **Rerank** — re-orders candidate documents with a relevance score; same credential/header conventions apply (Source: [inference/app/routes/rerank/schema.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/routes/rerank/schema.py)).

Model schemas are loaded once into memory with pricing metadata and capability flags (`streaming`, `function_call`), driving both the chat completion flow and tool-call validation (Source: [inference/app/models/model_schema.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/models/model_schema.py)). A known sharp edge here is that `custom_host` providers must emit `tool_calls` via the modern `tools` field rather than legacy `functions`; otherwise the model layer rejects the request (community issue #366).

## RAG and Retrieval Pipeline

Retrievals are configured per-assistant with parameters such as `top_k`, `max_tokens`, `score_threshold` (0–1), and a `method` (`user_message`, `function_call`, etc.). The default config is `top_k=3`, `score_threshold=0.6`, `method=USER_MESSAGE` (Source: [backend/app/models/retrieval/retrieval.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/retrieval/retrieval.py)).

A `Collection` is a bounded vector store (with `capacity`, `num_records`, `num_chunks`, an `embedding_model_id`, and an `embedding_size`) that hosts `Record` objects of type `text`, `file`, or `web` (Source: [backend/app/models/retrieval/collection.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/retrieval/collection.py), [backend/app/models/retrieval/record.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/retrieval/record.py)). Each record is split via the token-aware splitter into `Chunk` entities carrying `content`, `num_tokens`, and an optional relevance `score` returned at query time (Source: [backend/app/models/retrieval/chunk.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/retrieval/chunk.py), [backend/app/models/retrieval/text_splitter/token_handler.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/retrieval/text_splitter/token_handler.py)).

## Security, Tooling, and Community Considerations

TaskingAI plugins run as in-process functions; community-reported issues #374 and #375 highlight path-traversal risks in plugins that accept a `project_id` to construct filesystem paths (e.g., DALL·E 3's `save_url_image` and the QR code generator's `save_base64_image`). Any deployment that exposes plugins externally should pin to a patched release and validate `project_id` strictly. Other recurring community themes include:

- **Local/offline deployments** — images pulled for offline use may auto-exit if container network egress is not configured (issue #363).
- **Custom model URLs** — long-standing demand for per-model base URLs (issue #11), partially addressed via the `custom_host` provider and `proxy` parameters.
- **Consumption caching** — request for proxy-side caching to manage token spend (issue #105).
- **Chat-level configuration** — accepting `temperature`/`top_p` at chat creation (issue #360).
- **First-login UX** — POST `/api/v1/admins/login` returning 404 during initial Docker startup (issue #370) is typically a transient readiness race rather than a misconfiguration.

(Source: README.md, community issues #11, #58, #105, #190, #342, #360, #363, #366, #370, #374, #375)

## See Also

- Assistant and Chat lifecycle
- Model providers and the inference route layer
- Retrieval collections, records, and chunks
- Plugin bundles and tool-call integration
- API key authentication and multi-tenant isolation

---

<a id='page-inference-app'></a>

## App

### Related Pages

Related topics: [Overview](#page-overview), [App](#page-plugin-app)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [README.md](https://github.com/TaskingAI/TaskingAI/blob/main/README.md)
- [inference/app/models/__init__.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/models/__init__.py)
- [inference/app/models/provider.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/models/provider.py)
- [inference/app/cache/rerank.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/cache/rerank.py)
- [inference/app/routes/text_embedding/schema.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/routes/text_embedding/schema.py)
- [inference/app/routes/rerank/schema.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/routes/rerank/schema.py)
- [backend/app/models/model/model.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/model/model.py)
- [backend/app/models/model/provider.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/model/provider.py)
- [backend/app/models/assistant/assistant.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/assistant/assistant.py)
- [backend/app/models/assistant/chat.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/assistant/chat.py)
- [backend/app/models/assistant/message.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/assistant/message.py)
- [backend/app/models/retrieval/collection.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/retrieval/collection.py)
- [backend/app/models/retrieval/record.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/retrieval/record.py)
- [backend/app/models/retrieval/chunk.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/retrieval/chunk.py)
- [backend/app/models/retrieval/text_splitter/token_handler.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/retrieval/text_splitter/token_handler.py)
- [backend/app/models/tool/plugin.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/tool/plugin.py)
- [backend/app/models/auth/apikey.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/auth/apikey.py)
</details>

# App

## Overview

TaskingAI is organized as two cooperating Python services that together form the "App" layer of the platform: a **backend app** that owns state, metadata, agents, and the retrieval/RAG subsystem, and an **inference app** that provides a thin, provider-agnostic façade for calling LLMs, embedding models, and rerankers. This separation lets the backend stay focused on orchestration and persistence while the inference tier absorbs all provider-specific complexity. According to the [README.md](https://github.com/TaskingAI/TaskingAI/blob/main/README.md), the project is an "All-In-One LLM Platform" delivered as a Docker-deployable BaaS, and the dual-app layout reflects its "BaaS-Inspired Workflow" of separating AI logic from product development.

The inference app exposes three primary inference surfaces — chat completion, text embedding, and rerank — and dynamically loads provider implementations from a directory layout. The backend app exposes the higher-level abstractions (assistants, chats, messages, tools, retrievals, collections, records, chunks, models, providers, and API keys) that user-facing clients manipulate through RESTful APIs.

## Architecture and Module Layout

The two apps are loosely coupled: the backend persists configuration and delegates actual model calls to the inference tier. Within the inference tier, the package `inference.app.models` re-exports the public schema types used by route handlers, as declared in [inference/app/models/__init__.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/models/__init__.py), which exposes `base`, `model_schema`, `provider`, `provider_credentials`, `chat_completion`, `text_embedding`, `tokenizer`, and `model_config`.

```mermaid
flowchart LR
    Client[Client SDK / Console] --> Backend[backend/app]
    Backend -- delegate inference --> Inference[inference/app]
    Inference --> Providers[Provider Modules<br/>OpenAI, Anthropic, Ollama, LM Studio, Custom Host]
    Backend --> DB[(Postgres + Redis)]
    Backend --> Storage[(Object Storage<br/>Files / Images)]
```

### Backend App Domain Modules

The backend models under `backend/app/models/` form the persistence layer for every user-visible resource. Each module is a Pydantic `ModelEntity` that knows how to `build()` from a database row and how to serialize to a response dict.

- **Assistant module** — defines the `Assistant` entity in [assistant.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/assistant/assistant.py), which references a `model_id`, a `system_prompt_template`, an `AssistantMemory` block, a list of `ToolRef`, and a list of `RetrievalRef` with `retrieval_configs`. The assistant is the top-level agent object users create and configure.
- **Chat and Message modules** — `Chat` (see [chat.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/assistant/chat.py)) represents a conversation session bound to an assistant, including its `ChatMemory`. `Message` (see [message.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/assistant/message.py)) models individual turns with `MessageRole` (`user`/`assistant`), text `MessageContent`, and an optional `MessageGenerationLog` for diagnostics.
- **Retrieval module** — three coordinated entities implement RAG: `Collection` ([collection.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/retrieval/collection.py)) which holds capacity and embedding configuration; `Record` ([record.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/retrieval/record.py)) which represents a logical source document of type `text`, `file`, or `web`; and `Chunk` ([chunk.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/retrieval/chunk.py)) which is the unit of retrieval. Text is split into chunks by `split_text_by_token` in [token_handler.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/retrieval/text_splitter/token_handler.py), with `chunk_size` and `chunk_overlap` parameters and a title prefix.
- **Model and Provider modules** — `Model` ([model.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/model/model.py)) captures a configured model instance with `model_schema_id`, `provider_id`, `provider_model_id`, `properties`, `configs`, and encrypted credentials. Helper methods expose `is_chat_completion()`, `is_text_embedding()`, `is_rerank()`, `is_custom_host()`, `allow_function_call()`, and `allow_streaming()`. `Provider` ([provider.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/model/provider.py)) describes the upstream vendor and its `credentials_schema`.
- **Plugin module** — `Plugin` (see [plugin.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/tool/plugin.py)) provides a converter that flattens a plugin's input schema into a `ChatCompletionFunction` for LLM tool use, including internationalization of descriptions.
- **Auth module** — `Apikey` ([apikey.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/auth/apikey.py)) stores both the encrypted and decrypted form of the API key, returning only a masked version (first two and last two characters) to API consumers.

### Inference App Surfaces

The inference app's request schemas, illustrated by [text_embedding/schema.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/routes/text_embedding/schema.py) and [rerank/schema.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/routes/rerank/schema.py), share a common shape: an optional `proxy`, an optional `custom_headers` map (capped at 16 entries with per-key and per-value length limits), a `credentials` dict or its encrypted twin, plus a `configs` block and a model-specific payload. The `Provider` model in [inference/app/models/provider.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/models/provider.py) carries booleans such as `enable_proxy`, `enable_custom_headers`, `return_token_usage`, and `return_stream_token_usage`, which the routes consult when constructing provider requests.

The provider implementations are discovered at startup. As shown in [cache/rerank.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/cache/rerank.py), `load_all_rerank_models` walks `providers/` and imports each vendor's `rerank.py`, instantiating one cached provider object per `provider_id`. The same pattern applies to chat completion and text embedding caches, which is why the inference app can add new providers without touching route code.

## Common Configuration and Failure Modes

Several cross-cutting parameters recur across modules and are worth knowing when troubleshooting:

| Parameter | Where it appears | Effect |
|---|---|---|
| `proxy` | inference request schemas | Outbound HTTP proxy for the provider call |
| `custom_headers` | inference request schemas | Up to 16 headers with bounded key/value lengths |
| `credentials` / `encrypted_credentials` | inference schemas, `Model.encrypted_credentials`, `Apikey.encrypted_apikey` | Either plaintext (transient) or AES-encrypted at rest |
| `fallbacks` | `Model.fallbacks` | Ordered list of `ModelFallback` model IDs for retry |

Common failure modes reported by the community tie directly to these surfaces:

- **Custom-host tool-use incompatibility** — issue #366 reports that pairing a `custom_host` model with a tool (e.g., `arxiv_search`) produces `Invalid parameter: 'tool_calls' cannot be used when 'functions' are present`. This is driven by the `allow_function_call()` check in [model.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/model/model.py), which requires the provider to expose `function_call` semantics.
- **Path-traversal in plugin image savers** — issues #374 and #375 describe vulnerabilities in plugins that write images to disk using unvalidated `project_id` parameters, which sit inside the `Plugin` tool execution path of [plugin.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/tool/plugin.py).
- **Per-chat configuration** — issue #360 requests that the `Chat.create` call accept a `configs` parameter; today the only per-message configuration hooks live in `Model.configs` and the inference `configs` block.
- **Local-model provider docs** — issue #58 highlights confusion around LM Studio and Ollama integration, which the inference cache loader handles via the dynamic `providers/` discovery pattern.

## See Also

- [README.md](https://github.com/TaskingAI/TaskingAI/blob/main/README.md) — platform overview and deployment notes
- v0.3.0 release notes — introduces an OpenAI-compatible chat completion API and playground upgrades
- [inference/app/cache/rerank.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/cache/rerank.py) — provider discovery pattern for rerank models
- [backend/app/models/retrieval/text_splitter/token_handler.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/retrieval/text_splitter/token_handler.py) — token-aware chunking used by RAG

---

<a id='page-plugin-app'></a>

## App

### Related Pages

Related topics: [App](#page-inference-app), [Models](#page-backend-app-models)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [README.md](https://github.com/TaskingAI/TaskingAI/blob/main/README.md)
- [backend/app/models/assistant/assistant.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/assistant/assistant.py)
- [backend/app/models/assistant/chat.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/assistant/chat.py)
- [backend/app/models/assistant/message.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/assistant/message.py)
- [backend/app/models/auth/apikey.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/auth/apikey.py)
- [backend/app/models/model/model.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/model/model.py)
- [backend/app/models/model/provider.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/model/provider.py)
- [backend/app/models/retrieval/chunk.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/retrieval/chunk.py)
- [backend/app/models/retrieval/collection.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/retrieval/collection.py)
- [backend/app/models/retrieval/record.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/retrieval/record.py)
- [backend/app/models/retrieval/text_splitter/token_handler.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/retrieval/text_splitter/token_handler.py)
- [backend/app/models/tool/plugin.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/tool/plugin.py)
- [inference/app/routes/text_embedding/schema.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/routes/text_embedding/schema.py)
- [inference/app/routes/rerank/schema.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/routes/rerank/schema.py)
- [inference/app/cache/rerank.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/cache/rerank.py)
- [inference/app/models/provider.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/models/provider.py)
- [inference/app/models/__init__.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/models/__init__.py)
</details>

# App

## Overview

TaskingAI is delivered as a Docker-deployable, BaaS-style platform whose code is organized into three independently deployed Python services, each rooted at its own `app/` package. The platform is presented in the README as "an all-in-one LLM platform" that exposes unified REST APIs to "hundreds of AI models," a RAG subsystem, assistants, tools/plugins, and a console. The split between services is intentional: the `backend/app` service owns business entities and state, the `inference/app` service owns model invocation against providers, and the `plugin/app` service owns tool/plugin execution. This page covers the shared structure of those `app/` packages and the core domain models that flow through them.

Source: [README.md:1-50]()

```mermaid
flowchart LR
    Client[Client SDK / Console] -->|REST| Backend[backend/app]
    Backend -->|HTTP| Inference[inference/app]
    Backend -->|HTTP| Plugin[plugin/app]
    Inference -->|HTTPS| Providers[(OpenAI, Anthropic, Cohere, ...)]
    Plugin -->|HTTPS| External[External APIs: Google, etc.]
    Backend --> PG[(Postgres)]
    Backend --> Redis[(Redis)]
    Backend --> Minio[(Object Storage)]
```

## Backend App — Domain Model Layer

The `backend/app/models/` package is the canonical source of truth for TaskingAI's domain entities. Every entity extends the `ModelEntity` base class from `tkhelper.models` and implements a `build(row)` constructor plus an `object_name()` / `table_name()` for persistence. The most central entity is the `Assistant`, which composes a model reference, a memory configuration, a list of `ToolRef` objects, a list of `RetrievalRef` objects, and a `system_prompt_template` list:

```python
class Assistant(ModelEntity):
    object: str = "Assistant"
    assistant_id: str = id_field("assistant", length_range=(1, 50))
    model_id: str = id_field("model", length=8)
    system_prompt_template: List[str] = Field([])
    memory: AssistantMemory = Field(...)
    tools: List[ToolRef] = Field([])
    retrievals: List[RetrievalRef] = Field([])
    retrieval_configs: RetrievalConfig = Field(...)
```

Source: [backend/app/models/assistant/assistant.py:13-34]()

An Assistant drives `Chat` sessions, where each `Chat` is identified by a 24-character `chat_id` bound to a parent `assistant_id`. The `Chat` model also persists a `ChatMemory` object that the backend rewrites on every turn to implement zero/short-term memory strategies.

Source: [backend/app/models/assistant/chat.py:12-46]()

Each turn inside a chat is stored as a `Message`. Messages carry a `role` (user/assistant), a typed `MessageContent` payload (currently text-only), a `num_tokens` counter for billing, and a per-session `MessageGenerationLog` record. The log object — with fields `session_id`, `event`, `event_id`, `event_step`, `timestamp`, and a `content` dictionary — is what the Playground UI subscribes to in order to render the step-by-step generation trace.

Source: [backend/app/models/assistant/message.py:21-72]()

### Model, Provider, and Credential Storage

A `Model` in the backend is a user-provisioned binding between a provider (`provider_id`), a specific upstream `provider_model_id`, an encrypted credentials blob (`encrypted_credentials`), a `display_credentials` mask, and a list of fallback models. The `Model` exposes convenience predicates such as `is_chat_completion()`, `is_text_embedding()`, `is_rerank()`, and `is_custom_host()` — the last one gates the path taken in the inference service (see [Issue #366](https://github.com/TaskingAI/TaskingAI/issues/366) where a `custom_host` provider was rejecting requests because it expected `tools` rather than `functions`).

Source: [backend/app/models/model/model.py:14-65]()

The `Provider` model carries the catalog metadata (icon, name, model-type list, `credentials_schema`) and a `has_model_type()` helper. This is the object the console uses to render the "Add Provider" form and to validate user-supplied credentials against a JSON schema before encrypting them.

Source: [backend/app/models/model/provider.py:6-56]()

API keys for the console itself are stored via the `Apikey` model. The build step decrypts the stored value with `tkhelper.encryption.aes.aes_decrypt` and the `to_response_dict()` method masks all but the first and last two characters (`sk****fk`) so the secret is never echoed in full over the wire.

Source: [backend/app/models/auth/apikey.py:6-34]()

### Retrieval: Collection, Record, Chunk

The retrieval subsystem is built around a three-level hierarchy:

| Level | Entity | Purpose | Key Fields |
| --- | --- | --- | --- |
| L1 | `Collection` | A vector-indexed container bound to one embedding model | `collection_id`, `embedding_model_id`, `embedding_size`, `capacity`, `status` |
| L2 | `Record` | A source document (text, file, or web URL) | `record_id`, `type` (`TEXT`/`FILE`/`WEB`), `content`, `num_chunks`, `status` |
| L3 | `Chunk` | An embedding-stored fragment returned at query time | `chunk_id`, `record_id`, `content`, `num_tokens`, `score` |

A `Collection` tracks its current `num_chunks` versus `capacity` and exposes `has_available_capacity()` and `rest_capacity()` helpers used to reject oversized uploads before they reach Postgres. Each collection owns a per-collection chunk table named via `Collection.get_chunk_table_name(collection_id)`, which is how the backend isolates vector storage per tenant.

Source: [backend/app/models/retrieval/collection.py:12-58]()

A `Record` accepts three ingestion types — `TEXT`, `FILE`, and `WEB` — and `file_id()` / `url()` helpers parse the JSON `content` field to recover the underlying object-storage or web reference.

Source: [backend/app/models/retrieval/record.py:14-44]()

`Chunk` records carry an optional `score` field that is populated only at query time by the rerank/embedding pipeline, and the model supports a `to_response_dict()` serialization for API responses.

Source: [backend/app/models/retrieval/chunk.py:10-38]()

Text is split into chunks by `split_text_by_token()`, which uses a `default_tokenizer` to encode the document, computes the number of chunks `K = ceil((size - overlap) / (chunk_size - overlap))`, and balances the per-chunk token counts so the chunks are as close to the requested `chunk_size` as possible. A title, when supplied, is prepended to each chunk.

Source: [backend/app/models/retrieval/text_splitter/token_handler.py:9-50]()

### Tool / Plugin Definitions

Plugins are defined declaratively in bundles. The `Plugin` Pydantic model holds `bundle_id`, `plugin_id`, `name`, `description`, an `input_schema`, and an `output_schema` (both `Dict[str, ParameterSchema]`). A helper function `convert_plugin_to_function` walks the input schema, keeps only `type`, `enum`, and `description` per parameter, resolves i18n strings via `i18n_text(bundle_id, value["description"], "en")`, and emits a `ChatCompletionFunction` object. This is the bridge that turns a plugin definition into something the chat-completion model can call as a tool.

Source: [backend/app/models/tool/plugin.py:6-44]()

## Inference App — Provider Execution Layer

The `inference/app` service is a thin FastAPI wrapper that takes a request, looks up (or instantiates) a provider-specific model class, forwards the call to the upstream API, and returns a normalized response. Provider modules are discovered dynamically — for rerank models, `inference/app/cache/rerank.py` derives the class name from the `provider_id` (`provider_id="cohere"` → `CohereRerankModel`) and `importlib.import_module(f"providers.{provider_id}.rerank")` resolves it. `load_all_rerank_models()` walks the `providers/` directory at startup and instantiates a singleton for every provider that ships a `rerank.py` file.

Source: [inference/app/cache/rerank.py:8-44]()

The inference service accepts proxy, custom-headers, and either plaintext or encrypted credentials on every request. For example, the text-embedding schema exposes `proxy` (an HTTP proxy string), `custom_headers` (a dict capped at 16 entries, each key ≤ 64 chars and each value ≤ 512 chars), and both `credentials` and `encrypted_credentials` — the latter for cases where the caller has already encrypted the secret with the platform key.

Source: [inference/app/routes/text_embedding/schema.py:6-44]()

The same shape is mirrored by the rerank route's `RerankRequest`, which returns a `RerankResponse` containing a list of `{index, document, relevance_score}` records ranked from highest to lowest score.

Source: [inference/app/routes/rerank/schema.py:6-60]()

The `inference/app/models` package re-exports the cross-cutting types — `base`, `model_schema`, `provider`, `provider_credentials`, `chat_completion`, `text_embedding`, `tokenizer`, and `model_config` — so the routes only need a single import to reach all of them. The `Provider` model in the inference service is a stricter cousin of the backend's `Provider`, adding booleans such as `enable_proxy`, `enable_custom_headers`, `return_token_usage`, and `return_stream_token_usage` that the backend can poll to decide whether to surface proxy/header fields in its own API.

Source: [inference/app/models/__init__.py:1-8](), [inference/app/models/provider.py:8-58]()

## Community-Considered Concerns

Several community-reported issues map directly to these `app/` modules. Path-traversal reports ([#375](https://github.com/TaskingAI/TaskingAI/issues/375) for the DALL-E 3 plugin and [#374](https://github.com/TaskingAI/TaskingAI/issues/374) for the QR Code plugin) all originate in plugin code under `plugin/app/`, where `save_url_image` and `save_base64_image` accept a `project_id` that is concatenated into a filesystem path without sanitization — a reminder that any new file-writing plugin must validate IDs against `^[A-Za-z0-9_-]+$` before joining them with a base directory. Tool-use errors against `custom_host` providers ([#366](https://github.com/TaskingAI/TaskingAI/issues/366)) trace back to the `Model.is_custom_host()` branch in [backend/app/models/model/model.py]() choosing the `tools=` payload shape, which a local LLM server (e.g. LM Studio, the subject of [Issue #58](https://github.com/TaskingAI/TaskingAI/issues/58)) may not yet support. The Docker first-login 404 reported in [#370](https://github.com/TaskingAI/TaskingAI/issues/370) points to the `POST /api/v1/admins/login` route registration, which lives in the `backend/app` HTTP layer rather than the domain models.

## See Also

- [Models](https://github.com/TaskingAI/TaskingAI) — provider and model schema reference
- [Retrieval / RAG](https://github.com/TaskingAI/TaskingAI) — collection, record, and chunk lifecycle
- [Assistants & Chats](https://github.com/TaskingAI/TaskingAI) — assistant, chat, and message model
- [Plugins](https://github.com/TaskingAI/TaskingAI) — plugin bundle and tool-call conversion
- [Release Notes v0.3.0](https://github.com/TaskingAI/TaskingAI/releases/tag/v0.3.0) — Playground markdown rendering and the OpenAI-compatible chat completion API

---

<a id='page-backend-app-models'></a>

## Models

### Related Pages

Related topics: [App](#page-plugin-app)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [backend/app/models/model/model.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/model/model.py)
- [backend/app/models/model/provider.py](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/model/provider.py)
- [inference/app/models/model_schema.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/models/model_schema.py)
- [inference/app/models/provider.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/models/provider.py)
- [inference/app/models/__init__.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/models/__init__.py)
- [inference/app/cache/rerank.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/cache/rerank.py)
- [inference/app/routes/text_embedding/schema.py](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/routes/text_embedding/schema.py)
- [inference/app/models/model_config/resources/i18n/en.yml](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/models/model_config/resources/i18n/en.yml)
- [README.md](https://github.com/TaskingAI/TaskingAI/blob/main/README.md)
</details>

# Models

## Overview

In TaskingAI, a **Model** is the concrete, user-created instance of an AI model that the platform routes inference calls to. While the README frames the platform as providing "access to hundreds of AI models with unified APIs" (`README.md:1-50`), the runtime Model object is the bridge between an abstract model schema and a real provider such as OpenAI, Anthropic, Ollama, or a self-hosted endpoint.

The Models subsystem spans two services: the **backend** (`backend/app/models/model/`), which stores, persists, and exposes Model, Provider, and ModelSchema entities; and the **inference** layer (`inference/app/models/`), which executes the actual calls using a per-provider module hierarchy and cached model classes. Source: [backend/app/models/model/model.py:1-15](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/model/model.py).

## Model Entity and Core Properties

The `Model` entity is the user-facing record. Its fields describe both identity and execution metadata:

| Field | Purpose |
| --- | --- |
| `model_id` | Unique identifier of the created model instance. |
| `model_schema_id` | Pointer to a published schema describing supported properties. |
| `provider_id` / `provider_model_id` | Which provider supplies the model and which upstream model to call. |
| `name`, `type` | Display name and the model kind (`chat_completion`, `text_embedding`, `rerank`). |
| `properties`, `configs` | Vendor-specific properties and unified inference configurations. |
| `encrypted_credentials` / `display_credentials` | Secrets are encrypted at rest; the display form is masked. |
| `fallbacks` | Optional list of fallback models for resilience. |

Source: [backend/app/models/model/model.py:1-50](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/model/model.py).

`Model` extends the shared `ModelEntity` and exposes helper methods used throughout the backend. `is_chat_completion`, `is_text_embedding`, and `is_rerank` discriminate by the `type` field. `is_custom_host` returns `True` when `provider_id == "custom_host"`, which is how TaskingAI flags user-defined endpoints that bring their own URL and credentials. Source: [backend/app/models/model/model.py:30-50](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/model/model.py).

Capability flags such as `allow_function_call` and `allow_streaming` are derived from `properties`, ensuring the chat-completion path only enables tool/function calls and streaming when the underlying schema advertises support. Source: [backend/app/models/model/model.py:45-55](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/model/model.py).

## Model Types, Providers, and Schema Resolution

The supported `ModelType` values are listed in `inference/app/models/__init__.py`, which re-exports `base`, `model_schema`, `provider`, `chat_completion`, `text_embedding`, `tokenizer`, and `model_config`. A model whose schema type is `WILDCARD` must be refined by the caller-supplied `model_type`, otherwise the inference layer raises `REQUEST_VALIDATION_ERROR`. Source: [inference/app/models/model_schema.py:1-60](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/models/model_schema.py).

The `Provider` object describes an upstream vendor — its `provider_id`, `name`, `credentials_schema`, `icon_svg_url`, and a `model_types` list. `Provider.has_model_type()` accepts either a concrete type or the wildcard, so a single provider entry can expose chat completion, embeddings, and rerank models under the same identifier. Source: [backend/app/models/model/provider.py:1-55](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/model/provider.py).

In the inference service, providers are loaded lazily. `inference/app/cache/rerank.py` demonstrates the pattern: it converts a snake_case `provider_id` (e.g., `cohere`) into a PascalCase class name (`CohereRerankModel`), imports `providers.<provider_id>.rerank`, and instantiates and caches the class on first use. `load_all_rerank_models` walks the `providers/` directory at startup to register every provider that ships a `rerank.py` module. Source: [inference/app/cache/rerank.py:1-55](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/cache/rerank.py).

The inference-layer `Provider` extends the backend concept with execution toggles such as `enable_proxy`, `enable_custom_headers`, `return_token_usage`, `return_stream_token_usage`, and `pass_provider_level_credential_check`. Source: [inference/app/models/provider.py:1-60](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/models/provider.py).

## Configuration, Credentials, and Request Options

Model configuration is presented uniformly regardless of provider. The i18n file lists the canonical fields: `max_tokens`, `stop`, `temperature`, `top_k`, `top_p`, `frequency_penalty`, and `presence_penalty` — each with a `name` and `description` string shown in the console and Playground. Source: [inference/app/models/model_config/resources/i18n/en.yml:1-30](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/models/model_config/resources/i18n/en.yml).

Per-request overrides are accepted on the text embedding route, mirroring the chat completion endpoint. The `TextEmbeddingRequest` schema accepts `proxy` (optional HTTP proxy string), `custom_headers` (up to 16 key-value pairs), `credentials` or `encrypted_credentials` (mutually exclusive), `properties` (provider-specific overrides), `configs` (a `TextEmbeddingModelConfiguration` object), and an `input_type` discriminator (`document` or `query`). Source: [inference/app/routes/text_embedding/schema.py:1-80](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/routes/text_embedding/schema.py).

Credentials are stored encrypted on the `Model` row; the display form returned to the console is masked. API keys are likewise decrypted only when needed via `aes_decrypt` on the backend, as shown in `Apikey.build`. Source: [backend/app/models/auth/apikey.py:1-40](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/auth/apikey.py).

## Fallbacks, Function Calls, and Community Considerations

### Fallback chains

`ModelFallbackConfig` wraps a `model_list` of `ModelFallback` entries (`model_id` only). This lets the inference service degrade gracefully when a primary model fails — a recurring community ask for production reliability. Source: [backend/app/models/model/model.py:1-25](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/model/model.py).

### Custom host and function calling

The `is_custom_host` flag combined with `allow_function_call` is significant. Community issue [#366](https://github.com/TaskingAI/TaskingAI/issues/366) reports that some custom-host providers reject requests when both `tool_calls` (the OpenAI `tools` parameter) and `functions` (legacy) are present. Because `allow_function_call` is derived from schema `properties`, operators must ensure the underlying schema advertises function-call support and that the request payload uses the modern `tools` field. Source: [backend/app/models/model/model.py:30-55](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/model/model.py).

### Custom model URLs and local providers

Community issue [#11](https://github.com/TaskingAI/TaskingAI/issues/11) requests the ability to define a custom model URL for OpenAI models. This maps to TaskingAI's `custom_host` provider: a Model whose `provider_id == "custom_host"` accepts arbitrary `provider_model_id` strings and per-model credentials, which is the mechanism used to integrate LM Studio and Ollama endpoints. Issue [#58](https://github.com/TaskingAI/TaskingAI/issues/58) further highlights that local-server + Dockerized TaskingAI is the common deployment pattern for these providers. Source: [backend/app/models/model/model.py:30-50](https://github.com/TaskingAI/TaskingAI/blob/main/backend/app/models/model/model.py).

### Proxy, custom headers, and token usage

Issue [#105](https://github.com/TaskingAI/TaskingAI/issues/105) requests proxy integration for token consumption and caching. The inference `Provider` already exposes `enable_proxy` and `enable_custom_headers`, and the text embedding schema accepts `proxy` and `custom_headers` per request — meaning today the feature is wired in but operated at the request level rather than centrally cached. Source: [inference/app/models/provider.py:1-60](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/models/provider.py), [inference/app/routes/text_embedding/schema.py:1-80](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/routes/text_embedding/schema.py).

### Per-Chat model configuration

Issue [#360](https://github.com/TaskingAI/TaskingAI/issues/360) requests per-Chat overrides for `temperature`, `top_p`, etc. The unified `configs` field on `Model` and the `TextEmbeddingModelConfiguration` object already standardize these parameters, so the work is largely on exposing them at Chat creation time. The v0.2.2 release notes confirm that model configuration updates are supported on the Model itself. Source: [inference/app/models/model_config/resources/i18n/en.yml:1-30](https://github.com/TaskingAI/TaskingAI/blob/main/inference/app/models/model_config/resources/i18n/en.yml).

## See Also

- [TaskingAI README](https://github.com/TaskingAI/TaskingAI/blob/main/README.md)
- Plugin and tool action schema — `backend/app/models/tool/plugin.py`
- Assistant memory configuration — `backend/app/models/assistant/assistant.py`
- RAG collection and chunk schema — `backend/app/models/retrieval/collection.py`

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Pitfall Log

Project: TaskingAI/TaskingAI

Summary: Found 15 structured pitfall item(s), including 1 high/blocking item(s). Top priority: Security or permission risk - Security or permission risk requires verification.

## 1. Security or permission risk - Security or permission risk requires verification

- Severity: high
- Evidence strength: source_linked
- Finding: Project evidence flags a security or permission risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/TaskingAI/TaskingAI/issues/105

## 2. Installation risk - Installation risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/TaskingAI/TaskingAI/issues/370

## 3. Installation risk - Installation risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/TaskingAI/TaskingAI/issues/372

## 4. Installation risk - Installation risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/TaskingAI/TaskingAI/issues/363

## 5. Configuration risk - Configuration risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a configuration risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/TaskingAI/TaskingAI/issues/360

## 6. Capability evidence risk - Capability evidence risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: README/documentation is current enough for a first validation pass.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.assumptions | https://github.com/TaskingAI/TaskingAI

## 7. Runtime risk - Runtime risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a runtime risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/TaskingAI/TaskingAI/issues/365

## 8. Runtime risk - Runtime risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a runtime risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/TaskingAI/TaskingAI/issues/366

## 9. Maintenance risk - Maintenance risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/TaskingAI/TaskingAI

## 10. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: downstream_validation.risk_items | https://github.com/TaskingAI/TaskingAI

## 11. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: risks.scoring_risks | https://github.com/TaskingAI/TaskingAI

## 12. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a security or permission risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/TaskingAI/TaskingAI/issues/375

## 13. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a security or permission risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/TaskingAI/TaskingAI/issues/374

## 14. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: issue_or_pr_quality=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/TaskingAI/TaskingAI

## 15. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: release_recency=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/TaskingAI/TaskingAI

<!-- canonical_name: TaskingAI/TaskingAI; human_manual_source: deepwiki_human_wiki -->
