Skip to content

feat: implement map plugin data by persona name - #11348

Open
undivisible wants to merge 4 commits into
mainfrom
fix-map-plugin-data-by-persona-10758176398782856520
Open

feat: implement map plugin data by persona name#11348
undivisible wants to merge 4 commits into
mainfrom
fix-map-plugin-data-by-persona-10758176398782856520

Conversation

@undivisible

@undivisible undivisible commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Implement mapping for plugin data based on persona name to a local JSON file.


PR created automatically by Jules for task 10758176398782856520 started by @undivisible

Review in cubic


Note

High Risk
Removes multiple first-party LLM and language APIs, changes desktop release automation and CI gates, and touches auth/env/OpenAI usage on mobile—high blast radius if merged unintentionally with the small script change.

Overview
This PR is far larger than the Jules task title suggests. Besides the intended backend/scripts/web.py change that groups exported persona messages into plugin_data_by_persona_name.json, the diff rolls back many recent platform changes across CI, backend, mobile, and desktop.

Desktop release & CI: macOS candidate tagging is manual-only (workflow_dispatch); the hourly schedule, tag-interval throttle, and “newest green SHA” fallback are removed from plan-desktop-release.py. Desktop changelog enforcement no longer accepts unreleased fragments already in the tree on release-lane pushes. Pre-push CI again skips desktop-swift-release-compile on PRs (main-only). Several failure-class records flip from dormant to open; one transparent-window failure class file is deleted.

Backend API removals: Return-only managed-LLM endpoints are dropped (/v1/knowledge-graph/extract, /v1/memories/extract, /v1/connectors/synthesize, /v1/conversations/topic, /v1/users/ai-profile/synthesize, GET /v1/users/available-languages) along with related policy/manifest entries, tests, and inventory docs. MCP conversation search reverts to summary vectors only (no transcript-chunk merge or match_snippets). desktop_chat no longer routes a separate structured Luna lane. Action-item date coercion on write is simplified (string parse only). Vector search drops optional precomputed query_vector.

Mobile app: Restores a client-side openai.dart and OPENAI_API_KEY in env; removes server-driven available-languages fetch/cache and deletes home_provider_languages_test.dart.

Misc: Listen STT failure attribution uses provider captured at init again; firmware adds a temporary OMI_shell → CV1 mapping; ratchet baselines and codemagic contract hashes updated.

Reviewed by Cursor Bugbot for commit e24cdb4. Configure here.

@google-labs-jules

Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@cursor

cursor Bot commented Aug 10, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_e632ea19-eb4c-429a-90c2-27df637058e4)

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 1 file

Confidence score: 5/5

  • In backend/scripts/web.py, the new persona grouping/UID injection and missing-input-file paths currently lack hermetic regression coverage, so future edits could silently alter file transforms or error handling and ship incorrect outputs; add focused hermetic tests for those branches to lock behavior down.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="backend/scripts/web.py">

<violation number="1" location="backend/scripts/web.py:38">
P3: Add hermetic coverage for persona grouping/UID injection and the missing-input-file branch; this new file-transforming behavior otherwise has no regression guard.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread backend/scripts/web.py
return uids


def map_plugin_data_by_persona_name() -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: Add hermetic coverage for persona grouping/UID injection and the missing-input-file branch; this new file-transforming behavior otherwise has no regression guard.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At backend/scripts/web.py, line 38:

<comment>Add hermetic coverage for persona grouping/UID injection and the missing-input-file branch; this new file-transforming behavior otherwise has no regression guard.</comment>

<file context>
@@ -35,9 +35,36 @@ def process_user(uid: str) -> None:
     return uids
 
 
+def map_plugin_data_by_persona_name() -> None:
+    try:
+        with open("user_messages_with_bot_name.json", "r") as f:
</file context>

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9c00a20edb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread backend/scripts/web.py
Comment on lines +55 to +57
message_with_uid = message.copy()
message_with_uid["uid"] = uid
plugin_data_by_persona[bot_name].append(message_with_uid)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Load plugin documents instead of relabeling messages

