The e2e suite and CI gates could report green without checking anything: the
lint/codegen gate never ran on fork PRs, the codegen freshness check diffed the
wrong range, the sticky comment claimed passes it never read, and several
visual/palette/contrast/a11y gates were written so they could not fail. Closing
those gates then exposed real defects.
**E2E and CI.** New coverage for the assistant lifecycle, flow interrupt, live
panels, tab deep links, the report route and its exports, session expiry, and
uploads/downloads (59 → 125 spec cases). Gates now fail on real regressions:
absolute pixel budget, per-tab panel sweeps, scoped a11y waivers, page-error
assertions. CI runs on `pull_request`, ranges from the PR base, routes comments
by PR identity, and redacts stand secrets from the public artifact.
**Markdown editor.** ~20 round-trip and toolbar fixes: table pipe escaping
(nested lists, Go template pipelines, headerless tables), fence validity,
setext and line-leading escapes, inline code containing a backtick, block
toggles under select-all, controls disabled where the command is unavailable or
a table cell cannot hold the block, theme-aware code surface. Two perf fixes cut
1 MB document load from 69s to 4s.
**Accessibility and UI.** Focus returns to whatever opened a dialog, sheet or
menu; icon-only buttons named; `aria-sort` on table columns; syntax tokens
retuned to clear AA in both themes; a dedicated link token. Detail and settings
pages now distinguish authz denials and partial errors from missing records,
survive background refetches without blanking or discarding unsaved edits, and
stop naming exported PDFs `*.pdf.pdf`.
**Backend.** Passwords capped at the 72 bytes bcrypt can hash (over-long ones
previously 500'd after passing validation); four agent options the GraphQL round
trip silently dropped are carried through; a flow whose worker fails to start is
no longer left in the listing; the Graphiti health check retries before
permanently disabling the client.
---------
Co-authored-by: Sergey Kozyrenko <sirozha_blr@tut.by>
The backend already threaded a per-agent `extra_body` map into the LLM request
(pconfig.AgentConfig, openai.WithExtraBody), but it was reachable only from YAML
provisioning — the GraphQL type, the converter, and the settings form all
dropped it. Editing a YAML-provisioned provider through the UI therefore round-
tripped its config and silently stripped extra_body.
Add `extraBody: Map` to AgentConfig / AgentConfigInput, carry it through the
converter in both directions, and give each agent an "Extra Body" JSON field in
the provider form (validated as an object, serialized on load, parsed on save).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add an explicit reasoning Off to the per-agent config, backed by the langchaingo
tri-state API. Off emits llms.WithReasoningDisabled() (the provider disable wire)
via BuildOptions, and UsesAdaptiveThinking is guarded so Off overrides the
adaptive-only auto-adaptive.
Per-model capability is derived at runtime from llms.ReasoningSupportFor and
surfaced through GraphQL ModelReasoningInfo, so the UI only offers Off where it
actually disables: cannotDisable reports when Off would be rejected (always-on
models) OR a silent no-op (an unclassified default-on model whose disable wire is
omitted), and capability is surfaced for any thinking-capable model (e.g. Gemini,
which declares thinking without a reasoning block). A new
ProviderType.ReasoningProvider() supplies the provider to the resolver.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- prompts_test.go: PatchPrompt rejects a syntax error, an undeclared variable,
and a whitespace-only template over REST (the path a raw client hits when the
UI is bypassed) and does not persist them; valid templates still create/update.
- validation_test.go: validateKnowledgeFieldLengths accepts each field at its
max length and rejects one character over.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The REST handlers reject empty or oversized knowledge fields and over-long
API-token names through their request-model validate tags, but the GraphQL
mutations — the path the web UI uses — accepted them unchecked, so the same
entity could be stored past its documented limits depending on the caller.
Mirror the REST caps at the resolver boundary:
- createKnowledgeDocument / updateKnowledgeDocument: require content (and
question on create), and cap content/question/description/codeLang lengths.
- createAPIToken / updateAPIToken: cap the token-name length.
Limits are kept in sync with server/models via mirror comments.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The renameFlow / putUserInput / callAssistant GraphQL resolvers passed the
title/input straight to the controller with no non-empty check, while the
equivalent REST handlers reject them with 400. An empty flow title in
particular then fails the Flow model's `required` invariant and breaks the
REST GET /flows listing for that user. Mirror the REST guard at the resolver
boundary, matching the existing createFlow "... is required" checks.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Review nits:
- schema.resolvers.go: log (not swallow) bedrock.DefaultModels errors so an
invalid BEDROCK_MODELS_PATH no longer yields a silently-empty model list.
- settings-providers.tsx: derive the create-provider type list from an
exhaustive Record<ProviderType,string> so a future ProviderType is a compile
error here instead of silently missing from the menu.
- trim two doc comments (convertModelReasoningMode, ReasoningFields) to lead
with the load-bearing contract instead of restating the name.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reworks external PR #328 (octo-patch). The PR added only the provider core;
this brings MiniMax to full parity with the other providers (qwen) so it is
selectable and configurable in the UI and installer.
Applied from the PR (verified against MiniMax's official API docs — M3/M2.7/
M2.7-highspeed are real current models; corrected the M3 description from the
PR's "512K" to the documented ~1M context):
- minimax provider package (OpenAI-compatible https://api.minimax.io/v1),
config.yml, models.yml, tests; MINIMAX_API_KEY/SERVER_URL/PROVIDER env vars;
ProviderMiniMax type + DefaultProviderNameMiniMax; providers.go wiring;
Valid() whitelist.
Added for completeness:
- goose migration adding 'minimax' to the PROVIDER_TYPE enum + database
ProviderTypeMinimax const.
- GraphQL: minimax in ProviderType enum, ProvidersModelsList,
ProvidersReadinessStatus, DefaultProvidersConfig; resolvers wire default
config/models + enabled status; gqlgen regenerated.
- Frontend: MiniMax icon (lobehub), provider-icon + settings-providers
registration + provider type list; regenerated GraphQL types.
- Installer wizard: provider form, screen, list, registry, env-var mappings,
locale strings + help text.
- ctester/ftester: -type/-provider minimax support.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds ModelReasoningInfo (mode + allowed efforts) to the GraphQL ModelConfig so
the frontend can gate the reasoning mode/effort UI by each model's declared
capability instead of a model-name regex. New ModelReasoningMode enum
(budget | adaptive | adaptive_only) mirrors the models.yml descriptor; the
converter maps pconfig adaptive-only -> GraphQL adaptive_only.
Backend groundwork for the Layer 2 frontend adaptive-thinking UI.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Integrates the backend half of PR #288 onto our branch (the frontend is
reworked separately in our codegen style), 3-way merged so the #233
config/models-path changes are preserved:
- adaptive_thinking.go: smithy Build middleware that rewrites the langchaingo
Converse body from thinking{type:enabled,budget_tokens} to
thinking{type:adaptive} + output_config.effort, wired via WithAPIOptions and
prepareCallOptions in Call/CallEx/CallWithTools.
- pconfig: ReasoningConfig.Mode (adaptive|budget) + EffectiveMode/IsZero.
- GraphQL: ReasoningMode enum, reasoning.mode field, xhigh/max effort levels.
Drops the dead llms.WithMetadata adaptive branch from AgentConfig.BuildOptions
(nothing reads opts.Metadata on the Bedrock path; adaptive is applied per-call
by the provider) and updates the unit test accordingly.
Hardening still pending (next commit): strip temperature/top_p/top_k and set
display:summarized for adaptive requests, add Opus 4.7/4.8 catalog entries with
a model reasoning-capability descriptor + force-adaptive backstop, and a live
Bedrock repro. Until then Opus 4.7 should not be selected for an agent.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reworks PR #233 to follow the existing config-path pattern and make an
externally-added Bedrock model fully usable from the web UI.
- BEDROCK_CONFIG_PATH: replace the embedded per-agent config (model
assignments + prices), mirroring OLLAMA_SERVER_CONFIG_PATH /
LLM_SERVER_CONFIG_PATH. DefaultProviderConfig now takes *config.Config
and reads the external file when set, else the embedded config.yml.
- BEDROCK_MODELS_PATH: merge an external model catalog onto the embedded
models.yml so new ids appear and are selectable under Settings ->
Providers. DefaultModels now takes *config.Config and the resolver +
provider construction pass it through; new ids are added, a matching
name overrides the embedded entry.
Wires both through docker-compose, .env.example, config.md and the README,
and ships examples/configs/bedrock-glm-flash.{provider,models}.yml using the
real AWS Bedrock id zai.glm-4.7-flash (In-Region, no inference-profile
prefix, 4K max output).
Dropped from #233: the ProviderConfig.Name field and the SeedDefaultProviders
mechanism (a per-user DB write fired on startup and inside the read-only
SettingsProviders resolver) -- the config already reaches the UI through
DefaultProvidersConfig without any DB rows.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rename a knowledge document via a dedicated mutation that rewrites only the
question in cmetadata — no re-embedding, no embedder required — mirroring the
flows renameFlow pattern instead of round-tripping the full document through
updateKnowledgeDocument.
Backend:
- renameKnowledgeDocument(id, question) mutation + resolver (admin/user split;
ownership enforced at GetUserDocument, like the update pair)
- metadata-only query UpdateKnowledgeDocumentMetadata (no migration)
- unit + edge tests: metadata-only, missing-doc error, non-owner rejection
Frontend:
- renameKnowledge provider method; wire list and detail inline-rename to it
- drop the content "Preview" column and request the list with withContent:false
so it no longer pulls full document bodies
Verified end to end against a local Docker backend (rename works; content and
embedding preserved) and against the remote backend (graceful failure where the
mutation is not yet deployed).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 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.
- 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.
- 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 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.
- 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 new endpoints for managing flow files, including listing, uploading, and deleting files within flow workspaces.
- Introduced FlowFile model to represent file metadata.
- Enhanced GraphQL schema to support flow file operations and subscriptions for real-time updates.
- Updated API documentation to reflect new flow file functionalities.
- Implemented a new SQL query to retrieve usage statistics by model and agents for a specific flow.
- Added corresponding Go types and methods to handle the new query in the database layer.
- Updated GraphQL schema to include the new ModelAgentsUsageStats type and the usageStatsByModelAgentsForFlow query.
- Enhanced frontend components to display the new usage statistics in the flow dashboard.
Adds conditional chain normalization in processChain to preserve reasoning cache when provider unchanged while fixing incomplete tool_calls and converting IDs when switching providers. Extends GraphQL API with modelProvider parameter for seamless provider changes without restart.
- Add Name field to ProviderConfig; YAML name: key sets the provider
name shown in the UI (e.g. glm_flash)
- Add SeedDefaultProviders to ProviderController: upserts the Bedrock
provider into the DB for all existing users at startup and lazily for
new users on their first Settings page visit
- Editing the YAML and restarting PentAGI automatically propagates new
values with no UI interaction required
- Simplify to a single BEDROCK_CONFIG_PATH variable: compose uses it as
the host-side volume mount path and translates it to the fixed
container path via :+ substitution, eliminating PENTAGI_BEDROCK_CONFIG_PATH
- Fix bedrock_test.go: pass &config.Config{} to DefaultProviderConfig
after its signature was updated to accept a config argument
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>