Skip to content

[FTRY-1469] Read and edit your memory from the SDK and CLI - #95

Closed
dvlpjrs wants to merge 1 commit into
mainfrom
cursor/ftry-1469-memory-sdk-cli-ccb2
Closed

dvlpjrs wants to merge 1 commit into
mainfrom
cursor/ftry-1469-memory-sdk-cli-ccb2

Conversation

@dvlpjrs

@dvlpjrs dvlpjrs commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator

Ticket: https://linear.app/gumloop/issue/FTRY-1469

Adds client.memory (sync and async) and gumloop memory over the public memory API. Tracks the backend PR https://github.com/gumloop/gumloop_backend/pull/11023 at 792518967a (source of truth for the wire shapes). Draft until the backend lands on staging and this is re-verified against it.

Why

The SDK and CLI only read the wiki through POST /wiki/query. The product treats it as the user's memory, so callers get the same thing under the product name: browse cards and facts, remember and forget, state tone and design rules, review and undo changes, check or start a sync.

Scope

  • src/gumloop/resources/memory.py: Memory / AsyncMemory with overview, query, list_cards, get_card, update_card, regenerate_card, delete_card, list_facts, create_fact, get_fact, update_fact, delete_fact, get_rules, create_rule, list_revisions, undo_revision, get_sync, start_sync. Flat methods like Brain; lists take page_size / cursor and return the plain cursor envelope (data, page_size, next_cursor, has_more, no totals); csv filters accept a list or a string.
  • src/gumloop/types.py: MemoryCard, MemoryFact, MemoryCardRef, MemoryCardRank + MemoryRankSource, MemoryRevision (with undoable) + MemorySnapshot, MemorySync, MemoryRuleSet, request models and list envelopes, mirroring api/types/public_api/memory.py on the backend branch. WikiCard, WikiFact, WikiCardType, WikiQueryRequest, WikiQueryResponse stay as aliases so client.wiki importers keep working and pick up the new connector type and additive fields.
  • src/gumloop/cli/commands/memory.py: gumloop memory overview|query, cards list|get|update|regenerate|delete, facts list|create|get|update|delete, rules list|create, revisions list|undo (list shows UNDOABLE), sync status|start. --json everywhere, Next cursor: on lists. The 402 credit_limit_exceeded from cards regenerate and sync start surfaces like every other API error (Error: <message>, or the error object under --json), the same as brain sources approve.
  • client.wiki and gumloop wiki query keep working; the CLI group help names memory. Error codes pass through untouched: memory_* (including the 400 memory_card_key_invalid on create_fact with param: entity_key) from every /memory route, wiki_card_not_found only from POST /wiki/query.
  • Scopes: reads accept gumloop_api.memory or gumloop_api.wiki, writes need gumloop_api.memory or a personal API key; stated in README and docs/client-capabilities.md. gumloop login requests gumloop_api, which covers both, so no CLI change.
  • Tests mirror tests/sdk/test_wiki.py and tests/cli/test_wiki.py; README and docs/client-capabilities.md rows.

Out of scope: sharing (no backend primitive), docs site pages.

Open questions

  • POST /memory/facts and POST /memory/rules answer 201 on create and 200 on revive; the SDK returns the body only, as every sibling does, so a caller cannot tell the two apart. Fine, or expose it?
  • Memory calls send no team_id even when the client has a team selected (scoped=False, like browser profiles), since the routes take no team keys. client.wiki.query still rides the team param; left as is.
  • update_card(status=...) and create_rule(type=...) are plain strings; the server's 400 is the validation, as for brain.create_source(scope=...).

Verification

No backend with these routes is reachable with a credential I hold: staging does not have them yet, and a local backend on the PR branch would need a staging personal API key or OAuth token for the test user, which means minting one (a staging write). So every command ran against a local stub (/tmp/memory_stub.py, outside the repo) that replays the payload shapes from the backend branch's api/types/public_api/memory.py and pagination/flask.py envelope and logs each request. All 28 commands produced the expected output; the stub received the backend's paths, query strings (csv joins, %40 in entity keys, no team_id) and bodies; 400 / 402 / 404 / 409 envelopes (memory_card_key_invalid, credit_limit_exceeded, memory_card_not_found, memory_card_has_no_summary, memory_revision_superseded, memory_revision_not_undoable, wiki_card_not_found on the legacy path) surface as Error: <message> and as the JSON error object under --json. Transcript and request log attached as memory-cli-stub-run.txt. Will re-run against staging once #11023 deploys.

uv run pytest (minus tests/integration, which needs live credentials): 887 passed; the 2 test_voice failures and test_oauth_default_does_not_send_x_auth_key_header fail identically on main.

Trail

  • cursor (cloud agent VM), chat bc-6b22d7ba-8ef8-411f-96d6-b1c62adb33c1 (worker bc-60957ea4-6b0a-5b74-888b-cebbe3a2ccb2)
Open in Web Open in Cursor 

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@cursor
cursor Bot force-pushed the cursor/ftry-1469-memory-sdk-cli-ccb2 branch 3 times, most recently from 43280ac to 737c022 Compare October 27, 2026 09:57
@dvlpjrs
dvlpjrs marked this pull request as ready for review October 27, 2026 15:51

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

@cursor
cursor Bot force-pushed the cursor/ftry-1469-memory-sdk-cli-ccb2 branch from 737c022 to 328050e Compare October 27, 2026 16:02
@cursor

cursor Bot commented Oct 27, 2026

Copy link
Copy Markdown

@devin review

Typed MemoryCard, MemoryFact, MemoryRevision, MemorySync and the list
envelopes; the Wiki* names stay as aliases for client.wiki importers.
Every memory call is personal (no team scoping), like browser profiles.

Co-authored-by: jyoti <jyoti@gumloop.com>
@cursor
cursor Bot force-pushed the cursor/ftry-1469-memory-sdk-cli-ccb2 branch from 328050e to d648730 Compare October 27, 2026 16:18
@cursor

cursor Bot commented Oct 27, 2026

Copy link
Copy Markdown

@devin review

@dvlpjrs dvlpjrs closed this Oct 27, 2026
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.

2 participants