Skip to content

chore(ci): Python SDK pytest workflow - #1431

Open
Dhravya wants to merge 39 commits into
graphite-base/1431from
chore/ci-python-sdk-tests
Open

chore(ci): Python SDK pytest workflow#1431
Dhravya wants to merge 39 commits into
graphite-base/1431from
chore/ci-python-sdk-tests

Conversation

@Dhravya

@Dhravya Dhravya commented Aug 8, 2026

Copy link
Copy Markdown
Member

Summary

  • Add .github/workflows/ci-python.yml to run pytest for the four Python SDK packages

Stacked on #1430

Test plan

  • CI passes on this PR

Made with Cursor

Run pytest for openai-sdk-python, agent-framework, cartesia, and pipecat
packages on PRs touching those paths.

Co-authored-by: Cursor <cursoragent@cursor.com>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 8, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
supermemory-mcp 006a3f5 Aug 21 2026, 05:35 PM

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 8, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
supermemory-app 006a3f5 Commit Preview URL

Branch Preview URL
Aug 21 2026, 05:36 PM

@claude

claude Bot commented Aug 8, 2026

Copy link
Copy Markdown

Claude finished @ved015's task in 1m 52s —— View job


Code Review Complete

  • Fetch PR diff and existing review comments
  • Analyze changes for bugs, security issues, and logic errors
  • Submit review findings

Summary: Reviewed 91 changed files covering CI workflow, Python SDK v4 migration, browser extension improvements, MCP authentication, and web app enhancements. No bugs or security issues found — the code is solid and ready to ship (9/10).

Dhravya commented Aug 8, 2026

Copy link
Copy Markdown
Member Author

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more


How to use the Graphite Merge Queue

Add the label Main to this PR to add it to the merge queue.

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

MaheshtheDev and others added 15 commits August 10, 2026 00:02
…#1396)

Inline notice with app icons when a channel automation can't use personal-only connections (footer, next to Save), post-save warning toast from the API, templates capped to 3 connection-relevant ideas with a show-all toggle, and New automation promoted to a primary button on the heading row. Pairs with mono #2724; degrades gracefully without it.

Fixes ENG-1151
Company Brain workspaces could only buy Scale at $399/mo, which is roughly eight times what the median team uses. Adds the $100/mo Max card to the Company Brain plan picker, notes what a Scale trial loses on the way down, and flags that Scale is cheaper above about $400/mo of credits.
Co-authored-by: Vedant Mahajan <vedant.04.mahajan@gmail.com>
Co-authored-by: Vedant Mahajan <vedant.04.mahajan@gmail.com>
…#1340)