Whenever this function runs, it copies records from user_messages_with_bot_name.json into the new output without ever reading the authoritative plugins_data collection (backend/database/apps.py:30). Consequently, plugin_data_by_persona_name.json contains chat-message documents plus a UID—not persona/plugin metadata—so downstream analysis expecting plugin data receives the wrong dataset despite the success message. Query the plugin documents and index their data by the persona name field instead.

Useful? React with 👍 / 👎.

Comment thread backend/scripts/web.py
if __name__ == "__main__":
get_user_messages_with_bot_name()
# TODO: map all plugin_data by persona_name so that we can map, local json
map_plugin_data_by_persona_name()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid mapping only the first twenty users

In the script's new execution path, this call always consumes the file just generated by get_user_messages_with_bot_name(), whose UID list is capped with get_users_uid()[:20]. Thus, even if grouping messages is intentional, the advertised persona mapping silently excludes every qualifying user after the first twenty and produces incomplete analysis results; remove the sampling cap or make the limited scope explicit in the output.

Useful? React with 👍 / 👎.

@Git-on-my-level Git-on-my-level added needs-tests PR introduces logic that should be covered by tests python labels Aug 10, 2026
@Git-on-my-level

Copy link
Copy Markdown
Collaborator

Thanks for the focused cleanup here. I reviewed the single changed file, backend/scripts/web.py:

  • map_plugin_data_by_persona_name() keeps the transform local/offline: it reads user_messages_with_bot_name.json, groups messages by botName, copies each message before adding uid, and writes plugin_data_by_persona_name.json. That matches the stated goal without touching production request paths.
  • The FileNotFoundError branch is safe for reruns/manual use: it prints a clear message and returns instead of failing with a traceback.
  • The __main__ order is sensible: get_user_messages_with_bot_name() now produces the input file before the mapper runs.

I am not formally approving because this is still a backend script/data-export path, and the new JSON transform has no hermetic regression coverage. A small test or documented sample input/output for the grouping, uid injection, skipped empty botName, and missing-input branch would make this much safer to maintain.

Leaving this as a positive implementation signal, with needs-tests for the missing regression coverage.

Automated maintainer review by glm-5.2.


by AI on behalf of David — if you need David’s attention urgently, please @Git-on-my-level and escalate with need human response.

@undivisible undivisible added human Human-authored pull request backend Backend Task (python) workflow-review Needs maintainer review for workflow, automation, hooks, or CI behavior AI and removed human Human-authored pull request labels Aug 10, 2026
@Git-on-my-level Git-on-my-level removed python workflow-review Needs maintainer review for workflow, automation, hooks, or CI behavior labels Aug 10, 2026
@cursor

cursor Bot commented Aug 10, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_e9212a3e-950e-47ac-9350-5da2ab1c565a)

@Git-on-my-level Git-on-my-level added positive-signal Good PR — positive signal, not a formal approval and removed needs-tests PR introduces logic that should be covered by tests labels Aug 10, 2026
@Git-on-my-level

Copy link
Copy Markdown
Collaborator

Thanks for the follow-up here — this addresses the coverage gap from the earlier review.

I reviewed both changed files on the current head:

  • backend/scripts/web.py: get_user_messages_with_bot_name() now exports all user IDs instead of the earlier sample cap, and map_plugin_data_by_persona_name() stays confined to the offline/local JSON workflow. The mapper reads user_messages_with_bot_name.json, skips messages without a truthy botName, copies each message before adding uid, writes plugin_data_by_persona_name.json, and handles a missing input file by returning without writing output. I do not see this touching production request/auth paths.
  • backend/tests/unit/test_web_persona_export.py: the new tests use testing.import_isolation plus a stubbed database._client, so they exercise the mapper without Firestore credentials. They cover grouping by persona name, uid injection, skipping records without botName, and the missing-input branch.

Verification I ran locally:

BACKEND_UNIT_TEST_FILE_LIST=/tmp/pr11348-tests.txt BACKEND_PYTEST_WORKERS=1 ./test.sh

Result: 2 passed in 0.09s for tests/unit/test_web_persona_export.py.

I’m removing needs-tests and leaving this as a positive implementation signal rather than a formal approval because this remains a backend data-export script path; maintainers can decide final merge readiness.

