Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ LICENSE_KEY=
ASK_USER=

## LLM Providers
## aimlapi.com LLM provider (aggregator, OpenAI-compatible)
AIMLAPI_API_KEY=
AIMLAPI_SERVER_URL=https://api.aimlapi.com/v1
AIMLAPI_PROVIDER=

OPEN_AI_KEY=
OPEN_AI_SERVER_URL=https://api.openai.com/v1

Expand Down
2 changes: 2 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
// "-type", "kimi",
// "-type", "qwen",
// "-type", "minimax",
// "-type", "aimlapi",
"-config", "${workspaceFolder}/examples/configs/moonshot.provider.yml",
// "-config", "${workspaceFolder}/examples/configs/deepseek.provider.yml",
// "-config", "${workspaceFolder}/examples/configs/ollama-cloud.provider.yml",
Expand Down Expand Up @@ -103,6 +104,7 @@
// "-report", "${workspaceFolder}/examples/tests/kimi-report.md",
// "-report", "${workspaceFolder}/examples/tests/qwen-report.md",
// "-report", "${workspaceFolder}/examples/tests/minimax-report.md",
// "-report", "${workspaceFolder}/examples/tests/aimlapi-report.md",
// "-report", "${workspaceFolder}/examples/tests/hcnsec-report.md",
// "-report", "${workspaceFolder}/examples/tests/custom-openai-report.md",
// "-report", "${workspaceFolder}/examples/tests/opencode-report.md",
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ State is managed primarily through Apollo Client (GraphQL) with real-time update

### Key Integrations

