Skip to content

fix(desktop): align API response keys with Python backend#6381

Closed
beastoin wants to merge 1 commit into
mainfrom
fix/desktop-api-response-mismatch-6174
Closed

fix(desktop): align API response keys with Python backend#6381
beastoin wants to merge 1 commit into
mainfrom
fix/desktop-api-response-mismatch-6174

Conversation

@beastoin
Copy link
Copy Markdown
Collaborator

@beastoin beastoin commented Apr 7, 2026

Summary

  • ActionItemsListResponse: backend returns action_items key but Swift decoded items → all task loading failed with "key 'items' not found"
  • Goals API: /v1/goals/all and /v1/goals/completed return plain JSON arrays, not {"goals": [...]} wrapper → "Expected Dictionary but found array" error
  • Apps v2: reduce default limit from 100 to 50 to match backend validation max (was returning 422)

These are response format mismatches introduced by the desktop → Python backend migration (#6174).

Test plan

  • Tasks load in the Tasks page (no more "key 'items' not found" errors)
  • Goals widget loads on Dashboard (no more "Expected Dictionary" errors)
  • Apps page loads without 422 error

🤖 Generated with Claude Code

Three response format mismatches after desktop→Python backend migration:
- ActionItemsListResponse: map `items` to `action_items` key from backend
- Goals endpoints: backend returns plain array, not `{goals:[...]}` wrapper
- Apps v2: reduce default limit from 100 to 50 (backend maximum)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 7, 2026

Greptile Summary

This PR aligns three Swift decoding mismatches with the Python backend: maps the action_items JSON key correctly in ActionItemsListResponse, decodes /v1/goals/all as a plain [Goal] array (not the old GoalsListResponse wrapper), and drops the getAppsV2 default limit from 100 to 50 to stay within the backend's le=50 validation.

  • P1 – getCompletedGoals() will still 404: GET /v1/goals/completed does not exist in backend/routers/goals.py; only /v1/goals/all is present. The Goals History page and GoalsAIService will continue to fail until this endpoint is added to the Python router.
  • P2 – GoalsListResponse is dead code: the struct at line 2665 is no longer referenced after the goals decoding change and should be removed.

Confidence Score: 4/5

Safe to merge for the three described fixes, but the Goals History page remains broken due to a missing Python backend endpoint.

The action items key mapping and apps v2 limit reduction are correct and unambiguous fixes. The getGoals() plain-array decode is also correct. However, getCompletedGoals() calls GET /v1/goals/completed which does not exist in the Python backend (confirmed by reading backend/routers/goals.py) — the Goals History page will continue to surface a 404 error, a current defect the PR description claims to fix but does not.

desktop/Desktop/Sources/APIClient.swift (getCompletedGoals at line 2048) and backend/routers/goals.py (missing /v1/goals/completed endpoint)

Important Files Changed

Filename Overview
desktop/Desktop/Sources/APIClient.swift Three API response-format fixes (ActionItemsListResponse key mapping, Goals plain-array decoding, Apps v2 limit) — but getCompletedGoals() calls a Python backend endpoint that does not exist, leaving Goals History page broken.

Sequence Diagram

sequenceDiagram
    participant Swift as Swift APIClient
    participant Py as Python Backend (api.omi.me)

    Note over Swift,Py: Action Items (FIXED)
    Swift->>Py: GET /v1/action-items
    Py-->>Swift: {"action_items": [...], "has_more": false}
    Note right of Swift: Decoded via CodingKeys: items="action_items" ✓

    Note over Swift,Py: Goals - getGoals() (FIXED)
    Swift->>Py: GET /v1/goals/all
    Py-->>Swift: [...] plain array
    Note right of Swift: Decoded as [Goal] ✓

    Note over Swift,Py: Goals - getCompletedGoals() (STILL BROKEN)
    Swift->>Py: GET /v1/goals/completed
    Py-->>Swift: 404 Not Found
    Note right of Swift: Endpoint does not exist in Python backend ✗

    Note over Swift,Py: Apps V2 (FIXED)
    Swift->>Py: GET /v2/apps?limit=50
    Py-->>Swift: 200 OK (was 422 with limit=100)
Loading

Comments Outside Diff (1)

  1. desktop/Desktop/Sources/APIClient.swift, line 2664-2667 (link)

    P2 GoalsListResponse is now dead code

    After this PR both goals functions decode directly as [Goal], so GoalsListResponse is no longer referenced anywhere in the Swift codebase. The struct can be removed.

Reviews (1): Last reviewed commit: "fix(desktop): align API response keys wi..." | Re-trigger Greptile

Comment on lines 2048 to +2050
func getCompletedGoals() async throws -> [Goal] {
let response: GoalsListResponse = try await get("v1/goals/completed")
return response.goals
let goals: [Goal] = try await get("v1/goals/completed")
return goals
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Missing /v1/goals/completed endpoint on Python backend

The Python backend (backend/routers/goals.py) has no GET /v1/goals/completed route — only /v1/goals/all exists as a list endpoint. Calling this will always return a 404, which surfaces as a visible error on the Goals History page (GoalsHistoryPage.swift:95) and produces empty goal history in GoalsAIService.swift:183. The decoding fix (plain [Goal] array) is correct for when the endpoint eventually exists, but it won't take effect until a /v1/goals/completed route is added to the Python backend router.

@beastoin
Copy link
Copy Markdown
Collaborator Author

beastoin commented Apr 7, 2026

Merged into #6380 per manager request to combine both PRs.

@beastoin beastoin closed this Apr 7, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 7, 2026

Hey @beastoin 👋

Thank you so much for taking the time to contribute to Omi! We truly appreciate you putting in the effort to submit this pull request.

After careful review, we've decided not to merge this particular PR. Please don't take this personally — we genuinely try to merge as many contributions as possible, but sometimes we have to make tough calls based on:

  • Project standards — Ensuring consistency across the codebase
  • User needs — Making sure changes align with what our users need
  • Code best practices — Maintaining code quality and maintainability
  • Project direction — Keeping aligned with our roadmap and vision

Your contribution is still valuable to us, and we'd love to see you contribute again in the future! If you'd like feedback on how to improve this PR or want to discuss alternative approaches, please don't hesitate to reach out.

Thank you for being part of the Omi community! 💜

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.

1 participant