Automated maintainer review by glm-5.2.


by AI on behalf of David — leaving final merge readiness to human maintainer review for this backend data-export script path.

@undivisible
undivisible force-pushed the fix-map-plugin-data-by-persona-10758176398782856520 branch from 7d9d50e to ab2b479 Compare August 10, 2026 21:11
@cursor

cursor Bot commented Aug 10, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_aeca79af-7654-4d07-a4ae-af10bb177eb9)

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ab2b479d28

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread backend/scripts/web.py
if __name__ == "__main__":
get_user_messages_with_bot_name()
# TODO: map all plugin_data by persona_name so that we can map, local json
map_plugin_data_by_persona_name()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Propagate export failures before mapping

When any user's Firestore stream raises, such as during a transient RPC failure, the iterator returned by executor.map() at line 30 is never consumed, so the worker exception is suppressed and get_user_messages_with_bot_name() writes a partial input file. This newly unconditional mapping step then converts that incomplete file and reports success, silently excluding affected users from the analysis; consume the executor results so failures surface, and only map after a successful export.

Useful? React with 👍 / 👎.

undivisible and others added 2 commits August 11, 2026 07:11
Addresses a TODO in `backend/scripts/web.py` by implementing
`map_plugin_data_by_persona_name` to organize existing plugin data
by persona name (`botName`) and output it to a local JSON file.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
@undivisible
undivisible force-pushed the fix-map-plugin-data-by-persona-10758176398782856520 branch from ab2b479 to b3218ad Compare August 10, 2026 23:11
@cursor

cursor Bot commented Aug 10, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_54c6528d-cff2-4c54-9b68-436cf3efdbdb)

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b3218ad20d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread backend/scripts/web.py Outdated
def get_user_messages_with_bot_name() -> List[str]:
user_messages_with_bot_name: Dict[str, List[Dict[str, Any]]] = {}
uids = get_users_uid()[:20]
uids = get_users_uid()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Batch the now-unbounded user export

When this is run against the production users collection, removing the 20-user cap makes get_users_uid() materialize every UID, ThreadPoolExecutor.map() eagerly submit work for all of them, and user_messages_with_bot_name retain every matching message until the final JSON write. On a large database this can exhaust process memory or generate an unexpectedly large Firestore read burst before producing any output; iterate through bounded user batches and flush results incrementally instead.

Useful? React with 👍 / 👎.

Comment thread backend/scripts/web.py
message_with_uid["uid"] = uid
plugin_data_by_persona[bot_name].append(message_with_uid)

with open("plugin_data_by_persona_name.json", "w") as f:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Ignore the generated user-data export

When the script is run from the repository worktree, this creates an untracked plugin_data_by_persona_name.json containing user messages and UIDs, but neither the root nor backend .gitignore ignores that filename. A routine git add -A can therefore stage a production-data export—made especially easy to overlook by the plugin-data filename—so this generated file should be ignored or written outside the repository.

Useful? React with 👍 / 👎.

@cursor

cursor Bot commented Aug 11, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_ab184a93-4f04-460e-b8aa-79335f4ecd8f)

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ec90cbc9a8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread backend/scripts/web.py Outdated
Comment on lines +61 to +62
persona_name = plugin_data.get("name")
if not isinstance(persona_name, str) or persona_name not in persona_uids:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Join persona usage on pluginId rather than name

When two personas share a display name, or a persona is renamed after messages are saved, this join assigns every same-named plugin document to the user or drops the usage entirely. The web writer stores the stable pluginId in each message (web/personas-open-source/src/app/chat/page.tsx:165-171), while persona creation does not make name unique (backend/routers/apps.py:899-905), so use the plugin ID for the join and reserve name for the output label.

Useful? React with 👍 / 👎.

Comment thread backend/scripts/web.py Outdated
for uid in sorted(persona_uids[persona_name]):
# Include uid in the mapped data to keep track of who the message belongs to
plugin_data_with_uid = plugin_data.copy()
plugin_data_with_uid["uid"] = uid

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve the plugin owner's uid

For normal plugin documents, uid already identifies the owner and is set during persona creation; overwriting it here with the user who sent a message silently corrupts that plugin metadata and makes creator and consumer indistinguishable in the export. Keep the original uid and add the chatting user under a separate field such as user_uid.

