Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughRefactors deployment modes from a single "standalone" option into three modes: "memory" (in-memory SQLite with embedded services), "persistent" (file-backed SQLite with embedded services), and "distributed" (external services). Propagates mode through config, CLI, templates, infra initialization, and extensive tests. Changes
Sequence Diagram(s)sequenceDiagram
participant CLI as CLI / TUI
participant Form as Project Form
participant Template as Template Generator
participant Config as Config Resolver
CLI->>Form: open init form (may pass default mode)
Form->>Form: validate mode (memory/persistent/distributed)
Form->>Form: toggle Docker prompt based on mode
Form-->>CLI: return ProjectFormData{Mode}
CLI->>Template: Generate project with Mode in GenerateOptions
Template->>Config: build project config with Mode
Config-->>Template: return mode-specific settings (DB, Redis, Temporal)
Template->>Template: render mode-specific files (README, env, compozy.yaml)
Template-->>CLI: emit generated files (Docker included only when distributed)
sequenceDiagram
participant Server as Compozy Server
participant Mode as Mode Resolver
participant Cache as Cache Setup
participant Temporal as Embedded Temporal
Server->>Mode: resolve effective mode (component/global/default)
alt Embedded (memory/persistent)
Mode-->>Server: ModeMemory/ModePersistent
Server->>Cache: setupEmbeddedCache(persistence?)
Server->>Temporal: maybeStartEmbeddedTemporal(mode)
else Distributed
Mode-->>Server: ModeDistributed
Server->>Cache: connectExternalRedis()
Server->>Temporal: use external Temporal cluster
end
Cache-->>Server: ready
Temporal-->>Server: ready
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Areas requiring extra attention:
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
cli/cmd/start/start.go (1)
89-91: Fix nil cobraCmd preventing --mode flag processing in JSON mode.The function discards the received
cobraCmdparameter and passesniltohandleStartTUI. This preventsresolveStartMode(line 56) from processing the--modeflag, as it returns early whencobraCmd == nil(line 101-103). Users invoking the start command in JSON mode won't be able to override the mode via the--modeflag.Apply this diff to preserve the cobraCmd parameter:
-func handleStartJSON(ctx context.Context, _ *cobra.Command, executor *cmd.CommandExecutor, _ []string) error { - return handleStartTUI(ctx, nil, executor, nil) +func handleStartJSON(ctx context.Context, cobraCmd *cobra.Command, executor *cmd.CommandExecutor, args []string) error { + return handleStartTUI(ctx, cobraCmd, executor, args) }pkg/config/loader.go (1)
505-521: Update embedded Temporal error messagingThe errors still instruct users to set
mode=standalone, but that mode was just removed. When someone runs inmemoryorpersistentand forgets a required field, the message points them at an impossible fix. Please update these errors to reference the supported embedded modes (ModeMemory,ModePersistent) so the guidance matches the new behavior.Apply this diff to adjust the messaging:
@@ - return fmt.Errorf("temporal.standalone.bind_ip is required when mode=standalone") + return fmt.Errorf( + "temporal.standalone.bind_ip is required when temporal.mode is %q or %q", + ModeMemory, + ModePersistent, + ) @@ - return fmt.Errorf("temporal.standalone.namespace is required when mode=standalone") + return fmt.Errorf( + "temporal.standalone.namespace is required when temporal.mode is %q or %q", + ModeMemory, + ModePersistent, + ) @@ - return fmt.Errorf("temporal.standalone.cluster_name is required when mode=standalone") + return fmt.Errorf( + "temporal.standalone.cluster_name is required when temporal.mode is %q or %q", + ModeMemory, + ModePersistent, + )test/integration/store/operations_test.go (1)
239-256: Fix the data race in the concurrent user creation test.Each goroutine mutates
userIDs[index]without synchronization. Even though the indices differ, they still touch the same underlying slice, sogo test -racewill flag this as a data race and the values are not guaranteed. Gather the results on a channel (or guard the write) and updateuserIDsfrom the main goroutine instead.- errChan := make(chan error, numUsers) - for i := 0; i < numUsers; i++ { - go func(index int) { - userID := core.MustNewID() - userIDs[index] = userID - user := &model.User{ - ID: userID, - Email: fmt.Sprintf("user%d@example.com", index), - Role: model.RoleUser, - } - errChan <- authRepo.CreateUser(ctx, user) - }(i) - } - - for i := 0; i < numUsers; i++ { - err := <-errChan - require.NoError(t, err, "concurrent user creation should succeed") - } + type creationResult struct { + index int + id core.ID + err error + } + results := make(chan creationResult, numUsers) + for i := 0; i < numUsers; i++ { + go func(index int) { + userID := core.MustNewID() + user := &model.User{ + ID: userID, + Email: fmt.Sprintf("user%d@example.com", index), + Role: model.RoleUser, + } + results <- creationResult{ + index: index, + id: userID, + err: authRepo.CreateUser(ctx, user), + } + }(i) + } + + for i := 0; i < numUsers; i++ { + res := <-results + require.NoError(t, res.err, "concurrent user creation should succeed") + userIDs[res.index] = res.id + }test/helpers/server/server.go (1)
131-141: Do not drop the config dependency fromappstate.NewBaseDeps.
appstate.NewBaseDepsassumes a non-nil*config.Configand eagerly dereferences it to build repo factories, runtime knobs, and middleware state. Passingnilhere regresses every harness boot with a nil-pointer panic insideappstate.NewState. Keep threading the loaded config through this helper.Apply this diff:
- state, store := buildApplicationState(t, proj, provider) + state, store := buildApplicationState(t, cfg, proj, provider) @@ -func buildApplicationState( - t *testing.T, - proj *project.Config, - provider *repo.Provider, -) (*appstate.State, resources.ResourceStore) { - deps := appstate.NewBaseDeps(proj, nil, provider, nil) +func buildApplicationState( + t *testing.T, + cfg *config.Config, + proj *project.Config, + provider *repo.Provider, +) (*appstate.State, resources.ResourceStore) { + deps := appstate.NewBaseDeps(proj, cfg, provider, nil)scripts/markdown/check.go (1)
1184-1193: Batching now splits per issue instead of per file (regression)
createIssueBatchesnow chunks the flattened issue list bybatchSize, so with the default--batch-size=1every individual issue becomes its own job. Files with multiple unresolved issues now get split across multiple prompts, which defeats the “file group” batching described in the CLI help and was previously guaranteed by the per-file grouping logic. This is a blocking behavioral regression because the generated prompts no longer contain the full context for a file.Please restore batching to operate on distinct
codeFilegroups (keeping all issues for a file together) before applying the batch-size cap. One way is to derive an ordered list of code files fromp.collected, then accumulate whole groups until you reach the requested batch size:func (p *promptPreparationFSM) groupEntries() error { - p.batches = createIssueBatches(p.collected, p.cfg.batchSize) - if len(p.batches) == 0 { - return p.fail(fmt.Errorf("no batches created for prompt preparation")) - } - return p.transition(prepEventGrouped) + batches, err := createIssueBatchesByGroup(p.collected, p.cfg.groups, p.cfg.batchSize) + if err != nil { + return p.fail(err) + } + p.batches = batches + return p.transition(prepEventGrouped) } @@ -func createIssueBatches(allIssues []issueEntry, batchSize int) [][]issueEntry { - batches := make([][]issueEntry, 0) - for i := 0; i < len(allIssues); i += batchSize { - end := i + batchSize - if end > len(allIssues) { - end = len(allIssues) - } - batches = append(batches, allIssues[i:end]) - } - return batches +func createIssueBatchesByGroup( + orderedIssues []issueEntry, + groups map[string][]issueEntry, + batchSize int, +) ([][]issueEntry, error) { + if batchSize <= 0 { + batchSize = 1 + } + orderedFiles := make([]string, 0, len(groups)) + seen := make(map[string]struct{}, len(groups)) + for _, issue := range orderedIssues { + if _, ok := seen[issue.codeFile]; ok { + continue + } + orderedFiles = append(orderedFiles, issue.codeFile) + seen[issue.codeFile] = struct{}{} + } + batches := make([][]issueEntry, 0, len(orderedFiles)) + var ( + current []issueEntry + currentFiles int + ) + for _, codeFile := range orderedFiles { + issues := groups[codeFile] + current = append(current, issues...) + currentFiles++ + if currentFiles == batchSize { + batches = append(batches, current) + current = nil + currentFiles = 0 + } + } + if len(current) > 0 { + batches = append(batches, current) + } + if len(batches) == 0 { + return nil, fmt.Errorf("no batches created for prompt preparation") + } + return batches, nil }This keeps all issues for a file together and preserves the documented meaning of
--batch-size.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (110)
cli/help/global-flags.mdis excluded by!**/*.mddocs/content/docs/configuration/mode-configuration.mdxis excluded by!**/*.mdxdocs/content/docs/configuration/redis.mdxis excluded by!**/*.mdxdocs/content/docs/deployment/distributed-mode.mdxis excluded by!**/*.mdxdocs/content/docs/deployment/memory-mode.mdxis excluded by!**/*.mdxdocs/content/docs/deployment/meta.jsonis excluded by!**/*.jsondocs/content/docs/deployment/persistent-mode.mdxis excluded by!**/*.mdxdocs/content/docs/deployment/standalone-mode.mdxis excluded by!**/*.mdxdocs/content/docs/examples/distributed-mode.mdxis excluded by!**/*.mdxdocs/content/docs/examples/index.mdxis excluded by!**/*.mdxdocs/content/docs/examples/memory-mode.mdxis excluded by!**/*.mdxdocs/content/docs/examples/meta.jsonis excluded by!**/*.jsondocs/content/docs/examples/persistent-mode.mdxis excluded by!**/*.mdxdocs/content/docs/guides/meta.jsonis excluded by!**/*.jsondocs/content/docs/guides/migrate-standalone-to-distributed.mdxis excluded by!**/*.mdxdocs/content/docs/guides/mode-migration-guide.mdxis excluded by!**/*.mdxdocs/content/docs/meta.jsonis excluded by!**/*.jsondocs/content/docs/quick-start/index.mdxis excluded by!**/*.mdxdocs/swagger.jsonis excluded by!**/*.json,!docs/swagger.*docs/swagger.yamlis excluded by!**/*.yaml,!docs/swagger.*examples/README.mdis excluded by!**/*.mdexamples/configs/distributed-mode.yamlis excluded by!**/*.yamlexamples/configs/memory-mode.yamlis excluded by!**/*.yamlexamples/configs/persistent-mode.yamlis excluded by!**/*.yamlexamples/configs/workflows/echo.yamlis excluded by!**/*.yamlexamples/configs/workflows/summarize.yamlis excluded by!**/*.yamlexamples/configs/workflows/support-router.yamlis excluded by!**/*.yamlexamples/distributed-mode/README.mdis excluded by!**/*.mdexamples/distributed-mode/compozy.yamlis excluded by!**/*.yamlexamples/distributed-mode/docker-compose.ymlis excluded by!**/*.ymlexamples/distributed-mode/workflow.yamlis excluded by!**/*.yamlexamples/memory-mode/README.mdis excluded by!**/*.mdexamples/memory-mode/compozy.yamlis excluded by!**/*.yamlexamples/memory-mode/workflow.yamlis excluded by!**/*.yamlexamples/persistent-mode/README.mdis excluded by!**/*.mdexamples/persistent-mode/compozy.yamlis excluded by!**/*.yamlexamples/persistent-mode/workflow.yamlis excluded by!**/*.yamlexamples/standalone/README.mdis excluded by!**/*.mdexamples/standalone/compozy.yamlis excluded by!**/*.yamlexamples/standalone/workflow.yamlis excluded by!**/*.yamlpkg/template/README.mdis excluded by!**/*.mdschemas/agent.jsonis excluded by!**/*.jsonschemas/cache.jsonis excluded by!**/*.jsonschemas/compozy.jsonis excluded by!**/*.jsonschemas/config-cli.jsonis excluded by!**/*.jsonschemas/config-database.jsonis excluded by!**/*.jsonschemas/config-knowledge.jsonis excluded by!**/*.jsonschemas/config-llm.jsonis excluded by!**/*.jsonschemas/config-mcpproxy.jsonis excluded by!**/*.jsonschemas/config-redis.jsonis excluded by!**/*.jsonschemas/config-server.jsonis excluded by!**/*.jsonschemas/config-temporal.jsonis excluded by!**/*.jsonschemas/config.jsonis excluded by!**/*.jsonschemas/project.jsonis excluded by!**/*.jsonschemas/provider.jsonis excluded by!**/*.jsonschemas/runtime.jsonis excluded by!**/*.jsonschemas/task.jsonis excluded by!**/*.jsonschemas/vectordb.jsonis excluded by!**/*.jsontasks/prd-modes/_task_1.mdis excluded by!**/*.mdtasks/prd-modes/_task_10.mdis excluded by!**/*.mdtasks/prd-modes/_task_11.mdis excluded by!**/*.mdtasks/prd-modes/_task_12.mdis excluded by!**/*.mdtasks/prd-modes/_task_13.mdis excluded by!**/*.mdtasks/prd-modes/_task_14.mdis excluded by!**/*.mdtasks/prd-modes/_task_15.mdis excluded by!**/*.mdtasks/prd-modes/_task_16.mdis excluded by!**/*.mdtasks/prd-modes/_task_17.mdis excluded by!**/*.mdtasks/prd-modes/_task_18.mdis excluded by!**/*.mdtasks/prd-modes/_task_19.mdis excluded by!**/*.mdtasks/prd-modes/_task_2.mdis excluded by!**/*.mdtasks/prd-modes/_task_20.mdis excluded by!**/*.mdtasks/prd-modes/_task_21.mdis excluded by!**/*.mdtasks/prd-modes/_task_22.mdis excluded by!**/*.mdtasks/prd-modes/_task_23.0.mdis excluded by!**/*.mdtasks/prd-modes/_task_24.0.mdis excluded by!**/*.mdtasks/prd-modes/_task_25.0.mdis excluded by!**/*.mdtasks/prd-modes/_task_26.0.mdis excluded by!**/*.mdtasks/prd-modes/_task_27.mdis excluded by!**/*.mdtasks/prd-modes/_task_28.mdis excluded by!**/*.mdtasks/prd-modes/_task_29.mdis excluded by!**/*.mdtasks/prd-modes/_task_3.mdis excluded by!**/*.mdtasks/prd-modes/_task_4.mdis excluded by!**/*.mdtasks/prd-modes/_task_5.mdis excluded by!**/*.mdtasks/prd-modes/_task_6.mdis excluded by!**/*.mdtasks/prd-modes/_task_7.mdis excluded by!**/*.mdtasks/prd-modes/_task_8.0.mdis excluded by!**/*.mdtasks/prd-modes/_task_8.mdis excluded by!**/*.mdtasks/prd-modes/_task_9.mdis excluded by!**/*.mdtasks/prd-modes/_tasks.mdis excluded by!**/*.mdtasks/prd-modes/_techspec.mdis excluded by!**/*.mdtasks/prd-redis/_docs.mdis excluded by!**/*.mdtasks/prd-redis/_examples.mdis excluded by!**/*.mdtasks/prd-redis/_prd.mdis excluded by!**/*.mdtasks/prd-redis/_task_01.mdis excluded by!**/*.mdtasks/prd-redis/_task_02.mdis excluded by!**/*.mdtasks/prd-redis/_task_03.mdis excluded by!**/*.mdtasks/prd-redis/_task_04.mdis excluded by!**/*.mdtasks/prd-redis/_task_05.mdis excluded by!**/*.mdtasks/prd-redis/_task_06.mdis excluded by!**/*.mdtasks/prd-redis/_task_07.mdis excluded by!**/*.mdtasks/prd-redis/_task_08.mdis excluded by!**/*.mdtasks/prd-redis/_task_09.mdis excluded by!**/*.mdtasks/prd-redis/_task_10.mdis excluded by!**/*.mdtasks/prd-redis/_task_11.mdis excluded by!**/*.mdtasks/prd-redis/_task_12.mdis excluded by!**/*.mdtasks/prd-redis/_task_13.mdis excluded by!**/*.mdtasks/prd-redis/_tasks.mdis excluded by!**/*.mdtasks/prd-redis/_techspec.mdis excluded by!**/*.mdtasks/prd-redis/_tests.mdis excluded by!**/*.mdtest/integration/README.mdis excluded by!**/*.md
📒 Files selected for processing (63)
cli/cmd/config/config_test.go(5 hunks)cli/cmd/init/components/project_form.go(5 hunks)cli/cmd/init/init.go(12 hunks)cli/cmd/start/start.go(2 hunks)cli/cmd/start/start_test.go(2 hunks)cli/helpers/flag_categories.go(1 hunks)docs/docs.go(12 hunks)engine/infra/cache/miniredis_standalone.go(1 hunks)engine/infra/cache/mod.go(3 hunks)engine/infra/cache/mod_test.go(2 hunks)engine/infra/postgres/migrations.go(3 hunks)engine/infra/postgres/taskrepo.go(1 hunks)engine/infra/server/dependencies.go(5 hunks)engine/infra/server/dependencies_test.go(1 hunks)engine/infra/server/mcp.go(3 hunks)engine/infra/server/mcp_test.go(2 hunks)engine/infra/server/server.go(2 hunks)engine/infra/sqlite/migrations.go(2 hunks)engine/infra/sqlite/migrations/20250603124915_create_task_states.sql(1 hunks)engine/infra/sqlite/taskrepo.go(3 hunks)engine/worker/embedded/namespace.go(1 hunks)examples/distributed-mode/.env.example(1 hunks)examples/memory-mode/.env.example(1 hunks)examples/memory-mode/api.http(1 hunks)examples/memory-mode/edge-deployment/Dockerfile.edge(1 hunks)examples/persistent-mode/.env.example(1 hunks)examples/standalone/.env.example(0 hunks)pkg/config/config.go(9 hunks)pkg/config/config_test.go(12 hunks)pkg/config/definition/schema.go(6 hunks)pkg/config/loader.go(7 hunks)pkg/config/loader_test.go(4 hunks)pkg/config/resolver.go(4 hunks)pkg/config/resolver_test.go(1 hunks)pkg/template/generator.go(3 hunks)pkg/template/service.go(2 hunks)pkg/template/templates/basic/README.md.tmpl(1 hunks)pkg/template/templates/basic/basic.go(4 hunks)pkg/template/templates/basic/basic_test.go(1 hunks)pkg/template/templates/basic/compozy.yaml.tmpl(1 hunks)pkg/template/templates/basic/env.example.tmpl(1 hunks)pkg/template/templates/basic/gitignore.tmpl(1 hunks)pkg/template/types.go(2 hunks)pkg/template/types_test.go(1 hunks)scripts/markdown/check.go(29 hunks)test/helpers/database.go(4 hunks)test/helpers/database_test.go(2 hunks)test/helpers/repo.go(1 hunks)test/helpers/server/server.go(4 hunks)test/integration/cache/adapter_contract_test.go(1 hunks)test/integration/database/multi_driver_test.go(2 hunks)test/integration/database/sqlite_specific_test.go(1 hunks)test/integration/repo/repo_test_helpers.go(1 hunks)test/integration/repo/task_test.go(0 hunks)test/integration/repo/workflow_test.go(0 hunks)test/integration/server/executions_integration_test.go(2 hunks)test/integration/server/mcp_health_test.go(1 hunks)test/integration/standalone/helpers.go(4 hunks)test/integration/standalone/workflow_test.go(2 hunks)test/integration/store/operations_test.go(6 hunks)test/integration/tasks/basic/response_handler_test.go(2 hunks)test/integration/tasks/core/concurrent_test.go(1 hunks)test/integration/tasks/helpers/setup.go(2 hunks)
💤 Files with no reviewable changes (3)
- examples/standalone/.env.example
- test/integration/repo/workflow_test.go
- test/integration/repo/task_test.go
🧰 Additional context used
📓 Path-based instructions (20)
**/*.go
📄 CodeRabbit inference engine (.cursor/rules/api-standards.mdc)
**/*.go: Return properly structured error responses
Use middleware for cross-cutting concerns (e.g., logging, auth, rate limiting)
Implement proper authentication and authorization in the API
Apply rate limiting and request validation
Version API routes under the prefix /api/v0/
Use gin-gonic/gin for HTTP APIs
Ensure consistent response formats across all endpoints
Use appropriate HTTP status codes (200, 201, 400, 401, 403, 404, 500)
Return JSON responses with a consistent error structure
Update Swagger annotations for all API changes
Generate Swagger docs served at /swagger/index.html using swaggo/swag
Include request and response examples in Swagger annotations
Document all parameters, headers, and error responses in Swagger
Success response body should contain fields: data and message ("Success")
Error response body should contain fields: error and details
**/*.go: Retrieve the logger via logger.FromContext(ctx) inside runtime code (handlers, services, workers)
Retrieve configuration via config.FromContext(ctx) inside runtime code (handlers, services, workers)
Attach *config.Manager at process edges using config.ContextWithManager(ctx, mgr)
Build the logger with logger.SetupLogger(...) at startup and attach with logger.ContextWithLogger(ctx, log)
For HTTP servers, ensure request contexts inherit BOTH manager and logger via middleware
Do not pass loggers via function parameters or dependency injection; always use context-backed retrieval
Do not use a global configuration singleton; read config from context
CLI/root flow: parse flags → construct sources → mgr.Load(...) → attach manager to ctx → setup logger honoring cfg.CLI.Debug/Quiet → attach logger to ctx → propagate ctx
Server startup should use the CLI-provided ctx and add middleware that sets c.Request = c.Request.WithContext(logger.ContextWithLogger(config.ContextWithManager(c.Request.Context(), mgr), log))
Optionally set http.Server.BaseContext to a parent context carrying manager and logger so all req...
Files:
engine/infra/postgres/taskrepo.gopkg/template/service.goengine/infra/cache/miniredis_standalone.gotest/integration/database/multi_driver_test.goengine/worker/embedded/namespace.goengine/infra/sqlite/migrations.gocli/cmd/start/start_test.goengine/infra/postgres/migrations.gopkg/config/resolver.goengine/infra/server/mcp_test.gocli/helpers/flag_categories.goengine/infra/sqlite/taskrepo.gopkg/config/loader_test.gopkg/template/templates/basic/basic_test.goengine/infra/server/dependencies_test.godocs/docs.gotest/integration/standalone/workflow_test.gocli/cmd/config/config_test.goengine/infra/server/dependencies.gopkg/template/types_test.gotest/integration/store/operations_test.gopkg/template/generator.gopkg/config/config.gopkg/config/resolver_test.gotest/integration/repo/repo_test_helpers.gotest/integration/cache/adapter_contract_test.goengine/infra/cache/mod.gotest/integration/server/mcp_health_test.goscripts/markdown/check.gotest/integration/standalone/helpers.goengine/infra/cache/mod_test.gotest/integration/server/executions_integration_test.gotest/helpers/database_test.goengine/infra/server/mcp.gotest/integration/tasks/basic/response_handler_test.gopkg/template/types.goengine/infra/server/server.gotest/helpers/repo.gopkg/config/loader.gopkg/template/templates/basic/basic.gocli/cmd/init/components/project_form.gotest/integration/tasks/core/concurrent_test.gocli/cmd/start/start.gotest/helpers/database.gocli/cmd/init/init.gotest/helpers/server/server.gopkg/config/config_test.gotest/integration/tasks/helpers/setup.gotest/integration/database/sqlite_specific_test.gopkg/config/definition/schema.go
**/!(*_test).go
📄 CodeRabbit inference engine (.cursor/rules/magic-numbers.mdc)
**/!(*_test).go: NEVER introduce magic numbers in runtime Go code; replace unexplained numeric literals with named constants or configuration
Operator-tunable values MUST be sourced from configuration as defined in @.cursor/rules/global-config.mdc
Fetch configuration via config.FromContext(ctx); do not use global singletons
Promote tunable values (timeouts, deadlines, polling intervals, retry/backoff counts and factors, concurrency limits, queue sizes, buffer/payload limits, behavior thresholds) to configurationIn runtime code, properly inherit context; never use context.Background() in code paths
In runtime code paths, inherit context properly; never use context.Background()
In runtime code paths, never use context.Background(); properly inherit context
In runtime code, properly inherit context; never use context.Background()
Files:
engine/infra/postgres/taskrepo.gopkg/template/service.goengine/infra/cache/miniredis_standalone.goengine/worker/embedded/namespace.goengine/infra/sqlite/migrations.goengine/infra/postgres/migrations.gopkg/config/resolver.gocli/helpers/flag_categories.goengine/infra/sqlite/taskrepo.godocs/docs.goengine/infra/server/dependencies.gopkg/template/generator.gopkg/config/config.gotest/integration/repo/repo_test_helpers.goengine/infra/cache/mod.goscripts/markdown/check.gotest/integration/standalone/helpers.goengine/infra/server/mcp.gopkg/template/types.goengine/infra/server/server.gotest/helpers/repo.gopkg/config/loader.gopkg/template/templates/basic/basic.gocli/cmd/init/components/project_form.gocli/cmd/start/start.gotest/helpers/database.gocli/cmd/init/init.gotest/helpers/server/server.gotest/integration/tasks/helpers/setup.gopkg/config/definition/schema.go
engine/infra/**/*.go
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
engine/infra/**/*.go: Infrastructure Layer (engine/infra): implement adapters for DB, cache, HTTP, storage, monitoring; must implement Application Layer interfaces
Adapter implementations belong in Infrastructure Layer and must implement Application Layer interfaces (no business logic leakage)
Infrastructure depends inward: Infrastructure → Application → Domain; avoid imports from cli and cross-infra coupling
Files:
engine/infra/postgres/taskrepo.goengine/infra/cache/miniredis_standalone.goengine/infra/sqlite/migrations.goengine/infra/postgres/migrations.goengine/infra/server/mcp_test.goengine/infra/sqlite/taskrepo.goengine/infra/server/dependencies_test.goengine/infra/server/dependencies.goengine/infra/cache/mod.goengine/infra/cache/mod_test.goengine/infra/server/mcp.goengine/infra/server/server.go
{engine,pkg,cli}/**/*.go
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
Context as the first parameter for I/O or long-running operations; always propagate and handle cancellation
Files:
engine/infra/postgres/taskrepo.gopkg/template/service.goengine/infra/cache/miniredis_standalone.goengine/worker/embedded/namespace.goengine/infra/sqlite/migrations.gocli/cmd/start/start_test.goengine/infra/postgres/migrations.gopkg/config/resolver.goengine/infra/server/mcp_test.gocli/helpers/flag_categories.goengine/infra/sqlite/taskrepo.gopkg/config/loader_test.gopkg/template/templates/basic/basic_test.goengine/infra/server/dependencies_test.gocli/cmd/config/config_test.goengine/infra/server/dependencies.gopkg/template/types_test.gopkg/template/generator.gopkg/config/config.gopkg/config/resolver_test.goengine/infra/cache/mod.goengine/infra/cache/mod_test.goengine/infra/server/mcp.gopkg/template/types.goengine/infra/server/server.gopkg/config/loader.gopkg/template/templates/basic/basic.gocli/cmd/init/components/project_form.gocli/cmd/start/start.gocli/cmd/init/init.gopkg/config/config_test.gopkg/config/definition/schema.go
pkg/**/*.go
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
Shared Packages (pkg): provide framework-level utilities (config, logging, templates, schema generation); must not contain business logic
Files:
pkg/template/service.gopkg/config/resolver.gopkg/config/loader_test.gopkg/template/templates/basic/basic_test.gopkg/template/types_test.gopkg/template/generator.gopkg/config/config.gopkg/config/resolver_test.gopkg/template/types.gopkg/config/loader.gopkg/template/templates/basic/basic.gopkg/config/config_test.gopkg/config/definition/schema.go
**/*_test.go
📄 CodeRabbit inference engine (.cursor/rules/logger-config.mdc)
**/*_test.go: In tests, set up configuration with config.Initialize or config.NewManager(...).Load(...) and attach via config.ContextWithManager
In tests, prefer logger.NewForTests() and attach with logger.ContextWithLogger
In tests, mock or stub external tools/services; do not introduce DI of logger/config into code under test
**/*_test.go: Prefer local test constants (e.g., const testTimeout = 5 * time.Second) in tests
Inline trivial literals in tests when intent is clear
Do not duplicate production constants in tests; import them or assert relative behavior
**/*_test.go: All tests pass and follow the established testing patterns
Code is well-tested with both unit and integration tests
Tests should follow the t.Run("Should...") subtest naming pattern
Ensure adequate test coverage
**/*_test.go: All Go tests must use t.Run("Should describe behavior", ...) subtests for each behavior
Use stretchr/testify for assertions and mocks in tests
Do not use testify suite patterns (no suite.Suite embedding or suite-based structures)
Do not use suite methods like s.Equal(), s.NoError(), or s.T()
Avoid weak assertions like assert.Error(t, err); use specific error validation instead
Prefer specific error assertions like assert.ErrorContains and assert.ErrorAs for validating errors
Unit tests should be placed alongside implementation files as *_test.go
Use testify/mock for mocking external dependencies or complex interfacesIn tests, never use context.Background(); use t.Context() instead
Aim for 80%+ test coverage on business logic; write focused, isolated tests
**/*_test.go: Use stretchr/testify for assertions and mocks; import as github.com/stretchr/testify/assert and github.com/stretchr/testify/mock; replace custom mocks with testify/mock
Use project test helpers (utils.SetupTest, utils.SetupFixture, etc.) in testsIn tests, never use context.Background(); use t.Context()
Files:
test/integration/database/multi_driver_test.gocli/cmd/start/start_test.goengine/infra/server/mcp_test.gopkg/config/loader_test.gopkg/template/templates/basic/basic_test.goengine/infra/server/dependencies_test.gotest/integration/standalone/workflow_test.gocli/cmd/config/config_test.gopkg/template/types_test.gotest/integration/store/operations_test.gopkg/config/resolver_test.gotest/integration/cache/adapter_contract_test.gotest/integration/server/mcp_health_test.goengine/infra/cache/mod_test.gotest/integration/server/executions_integration_test.gotest/helpers/database_test.gotest/integration/tasks/basic/response_handler_test.gotest/integration/tasks/core/concurrent_test.gopkg/config/config_test.gotest/integration/database/sqlite_specific_test.go
test/integration/**/*_test.go
📄 CodeRabbit inference engine (.cursor/rules/test-standards.mdc)
Integration tests must reside under test/integration/
Files:
test/integration/database/multi_driver_test.gotest/integration/standalone/workflow_test.gotest/integration/store/operations_test.gotest/integration/cache/adapter_contract_test.gotest/integration/server/mcp_health_test.gotest/integration/server/executions_integration_test.gotest/integration/tasks/basic/response_handler_test.gotest/integration/tasks/core/concurrent_test.gotest/integration/database/sqlite_specific_test.go
test/integration/**/*.go
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
Place integration tests under test/integration; keep them exercising cross-component behavior
Files:
test/integration/database/multi_driver_test.gotest/integration/standalone/workflow_test.gotest/integration/store/operations_test.gotest/integration/repo/repo_test_helpers.gotest/integration/cache/adapter_contract_test.gotest/integration/server/mcp_health_test.gotest/integration/standalone/helpers.gotest/integration/server/executions_integration_test.gotest/integration/tasks/basic/response_handler_test.gotest/integration/tasks/core/concurrent_test.gotest/integration/tasks/helpers/setup.gotest/integration/database/sqlite_specific_test.go
engine/{agent,task,task2,tool,workflow,runtime,llm,memory,memorycfg,knowledge,model,mcp,webhook,attachment,resources,auth,autoload,project,schema,worker}/**/*.go
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
engine/{agent,task,task2,tool,workflow,runtime,llm,memory,memorycfg,knowledge,model,mcp,webhook,attachment,resources,auth,autoload,project,schema,worker}/**/*.go: Application Layer (engine/): implement domain-specific business logic and ports; organize by domain with uc/ and router/ subpackages
Port interfaces (e.g., repositories, external services) are defined in Application Layer packages where they are used
Application layer depends inward: Application → Domain; avoid depending on infrastructure
Files:
engine/worker/embedded/namespace.go
cli/**/*.go
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
cli/**/*.go: Presentation Layer (cli): implement CLI, user interaction/formatting, and API client; no business logic
CLI depends inward: CLI → Application → Domain; do not depend directly on infrastructure
Files:
cli/cmd/start/start_test.gocli/helpers/flag_categories.gocli/cmd/config/config_test.gocli/cmd/init/components/project_form.gocli/cmd/start/start.gocli/cmd/init/init.go
pkg/config/**/*.go
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
Global configuration resides in pkg/config; expose retrieval via context (config.FromContext) and provide defaults; avoid global singletons
Files:
pkg/config/resolver.gopkg/config/loader_test.gopkg/config/config.gopkg/config/resolver_test.gopkg/config/loader.gopkg/config/config_test.gopkg/config/definition/schema.go
cli/helpers/flag_categories.go
📄 CodeRabbit inference engine (.cursor/rules/global-config.mdc)
cli/helpers/flag_categories.go: Categorize new CLI flags by adding their names to the appropriate category in flag_categories.go for better help UX
For new categories, add a category block or include flags in an existing category in flag_categories.goEnvironment variable overrides follow ATTACHMENTS_* naming (e.g., ATTACHMENTS_DOWNLOAD_TIMEOUT); ensure mapping from flags to env vars uses this prefix
Files:
cli/helpers/flag_categories.go
pkg/config/**/*_test.go
📄 CodeRabbit inference engine (.cursor/rules/global-config.mdc)
Add or extend tests under pkg/config/*_test.go when introducing validation or complex defaults
Files:
pkg/config/loader_test.gopkg/config/resolver_test.gopkg/config/config_test.go
docs/**/*.go
📄 CodeRabbit inference engine (docs/.cursor/rules/review-checklist.mdc)
docs/**/*.go: Code must be formatted withgo fmt
All linter warnings must be addressed
Error handling must follow project patterns
Security considerations must be addressed (e.g., no exposed secrets or unvalidated inputs)
Errors must be handled appropriately and with context
Interfaces must be used appropriately to define behavior
Code must pass all linter checks
Code must be secure and performant
Dependencies must be injected properly
Context must be propagated correctly
Hardcoded values that should be configurable must be avoided
Missing context propagation in functions that make external calls must be addressed
Performance issues like unnecessary allocations or inefficient algorithms must be avoided
docs/**/*.go: Use section comments with dashes for visual separation in Go code, formatted as:
// -----------------------------------------------------------------------------
// Section Name
// -----------------------------------------------------------------------------
Files:
docs/docs.go
pkg/config/config.go
📄 CodeRabbit inference engine (.cursor/rules/global-config.mdc)
pkg/config/config.go: Add the new field to the typed config struct with tags: koanf/json/yaml/mapstructure; include env tag when applicable; add validate tag if needed; use SensitiveString or sensitive:"true" for secrets
Map from registry to typed struct in buildConfig using getString/getInt/getBool/getDuration/getInt64/getStringSlice
For secrets, prefer SensitiveString type or sensitive:"true" tag to enable automatic JSON redaction
When creating a new category, define typeConfig struct with full tagging and validation
Add the new section to the root Config with koanf/json/yaml/mapstructure tags
Implement buildConfig(registry *definition.Registry) to map defaults from the registry to the typed struct
Always include koanf, json, yaml, and mapstructure tags on config struct fields; include env when applicable
Files:
pkg/config/config.go
{pkg/config/config.go,pkg/config/definition/schema.go}
📄 CodeRabbit inference engine (.cursor/rules/global-config.mdc)
Environment variable names must be UPPER_SNAKE_CASE with domain prefixes (e.g., SERVER_, DB_, RUNTIME_, CLI uses COMPOZY_)
Files:
pkg/config/config.gopkg/config/definition/schema.go
{compozy.yaml,examples/**/compozy.yaml,pkg/template/templates/**/compozy.yaml.tmpl}
📄 CodeRabbit inference engine (.cursor/rules/compozy/llm-providers.mdc)
{compozy.yaml,examples/**/compozy.yaml,pkg/template/templates/**/compozy.yaml.tmpl}: Define LLM providers under models in Compozy configuration files, not elsewhere
Each models entry must include required fields: provider and model (schemas/provider.json#ProviderConfig)
Use environment or secrets templates for api_key (e.g., "{{ .env.OPENAI_API_KEY }}"); do not hardcode API keys
Provider name must be one of: openai, anthropic, google, groq, ollama, deepseek, xai, mock
For provider: anthropic, do not set organization (unsupported)
For provider: google, do not set api_url or organization (not supported)
For provider: ollama (local), include api_url (e.g., http://localhost:11434); api_key is not required
Consider setting cost-control params under params (e.g., max_tokens, temperature) for expensive models
Use provider-appropriate features only (e.g., structured outputs and organization for OpenAI; avoid unsupported combinations)
Files:
pkg/template/templates/basic/compozy.yaml.tmpl
test/helpers/**
📄 CodeRabbit inference engine (.cursor/rules/test-standards.mdc)
Use test/helpers/ for shared test utilities and reusable helpers
Files:
test/helpers/database_test.gotest/helpers/repo.gotest/helpers/database.gotest/helpers/server/server.go
pkg/config/loader.go
📄 CodeRabbit inference engine (.cursor/rules/global-config.mdc)
pkg/config/loader.go: Implement cross-field validation in validateCustom when struct tag validation is insufficient
Extend validateCustom for cross-field constraints in new categories when struct tags are insufficient
Files:
pkg/config/loader.go
pkg/config/definition/schema.go
📄 CodeRabbit inference engine (.cursor/rules/global-config.mdc)
pkg/config/definition/schema.go: Use pkg/config/definition/schema.go as the single source of truth for configuration by registering fields in the registry
Add new property by registering it with registry.Register(&FieldDef{Path, Default, CLIFlag, EnvVar, Type, Help}); keep path namingcategory.property_name(snake_case)
Register all fields of a new category in registerFields and include it in CreateRegistry()
Config path format must be section.snake_case_property when registering fields
CLI flags in registry must use kebab-case (CLIFlag)
Durations should use time.Duration and defaults in the registry must be time.Duration values
Files:
pkg/config/definition/schema.go
🧬 Code graph analysis (41)
engine/infra/postgres/taskrepo.go (1)
engine/task/domain.go (2)
ExecutionType(18-18)ExecutionBasic(21-21)
pkg/template/service.go (2)
cli/tui/models/base.go (1)
Mode(10-10)pkg/template/types.go (2)
DefaultMode(12-12)ValidateMode(70-82)
test/integration/database/multi_driver_test.go (1)
test/helpers/database.go (2)
SetupPostgresContainer(426-429)SetupTestDatabase(406-421)
cli/cmd/start/start_test.go (1)
pkg/config/config.go (1)
SourceDefault(2013-2013)
pkg/config/resolver.go (1)
pkg/config/config.go (1)
Config(58-148)
engine/infra/server/mcp_test.go (1)
pkg/config/resolver.go (2)
ModeMemory(7-7)ModeDistributed(9-9)
engine/infra/sqlite/taskrepo.go (1)
engine/task/domain.go (2)
ExecutionType(18-18)ExecutionBasic(21-21)
pkg/config/loader_test.go (3)
pkg/config/resolver.go (3)
ModeMemory(7-7)ModePersistent(8-8)ModeDistributed(9-9)pkg/config/loader.go (1)
NewService(54-67)pkg/config/config.go (1)
Default(2023-2025)
pkg/template/templates/basic/basic_test.go (4)
pkg/template/templates/basic/basic.go (1)
Template(39-39)pkg/template/types.go (1)
GenerateOptions(57-67)pkg/template/service.go (1)
GetService(23-31)pkg/logger/mod.go (2)
ContextWithLogger(39-41)NewForTests(199-201)
test/integration/standalone/workflow_test.go (1)
test/integration/standalone/helpers.go (1)
SetupMemoryTestEnv(57-95)
cli/cmd/config/config_test.go (2)
pkg/logger/mod.go (2)
ContextWithLogger(39-41)NewForTests(199-201)pkg/config/resolver.go (3)
ModeMemory(7-7)ModeDistributed(9-9)ModePersistent(8-8)
engine/infra/server/dependencies.go (3)
pkg/config/resolver.go (2)
ModeMemory(7-7)ModePersistent(8-8)pkg/config/config.go (1)
Config(58-148)engine/worker/embedded/config.go (1)
Config(34-67)
pkg/template/types_test.go (1)
pkg/template/types.go (1)
ValidateMode(70-82)
test/integration/store/operations_test.go (3)
test/helpers/database.go (1)
SetupTestDatabase(406-421)engine/infra/postgres/taskrepo.go (1)
NewTaskRepo(91-93)engine/infra/sqlite/taskrepo.go (1)
NewTaskRepo(70-72)
pkg/template/generator.go (1)
cli/tui/models/base.go (1)
Mode(10-10)
pkg/config/config.go (1)
pkg/config/resolver.go (2)
ModeMemory(7-7)ModePersistent(8-8)
pkg/config/resolver_test.go (2)
pkg/config/resolver.go (5)
ModeDistributed(9-9)ModeMemory(7-7)ModePersistent(8-8)ModeRemoteTemporal(11-11)ResolveMode(20-28)pkg/config/config.go (5)
Config(58-148)RedisConfig(1322-1434)TemporalConfig(550-586)MCPProxyConfig(1711-1759)DatabaseConfig(310-425)
test/integration/repo/repo_test_helpers.go (1)
test/helpers/repo.go (1)
SetupTestRepos(14-28)
test/integration/cache/adapter_contract_test.go (1)
pkg/config/resolver.go (1)
ModePersistent(8-8)
engine/infra/cache/mod.go (2)
pkg/config/resolver.go (3)
ModeMemory(7-7)ModePersistent(8-8)ModeDistributed(9-9)pkg/config/config.go (2)
RedisConfig(1322-1434)Config(58-148)
test/integration/standalone/helpers.go (2)
cli/tui/models/base.go (1)
Mode(10-10)pkg/config/resolver.go (1)
ModeMemory(7-7)
engine/infra/cache/mod_test.go (5)
pkg/logger/mod.go (2)
ContextWithLogger(39-41)NewForTests(199-201)pkg/config/provider.go (2)
NewDefaultProvider(233-237)NewEnvProvider(21-23)pkg/config/context.go (1)
ContextWithManager(19-21)pkg/config/resolver.go (3)
ModeMemory(7-7)ModePersistent(8-8)ModeDistributed(9-9)engine/infra/cache/mod.go (1)
SetupCache(53-87)
test/integration/server/executions_integration_test.go (1)
test/helpers/database.go (1)
SetupTestDatabase(406-421)
test/helpers/database_test.go (2)
test/helpers/database.go (1)
SetupDatabaseWithMode(282-318)pkg/config/resolver.go (3)
ModeMemory(7-7)ModePersistent(8-8)ModeDistributed(9-9)
engine/infra/server/mcp.go (1)
pkg/config/resolver.go (2)
ModeMemory(7-7)ModePersistent(8-8)
test/integration/tasks/basic/response_handler_test.go (1)
test/integration/tasks/helpers/setup.go (1)
NewTestSetupWithDriver(39-70)
pkg/template/types.go (1)
cli/tui/models/base.go (1)
Mode(10-10)
engine/infra/server/server.go (1)
pkg/config/resolver.go (1)
ModeMemory(7-7)
test/helpers/repo.go (3)
test/helpers/database.go (1)
SetupTestDatabase(406-421)engine/infra/postgres/taskrepo.go (1)
NewTaskRepo(91-93)engine/infra/sqlite/taskrepo.go (1)
NewTaskRepo(70-72)
pkg/config/loader.go (3)
pkg/config/config.go (1)
Config(58-148)engine/worker/embedded/config.go (1)
Config(34-67)pkg/config/resolver.go (4)
ModeMemory(7-7)ModePersistent(8-8)ModeDistributed(9-9)ModeRemoteTemporal(11-11)
pkg/template/templates/basic/basic.go (1)
cli/tui/models/base.go (1)
Mode(10-10)
cli/cmd/init/components/project_form.go (2)
cli/tui/models/base.go (1)
Mode(10-10)cli/cmd/init/init.go (1)
Options(30-42)
test/integration/tasks/core/concurrent_test.go (1)
test/integration/tasks/helpers/setup.go (1)
NewTestSetupWithDriver(39-70)
cli/cmd/start/start.go (2)
cli/tui/models/base.go (1)
Mode(10-10)pkg/config/resolver.go (3)
ModeMemory(7-7)ModePersistent(8-8)ModeDistributed(9-9)
test/helpers/database.go (6)
pkg/config/resolver.go (3)
ModeMemory(7-7)ModePersistent(8-8)ModeDistributed(9-9)pkg/config/config.go (1)
Config(58-148)engine/infra/postgres/migrations.go (1)
ApplyMigrations(25-32)engine/infra/sqlite/migrations.go (1)
ApplyMigrations(21-55)test/helpers/testcontainer_retry.go (1)
SetupTestReposWithRetry(31-66)engine/infra/repo/provider.go (1)
Provider(24-29)
cli/cmd/init/init.go (3)
cli/tui/models/base.go (1)
Mode(10-10)pkg/template/service.go (1)
GetService(23-31)pkg/template/types.go (1)
GenerateOptions(57-67)
test/helpers/server/server.go (1)
test/helpers/database.go (1)
SetupTestDatabase(406-421)
pkg/config/config_test.go (5)
pkg/config/resolver.go (5)
ModeMemory(7-7)ResolveMode(20-28)ModePersistent(8-8)ModeDistributed(9-9)ModeRemoteTemporal(11-11)pkg/config/config.go (1)
Default(2023-2025)pkg/config/loader.go (1)
NewService(54-67)pkg/config/manager.go (1)
NewManager(32-45)pkg/config/provider.go (2)
NewDefaultProvider(233-237)NewCLIProvider(51-55)
test/integration/tasks/helpers/setup.go (1)
test/helpers/repo.go (1)
SetupTestRepos(14-28)
test/integration/database/sqlite_specific_test.go (1)
test/helpers/database.go (1)
SetupTestDatabase(406-421)
pkg/config/definition/schema.go (1)
pkg/config/definition/field.go (2)
Registry(21-23)FieldDef(10-18)
🪛 Checkov (3.2.334)
examples/memory-mode/edge-deployment/Dockerfile.edge
[low] 1-16: Ensure that a user for the container has been created
(CKV_DOCKER_3)
🪛 dotenv-linter (4.0.0)
examples/distributed-mode/.env.example
[warning] 5-5: [UnorderedKey] The REDIS_ADDRESS key should go before the TEMPORAL_ADDRESS key
(UnorderedKey)
[warning] 6-6: [UnorderedKey] The OPENAI_API_KEY key should go before the REDIS_ADDRESS key
(UnorderedKey)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: test
- GitHub Check: Container Security Scan
- GitHub Check: Analyze (go)
- GitHub Check: Security Scan (gosec)
- GitHub Check: Test Coverage
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
engine/task/exec/runner.go (1)
96-144: Consider extracting validation logic (optional refactor).The
Preparemethod is within the 50-line limit but performs multiple operations. Consider extracting the runner validation block (lines 100-108) into a separatevalidateRunner()helper method to improve maintainability and reduce cognitive complexity.Example refactor:
+func (r *Runner) validateRunner() error { + if r.state == nil { + return ErrStateRequired + } + if r.repo == nil { + return ErrRepositoryRequired + } + if r.store == nil { + return ErrResourceStoreRequired + } + return nil +} + func (r *Runner) Prepare(ctx context.Context, req ExecuteRequest) (*PreparedExecution, error) { if ctx == nil { return nil, fmt.Errorf("context is required") } - if r.state == nil { - return nil, ErrStateRequired - } - if r.repo == nil { - return nil, ErrRepositoryRequired - } - if r.store == nil { - return nil, ErrResourceStoreRequired + if err := r.validateRunner(); err != nil { + return nil, err } if strings.TrimSpace(req.TaskID) == "" { return nil, ErrTaskIDRequired }pkg/config/config.go (1)
1444-1449: Update embedded Redis env prefixes.These env tags still advertise the deprecated
REDIS_STANDALONE_*prefix; operators following the new embedded naming (REDIS_EMBEDDED_*) will find their settings ignored.- Enabled bool `koanf:"enabled" json:"enabled" yaml:"enabled" mapstructure:"enabled" env:"REDIS_STANDALONE_PERSISTENCE_ENABLED"` - DataDir string `koanf:"data_dir" json:"data_dir" yaml:"data_dir" mapstructure:"data_dir" env:"REDIS_STANDALONE_PERSISTENCE_DATA_DIR"` - SnapshotInterval time.Duration `koanf:"snapshot_interval" json:"snapshot_interval" yaml:"snapshot_interval" mapstructure:"snapshot_interval" env:"REDIS_STANDALONE_PERSISTENCE_SNAPSHOT_INTERVAL"` - SnapshotOnShutdown bool `koanf:"snapshot_on_shutdown" json:"snapshot_on_shutdown" yaml:"snapshot_on_shutdown" mapstructure:"snapshot_on_shutdown" env:"REDIS_STANDALONE_PERSISTENCE_SNAPSHOT_ON_SHUTDOWN"` - RestoreOnStartup bool `koanf:"restore_on_startup" json:"restore_on_startup" yaml:"restore_on_startup" mapstructure:"restore_on_startup" env:"REDIS_STANDALONE_PERSISTENCE_RESTORE_ON_STARTUP"` + Enabled bool `koanf:"enabled" json:"enabled" yaml:"enabled" mapstructure:"enabled" env:"REDIS_EMBEDDED_PERSISTENCE_ENABLED"` + DataDir string `koanf:"data_dir" json:"data_dir" yaml:"data_dir" mapstructure:"data_dir" env:"REDIS_EMBEDDED_PERSISTENCE_DATA_DIR"` + SnapshotInterval time.Duration `koanf:"snapshot_interval" json:"snapshot_interval" yaml:"snapshot_interval" mapstructure:"snapshot_interval" env:"REDIS_EMBEDDED_PERSISTENCE_SNAPSHOT_INTERVAL"` + SnapshotOnShutdown bool `koanf:"snapshot_on_shutdown" json:"snapshot_on_shutdown" yaml:"snapshot_on_shutdown" mapstructure:"snapshot_on_shutdown" env:"REDIS_EMBEDDED_PERSISTENCE_SNAPSHOT_ON_SHUTDOWN"` + RestoreOnStartup bool `koanf:"restore_on_startup" json:"restore_on_startup" yaml:"restore_on_startup" mapstructure:"restore_on_startup" env:"REDIS_EMBEDDED_PERSISTENCE_RESTORE_ON_STARTUP"`As per coding guidelines
♻️ Duplicate comments (1)
docs/docs.go (1)
1870-1870: Update source Swagger annotations and regenerate docs instead of editing generated file.This issue was already flagged in a previous review. The file
docs/docs.gois auto-generated byswaggo/swag, and manual edits will be overwritten whenswag initruns.Update the
@Failure 503annotations in the source handler files:
engine/workflow/router/stream.go(around line 168)engine/task/router/stream.go(around line 107)engine/agent/router/stream.go(around line 119)Then run
swag initto regenerate this file.As per coding guidelines.
Also applies to: 2074-2074, 2278-2278, 2357-2357, 2474-2474, 2573-2573, 2672-2672, 2771-2771, 2897-2897, 3023-3023, 10656-10656, 10792-10792, 10960-10960
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (45)
README.mdis excluded by!**/*.mdcli/help/global-flags.mdis excluded by!**/*.mddocs/content/docs/architecture/embedded-temporal.mdxis excluded by!**/*.mdxdocs/content/docs/architecture/overview.mdxis excluded by!**/*.mdxdocs/content/docs/cli/compozy-start.mdxis excluded by!**/*.mdxdocs/content/docs/configuration/mode-configuration.mdxis excluded by!**/*.mdxdocs/content/docs/configuration/redis.mdxis excluded by!**/*.mdxdocs/content/docs/configuration/temporal.mdxis excluded by!**/*.mdxdocs/content/docs/core/mcp/migration-notes.mdxis excluded by!**/*.mdxdocs/content/docs/deployment/distributed-mode.mdxis excluded by!**/*.mdxdocs/content/docs/deployment/docker.mdxis excluded by!**/*.mdxdocs/content/docs/deployment/memory-mode.mdxis excluded by!**/*.mdxdocs/content/docs/deployment/persistent-mode.mdxis excluded by!**/*.mdxdocs/content/docs/deployment/production.mdxis excluded by!**/*.mdxdocs/content/docs/deployment/temporal-modes.mdxis excluded by!**/*.mdxdocs/content/docs/examples/persistent-mode.mdxis excluded by!**/*.mdxdocs/content/docs/faq.mdxis excluded by!**/*.mdxdocs/content/docs/troubleshooting/common-issues.mdxis excluded by!**/*.mdxdocs/content/docs/troubleshooting/temporal.mdxis excluded by!**/*.mdxdocs/swagger.jsonis excluded by!**/*.json,!docs/swagger.*docs/swagger.yamlis excluded by!**/*.yaml,!docs/swagger.*examples/configs/distributed-mode.yamlis excluded by!**/*.yamlexamples/configs/persistent-mode.yamlis excluded by!**/*.yamlexamples/persistent-mode/compozy.yamlis excluded by!**/*.yamlschemas/cache.jsonis excluded by!**/*.jsonschemas/compozy.jsonis excluded by!**/*.jsonschemas/config-redis.jsonis excluded by!**/*.jsonschemas/config-temporal.jsonis excluded by!**/*.jsonschemas/config.jsonis excluded by!**/*.jsontasks/docs/_task-template.mdis excluded by!**/*.mdtasks/prd-modes-refac/_task_1.mdis excluded by!**/*.mdtasks/prd-modes-refac/_task_2.mdis excluded by!**/*.mdtasks/prd-modes-refac/_task_3.mdis excluded by!**/*.mdtasks/prd-modes-refac/_task_4.mdis excluded by!**/*.mdtasks/prd-modes-refac/_task_5.mdis excluded by!**/*.mdtasks/prd-modes-refac/_task_6.mdis excluded by!**/*.mdtasks/prd-modes-refac/_task_7.mdis excluded by!**/*.mdtasks/prd-modes-refac/_tasks.mdis excluded by!**/*.mdtasks/prd-modes-refac/_techspec.mdis excluded by!**/*.mdtest/fixtures/embedded/persistence.gois excluded by!**/fixtures/**test/fixtures/embedded/sample_resource.yamlis excluded by!**/*.yaml,!**/fixtures/**test/fixtures/embedded/streaming.gois excluded by!**/fixtures/**test/fixtures/embedded/workflows/stateful-workflow.yamlis excluded by!**/*.yaml,!**/fixtures/**test/fixtures/embedded/workflows/test-workflow.yamlis excluded by!**/*.yaml,!**/fixtures/**test/integration/README.mdis excluded by!**/*.md
📒 Files selected for processing (24)
docs/docs.go(15 hunks)engine/agent/router/stream.go(1 hunks)engine/infra/cache/miniredis_embedded.go(6 hunks)engine/infra/cache/miniredis_embedded_test.go(5 hunks)engine/infra/cache/mod.go(4 hunks)engine/infra/cache/mod_test.go(2 hunks)engine/infra/cache/snapshot_manager_test.go(4 hunks)engine/infra/server/dependencies.go(7 hunks)engine/infra/server/mcp_test.go(3 hunks)engine/infra/server/temporal_resolver_test.go(2 hunks)engine/infra/sqlite/migrations.go(2 hunks)engine/task/exec/runner.go(1 hunks)engine/task/router/stream.go(1 hunks)engine/tool/builtin/calltask/schema.go(1 hunks)engine/webhook/idem_memory.go(1 hunks)engine/worker/embedded/config.go(2 hunks)engine/worker/embedded/namespace_test.go(1 hunks)engine/workflow/router/stream.go(1 hunks)examples/persistent-mode/.env.example(1 hunks)pkg/config/config.go(10 hunks)pkg/config/config_test.go(12 hunks)pkg/config/definition/schema.go(7 hunks)pkg/config/loader.go(5 hunks)pkg/config/loader_test.go(4 hunks)
🧰 Additional context used
📓 Path-based instructions (15)
**/*.go
📄 CodeRabbit inference engine (.cursor/rules/api-standards.mdc)
**/*.go: Return properly structured error responses
Use middleware for cross-cutting concerns (e.g., logging, auth, rate limiting)
Implement proper authentication and authorization in the API
Apply rate limiting and request validation
Version API routes under the prefix /api/v0/
Use gin-gonic/gin for HTTP APIs
Ensure consistent response formats across all endpoints
Use appropriate HTTP status codes (200, 201, 400, 401, 403, 404, 500)
Return JSON responses with a consistent error structure
Update Swagger annotations for all API changes
Generate Swagger docs served at /swagger/index.html using swaggo/swag
Include request and response examples in Swagger annotations
Document all parameters, headers, and error responses in Swagger
Success response body should contain fields: data and message ("Success")
Error response body should contain fields: error and details
**/*.go: Retrieve the logger via logger.FromContext(ctx) inside runtime code (handlers, services, workers)
Retrieve configuration via config.FromContext(ctx) inside runtime code (handlers, services, workers)
Attach *config.Manager at process edges using config.ContextWithManager(ctx, mgr)
Build the logger with logger.SetupLogger(...) at startup and attach with logger.ContextWithLogger(ctx, log)
For HTTP servers, ensure request contexts inherit BOTH manager and logger via middleware
Do not pass loggers via function parameters or dependency injection; always use context-backed retrieval
Do not use a global configuration singleton; read config from context
CLI/root flow: parse flags → construct sources → mgr.Load(...) → attach manager to ctx → setup logger honoring cfg.CLI.Debug/Quiet → attach logger to ctx → propagate ctx
Server startup should use the CLI-provided ctx and add middleware that sets c.Request = c.Request.WithContext(logger.ContextWithLogger(config.ContextWithManager(c.Request.Context(), mgr), log))
Optionally set http.Server.BaseContext to a parent context carrying manager and logger so all req...
Files:
engine/workflow/router/stream.goengine/tool/builtin/calltask/schema.goengine/infra/sqlite/migrations.gopkg/config/config_test.goengine/task/router/stream.goengine/infra/server/temporal_resolver_test.goengine/worker/embedded/config.goengine/infra/server/mcp_test.goengine/infra/cache/miniredis_embedded_test.goengine/infra/cache/miniredis_embedded.goengine/webhook/idem_memory.goengine/infra/cache/mod.goengine/infra/cache/snapshot_manager_test.goengine/agent/router/stream.gopkg/config/loader_test.goengine/task/exec/runner.goengine/infra/server/dependencies.goengine/worker/embedded/namespace_test.goengine/infra/cache/mod_test.godocs/docs.gopkg/config/loader.gopkg/config/definition/schema.gopkg/config/config.go
**/!(*_test).go
📄 CodeRabbit inference engine (.cursor/rules/magic-numbers.mdc)
**/!(*_test).go: NEVER introduce magic numbers in runtime Go code; replace unexplained numeric literals with named constants or configuration
Operator-tunable values MUST be sourced from configuration as defined in @.cursor/rules/global-config.mdc
Fetch configuration via config.FromContext(ctx); do not use global singletons
Promote tunable values (timeouts, deadlines, polling intervals, retry/backoff counts and factors, concurrency limits, queue sizes, buffer/payload limits, behavior thresholds) to configurationIn runtime code, properly inherit context; never use context.Background() in code paths
In runtime code paths, inherit context properly; never use context.Background()
In runtime code paths, never use context.Background(); properly inherit context
In runtime code, properly inherit context; never use context.Background()
Files:
engine/workflow/router/stream.goengine/tool/builtin/calltask/schema.goengine/infra/sqlite/migrations.goengine/task/router/stream.goengine/worker/embedded/config.goengine/infra/cache/miniredis_embedded.goengine/webhook/idem_memory.goengine/infra/cache/mod.goengine/agent/router/stream.goengine/task/exec/runner.goengine/infra/server/dependencies.godocs/docs.gopkg/config/loader.gopkg/config/definition/schema.gopkg/config/config.go
engine/{agent,task,task2,tool,workflow,runtime,llm,memory,memorycfg,knowledge,model,mcp,webhook,attachment,resources,auth,autoload,project,schema,worker}/**/*.go
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
engine/{agent,task,task2,tool,workflow,runtime,llm,memory,memorycfg,knowledge,model,mcp,webhook,attachment,resources,auth,autoload,project,schema,worker}/**/*.go: Application Layer (engine/): implement domain-specific business logic and ports; organize by domain with uc/ and router/ subpackages
Port interfaces (e.g., repositories, external services) are defined in Application Layer packages where they are used
Application layer depends inward: Application → Domain; avoid depending on infrastructure
Files:
engine/workflow/router/stream.goengine/tool/builtin/calltask/schema.goengine/task/router/stream.goengine/worker/embedded/config.goengine/webhook/idem_memory.goengine/agent/router/stream.goengine/task/exec/runner.goengine/worker/embedded/namespace_test.go
engine/*/router/**/*.go
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
Routers contain HTTP handling only (transport mapping, DTOs); no business logic
Files:
engine/workflow/router/stream.goengine/task/router/stream.goengine/agent/router/stream.go
{engine,pkg,cli}/**/*.go
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
Context as the first parameter for I/O or long-running operations; always propagate and handle cancellation
Files:
engine/workflow/router/stream.goengine/tool/builtin/calltask/schema.goengine/infra/sqlite/migrations.gopkg/config/config_test.goengine/task/router/stream.goengine/infra/server/temporal_resolver_test.goengine/worker/embedded/config.goengine/infra/server/mcp_test.goengine/infra/cache/miniredis_embedded_test.goengine/infra/cache/miniredis_embedded.goengine/webhook/idem_memory.goengine/infra/cache/mod.goengine/infra/cache/snapshot_manager_test.goengine/agent/router/stream.gopkg/config/loader_test.goengine/task/exec/runner.goengine/infra/server/dependencies.goengine/worker/embedded/namespace_test.goengine/infra/cache/mod_test.gopkg/config/loader.gopkg/config/definition/schema.gopkg/config/config.go
engine/infra/**/*.go
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
engine/infra/**/*.go: Infrastructure Layer (engine/infra): implement adapters for DB, cache, HTTP, storage, monitoring; must implement Application Layer interfaces
Adapter implementations belong in Infrastructure Layer and must implement Application Layer interfaces (no business logic leakage)
Infrastructure depends inward: Infrastructure → Application → Domain; avoid imports from cli and cross-infra coupling
Files:
engine/infra/sqlite/migrations.goengine/infra/server/temporal_resolver_test.goengine/infra/server/mcp_test.goengine/infra/cache/miniredis_embedded_test.goengine/infra/cache/miniredis_embedded.goengine/infra/cache/mod.goengine/infra/cache/snapshot_manager_test.goengine/infra/server/dependencies.goengine/infra/cache/mod_test.go
pkg/config/**/*_test.go
📄 CodeRabbit inference engine (.cursor/rules/global-config.mdc)
Add or extend tests under pkg/config/*_test.go when introducing validation or complex defaults
Files:
pkg/config/config_test.gopkg/config/loader_test.go
**/*_test.go
📄 CodeRabbit inference engine (.cursor/rules/logger-config.mdc)
**/*_test.go: In tests, set up configuration with config.Initialize or config.NewManager(...).Load(...) and attach via config.ContextWithManager
In tests, prefer logger.NewForTests() and attach with logger.ContextWithLogger
In tests, mock or stub external tools/services; do not introduce DI of logger/config into code under test
**/*_test.go: Prefer local test constants (e.g., const testTimeout = 5 * time.Second) in tests
Inline trivial literals in tests when intent is clear
Do not duplicate production constants in tests; import them or assert relative behavior
**/*_test.go: All tests pass and follow the established testing patterns
Code is well-tested with both unit and integration tests
Tests should follow the t.Run("Should...") subtest naming pattern
Ensure adequate test coverage
**/*_test.go: All Go tests must use t.Run("Should describe behavior", ...) subtests for each behavior
Use stretchr/testify for assertions and mocks in tests
Do not use testify suite patterns (no suite.Suite embedding or suite-based structures)
Do not use suite methods like s.Equal(), s.NoError(), or s.T()
Avoid weak assertions like assert.Error(t, err); use specific error validation instead
Prefer specific error assertions like assert.ErrorContains and assert.ErrorAs for validating errors
Unit tests should be placed alongside implementation files as *_test.go
Use testify/mock for mocking external dependencies or complex interfacesIn tests, never use context.Background(); use t.Context() instead
Aim for 80%+ test coverage on business logic; write focused, isolated tests
**/*_test.go: Use stretchr/testify for assertions and mocks; import as github.com/stretchr/testify/assert and github.com/stretchr/testify/mock; replace custom mocks with testify/mock
Use project test helpers (utils.SetupTest, utils.SetupFixture, etc.) in testsIn tests, never use context.Background(); use t.Context()
Files:
pkg/config/config_test.goengine/infra/server/temporal_resolver_test.goengine/infra/server/mcp_test.goengine/infra/cache/miniredis_embedded_test.goengine/infra/cache/snapshot_manager_test.gopkg/config/loader_test.goengine/worker/embedded/namespace_test.goengine/infra/cache/mod_test.go
pkg/**/*.go
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
Shared Packages (pkg): provide framework-level utilities (config, logging, templates, schema generation); must not contain business logic
Files:
pkg/config/config_test.gopkg/config/loader_test.gopkg/config/loader.gopkg/config/definition/schema.gopkg/config/config.go
pkg/config/**/*.go
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
Global configuration resides in pkg/config; expose retrieval via context (config.FromContext) and provide defaults; avoid global singletons
Files:
pkg/config/config_test.gopkg/config/loader_test.gopkg/config/loader.gopkg/config/definition/schema.gopkg/config/config.go
docs/**/*.go
📄 CodeRabbit inference engine (docs/.cursor/rules/review-checklist.mdc)
docs/**/*.go: Code must be formatted withgo fmt
All linter warnings must be addressed
Error handling must follow project patterns
Security considerations must be addressed (e.g., no exposed secrets or unvalidated inputs)
Errors must be handled appropriately and with context
Interfaces must be used appropriately to define behavior
Code must pass all linter checks
Code must be secure and performant
Dependencies must be injected properly
Context must be propagated correctly
Hardcoded values that should be configurable must be avoided
Missing context propagation in functions that make external calls must be addressed
Performance issues like unnecessary allocations or inefficient algorithms must be avoided
docs/**/*.go: Use section comments with dashes for visual separation in Go code, formatted as:
// -----------------------------------------------------------------------------
// Section Name
// -----------------------------------------------------------------------------
Files:
docs/docs.go
pkg/config/loader.go
📄 CodeRabbit inference engine (.cursor/rules/global-config.mdc)
pkg/config/loader.go: Implement cross-field validation in validateCustom when struct tag validation is insufficient
Extend validateCustom for cross-field constraints in new categories when struct tags are insufficient
Files:
pkg/config/loader.go
pkg/config/definition/schema.go
📄 CodeRabbit inference engine (.cursor/rules/global-config.mdc)
pkg/config/definition/schema.go: Use pkg/config/definition/schema.go as the single source of truth for configuration by registering fields in the registry
Add new property by registering it with registry.Register(&FieldDef{Path, Default, CLIFlag, EnvVar, Type, Help}); keep path namingcategory.property_name(snake_case)
Register all fields of a new category in registerFields and include it in CreateRegistry()
Config path format must be section.snake_case_property when registering fields
CLI flags in registry must use kebab-case (CLIFlag)
Durations should use time.Duration and defaults in the registry must be time.Duration values
Files:
pkg/config/definition/schema.go
{pkg/config/config.go,pkg/config/definition/schema.go}
📄 CodeRabbit inference engine (.cursor/rules/global-config.mdc)
Environment variable names must be UPPER_SNAKE_CASE with domain prefixes (e.g., SERVER_, DB_, RUNTIME_, CLI uses COMPOZY_)
Files:
pkg/config/definition/schema.gopkg/config/config.go
pkg/config/config.go
📄 CodeRabbit inference engine (.cursor/rules/global-config.mdc)
pkg/config/config.go: Add the new field to the typed config struct with tags: koanf/json/yaml/mapstructure; include env tag when applicable; add validate tag if needed; use SensitiveString or sensitive:"true" for secrets
Map from registry to typed struct in buildConfig using getString/getInt/getBool/getDuration/getInt64/getStringSlice
For secrets, prefer SensitiveString type or sensitive:"true" tag to enable automatic JSON redaction
When creating a new category, define typeConfig struct with full tagging and validation
Add the new section to the root Config with koanf/json/yaml/mapstructure tags
Implement buildConfig(registry *definition.Registry) to map defaults from the registry to the typed struct
Always include koanf, json, yaml, and mapstructure tags on config struct fields; include env when applicable
Files:
pkg/config/config.go
🧬 Code graph analysis (12)
pkg/config/config_test.go (4)
pkg/config/resolver.go (5)
ModeMemory(7-7)ResolveMode(20-28)ModePersistent(8-8)ModeDistributed(9-9)ModeRemoteTemporal(11-11)pkg/config/config.go (1)
Default(2023-2025)pkg/config/loader.go (1)
NewService(54-67)pkg/config/provider.go (2)
NewDefaultProvider(233-237)NewCLIProvider(51-55)
engine/worker/embedded/config.go (1)
pkg/config/config.go (1)
EmbeddedTemporalConfig(592-624)
engine/infra/server/mcp_test.go (1)
pkg/config/resolver.go (2)
ModeMemory(7-7)ModeDistributed(9-9)
engine/infra/cache/miniredis_embedded_test.go (1)
engine/infra/cache/miniredis_embedded.go (2)
MiniredisEmbedded(18-23)NewMiniredisEmbedded(70-111)
engine/infra/cache/mod.go (3)
pkg/config/resolver.go (3)
ModeMemory(7-7)ModePersistent(8-8)ModeDistributed(9-9)engine/infra/cache/miniredis_embedded.go (2)
MiniredisEmbedded(18-23)NewMiniredisEmbedded(70-111)pkg/config/config.go (2)
Config(58-148)RedisConfig(1322-1434)
engine/infra/cache/snapshot_manager_test.go (2)
pkg/config/config.go (3)
EmbeddedRedisConfig(1437-1440)RedisConfig(1322-1434)Config(58-148)engine/infra/cache/miniredis_embedded.go (1)
NewMiniredisEmbedded(70-111)
pkg/config/loader_test.go (3)
pkg/config/resolver.go (3)
ModeMemory(7-7)ModeDistributed(9-9)ModePersistent(8-8)pkg/config/config.go (1)
Default(2023-2025)pkg/config/loader.go (1)
NewService(54-67)
engine/infra/server/dependencies.go (4)
pkg/config/resolver.go (2)
ModeMemory(7-7)ModePersistent(8-8)engine/worker/embedded/server.go (1)
Server(30-38)engine/worker/embedded/config.go (1)
Config(37-37)pkg/config/config.go (1)
Config(58-148)
engine/infra/cache/mod_test.go (5)
pkg/logger/mod.go (2)
ContextWithLogger(39-41)NewForTests(199-201)pkg/config/provider.go (2)
NewDefaultProvider(233-237)NewEnvProvider(21-23)pkg/config/context.go (1)
ContextWithManager(19-21)pkg/config/resolver.go (3)
ModeMemory(7-7)ModePersistent(8-8)ModeDistributed(9-9)engine/infra/cache/mod.go (1)
SetupCache(53-78)
pkg/config/loader.go (3)
engine/worker/embedded/config.go (1)
Config(37-37)pkg/config/config.go (2)
Config(58-148)EmbeddedTemporalConfig(592-624)pkg/config/resolver.go (4)
ModeMemory(7-7)ModePersistent(8-8)ModeDistributed(9-9)ModeRemoteTemporal(11-11)
pkg/config/definition/schema.go (1)
pkg/config/definition/field.go (2)
Registry(21-23)FieldDef(10-18)
pkg/config/config.go (1)
pkg/config/resolver.go (2)
ModeMemory(7-7)ModePersistent(8-8)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: test
- GitHub Check: Analyze (go)
- GitHub Check: Container Security Scan
- GitHub Check: Security Scan (gosec)
- GitHub Check: Test Coverage
🔇 Additional comments (41)
examples/persistent-mode/.env.example (1)
1-2: Helpful comment successfully added for consistency.The previous review feedback has been addressed—the helpful comment guiding users to populate credentials is now present and aligns with the pattern established in the memory-mode example.
engine/tool/builtin/calltask/schema.go (1)
10-10: Terminology update aligns with mode refactoring.The description change from "standalone" to "embedded" is consistent with the PR's shift toward the new modes architecture.
To confirm consistency, verify that similar terminology updates (if any) have been applied to related schema descriptions or documentation across the codebase. If there are other references to "standalone task" or similar patterns in schema definitions or API documentation, please ensure they have also been updated to reflect the new mode semantics.
engine/infra/sqlite/migrations.go (1)
40-52: Defer pattern correctly addresses previous concurrency concern.The mutex initialization is now properly guarded with a defer block (lines 41–44) that guarantees cleanup even if
goose.SetDialectorgoose.UpContextpanic. BaseFS and the mutex are always restored regardless of early returns or panic, preventing deadlock on subsequent calls. Context is correctly propagated togoose.UpContextat line 49.engine/task/exec/runner.go (4)
35-40: LGTM! Proper dependency injection for resource store.The addition of the
storefield properly extends the Runner to support embedded mode execution with resource store access. The comment update clearly indicates the execution semantics.
65-67: LGTM! Constructor properly initializes dependencies.The updated constructor signature correctly accepts and initializes the new resource store dependency.
106-108: LGTM! Proper validation for the new dependency.The nil check for
r.storefollows the same pattern as other dependency validations and ensures the runner is properly initialized.
173-211: LGTM! Proper resource store usage.The
r.storefield is correctly utilized in bothloadTaskConfigandhydrateAgentConfigmethods. Context propagation is correct, and errors are properly wrapped with contextual information.engine/webhook/idem_memory.go (1)
10-10: Terminology update looks goodComment now matches the embedded/dev mode nomenclature introduced elsewhere.
engine/worker/embedded/namespace_test.go (1)
69-69: Fixture matches embedded modeSwitching the test namespace to “embedded” keeps the test configuration in step with the new mode naming.
engine/worker/embedded/config.go (1)
35-37: Alias keeps embedded worker alignedAdopting the alias to
pkgconfig.EmbeddedTemporalConfigremoves duplication and lets this package track the canonical struct definition.engine/task/router/stream.go (1)
107-107: Doc wording is consistentThe 503 description now matches the worker-focused terminology used across the streaming APIs.
engine/agent/router/stream.go (1)
119-119: Doc terminology alignsUpdated 503 description matches the worker-focused language adopted elsewhere.
engine/workflow/router/stream.go (1)
168-168: LGTM! Documentation improvement.The updated description "Worker unavailable" is more specific and accurately reflects the primary 503 failure case when
ensureWorkerReadyreturns false (line 135). This change aligns well with the mode-based architecture refactoring mentioned in the PR objectives.engine/infra/server/temporal_resolver_test.go (1)
12-24: Embedded Temporal resolver coverage stays accurateRenaming the test and invoking
maybeStartEmbeddedTemporalkeeps the resolver spec in sync with the new embedded startup flow while still validating the distributed skip path. Nice alignment.engine/infra/server/mcp_test.go (1)
15-54: Mode constants now mirror production semanticsUsing
config.ModeMemoryandconfig.ModeDistributedin these scenarios keeps the MCP proxy embedding tests aligned with the new mode API and avoids string drift. Looks good.engine/infra/cache/snapshot_manager_test.go (1)
63-157: Embedded Redis snapshot flow validated end-to-endSwitching the tests to
EmbeddedRedisConfigandNewMiniredisEmbeddedexercises the new persistence wiring all the way through shutdown/restore, so coverage remains comprehensive after the rename.engine/infra/cache/mod_test.go (1)
15-97: Cache mode tests now match embedded/persistent semanticsThe shared helper plus
t.Runscenarios clearly assert memory, persistent, and distributed behaviors against the updated config toggles. This keeps coverage consistent with the revised cache setup.engine/infra/cache/miniredis_embedded_test.go (1)
17-152: Embedded miniredis tests track the renamed implementationUpdating the helpers and scenarios to
NewMiniredisEmbeddedensures lifecycle and operation checks remain pointed at the production wrapper after the rename. Coverage stays solid.pkg/config/config_test.go (5)
36-37: LGTM! Default mode correctly updated to memory.The test properly verifies that the default configuration mode is
ModeMemoryand thatResolveModecorrectly resolves to this default.
130-140: LGTM! Memory mode SQLite driver resolution test.The test correctly verifies that when global mode is set to
ModeMemory, the effective database driver resolves to SQLite.
142-184: LGTM! Comprehensive mode validation tests.The table-driven test properly covers:
- Valid modes (empty/memory/persistent/distributed)
- Deprecated standalone mode with helpful error messages
- Invalid mode values with appropriate errors
- Mode inheritance when empty
262-301: LGTM! Embedded Temporal mode tests properly updated.Tests correctly verify memory and persistent mode behavior with embedded Temporal configuration, including host/port overrides.
671-753: LGTM! MCP proxy mode validation comprehensive.The test suite properly validates:
- Mode inheritance from global config
- Explicit memory/persistent/distributed modes
- Deprecated standalone rejection
- Port requirements for embedded modes
engine/infra/cache/mod.go (3)
80-94: LGTM! Memory mode properly disables persistence.The function correctly:
- Validates Redis configuration presence
- Explicitly disables persistence for memory mode
- Logs both current and previous persistence state
- Routes to unified embedded cache setup
96-117: LGTM! Persistent mode properly enables persistence with defaults.The function correctly:
- Validates Redis configuration presence
- Enables persistence if not already enabled
- Applies default data directory when missing
- Logs persistence configuration details
119-150: LGTM! Unified embedded cache setup is well-structured.The function properly:
- Creates embedded miniredis instance
- Wraps with Redis facade, lock manager, and notification system
- Handles cleanup on failure paths
- Logs initialization with mode and persistence state
pkg/config/loader.go (4)
376-396: LGTM! Global mode validation with clear migration guidance.The validation correctly:
- Accepts empty, memory, persistent, and distributed modes
- Rejects deprecated standalone with helpful migration guidance
- Provides clear error messages for invalid values
430-454: LGTM! Temporal mode validation properly handles embedded modes.The validation correctly:
- Routes remote mode to host/port validation
- Routes memory/persistent to embedded config validation
- Rejects deprecated standalone with clear guidance
- Provides comprehensive error messages
548-585: LGTM! Redis mode validation handles embedded persistence.The validation correctly:
- Accepts empty, memory, persistent, and distributed modes
- Rejects deprecated standalone with migration guidance
- Validates embedded persistence settings when enabled
- Checks data directory and snapshot interval requirements
637-673: LGTM! MCP proxy mode validation comprehensive.The validation correctly:
- Separates mode validation into dedicated function
- Validates port requirements for embedded modes
- Rejects deprecated standalone mode
- Provides clear error messages
pkg/config/loader_test.go (3)
118-192: LGTM! MCP proxy mode validation tests comprehensive.The tests properly cover:
- Inheritance from global mode
- Explicit memory/persistent/distributed modes
- Deprecated standalone rejection with error substrings
- Invalid value rejection
194-221: LGTM! Port requirement tests for embedded modes.The tests correctly verify that memory and persistent modes require explicit non-zero ports, with appropriate error message validation.
223-309: LGTM! Global and component mode validation refactored to table-driven.The tests are well-structured with:
- Clear test case naming
- Proper error substring validation
- Coverage of valid, invalid, and deprecated modes
- Consistent use of mode constants
engine/infra/cache/miniredis_embedded.go (2)
15-23: LGTM! Type renaming to MiniredisEmbedded is appropriate.The renaming from
MiniredisStandalonetoMiniredisEmbeddedbetter reflects the new terminology and aligns with the embedded mode semantics across the codebase.
70-87: LGTM! Improved mode logging.The constructor now properly logs the effective Redis mode from configuration, providing better visibility into which mode is active.
engine/infra/server/dependencies.go (2)
139-169: LGTM! Database validation properly extracts and logs mode.The validation correctly:
- Extracts mode with default to memory
- Includes mode in log messages
- Warns about SQLite limitations with mode context
- Provides clear recommendations
389-431: LGTM! Embedded Temporal startup properly refactored.The function correctly:
- Uses EffectiveTemporalMode to determine mode
- Only starts for memory/persistent modes
- Logs mode throughout startup
- Provides development/testing warning with mode context
pkg/config/definition/schema.go (4)
47-57: LGTM! Global mode field properly registered.The field definition correctly:
- Sets default to "memory"
- Uses appropriate CLI flag and env var
- Provides clear help text describing all three modes
2213-2222: LGTM! Redis mode field properly added.The field definition correctly:
- Defaults to empty for inheritance
- Uses appropriate CLI flag and env var
- Clearly describes mode inheritance behavior
2419-2419: LGTM! CLI mode flag renamed to avoid collision.Renaming the CLI flag from
"mode"to"cli-mode"prevents collision with the global mode flag, which is the correct approach.
2896-2900: LGTM! MCP proxy mode default updated to memory.The default mode change from standalone to memory aligns with the new mode semantics, and the help text clearly describes the embedded vs distributed behavior.
| @@ -572,46 +581,46 @@ type TemporalConfig struct { | |||
| // Default: "compozy-tasks" | |||
| TaskQueue string `koanf:"task_queue" env:"TEMPORAL_TASK_QUEUE" json:"task_queue" yaml:"task_queue" mapstructure:"task_queue"` | |||
There was a problem hiding this comment.
Validate Temporal mode inputs.
The Temporal mode tag now accepts any value; we still only support memory/persistent/distributed, so keep the validator to stop invalid configs from slipping through.
- Mode string `koanf:"mode" env:"TEMPORAL_MODE" json:"mode" yaml:"mode" mapstructure:"mode" validate:"omitempty"`
+ Mode string `koanf:"mode" env:"TEMPORAL_MODE" json:"mode" yaml:"mode" mapstructure:"mode" validate:"omitempty,oneof=memory persistent distributed"`As per coding guidelines
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| Mode string `koanf:"mode" env:"TEMPORAL_MODE" json:"mode" yaml:"mode" mapstructure:"mode" validate:"omitempty,oneof=memory persistent distributed"` |
🤖 Prompt for AI Agents
In pkg/config/config.go around line 558, the Temporal mode tag currently accepts
any value; re-add/restore validation to ensure the mode is one of the supported
values ("memory", "persistent", "distributed") and reject anything else. Update
the config validation function to check the mode (case-insensitive if codebase
prefers) and return a clear error indicating the invalid value and allowed
options; make sure this happens early during config load/validation so invalid
configs fail fast and follow the project error-handling/logging conventions.
There was a problem hiding this comment.
Actionable comments posted: 3
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (2)
docs/swagger.jsonis excluded by!**/*.json,!docs/swagger.*docs/swagger.yamlis excluded by!**/*.yaml,!docs/swagger.*
📒 Files selected for processing (8)
docs/docs.go(15 hunks)engine/agent/router/stream.go(1 hunks)engine/infra/server/dependencies.go(7 hunks)engine/task/exec/runner.go(2 hunks)engine/task/router/stream.go(1 hunks)engine/workflow/router/stream.go(1 hunks)pkg/config/config.go(10 hunks)pkg/config/loader.go(6 hunks)
🧰 Additional context used
📓 Path-based instructions (12)
**/*.go
📄 CodeRabbit inference engine (.cursor/rules/api-standards.mdc)
**/*.go: Return properly structured error responses
Use middleware for cross-cutting concerns (e.g., logging, auth, rate limiting)
Implement proper authentication and authorization in the API
Apply rate limiting and request validation
Version API routes under the prefix /api/v0/
Use gin-gonic/gin for HTTP APIs
Ensure consistent response formats across all endpoints
Use appropriate HTTP status codes (200, 201, 400, 401, 403, 404, 500)
Return JSON responses with a consistent error structure
Update Swagger annotations for all API changes
Generate Swagger docs served at /swagger/index.html using swaggo/swag
Include request and response examples in Swagger annotations
Document all parameters, headers, and error responses in Swagger
Success response body should contain fields: data and message ("Success")
Error response body should contain fields: error and details
**/*.go: Retrieve the logger via logger.FromContext(ctx) inside runtime code (handlers, services, workers)
Retrieve configuration via config.FromContext(ctx) inside runtime code (handlers, services, workers)
Attach *config.Manager at process edges using config.ContextWithManager(ctx, mgr)
Build the logger with logger.SetupLogger(...) at startup and attach with logger.ContextWithLogger(ctx, log)
For HTTP servers, ensure request contexts inherit BOTH manager and logger via middleware
Do not pass loggers via function parameters or dependency injection; always use context-backed retrieval
Do not use a global configuration singleton; read config from context
CLI/root flow: parse flags → construct sources → mgr.Load(...) → attach manager to ctx → setup logger honoring cfg.CLI.Debug/Quiet → attach logger to ctx → propagate ctx
Server startup should use the CLI-provided ctx and add middleware that sets c.Request = c.Request.WithContext(logger.ContextWithLogger(config.ContextWithManager(c.Request.Context(), mgr), log))
Optionally set http.Server.BaseContext to a parent context carrying manager and logger so all req...
Files:
engine/workflow/router/stream.goengine/task/router/stream.goengine/agent/router/stream.goengine/infra/server/dependencies.godocs/docs.goengine/task/exec/runner.gopkg/config/loader.gopkg/config/config.go
**/!(*_test).go
📄 CodeRabbit inference engine (.cursor/rules/magic-numbers.mdc)
**/!(*_test).go: NEVER introduce magic numbers in runtime Go code; replace unexplained numeric literals with named constants or configuration
Operator-tunable values MUST be sourced from configuration as defined in @.cursor/rules/global-config.mdc
Fetch configuration via config.FromContext(ctx); do not use global singletons
Promote tunable values (timeouts, deadlines, polling intervals, retry/backoff counts and factors, concurrency limits, queue sizes, buffer/payload limits, behavior thresholds) to configurationIn runtime code, properly inherit context; never use context.Background() in code paths
In runtime code paths, inherit context properly; never use context.Background()
In runtime code paths, never use context.Background(); properly inherit context
In runtime code, properly inherit context; never use context.Background()
Files:
engine/workflow/router/stream.goengine/task/router/stream.goengine/agent/router/stream.goengine/infra/server/dependencies.godocs/docs.goengine/task/exec/runner.gopkg/config/loader.gopkg/config/config.go
engine/{agent,task,task2,tool,workflow,runtime,llm,memory,memorycfg,knowledge,model,mcp,webhook,attachment,resources,auth,autoload,project,schema,worker}/**/*.go
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
engine/{agent,task,task2,tool,workflow,runtime,llm,memory,memorycfg,knowledge,model,mcp,webhook,attachment,resources,auth,autoload,project,schema,worker}/**/*.go: Application Layer (engine/): implement domain-specific business logic and ports; organize by domain with uc/ and router/ subpackages
Port interfaces (e.g., repositories, external services) are defined in Application Layer packages where they are used
Application layer depends inward: Application → Domain; avoid depending on infrastructure
Files:
engine/workflow/router/stream.goengine/task/router/stream.goengine/agent/router/stream.goengine/task/exec/runner.go
engine/*/router/**/*.go
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
Routers contain HTTP handling only (transport mapping, DTOs); no business logic
Files:
engine/workflow/router/stream.goengine/task/router/stream.goengine/agent/router/stream.go
{engine,pkg,cli}/**/*.go
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
Context as the first parameter for I/O or long-running operations; always propagate and handle cancellation
Files:
engine/workflow/router/stream.goengine/task/router/stream.goengine/agent/router/stream.goengine/infra/server/dependencies.goengine/task/exec/runner.gopkg/config/loader.gopkg/config/config.go
engine/infra/**/*.go
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
engine/infra/**/*.go: Infrastructure Layer (engine/infra): implement adapters for DB, cache, HTTP, storage, monitoring; must implement Application Layer interfaces
Adapter implementations belong in Infrastructure Layer and must implement Application Layer interfaces (no business logic leakage)
Infrastructure depends inward: Infrastructure → Application → Domain; avoid imports from cli and cross-infra coupling
Files:
engine/infra/server/dependencies.go
docs/**/*.go
📄 CodeRabbit inference engine (docs/.cursor/rules/review-checklist.mdc)
docs/**/*.go: Code must be formatted withgo fmt
All linter warnings must be addressed
Error handling must follow project patterns
Security considerations must be addressed (e.g., no exposed secrets or unvalidated inputs)
Errors must be handled appropriately and with context
Interfaces must be used appropriately to define behavior
Code must pass all linter checks
Code must be secure and performant
Dependencies must be injected properly
Context must be propagated correctly
Hardcoded values that should be configurable must be avoided
Missing context propagation in functions that make external calls must be addressed
Performance issues like unnecessary allocations or inefficient algorithms must be avoided
docs/**/*.go: Use section comments with dashes for visual separation in Go code, formatted as:
// -----------------------------------------------------------------------------
// Section Name
// -----------------------------------------------------------------------------
Files:
docs/docs.go
pkg/config/loader.go
📄 CodeRabbit inference engine (.cursor/rules/global-config.mdc)
pkg/config/loader.go: Implement cross-field validation in validateCustom when struct tag validation is insufficient
Extend validateCustom for cross-field constraints in new categories when struct tags are insufficient
Files:
pkg/config/loader.go
pkg/**/*.go
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
Shared Packages (pkg): provide framework-level utilities (config, logging, templates, schema generation); must not contain business logic
Files:
pkg/config/loader.gopkg/config/config.go
pkg/config/**/*.go
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
Global configuration resides in pkg/config; expose retrieval via context (config.FromContext) and provide defaults; avoid global singletons
Files:
pkg/config/loader.gopkg/config/config.go
pkg/config/config.go
📄 CodeRabbit inference engine (.cursor/rules/global-config.mdc)
pkg/config/config.go: Add the new field to the typed config struct with tags: koanf/json/yaml/mapstructure; include env tag when applicable; add validate tag if needed; use SensitiveString or sensitive:"true" for secrets
Map from registry to typed struct in buildConfig using getString/getInt/getBool/getDuration/getInt64/getStringSlice
For secrets, prefer SensitiveString type or sensitive:"true" tag to enable automatic JSON redaction
When creating a new category, define typeConfig struct with full tagging and validation
Add the new section to the root Config with koanf/json/yaml/mapstructure tags
Implement buildConfig(registry *definition.Registry) to map defaults from the registry to the typed struct
Always include koanf, json, yaml, and mapstructure tags on config struct fields; include env when applicable
Files:
pkg/config/config.go
{pkg/config/config.go,pkg/config/definition/schema.go}
📄 CodeRabbit inference engine (.cursor/rules/global-config.mdc)
Environment variable names must be UPPER_SNAKE_CASE with domain prefixes (e.g., SERVER_, DB_, RUNTIME_, CLI uses COMPOZY_)
Files:
pkg/config/config.go
🧬 Code graph analysis (3)
engine/infra/server/dependencies.go (5)
pkg/config/resolver.go (2)
ModeMemory(7-7)ModePersistent(8-8)engine/infra/server/server.go (1)
Server(34-64)engine/worker/embedded/server.go (1)
Server(30-38)pkg/config/config.go (1)
Config(58-148)engine/worker/embedded/config.go (1)
Config(37-37)
pkg/config/loader.go (3)
pkg/config/config.go (2)
Config(58-148)EmbeddedTemporalConfig(592-624)engine/worker/embedded/config.go (1)
Config(37-37)pkg/config/resolver.go (4)
ModeMemory(7-7)ModePersistent(8-8)ModeDistributed(9-9)ModeRemoteTemporal(11-11)
pkg/config/config.go (1)
pkg/config/resolver.go (2)
ModeMemory(7-7)ModePersistent(8-8)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: test
- GitHub Check: Test Coverage
- GitHub Check: Container Security Scan
- GitHub Check: Analyze (go)
- GitHub Check: Security Scan (gosec)
🔇 Additional comments (5)
engine/task/exec/runner.go (2)
39-39: LGTM: Store field properly integrated.The
storefield is correctly added to the struct, initialized in the constructor (line 65), and used appropriately inloadTaskConfig(line 182) andhydrateAgentConfig(line 208).
95-107: LGTM: Clean dependency validation.The
validateRunner()method follows SRP and provides clear, specific error messages for each missing dependency. The early-return pattern keeps the logic flat and readable.docs/docs.go (1)
1870-1870: docs/docs.go is correctly regenerated from updated source annotations.Verification confirms that all changes in docs/docs.go reflect properly updated source Swagger annotations. The SSE endpoint descriptions and 503 error messages (including "Worker unavailable", "Pub/Sub provider unavailable", and "Workflow query client unavailable") originate from @description and @failure annotations in the corresponding source handlers:
engine/agent/router/stream.go: streamAgentExecution() handler includes routes.Base() context and "Pub/Sub provider unavailable" 503 errorengine/task/router/stream.go: streamTaskExecution() handler includes routes.Base() context and "Pubsub provider unavailable" 503 error- Additional 503 error descriptions found in
engine/workflow/router/execute.go,execs.go,events.go, andstream.goAll 15 changes in docs/docs.go correctly represent the regenerated Swagger documentation from these updated source annotations.
engine/agent/router/stream.go (1)
119-119: LGTM!The updated error message is more specific and accurately reflects the unavailable dependency. The "Pub/Sub" terminology is clear and professional.
engine/workflow/router/stream.go (1)
168-168: LGTM!The updated error message correctly identifies the workflow-specific dependency (query client) as opposed to the pub/sub provider used in task and agent streaming endpoints. This provides clearer information to API consumers.
| case config.ModePersistent: | ||
| if dbFile == "" || dbFile == sqliteMemoryDSN { | ||
| fromValue := originalDBFile | ||
| if fromValue == "" { | ||
| fromValue = "(empty)" | ||
| } | ||
| log.Info( | ||
| "Overriding Temporal database file for persistent mode", | ||
| "mode", mode, | ||
| "from", fromValue, | ||
| "to", persistentDBPath, | ||
| ) | ||
| dbFile = persistentDBPath | ||
| } |
There was a problem hiding this comment.
Ensure persistent mode overrides all in-memory Temporal DSNs
file::memory:?cache=shared and similar URIs are still in-memory SQLite. In persistent mode we must force a file-backed path, otherwise Temporal keeps running ephemerally and state disappears on restart. Right now we only override when the value is exactly :memory:. Please treat the entire file::memory: family as in-memory (you already added sqliteMemoryFilePrefix for this) so persistent mode can’t silently lose data.
@@
- dbFile := strings.TrimSpace(embeddedTemporal.DatabaseFile)
+ dbFile := strings.TrimSpace(embeddedTemporal.DatabaseFile)
+ dbLower := strings.ToLower(dbFile)
@@
- case config.ModePersistent:
- if dbFile == "" || dbFile == sqliteMemoryDSN {
+ case config.ModePersistent:
+ if dbFile == "" || dbLower == sqliteMemoryDSN || strings.HasPrefix(dbLower, sqliteMemoryFilePrefix) {
fromValue := originalDBFile
if fromValue == "" {
fromValue = "(empty)"
}Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In engine/infra/server/dependencies.go around lines 441 to 454, the
persistent-mode override only checks for an exact in-memory DSN but misses the
URI family (e.g. file::memory:?cache=shared); update the condition to treat any
DB file that equals sqliteMemoryDSN or has the sqliteMemoryFilePrefix prefix as
in-memory and therefore override it with persistentDBPath; use the existing
sqliteMemoryFilePrefix constant (and keep originalDBFile logging) so persistent
mode always forces a file-backed path.
| if ctx == nil { | ||
| return nil, fmt.Errorf("context is required") | ||
| } | ||
| if err := r.validateRunner(); err != nil { | ||
| return nil, err | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Suggest consistent error handling for context validation.
The context nil check uses fmt.Errorf("context is required") (also on line 157), while dependency validation uses predefined error constants (ErrStateRequired, etc.). For consistency with the existing error constants pattern (lines 27-32), consider adding ErrContextRequired to the error constant block and using it in both validation locations.
Apply this diff to add the constant at the top of the file:
var (
ErrTaskIDRequired = errors.New("task id is required")
ErrStateRequired = errors.New("application state is required")
ErrRepositoryRequired = errors.New("task repository is required")
ErrResourceStoreRequired = errors.New("resource store is required")
ErrProjectNameRequired = errors.New("project name is required")
ErrNegativeTimeout = errors.New("timeout must be non-negative")
+ ErrContextRequired = errors.New("context is required")
)Then update the validation checks:
func (r *Runner) Prepare(ctx context.Context, req ExecuteRequest) (*PreparedExecution, error) {
if ctx == nil {
- return nil, fmt.Errorf("context is required")
+ return nil, ErrContextRequired
} func (r *Runner) ExecutePrepared(ctx context.Context, prepared *PreparedExecution) (*ExecuteResult, error) {
if ctx == nil {
- return nil, fmt.Errorf("context is required")
+ return nil, ErrContextRequired
}Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In engine/task/exec/runner.go around lines 111-116 (and also update at line
157), the nil context checks use fmt.Errorf("context is required") while other
validations use predefined error constants; add a new error constant
ErrContextRequired to the file's error constant block near lines 27-32, then
replace the fmt.Errorf(...) occurrences at the two context checks with the new
ErrContextRequired constant so context validation follows the same
error-constant pattern as the other validations.
| // @Failure 400 {object} router.Response{error=router.ErrorInfo} "Invalid request" | ||
| // @Failure 404 {object} router.Response{error=router.ErrorInfo} "Execution not found" | ||
| // @Failure 503 {object} router.Response{error=router.ErrorInfo} "Streaming infrastructure unavailable" | ||
| // @Failure 503 {object} router.Response{error=router.ErrorInfo} "Pubsub provider unavailable" |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Inconsistent terminology with agent router.
The error message uses "Pubsub provider unavailable", while Line 119 in engine/agent/router/stream.go uses "Pub/Sub provider unavailable" (with capital P and slash). For consistency and clarity across API documentation, standardize the terminology.
Apply this diff to align with the agent router terminology:
-// @Failure 503 {object} router.Response{error=router.ErrorInfo} "Pubsub provider unavailable"
+// @Failure 503 {object} router.Response{error=router.ErrorInfo} "Pub/Sub provider unavailable"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // @Failure 503 {object} router.Response{error=router.ErrorInfo} "Pubsub provider unavailable" | |
| // @Failure 503 {object} router.Response{error=router.ErrorInfo} "Pub/Sub provider unavailable" |
🤖 Prompt for AI Agents
In engine/task/router/stream.go around line 107, the Swagger failure comment
reads "Pubsub provider unavailable" which is inconsistent with
engine/agent/router/stream.go (line 119) that uses "Pub/Sub provider
unavailable"; update the comment text to "Pub/Sub provider unavailable" (capital
P and slash) so the API docs use identical terminology across both routers.
Summary by CodeRabbit
New Features
Documentation
Tests