feat(kap-server): add POST /api/v1/feedback endpoint - #2355
Open
7Sageer wants to merge 6 commits into
Open
Conversation
|
commit: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related Issue
No linked issue; the problem is explained below.
Problem
kap-server has no way for hosts embedding it (the web UI) to submit user feedback. The CLI already ships a complete
/feedbackflow that posts to the managed collection backend with the managed provider's OAuth token; kap-server hosts need the same capability behind the local/api/v1surface.What changed
Mirrors the CLI's existing feedback implementation (
apps/kimi-code/src/feedback/on top of@moonshot-ai/kimi-code-oauth) as three kap-server routes:POST /api/v1/feedback— validates{ content, session_id, type?, title?, contact?, diagnostics?, agent_id?, info? }(zod) and forwards the submission to the managed backend with the managed provider's OAuth access token. The host version, server OS, and default model are stamped server-side (same fields the CLI sends); the form-only fields (type/title/diagnostics/agent_id) fold into the backend's structuredinfobag. Returns{ feedback_id }for the attachment flow. Onlycontentandsession_idare required — clients without a category picker are not forced into junk defaults.POST /api/v1/feedback/upload_url— proxies the backend's presigned-upload-url creation; the client then PUTs the archive parts to the presigned URLs directly (multipart, resumable).POST /api/v1/feedback/upload_complete— proxies the upload-completion marker.Error mapping: not signed in to the managed provider →
40111; backend failure →50001; validation →40001. The routes are mounted under/api/v1(so the global bearer-auth hook covers them) and appear in the OpenAPI document under a newfeedbacktag.Tests cover the forwarded request shape (URL, bearer header, body stamping,
infofolding), the not-signed-in gate (backend never called), backend-failure mapping, both upload proxies, and validation failures. The API-surface snapshot gains exactly the three new routes.The web UI feedback form that will consume these endpoints is follow-up work.
Client flow
All three endpoints are protected by kap-server's normal local bearer authentication. The managed provider's OAuth access token stays inside kap-server and is never returned to the client.
Every control-plane response uses the standard kap-server envelope:
{ "code": 0, "msg": "success", "data": {}, "request_id": "request-id" }The business result is carried by
code; callers must not use the HTTP status alone to determine success.1. Submit the text feedback
{ "content": "The session list flashes on open", "session_id": "session-id", "type": "bug", "diagnostics": "logs" }contentandsession_idare required.typeis one ofbug,feature, orother;diagnosticsis one ofnone,logs, orlogs_and_codebase. The optionalinfoobject may carry additional metadata, but must not redefine the reservedtype,title,diagnostics, oragent_idkeys.Successful response data:
{ "feedback_id": 7 }diagnosticsonly records the attachment selection in feedback metadata. kap-server does not collect, archive, or upload logs or source code automatically. The client is responsible for preparing each requested archive.2. Create an attachment upload
Compute the archive size and SHA-256 digest, then request the multipart upload:
{ "feedback_id": 7, "file_name": "session.zip", "file_size": 1048576, "file_hash": "<SHA-256 hex>" }Successful response data:
{ "upload_id": 3, "parts": [ { "part_number": 1, "url": "https://storage.example.test/presigned-part-1", "method": "PUT", "size": 1048576 } ] }Sort
partsbypart_number. Starting at byte offset zero, each part consumes the nextsizebytes of the archive; the next part starts immediately after the previous one. Upload those bytes directly to the returnedurl, using the returned HTTPmethodand aContent-Lengthmatching the part size. Record theETagresponse header for every successful part.The archive bytes and presigned upload requests do not pass through kap-server.
3. Complete the attachment upload
After every part succeeds, report the collected ETags:
{ "upload_id": 3, "parts": [ { "part_number": 1, "etag": "\"etag-value\"" } ] }Successful response data is
null.Text feedback is created before attachments are uploaded. An attachment preparation, part upload, or completion failure does not roll back the feedback record; clients should present that outcome as feedback submitted with an attachment failure, and may retry the attachment flow separately.
Checklist
gen-changesetsskill, or this PR needs no changeset — none: per the skill's rules, new kap-server REST endpoints without a shipped consumer are not user-perceivable (the global-search endpoint PR followed the same practice).gen-docsskill, or this PR needs no doc update — no user-facing surface yet.