- authLoginCallback matches users by email alone so an OAuth login links into an
existing (incl. local) account instead of 500-ing on users_mail_unique
- relink on a create-branch unique-violation race instead of returning 500
- issue the session with the linked account's actual role privileges
- clear the stale OAuth provider link when a user changes their email
- map the email-change unique-violation race to 409 instead of 500
- isUniqueViolation matches Postgres and SQLite case-insensitively
- tests for link/create/blocked/role-inheritance/race, email 409, provider reset
- update auth form test selectors after the form refactor
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- OAuth login callback now stores the provider (google/github) on the
user record and backfills it for pre-existing OAuth users on login,
so the UI can show which provider an account is linked to.
- Add PUT /user/name for any authenticated user (including OAuth): a
NameChange model + ChangeNameCurrentUser handler that lets users edit
their display name. Placed in a /user group without localUserRequired.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two crashes seen in production, both reproduced on the live app:
- "Failed to fetch dynamically imported module": after a redeploy rotates the
hashed chunk filenames, an open tab imports a deleted one. The server answered a
missing /assets/* with 301 -> index.html (HTML for a JS module -> a MIME
failure); it now returns 404 + no-store. The client listens for Vite's
vite:preloadError and reloads once (debounced) to pull the current build. Hashed
assets are served immutable; index.html and SPA routes no-cache.
- "Failed to execute 'removeChild' ... not a child of this node": an external
agent (a browser extension or auto-translation) mutates the DOM React owns,
desyncing reconciliation. A root react-router errorElement catches this
commit-phase crash and self-heals with a debounced reload, instead of React
Router's dead default error screen. translate="no" opts the English-only UI out
of the one trigger it can prevent (browser translation); the errorElement covers
the rest regardless of source.
Verified by reproducing both on the live old build (missing-chunk 301->HTML;
extension/translation DOM mutation -> the exact removeChild crash) and confirming
the fixed build recovers from each. Adds chunk-reload + RouteErrorBoundary unit
tests and a static-serving integration test.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fixes#312
Root cause:
During flow creation the first LLM call selects the primary Docker
image. When the configured LLM backend is unsupported or returns 404,
prv.Call fails, but the wrapped error read "failed to get primary
docker image". Users repeatedly interpreted this as a Docker problem
(see #312, #309, #203) and debugged Docker instead of their LLM
provider configuration.
Solution:
Reword the wrapped error to "failed to select primary docker image
via llm call" so the LLM provider is identified as the failing
component while still mentioning the image selection step.
Testing:
go build ./pkg/providers/ -> OK
Added new test cases to validate containment barriers in the `ResolvePulledStagedTarget` and `ZipRelativePaths` functions, ensuring that paths escaping the designated directories are properly rejected. Updated the `knowledge_test.go` to include scenarios for handling nil embedder and error propagation during document creation, improving overall test coverage and robustness.
Enhanced the flowWorker's task processing by introducing a cancellable context for task execution. This change ensures that tasks can be properly cancelled without reporting false success states. The `runTask` method has been refactored to utilize a new `execTask` method, which centralizes task execution logic and maintains context integrity. This update improves flow control and error handling during task creation and execution.
Updated the Qwen agent configuration to include `extra_body` parameters for thinking control across various models. Added `enable_thinking` and `preserve_thinking` options for reasoning agents, while utility agents have `enable_thinking` set to false. Adjusted the Qwen client initialization to support these new configurations. Updated test report to reflect changes in success rates and latencies.
DeepSeek V4 thinking mode defaults to enabled on both deepseek-v4-flash
and deepseek-v4-pro; non-thinking behavior requires an explicit toggle.
Per official docs, in thinking mode temperature/top_p/presence_penalty/
frequency_penalty are ignored, so the existing Flash role sampling knobs
would have been silently no-ops without the toggle.
Add extra_body.thinking.type=disabled to the five non-thinking Flash
roles so deepseek-v4-flash actually runs in non-thinking mode and
honors the role's temperature/top_p settings:
- simple, simple_json, adviser, searcher, enricher
Pro roles (primary_agent, assistant, generator, refiner, reflector,
coder, installer, pentester) intentionally keep thinking enabled (the
V4 default) for reasoning, tool-use, and security analysis.
PentAGI provider config already supports extra_body as a first-class
yaml field on AgentConfig and forwards it through openai.WithExtraBody,
which the vxcontrol langchaingo fork serializes at the top level of the
Chat Completions request - the same pattern Kimi uses for tool_choice.
No code, schema, or LiteLLM prefix changes required.
Touches:
- backend/pkg/providers/deepseek/config.yml (embedded production config)
- examples/configs/deepseek.provider.yml (user-facing example)
No change to role-to-model mapping, model metadata, pricing, README
wording, LiteLLM prefix, unrelated providers, lifecycle, queues, or
installer flow.
- Update model descriptions to reflect V4 1M context window (up to 384K output)
instead of legacy 128K wording in models.yml and README.
- Split Flash and Pro pricing per official DeepSeek API docs:
- deepseek-v4-flash: input 0.14 / output 0.28 / cache_hit 0.0028 per 1M tokens
- deepseek-v4-pro: input 0.435 / output 0.87 / cache_hit 0.003625 per 1M tokens
- Apply per-role price split across all 13 role configs in both the embedded
config.yml and the user-facing examples/configs/deepseek.provider.yml.
- Replace stale "cache pricing is 10% of input cost" claim in the README,
which no longer holds for either V4 model.
- No change to LiteLLM prefix behavior, role-to-model mapping, lifecycle,
queues, GraphQL schema, migrations, frontend, or installer flow.
The DeepSeek provider config still defaulted to the legacy
`deepseek-chat` and `deepseek-reasoner` model names, which the
upstream DeepSeek API has announced for deprecation on 2026-07-24.
A first-run install therefore breaks once the legacy names are
removed.
Swap the defaults to the current DeepSeek V4 family:
- non-thinking roles use `deepseek-v4-flash`
- reasoning-heavy roles use `deepseek-v4-pro`
The change is limited to the embedded `config.yml` / `models.yml`
inside `backend/pkg/providers/deepseek`, the matching example at
`examples/configs/deepseek.provider.yml`, the `DeepSeekAgentModel`
fallback constant in `deepseek.go`, and three doc references
(README.md, backend/docs/config.md, backend/docs/llms_how_to.md)
plus one installer help string in
`backend/cmd/installer/wizard/locale/locale.go`. LiteLLM prefix
behavior is untouched.
- Introduced `EMBEDDING_MAX_TEXT_BYTES` to limit the maximum byte size of text sent to the embedding model.
- Renamed database connection pool settings: `DATABASE_MAX_OPEN_CONNS`, `DATABASE_MAX_IDLE_CONNS`, and `DATABASE_VECTOR_MAX_CONNS` for improved PostgreSQL connection management.
- Updated relevant documentation to reflect these new configuration options and their usage.
- Adjusted various components to utilize the new settings for enhanced performance and resource management.
- Added ToolCallLogProvider interface with methods for logging tool calls, updating success and failure statuses.
- Introduced proxyToolCallLogProvider to handle ToolCall logging operations.
- Updated flow execution components to integrate ToolCall logging, including flow workers and controllers.
- Enhanced GraphQL schema to support ToolCall logs, including queries and subscriptions for real-time updates.
- Updated documentation to reflect the new ToolCall logging features and their usage.
- Introduced shared connection pooling for PostgreSQL using `*sql.DB` for sqlc and GORM, optimizing resource usage.
- Added new environment variables: `DB_MAX_OPEN_CONNS`, `DB_MAX_IDLE_CONNS`, and `DB_VECTOR_MAX_CONNS` for configurable connection limits.
- Updated documentation to reflect new connection pooling strategy and provide operational commands for monitoring.
- Implemented shared `pgxpool` for pgvector stores to reduce connection overhead and improve performance.
- Adjusted various components to utilize the new connection pooling setup, ensuring efficient database interactions.
- Introduced WaitTaskCompletion method in FlowWorker interface to block until the current task completes or the context expires.
- Implemented signalTaskComplete to manage task completion signaling across goroutines.
- Added waitFlowCompletion tool to handle waiting for task completion with configurable timeout.
- Updated assistant provider to include wait functionality for flow completion.
- Enhanced templates and tool registry to support new wait functionality.
When an LLM emits a truncated or malformed arguments field (e.g. "{") instead of valid JSON, downstream consumers such as LiteLLM reject the entire request with a 400 Bad Request, causing the chain to degrade into an infinite retry loop.
- SanitizeToolCallArguments now falls back to "{}" after control-char escaping if the result is still not valid JSON, fixing already-stored chains on restore
- callWithRetries logs a warning and substitutes "{}" at the moment the bad arguments arrive from the LLM, preventing them from ever reaching the database
- Added test cases for truncated JSON, partial objects, and empty strings
- Added a new SQL migration to insert toolcall privileges into the privileges table.
- Introduced the `ToolcallService` for managing toolcall data, including retrieval of toolcalls and flow-specific toolcalls.
- Implemented API endpoints for fetching toolcalls and toolcall details, with appropriate permission checks.
- Enhanced Swagger documentation to include new toolcall endpoints and their specifications.
- Created a new model for toolcalls, defining their structure and validation rules.
- Added error handling for invalid toolcall requests and not found scenarios.
- Added a new SQL migration to insert the 'anonymize.call' privilege into the privileges table.
- Introduced the `anonymizeText` mutation in the GraphQL schema, allowing users to anonymize sensitive text.
- Implemented the `AnonymizerService` to handle text anonymization requests via a REST API endpoint.
- Updated the GraphQL resolver to integrate the new mutation and ensure proper permission checks.
- Enhanced documentation with Swagger and OpenAPI specifications for the new endpoint.
- Added error handling for invalid requests and unavailable anonymizer configurations.
Eliminate the message length truncation from both `putMsg` methods in `aslog.go` and `msglog.go`. This change simplifies the message handling process by allowing messages to be processed without arbitrary length restrictions.
- Fix empty ID bug: langchaingo SimilaritySearch discarded document UUIDs; new SearchKnowledgeDocuments/SearchUserKnowledgeDocuments return them directly
- Remove unsafe fmt.Sprintf SQL filter interpolation, use parameterised queries
- Exclude memory documents from search results at SQL level
- Add FlowID support to passesSearchFilter
- Convert all $N positional params to sqlc.arg(name) across knowledge queries
- Update tests: replace TestBuildSearchFilters with TestPassesSearchFilter, add TestSearchDocuments and TestSearchUserDocuments
- Introduced a new `docType` field in the `UpdateKnowledgeDocumentInput` to manage document type changes.
- Updated the `doUpdate` method to clear subtype fields (GuideType, AnswerType, CodeLang) when the document type changes.
- Added comprehensive tests for various document type transitions to ensure correct behavior and state preservation.
- Updated GraphQL schema and generated models to accommodate the new `docType` field.
- Introduced "/resources" and "/knowledges" routes to the frontendRoutes array in the router configuration, expanding the application's routing capabilities.
- Removed the requirement for the "destination" field in MoveResourceRequest, allowing it to be an empty string, which signifies moving to the root directory.
- Updated related documentation in swagger.json, swagger.yaml, and docs.go to reflect the new behavior.
- Adjusted the MoveResource function to handle cases where the destination is empty, ensuring proper path sanitization and resource movement semantics.
- Enhanced test cases to cover scenarios involving moving resources to the root directory and handling conflicts appropriately.
- Allow POST /flows/0/assistants/ to create a new flow together with the assistant, mirroring the existing GraphQL createAssistant(flowID: 0) behavior
- Require both assistants.create and flows.create permissions when flowID=0
- Add explicit flow ownership check for non-zero flowID using flows.admin scope
- Load flow data in the response by fetching it via assistant.FlowID after creation, ensuring AssistantFlow is fully populated in all cases
- Introduced new fields `version` and `isDevelopMode` in the Settings model to provide application versioning and development mode status.
- Updated GraphQL schema and resolvers to support the new fields, ensuring they are accessible via the Settings query.
- Enhanced Swagger documentation to reflect the changes in the Settings API endpoint.
- Added necessary validation and response handling for the new fields in the Settings service.
Address two reviewer concerns on the issue #300 follow-up:
* Replace the `DumpTemplates()` -> `json.Unmarshal` round-trip in
buildUserPrompter with a new `templates.LoadDefaultPromptsMap()`
helper that returns the embedded defaults as a `PromptsMap`
directly. `defaultPrompter.DumpTemplates()` now delegates to the
same helper, so the JSON output for that API is unchanged.
* Add an optional `prompter` field to `assistantWorkerCtx`. When
set, `LoadAssistantWorker` reuses it instead of re-querying
`GetUserPrompts` and re-merging defaults. `LoadFlowWorker`
populates it once per flow load so multi-assistant flows pay the
DB+merge cost a single time.
Tests updated to match the new pure-merge `buildUserPrompter`
signature; behavior for users with no overrides is unchanged.
Signed-off-by: mason5052 <ehehwnwjs5052@gmail.com>
Address review on PR #303.
- helpers.go: remove the concrete model examples (llama3.1, qwen2.5, mistral-nemo) from the Ollama tools-unsupported hint. PentAGI does not verify Ollama model capabilities from upstream metadata, so a hard-coded list of supposedly tool-capable tags is risky and ages poorly. The hint now points users to select an Ollama model whose own metadata advertises tool/function calling support.
- helpers.go: rewrite the comment and error wording so it is no longer flow-only. The helper is shared by NewFlowProvider and NewAssistantProvider, so the message now refers to tool execution in flows and assistant sessions, and the doc-comment notes that wording must stay context-neutral.
- helpers_test.go: tighten TestWrapToolCallIDTemplateError to match the new wording, ban the previous concrete model tags, and ban flow-only language ('flow execution', 'flow creation'). The test still verifies that the original underlying error is wrapped via errors.Is.
Signed-off-by: mason5052 <ehehwnwjs5052@gmail.com>
## Summary
Surface an actionable hint when an Ollama model that does not support
tool/function calling is selected for a flow or assistant session, so
users do not have to parse a five-wrap-deep "failed to determine tool
call ID template" stack trace to figure out why flow creation fails.
## Problem
A user on an Ollama deployment of `gemma3:27b-it-q4_K_M` reports that
the Provider/LLM test passes the basic completion checks but flow
creation fails with:
failed to create flow worker: failed to get flow provider: failed
to determine tool call ID template: failed to collect tool call ID
samples: all sample collection attempts failed: failed to call LLM:
400 Bad Request: registry.ollama.ai/library/gemma3:27b-it-q4_K_M
does not support tools
The underlying signal "does not support tools" is emitted by the
Ollama API itself; PentAGI buries it five wraps deep, so the user is
left guessing whether the issue is configuration, networking, or
something internal to PentAGI.
## Solution
Add an unexported helper `wrapToolCallIDTemplateError` in
`pkg/providers/helpers.go` that detects the upstream "does not support
tools" substring and prepends a one-sentence guidance message naming
the constraint and a few known-good Ollama tags
(`llama3.1`, `qwen2.5`, `mistral-nemo`). All other errors keep the
existing wording. The original error is preserved via `%w` so log
spans, langfuse traces, and any future `errors.Is/As` callers continue
to work.
Both call sites in `pkg/providers/providers.go`
(`NewFlowProvider`, `NewAssistantProvider`) now route through the
helper.
No schema, API, or DB changes. No new lifecycle state. No background
work. The behavior change is the wording of one error string in one
upstream-defined failure case.
## User Impact
- Users who pick an Ollama model without tool support get a clear,
actionable error during flow / assistant creation instead of a deep
stack trace.
- Users on tool-capable models (Anthropic, OpenAI, Bedrock, and
tool-capable Ollama tags) see no behavioral or message change.
- No restart, migration, or configuration step required.
## Test Plan
- New table-driven test `TestWrapToolCallIDTemplateError` covers:
- nil error -> nil
- upstream "does not support tools" chain (matching the real five-
wrap shape) -> actionable message + `errors.Is` round-trips to the
original error
- generic non-tools error -> existing wrap text preserved, no
new guidance appended
- `go test ./pkg/providers/...` passes locally.
- `go build ./...` and `go vet ./pkg/providers/...` clean.
Closes#280
Signed-off-by: mason5052 <ehehwnwjs5052@gmail.com>
Custom prompts saved via the Settings -> Prompts UI are persisted to the
database, but every assistant and flow session creation path was using
templates.NewDefaultPrompter() with a leftover TODO, so user overrides
never reached the agents and Langfuse traces always showed the defaults.
Add a controller-side helper that loads the user's saved prompts and
overlays them on the compiled defaults. Prompt types the user has not
customized continue to use the defaults; an empty body row is treated
as no override (the UI uses delete to reset). A database error fails
session creation explicitly instead of silently falling back.
Wire the helper into the four affected call sites in NewAssistantWorker,
LoadAssistantWorker, NewFlowWorker, and LoadFlowWorker.
Closes#300
Signed-off-by: mason5052 <ehehwnwjs5052@gmail.com>
- Add Sources []string to MoveResourceRequest, CopyResourceRequest and AddResourceFromFlowRequest; merged with Source, deduplicated; multi-source uses destination as base dir and runs in a single atomic DB transaction
- Fix MoveResource response to return Added + Updated (not Updated only) so Apollo cache receives new parent directory entries alongside moved items
- Add missing errResourceNotFound case in CopyResource (was 500 instead of 404)
- Cover all new behaviour with table-driven tests (basename conflict, force overwrite, missing source, empty input, dir-into-itself guard, etc.)
- GraphQL/REST CRUD + semantic search for knowledge documents
- KnowledgeStore with admin/user-scoped filtering, re-embedding on update
- Real-time subscriptions (created/updated/deleted) per user and admin
- user_id tracking in all agent-stored documents (guide/answer/code/memory)
- sqlc queries, goose migrations, privilege grants, user_id backfill
- Memory cleanup on flow deletion; stale orphan purge via migration
- Unit tests for all KnowledgeStore operations including security cases
- Frontend GraphQL schema and TypeScript types regenerated
- Added `paths[]` query/body parameter to DeleteFlowFile, DownloadFlowFile,
GetFlowContainerFiles, PullFlowFiles, ListResources, DeleteResource, and
DownloadResource; single `path` parameter retained for backward compatibility.
- Introduced `DeduplicatePaths` in flowfiles package with coverage-based
deduplication (parent covers children), path normalization, and traversal safety.
- Added `ZipRelativePaths` to create ZIP archives from cache-relative paths,
sharing `zipWriteFile` helper with refactored `ZipDirectory`.
- Switched all ZIP and single-file responses to buffered `DataFromReader` with
explicit `Content-Length`, fixing Swagger UI download rendering.
- Expanded response payloads: delete and pull operations now enumerate all
affected nested files; list responses include ancestor directories for tree
completeness.
- Extended test coverage across flowfiles, flow_files, and resources packages
with batch, deduplication, atomicity, Docker exec, and security scenarios.
- Implemented `SanitizeJSONControlChars` to escape literal control characters in JSON string values, ensuring compliance with the JSON specification.
- Enhanced `SanitizeToolCallArguments` method to apply sanitization across tool call arguments in the chain.
- Added comprehensive tests for both sanitization functions to validate behavior with various input scenarios.
- Updated the logic in `determineRecentSectionsToKeep` to clamp the lower bound of the recent sections to keep, ensuring it does not exceed the available sections. This prevents potential out-of-range errors when `keepQASections` is greater than the total number of sections.
- Updated `getHTML` and `getMD` methods to return warnings for small content instead of errors.
- Implemented checks for binary URLs, returning descriptive errors when such URLs are encountered.
- Added new tests to validate the updated behavior for small and empty content handling.
- Added TryLock mechanism to avoid deadlock situations when reading from the channel while the mutex is held.
- Enhanced timer handling to reset when the mutex is not available, ensuring continuous operation of the stream.
- Adjusted descriptions in API documentation to clarify paths for uploads, resources, and containers.
- Updated data models to use consistent naming conventions (e.g., `isDir` to `is_dir`, `modifiedAt` to `modified_at`).
- Changed resource ID types from string to uint64 for better consistency across the application.
- Enhanced flow file upload functionality to support batch processing of resource files.
- Removed deprecated code related to resource entry responses in tests.
- Replaced ambiguous "user's language" guidance in tools/args.go with explicit engagement-log vs technical-channel markers per field, with strong English-only requirement for vector-store and search-engine queries.
- Added a unified LANGUAGE POLICY block to every agent prompt (primary_agent, assistant, pentester, coder, installer, searcher, memorist, generator, refiner, reporter, enricher), tailored per agent based on its actual tool set.
- Extended template variables and tool access (TerminalToolName, FileToolName) for coder, pentester, installer, memorist, generator, refiner, and enricher to match their runtime tool registrations.
- Fixed inverted UseAgents condition and removed misleading vector-store write references in assistant prompt; corrected MEMORY SYSTEM INTEGRATION for mode-specific tool references.
- Compressed COMPLETION REQUIREMENTS across templates and aligned closing-tool guidance with the channel mapping (engagement-log message vs technical-channel result).
Fixes#285.
Co-Authored-By: Octopus <liyuan851277048@icloud.com>
- Added table-driven scenarios for all 8 endpoints (Get/Upload/Delete/Download flow files, Pull from container, GetContainerFiles, AddResourcesToFlow, AddResourceFromFlow) covering success paths, all privilege combinations (view/upload/admin/cross-user), error responses (forbidden/not-found/conflict/invalid request), and security checks (path traversal, symlink rejection).
- Introduced reusable test infrastructure: sqlite-backed flows/user_resources schema, fakeDockerClient implementing the full docker.DockerClient interface, flowFileCaptureSubscriptions recording both FlowPublisher and ResourcePublisher events, and helpers for multipart upload bodies and container TAR fixtures.
- Added direct unit tests for shellQuote, parseFlowIDParam, cleanupPendingUploads, and flowScopeForFiles privilege matrix.
- Lifts handler coverage from 0% to 60-90% across the file and total services package coverage from 10.2% to 28.6%.
- Restructured single-case tests for List, Mkdir, Download, and CleanupOrphanBlobs into table-driven scenarios.
- Extended Upload, Delete, Copy, and Move scenarios with admin, forbidden, malformed JSON, invalid path, missing source, and trailing-slash hint cases.
- Added dedicated tests for blob deduplication on upload/copy, non-multipart bodies, orphan blob preservation on rollback, and direct deleteOrphanBlob coverage.
- Introduced helpers for parameterized multipart field names, custom UID context, and on-disk blob counting.