chore(ci): Python SDK pytest workflow - #1431
Conversation
Run pytest for openai-sdk-python, agent-framework, cartesia, and pipecat packages on PRs touching those paths. Co-authored-by: Cursor <cursoragent@cursor.com>
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
supermemory-mcp | 006a3f5 | Aug 21 2026, 05:35 PM |
Deploying with
|
| 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 finished @ved015's task in 1m 52s —— View job Code Review Complete
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). |
…#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: Vedant Mahajan <vedant.04.mahajan@gmail.com>
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.
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]*    <!-- 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 -->
There was a problem hiding this comment.
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, addsadditionalProperties: falseto 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.

Summary
.github/workflows/ci-python.ymlto run pytest for the four Python SDK packagesStacked on #1430
Test plan
Made with Cursor