Skip to content

Comments

feat: agent memory system#1659

Merged
yottahmd merged 11 commits intomainfrom
agent-memory
Feb 13, 2026
Merged

feat: agent memory system#1659
yottahmd merged 11 commits intomainfrom
agent-memory

Conversation

@yottahmd
Copy link
Collaborator

@yottahmd yottahmd commented Feb 12, 2026

Summary by CodeRabbit

  • New Features

    • Admin "Agent Memory" page to view, edit, clear global memory and manage per‑DAG memories (save/delete).
    • New agent memory API surface for global and per‑DAG memory operations.
    • UI: "Agent Memory" menu item and per‑DAG memory badges.
  • Improvements

    • Selective DAG publishing: choose specific DAGs to publish; Git Sync adds row checkboxes and toggle‑all.

@coderabbitai
Copy link

coderabbitai bot commented Feb 12, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a persistent agent memory subsystem (file-backed), new admin REST endpoints for global and per‑DAG memory, integrates memory into session/system prompts, updates sync to publish selected DAG IDs and treat memory .md files, and adds frontend UI for memory management and selective DAG publishing.

Changes

Cohort / File(s) Summary
API Spec & Client Schema
api/v1/api.yaml, ui/src/api/v1/schema.ts
Added /settings/agent/memory and /settings/agent/memory/dags/{dagName} GET/PUT/DELETE endpoints and schemas (AgentMemoryResponse, AgentDAGMemoryResponse, UpdateAgentMemoryRequest). Updated SyncPublishAllRequest to require dagIds.
Frontend UI
ui/src/pages/agent-memory/index.tsx, ui/src/App.tsx, ui/src/menu.tsx, ui/src/pages/git-sync/index.tsx
Added Agent Memory page and menu entry, admin-protected route, memory editing UX (global + per-DAG), and git-sync UI changes for selecting specific DAGs for publish (checkboxes, selected dagIds passed).
Frontend API Surface
internal/service/frontend/api/v1/agent_memory.go, internal/service/frontend/api/v1/api.go, internal/service/frontend/api/v1/sync.go, internal/service/frontend/api/v1/sync_test.go
Implemented v1 handlers for agent memory (get/update/delete global and per-DAG) with admin checks and audit logging. Updated SyncPublishAll to accept dagIds and added validation/error mapping and tests.
Server wiring & API options
internal/service/frontend/server.go, internal/service/frontend/api/v1/api.go
Created and wired file-based memory store into REST server and added WithAgentMemoryStore API option; exposed agent MemoryStore in API struct.
Agent core integration
internal/agent/api.go, internal/agent/session.go, internal/agent/system_prompt.go, internal/agent/system_prompt.txt, internal/agent/system_prompt_test.go
Added MemoryStore to API/SessionManager configs, load memory at session start, pass MemoryContent into system prompt generation and template; updated tests.
Memory interface & data model
internal/agent/memory.go
Introduced public MemoryStore interface and MemoryContent struct for global and DAG memory access and metadata.
File-backed memory implementation
internal/persis/filememory/store.go, internal/persis/filememory/store_test.go
Added thread-safe file-backed Store implementing agent.MemoryStore with atomic writes, truncation (200 lines), DAG name validation/path-safety, listing and delete support, and comprehensive tests.
Git sync: publish & memory handling
internal/cmd/sync.go, internal/gitsync/service.go, internal/gitsync/service_test.go, internal/gitsync/errors.go
Changed PublishAll to accept explicit dagIDs; added memory file detection (.md), safe DAG ID/path helpers, target resolution/validation, adjusted scanning and publish flow, added InvalidDAGIDError and corresponding tests.

Sequence Diagram