- **LLM Providers**: OpenAI, Anthropic, Gemini, AWS Bedrock, Ollama, DeepSeek, GLM, Kimi, Qwen, and custom HTTP endpoints — configured via environment variables or the Settings UI
- **LLM Providers**: aimlapi.com, OpenAI, Anthropic, Gemini, AWS Bedrock, Ollama, DeepSeek, GLM, Kimi, Qwen, MiniMax, and custom HTTP endpoints — configured via environment variables or the Settings UI
- **Search**: DuckDuckGo, Google, Tavily, Firecrawl, Traversaal, Perplexity, Searxng
- **Databases**: PostgreSQL + pgvector (required), Neo4j (optional, for knowledge graph)
- **Observability**: OpenTelemetry → VictoriaMetrics + Loki + Jaeger → Grafana; Langfuse for LLM analytics
Expand Down
52 changes: 50 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
- [How to Use PentAGI After Login](#how-to-use-pentagi-after-login)
- [API Access](#api-access)
- [LLM Provider Configuration](#custom-llm-provider-configuration)
- [aimlapi.com](#aimlapicom-provider-configuration)
- [Ollama](#ollama-provider-configuration)
- [OpenAI](#openai-provider-configuration)
- [Anthropic](#anthropic-provider-configuration)
Expand Down Expand Up @@ -75,7 +76,7 @@ You can watch the video **PentAGI overview**:
- Persistent Storage. All commands and outputs are stored in PostgreSQL with [pgvector](https://hub.docker.com/r/vxcontrol/pgvector) extension.
- Scalable Architecture. Microservices-based design supporting horizontal scaling.
- Self-Hosted Solution. Complete control over your deployment and data.
- Flexible Authentication. Support for 10+ LLM providers ([OpenAI](https://platform.openai.com/), [Anthropic](https://www.anthropic.com/), [Google AI/Gemini](https://ai.google.dev/), [AWS Bedrock](https://aws.amazon.com/bedrock/), [Ollama](https://ollama.com/), [DeepSeek](https://www.deepseek.com/en/), [GLM](https://z.ai/), [Kimi](https://platform.moonshot.ai/), [Qwen](https://www.alibabacloud.com/en/), [MiniMax](https://www.minimax.io/), Custom) plus aggregators ([OpenRouter](https://openrouter.ai/), [DeepInfra](https://deepinfra.com/), [Atlas Cloud](https://www.atlascloud.ai/), [OpenCode Go plan](https://opencode.ai/en/go)). For production local deployments, see our [vLLM + Qwen3.5-27B-FP8 guide](examples/guides/vllm-qwen35-27b-fp8.md).
- Flexible Authentication. Support for 10+ LLM providers ([OpenAI](https://platform.openai.com/), [Anthropic](https://www.anthropic.com/), [Google AI/Gemini](https://ai.google.dev/), [AWS Bedrock](https://aws.amazon.com/bedrock/), [Ollama](https://ollama.com/), [DeepSeek](https://www.deepseek.com/en/), [GLM](https://z.ai/), [Kimi](https://platform.moonshot.ai/), [Qwen](https://www.alibabacloud.com/en/), [MiniMax](https://www.minimax.io/), Custom) plus aggregators ([aimlapi.com](https://aimlapi.com/), [OpenRouter](https://openrouter.ai/), [DeepInfra](https://deepinfra.com/), [Atlas Cloud](https://www.atlascloud.ai/), [OpenCode Go plan](https://opencode.ai/en/go)). For production local deployments, see our [vLLM + Qwen3.5-27B-FP8 guide](examples/guides/vllm-qwen35-27b-fp8.md).
- API Token Authentication. Secure Bearer token system for programmatic access to REST and GraphQL APIs.
- Quick Deployment. Easy setup through [Docker Compose](https://docs.docker.com/compose/) with comprehensive environment configuration.

Expand Down Expand Up @@ -766,6 +767,9 @@ BEDROCK_DEFAULT_AUTH=true # Option 1: Use AWS SDK default
# QWEN_API_KEY=your_qwen_key # Qwen (Alibaba Cloud, multimodal)
# MINIMAX_API_KEY=your_minimax_key # MiniMax

# Optional: aggregators (one key, many vendors)
# AIMLAPI_API_KEY=your_aimlapi_key # aimlapi.com (350+ chat models)

# Optional: Local LLM provider (zero-cost inference)
OLLAMA_SERVER_URL=http://localhost:11434
OLLAMA_SERVER_MODEL=your_model_name
Expand Down Expand Up @@ -1475,6 +1479,50 @@ How to investigate:
3. Confirm the backend's tool-call parser and chat template are the ones recommended for the model you are serving, and that the model itself supports tool calling.
4. Update PentAGI to the latest build. Recent versions sanitize malformed function-call arguments returned by the model so a single bad response no longer stalls the whole flow; older builds forwarded the corrupted arguments and could get stuck.

### aimlapi.com Provider Configuration

[aimlapi.com](https://aimlapi.com/) is an aggregator: one OpenAI-compatible endpoint at `https://api.aimlapi.com/v1` and one key in front of 350+ chat models from many vendors, with tool calling, structured output, streaming and reasoning support.

Requests PentAGI sends to `api.aimlapi.com` carry `HTTP-Referer`, `X-Title`, `X-AIMLAPI-Source` and `X-AIMLAPI-Partner-ID` identifying PentAGI as the calling application. The headers are scoped to that host, so pointing `AIMLAPI_SERVER_URL` at a proxy or a self-hosted gateway disables them rather than tagging someone else's traffic.

#### Configuration Variables

| Variable | Default Value | Description |
| -------------------- | ---------------------------- | -------------------------------------------------- |
| `AIMLAPI_API_KEY` | | aimlapi.com API key for authentication |
| `AIMLAPI_SERVER_URL` | `https://api.aimlapi.com/v1` | aimlapi.com API endpoint URL |
| `AIMLAPI_PROVIDER` | | Provider prefix for LiteLLM integration (optional) |

#### Configuration Examples

```bash
# Direct API usage
AIMLAPI_API_KEY=your_aimlapi_api_key
AIMLAPI_SERVER_URL=https://api.aimlapi.com/v1

# With LiteLLM proxy
AIMLAPI_API_KEY=your_litellm_key
AIMLAPI_SERVER_URL=http://litellm-proxy:4000
AIMLAPI_PROVIDER=aimlapi # Adds prefix to model names for LiteLLM
```

#### Supported Models

PentAGI ships 6 aimlapi.com models across the 13 agent roles. Model ids are vendor-namespaced and are sent verbatim; the gateway also accepts short aliases, but an alias can resolve to a different model than its name suggests, so only canonical ids are used. Prices are USD per 1M tokens as published by `GET https://api.aimlapi.com/v1/models?include=all` on 2026-09-03.

| Model ID | Context | Price (Input/Output) | Use Case |
| ----------------------------- | ------- | -------------------- | ----------------------------------------------------------------- |
| `deepseek/deepseek-v4-flash`* | 1M | $0.182/$0.364 | Utility agents, enricher and pentester; provider-wide fallback (default) |
| `deepseek/deepseek-v4-pro` | 1M | $0.5655/$1.131 | Reserved for heavy multi-step reasoning |
| `z-ai/glm-5-turbo` | 262K | $1.56/$5.20 | Orchestrator and assistant, tuned for tool invocation |
| `zhipu/glm-5.2` | 1M | $1.82/$5.72 | Plan generation and refinement at max reasoning effort |
| `minimax/minimax-m3` | 524K | $0.39/$1.56 | Adviser, adaptive thinking via `extra_body` |
| `moonshot/kimi-k2-7-code` | 262K | $1.235/$5.20 | Coder and installer |

The default roster deliberately excludes the OpenAI/Anthropic/Google models the gateway also carries: this product runs offensive-security workloads and those vendors' guardrails false-positive on legitimate exploit-development content. Any other catalog id can be selected per agent role in the Settings UI or in a provider config file.

**LiteLLM Integration**: Set `AIMLAPI_PROVIDER=aimlapi` to enable model name prefixing when using default PentAGI configurations with LiteLLM proxy. Leave empty for direct API usage.

### Ollama Provider Configuration

PentAGI supports Ollama for both local LLM inference (zero-cost, enhanced privacy) and Ollama Cloud (managed service with free tier).
Expand Down Expand Up @@ -3997,7 +4045,7 @@ To access detailed logs:
The main utility accepts several options:

- `-env <path>` - Path to environment file (optional, default: `.env`)
- `-provider <type>` - Provider type to use (default: `custom`, options: `openai`, `anthropic`, `gemini`, `bedrock`, `ollama`, `deepseek`, `glm`, `kimi`, `qwen`, `minimax`, `custom`)
- `-provider <type>` - Provider type to use (default: `custom`, options: `openai`, `anthropic`, `gemini`, `bedrock`, `ollama`, `deepseek`, `glm`, `kimi`, `qwen`, `minimax`, `aimlapi`, `custom`)
- `-flow <id>` - Flow ID for testing functions that require it (0 means using mocks, default: `0`)
- `-user <id>` - User ID for testing functions that require it (default: `0`; `1` is the default admin user)
- `-task <id>` - Task ID for agent context (optional)
Expand Down
13 changes: 12 additions & 1 deletion backend/cmd/ctester/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"time"

"pentagi/pkg/config"
"pentagi/pkg/providers/aimlapi"
"pentagi/pkg/providers/anthropic"
"pentagi/pkg/providers/bedrock"
"pentagi/pkg/providers/custom"
Expand All @@ -33,7 +34,7 @@ import (

func main() {
envFile := flag.String("env", ".env", "Path to environment file")
providerType := flag.String("type", "custom", "Provider type [custom, openai, anthropic, gemini, bedrock, ollama, deepseek, glm, kimi, qwen, minimax]")
providerType := flag.String("type", "custom", "Provider type [custom, openai, anthropic, gemini, bedrock, ollama, deepseek, glm, kimi, qwen, minimax, aimlapi]")
providerName := flag.String("name", "", "Provider name using as PROVDER_NAME/MODEL_NAME while building provider config")
configPath := flag.String("config", "", "Path to provider config file")
testsPath := flag.String("tests", "", "Path to custom tests YAML file")
Expand Down Expand Up @@ -235,6 +236,16 @@ func createProvider(providerType string, cfg *config.Config) (provider.Provider,
}
return minimax.New(cfg, provider.DefaultProviderNameMiniMax, providerConfig)

case "aimlapi":
if cfg.AIMLAPIKey == "" {
return nil, fmt.Errorf("AI/ML API key is not set")
}
providerConfig, err := aimlapi.DefaultProviderConfig()
if err != nil {
return nil, fmt.Errorf("error creating aimlapi provider config: %w", err)
}
return aimlapi.New(cfg, provider.DefaultProviderNameAIMLAPI, providerConfig)

default:
return nil, fmt.Errorf("unsupported provider type: %s", providerType)
}
Expand Down
2 changes: 1 addition & 1 deletion backend/cmd/ftester/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (

func main() {
envFile := flag.String("env", ".env", "Path to environment file")
providerName := flag.String("provider", "custom", "Provider name (openai, anthropic, gemini, bedrock, ollama, deepseek, glm, kimi, qwen, minimax, custom)")
providerName := flag.String("provider", "custom", "Provider name (openai, anthropic, gemini, bedrock, ollama, deepseek, glm, kimi, qwen, minimax, aimlapi, custom)")
flowID := flag.Int64("flow", 0, "Flow ID for testing functions that require it (0 means using mocks)")
userID := flag.Int64("user", 0, "User ID for testing functions that require it (1 is default admin user)")
taskID := flag.Int64("task", 0, "Task ID for testing functions with default unset")
Expand Down
23 changes: 20 additions & 3 deletions backend/cmd/installer/wizard/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ type LLMProviderConfig struct {

// direct form field mappings using loader.EnvVar
// these fields directly correspond to environment variables and form inputs (not computed)
BaseURL loader.EnvVar // OPEN_AI_SERVER_URL | ANTHROPIC_SERVER_URL | GEMINI_SERVER_URL | BEDROCK_SERVER_URL | OLLAMA_SERVER_URL | DEEPSEEK_SERVER_URL | GLM_SERVER_URL | KIMI_SERVER_URL | QWEN_SERVER_URL | MINIMAX_SERVER_URL | LLM_SERVER_URL
APIKey loader.EnvVar // OPEN_AI_KEY | ANTHROPIC_API_KEY | GEMINI_API_KEY | LLM_SERVER_KEY | DEEPSEEK_API_KEY | GLM_API_KEY | KIMI_API_KEY | QWEN_API_KEY | MINIMAX_API_KEY | OLLAMA_SERVER_API_KEY
BaseURL loader.EnvVar // OPEN_AI_SERVER_URL | ANTHROPIC_SERVER_URL | GEMINI_SERVER_URL | BEDROCK_SERVER_URL | OLLAMA_SERVER_URL | DEEPSEEK_SERVER_URL | GLM_SERVER_URL | KIMI_SERVER_URL | QWEN_SERVER_URL | MINIMAX_SERVER_URL | AIMLAPI_SERVER_URL | LLM_SERVER_URL
APIKey loader.EnvVar // OPEN_AI_KEY | ANTHROPIC_API_KEY | GEMINI_API_KEY | LLM_SERVER_KEY | DEEPSEEK_API_KEY | GLM_API_KEY | KIMI_API_KEY | QWEN_API_KEY | MINIMAX_API_KEY | AIMLAPI_API_KEY | OLLAMA_SERVER_API_KEY
Model loader.EnvVar // LLM_SERVER_MODEL
// AWS Bedrock specific fields
DefaultAuth loader.EnvVar // BEDROCK_DEFAULT_AUTH
Expand Down Expand Up @@ -203,6 +203,7 @@ func (c *controller) GetLLMProviders() map[string]*LLMProviderConfig {
"kimi": c.GetLLMProviderConfig("kimi"),
"qwen": c.GetLLMProviderConfig("qwen"),
"minimax": c.GetLLMProviderConfig("minimax"),
"aimlapi": c.GetLLMProviderConfig("aimlapi"),
"custom": c.GetLLMProviderConfig("custom"),
}
}
Expand Down Expand Up @@ -298,6 +299,13 @@ func (c *controller) GetLLMProviderConfig(providerID string) *LLMProviderConfig
providerConfig.ProviderName, _ = c.GetVar("MINIMAX_PROVIDER")
providerConfig.Configured = providerConfig.APIKey.Value != ""

case "aimlapi":
providerConfig.Name = "aimlapi.com"
providerConfig.APIKey, _ = c.GetVar("AIMLAPI_API_KEY")
providerConfig.BaseURL, _ = c.GetVar("AIMLAPI_SERVER_URL")
providerConfig.ProviderName, _ = c.GetVar("AIMLAPI_PROVIDER")
providerConfig.Configured = providerConfig.APIKey.Value != ""

case "custom":
providerConfig.Name = "Custom"
providerConfig.BaseURL, _ = c.GetVar("LLM_SERVER_URL")
Expand Down Expand Up @@ -450,7 +458,7 @@ func (c *controller) UpdateLLMProviderConfig(providerID string, config *LLMProvi
return fmt.Errorf("failed to set %s: %w", config.ProviderName.Name, err)
}

case "minimax":
case "minimax", "aimlapi":
if err := c.SetVar(config.APIKey.Name, config.APIKey.Value); err != nil {
return fmt.Errorf("failed to set %s: %w", config.APIKey.Name, err)
}
Expand Down Expand Up @@ -540,6 +548,8 @@ func (c *controller) ResetLLMProviderConfig(providerID string) map[string]*LLMPr
vars = []string{"QWEN_API_KEY", "QWEN_SERVER_URL", "QWEN_PROVIDER"}
case "minimax":
vars = []string{"MINIMAX_API_KEY", "MINIMAX_SERVER_URL", "MINIMAX_PROVIDER"}
case "aimlapi":
vars = []string{"AIMLAPI_API_KEY", "AIMLAPI_SERVER_URL", "AIMLAPI_PROVIDER"}
case "custom":
vars = []string{
"LLM_SERVER_URL", "LLM_SERVER_KEY", "LLM_SERVER_MODEL",
Expand Down Expand Up @@ -2347,6 +2357,9 @@ func (c *controller) getVariableDescription(varName string) string {
"MINIMAX_API_KEY": locale.EnvDesc_MINIMAX_API_KEY,
"MINIMAX_SERVER_URL": locale.EnvDesc_MINIMAX_SERVER_URL,
"MINIMAX_PROVIDER": locale.EnvDesc_MINIMAX_PROVIDER,
"AIMLAPI_API_KEY": locale.EnvDesc_AIMLAPI_API_KEY,
"AIMLAPI_SERVER_URL": locale.EnvDesc_AIMLAPI_SERVER_URL,
"AIMLAPI_PROVIDER": locale.EnvDesc_AIMLAPI_PROVIDER,
"LLM_SERVER_URL": locale.EnvDesc_LLM_SERVER_URL,
"LLM_SERVER_KEY": locale.EnvDesc_LLM_SERVER_KEY,
"LLM_SERVER_MODEL": locale.EnvDesc_LLM_SERVER_MODEL,
Expand Down Expand Up @@ -2542,6 +2555,7 @@ var maskedVariables = map[string]bool{
"KIMI_API_KEY": true,
"QWEN_API_KEY": true,
"MINIMAX_API_KEY": true,
"AIMLAPI_API_KEY": true,
"LLM_SERVER_KEY": true,
"LANGFUSE_PUBLIC_KEY": true,
"LANGFUSE_SECRET_KEY": true,
Expand Down Expand Up @@ -2633,6 +2647,9 @@ var criticalVariables = map[string]bool{
"MINIMAX_API_KEY": true,
"MINIMAX_SERVER_URL": true,
"MINIMAX_PROVIDER": true,
"AIMLAPI_API_KEY": true,
"AIMLAPI_SERVER_URL": true,
"AIMLAPI_PROVIDER": true,
"LLM_SERVER_URL": true,
"LLM_SERVER_KEY": true,
"LLM_SERVER_MODEL": true,
Expand Down
Loading