Skip to content

Conversation

@AnthonyRonning
Copy link
Contributor

@AnthonyRonning AnthonyRonning commented Nov 22, 2025

This PR implements the DELETE /v1/conversations endpoint in both the Rust and TypeScript SDKs.

Changes:

  • Rust SDK: Added delete_conversations method to OpenSecretClient and ConversationsDeleteResponse struct.
  • TypeScript SDK: Added deleteConversations function and ConversationsDeleteResponse type.
  • Tests: Added integration tests for both SDKs to verify the functionality.

Verified with:

  • cargo check
  • bun run build
  • Integration tests (local verification passed for new features)

Summary by CodeRabbit

  • New Features

    • Bulk conversation deletion added (new API and exposed via app context).
  • Refactor

    • Response shape updated to allow string or array outputs.
    • Formatting and minor style cleanups across TypeScript code.
  • Tests

    • Integration tests covering conversation creation, listing, bulk deletion, and improved test cleanup and assertions.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Nov 22, 2025

Walkthrough

Adds bulk conversation deletion across Rust and TypeScript SDKs: new delete_conversations/deleteConversations API methods, a ConversationsDeleteResponse type, TypeScript context/provider wiring, tests exercising the delete flow, and minor formatting/type adjustments (ResponsesRetrieveResponse.output broadened to string | any[]).

Changes

