feature/agent-memory-skills-and-unified-model - #135
Merged
Conversation
TOKEN_KEY, authHeaders() y authFetch() viven ahora en un solo modulo. api.ts, auth.ts, ChatInput (transcribe/FormData) y RoutineResultView (AuthImage/blob) lo reutilizan en vez de redefinir "condor_token" y armar el header Bearer a mano. El literal aparece una sola vez en src/. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
selectedTask/pinnedTask result se reparseaba (candles/executors, miles de filas) en cada render: tipear en el form, polls de 2s y toasts. Ahora va en useMemo keyed sobre la referencia cruda del result, estable entre renders de react-query. Solo reparsea cuando llega data nueva de la task. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Los handlers de resize adjuntaban mousemove/mouseup a document en onMouseDown y solo los removian en mouseup. Si el panel se desmontaba a mitad de un drag, los listeners quedaban pegados y cursor/userSelect de document.body corruptos globalmente. Ahora cada drag guarda su teardown en un ref y un useEffect de unmount lo ejecuta. Aplicado en Executors, CreateExecutor (H y V) y AgentFloatingPanel. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…026) onLoaded/onError llamaban setOpenTabs del padre EditorTab desde el render body del hijo (anti-patron "update a component while rendering"). Se mueve el manejo de controllerQuery/configQuery a un useEffect keyed sobre data/isError/error, guardado por loadedRef. El setState del padre se difiere a la fase de commit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
El fin de cada bloque de tool-call se calculaba como headers[i+1].index - name.length - 20, un offset magico que ignora status.length y los digitos de N, cortando antes/despues del header siguiente y contaminando la extraccion de Input/Output. Ahora se guarda start=match.index y blockEnd = headers[i+1].start (exacto). Sin numeros magicos. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
saveMutation.onSuccess solo invalidaba caches para kind === config. Al guardar un .py de controller, la query ['controller-source', ...] quedaba stale (staleTime 5s global) y al reabrir el tab se servia el fuente pre-edicion. Se agrega la rama else para controllers que invalida esa query. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
SessionExecutors fetcheaba los snapshots de a uno en un for await dentro del queryFn, sumando N latencias antes de renderizar las burbujas del chart. Se reemplaza por Promise.all sobre los summaries: corren concurrentemente, el orden por tick se preserva y un snapshot que falla sigue dando burbuja fallback. La latencia colapsa a la del request mas lento. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
configToYaml(config) (yaml.dump + sort) corria en cada render: tipear, toasts y cada tick WS de bots que re-deriva config. Ademas el useEffect [config] reseteaba yamlContent cada tick, pisando ediciones sin guardar. Ahora originalYaml va en useMemo([config]) y el effect de sync se keyea sobre ese string (comparado por valor): un tick con identidad nueva pero contenido igual deja originalYaml estable y las ediciones sobreviven. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
AgentExperimentsTab, AgentSessionsTab, AgentToolbar, AgentFloatingPanel y AgentRoutinesTab formaban una isla aislada sin importers externos (la UI viva del agent usa SessionReviewer y AgentOverviewTab). Duplicaban la state machine de routines y el render de snapshots de experimentos. Confirmado grep cero referencias externas; tsc y vite build limpios. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…EAT-001)
Pure-filesystem MemoryStore keyed by user_id under data/memory/user_{id}/:
one fact per file (frontmatter + body), a regenerated MEMORY.md index, and a
JSONL audit.log. Atomic writes + reindex-from-disk make the index never stale
and safe under concurrent writers. search() is the single seam for future
semantic retrieval. 12 unit tests cover the lifecycle, atomicity and dedup.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… (FEAT-001) manage_memory(write/read/search/list/delete/audit) resolves MemoryStore by settings.user_id and derives the audit source from settings.agent_slug (agent:<slug> vs chat), so both ACP and pydantic-ai backends get it for free. manage_notes becomes a thin deprecated alias mapping onto the same store. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nts (FEAT-001) build_initial_context appends the user's memory index (read on demand via manage_memory) and swaps the deprecated manage_notes for manage_memory in the ACP tool preload. condor.md and agent_builder.md get a MEMORY section telling the agent when to read and write. Nothing is injected for users with no memory. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
build_tick_prompt gains an optional user_memory param rendered as a [USER MEMORY] section (distinct from operational [LEARNINGS]); engine.py reads the owner's memory index fresh each tick (small file read, never blocks a tick). MEMORY guidance added to BASE_PROMPT_COMMON and manage_memory added to the ACP tool preloads. Existing ticks without memory are unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
New handlers/memory shows the user's memory index plus recent audit entries with an inline delete button per memory; deletes go through MemoryStore.delete(..., source="user") so they are audited too. Registered in main.py (command, callback, bot-command menu). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…-001)
One-shot, idempotent script: resolves each chat_{id}.json to a user_id (the
chat_id itself for DMs, else the chat's default-server owner) and writes one
type="reference" memory per key/value. Existing slugs are skipped; source JSON
is left as backup. Ran over the 2 real note files -> 3 memories migrated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…te (FEAT-002) A skill is a markdown playbook (when_to_use + steps) that optionally references an existing routine. SkillStore mirrors MemoryStore 1:1 (file-per-skill + a regenerable SKILLS.md index + the SHARED audit.log, target skill:<slug>). read() validates references_routine against the routine registry and surfaces routine_ok so the agent never invokes a broken reference. Extract append_audit into a free function so memories and skills write the same format to the same per-user audit.log. Unit tests cover create/list/read (with routine validation)/ search/edit/delete and the shared-audit guarantee. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Thin MCP wrapper over SkillStore (create/read/search/list/edit/delete), resolving the store by settings.user_id and deriving the audit source from settings.agent_slug — same pattern as manage_memory. Registered in server.py with a docstring contract teaching when to create a skill and how a playbook references a routine (routine_ok=false → don't invoke). Identical for ACP and pydantic-ai since both connect to the same MCP server. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…h assistants (FEAT-002) Chat (build_initial_context): inject the skills index as [SKILLS — playbooks you can follow] alongside [USER MEMORY]; add manage_skill to the ToolSearch preload. Trading agent (build_tick_prompt): unify the routines section into [AVAILABLE SKILLS & ROUTINES] — skills first (read fresh each tick so an agent sees skills it just created), routines after (cached). Teach BASE_PROMPT_COMMON and both tool-preload strings. Teach condor.md / agent_builder.md to read a playbook before a known flow and save reusable procedures; routine_builder.md gets the playbook→routine bridge note. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extend /memory to show the user's skill playbooks (with their when_to_use and routine-reference status) and a delete button per skill (callback delete_skill:, routed to SkillStore.delete source="user"). The audit.log is already shared, so skill writes/deletes already surfaced under "Recent changes". Closes FEAT-002: move the design doc to features/done/ with status done and commit trail. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Point the commits[] close entry at the actual close commit (fdb52c9); a commit cannot self-reference its own post-amend hash, so this is a small follow-up bookkeeping commit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
AuthImage rendered null until the authenticated blob fetch resolved, then popped in a full-width img that pushed the table/raw-output sections down (large CLS on every report open and instance switch). Now shows a pulsing aspect-[2/1] placeholder while loading and keeps the same aspect box (with object-contain) on the loaded img; failed fetches still collapse to null. Closes PERF-090. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replace hand-rolled `${x >= 0 ? "+" : ""}{x.toFixed(2)}` PnL soup and raw
toLocaleString volumes with formatCurrencyPnl/formatCurrencyVolume/
formatCurrency from lib/formatters, matching Portfolio: negatives render
"-$12.34" (not "$-12.34") and large values compact to K/M.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The amber Agent pill and the synthetic Cmd+K KeyboardEvent hack were copy-pasted across AppShell, ControllerBrowser and ReportBrowser. Extract frontend/src/components/layout/AgentToggleButton.tsx encapsulating the pill styling and the chat-toggle trigger; AppShell passes its active state and own onClick, the two browsers render the shared component. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…RR-098) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s crosshair (PERF-091) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
READ-062: the DRY RUN / RUN ONCE badge ternary was duplicated character-for-character in Agents.tsx and AgentOverviewTab.tsx, and SessionReviewer.tsx encoded the same mode-to-color concept a third way. Centralize it as MODE_STYLES (modeStyles.ts) + ModeBadge component, mirroring the STATUS_STYLES/StatusBadge split. SessionReviewer's compact sidebar keeps its icon+short-label UI and shares only the color map. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tors/Bots pages (READ-075) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…o-server pages (READ-076) Replaces the bare 'Select a server' text on Executors, Active Bots, Runs, Routines, Editor, Backtesting, Create Executor, Create Grid Executor and Archived Bots with the explanatory card Portfolio already had, now extracted to components/NoServerCard.tsx with a 'Go to Settings -> Servers' action. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…EAD-099) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replace hardcoded text-emerald-400/text-red-400 on PnL numbers and buy/sell sides with text-[var(--color-green)]/text-[var(--color-red)] so the colorblind theme (blue/orange) and light theme apply correctly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Nine hand-rolled modals (EditorDialogs x4, StopConfirmDialog, CreateAgentDialog, CreateStrategyDialog + delete confirms, StartSessionDialog, DeployBotDialog) only closed via backdrop or Cancel. Extract the inline Escape effect into useEscapeKey and wire it into every dialog, replacing the duplicated inline effects in AgentDetail and StrategyDetail. Also covers the newer DeleteAgentDialog in Agents.tsx (CORR-077). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Closing a tab whose content differed from originalContent silently discarded unsaved YAML/Python edits. The tab-bar X now routes through requestCloseTab: dirty tabs open a DiscardChangesDialog (same pattern as DeleteConfirmDialog, with Escape support) offering Discard changes / Keep editing; clean tabs still close instantly. The post-delete cleanup path keeps closing directly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s (CORR-093) MarkdownEditor now reports dirtiness via an optional onDirtyChange prop. StrategyDetail and AgentDetail route backdrop click, Escape and the X button through a guard: with unsaved edits they open the shared DiscardChangesDialog instead of silently unmounting the editor; clean modals close exactly as before, and a successful save resets the guard. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Extract a shared ConfirmDialog component and route the three copy-pasted delete-confirm modals (Agents.tsx DeleteAgentDialog, AgentDetail agent and strategy deletes) through it. Its destructive button uses the themed bg-[var(--color-red)] token instead of hardcoded bg-red-500, so agent deletes now honor the colorblind theme's red remap and match the editor dialogs. The dialog also closes on Escape internally via useEscapeKey, replacing the two parent-level registrations in AgentDetail. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nt PnL charts on theme switch (CORR-057) Extend ThemeColors with bg/grid/text and delete the four private getChartColors() copies (TradeChart, ExecutorChart, AgentPnlChart, ArchivedPerformanceCharts) that each called getComputedStyle directly, routing them through the cached getThemeColors() in lib/theme-colors.ts. Replicate TradeChart's data-theme MutationObserver in ExecutorChart and AgentPnlChart so switching dark/light repaints chart background/grid/text immediately instead of leaving stale colors until remount. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add Escape handling and aria-expanded/aria-haspopup to ServerSelector, CurrencySelector, the shared SelectField, and the backtest config picker, matching the existing PairSelector keyboard pattern (CORR-082). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
|
Commit 36ae26a
Retest
|
Extract the byte-for-byte identical PnlTooltip/BottomTooltip components out of AggregatedPnlChart and ControllerPnlChart into a shared components/bots/PnlChartTooltips.tsx, and centralize the fixed series colors (unrealized/volume/position) as PNL_SERIES_COLORS in lib/pnl-chart.ts so strokes, axis ticks, header stats and tooltips reference one source. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Render at most 100 rows initially with a "Show N more" control instead of mounting all up to ~2000 archived executors (~26k DOM cells) at once. Sorting still runs on the full array so top-N by any column stays correct; select-all/CSV/aggregates are computed in the parent from full arrays and are unaffected. No new dependency (no virtualization lib installed). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
|
Commit 99a4752
Retest agents routes and strategy lifecycle, especially /agents/delegations behavior ✅
Re-test bots page parity between REST and websocket updates, including stopping overlays and controller PnL data. ✅
Re-test chat permission isolation with two users. ✅
Re-test risk gating for repeated executor creates in one tick and tracker-failure handling. ✅
Manually validate the new Market Making Expert consult/delegate flow. ✅
|
rapcmia
approved these changes
Jul 3, 2026
rapcmia
left a comment
Contributor
There was a problem hiding this comment.
- Memory separation worked across Condor chat, trading-agent flows, and Routine Builder style routine access.
- The unified agent migration worked: Telegram trading-agent loops still ran, and Condor consult reached the correct unified agent path.
- Trading-agent session launch now carries the correct user identity through
CONDOR_USER_ID. - Condor web login worked correctly, including one-time token use, redirect to the right page, and token invalidation after reuse/logout.
- Protected Condor routes enforced auth correctly, and authenticated agent/delegation routes resolved as expected.
- Access isolation worked: a normal approved user could not reuse an admin user's server-backed consult access.
server_required=truebehavior improved: consult was blocked for no-server users, and launch was also stopped in practice when required checks could not complete.- Normal consult still worked for the matching non-server-required setup.
- Bots page data stayed consistent between REST and websocket updates, including status, PnL, and stopping overlays.
- Delegation flow worked end to end: delegation routes resolved correctly, background tasks completed, and results could be fetched separately.
- Consult and delegation responses rendered clearly in the UI, including markdown tables, headings, bullets, and readable error output.
- The new Market Making Expert flow worked as intended: consult returned inline advice, while delegate ran in the background and finished separately.
- Risk gating blocked repeated executor creation in the same tick after the first approved create.
- FEAT-007 shutdown behavior worked end to end and stayed distinct from normal Stop.
- Dry-run startup no longer showed the earlier obvious journal-write failure.
- Strategy detail correctly showed saved Dry run counts.
- The live hummingbot-api gateway docs no longer showed a passphrase field.
- The Routines page worked in both grid and table views, including search, sorting, and linked report navigation.
- Server pinning worked correctly at runtime once the pinned agent/strategy path was tested directly.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.









What changed
manage_notes is now a deprecated alias. New /memory command to review/prune.
folder form (assistants/condor/AGENT.md); runtime stores gitignored.
removed; endpoints folded into routes/agents.py (/agents/{slug}/consult, /agents/{slug}/strategies/...). Migration script included.
test_memory_store, test_skill_store).
QA recommendations
Migrations (run first, highest risk)
legacy store is archived, not deleted.
Memory & Skills
(isolation is the core FEAT-003 guarantee).
Unified Agent / trading agents
Verify existing brigado agent still ticks after migration.
Hyperliquid connect
double-count.
Security regressions (verify the fixes hold)
Smoke / regression
detail — watch for empty tables or chart render regressions.