Useful? React with 👍 / 👎.

Comment thread backend/scripts/web.py Outdated
persona_uids.setdefault(bot_name, set()).add(uid)

plugin_data_by_persona: Dict[str, List[Dict[str, Any]]] = {}
for plugin_document in db.collection("plugins_data").stream():

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Obtain the Firestore client at call time

The new mapper reads through the module-level legacy db proxy, preventing the function from using the repository's injectable Firestore seam and forcing tests to replace the imported module. Accept an optional keyword-only client and otherwise call get_firestore_client() when the mapper runs.

AGENTS.md reference: backend/AGENTS.md:L193-L193

Useful? React with 👍 / 👎.

Comment thread backend/scripts/web.py Outdated
Comment on lines +31 to +33
for start in range(0, len(uids), USER_BATCH_SIZE):
with ThreadPoolExecutor(max_workers=USER_BATCH_SIZE) as executor:
list(executor.map(process_user, uids[start : start + USER_BATCH_SIZE]))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Flush each export batch before reading the next

When production contains enough users or messages, this loop only caps simultaneous Firestore reads: get_users_uid() is still fully materialized and every batch continues accumulating its matching documents in user_messages_with_bot_name until the final JSON dump. Fresh evidence in this revision is that the newly added executor batching has no per-batch flush, so memory remains proportional to the entire export and can still be exhausted; write each batch incrementally or merge bounded temporary files.

Useful? React with 👍 / 👎.

Comment thread backend/scripts/web.py
Comment on lines +45 to +47
except FileNotFoundError:
print("user_messages_with_bot_name.json not found. Run get_user_messages_with_bot_name() first.")
return

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Remove stale output when the input is missing

When an earlier run has already created plugin_data_by_persona_name.json and the input file is later removed or unavailable, this branch reports the problem and returns successfully without deleting the previous output. A caller can then mistake that stale mapping for the result of the current run; remove the output before returning or raise an error so the failed export cannot leave an apparently valid artifact.

Useful? React with 👍 / 👎.

Comment thread backend/scripts/web.py Outdated
continue
for uid in sorted(persona_uids[persona_name]):
# Include uid in the mapped data to keep track of who the message belongs to
plugin_data_with_uid = plugin_data.copy()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Redact stored credentials from the export

When a matched plugins_data document belongs to an OAuth-enabled app, copying the complete document also copies external_integration.mcp_oauth_tokens, which stores client_secret, access_token, and refresh_token (backend/routers/apps.py:1895-1903,1995-2017). The subsequent JSON write creates a plaintext credential export, and .gitignore only prevents Git tracking rather than disclosure from the file itself; project only the metadata needed for analysis or explicitly remove secret-bearing fields before serialization.

Useful? React with 👍 / 👎.

@Git-on-my-level Git-on-my-level removed the positive-signal Good PR — positive signal, not a formal approval label Aug 11, 2026

@Git-on-my-level Git-on-my-level left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the iteration here — I reviewed the current head (ec90cbc9a84a6f3e60a1835977b0cecaf533ba77) and the implementation is close, but one merge-blocking repository contract still needs to be fixed before this should land.

File-by-file notes:

  • .gitignore: adding **/user_messages_with_bot_name.json and **/plugin_data_by_persona_name.json is the right direction for this local export workflow; these generated Firestore-derived JSON artifacts should not be committed.
  • backend/scripts/web.py: get_user_messages_with_bot_name() now intentionally scans all UIDs and batches workers with USER_BATCH_SIZE = 20, which avoids one unbounded executor over the whole user base. The new map_plugin_data_by_persona_name() also keeps the export local/offline: it reads user_messages_with_bot_name.json, builds persona-name to UID sets from botName, streams plugins_data, copies each matched plugin document, injects uid, and writes plugin_data_by_persona_name.json. I did not find a production request/auth path change here.
  • backend/tests/unit/test_web_persona_export.py: the added hermetic tests stub database._client, cover plugin document grouping plus UID injection, cover the missing-input-file branch, verify the all-user scan writes only messages with botName, and assert worker stream failures propagate without writing a partial export.