Cohort / File(s) Summary
Rust client
rust/src/client.rs
Added pub async fn delete_conversations(&self) -> Result<ConversationsDeleteResponse> which issues an encrypted DELETE to /v1/conversations.
Rust types
rust/src/types.rs
Added pub struct ConversationsDeleteResponse { pub object: String, pub deleted: bool } with derives Debug, Clone, Serialize, Deserialize.
Rust tests
rust/tests/ai_integration.rs
Added test_delete_conversations that authenticates, calls delete_conversations, and asserts object and deleted fields.
TypeScript API surface
src/lib/api.ts
Added ConversationsDeleteResponse type and export async function deleteConversations(): Promise<ConversationsDeleteResponse>; changed ResponsesRetrieveResponse.output from string to `string
TypeScript core files (formatting)
src/lib/ai.ts, src/lib/encryptedApi.ts
Small formatting/whitespace and string-quote adjustments; no functional behavior changes.
TypeScript context & provider
src/lib/main.tsx
Added deleteConversations: typeof api.deleteConversations to OpenSecretContextType, default context value, and provider wiring.
TypeScript exports
src/lib/index.ts
Re-exported ConversationsDeleteResponse from ./api.
TypeScript integration tests
src/lib/test/integration/ai.test.ts, src/lib/test/integration/api.test.ts, src/lib/test/integration/apiKeys.test.ts
Added integration test for deleting all conversations; imported deleteConversations (and listConversations), updated assertions, improved cleanup and some optional-chaining guards; several formatting tweaks.

Sequence Diagram

sequenceDiagram
    participant Consumer
    participant Provider as OpenSecretProvider
    participant SDK as API (TS/Rust)
    participant Backend as /v1/conversations

    Consumer->>Provider: call deleteConversations()
    Provider->>SDK: deleteConversations()
    SDK->>Backend: Encrypted DELETE /v1/conversations
    Backend-->>SDK: {"object":"list.deleted","deleted":true}
    SDK-->>Provider: Promise<ConversationsDeleteResponse>
    Provider-->>Consumer: resolved response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Areas needing attention:
    • Type change: ResponsesRetrieveResponse.outputstring | any[] (check downstream typing and usages)
    • Context/provider wiring in src/lib/main.tsx (ensure proper types and exports)
    • Integration test logic in src/lib/test/integration/ai.test.ts (create/list/delete sequence and cleanup)
    • Rust encrypted DELETE request shape and response deserialization in rust/src/client.rs / rust/src/types.rs

Possibly related PRs

Poem

🐰 I dug a tunnel in the code, so neat,
One hop — all chats are swept off their feet.
From Rust burrow to TS hilltop,
A single call and — poof — they stop.
Hooray for tidy trails and tiny feet! 🥕✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main feature: implementing a delete all conversations endpoint across both Rust and TypeScript SDKs, which is reflected throughout the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 94.12% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/delete-all-conversations

Comment @coderabbitai help to get the list of available commands and usage tips.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Nov 22, 2025

Deploying opensecret-sdk with  Cloudflare Pages  Cloudflare Pages

Latest commit: 0dddce8
Status: ✅  Deploy successful!
Preview URL: https://c817d1a8.opensecret-sdk.pages.dev
Branch Preview URL: https://feat-delete-all-conversation.opensecret-sdk.pages.dev

View logs

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Nov 22, 2025

Greptile Overview

Greptile Summary

Added DELETE /v1/conversations endpoint implementation to both Rust and TypeScript SDKs with comprehensive integration tests.

Key Changes

  • Rust SDK: Added delete_conversations() method in client.rs and ConversationsDeleteResponse struct in types.rs
  • TypeScript SDK: Added deleteConversations() function in api.ts, exported type in index.ts, and integrated into React context in main.tsx
  • Tests: Added integration tests in both SDKs that verify the endpoint returns expected response format
  • Type Enhancement: Changed ResponsesRetrieveResponse.output field from string to string | any[] to properly handle array responses
  • Formatting: Minor code formatting improvements across several files (Prettier/linter cleanup)

Implementation Quality

  • Follows existing SDK patterns and conventions consistently
  • Proper TypeScript type safety with correct type exports
  • Complete integration into React context for easy consumption
  • Comprehensive test coverage with proper assertions
  • Documentation includes clear warnings about permanence of deletion

Confidence Score: 5/5

  • This PR is safe to merge with no identified issues
  • The implementation is clean, follows established patterns perfectly, includes proper tests with assertions (per custom instructions), and the type enhancement for output field improves type safety. All changes are additive with no breaking modifications.
  • No files require special attention

Important Files Changed

File Analysis

Filename Score Overview
rust/src/client.rs 5/5 Added delete_conversations method that calls encrypted API endpoint - clean implementation consistent with existing patterns
rust/src/types.rs 5/5 Added ConversationsDeleteResponse struct with proper serialization - straightforward type definition
rust/tests/ai_integration.rs 4/5 Added integration test for delete conversations endpoint - test doesn't create conversations first but verifies API contract
src/lib/api.ts 5/5 Added deleteConversations function and ConversationsDeleteResponse type, plus formatting improvements - implementation follows existing patterns
src/lib/main.tsx 5/5 Added deleteConversations to context type and provider - proper context integration
src/lib/test/integration/ai.test.ts 5/5 Added comprehensive test that creates conversations, deletes all, and verifies deletion - complete test coverage with proper assertions

Sequence Diagram

sequenceDiagram
    participant Client as SDK Client
    participant API as OpenSecret API
    participant DB as Database

    Note over Client,DB: Delete All Conversations Flow

    Client->>API: DELETE /v1/conversations
    Note right of Client: Authenticated request<br/>(JWT or API Key)
    
    API->>API: Verify authentication
    API->>API: Decrypt request
    
    API->>DB: Query user's conversations
    DB-->>API: Return conversation IDs
    
    API->>DB: Delete all conversations<br/>and associated items
    DB-->>API: Deletion confirmed
    
    API->>API: Encrypt response
    API-->>Client: ConversationsDeleteResponse<br/>{object: "list.deleted", deleted: true}
    
    Note over Client: Response decrypted<br/>in SDK
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

11 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

@AnthonyRonning AnthonyRonning force-pushed the feat/delete-all-conversations branch from c35b528 to 0dddce8 Compare November 22, 2025 23:13
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

11 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
rust/tests/ai_integration.rs (1)

239-266: Address failing test_guest_user_cannot_use_ai before merging

CI indicates test_guest_user_cannot_use_ai is currently failing (“Guest users should not be able to access models”), so the guest user is now apparently able to hit at least get_models() successfully.

Please decide whether:

  • The intended behavior changed (guests may use AI) → update/relax this test accordingly, or
  • Guests should still be blocked → adjust server-side behavior (or client-side error handling) so the assertions here hold again.

Either way, this failure needs to be resolved for the Rust CI pipeline to pass.

🧹 Nitpick comments (4)
rust/src/types.rs (1)

301-305: ConversationsDeleteResponse struct matches the new endpoint shape

The struct mirrors the TS ConversationsDeleteResponse at runtime (object + deleted) and follows existing derive patterns. If you ever want stricter typing, you could narrow object (e.g., to a small enum or a &'static str), but it’s not required for this PR.

src/lib/main.tsx (1)

755-766: Conversation list/delete additions are wired correctly; consider DRYing the params type

Adding listConversations and deleteConversations to the context type, default value, and provider value keeps the React surface aligned with the new API functions and looks correct.

One minor suggestion: listConversations currently inlines its params shape. To avoid drift if api.listConversations evolves (e.g., adding order), you might eventually:

  • Export a ConversationsListParams type from ./api, and/or
  • Type this as typeof api.listConversations for consistency with most other methods.

Not urgent, but it would reduce maintenance risk.

Also applies to: 911-911, 1325-1325

rust/tests/ai_integration.rs (1)

178-207: test_delete_conversations covers the core contract; room for future tightening

The integration test correctly exercises delete_conversations on an authenticated client and asserts the expected "list.deleted" + deleted: true response, which is enough to validate the endpoint wiring today.

Once the Rust client exposes explicit conversation create/list APIs, you might:

  • Create a few conversations first and then assert that subsequent list calls are empty after deletion.
  • Trim some of the now-historical comments about SDK gaps to keep the test focused.

For now, this is fine as an initial coverage point.

src/lib/api.ts (1)

1565-1565: Consider more specific typing than any[].

The broadened type string | any[] improves flexibility but loses type safety. Consider defining a more specific type for the array case based on the actual response structure (e.g., Array<ResponseOutputItem> where ResponseOutputItem has defined shape).

// Consider defining a more specific type
export type ResponseOutputItem = {
  type: "message";
  content: Array<{ type: string; text?: string; }>;
  // ... other known fields
};

export type ResponsesRetrieveResponse = {
  // ...
  output?: string | Array<ResponseOutputItem>;
};
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 39cc7ea and 0dddce8.

📒 Files selected for processing (11)
  • rust/src/client.rs (1 hunks)
  • rust/src/types.rs (1 hunks)
  • rust/tests/ai_integration.rs (1 hunks)
  • src/lib/ai.ts (2 hunks)
  • src/lib/api.ts (16 hunks)
  • src/lib/encryptedApi.ts (1 hunks)
  • src/lib/index.ts (1 hunks)
  • src/lib/main.tsx (4 hunks)
  • src/lib/test/integration/ai.test.ts (10 hunks)
  • src/lib/test/integration/api.test.ts (1 hunks)
  • src/lib/test/integration/apiKeys.test.ts (6 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-08-21T21:30:25.143Z
Learnt from: AnthonyRonning
Repo: OpenSecretCloud/OpenSecret-SDK PR: 44
File: src/lib/test/integration/apiKeys.test.ts:2-8
Timestamp: 2025-08-21T21:30:25.143Z
Learning: In the OpenSecret SDK codebase, integration tests follow an established architecture where the API URL is set globally via bunfig.toml's preload configuration that includes api-url-loader.ts, which runs before all tests. Individual test files do not call setApiUrl() as this would be redundant and inconsistent with the established pattern used across all integration tests.

Applied to files:

  • src/lib/test/integration/ai.test.ts
  • src/lib/test/integration/apiKeys.test.ts
📚 Learning: 2025-08-21T21:30:25.143Z
Learnt from: AnthonyRonning
Repo: OpenSecretCloud/OpenSecret-SDK PR: 44
File: src/lib/test/integration/apiKeys.test.ts:2-8
Timestamp: 2025-08-21T21:30:25.143Z
Learning: In the OpenSecret SDK codebase, integration tests use a global setup architecture where bunfig.toml preloads api-url-loader.ts, which calls setApiUrl() globally before all tests run. Individual integration test files (like api.test.ts and apiKeys.test.ts) do not call setApiUrl() as this would be redundant and inconsistent with the established pattern. The API URL is set once globally via environment variables through this preload mechanism.

Applied to files:

  • src/lib/test/integration/ai.test.ts
  • src/lib/test/integration/apiKeys.test.ts
📚 Learning: 2025-02-28T02:12:34.704Z
Learnt from: AnthonyRonning
Repo: OpenSecretCloud/OpenSecret-SDK PR: 24
File: src/lib/platformApi.ts:291-300
Timestamp: 2025-02-28T02:12:34.704Z
Learning: The listProjectSecrets function in platformApi.ts only returns metadata about secrets (key_name and timestamps) and not the actual secret values, following security best practices.

Applied to files:

  • src/lib/api.ts
🧬 Code graph analysis (6)
rust/src/client.rs (2)
src/lib/api.ts (1)
  • ConversationsDeleteResponse (1642-1645)
src/lib/index.ts (1)
  • ConversationsDeleteResponse (28-28)
rust/src/types.rs (2)
src/lib/api.ts (1)
  • ConversationsDeleteResponse (1642-1645)
src/lib/index.ts (1)
  • ConversationsDeleteResponse (28-28)
src/lib/test/integration/ai.test.ts (2)
src/lib/api.ts (3)
  • transcribeAudio (1511-1546)
  • listConversations (2062-2090)
  • deleteConversations (1944-1951)
src/lib/ai.ts (1)
  • createCustomFetch (9-204)
src/lib/main.tsx (2)
src/lib/api.ts (1)
  • ConversationsListResponse (1628-1634)
src/lib/index.ts (1)
  • ConversationsListResponse (26-26)
src/lib/test/integration/apiKeys.test.ts (2)
src/lib/api.ts (3)
  • listApiKeys (1247-1259)
  • deleteApiKey (1282-1291)
  • createApiKey (1218-1225)
src/lib/ai.ts (1)
  • createCustomFetch (9-204)
src/lib/api.ts (2)
src/lib/index.ts (5)
  • ConversationsDeleteResponse (28-28)
  • Conversation (21-21)
  • ConversationCreateRequest (23-23)
  • ConversationsListResponse (26-26)
  • ResponsesCreateRequest (20-20)
src/lib/encryptedApi.ts (1)
  • authenticatedApiCall (17-77)
🪛 GitHub Actions: Rust CI
rust/tests/ai_integration.rs

[error] 241-241: Guest users should not be able to access models. Test 'test_guest_user_cannot_use_ai' failed (exit code 101).

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (12)
src/lib/encryptedApi.ts (1)

91-104: Formatting-only change in openAiAuthenticatedApiCall

The refactor to a single-line internalEncryptedApiCall and whitespace cleanup are no-ops behaviorally; the API-key path and error handling remain correct and consistent with authenticatedApiCall.

src/lib/test/integration/api.test.ts (1)

335-337: Multi-line updatedInstruction.prompt assertion is fine

Only readability changed; the expectation string is identical, so test behavior is preserved.

src/lib/index.ts (1)

27-28: Re-export of ConversationsDeleteResponse keeps public TS surface in sync

Exporting ConversationsDeleteResponse alongside ConversationDeleteResponse matches the new /v1/conversations delete-all API and allows consumers to import the type from the root.

src/lib/ai.ts (1)

9-11: createCustomFetch signature and TTS header tweaks are behavior‑preserving

The multi-line createCustomFetch signature and lowercased header names for TTS responses do not change runtime behavior; the custom fetch API and decryption logic remain intact.

Also applies to: 167-170

src/lib/main.tsx (1)

645-671: Transcribe audio JSDoc spacing change is non-functional

Only comment formatting changed around transcribeAudio; the documented behavior and function signature remain the same.

src/lib/test/integration/ai.test.ts (4)

2-8: LGTM: Import additions are correct.

The new imports deleteConversations and listConversations properly reference the functions added to src/lib/api.ts.


751-760: Good defensive programming with optional chaining.

The addition of optional chaining (retrievedResponse.output?.length) and runtime type guards properly handles the updated type signature of ResponsesRetrieveResponse.output, which now allows string | any[].


814-819: Consistent defensive programming pattern.

The type checking pattern matches the changes at lines 751-760, ensuring robust handling of the updated ResponsesRetrieveResponse.output type.


1101-1131: Well-structured integration test for bulk deletion.

The test properly verifies the deleteConversations() workflow:

  1. Creates test data (2 conversations)
  2. Verifies existence (at least 2 conversations)
  3. Calls bulk delete
  4. Verifies response structure
  5. Confirms deletion (exactly 0 conversations)
src/lib/api.ts (2)

1642-1645: LGTM: Type definition follows established patterns.

The ConversationsDeleteResponse type is well-structured and consistent with the existing ConversationDeleteResponse (singular). The object: "list.deleted" discriminator clearly distinguishes bulk deletion from single-item deletion.


1925-1951: Client-side implementation is correct; backend safeguards are outside scope of this PR.

The function properly implements the client-side DELETE call to /v1/conversations with appropriate error handling and documentation. However, this repository contains only client libraries (TypeScript and Rust), not the backend implementation. Verification of backend safeguards (soft delete, backup, audit logging, batch handling for large datasets) must be conducted against the actual backend service repository, which is out of scope for this PR.

Confirm with the backend team that the endpoint implements appropriate protections before deployment.

src/lib/test/integration/apiKeys.test.ts (1)

82-91: Good improvement: Cleanup in finally block.

Moving the cleanup logic to a finally block ensures that test API keys are deleted even if the test fails. The try-catch within the cleanup loop properly handles individual deletion failures without stopping the cleanup of remaining keys.

@AnthonyRonning AnthonyRonning merged commit a2cb223 into master Nov 23, 2025
7 of 8 checks passed
@AnthonyRonning AnthonyRonning deleted the feat/delete-all-conversations branch November 23, 2025 02:24
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