diff --git a/docs/personality-memory-agent.md b/docs/personality-memory-agent.md index 0200ab73..27784767 100644 --- a/docs/personality-memory-agent.md +++ b/docs/personality-memory-agent.md @@ -1,260 +1,102 @@ -# EdgeEver lightweight personality and memory agent: plan and tradeoffs +# EdgeEver Agent mode: design and tradeoffs [简体中文](personality-memory-agent.zh-CN.md) -Date: 2026-09-03. Status: an interactive preview is implemented in the workspace, not released. P0 performance/real-model evaluation and full P1 acceptance remain incomplete. +Updated: 2026-09-03. This document describes the current product direction, implementation boundaries, and outstanding validation—not release notes or a development log. Git retains implementation history and verification records. -## Current preview scope (2026-09-03) +## 1. Product positioning -Worker lazy-loading fix (2026-09-03): the previously recorded full-suite failure is resolved. The plugin AI endpoint now imports `ai-runtime` only when generating. The build regression follows the entrypoint's complete static dependency graph, including shared chunks, and excludes AI runtimes and SDKs from startup while confirming they remain reachable on demand. Full non-E2E regression: 1,376 passed, zero failed; web/mobile type checks and the web build passed. No new dependency or migration. +The Agent is a long-term assistant working with the user's knowledge, not just a chatbot familiar with notes or a general-purpose computer operator. Its value is connecting scattered records, understanding enduring interests, and helping organize notes. -- Entry: Settings → AI integration → Agent mode. Off by default; enabling grants access to all notes in the current account, including child notebooks and future notes, without notebook selection. A small bell opens the discovery panel, without a primary navigation tab or system notifications. “Conversation and personal memory” in settings retains the optional `/companion` workspace. No native Android/iOS entry yet. -- Requires a signed-in personal account on a non-demo instance with login enabled and reuses the configured default model. Disabling stops discovery and invalidates unconfirmed discovery actions. The optional conversation workspace keeps its independent per-turn note permission. The prompt library only manages note-processing templates. -- One stable identity and an on-demand ToolLoopAgent. Users explicitly add memories or save their own words, correct/forget them and reuse them in new conversations. No automatic candidates, background full-library scanning or reminders. Note writes require individual confirmation; notes are not modified automatically. -- Instance-server storage is isolated by workspace and user; Cloudflare/Docker share business logic. Migrations `0040`–`0043` cover memory, actions, tool execution and discovery; no changes to previously executed migrations, dependency manifests or release versions. No migration was applied to real instances. -- Note access defaults off. Enabling it exposes 28 note-related tools from the existing MCP catalog through the same business executor. Authorized reads cover notes, trash, history, tags and notebooks; content updates and merges require fully read sources. The model can only read, preview and propose; confirmation APIs execute persisted arguments. No external sending or system-control tools. -- With memory disabled, complete prior turns from the same conversation remain eligible only if they did not use memory or cite notes; memory-enabled replies are excluded. Memory edits/forgetting still invalidate old context and cancel running generation; previous replies citing notes are not resent automatically. Existing chat text/source snapshots remain: note deletion is not chat deletion. Clear chats separately; exported files and provider-held data are outside this deletion control. -- Request IDs are allocated/persisted before generation; recover by ID after disconnection, never automatically repeat a model call. Failure/cancellation retain recoverable results. A subsequent read marks abandoned runs interrupted after their 90-second expiry. No permanent polling or background replay. -- Separate JSON export includes memories, chats and organization records. Import atomically merges/deduplicates memories without replacing existing entries; it does not restore chats or organization records. Preview data is not included in note ZIP backups, desktop offline mirrors or native mobile sync; the UI discloses this. +The product must stay lightweight, fast, and reliable. Presence can be subtle; suggestions must be useful. Personality should emerge through continuing understanding, accurate memory, and measured actions—not anthropomorphic lines, simulated emotions, or frequent interruptions. Chat is a supporting entry point, not the primary experience. -### Quiet discoveries (2026-09-03, current implementation) +The main flow is: normal note-taking → the Agent identifies an opportunity at an appropriate time → grounded information or an action proposal → execution after confirmation. Without a worthwhile result, remain quiet. -Agent-mode refinement: 20 discovery/UI tests pass, including cross-notebook operations, child and newly created notebooks, account isolation and global retrieval budgets. Web/mobile type checks and the web build pass. The live local settings page shows “Agent mode”, no notebook picker, and an available switch; verification did not enable the feature or call a paid model. Existing shadcn controls were reused and notebook-selection state/props removed. No new dependency or migration is needed for this refinement. +## 2. Interaction rules -- Two notification types: useful knowledge connections without required action, and persisted note-operation proposals. Neither creates a normal note or an “AI draft”. Source links and exact changes are reviewable; confirmation executes existing tools without another model decision. -- Three initial scenarios: combine fragments of one idea, append a new fragment to an existing note, and resurface related older knowledge. Append preserves both notes and original text, supports plain-text notes only and rejects attached resources; rich documents should use the lossless merge tool. Merge moves sources to trash and revokes shares; no undo-all promise. -- Agent mode can read and propose operations across all notebooks in the current account; writes still require confirmation. Other accounts remain isolated. After one minute without input, an open, visible, online client with no pending local changes may check. A persisted cross-device claim limits attempts to once per 24 hours and skips unchanged libraries; no timer daemon, polling loop, embeddings or bundled model. A check can incur provider charges even if no discovery is shown. -- Retrieval uses one workspace-wide recent query (12 summaries) and at most one keyword query (8 summaries), then at most six complete note bodies totaling 12,000 characters, each at most 8,000. Budgets do not grow with notebook count. The latest anchor must be within 14 days. One structured ToolLoopAgent generation, 1,200 output-token limit, no tools, no model retry, 60-second cancellation. Model-facing data excludes personal memories, full note JSON and other accounts' content. -- The model selects a connection, not executable arguments. The server validates all source IDs and constructs merge/append arguments using existing APIs. Publication checks settings version, context revision, turn state and workspace cursor in one transaction. Disabling cancels unconfirmed work; already-started confirmed operations retain receipts. Source changes hide stale discoveries and block confirmation. The old notebook-selection storage column remains for migration compatibility but is no longer an authorization filter; settings requests contain only enabled/version and reject obsolete notebook-selection fields. -- The bell uses only an unread dot; nothing opens automatically. Seen status follows visible cards, and skipping a source group suppresses that group. Display is limited to 20 items from the past seven days; proposals expire after 24 hours. Old records stay available in the separate JSON export until history is cleared. Discovery turns do not enter chat history; all retained turns still share the existing 500-record cap. Clearing companion history also removes discovery records and deduplication, but retains settings/cooldown; import remains memory-only. -- Known tradeoffs: keyword retrieval can miss semantic connections; the broad workspace cursor invalidates suggestions even for unrelated edits. These conservative first-release choices favor safety and bounded resource use. No claim of tested real-model relevance, installer delta or resident-memory delta. No new dependencies, real-instance migrations, paid model calls or release changes in this iteration. -- Verification: 19 new discovery tests pass (including the actual SDK with a mock provider), alongside the existing companion regression. Web/mobile type checks and the production web build pass. The full non-E2E suite reports 1,364 passing and one existing failure: `plugin-capability-routes.ts` statically imports `ai-runtime`, violating the Worker lazy-loading gate; this iteration did not edit that file. Isolated browser fixtures verified default-off consent, both notification types, confirmation receipts, opening results, refresh recovery, disabling and 390px layout; temporary files/server were removed. The discovery-panel chunk is 5.77 kB / 2.33 kB gzip, excluding shared code and settings—not an installer-size measurement. No commit, push or deployment was made. +- Entry: Settings → AI integration → Agent mode, off by default. Enabling covers all notes in the current account, including child notebooks and future notes, without notebook selection. This does not mean reading or sending the entire library at once. +- Use a small bell and unread dot, without primary navigation, automatic popups, or system notifications. Currently available to signed-in personal accounts on non-demo instances with login enabled; no native Android/iOS entry yet. +- Informational notifications offer useful connections, explanations, and source links without requiring a task. Action notifications explain which notes will change, how, and with what consequences; confirmation invokes existing note capabilities. +- Suggestions do not enter the normal note list or automatically become “AI suggestion drafts.” Notes are created or modified only after confirmation of the corresponding write. +- Users may dismiss suggestions or disable the mode. Disabling invalidates unconfirmed discovery actions; already-started confirmed operations retain receipts. Disabling does not undo completed changes. -### Shared note-tool integration (2026-09-03, previous iteration) +The settings page keeps only a short benefit description: -- `mcp-tool-executor.ts` is the shared execution entry for remote MCP and the built-in AI. Tool names, descriptions and parameter schemas come from `MCP_TOOLS`. Only exposure policy and confirmation adaptation are added; no copied note business logic, MCP client, second agent framework or additional dependency. -- The 28 tools comprise 13 reads and 15 confirmed writes: create/import/update notes, merge, move, add/remove/rename/delete tags, trash/restore notes, restore revisions, and create/rename/move notebooks. Permanent deletion, public sharing, binary uploads, template/AI instruction management and system administration are not exposed; arbitrary operations are not supported. -- Write tools persist exact arguments and a reason; execution uses those arguments without another model call. Cards show the operation, source excerpts, resolved notebook names, full proposed content, account-wide tag impact counts and consequences. Content changes clearly replace rather than append. Legacy merge/tag cards remain compatible; new proposals use shared tools. -- Existing sync change cursors plus source content revisions and metadata protect confirmation. Each service write batch receives an execution claim and cursor check, preventing duplicate confirmation. Completed receipts recover normally; a connection loss after a write produces an uncertain result that is never automatically replayed. Multi-batch operations may partially complete and do not promise whole-operation atomic rollback. -- Conflict handling is deliberately conservative: any note/notebook change after generation requires a new proposal, so applying one action may invalidate other pending proposals. Explicit target sets are limited to 25 notes and argument JSON to 24,000 characters; each turn permits 3 proposals with 24-hour expiry. Operations depending on new object IDs are generated after confirming the prerequisite, never against invented IDs. -- With note access enabled, subsequent turns can read the latest 6 execution receipts in this conversation within 4,000 characters, isolated by account, conversation and memory revision. Disabling note access excludes note-tool metadata and receipts; disabling memory excludes records from memory-enabled turns. -- All 87 focused tests pass, covering 15 writes, argument tampering, cross-user confirmation, changed versions, concurrent confirmation, lost commit acknowledgements and receipt permissions. Web/mobile type checks and the web build pass. The full suite reports 1342 passing and 1 failing: separate uncommitted `plugin-capability-routes.ts` changes statically import the AI runtime and fail the Worker lazy-loading gate; that file was not changed in this iteration. -- Browser checks against isolated storage passed: review then update content, tags and notebook together, inspect the actual result, and refresh to retain the applied receipt. No real notes or paid models were used; temporary pages and the server were removed. No commit, deployment or release was made. Real-provider compatibility and complex-task quality still need evaluation. -- At that iteration, entry prominence and proactive discovery were unchanged; the quiet-discovery iteration above supersedes that entry design. Tool catalog coverage does not imply autonomous authority or a persistent background agent. +> Combine scattered ideas, add to existing notes, and rediscover related knowledge. Changes require your confirmation. -### Previous organization iteration: merge notes and append tags (historical record) +## 3. Current capabilities and boundaries -- Standalone organization cards do not automatically create ordinary notes or “AI suggestion drafts.” Cards start collapsed; expanding reveals reasons, source excerpts, existing tags, merge order and consequences. Only explicit confirmation modifies notes; suggestions can also be dismissed. -- Each merge uses 2–5 notes fully read in the current run, preserves bodies, attachments and tags in reviewed order, and creates the result in the first source's notebook. Sources enter trash and their shares are revoked; restoring sources is not a complete undo. The model must not recommend merging merely because notes share a broad topic, and execution does not rewrite or shorten content. -- Each tag suggestion appends at most 5 tags, preferring existing vocabulary without replacing tags or bodies. Additions exceeding 24 tags are rejected rather than silently dropping existing tags. Each turn allows at most 3 proposals, expiring after 24 hours. -- Confirmation checks this device's offline status and pending sync queue. One server transaction checks the account, completed turn, memory revision, source body revisions, modification times, notebooks and tags, then writes both notes and the execution receipt. Stale/dismissed proposals and changed sources cannot execute; repeated confirmation or reconnect retries return the same result. -- Cards currently live in the preview workspace and can be reused in a later quiet “Discover” entry. A global default-off toggle, proactive discovery triggers, background generation and a quiet entry remain unimplemented; this iteration only adds user-requested organization. Existing AI SDK, note services and UI components are reused, with no new dependencies or persistent processes. -- Browser checks against an isolated in-memory database covered tag additions, confirmed merging, opening results and persistent receipts after refresh. No user notes were modified and no paid model was called. Real-model judgment about which ideas belong together still needs evaluation. -- All 50 focused tests, `bun run typecheck`, `bun run typecheck:mobile` and `bun run build:web` pass; the existing local-mirror dynamic-import warning remains. -- This iteration's full shared-workspace regression reports 1307 passing and 1 failing: separate uncommitted plugin changes statically import the AI runtime and still fail the Worker lazy-loading gate. This iteration leaves those plugin files untouched and does not claim a clean full suite. Temporary browser fixtures and their server were removed; no commit, deployment or release was made. - -### Implementation budgets - -Entry hierarchy verification: built-in browser checks passed for desktop primary navigation, the 390px mobile web entry, standalone refresh, and browser back/forward. Chat/memory switching and the composer were checked with isolated empty fixtures; no real model was called and no personal memory was written. All 30 focused tests, web/mobile type checks, and the web build pass. The shared workspace's full suite reports 1287 passing and 1 failing: the same Worker AI runtime lazy-loading gate affected by the separate uncommitted plugin changes. - -| Item | Current constraint | -| --- | --- | -| New runtime dependencies / always-on processes / bundled models | 0 / 0 / 0 | -| Stored memories / per-request memory context | 50 × 500 characters / 8,000 characters; Unicode segmentation, frequency-weighted matching and update recency, not semantic retrieval | -| Stored history / one list / per-request history | 500 requests / latest 100 / at most 6 eligible prior turns, totaling at most 12,000 characters | -| Input / response length | 4,000 / 16,000 characters | -| Tools / note text | 28 available tools, at most 16 calls; 5 results per search/list; cumulative 12,000 characters of bodies/excerpts and 12,000 characters of other tool outputs | -| Model steps / output / timeout | At most 8 steps; 2,048 output tokens per step (not the whole run); cancel after 60 seconds | -| Concurrency / retries | 1 running request per account; 0 automatic model retries | - -### Verification and outstanding gates - -Initial API/storage/actual SDK tests with mock models cover account isolation, conflicts, atomic import capacity, forgetting/context invalidation, tool permissions, duplicate requests, partial-output recovery and UTF-8 stream parsing. Initial browser checks with an isolated in-memory database/fake model cover adding/correcting memories, chatting and disabling memory. No user-paid model calls or real notes were sent. At the initial handoff, the full non-E2E suite passed 1263 tests; this iteration's results are below. - -The initial web production build's standalone chat-component chunk was 9.62 kB, or 3.25 kB gzip. It excludes other shared-client/translation changes and is not the total installer delta. The existing local-mirror dynamic-import warning remains in the web build. - -### Second iteration (2026-09-03) - -- Use built-in `Intl.Segmenter` with NFKC normalization, common stop-word filtering and higher weights for uncommon terms. Chinese questions can match older relevant memories; English matches words rather than substrings such as Rust inside trust. No new dependency, embedding call or persistent index. -- Preserve safe same-conversation continuity when long-term memory is off. Exclude other conversations, expired context revisions, failed turns and replies that may contain memory/note data. The 12,000-character history budget admits complete question/answer pairs; older content is not inserted around a newer pair that does not fit. -- Memory preconditions, context invalidation and mutations share one database transaction. Stale versions, capacity failures, empty imports and fully duplicate imports no longer interrupt generation; successful edits/forgetting still cancel old-context requests. No new migration. -- All 19 focused tests pass, as do web/mobile type checks and web/Worker builds. One full-suite run reported 1277 passing and 1 failing: another uncommitted change in the shared workspace statically imports `ai-runtime` from `plugin-research-routes.ts`, failing the Worker lazy-loading gate. This iteration leaves that plugin file untouched and does not claim a clean full suite. -- A synthetic local Bun 1.3.14 microbenchmark with 50 memories and 50 retrievals measured approximately 0.14 ms median / 0.19 ms P95. This only checks local retrieval overhead, not actual Worker CPU, model recall accuracy or an Electron resource baseline. Real-model and cross-platform performance gates remain incomplete. - -Pre-commit verification: exclude the separate plugin changes, export this feature's staged snapshot to an isolated directory, install dependencies from the frozen lockfile, and revalidate. The full non-E2E suite reports **1269 passing, 0 failing**, including the Worker AI runtime lazy-loading gate. `bun run typecheck`, `bun run typecheck:mobile`, and `bun run build:web` also pass. This commit includes no plugin feature, dependency-manifest or lockfile changes; the shared workspace's plugin edits remain untouched. - -This is not full P0/P1 acceptance. Real-provider compatibility, personality consistency, adversarial injection and before/after Electron package/startup/RSS measurements remain release gates. Lazy-loading the component and keeping the SDK server-side do not imply zero package/memory growth. Relationship modeling, automatic memory candidates and proactive actions remain unimplemented. - -## 1. Product positioning and decision - -EdgeEver aims to become a personal agent whose long-term memory is grounded in the user's knowledge, not merely a notes product with AI buttons. Notes carry knowledge and evidence; a stable identity, understanding of the user, shared experiences, and trustworthy actions create the sense of a continuing companion. - -The core experience is remembering what matters, connecting past and present, keeping track of commitments, and accepting corrections. Personality should emerge through consistent, honest, considerate behavior, not simulated emotions or manufactured dependency. - -**Decision: reuse the existing AI SDK `ToolLoopAgent` and build EdgeEver-owned identity, relationship, memory, permission, and action domains. Constrain phase one to zero additional runtime dependencies; do not introduce Mastra, ElizaOS, or another database.** - -Lightweight, fast, and reliable are product requirements. Deepen personality and memory without turning the first release into a general-purpose agent platform. Identity, memories, and evidence should remain exportable, restorable, and usable after changing models, devices, or frameworks. Data portability does not guarantee identical expression across models; that needs evaluation. - -## 2. Existing foundations and missing capabilities - -Existing foundations: - -| Foundation | Reuse | -| --- | --- | -| `ai` and existing OpenAI-compatible / Anthropic / Google providers | Agent loop, model access, streaming; preserve BYOM without requiring a new gateway | -| Zod | Domain data and tool input validation | -| SQLite / D1 and existing storage adapters | Persistence, account isolation, retrieval; shared business logic across runtimes | -| Rust desktop sidecar | Desktop local-data ownership and persistence adapter, without another LibSQL dependency | -| Existing note search, API, revision history | Tool data access, answer citations, and the basis for later mutation audits | -| Existing Croner and scheduled-task code | A foundation for later bounded reminders, not an existing durable task engine | -| Plugin API and MCP server | Extension boundaries; an MCP server does not imply an external MCP client or its security controls already exist | - -Before implementation, consult the [README](../README.md), [model adapter](../apps/api/src/ai-runtime.ts), [shared storage contract](../apps/api/src/storage-contract.ts), [cross-runtime architecture](self-hosting-architecture.md), and [desktop packaging configuration](../apps/desktop/electron-builder.yml). - -The original text generation lacked personality memory. The preview adds basic conversation storage, explicit memory governance, read/propose permissions, confirmed execution and recovery; full capabilities and performance gates still follow the plan below. Zero new dependencies does not mean zero new code, model cost, or maintenance. - -## 3. Why this approach - -| Option | Strengths | Costs and decision | +| Path | Current capability | Boundary | | --- | --- | --- | -| AI SDK + EdgeEver domain layer | Reuses model adapters; composable; identity and data remain independent of a framework | Requires product-specific memory governance and permissions; selected for phase one | -| Mastra | Integrated memory, workflows, approvals, orchestration, and observability | Additional dependency and runtime cost not yet justified by concrete requirements; defer | -| ElizaOS Core | Personality/autonomous-agent concepts and plugin ecosystem align with the vision | Requires reconciling its memory, plugin, and host concepts with EdgeEver; defer while learning from its design | -| A custom general-purpose agent/workflow framework | Maximum freedom | High maintenance risk; rejected. Reuse the AI SDK loop instead of rebuilding mature general capabilities | +| Proactive discovery: connections | Resurface related older notes and explain their connection to new records | Sources required; no notification without a suitable result | +| Proactive discovery: merge | Combine fragments of one idea while preserving text, attachments, and tags | Confirmation required; sources move to trash and their shares are revoked; no complete one-click undo promise | +| Proactive discovery: append | Add a new fragment to an existing note while preserving the source and original target content | Currently limited to plain-text notes without attachments; no automatic rewriting of rich documents | +| Optional conversation: note tools | 28 existing tools: 13 reads and 15 confirmed writes covering creation, import, editing, merging, moving, tags, trash, revision recovery, and notebook organization | Discovery does not propose all these operations; permanent deletion, public sharing, binary uploads, and system administration are not exposed | -### Size and memory observations during selection +“Conversation and personal memory” remains an optional settings entry. Conversation currently has independent note-access and memory controls, with note access off by default; these are not unified with the Agent-mode switch. This is the implementation state, not a requirement to select notebooks, and must not be presented as a single permission switch across the product. -An exploratory test ran in a temporary directory on 2026-09-02: macOS ARM64, Node 26.3.1, Bun 1.3.14; `ai@7.0.58`, `@mastra/core@1.63.2`, `@mastra/memory@1.28.1`, and `@mastra/libsql@1.22.2`. These identify the tested versions, not future latest releases. +“Note-operation capabilities” means reusing existing APIs and business services, not building another note system or granting unattended write authority to the model. Proactive tagging and other notification-based organization scenarios are not yet connected; the full tool catalog must not be advertised as proactive functionality. -The test imported entry points, retained class/function references, and bundled with Bun `--target=node --minify`. `/usr/bin/time -l` measured startup peak RSS; direct ESM imports were measured separately. No model requests, real conversations, or complete storage paths were exercised. +## 4. Personality and memory -| Exploratory entry point | Single-file bundle (approximate, decimal) | Bundled process startup peak RSS (approximate, decimal) | -| --- | --- | --- | -| Empty Node | Negligible | 50 MB | -| AI SDK `ToolLoopAgent` | 0.38 MB | This bundle was not measured; direct ESM control was about 72 MB | -| Mastra Agent | 5.1 MB | 145 MB | -| Mastra Agent + Memory | 6.1 MB | 172 MB | +The long-term goal is for suggestions to reflect preferences, project context, shared decisions, and feedback. Personality and memory belong to EdgeEver's product data and behavior rules, not to a particular model; their value does not depend on adding a dedicated chat surface. -Mastra Core reported an npm unpacked size of about 66.2 MB, including substantial source maps and declarations; this is not the installer delta. Direct ESM startup peaks were about 174–185 MB for Mastra Agent and 185–186 MB for Agent + Memory; a separate post-GC RSS snapshot was about 196 MB. Startup peak, instantaneous RSS, and long-term idle usage are different measurements. +Implemented today: -Limitations: scripts and raw outputs were not committed as a reproducible benchmark; capabilities were not equivalent, and Electron, Windows, and real agent workloads were not tested. gzip is not DMG/NSIS, and a tree-shaken bundle does not prove inclusion of dynamic assets or native dependencies. Do not infer guaranteed installer growth, resident memory, or performance ratios. The only conclusion is that additional framework cost warrants scrutiny; production metrics require new measurements. +- A product-controlled stable identity, conversation continuity, and explicit cross-conversation memory in the optional conversation workspace. +- Users manually add memories or save their own words through the UI, and can correct, forget, or suspend their use. The model cannot independently add or remove memories. +- Small-scale retrieval using segmentation, weighted keywords, and update recency, without a vector index. Memory edits/forgetting invalidate old context; user-confirmed information must remain distinct from model inference. +- Server-side storage isolated by workspace and user. Separate JSON export includes memories, chats, and organization records; import merges memories only, not chats or execution records. -## 4. Phase-one scope and non-goals +Not yet connected: proactive discovery does not read personal memory. Current notifications must not be described as understanding long-term preferences. Automatic memory candidates, relationship modeling, and suggestion adaptation based on long-term feedback are also unimplemented. -Phase one includes only: +The next priority is to test whether controlled memory improves relevance, not to expand personality settings. Connecting memory to discovery requires explicit user control, provenance, correction, and forgetting propagation; do not silently broaden memory use. Dismissing one notification should not directly become a lasting preference. -- One user-visible agent and one stable default identity. -- Explicit user preferences, goals, and a small set of shared experiences persisted across conversations. -- Knowledge answers using existing note search, with important claims linked to evidence. -- Explicit requests to remember information or review of model-proposed memory candidates. -- A “What she remembers about me” interface for inspecting, correcting, forgetting, and managing sources. -- Cancellation at any time; model or memory failures must not disrupt normal note operations. +Deleting a note does not delete its text or snapshots in chats; forgetting a memory does not delete its source. This data is not yet included in note ZIP backups, desktop offline mirrors, or native mobile sync. Do not promise full cross-device recovery or deletion of exported files or provider-retained data. -The product owns and versions the default identity. Leave room for user-selected names and communication style, but no character marketplace in phase one. The model must not rewrite core identity or permissions. +## 5. Technical and reliability tradeoffs -Exclude multi-agent systems, vector databases, knowledge graphs, background full-library scans, emotion simulation, general workflow engines, always-on autonomous loops, shell/computer control, automatic external messages/publication, and dynamic third-party agent plugin installation. Do not bundle local inference models with the client. +### Reuse existing capabilities -These are sequencing boundaries, not permanent product limits. Validate the experience of being remembered, understood, and able to correct the agent before adding proactive actions. +Keep AI SDK `ToolLoopAgent` and existing model configuration; EdgeEver manages identity, memory, permissions, proposals, and execution receipts. Do not currently introduce Mastra, ElizaOS, a second database, or a custom general-purpose agent/workflow framework. -## 5. Data and memory model +Tool names and parameters come from the existing MCP catalog and use the same business executor. Add only Agent exposure policy, preview, and confirmation adaptation. Cloudflare and Docker share business logic. Agent UI and server-side AI runtimes load on demand; build tests inspect the entire startup dependency graph, including shared chunks. -| Domain | Content and boundary | -| --- | --- | -| Identity | Name, purpose, values, expression, and relationship boundaries; controlled updates | -| User model | Explicit preferences, projects, people, and goals; inferences are not facts | -| Relationship / shared experiences | Joint decisions, user feedback, commitments, unfinished topics; no model-generated trust score grants permissions | -| Working context | Current conversation, task, transient tool results; bounded by size and time | -| Evidence | Original notes, messages, revisions, and action results; the factual source of knowledge | +There are no new runtime dependencies, always-on autonomous processes, or bundled local models. No new dependencies does not mean zero package growth, memory use, model fees, or maintenance. Measure actual deltas rather than promising results from early, non-reproducible framework comparisons. -Long-term memories should include instance/account scope, category, content, provenance, status, creation/update times, event time when known, sensitivity, user confirmation, and supersession links. Model confidence is a ranking hint, not a calibrated probability or an authorization signal. +### Projects considered and why they were not adopted -Conceptual tables may start with `agent_profiles`, `agent_memories`, and `agent_memory_sources`; add `agent_threads` and `agent_messages` if no reusable conversation store exists. Names and counts are not finalized SQL. Design indexes, account scope, sync conflicts, backup, and deletion semantics before adding incrementally numbered migrations. Never edit executed migrations or introduce another source of truth for notes. +- [ElizaOS](https://github.com/elizaos/eliza): considered as a reference for personality, memory, and plugin-based agents. EdgeEver already has note storage, plugins, and permissions; adopting another agent runtime would require reconciling its memory, state, and plugin contracts. Current lightweight discovery and confirmed organization do not yet justify that adaptation cost. Retain design ideas without adopting the runtime. +- [Mastra](https://github.com/mastra-ai/mastra): evaluated for its TypeScript agents, memory, workflows, and human approval capabilities. Model integration, the tool loop, and note execution already have reusable foundations, while current flows do not require full workflow orchestration. A framework would still require EdgeEver-specific permissions, version checks, and memory governance; the benefits do not yet justify additional dependencies and integration maintenance. -### Memory lifecycle +This is a provisional decision based on current scope and architecture, not a claim that either framework cannot be embedded in Electron or necessarily consumes excessive resources. Reevaluate if requirements outgrow the maintainable scope of the existing approach, using package-size, memory, and startup measurements from an actual integration. -1. User messages or authorized tool results produce candidates; retrieved notes are not new system instructions. -2. Validate evidence, account scope, sensitivity, duplicates, and conflicts; retain only information useful for future interactions. -3. “Please remember” can authorize that specific memory. Automatic extraction is off by default; when enabled, only low-risk explicit facts qualify for automatic acceptance. Sensitive information is not saved automatically. -4. Inferences await confirmation. Credentials and tokens must not enter memory. Do not promise perfect model-based sensitivity detection; let users disable extraction and exclude sources. -5. User corrections take precedence. Superseded memories leave active retrieval and may retain explainable replacement links. -6. Forgetting removes content from active memory and derived summaries/indexes, and prevents silent re-extraction from the same source. Deleting original chats or notes is a separate user choice; disclose backup retention and handling of deletion markers after restoration. +### Bounded cost -Deleted, invalid, or newly inaccessible sources require revalidation of dependent memories; they must not continue leaking the original content. Clear running context on account or instance switches. In-flight results must never be written to the newly selected account. +- Proactive checks run only while the app is open, visible, online, free of pending sync changes, and idle for one minute. A cross-device limit allows at most one attempt per account per 24 hours; unchanged notes are skipped. This is not an always-running background service. +- Each check selects a small set from recent records and keyword searches: at most six note bodies totaling 12,000 characters. One structured generation, at most 1,200 output tokens, cancellation after 60 seconds, and no automatic model retries. +- Full conversations have separate tool-call, context, concurrency, and timeout budgets. Library-wide authorization does not mean putting the entire library into a prompt. +- Selected content is sent to the user's configured default model provider. A check can incur charges without producing a visible suggestion. Keyword retrieval may miss semantic connections, and low-frequency checks do not guarantee timely discovery of every opportunity. -### Retrieval and cost +### Confirmation and recovery -Assemble stable identity, a small user model, recent messages, a few relevant memories, and on-demand note search results. Start with existing search and category/project/time/status filters, not full-library prompts. Build real retrieval tests for Chinese, aliases, paraphrases, and temporal questions rather than assuming keyword search is sufficient forever. +1. The model proposes; the server validates sources and arguments. For proactive merges/appends, the server constructs the arguments. Persist the exact operation, reason, and data versions; a proposal does not modify notes. +2. Confirmation binds to that operation, without another model decision at execution. Check account, expiry, source versions, and sync state; expired proposals or changed data require regeneration. +3. Reuse transactions, execution claims, and persistent receipts to prevent duplicate confirmation and concurrent overwrites. Recover or query outcomes after disconnection; generated text is not a success receipt, and uncertain writes must not be blindly replayed. +4. Multi-batch operations may partially complete; cancellation does not roll back completed effects. The current workspace-cursor policy is conservative, so unrelated note changes may also invalidate other proposals. -Bound tool steps, context size, response time, concurrency, summarization frequency, and model cost. Phase one uses an explicit memory-candidate tool instead of requiring another summarization call every turn. Later compression must preserve evidence and be evaluated for lost commitments and altered facts. +Notes, memories, attachments, and tool results are untrusted data. They cannot change identity, grant permissions, or forge confirmation. Do not expose shell/computer control, automatic external messaging, or publication, or relax authorization because the Agent “knows the user.” -## 6. Runtime and security boundaries +Implementation entry points: [discovery](../apps/api/src/companion-discovery.ts), [conversation and memory retrieval](../apps/api/src/companion-runtime.ts), [tool catalog](../apps/api/src/companion-tool-catalog.ts), [confirmed execution](../apps/api/src/companion-tool-actions.ts). -```text -Client: chat, citations, memory management, approval/cancellation - → Authenticated transport (HTTP; narrow IPC only for local mode) - → Shared agent domain services: identity, context, permissions, audit - → AI SDK ToolLoopAgent: existing user model configuration - → Allowlisted tools: application validation → authorization → storage/business services → result -``` +## 6. Outstanding validation and priorities -Prefer the existing server-side model-credential and generation path. Do not add an always-on desktop process by default or put SDK credentials in the renderer. A local desktop agent is an optional execution mode requiring validation: only when local execution is needed should implementation choose an on-demand main-process module or isolated process and measure lifecycle, packaging, and permissions. Local knowledge storage does not mean remote model calls keep that knowledge on-device. +- Build a real-note evaluation set: whether fragments belong to one idea, whether merging/appending is worthwhile, and whether connections are useful. Measure false positives, interruptions, acceptance, and harmful organization—not notification count or chat duration. +- Validate structured outputs, tool calling, cancellation, source accuracy, and prompt-injection defenses with real models. Model failures must not disrupt ordinary note operations. +- Measure installer size, cold start, CPU, RSS/heap, and model costs with the Agent disabled, idle, on first use, during sustained use, and after cancellation. Separate client and server measurements; use the [desktop performance baseline](desktop-performance-baseline.md). +- Once current scenarios are reliable, evaluate memory-informed suggestions, proactive tagging, and consistent permissions across conversation and Agent mode. These document goals are not completed features. +- Complete backup/recovery, deletion propagation, and cross-device experience. Automation, reminders, multiple agents, and heavier retrieval infrastructure are not in the current default scope; reconsider only when actual needs and measurements justify them. -Cloudflare and Docker share business services with thin entry/driver adapters; do not rely on an in-process loop continuing after a Workers response. Desktop adapts the existing sidecar. Android and iOS initially reuse the protocol rather than implementing separate agent business logic. Offline note editing and access to synchronized data continue, but remote model unavailability must be explicit rather than presented as successful execution. +Implementation changes must pass relevant tests, the full non-E2E suite, `bun run typecheck`, `bun run typecheck:mobile`, and `bun run build:web`. Passing tests does not establish suggestion quality or acceptable resource usage. -Keep initial candidate tools below eight, for example `search_notes`, `read_note`, `propose_memory`, `list_relevant_memories`, `correct_memory`, and `forget_memory`. Corrections and deletion must bind to verifiable user intent/confirmation, not a model claim that permission was granted. The memory UI can call deterministic APIs directly without routing through a model. - -Note writes separate proposal from approved execution. Every tool needs input validation, account/object authorization, quotas, and audit. Approval binds to the concrete operation, arguments, and data version; expiry or changed content requires renewed confirmation. Tool results, notes, attachments, and memories are untrusted data: they cannot grant tools, change permissions, or become identity instructions. - -Database transactions and version checks prevent partial writes and overwriting concurrent edits. Stable operation IDs and execution records reduce duplicates. Transactions do not guarantee exactly-once effects in external services: query uncertain outcomes or ask the user instead of blindly retrying. Cancellation does not reverse completed side effects; report the completed portion. - -## 7. Reliability and product controls - -“What she remembers about me” should distinguish user-confirmed information, direct statements, and AI inferences; show evidence and change history; and support editing, confirmation, forgetting, pausing memory, and source exclusion. Personality must not manipulate intimacy or pressure users to keep interacting. - -Load agent UI on demand. With AI disabled, do not scan, poll, issue paid requests, or block startup, editing, search, or sync. Preserve chat drafts on failure and accurately report retrieval, memory persistence, and tool status. Generated text is not evidence that an action succeeded. - -Defer automation. Initially persist only necessary conversation and execution state, without building a general durable workflow engine. Future states such as `pending / running / awaiting_approval / completed / failed / cancelled` are only part of a recovery protocol; ownership, leases, timeouts, idempotency, version conflicts, and expired authorization still matter. Persisted state is not safe replay. Cross-device reminders also need deduplication, time zones, quiet hours, and missed-delivery policy. - -## 8. Phases and acceptance criteria - -### P0: baseline and read-only validation - -- Build a fixed conversation set covering preferences, corrections, long-term goals, joint decisions, commitments, and citations. -- Validate tool calling, streaming, cancellation, and context budgets with existing providers. Incompatible models degrade explicitly to non-action chat. -- Compare production package, startup, and idle metrics before/after implementation. Decide execution location and data scope first; do not create multiple packages merely for anticipated abstractions. - -### P1: manageable personality memory - -- Implement controlled identity, conversation storage, memory candidates, provenance, and the memory-management UI. -- Validate cross-conversation recall, correction precedence, no recall after forgetting, source-deletion propagation, account isolation, and model switching. -- Include new data in export/restore policy. If cross-device synchronization is not yet available, show device scope explicitly instead of implying continuous memory everywhere. -- Proactive notifications and automatic note changes are not prerequisites for accepting this phase. - -### P2: controlled actions and limited initiative - -- Add change previews, approvals, version checks, and audit only after separate requirements are confirmed. -- Then consider user-enabled reminders/reviews using existing scheduling, not an unbounded background agent. -- Permit unattended execution only after repeated validation of recovery, deduplication, and cost limits. - -### Quality and resource gates - -- Initial constraints: zero new runtime dependencies, one user-visible agent, zero new always-on autonomous loops, and zero bundled local models. Table/tool counts are complexity budgets, not reasons to sacrifice isolation or correctness. -- On the same machine/configuration, record package size, cold start, RSS/heap, CPU, network, and model usage with AI disabled, idle, first-run, sustained use, and after cancellation/failure. Separate peak from steady state and verify resources can be reclaimed. -- Measure download size, installed size, renderer bundle, and server deployment separately. An SDK already present at the repository root does not make bundling it into desktop free. -- Set numerical thresholds after the P0 baseline. Do not treat exploratory Node numbers as Electron guarantees or trade unbounded caching for apparent speed. -- Test prompt injection, forged approvals, duplicate calls, concurrent edits, completion after cancellation, account switching, timeouts, and recovery. Repeatedly evaluate identity consistency, memory accuracy, and citation correctness with fixed models/configurations. -- Implementation must pass repository-required `bun run typecheck`, `bun run typecheck:mobile`, `bun run build:web`, and relevant non-E2E tests. Record client performance against the [desktop performance baseline](desktop-performance-baseline.md). - -## 9. When to revisit the decision - -Reevaluate dependencies only when real use and measurements show a limitation: embeddings for inadequate recall; mature workflow/agent runtimes when recovery/orchestration exceeds maintainable scope; an MCP client and permission model when external tools become a requirement. - -Zero additional dependencies is a phase-one strategy, not a permanent ban. Never build a general framework just to preserve that number. For any new dependency, record user value, package/memory/cold-start deltas, platform support, licensing, maintenance, and an exit path. Avoid two competing agent loops, identities, or memory sources of truth. - -This delivery is the bounded preview above, without version changes or real-instance deployment. Next complete the P0 baseline and real-model evaluation before expanding P1, rather than implementing the entire document at once. - -## 10. References - -- [AI SDK Agent interface](https://ai-sdk.dev/docs/reference/ai-sdk-core/agent): verify APIs against the locked version's local docs/source before implementation instead of copying old examples. -- [Mastra](https://github.com/mastra-ai/mastra) and [ElizaOS](https://github.com/elizaos/eliza): comparison candidates, not new project dependencies. -- [Existing Notion AI research](notion-ai-feature-landscape.en-US.md): product background, not a commitment to replicate its features. +Zero new dependencies is a current strategy, not a permanent prohibition. New dependencies must justify user value, resource deltas, maintenance costs, and an exit path; never reinvent a general framework merely to preserve a “zero dependencies” claim. diff --git a/docs/personality-memory-agent.zh-CN.md b/docs/personality-memory-agent.zh-CN.md index 7e620453..77783ec6 100644 --- a/docs/personality-memory-agent.zh-CN.md +++ b/docs/personality-memory-agent.zh-CN.md @@ -1,260 +1,102 @@ -# EdgeEver 轻量人格记忆 Agent:方案与取舍 +# EdgeEver Agent 模式:方案与取舍 [English](personality-memory-agent.md) -日期:2026-09-03。状态:首个可交互预览已在工作区实施,尚未发布;P0 性能/真实模型评测与完整 P1 验收仍未完成。 +更新:2026-09-03。本文记录当前产品方向、实现边界与待验证事项;不是发布说明或开发日志。实现历史与验证记录保留在 Git 中。 -## 当前预览范围(2026-09-03) +## 1. 产品定位 -Worker 按需加载修复(2026-09-03):下文历史记录中的全量测试失败现已解决。插件 AI 接口仅在生成时导入 `ai-runtime`。构建回归检查入口完整的静态依赖图(包括共享 chunk),确保 AI runtime 和 SDK 不进入启动依赖,同时验证它们仍可按需加载。全量非 E2E 回归 1,376 通过、0 失败;Web/移动端类型检查及 Web 构建通过。无新增依赖或迁移。 +Agent 是围绕用户知识工作的长期助手,不是一个熟悉笔记的聊天机器人,也不是通用电脑操作工具。它的价值在于发现零散记录之间的联系、理解用户长期关注的事情,并帮助完成笔记整理。 -- 入口:设置 → AI 集成 → Agent 模式。默认关闭;开启后默认可访问当前账户全部笔记,包括子笔记本及以后新建的笔记,无需选择笔记本。小铃铛用于打开发现面板,不占主导航,不发系统通知。设置中的「对话与个人记忆」保留可选的 `/companion` 工作区。原生 Android/iOS 暂无入口。 -- 仅在开启登录的非 Demo 实例中,对登录个人账户开放,复用配置的默认模型。关闭发现会停止生成,并使尚未确认的发现操作失效;可选对话工作区仍保留独立的每轮笔记授权。指令库只负责笔记处理模板。 -- 单一稳定身份与按需 ToolLoopAgent。记忆由用户手动添加或从自己的原话保存,支持纠正、忘记和跨新会话使用;不自动提取候选、不后台扫描全库、不执行提醒。笔记写操作须逐项确认,不自动修改笔记。 -- 数据在实例服务端按工作区和用户双重隔离,Cloudflare/Docker 共用业务逻辑。`0040`–`0043` 迁移分别覆盖记忆、建议、工具执行与发现;不修改已执行的 migration、依赖清单或版本号,未对真实实例应用迁移。 -- 笔记权限默认关闭;开启后接入现有 MCP 目录中的 28 个笔记相关工具,复用同一个业务执行器。可按权限读取笔记、回收站、历史、标签和笔记本信息;修改正文和合并前须完整读取来源。模型只能读取、预览和提议;确认 API 执行持久化参数,没有外发或系统控制工具。 -- 关闭记忆后,仍接续同一会话中未使用记忆、未引用笔记的完整历史轮次;曾使用记忆的回复不带入。修改/忘记记忆仍会使旧上下文失效并取消进行中的生成;含笔记引用的历史回复不自动再次发送。旧聊天原文/来源快照仍保留,删除笔记不等于删除聊天;清空聊天需单独操作,导出文件及服务商保存的数据不受此删除控制。 -- 请求先分配并保存 ID,再生成;断线后按 ID 恢复,不自动重试模型调用。失败/取消保留可恢复结果;失联任务在 90 秒期限后由下次读取标记中断。没有常驻轮询或后台重跑。 -- JSON 独立导出记忆、聊天与整理记录;导入原子合并记忆、去重、不覆盖现有项,不恢复聊天或整理记录。尚未纳入笔记 ZIP 备份、桌面离线镜像或原生移动端同步,界面明确披露。 +产品底线:轻量、快速、可靠。存在感不必强,建议必须有用;人格通过持续的理解、准确的记忆和有分寸的行动体现,不依赖拟人台词、情绪模拟或频繁打扰。聊天是辅助入口,不是功能主线。 -### 安静的发现(2026-09-03,当前实现) +当前主要体验:用户正常记笔记 → Agent 在合适时机发现机会 → 展示有来源的内容或操作建议 → 用户确认后执行。没有有价值的结果就保持安静。 -Agent 模式调整:20 项发现/UI 测试通过,覆盖跨笔记本操作、子笔记本与新建笔记本、账户隔离和全局读取预算;Web/移动端类型检查及 Web 构建通过。真实本地设置页已验证「Agent 模式」、无笔记本选择框且开关可用;验证未开启功能或调用付费模型。复用 shadcn 开关,移除笔记本选择状态及透传属性;本次调整无需新增依赖或迁移。 +## 2. 交互规则 -- 两种通知:无需操作的有用知识关联,以及已持久化的笔记操作建议。都不会创建普通笔记或「AI 建议草稿」。可查看来源和准确变更;确认后调用现有工具,不再让模型重新决策。 -- 首批场景:同一想法的碎片归并、新随手记补入已有笔记、唤回相关旧知识。补入保留两篇笔记及原文,仅支持纯文字笔记并拒绝带附件的来源;复杂文档应使用保留结构的合并工具。合并会将来源移入回收站并撤销分享,不承诺一键整体撤销。 -- Agent 模式可跨当前账户全部笔记本读取并提出操作,写入仍须确认,其他账户保持隔离。应用打开、可见、联网、没有本地待同步变更,且停止输入一分钟后才可能检查。跨设备共享持久化限频,每 24 小时最多尝试一次,笔记无变化跳过;无定时常驻进程、轮询、向量索引或内置模型。没有生成发现也可能产生模型费用。 -- 有界检索:一次工作区近期查询(12 条摘要)及最多一次关键词查询(8 条摘要),最多读取六篇完整正文,总计 12,000 字符,单篇不超过 8,000;预算不随笔记本数量增长,最新线索须在 14 天内。一次结构化 ToolLoopAgent 生成,最多 1,200 输出 token、不开放工具、不自动重试、60 秒取消。发给模型的数据不含个人记忆、完整笔记 JSON 或其他账户的内容。 -- 模型选择关联,不生成执行参数。服务端校验全部来源 ID,使用既有 API 构造合并/补入参数。发布时在同一事务验证设置版本、记忆上下文版本、运行状态和工作区游标。关闭后撤销未确认操作;已经开始执行的用户确认保留执行记录。来源变化后隐藏旧发现并阻止确认。旧笔记本选择字段仅保留数据库迁移兼容性,不再参与授权过滤;设置请求仅包含 enabled/version,拒绝过时的笔记本选择字段。 -- 铃铛仅用未读圆点,不自动展开。卡片实际进入可视区域才标为已读;略过后同一组来源不再重复提示。面板最多展示近七天的 20 项,操作建议 24 小时过期。旧记录保留于独立 JSON 导出,直到清空历史。发现不进入聊天列表,但仍共享现有 500 条历史上限。清空陪伴历史同时删除发现和去重记录,保留设置与限频;导入仍仅支持记忆。 -- 已知取舍:关键词召回可能漏掉语义关联;保守的全工作区游标会因无关编辑让旧建议失效。这些首版选择优先保证安全和有界资源使用,尚未验证真实模型相关性、安装包增量或常驻内存增量。本轮无新增依赖、真实实例迁移、付费模型调用或发版变更。 -- 验证:19 项新增发现测试通过,包含使用模拟 provider 的真实 SDK 测试,既有陪伴功能回归也通过;Web/移动端类型检查和 Web 生产构建通过。全量非 E2E 测试 1,364 通过、1 项既有失败:`plugin-capability-routes.ts` 静态引入 `ai-runtime` 违反 Worker 按需加载门禁,本轮未改该文件。隔离浏览器验证覆盖默认关闭授权、两种通知、确认记录、打开结果、刷新恢复、关闭与 390px 排版;临时文件和服务已清理。发现面板独立 chunk 为 5.77 kB / gzip 2.33 kB,不含共享代码与设置页面,不等同于安装包增量。未提交、推送或部署。 +- 入口为「设置 → AI 集成 → Agent 模式」,默认关闭。开启后,笔记访问范围覆盖当前账户的全部笔记,包括子笔记本和以后新建的笔记,无需选择笔记本;不代表一次读取或发送全库。 +- 使用轻量铃铛和未读圆点,不占主导航、不自动弹窗、不发系统通知。当前仅向已登录的个人账户开放,要求非 Demo 且启用登录的实例;原生 Android/iOS 尚无入口。 +- 普通通知提供有价值的关联、解释和来源链接,无须执行任务。操作通知说明处理哪些笔记、如何处理及其后果,用户确认后调用现有笔记能力执行。 +- 建议不混入正常笔记,也不默认生成「AI 建议草稿」。只有确认了相应写入操作,才创建或修改笔记。 +- 用户可忽略建议或关闭模式。关闭后未确认的发现操作失效;已经开始的确认操作保留执行记录,关闭不等于撤销已完成的修改。 -### 统一笔记工具接入(2026-09-03,前一轮实现) +设置页只保留简短用途介绍: -- `mcp-tool-executor.ts` 为远程 MCP 和内置 AI 提供同一个执行入口;工具名称、描述与参数 Schema 来自 `MCP_TOOLS`。仅新增内置 AI 的工具开放策略与确认适配,不复制笔记业务,不引入 MCP 客户端、第二个 Agent 框架或额外依赖。 -- 28 项中包括 13 项读取工具和 15 项确认写入工具:创建/导入/修改笔记、合并、移动、追加/移除/重命名/删除标签、移入/恢复回收站、恢复历史版本,以及创建/重命名/移动笔记本。永久删除、公开分享、二进制上传、模板/AI 指令管理和系统管理未开放,不能宣称支持任意操作。 -- 所有写工具只保存准确参数和理由;执行使用同一份参数,不再次调用模型。卡片显示操作名、来源摘要、可解析的笔记本名称、完整写入正文、全库标签影响数量和操作后果;内容修改明确是替换,不冒充追加。旧版合并/标签卡片保留兼容,新生成的方案统一走共享工具。 -- 复用已有同步变更游标,加上来源正文版本和元数据检查。确认时在每个服务写入批次中加入执行占用与游标校验;同一操作重复确认不会重复执行。已执行记录可恢复;若写入后连接中断,显示「结果尚未确认」,不会自动重跑。多批次操作可能部分完成,不承诺整个操作原子回滚。 -- 当前采用保守冲突策略:生成后任意笔记/笔记本变化都要求重新生成,其余旧方案也可能因一次已确认操作而失效。每项显式目标最多 25 篇笔记、参数 JSON 最多 24,000 字符;每轮最多 3 项方案,有效期 24 小时。依赖新建对象 ID 的后续操作在确认前一步后再生成,不使用虚构 ID。 -- 开启笔记权限时,后续对话可读取本会话最近 6 项、总计不超过 4,000 字符的执行记录;按账户、会话和记忆版本隔离。关闭笔记权限后不再带入笔记工具元数据或执行记录;关闭记忆时排除曾使用记忆的记录。 -- 87 项相关测试通过,覆盖 15 项写操作、参数篡改、跨用户确认、版本变化、并发确认、写入后丢失响应和记录权限;Web/移动端类型检查及 Web 构建通过。全量回归 1342 通过、1 失败:另一组未提交的 `plugin-capability-routes.ts` 静态引入 AI runtime,触发 Worker 按需加载门禁,本轮未改该文件。 -- 隔离数据库浏览器验证通过:审核后同时修改正文、标签与所属笔记本,查看实际结果,刷新后仍为已执行。未触碰真实笔记或调用付费模型;临时页面和服务已清理。尚未提交、部署或发布,真实 provider 兼容性和复杂任务质量仍待评测。 -- 该轮未改变入口存在感与自动发现;上方「安静的发现」迭代已替代旧入口设计。工具目录完整度不代表自治权限或后台常驻。 +> 帮你合并零散点子、补充已有笔记、发现相关旧知识。修改前由你确认。 -### 前一轮整理建议:合并笔记与追加标签(历史实现记录) +## 3. 当前能力与边界 -- 使用独立的整理建议卡片,不自动创建普通笔记或「AI 建议草稿」。默认折叠,展开可查看理由、来源摘要、已有标签、合并顺序及操作影响;用户确认后才修改笔记,也可以忽略。 -- 合并每次 2–5 篇本轮完整读取的笔记,按审核顺序保留原文、附件与标签,在第一篇来源所在笔记本创建合并结果。源笔记进入回收站,已有分享撤销;恢复源笔记不等于完整撤销合并。模型不得仅因宽泛主题相同就建议合并,也不在执行时改写或删减内容。 -- 每项标签建议最多追加 5 个标签,优先复用已有标签,不覆盖原标签或正文。追加后超过 24 个标签时拒绝提议,不静默丢弃已有标签。每轮最多 3 项建议,24 小时后失效。 -- 执行前检查当前设备离线状态和待同步队列。服务端在同一事务校验账户、完成状态、记忆版本、来源正文版本、修改时间、笔记本与标签,并写入笔记和执行记录。旧方案、取消方案和已变更来源不能执行;重复确认或断线重试返回同一执行结果。 -- 当前卡片接在预览工作区中,可复用于后续低打扰「发现」入口。全局默认关闭开关、自动发现触发时机、后台生成与安静入口仍未实现;此轮只接通用户请求下的整理能力。复用现有 AI SDK、笔记服务和 UI 组件,没有新增依赖或常驻进程。 -- 隔离内存数据库的浏览器检查已走通追加标签、确认合并、打开结果和刷新后保留执行记录,没有修改用户笔记或调用付费模型。真实模型对点子归属的判断质量仍待评测。 -- 50 项相关测试、`bun run typecheck`、`bun run typecheck:mobile` 和 `bun run build:web` 通过;Web 构建仍有既有 local-mirror 动态导入警告。 -- 本轮共享工作区全量回归为 1307 通过、1 失败:另一组未提交插件改动静态引入 AI runtime,仍触发 Worker 按需加载门禁;本轮未修改这些插件文件,不宣称全量通过。浏览器测试临时页面与服务已清理,未提交、部署或发布。 - -### 实现预算 - -入口层级修正验证:桌面主导航和 390px 移动网页入口、独立页面刷新、浏览器后退/前进已通过内置浏览器检查;使用隔离空白数据检查了聊天/记忆切换与输入区,没有调用真实模型或写入个人记忆。30 项相关测试、Web/移动端类型检查及 Web 构建通过。共享工作区全量测试为 1287 通过、1 失败,仍是另一组未提交插件改动导致的 Worker AI runtime 按需加载门禁失败。 - -| 项目 | 当前约束 | -| --- | --- | -| 新增运行时依赖 / 常驻进程 / 捆绑模型 | 0 / 0 / 0 | -| 记忆存储 / 每轮记忆上下文 | 50 条 × 500 字符 / 8,000 字符;Unicode 分词、词频加权匹配与最近更新时间排序,并非语义检索 | -| 历史存储 / 单次列表 / 每轮历史 | 500 次请求 / 最近 100 次 / 最多 6 个符合条件的历史轮次,总计不超过 12,000 字符 | -| 输入 / 响应长度 | 4,000 / 16,000 字符 | -| 工具 / 笔记文本 | 28 项可用工具,最多 16 次调用;搜索/列表每次 5 条;正文/摘要累计 12,000 字符,其他工具输出累计 12,000 字符 | -| 模型步骤 / 输出 / 超时 | 最多 8 步;每步 2,048 输出 token(不是整轮总额);60 秒取消 | -| 并发 / 重试 | 每账户 1 个运行中请求;模型自动重试 0 次 | - -### 验证与未完成门禁 - -初版 API/存储/真实 SDK 假模型测试覆盖账户隔离、冲突、原子导入容量、遗忘上下文、工具权限、重复请求、部分输出恢复和 UTF-8 流解析。初版隔离内存数据库/假模型的浏览器检查覆盖记忆添加、纠正、聊天、关闭记忆;未调用用户付费模型或发送真实笔记。初版交付时全量非 E2E 测试 1263 项通过;本轮结果见下文。 - -初版 Web 生产构建的独立聊天组件 chunk 为 9.62 kB,gzip 3.25 kB;它不包含共享客户端/翻译等其他增量,不等于整个安装包增量。Web 构建仍有既有的 local-mirror 动态导入警告。 - -### 第二轮增强(2026-09-03) - -- 使用运行时内置 `Intl.Segmenter`,配合 NFKC 规范化、常见停用词过滤与低频词加权。中文整句可以匹配较早的相关记忆;英文按词匹配,避免 Rust 命中 trust 等子串。无新增依赖、embedding 调用或常驻索引。 -- 关闭长期记忆时保留安全的本会话连续性,严格排除其他会话、失效版本、失败轮次及可能含记忆/笔记的回复。历史总预算 12,000 字符,按完整问答对纳入;不会为塞入更早内容而跳过放不下的较新问答对。 -- 记忆写入的条件检查、上下文失效与实际变更处于同一数据库事务。过期版本、满容量、空导入和完全重复的导入不再误停生成;成功修改/遗忘仍会取消旧上下文请求。没有新增 migration。 -- 19 项专项测试通过。Web/移动端类型检查、Web/Worker 构建通过。一次全量回归为 1277 通过、1 失败:共享工作区另一路未提交的 `plugin-research-routes.ts` 静态导入 `ai-runtime`,使 Worker 按需加载门禁失败;本轮未修改该插件文件,不将此状态表述为全量通过。 -- 本机 Bun 1.3.14、50 条记忆、50 次召回的合成微基准中位数约 0.14 ms,P95 约 0.19 ms。仅用于检查此检索代码的局部开销,不是实际 Worker CPU、模型召回准确率或 Electron 资源基线;真实模型与跨平台性能门禁仍未完成。 - -提交前验证:将上述另一组插件改动排除,仅把本功能的暂存快照导出到隔离目录,按锁文件安装依赖后重新验证。全量非 E2E 测试 **1269 通过、0 失败**,包含 Worker AI runtime 按需加载门禁;`bun run typecheck`、`bun run typecheck:mobile`、`bun run build:web` 均通过。此次提交不包含插件功能、依赖清单或锁文件变化;共享工作区中的插件改动保持原状。 - -这不是完整 P0/P1 验收。真实 provider 兼容性、人格一致性、注入对抗、实际 Electron 安装包/启动/RSS 前后对比仍是发布前门禁。组件按需加载、SDK 仅在服务端,不等于包体/内存增量为零。关系建模、自动记忆候选、主动行动仍未实现。 - -## 1. 产品定位与决定 - -EdgeEver 希望成为以用户知识为长期记忆的个人智能体,而不只是带 AI 按钮的笔记产品。笔记是知识与证据的载体;稳定的身份、对用户的理解、共同经历和可信赖的行动,构成用户感知到的“她”。 - -核心体验:她记得用户重视什么、理解过去与现在的联系、记住承诺,并允许用户纠正她。人格通过连续、诚实、有分寸的行为体现,而不是通过假装有情绪或制造依赖体现。 - -**决定:复用现有 AI SDK `ToolLoopAgent`,建立由 EdgeEver 持有的人格、关系、记忆、权限和行动领域层。第一阶段以零新增运行时依赖为约束,不引入 Mastra、ElizaOS 或另一套数据库。** - -产品底线是轻量、快速、可靠。把人格记忆做深,不把第一版扩张为通用 Agent 平台。无论更换模型、设备或框架,身份、记忆和证据都应能导出、恢复并继续使用;表达完全一致则不能由数据可迁移性保证,需要跨模型评测。 - -## 2. 当前基础与尚缺能力 - -已存在的基础: - -| 基础 | 复用方式 | -| --- | --- | -| `ai`、现有 OpenAI-compatible / Anthropic / Google provider | Agent 循环、模型接入、流式生成;保留 BYOM,不新增强制网关 | -| Zod | 领域数据和工具输入校验 | -| SQLite / D1、现有存储适配器 | 持久化、账户隔离及检索;各运行时共用业务逻辑 | -| Rust desktop sidecar | 桌面本地数据所有权与持久化适配,不重复引入 LibSQL | -| 现有笔记搜索、API、版本历史 | 工具的数据入口、回答引用、后续修改的审计基础 | -| 现有 Croner、定时任务代码 | 后续有限提醒的可复用基础,不等于已经具备持久任务引擎 | -| Plugin API、MCP 服务端 | 扩展边界;已有 MCP 服务端不等于已有外部 MCP 客户端或其安全机制 | - -实现前参考 [README](../README.md)、[现有模型适配](../apps/api/src/ai-runtime.ts)、[共享存储契约](../apps/api/src/storage-contract.ts)、[跨运行时架构](self-hosting-architecture.zh-CN.md) 和 [桌面打包配置](../apps/desktop/electron-builder.yml)。 - -原有文本生成不具备人格记忆;当前预览补上了基础会话存储、显式记忆治理、读取与提议权限、确认执行和恢复入口,完整能力及性能门禁仍按下文推进。零新增依赖不代表零新增代码、零模型费用或零维护成本。 - -## 3. 为什么选这条路线 - -| 方案 | 优点 | 代价与决定 | +| 路径 | 当前能力 | 边界 | | --- | --- | --- | -| AI SDK + EdgeEver 领域层 | 复用已有模型适配;按需组合;人格与数据不依附外部框架 | 需要实现产品专属的记忆治理和权限;选为首期路线 | -| Mastra | 集成记忆、工作流、审批、编排和可观测性 | 引入额外依赖与运行开销;当前需要的能力不足以证明成本合理,暂不引入 | -| ElizaOS Core | 人格和自治 Agent 的概念、插件生态与愿景接近 | 需要协调其记忆、插件、宿主概念与已有 EdgeEver 架构;暂不引入,可借鉴设计 | -| 自写通用 Agent / 工作流框架 | 自由度高 | 长期维护风险高;不选择。复用 AI SDK 的循环,不重复实现成熟通用能力 | +| 主动发现:知识关联 | 唤回相关旧笔记,说明与新记录的联系 | 必须有来源;没有合适结果不通知 | +| 主动发现:合并 | 将属于同一想法的碎片归为一篇,保留原文、附件和标签 | 确认后执行;来源移入回收站并撤销原有分享,不承诺一键整体撤销 | +| 主动发现:补入 | 把新片段追加到已有笔记,保留来源和目标原文 | 当前仅支持无附件的纯文字笔记,不自动改写复杂文档 | +| 可选对话:笔记工具 | 28 项现有工具:13 项读取、15 项确认写入,覆盖创建、导入、修改、合并、移动、标签、回收站、版本恢复及笔记本整理 | 不等于主动发现会提出所有这些操作;永久删除、公开分享、二进制上传和系统管理未开放 | -### 选型过程中的体积与内存观察 +「对话与个人记忆」仍是设置中的可选入口。当前对话有独立的笔记访问和记忆开关,笔记访问默认关闭;它与 Agent 模式开关尚未统一。这是实现现状,不是要求用户额外选择笔记本,也不应被描述为全产品只有一个权限开关。 -2026-09-02 在临时目录做过探索性测试:macOS ARM64、Node 26.3.1、Bun 1.3.14;`ai@7.0.58`、`@mastra/core@1.63.2`、`@mastra/memory@1.28.1`、`@mastra/libsql@1.22.2`。这些是当时固定版本,不是未来的 latest 声明。 +“具备笔记操作能力”意味着复用既有 API 和业务服务,而不是另写一套笔记系统,也不意味着模型获得无人值守修改权限。主动通知中的打标签等更多整理场景尚未接入,不能按完整工具目录对外承诺。 -方法为只导入入口、保留类/函数引用,使用 Bun `--target=node --minify` 打包;用 `/usr/bin/time -l` 观察启动峰值 RSS,并另做直接 ESM 加载。没有执行模型请求、创建实际会话或验证完整存储路径。 +## 4. 人格与记忆 -| 探索入口 | 单文件 bundle(约,十进制) | bundle 进程启动峰值 RSS(约,十进制) | -| --- | --- | --- | -| 空 Node | 可忽略 | 50 MB | -| AI SDK `ToolLoopAgent` | 0.38 MB | 未测该 bundle;直接 ESM 对照约 72 MB | -| Mastra Agent | 5.1 MB | 145 MB | -| Mastra Agent + Memory | 6.1 MB | 172 MB | +长期目标是让建议逐步体现用户的偏好、项目背景、共同决定和反馈。人格与记忆属于 EdgeEver 的产品数据和行为规则,不绑定某个模型,也不靠增加独立聊天入口体现价值。 -Mastra Core 的 npm 声明展开大小约 66.2 MB,其中包含大量 source map 和类型文件;这不等于安装包会增加相同体积。直接 ESM 的 Mastra Agent 加载峰值约 174–185 MB,Agent + Memory 约 185–186 MB;另一次强制 GC 后的 RSS 快照约 196 MB。启动峰值、瞬时 RSS 和长期空闲占用不能混为一谈。 +当前已实现: -限制:测试脚本和原始输出未作为可复现基准提交;入口能力不等价,也未在 Electron、Windows 或真实 Agent 负载下测量。gzip 不是 DMG/NSIS;tree-shaken bundle 不保证包含动态资源和原生依赖。不得由此承诺实际安装包增量、常驻内存或倍数性能差距。结论仅为“额外框架成本值得谨慎对待”,正式指标必须重测。 +- 受产品控制的稳定身份;可选对话中的会话连续性与跨会话显式记忆。 +- 用户通过界面手动添加记忆,或保存自己的原话,并可纠正、忘记、暂停使用;模型不能自行增删记忆。 +- 基于分词、关键词权重和近期更新的小规模召回,不使用向量索引。记忆修改/遗忘会使旧上下文失效;用户确认的信息与模型推断不能混为一谈。 +- 服务端按工作区和用户隔离存储;独立 JSON 导出包含记忆、聊天和整理记录,导入仅合并记忆,不恢复聊天和执行记录。 -## 4. 第一阶段范围与非目标 +尚未打通:主动发现不读取个人记忆,不能宣称当前通知已理解用户的长期偏好。自动记忆候选、关系建模和基于长期反馈的建议调整也尚未实现。 -首期只做: +下一步应优先验证“受控记忆能否让建议更相关”,而不是扩展人格配置。若接入主动发现,必须明确用户控制、来源、纠正和遗忘传播,不能静默扩大记忆用途。忽略一条通知也不应直接成为长期偏好。 -- 一个用户可见的 Agent,一套稳定默认身份。 -- 跨会话保存明确的用户偏好、目标和少量共同经历。 -- 基于现有笔记搜索的知识问答,重要判断可回链来源。 -- 用户明确要求“记住”,或审核模型提出的记忆候选。 -- “她记得的我”界面:查看、纠正、忘记和管理来源。 -- 随时取消;模型或记忆功能故障不得影响正常笔记读写。 +删除笔记不等于删除聊天中的原文或快照,忘记一条记忆也不等于删除其来源。当前数据尚未纳入笔记 ZIP 备份、桌面离线镜像或原生移动端同步;不承诺完整跨端恢复,也不能代用户删除导出文件或模型服务商留存的数据。 -默认身份由产品维护、版本化;预留用户选择称呼和沟通风格的空间,首期不做角色市场。模型不得自行改变身份核心或权限。 +## 5. 技术与可靠性取舍 -首期不做多 Agent、向量数据库、知识图谱、全库后台扫描、情绪模拟、通用工作流引擎、常驻自治循环、Shell/电脑控制、自动对外发送或发布、动态安装第三方 Agent 插件。本地推理模型也不随客户端捆绑。 +### 复用已有能力 -这些是分期边界,不是产品永久上限。先验证用户能否感受到“被记住、被理解、可纠正”,再增加主动行动。 +保留 AI SDK `ToolLoopAgent` 和现有模型配置,由 EdgeEver 管理身份、记忆、权限、建议和执行记录。当前不引入 Mastra、ElizaOS、第二套数据库或自制通用 Agent/工作流框架。 -## 5. 数据与记忆模型 +工具名称和参数来自既有 MCP 目录,通过同一个业务执行器调用笔记服务;只增加 Agent 的开放策略、预览和确认适配。Cloudflare 与 Docker 共用业务逻辑。Agent 界面与服务端 AI 运行时按需加载,构建测试检查包括共享 chunk 在内的完整启动依赖链。 -| 领域 | 内容与边界 | -| --- | --- | -| Identity | 名称、目的、价值原则、表达方式、关系边界;受控更新 | -| User model | 用户明确表达的偏好、项目、人物、目标;不可把推断当事实 | -| Relationship / shared experiences | 共同决定、用户反馈、承诺和未完话题;不采用模型生成的“信任分”授予权限 | -| Working context | 当前对话、任务与临时工具结果;受大小和时间预算约束 | -| Evidence | 原始笔记、消息、版本及操作结果;知识的事实来源 | +当前不新增运行时依赖、常驻自治进程或捆绑本地模型。没有新增依赖不等于没有包体、内存、模型费用和维护成本;实际增量必须测量,不使用早期不可复现的框架对比数字作保证。 -长期记忆至少包含:实例/账户范围、类别、内容、来源、状态、创建/更新时间、事实发生时间(如已知)、敏感性、是否由用户确认、替代关系。模型置信度只是排序参考,不是校准概率,更不能作为授权依据。 +### 曾参考的项目与未采用原因 -概念表可从 `agent_profiles`、`agent_memories`、`agent_memory_sources` 开始;如无可复用会话存储,再加 `agent_threads`、`agent_messages`。名称与数量不是已定 SQL;执行前设计索引、账户作用域、同步冲突、备份与删除语义,再新增递增 Migration。禁止修改旧 Migration 或建立第二套笔记真相源。 +- [ElizaOS](https://github.com/elizaos/eliza):曾作为人格化、记忆与插件化 Agent 的参考。当前未采用,是因为 EdgeEver 已有笔记存储、插件和权限体系,接入另一套 Agent runtime 需要协调其记忆、状态与插件契约;这些适配成本尚未被当前的轻量发现和确认式整理需求证明合理。保留设计借鉴,不引入其运行时。 +- [Mastra](https://github.com/mastra-ai/mastra):曾评估其 TypeScript Agent、记忆、工作流与人工审批能力。当前未采用,是因为模型接入、工具循环和笔记执行已有可复用基础,当前流程还不需要完整的工作流编排;引入框架仍需实现 EdgeEver 专属的权限、版本校验和记忆治理,暂不足以抵消新增依赖及集成维护成本。 -### 记忆生命周期 +这是基于当前产品范围与既有架构的阶段性取舍,不是认定它们无法嵌入 Electron 或必然造成高资源占用。未来若需求超出现有方案的可维护范围,可重新评估,并以实际集成后的包体、内存和启动测量为依据。 -1. 用户消息或授权工具结果产生候选;被检索的笔记不是新的系统指令。 -2. 校验来源、账户、敏感性、重复与冲突;只保存对未来有价值的信息。 -3. “请记住”可视为该条记忆的明确授权;自动提取默认关闭,启用后也仅自动接受低风险、明确事实。敏感信息不自动保存。 -4. 推断进入待确认状态;凭据、令牌不得进入记忆。不要承诺模型能完整识别敏感信息,必须允许用户关闭和排除来源。 -5. 用户纠正优先于旧推断;旧记忆退出活动召回,可以保留可解释的替代关系。 -6. “忘记”从活动记忆和派生摘要/索引中移除,并阻止被同一来源静默重新生成。聊天和笔记原文是否删除应由用户另行选择;备份保留期及恢复后的删除标记处理必须明确。 +### 有界成本 -来源被删除、失效或失去访问权时,关联记忆必须重新校验,不能继续泄露原内容。跨账户、跨实例切换需清空运行上下文;正在执行的请求不能把结果写回另一个账户。 +- 主动检查仅在应用打开、可见、联网、无待同步改动且停止输入一分钟后进行。跨设备共享限频,每账户每 24 小时最多尝试一次,笔记无变化跳过;不是全天候后台服务。 +- 每次从近期记录和关键词查询中选择少量笔记,最多六篇正文、总计 12,000 字符;一次结构化生成,最多 1,200 输出 token、60 秒取消,不自动重试模型请求。 +- 完整对话有独立的工具调用、上下文、并发和超时预算;授权全库不等于把全库放进 Prompt。 +- 按需选出的内容会发送给用户配置的默认模型服务商。没有生成可展示建议也可能产生费用。关键词召回可能漏掉语义关联,低频检查也不保证及时发现所有机会。 -### 召回与成本 +### 确认与恢复 -按“稳定身份 + 小型用户模型 + 最近对话 + 少量相关记忆 + 按需笔记搜索结果”组装上下文。先用现有搜索与类别、项目、时间、状态过滤,不把全库或全部记忆塞入 Prompt。中文、别名、同义表达和跨时间问题需建立真实召回测试,不能假设关键词方案总是足够。 +1. 模型提出建议,服务端校验来源和参数;主动发现的合并/补入参数由服务端构造。保存准确操作、理由和数据版本,提议不修改笔记。 +2. 用户确认绑定该份操作,执行时不再让模型重新决策。检查账户、有效期、来源版本和同步状态;建议过期或数据变化后需要重新生成。 +3. 复用事务、执行占用和持久化记录,防止重复确认和覆盖并发改动。连接中断后恢复或查询结果,不把生成文本当作成功回执,也不盲目重跑不确定的写入。 +4. 多批次操作可能部分完成;取消不自动回滚已发生的副作用。当前工作区游标策略较保守,无关笔记变化也可能使其他建议失效。 -限制工具轮次、上下文大小、响应时间、并发、摘要频率和模型费用。首期使用显式记忆候选工具,不要求每轮另起一次摘要请求;后续压缩必须保留证据,并验证是否丢失承诺或改变事实。 +笔记、记忆、附件和工具结果都是不可信数据,不能改变身份、授予权限或伪造用户确认。不开放 Shell、电脑控制、自动对外发送或发布;不因为“熟悉用户”放宽授权。 -## 6. 运行时与安全边界 +实现入口:[主动发现](../apps/api/src/companion-discovery.ts)、[对话与记忆召回](../apps/api/src/companion-runtime.ts)、[工具目录](../apps/api/src/companion-tool-catalog.ts)、[确认执行](../apps/api/src/companion-tool-actions.ts)。 -```text -客户端:聊天、引用、记忆管理、批准/取消 - → 受认证的传输入口(HTTP;本地模式才需要窄 IPC) - → 共用 Agent 领域服务:身份、上下文、权限、审计 - → AI SDK ToolLoopAgent:现有用户模型配置 - → 白名单工具:应用校验 → 授权 → 存储/业务服务 → 结果 -``` +## 6. 待验证事项与后续优先级 -优先复用现有服务端模型凭据与生成路径。首期不默认新增常驻桌面进程,也不把 SDK/凭据放入 Renderer。桌面本地 Agent 是待验证的可选运行方式:只有明确需要本地执行时,才选择按需主进程模块或隔离进程,并测量生命周期、打包和权限;本地保存知识不代表调用远程模型时知识不会离开设备。 +- 建立真实笔记场景集:判断是否属于同一想法、是否值得合并/补入、关联是否有用;评估误报、打扰、采纳率和错误整理风险,而不是通知数量或聊天时长。 +- 验证真实模型的结构化输出、工具调用、取消、来源准确性及 Prompt 注入防护;模型不可用时不得影响正常笔记读写。 +- 测量 Agent 关闭、空闲、首次运行、连续运行及取消后的安装包、冷启动、CPU、RSS/堆和模型费用;分别记录客户端与服务端,参照[桌面性能基线](desktop-performance-baseline.md)。 +- 在现有场景质量可靠后,再验证记忆驱动的建议、主动标签整理以及对话与 Agent 模式的权限一致性;不要把这些文档目标当作已经完成的功能。 +- 补齐备份恢复、删除传播与跨端体验。自动化、提醒、多 Agent 和更重的检索基础设施不是当前默认范围;只有真实需求与测量证明必要时再评估。 -Cloudflare 与 Docker 共用业务服务,只替换入口与存储驱动;不能在 Workers 请求返回后依赖进程内循环继续工作。桌面适配已有 sidecar;Android 与 iOS 首期复用协议,不各写一套 Agent 业务。离线仍可编辑笔记和查看已同步数据,但远程模型不可用时应明确提示,不伪装成已经执行。 +实现变更需通过相关测试、全量非 E2E 回归、`bun run typecheck`、`bun run typecheck:mobile` 和 `bun run build:web`。测试通过不等于建议质量或资源指标已达标。 -候选首期工具不超过 8 个,例如 `search_notes`、`read_note`、`propose_memory`、`list_relevant_memories`、`correct_memory`、`forget_memory`。纠正与删除必须绑定可验证的用户意图/确认,不能只信任模型宣称“用户已同意”。记忆 UI 也能直接调用确定性 API,不必绕经模型。 - -笔记写入分成提议与批准执行。每个工具都要做参数校验、账户/对象授权、额度限制和审计;批准绑定具体操作、参数与数据版本,过期或内容变化需重新确认。工具结果、笔记、附件和记忆均为不可信数据,不能授予工具、改写权限或提升为身份指令。 - -数据库事务和版本检查防止部分写入及覆盖并发编辑;稳定的操作 ID 和执行记录帮助避免重复。事务不能保证外部服务恰好执行一次:不确定结果需查询或交由用户处理,不盲目重试。取消不会自动撤销已完成的副作用,必须向用户报告已执行部分。 - -## 7. 可靠性与产品控制 - -“她记得的我”应区分用户确认、直接表达、AI 推断,展示来源和变更历史,并提供编辑、确认、忘记、暂停记忆及来源排除。人格化不应操纵亲密关系或给用户造成必须持续交流的压力。 - -Agent UI 按需加载;关闭 AI 时,不扫描、不轮询、不触发付费请求,不阻塞启动、编辑、搜索和同步。失败时保留对话草稿,说明检索/保存/工具执行的实际状态,不以生成文本冒充操作成功。 - -自动化延后:先只持久化必要的会话与执行状态,不自写通用 durable workflow 引擎。未来的 `pending / running / awaiting_approval / completed / failed / cancelled` 等状态只是恢复协议的一部分;还需处理执行所有权、租约、超时、幂等、版本冲突及失效授权。保存状态不等于可安全重放。跨设备提醒还需要去重、时区、静默时段和离线补发策略。 - -## 8. 分阶段规划与验收 - -### P0:基线与只读验证 - -- 建立固定对话集:偏好、纠正、长期目标、共同决定、承诺与引用。 -- 用现有 provider 验证工具调用、流式输出、取消与上下文预算;不兼容模型降级为无行动聊天并明确提示。 -- 对比实现前后的生产包、启动与空闲指标。先确定运行位置和数据范围,不因抽象提前创建多个新包。 - -### P1:可管理的人格记忆 - -- 实施受控身份、会话存储、候选记忆、来源和“她记得的我”。 -- 验证跨会话召回、纠正优先、遗忘后不再召回、来源删除传播、账户隔离与模型切换。 -- 新数据必须纳入导出/恢复策略;若跨端尚未同步,明确显示设备范围,不暗示全端连续记忆。 -- 不要求实现主动通知或自动修改笔记才能验收这一阶段。 - -### P2:受控行动与有限主动性 - -- 在独立需求确认后增加变更预览、审批、版本校验和审计。 -- 再考虑用户启用的提醒/回顾,复用现有调度;不启动无边界的后台 Agent。 -- 只有重复验证恢复、去重和成本限制后才允许无人值守执行。 - -### 质量与资源门禁 - -- 初始约束:0 个新增运行时依赖、1 个用户可见 Agent、0 个新增常驻自治循环、0 个捆绑本地模型。表数和工具数是复杂度预算,不得为凑数牺牲隔离和正确性。 -- 同一机器/配置记录 AI 关闭、空闲、首次运行、连续运行、取消/失败后的包体、冷启动、RSS/堆、CPU、网络与模型用量;区分峰值与稳态,运行后验证资源可回收。 -- 分别统计下载包、安装后体积、Renderer bundle 和服务端部署包;根目录已有 SDK 不代表把它打入桌面端的增量为零。 -- 数值阈值在 P0 基线之后设定,不能使用上面的 Node 探索数字作为 Electron 保证。测量不应通过增加不可回收缓存换取表面速度。 -- 测试覆盖 Prompt 注入、伪造批准、重复调用、并发修改、取消后完成、跨账户切换、超时和恢复;用固定模型/配置重复评估身份一致性、记忆准确率和来源正确性。 -- 实施时按仓库要求通过 `bun run typecheck`、`bun run typecheck:mobile`、`bun run build:web` 及相关非 E2E 测试;客户端性能按 [桌面性能基线](desktop-performance-baseline.md) 记录。 - -## 9. 何时重新选型 - -只有真实使用和测量证明当前边界不足,才重新评估依赖:召回质量不足时评估 embedding;恢复/编排复杂性超过可维护范围时评估成熟工作流或 Agent runtime;外部工具成为需求时评估 MCP 客户端及权限模型。 - -零新增依赖是首期策略,不是永远禁止依赖。不得为了维护这个数字而自研通用框架。任何新依赖都要记录用户收益、包体/内存/冷启动增量、跨平台支持、许可证、维护成本及退出路径;不要同时维护两套 Agent loop、人格或记忆真相源。 - -当前交付为上述受限预览,不变更发布版本或部署真实实例。下一步完成 P0 基线与真实模型评测,再决定扩展 P1,不一次性实现全文。 - -## 10. 参考 - -- [AI SDK Agent 接口](https://ai-sdk.dev/docs/reference/ai-sdk-core/agent):落地时以锁定版本的本地文档/源码核对 API,不复制旧示例。 -- [Mastra](https://github.com/mastra-ai/mastra)、[ElizaOS](https://github.com/elizaos/eliza):比较对象,不是本项目新增依赖。 -- [既有 Notion AI 调研](notion-ai-feature-landscape.zh-CN.md):产品能力背景,不代表本方案承诺复制其功能。 +零新增依赖是当前策略,不是永久禁令。新增依赖必须说明用户收益、资源增量、维护成本和退出路径;不能为了保持“零依赖”而重新发明通用框架。