Validation:

  • GitHub CI currently fails PR Metadata Preflight on failure-class-protocol: the branch includes fix(scripts): map persona exports from plugin data, and fix-prefixed commits need a Failure-Class: FC-<slug> | new | none declaration.
  • I also ran a no-secrets local smoke of the changed export functions against stubbed Firestore collections; it passed for all-user message export, plugin-data mapping, and missing-input handling.
  • The repo backend/test.sh focused run could not execute in this local checkout because backend test dependencies are not installed here (ModuleNotFoundError: No module named 'google' from tests/unit/conftest.py), so I am relying on the CI backend gate plus the manual hermetic smoke for execution evidence.

Please add the required failure-class declaration (or adjust the commit subject if this is not intended to be a fix) and get the failing preflight green. I’m removing the positive-signal label for now because CI is still red; the backend implementation itself looks reasonable once that metadata gate is satisfied.

Automated maintainer review by glm-5.2.


by AI on behalf of David — leaving final merge readiness to human maintainer review after the repository preflight contract is green.

Addresses a TODO in `backend/scripts/web.py` by implementing
`map_plugin_data_by_persona_name` to organize existing plugin data
by persona name (`botName`) and output it to a local JSON file.

Failure-Class: none

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
@mintlify

mintlify Bot commented Aug 11, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
omi 🟢 Ready View Preview Aug 11, 2026, 6:00 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@cursor

cursor Bot commented Aug 11, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_b238f6f8-2694-4869-b133-681f11efecb0)

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e24cdb42a8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +4 to 8
# Manual only: automatic push/schedule tagging was cutting a new macOS candidate
# tag on nearly every desktop-affecting main merge and every 15 minutes. Plan and
# publish a candidate deliberately via workflow_dispatch; qualification/promotion
# workflows remain unchanged once a tag exists.
workflow_dispatch:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restore an automatic desktop release trigger

The inspected on: block now contains only workflow_dispatch, and a repo-wide search found no other workflow that invokes this candidate planner automatically. Consequently, macOS-affecting merges no longer create a candidate tag, start Codemagic, or reach automatic beta qualification unless an operator manually dispatches this workflow, contrary to the documented automatic release path. Restore the scheduled or push trigger.

AGENTS.md reference: desktop/macos/AGENTS.md:L59-L61

Useful? React with 👍 / 👎.

Comment on lines +614 to +618
OMI_NOTIFICATION_CALLBACK_SMOKE_RESULT_PATH="$NOTIFICATION_CALLBACK_MARKER" \
"$executable" >/tmp/omi-signed-artifact-smoke.out 2>/tmp/omi-signed-artifact-smoke.err &
SMOKE_PID=$!
pass "Signed app launched for UserNotifications callback canary"
return 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep the normal-launch liveness check in canary mode

Codemagic invokes this script with both --launch and --notification-callback-canary for the signed app and Beta artifacts, but this branch returns immediately after starting the callback-only process. That process deliberately exits after writing its marker, so the release smoke no longer opens the app through LaunchServices or checks sustained liveness; an artifact whose normal startup crashes can therefore pass the signed smoke and continue toward publication.

AGENTS.md reference: desktop/macos/AGENTS.md:L79-L79

Useful? React with 👍 / 👎.

updated[existingIndex] = segment;
return updated;
}
return [...prev, segment];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Bound the live transcript segment list

For long web recordings that produce more than a few hundred unique STT segments, this append path grows segments without limit and causes every incoming segment to copy and rerender the entire non-virtualized transcript. The removed applyLiveTranscriptSegment path capped the live UI at 400 entries specifically to prevent Chrome degradation and freezes during roughly hour-long sessions while preserving the full server-side recording; retain that bounded path.

Useful? React with 👍 / 👎.

Comment thread backend/routers/users.py
url = data.url
set_user_webhook_db(uid, wtype, url)
if not webhook_url_from_setting(wtype, url):
if url == '' or url == ',':

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Treat delayed empty audio webhook URLs as disabled