Co-authored-by: Vedant Mahajan <vedant.04.mahajan@gmail.com>
…s or newlines (#1339)

Co-authored-by: Vedant Mahajan <vedant.04.mahajan@gmail.com>
Onboarding now opens a trial step that collects a card through Stripe checkout before the brain is enabled, with a timeline showing today's $0, the day-12 reminder, and the day-14 charge.

- Only leaves the card step once the API confirms the trial is live
- Brain home shows a setup banner and dims what the trial unlocks
- Recovers orgs that abandoned checkout instead of stranding them
- Adds the organization ID to account settings, copyable from the label
Co-authored-by: abhay-codes07 <abhaysingh0293@gmail.com>
Co-authored-by: Vedant Mahajan <vedant.04.mahajan@gmail.com>
Co-authored-by: Vedant Mahajan <vedant.04.mahajan@gmail.com>
MaheshtheDev and others added 7 commits August 14, 2026 05:36
Make the trial terms and payment timing clear, and simplify the call to action.
Adds a focused guide for backfilling dated documents with `documentDate` and the batch ingestion API.

- includes TypeScript and Python batch examples plus optional completion polling
- links the guide from the docs navigation and ingestion entry points

Validated with `bunx mintlify@latest validate` and `bunx mintlify@latest broken-links`.
…locked' (#1406)

## Why?

Plain **T-1554**: a user with a **read-only** MCP OAuth grant got 403s on memory listing, and the client rendered them as *"Access forbidden. Your account may be restricted or blocked."* The API's actual error body said `{"error": "This API key has read-only access"}` — but `handleError` discarded it, so the user (and support) chased a nonexistent account ban.

Two masking layers:
1. `handleError` used the raw error `message`, which for our raw-fetch endpoints was a hardcoded string ("Failed to fetch documents") or unparsed JSON, and fell back to the scary "restricted or blocked" text when empty.
2. `getDocuments` didn't read the response body at all.

## What?

- New `extractApiErrorMessage()` unwraps JSON error bodies (`{"error": ...}` / `{"message": ...}`) so the API's real reason reaches the user.
- `getDocuments` and `listMemoryEntries` now pass the (unwrapped) response body through with the status, letting `handleError` apply status-aware fallbacks when the body is empty.
- Reworded the empty-body 403 fallback to point at the common cause first: *"Access forbidden. This connection may be read-only or scoped to specific spaces — reconnect with broader access, or check your account status."*

Companion API-side fix (read-only grants couldn't call semantically-read POST list endpoints at all): supermemoryai/mono#2772.

## Testing

- Added tests: a 403 with a JSON error body surfaces the API's message; an empty-body 403 gets the scope-aware fallback. `vitest run src/server/client/index.test.ts` — 3 passed.
- `tsc --noEmit -p tsconfig.json` clean. (The `check-types` script also runs `tsconfig.widget.json`, which fails on origin/main with a pre-existing `UseAppOptions.strict` error, unrelated.)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> User-facing error text only in the MCP client; no auth or API behavior changes.
>
> **Overview**
> **MCP client errors now show what the API actually returned** instead of hardcoded strings or misleading “restricted or blocked” text.
>
> Adds `extractApiErrorMessage()` to parse JSON bodies (`error` / `message` fields) from failed responses. **`getDocuments`** and **`listMemoryEntries`** read the response body on non-OK status and attach the unwrapped message (with status) for **`handleError`**, which also uses the helper on error messages. When a 403 has no body message, the fallback now points users toward **read-only or scoped OAuth** rather than an account ban.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 1f49247. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## What?

Adds a "Continue with AgentID" button to the web app's login page, matching the existing Google/GitHub buttons (same `ExternalAuthButton` pattern, PostHog `login_attempt` capture, last-used badge).

- `packages/lib/auth.ts`: adds the `genericOAuthClient` plugin — generic OAuth providers sign in via `signIn.oauth2({ providerId })`, not `signIn.social`.
- `apps/web/app/(auth)/login/page.tsx`: the button, gated the same way as the other social buttons — always shown on cloud (`NEXT_PUBLIC_HOST_ID === "supermemory"`), opt-in elsewhere via `NEXT_PUBLIC_AGENTID_AUTH_ENABLED` (added to `.env.example`).

## Why?

Companion to supermemoryai/mono#2908, which registers an `agentid` generic OAuth provider (OIDC against auth.agentid.com) on the API so agents can authenticate with their AgentID identity. The consumer app talks to the same better-auth server, so it gets the same sign-in option. mono#2916 additionally auto-invites the agent's verified human owner to the agent's workspace.

Requires mono#2908 to be deployed for the button to work; until then the API rejects the unknown provider and the page shows its normal error state.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches authentication entry points and OAuth client configuration; risk is moderate because it extends login surface area but follows existing social sign-in patterns and is feature-flagged.
>
> **Overview**
> Adds **Continue with AgentID** on the web login page, using the same `ExternalAuthButton` flow as Google/GitHub (PostHog `login_attempt`, last-used badge, loading/error handling).
>
> The button calls **`signIn.oauth2({ providerId: "agentid" })`** instead of `signIn.social`, enabled by registering **`genericOAuthClient`** on the shared better-auth client in `packages/lib/auth.ts`.
>
> Visibility matches other social providers: shown on cloud when `NEXT_PUBLIC_HOST_ID === "supermemory"`, or elsewhere when **`NEXT_PUBLIC_AGENTID_AUTH_ENABLED`** is set (documented in `.env.example`). Depends on the API registering the `agentid` generic OAuth provider.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 90a3278. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## Summary

- Reorder Apps & extensions so Import X bookmarks appears in the top row and Apple Shortcuts uses the open space below.
- Keep both Apple Shortcut actions inline on larger screens while allowing the card to grow only as much as needed.
- Rework the Company Brain promo on phones so its logo, copy, close control, and CTA remain readable and aligned.
cursoragent and others added 14 commits August 18, 2026 15:20
Resolve pyproject.toml conflict by keeping supermemory>=3.50.0
(required for v4 API migration) and main's package version 1.0.5.

Co-authored-by: Dhravya Shah <dhravya@supermemory.com>
Two hand-rolled copies of the add-on/brainMode rule replaced by a single shared helper, and the one-line isCompanyBrainOrganization wrapper dropped. No behaviour change.
…1536)

Returning from Stripe remounts onboarding and reseeds the domain from the user's email, so the header showed the wrong company and a research retry would re-run on the wrong domain. Past the confirm step, read the org's stored brainWorkspaceDomain instead.
## Stack Context

Single-auth story for the Claude Code supermemory plugin rework: the plugin's hooks and its MCP surface share one credential (`sm_` API key from the existing browser connect flow). That requires `mcp.supermemory.ai` to accept plain API keys, which it currently rejects (OAuth JWT only).

## What?

- `validateApiKey()` in `server/auth`: `sm_`-prefixed Bearer tokens validate via the existing `fetchSession()` (`GET /v3/session`) and map to the same `AuthUser` shape as OAuth tokens (`userId` ← `user.id`, `organizationId` ← `org.id`, the key itself as `bearerToken` for downstream API calls). Successful lookups cached per isolate for 60s.
- `handleMcpRequest` routes by token shape: `sm_` keys → session validation, everything else → OAuth JWT verification (unchanged).
- `sessionInfoSchema` now types the `org.id` field the session endpoint already returns.

## Why?

MCP clients that already hold an API key (Claude Code plugin hooks, CLI, scripts) can connect without an OAuth dance or a second consent. OAuth behavior is untouched — the existing "rejects opaque API keys" test on the OAuth validator still passes; keys just get their own path. Malformed keys are rejected without an API round-trip.

Tests: 4 new cases (valid key → AuthUser, cache hit → single fetch, 401 → null, malformed → no request). `vitest run src/server/auth` 13/13, `tsc --noEmit` clean.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Adds a new authentication path on the MCP entrypoint with in-memory key caching (60s TTL), so revoked keys may remain valid briefly within an isolate; OAuth behavior is unchanged.
>
> **Overview**
> MCP Bearer auth now accepts **`sm_` Supermemory API keys** in addition to OAuth JWTs, so clients that already hold an API key can connect without OAuth.
>
> **`validateApiKey`** treats keys matching `sm_` plus at least 17 non-space characters as API keys: it calls **`GET /v3/session`** with the key as Bearer, maps **`user.id`** and **`org.id`** into the same **`AuthUser`** shape as OAuth (key kept as **`bearerToken`** for downstream API calls), and caches successful results per isolate for **60s** (up to 1000 entries, full clear on overflow). Malformed keys are rejected locally with no HTTP call; session **401** yields unauthenticated.
>
> **`handleMcpRequest`** branches on token shape: API keys go through session validation; other tokens still use JWT verification unchanged.
>
> **`sessionInfoSchema`** now includes optional **`org.id`** typing for session responses used when resolving organization context from API keys.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit e54fb11. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
## Summary

- add an “Install plugins with one command” action beside the Plugins section

<img width="1280" height="651" alt="image" src="https://github.com/user-attachments/assets/a2e19a91-c94c-4a56-87c4-b72c4dbe89ba" />
<img width="1280" height="554" alt="image" src="https://github.com/user-attachments/assets/2cd4b3a4-ac30-4411-8221-baca09e90b0f" />
<!-- VORFLUX_AGENT_PR_BODY_BEGIN -->
Adds the full 654-entry MCP directory without bundling records into client JavaScript, with explicit capability status and connector branding that degrades safely when no authoritative logo is available.

## Changes

- Lazy-load and validate the searchable, filterable, progressively rendered MCP catalog.
- Render same-origin proxied provider icons for 543 entries, with a reviewed domain allowlist and deterministic fallback marks for 111 unresolved or unbranded entries.
- Record OAuth discovery capability separately from end-to-end support; all directory setup actions remain suppressed until their authentication flow is verified.
- Add a reproducible OAuth metadata probe with HTTPS/private-network protections, stable URL keys, authorization-server scanning, and catalog fingerprint validation.
- Add Google Drive branding for the curated built-in connector.

## Testing

- **Passed:** Deterministic generation and catalog assertions.
  ```bash
  PATH="$HOME/.bun/bin:$PATH" python3 apps/web/scripts/generate-mcp-directory.py --output
  cmp apps/web/public/mcp-directory.json
  ```
  Verified 654 entries, 254 DCR discoveries, 27 preregistered OAuth discoveries, 373 unclassified entries, and zero directory setup actions.
- **Passed:** Stale OAuth metadata fingerprint is rejected by the generator.
- **Passed:** Touched-file Biome checks and `git diff --check`.
- **Passed:** Icon proxy returned 200 for an allowlisted domain and 400 for an unknown valid-looking domain.
- **Passed:** Authenticated desktop/mobile browser inspection and conservative capability labels.
- **Passed:** Public preview returned HTTP 200 and rendered the real app. Authentication cookies do not transfer to the public hostname, so the public screenshot shows login.
- **Partial:** Repository-wide TypeScript checks remain blocked by unrelated existing errors outside the touched MCP files.
- **Partial:** 111 entries intentionally retain deterministic fallback marks; endpoint-derived domains may not always be the canonical brand logo.
- **Blocked:** Google rejected the local HTTP OAuth callback, so live Google Drive consent, callback, persistence, tool discovery, disconnect, and reconnect were not completed.

Public preview: https://ar8ruchhbi65.preview.us1.vorflux.com/configure/tools

---
**Attached Images**

*[288.csv]*

*[mcp-directory-final.json]*

![mcp-directory-branding-desktop.png](https://api.us1.vorflux.com/assets/artifacts/c3VwZXJtZW1vcnk6Zjo4MDA0.3_UzR_OP9Jk228FYbrAPTXyqybRBlqwn5Uv4tksf_Y0.png)

![mcp-directory-branding-mobile.png](https://api.us1.vorflux.com/assets/artifacts/c3VwZXJtZW1vcnk6Zjo4MDA1.b5G6nsOBVm2s6DlEFWFiMFCcULAkV0MCCGZ8XVsA5js.png)

![mcp-directory-public-preview.png](https://api.us1.vorflux.com/assets/artifacts/c3VwZXJtZW1vcnk6Zjo4MDA2.ZrBAeBi62JX1xavAtaDLQ0fuixgBjN7x1NrqIxtdmKw.png)
<!-- VORFLUX_AGENT_PR_BODY_END -->

---
**Session Details**
- Session: [View Session](https://supermemory.us1.vorflux.com/agent-sessions/1cd0aab9-2a45-4818-aa13-f9bfe032ddba)
- Requested by: Dhravya Shah (dhravya@supermemory.com)
- Address comments on this PR. Add `(aside)` to your comment to have me ignore it.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes how users pick MCP URLs and auth (OAuth vs API key) before hitting existing connect endpoints; no new backend auth logic in this diff, but misconfiguration or trusting bad URLs remains a user-risk surface.
>
> **Overview**
> Adds a **browseable MCP directory** on the Company Brain connectors page: the catalog is **not bundled in JS**—it loads from static **`/mcp-directory.json`** only after the user opens the directory (with validation, caching, and abort handling).
>
> The new **`McpDirectoryBrowser`** supports search, category/availability filters, and progressive “show more” rendering. Supported remote entries route into the existing custom MCP flow via **Set up**, which pre-fills name/URL and opens the connector dialog with context-specific copy.
>
> The custom connector dialog now uses an explicit **OAuth vs API key** toggle; API key fields only appear for API-key mode, and directory-backed connections get **stable slugs** (`-dir-` suffix) so names display cleanly on connected cards. **Middleware** excludes `mcp-directory.json` from the auth matcher so the asset can be fetched publicly.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 8b59bae. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@graphite-app graphite-app Bot added the extension related to Supermemory Chrome Extension label Aug 21, 2026

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Overview: Adds a GitHub Actions workflow to run pytest for four Python SDK packages, along with Python SDK v4 API migration, browser extension memory serialization improvements, MCP API key authentication, and various web app enhancements.

Issues found: None — this looks good to ship.

The code changes are well-structured:

  • CI workflow properly tests across Python versions (3.9-3.13) with dependency matrices for minimum/locked/current SDK versions
  • Python SDK correctly migrates to v4 API with proper deprecation warnings for include_full_docs, adds additionalProperties: false to tool schemas for stricter validation, and implements document delete scope checking
  • MCP auth adds API key validation with reasonable cache limits (1000 entries, 60s TTL)
  • Middleware properly scopes the ?view= bypass to / pathname only (security improvement)
  • Browser extension fixes memory serialization by using JSON instead of comma-delimited strings, preventing parsing issues with memories containing commas

Score: 9/10

Minor note: The PR title says "Python SDK pytest workflow" but includes substantial changes beyond CI. Consider updating the PR description to reflect the full scope for reviewers.

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

Labels

extension related to Supermemory Chrome Extension

Projects

None yet

Development

Successfully merging this pull request may close these issues.