sequenceDiagram
    participant Client
    participant APIHandler as API Handler\n(internal/service/frontend/api/v1/agent_memory.go)
    participant MemStore as MemoryStore\n(internal/persis/filememory)
    participant FileSystem as File System
    participant SessionMgr as SessionManager\n(internal/agent/session.go)

    Client->>APIHandler: PUT /settings/agent/memory\n{content}
    APIHandler->>APIHandler: require admin & authz
    APIHandler->>MemStore: SaveGlobalMemory(ctx, content)
    MemStore->>FileSystem: write memory/MEMORY.md (atomic, truncate)
    FileSystem-->>MemStore: success
    MemStore-->>APIHandler: nil
    APIHandler->>APIHandler: audit log
    APIHandler-->>Client: 200 OK

    rect rgba(100, 150, 200, 0.5)
    Note over Client,SessionMgr: Session creation uses memory
    Client->>SessionMgr: Start new session (DAG contexts)
    SessionMgr->>MemStore: LoadGlobalMemory(ctx)
    MemStore->>FileSystem: read memory/MEMORY.md
    FileSystem-->>MemStore: content
    MemStore-->>SessionMgr: content
    SessionMgr->>SessionMgr: GenerateSystemPrompt(..., memory)
    SessionMgr-->>Client: Session ready
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 32.69% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: agent memory system' is clear, concise, and directly describes the main feature being added - a memory system for agents.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch agent-memory

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
internal/agent/api.go (1)

611-625: ⚠️ Potential issue | 🟡 Minor

DAGName is not propagated to reactivated sessions.

reactivateSession passes MemoryStore (Line 624) but doesn't set DAGName in SessionManagerConfig. Reactivated sessions will load global memory but never DAG-specific memory, even if the original session had a DAG context.

If the DAG name was persisted alongside the session (or could be inferred from stored messages), it could be restored here. Otherwise, consider documenting this as a known limitation.

internal/gitsync/service.go (2)

557-579: ⚠️ Potential issue | 🟠 Major

Validate each DAG’s publishable state before staging.

PublishAll skips validatePublishable, so conflicted or already-synced DAGs can be published without a force flag. That’s a behavior change vs single-DAG publish and can overwrite conflicts unintentionally.

🔧 Proposed fix (per-DAG validation before staging)
 	for _, dagID := range dagIDs {
+		dagState := state.DAGs[dagID]
+		if dagState == nil {
+			result.Errors = append(result.Errors, SyncError{DAGID: dagID, Message: "DAG not found"})
+			continue
+		}
+		if err := s.validatePublishable(dagState, dagID, false); err != nil {
+			result.Errors = append(result.Errors, SyncError{DAGID: dagID, Message: err.Error()})
+			continue
+		}
 		dagFilePath := s.dagIDToFilePath(dagID)
 		repoFilePath := s.dagIDToRepoPath(dagID)

587-602: ⚠️ Potential issue | 🟠 Major

Change AddAndCommit call to avoid re-staging all files.

The selective staging in lines 590-596 is undermined by AddAndCommit(".", message) on line 601. The AddAndCommit implementation calls wt.Add(filePath), so passing "." stages all changes in the working tree, bypassing the intent to commit only the files in stagedFiles. Pass specific files or refactor to use a commit-only variant that doesn't re-stage.

🤖 Fix all issues with AI agents
In `@api/v1/api.yaml`:
- Around line 6399-6412: The OpenAPI model SyncPublishAllRequest now requires
dagIds but the /sync/publish-all operation summary/description still implies
"publish all modified DAGs"; update the /sync/publish-all operation in api.yaml
to reference SyncPublishAllRequest and change its summary/description to state
it publishes the specified/selected DAGs (accepts dagIds array) — locate the
operation for path "/sync/publish-all" and modify its summary/description to
clearly mention that dagIds are required and only those DAGs will be published.
- Around line 3985-4083: Replace the inline dagName parameter schema (the
parameter named dagName in the get/put/delete endpoints, including operationId
updateAgentDAGMemory and deleteAgentDAGMemory) with a reference to the canonical
DAGName schema to ensure consistent validation: remove the current inline schema
block (type/minLength) and set schema: $ref: "#/components/schemas/DAGName"
while preserving the parameter name, in, required and description fields.

In `@internal/agent/system_prompt.txt`:
- Around line 49-53: The <memory_paths> block renders broken paths when
.Memory.MemoryDir is empty; wrap the entire <memory_paths> section in a template
conditional that checks .Memory.MemoryDir (e.g., {{if .Memory.MemoryDir}} ...
{{end}}) so the "Memory directory" and "Global memory" lines (and the existing
{{if .Memory.DAGName}} DAG memory line) are only rendered when MemoryDir is set;
keep the inner DAGName conditional as-is.

In `@internal/service/frontend/server.go`:
- Around line 263-266: The code creates two separate filememory.Store instances
by calling filememory.New(cfg.Paths.DAGsDir) in multiple places (once when
building allAPIOptions via apiv1.WithAgentMemoryStore and again inside
initAgentAPI), causing unsynchronized access to the same files; fix it by
creating a single shared store (call filememory.New once with
cfg.Paths.DAGsDir), reuse that instance for apiv1.WithAgentMemoryStore, and
change initAgentAPI to accept the shared filememory.Store (remove its internal
call to filememory.New) so both the REST API and Agent API use the same Store
and mutex.

In `@ui/src/pages/agent-memory/index.tsx`:
- Around line 155-161: The current implementation returns a full-page spinner
when isLoading is true (the Loader2 block), which hides the entire page;
instead, remove the early return and always render the page skeleton (headings,
controls, empty textareas) so stale data remains visible, keep using isLoading
to show inline loading indicators next to or inside the specific data
sections/components (replace the centered Loader2 overlay with small loaders or
skeletons inside the memory list, detail pane, or form components), and ensure
components like the memory list rendering logic check isLoading to display their
own inline placeholders rather than hiding the whole page.
- Around line 255-276: The DAG chip currently nests a clickable trash <button>
inside the main chip <button>, which is invalid HTML; update the chip to be a
non-button container (e.g., a <div> or a semantic element with role="button" and
proper keyboard handlers) that uses the existing handleSelectDAG(name) for chip
activation and keep the trash control as a separate interactive element that
calls setDeletingDAG(name); ensure selectedDAG checks and styling remain tied to
the container and maintain accessible keyboard handling
(onKeyDown/role/aria-pressed) and focusability for the container while
preserving the Trash2 icon button as an independent clickable element.

In `@ui/src/pages/git-sync/index.tsx`:
- Around line 143-153: The effect that auto-selects publishable DAGs (useEffect
referencing status?.dags) is re-running on every poll because the fetched object
reference changes; change it to only auto-select on first load or when the
actual set of publishable IDs changes: add a persisted ref (e.g.,
initialAutoSelectedRef) to run the selection only once on mount OR compute the
current publishable ID set inside the effect and compare it to a
previousPublishableIds ref (or memoized value) and call
setSelectedDags(publishable) only when the ID set differs; update the effect
body that currently iterates over Object.entries(status.dags) and the dependency
list so it no longer blindly depends on status?.dags reference changes.
🧹 Nitpick comments (8)
ui/src/pages/git-sync/index.tsx (1)

270-281: useMemo on filteredDags is effectively a no-op.

filteredDags is recomputed inline on every render (lines 263-268), producing a new array reference each time. Passing it as a dependency to useMemo means the memo always recalculates. Consider memoizing filteredDags itself, or derive publishableDagIds from status?.dags and filter directly.

internal/agent/system_prompt_test.go (1)

1-7: Consider using require instead of assert for consistency with coding guidelines.

The coding guidelines recommend stretchr/testify/require for assertions. The existing tests already use assert, so this is a pre-existing pattern, but new test additions could start adopting require for fail-fast behavior.

As per coding guidelines, "Use stretchr/testify/require for assertions and shared fixtures from internal/test instead of duplicating mocks".

internal/cmd/sync.go (1)

232-244: LGTM — CLI now collects publishable DAG IDs before batch publish.

The status-then-filter-then-publish flow is correct and consistent with the frontend's approach. One minor consideration: if no DAGs match (empty dagIDs), the CLI still calls PublishAll — you may want to short-circuit with a message like "No modified DAGs to publish."

Optional early exit
 		var dagIDs []string
 		for id, dagState := range status.DAGs {
 			if dagState.Status == gitsync.StatusModified || dagState.Status == gitsync.StatusUntracked {
 				dagIDs = append(dagIDs, id)
 			}
 		}
+		if len(dagIDs) == 0 {
+			fmt.Println("No modified or untracked DAGs to publish")
+			return nil
+		}
 		result, err = syncSvc.PublishAll(ctx, message, dagIDs)
internal/service/frontend/api/v1/sync.go (1)

122-129: Add validation in the handler to distinguish client error (empty dagIDs) from internal errors.

While PublishAll does validate empty dagIDs and returns ErrNoChanges, the handler converts this error via internalError(err), which sends a 500 response. Since an empty dagIds array is a client error, not a server error, returning a 400 Bad Request from the handler would be more semantically correct and provide a clearer API contract.

Proposed validation
 	var message string
 	var dagIDs []string
 	if req.Body != nil {
 		message = valueOf(req.Body.Message)
 		dagIDs = req.Body.DagIds
 	}

+	if len(dagIDs) == 0 {
+		return nil, &Error{
+			Code:       api.ErrorCodeBadRequest,
+			Message:    "at least one DAG ID is required",
+			HTTPStatus: http.StatusBadRequest,
+		}
+	}
+
 	result, err := a.syncService.PublishAll(ctx, message, dagIDs)
internal/agent/session.go (1)

385-401: Silently discarded errors from memory store could hide configuration issues.

Lines 390 and 393 discard errors from LoadGlobalMemory and LoadDAGMemory. While it's reasonable to proceed without memory if loading fails, a debug log would help with troubleshooting.

♻️ Proposed fix: add debug logging for memory load failures
 func (sm *SessionManager) loadMemory() MemoryContent {
 	if sm.memoryStore == nil {
 		return MemoryContent{}
 	}
-	global, _ := sm.memoryStore.LoadGlobalMemory(context.Background())
+	global, err := sm.memoryStore.LoadGlobalMemory(context.Background())
+	if err != nil {
+		sm.logger.Debug("failed to load global memory", "error", err)
+	}
 	var dagMem string
 	if sm.dagName != "" {
-		dagMem, _ = sm.memoryStore.LoadDAGMemory(context.Background(), sm.dagName)
+		dagMem, err = sm.memoryStore.LoadDAGMemory(context.Background(), sm.dagName)
+		if err != nil {
+			sm.logger.Debug("failed to load DAG memory", "dag", sm.dagName, "error", err)
+		}
 	}
 	return MemoryContent{
 		GlobalMemory: global,
internal/service/frontend/server.go (1)

263-266: Silent error swallowing — inconsistent with the Agent API path.

Line 264 silently discards the error from filememory.New, while the equivalent block at Lines 420-424 logs a warning. Add a warning log here for consistency and debuggability.

♻️ Proposed fix
 	// Wire up agent memory store for the REST API
-	if memoryStore, err := filememory.New(cfg.Paths.DAGsDir); err == nil {
+	memoryStore, err := filememory.New(cfg.Paths.DAGsDir)
+	if err != nil {
+		logger.Warn(ctx, "Failed to create REST API memory store", tag.Error(err))
+	} else {
 		allAPIOptions = append(allAPIOptions, apiv1.WithAgentMemoryStore(memoryStore))
 	}
ui/src/pages/agent-memory/index.tsx (1)

177-187: Error and success banners never auto-dismiss.

The error and success messages stay visible indefinitely. Consider auto-clearing the success message after a few seconds so it doesn't clutter the UI for users performing multiple operations.

♻️ Example: auto-dismiss success messages
useEffect(() => {
  if (!success) return;
  const timer = setTimeout(() => setSuccess(null), 3000);
  return () => clearTimeout(timer);
}, [success]);
ui/src/api/v1/schema.ts (1)

3013-3026: Prefer DAGName for memory DAG identifiers.
dagName and dagMemories are typed as plain strings, while other DAG endpoints use the shared DAGName schema/parameter. Reusing it keeps validation/typing consistent in generated clients (update the OpenAPI source since this file is generated).

♻️ Suggested schema alignment
-            dagMemories?: string[];
+            dagMemories?: components["schemas"]["DAGName"][];

-        AgentDAGMemoryResponse: {
-            dagName: string;
+        AgentDAGMemoryResponse: {
+            dagName: components["schemas"]["DAGName"];
             content: string;
         };

-                dagName: string;
+                dagName: components["parameters"]["DAGName"];

Also applies to: 8014-8133

@yottahmd
Copy link
Collaborator Author

@coderabbitai perform full review

@coderabbitai
Copy link

coderabbitai bot commented Feb 13, 2026

@yottahmd, I'll perform a full review of the PR now.

✅ Actions performed

Full review triggered.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 (3)
internal/agent/system_prompt.go (1)

56-58: ⚠️ Potential issue | 🟡 Minor

Fallback prompt uses wrong identity name.

The fallback says "You are Hermio" but the system prompt template (line 2 of system_prompt.txt) identifies the agent as "Tsumugi". If template rendering ever fails, the agent would introduce itself with a different name.

Proposed fix
 func fallbackPrompt(env EnvironmentInfo) string {
-	return "You are Hermio, an AI assistant for DAG workflows. DAGs Directory: " + env.DAGsDir
+	return "You are Tsumugi, an AI assistant for DAG workflows. DAGs Directory: " + env.DAGsDir
 }
internal/agent/api.go (1)

611-625: ⚠️ Potential issue | 🟠 Major

Reactivated sessions lose per-DAG memory context — DAGName is not restored.

reactivateSession passes MemoryStore (line 624) but omits DAGName. When the session loop is recreated on the next message, loadMemory() will only load global memory, silently losing the per-DAG memory that was available in the original session.

If DAGName isn't persisted in the session store, consider storing it (or the original DAG contexts) so reactivated sessions can restore their memory scope.

#!/bin/bash
# Check if Session struct or store has a DAGName/DAGContext field
echo "=== Session struct ==="
ast-grep --pattern 'type Session struct {
  $$$
}'

echo "=== SessionStore interface ==="
ast-grep --pattern 'type SessionStore interface {
  $$$
}'

echo "=== CreateSession usage ==="
rg -n 'CreateSession' --type=go -C3
internal/gitsync/service.go (1)

539-623: ⚠️ Potential issue | 🟠 Major

Remove the re-staging call to AddAndCommit; commit the already-staged files directly.

PublishAll correctly stages only the selected files (lines 572–576), but AddAndCommit(".", message) immediately re-runs wt.Add(".") internally, which stages all repository changes and defeats selective staging. Instead of calling AddAndCommit(".", ...), directly commit the staged files using wt.Commit(message, ...) to preserve the selective staging.

🤖 Fix all issues with AI agents
In `@internal/agent/system_prompt.txt`:
- Around line 155-171: The <memory_management> block references
{{.Memory.MemoryDir}} and will render broken paths when memory isn't configured;
wrap the entire <memory_management> section (including the Paths lines and rules
mentioning MEMORY.md) in a conditional check like {{if .Memory.MemoryDir}} ...
{{end}} so it only renders when MemoryDir is set, and ensure the guidance still
mentions MEMORY.md and read/patch commands inside that conditional; locate the
<memory_management> section in the template and apply the conditional around its
contents to prevent displaying empty/broken paths.

In `@internal/cmd/sync.go`:
- Around line 233-246: The publishAll branch collects dagIDs from status.DAGs
and may call syncSvc.PublishAll with an empty slice, causing a validation error;
before calling syncSvc.PublishAll (in the block that uses publishAll, status :=
syncSvc.GetStatus(...) and builds dagIDs), check if dagIDs is empty and instead
print a friendly message like "No modified or untracked DAGs to publish" and
return early (nil) to avoid calling syncSvc.PublishAll with an empty dagIDs
slice; update the logic around the dagIDs variable and the PublishAll call to
perform this pre-check.

In `@internal/service/frontend/api/v1/agent_memory.go`:
- Around line 18-41: Rename the package-level error variables to follow the
Err... convention: change errAgentMemoryNotAvailable to
ErrAgentMemoryNotAvailable, errFailedToLoadMemory to ErrFailedToLoadMemory,
errFailedToSaveMemory to ErrFailedToSaveMemory, and errFailedToDeleteMemory to
ErrFailedToDeleteMemory; update all references to these symbols (e.g., usages in
functions like LoadAgentMemory, SaveAgentMemory, DeleteAgentMemory or any
handlers) to the new names and run a build to catch any remaining references.

In `@ui/src/api/v1/schema.ts`:
- Around line 2848-2854: The schema change made dagIds required in
SyncPublishAllRequest will break clients calling /sync/publish-all without that
field; update the OpenAPI source (not this generated file) to make dagIds
optional (e.g., dagIds?: string[]) or add a new request schema/endpoint, and
ensure the server handler for /sync/publish-all (which consumes
SyncPublishAllRequest) implements defaulting behavior (treat missing dagIds as
"all") so backward-compatible requests continue to work; regenerate
ui/src/api/v1/schema.ts from the updated OpenAPI spec.

In `@ui/src/pages/git-sync/index.tsx`:
- Around line 270-281: filteredDags is recreated each render so
publishableDagIds' useMemo is ineffective; fix by memoizing filteredDags first
(e.g., wrap the computation that produces filteredDags in useMemo) with stable
dependencies like status?.dags and filter, then keep publishableDagIds as a
useMemo that depends on the memoized filteredDags (or alternatively derive
publishableDagIds directly from status?.dags and filter in one useMemo). Update
related logic that uses publishableDagIds — allPublishableSelected and
handleToggleSelectAll — to depend on the memoized value so their memoization
becomes effective.
🧹 Nitpick comments (4)
internal/agent/session.go (1)

385-402: Silently swallowed errors in loadMemory may hinder debugging.

LoadGlobalMemory and LoadDAGMemory errors are discarded (lines 391, 394). Since this is supplementary data, not blocking is reasonable, but a debug-level log would help diagnose cases where memory unexpectedly doesn't appear in prompts.

♻️ Suggested improvement
 func (sm *SessionManager) loadMemory() MemoryContent {
 	if sm.memoryStore == nil {
 		return MemoryContent{}
 	}
 	ctx := context.Background()
-	global, _ := sm.memoryStore.LoadGlobalMemory(ctx)
+	global, err := sm.memoryStore.LoadGlobalMemory(ctx)
+	if err != nil {
+		sm.logger.Debug("failed to load global memory", "error", err)
+	}
 	var dagMem string
 	if sm.dagName != "" {
-		dagMem, _ = sm.memoryStore.LoadDAGMemory(ctx, sm.dagName)
+		dagMem, err = sm.memoryStore.LoadDAGMemory(ctx, sm.dagName)
+		if err != nil {
+			sm.logger.Debug("failed to load DAG memory", "error", err, "dag", sm.dagName)
+		}
 	}
ui/src/pages/agent-memory/index.tsx (1)

33-35: useEffect dependency on appBarContext object may cause unnecessary re-runs.

appBarContext is likely a new object reference on each render, causing setTitle to be called repeatedly. Depend on appBarContext.setTitle instead, or extract setTitle from the context before the effect.

♻️ Suggested fix
+  const { setTitle } = appBarContext;
+
   useEffect(() => {
-    appBarContext.setTitle('Agent Memory');
-  }, [appBarContext]);
+    setTitle('Agent Memory');
+  }, [setTitle]);
ui/src/api/v1/schema.ts (2)

3013-3031: Prefer DAGName typing for memory identifiers.

Using the existing DAGName schema improves consistency and validation with the rest of the API. Update in the OpenAPI source so the generated types follow suit.

♻️ Suggested typing refinement
 AgentMemoryResponse: {
     /** `@description` Content of global MEMORY.md */
     globalMemory?: string;
     /** `@description` List of DAG names that have memory files */
-    dagMemories?: string[];
+    dagMemories?: components["schemas"]["DAGName"][];
     /** `@description` Root memory directory path */
     memoryDir?: string;
 };
 AgentDAGMemoryResponse: {
-    dagName: string;
+    dagName: components["schemas"]["DAGName"];
     content: string;
 };

8013-8016: Use DAGName parameter typing for DAG memory routes.

This keeps the DAG path parameters consistent with other DAG endpoints and preserves regex validation in the generated types. Update the OpenAPI source so the generator emits the stronger type.

♻️ Suggested typing refinement
 path: {
     /** `@description` Name of the DAG */
-    dagName: string;
+    dagName: components["parameters"]["DAGName"];
 };

Also applies to: 8067-8070, 8131-8134

@yottahmd yottahmd merged commit d5c68c5 into main Feb 13, 2026
6 checks passed
@yottahmd yottahmd deleted the agent-memory branch February 13, 2026 13:21
@codecov
Copy link

codecov bot commented Feb 13, 2026

Codecov Report

❌ Patch coverage is 46.34703% with 235 lines in your changes missing coverage. Please review.
✅ Project coverage is 69.70%. Comparing base (5394d09) to head (4273c20).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
internal/gitsync/service.go 38.11% 100 Missing and 38 partials ⚠️
internal/persis/filememory/store.go 67.44% 14 Missing and 28 partials ⚠️
internal/gitsync/git.go 0.00% 16 Missing ⚠️
internal/agent/session.go 31.81% 14 Missing and 1 partial ⚠️
internal/cmd/sync.go 0.00% 14 Missing ⚠️
internal/agent/api.go 61.53% 3 Missing and 2 partials ⚠️
internal/gitsync/errors.go 50.00% 3 Missing and 2 partials ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1659      +/-   ##
==========================================
- Coverage   70.18%   69.70%   -0.48%     
==========================================
  Files         344      345       +1     
  Lines       38257    38662     +405     
==========================================
+ Hits        26851    26950      +99     
- Misses       9273     9355      +82     
- Partials     2133     2357     +224     
Files with missing lines Coverage Δ
internal/agent/system_prompt.go 75.00% <100.00%> (+1.66%) ⬆️
internal/agent/types.go 88.88% <ø> (-11.12%) ⬇️
internal/gitsync/state.go 56.25% <100.00%> (+21.55%) ⬆️
internal/persis/filesession/store.go 70.34% <100.00%> (-20.47%) ⬇️
internal/agent/api.go 58.86% <61.53%> (-10.81%) ⬇️
internal/gitsync/errors.go 26.47% <50.00%> (+26.47%) ⬆️
internal/cmd/sync.go 33.63% <0.00%> (-3.81%) ⬇️
internal/agent/session.go 65.73% <31.81%> (-10.53%) ⬇️
internal/gitsync/git.go 15.30% <0.00%> (-3.32%) ⬇️
internal/persis/filememory/store.go 67.44% <67.44%> (ø)
... and 1 more

... and 9 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 5394d09...4273c20. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant