Skip to content
Closed
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 @@ -71,6 +71,11 @@ MINIMAX_API_KEY=
MINIMAX_SERVER_URL=https://api.minimax.io/v1
MINIMAX_PROVIDER=

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

## Custom LLM provider
LLM_SERVER_URL=
LLM_SERVER_KEY=
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**: OpenAI, Anthropic, Gemini, AWS Bedrock, Ollama, DeepSeek, GLM, Kimi, Qwen, MiniMax, aimlapi.com, 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 @@ -36,6 +36,7 @@
- [Kimi](#kimi-provider-configuration)
- [Qwen](#qwen-provider-configuration)
- [MiniMax](#minimax-provider-configuration)
- [aimlapi.com](#aimlapicom-provider-configuration)
- [Advanced Setup](#advanced-setup)
- [Langfuse Integration](#langfuse-integration)
- [Monitoring and Observability](#monitoring-and-observability)
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 ([OpenRouter](https://openrouter.ai/), [DeepInfra](https://deepinfra.com/), [Atlas Cloud](https://www.atlascloud.ai/), [OpenCode Go plan](https://opencode.ai/en/go), [aimlapi.com](https://aimlapi.com/)). 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 @@ -2576,6 +2580,50 @@ PentAGI ships 3 MiniMax models with tool calling, JSON output, and streaming. `M

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

### 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.

## Advanced Setup

### Langfuse Integration
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
35 changes: 35 additions & 0 deletions backend/cmd/installer/wizard/locale/locale.go
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,7 @@ const (
LLMProviderKimi = "Kimi Moonshot AI"
LLMProviderQwen = "Qwen Alibaba Cloud"
LLMProviderMiniMax = "MiniMax"
LLMProviderAIMLAPI = "aimlapi.com"
LLMProviderCustom = "Custom"
LLMProviderOpenAIDesc = "Industry-leading GPT models with excellent general performance"
LLMProviderAnthropicDesc = "Claude models with superior reasoning and safety features"
Expand All @@ -378,6 +379,7 @@ const (
LLMProviderKimiDesc = "Moonshot AI's long-context models for document analysis"
LLMProviderQwenDesc = "Alibaba Cloud's Qwen models for multilingual tasks"
LLMProviderMiniMaxDesc = "MiniMax's M-series models for agentic reasoning and long-context tasks"
LLMProviderAIMLAPIDesc = "Single OpenAI-compatible endpoint fronting 350+ chat models from many vendors"
LLMProviderCustomDesc = "Custom OpenAI-compatible endpoint for maximum flexibility"
)

Expand Down Expand Up @@ -627,6 +629,36 @@ Cost: Competitive per-token pricing across the M-series

Setup: Get your API key from https://platform.minimax.io/`

LLMFormAIMLAPIHelp = `aimlapi.com is an aggregator: one OpenAI-compatible endpoint and one API key in front of 350+ chat models from many vendors.

Default PentAGI Models:
• deepseek/deepseek-v4-flash: utility agents, enricher and pentester (1M context, hybrid thinking)
• deepseek/deepseek-v4-pro: reserved for heavy multi-step reasoning
• z-ai/glm-5-turbo: orchestrator and assistant, tuned for tool invocation
• zhipu/glm-5.2: plan generation and refinement at max reasoning effort
• minimax/minimax-m3: adviser, adaptive thinking via extra_body
• moonshot/kimi-k2-7-code: coder and installer

Key Advantages:
• One key and one endpoint across DeepSeek, GLM, MiniMax, Kimi, Qwen and others
• Model ids are vendor-namespaced, so swapping a role's model needs no new credential
• Full tool calling, structured output, streaming and reasoning support

API Endpoint:
• https://api.aimlapi.com/v1 (default)

LiteLLM Integration:
• Set Provider Name to 'aimlapi' when using a LiteLLM proxy
• Enables model prefix (e.g., aimlapi/deepseek/deepseek-v4-flash) without modifying config.yml
• Optional for direct aimlapi.com usage

Note: the default model roster deliberately excludes OpenAI/Anthropic/Google models that the gateway also carries, because their guardrails false-positive on legitimate exploit-development work.

Best for: Trying several vendors' models across agent roles without managing one account per vendor
Cost: Per-token, published per model at https://api.aimlapi.com/v1/models?include=all

Setup: Get your API key from https://aimlapi.com/app/keys`

LLMFormCustomHelp = `Configure any OpenAI-compatible API endpoint for maximum flexibility and integration with existing infrastructure.

Ready-to-use Configurations:
Expand Down Expand Up @@ -2352,6 +2384,9 @@ const (
EnvDesc_MINIMAX_API_KEY = "MiniMax API Key"
EnvDesc_MINIMAX_SERVER_URL = "MiniMax Server URL"
EnvDesc_MINIMAX_PROVIDER = "MiniMax Provider Name Prefix (for LiteLLM, e.g., 'minimax')"
EnvDesc_AIMLAPI_API_KEY = "aimlapi.com API Key"
EnvDesc_AIMLAPI_SERVER_URL = "aimlapi.com Server URL"
EnvDesc_AIMLAPI_PROVIDER = "aimlapi.com Provider Name Prefix (for LiteLLM, e.g., 'aimlapi')"
EnvDesc_LLM_SERVER_URL = "Custom LLM Server URL"
EnvDesc_LLM_SERVER_KEY = "Custom LLM API Key"
EnvDesc_LLM_SERVER_MODEL = "Custom LLM Model"
Expand Down
Loading