When a user clears an audio-bytes webhook while retaining its configured delay, the app stores a value such as ,5; this condition recognizes only '' and the literal ',', so saving the cleared setting re-enables the webhook and makes the toggle come back on. Determine emptiness from the URL portion before the comma rather than comparing the complete stored value.

Useful? React with 👍 / 👎.

int? maxTokens,
}) async {
final url = 'https://api.openai.com/v1/$urlSuffix';
final headers = {'Content-Type': 'application/json; charset=utf-8', 'Authorization': 'Bearer ${Env.openAIAPIKey}'};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep the OpenAI credential out of the mobile binary

When OPENAI_API_KEY is populated for a production build as the new environment field expects, Envied embeds the value in the distributable app and this request uses it directly as a bearer credential. Envied obfuscation does not provide a server-side trust boundary, so anyone with the APK or IPA can recover the shared key and consume its project quota; route these requests through the authenticated backend or require a user-owned credential instead.

Useful? React with 👍 / 👎.

Comment thread backend/routers/mcp.py
search_transcript_chunks=vector_db.search_transcript_chunks,
embed_query=vector_db.embeddings.embed_query,
)
conversation_ids = vector_db.query_vectors(query, uid, starts_at=starts_at, ends_at=ends_at, k=limit)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Include transcript chunks in MCP conversation search

When a query phrase appears only in a transcript and not in the generated conversation summary, this summary-vector-only lookup returns no hit even though transcript chunks are indexed. I checked both MCP handlers and found no relocated call to search_transcript_chunks; the remaining caller is a separate tools route, so REST and SSE MCP clients lose transcript-only matches and the accompanying evidence snippets. Merge chunk hits with summary hits as before.

Useful? React with 👍 / 👎.

Comment on lines +35 to +37
String? selectedLanguageName = selectedLanguage != null
? homeProvider.availableLanguages.entries.firstWhere((element) => element.value == selectedLanguage).key
: null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Handle stored languages absent from the bundled catalog

When an existing user has a primary-language value that is absent from this restored static map—for example a legacy value accepted before server-side normalization—opening the language dialog executes firstWhere before rendering and throws StateError. The removed lookup returned the bundled name or the raw code for exactly this persisted-data case; use a nullable lookup or fallback so users can still open the picker and replace the value.

Useful? React with 👍 / 👎.

Comment on lines +334 to +335
private func notchFixedIdleSurfaceSize() -> NSSize {
notchHoverMenuSurfaceSize(agentCount: Self.notchAgentListMaxVisibleAgents)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Make transparent notch margins click through

On notch-mode Macs while the hover menu is closed, this keeps the NSPanel sized for the maximum five-agent menu even though only the small notch chrome is visible. The remaining view-level hit test cannot make an AppKit window frame pass clicks to the window underneath, so the large transparent area becomes an invisible click sink over other apps and Omi's centered top navigation. Synchronize ignoresMouseEvents with the visible hit region or shrink the panel at the closed boundary.

Useful? React with 👍 / 👎.

Comment on lines +489 to +491
let sortedOverdue = snapshot.overdue.sorted(by: Self.sortByDueDateThenSource)
let sortedToday = snapshot.today.sorted(by: Self.sortByDueDateThenSource)
let sortedNoDueDate = snapshot.noDueDate.sorted(by: Self.sortByDueDateThenSource)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep unaccepted AI captures out of active task lanes

When screenshot, conversation, or transcription extraction creates an unaccepted task, these unfiltered assignments now place it directly into Today, overdue, or no-deadline dashboard lists. Those same lists feed proactive-nudge grounding, so automatic captures—including ones the user previously deleted and that were recaptured—can immediately appear and trigger attention before the user accepts them; retain the pending-suggestion filter and separate acceptance flow.

Useful? React with 👍 / 👎.

// Always `false`, in both presentations, and asserted rather than omitted — see this file's
// header. A shell that ordered itself out whenever another app took focus deleted the window
// mid-answer and re-landed it on the way back; neither failure has any runtime signal.
window.hidesOnDeactivate = false

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Restore click-away dismissal for the summoned shell

For signed-in, onboarded users, the shell is dressed as .summoned, but this unconditional assignment leaves the floating window visible when the user clicks the desktop or switches to another app. That breaks the summoned-panel interaction and leaves an always-on-top Omi window obscuring the user's work until they explicitly close it; keep false for onboarding's anchored presentation but set hidesOnDeactivate for the summoned presentation.

Useful? React with 👍 / 👎.

@Git-on-my-level Git-on-my-level added security-review Touches auth, provider routing, secrets, or security-sensitive surfaces workflow-review Needs maintainer review for workflow, automation, hooks, or CI behavior needs-maintainer-review Needs a human maintainer to sign off before merge and removed backend Backend Task (python) labels Aug 11, 2026

@Git-on-my-level Git-on-my-level left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the update. I re-reviewed the new head (e24cdb42a891978b99263b983d7094be7790a8a6). I have to keep this as changes requested because this branch has expanded from the original local export helper into broad client/backend/release/agent-instruction changes, and I found security/privacy and release-process blockers.

File-specific notes:

  • app/lib/backend/http/openai.dart: this introduces direct client calls to https://api.openai.com/v1/... with Authorization: Bearer ${Env.openAIAPIKey}. Shipping an OpenAI key in the Flutter app, even via an obfuscated env field, is not a safe production secret boundary; users can extract it from the app bundle. It also sends conversation transcripts and photo data directly from the client to OpenAI, bypassing the backend's auth, rate-limit, BYOK/provider-routing, logging, and privacy controls.
  • app/lib/env/env.dart / app/.env.template: adding OPENAI_API_KEY as an app env value makes that server/provider credential part of the public client configuration surface. This should stay behind the backend/gateway rather than in shipped mobile configuration.
  • backend/routers/knowledge_graph.py, backend/routers/memories.py, backend/routers/integrations.py, and backend/routers/conversations.py: the PR removes the managed return-only extraction/synthesis/topic endpoints (/v1/knowledge-graph/extract, /v1/memories/extract, /v1/connectors/synthesize, /v1/conversations/topic) plus their route-policy manifest entries and tests. That removes the server-side authentication, rate limiting, subscription gating, model routing, and strict parse/fail-closed boundary these callers depended on.
  • desktop/macos/Desktop/Sources/AppleNotesReaderService.swift, CalendarReaderService.swift, and GmailReaderService.swift: connector synthesis moves back into local AgentClient.run prompts with ad-hoc JSON scraping. That is a product/privacy architecture decision and regresses the backend-owned managed synthesis path that was designed to keep prompts/models/gates centralized. The Calendar path also logs the raw synthesis response prefix, which can include user-derived calendar/profile content.
  • .github/workflows/desktop_auto_release.yml and .github/actions/release-eligibility/action.yml: the release train is changed to manual-only and the tree-fragment changelog acceptance is removed. That is a high-blast-radius release policy change, not part of the persona-export feature, and it needs explicit maintainer sign-off with release validation.
  • desktop/macos/AGENTS.md: this agent-instruction file is changed to tell coding/review agents that macOS beta candidates are cut on push plus a 15-minute schedule backstop, while the workflow in this same PR removes the schedule and leaves only manual dispatch. That mismatch can mislead future AI coding/review agents about the release process, so the agent guidance should either be reverted or aligned with the actual workflow after a maintainer-approved release-policy decision.

I also ran a local static verification that confirmed the new Flutter code contains the direct OpenAI endpoint, Env.openAIAPIKey authorization header, photo base64 payload path, and transcript prompt interpolation. I ran scripts/test-public-secret-scanners.py as a sanity check; it passed, but it does not cover this new app-side OpenAI-key/API path, so it should not be treated as validation for shipping this.

Please narrow this back to the persona export work, or split out the release-policy, managed-LLM-boundary, and client-secret architecture changes for explicit human maintainer review. The direct client OpenAI credential/API path should be removed before merge.

Automated maintainer review by glm-5.2.


by AI on behalf of David — security-sensitive client credential handling, managed LLM routing, and macOS release policy need maintainer sign-off before this can proceed.

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

Labels

AI needs-maintainer-review Needs a human maintainer to sign off before merge security-review Touches auth, provider routing, secrets, or security-sensitive surfaces workflow-review Needs maintainer review for workflow, automation, hooks, or CI behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants