Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
React Doctor found no new issues. 🎉 Reviewed by React Doctor for commit |
|
| // The authenticated API request authorizes native writes; there is no | ||
| // interactive approval response endpoint on this transport. External | ||
| // MCP tools retain their separate approval policy. | ||
| requireNativeToolApproval: false, |
There was a problem hiding this comment.
Disabling native approval for every authenticated API chat lets a credential with only chats.write request skill or post creation even though it lacks skills.write or posts.write. The native tools authorize these database mutations using only the trusted organization ID, so a chat-scoped credential can perform durable writes outside its resource permissions. Preserve the resource-scope checks before bypassing approval, or limit this behavior to credentials with the corresponding write scope.
How this was verified: POST chat requests accept the chat write scope, while the newly unblocked skill and post tools perform organization-scoped writes without checking the credential's skill or post permissions.
Knowledge Base Used:
| const approvalTools = getStandaloneApprovalToolNames(requireApproval); | ||
| const result = await generateText({ | ||
| model: new MockLanguageModelV4({ | ||
| doGenerate: { | ||
| content: [ | ||
| { | ||
| type: "tool-call", | ||
| toolCallId: "save-skill", | ||
| toolName: "createSkill", | ||
| input: JSON.stringify({ name: "marketplace-review-voice" }), | ||
| }, | ||
| ], | ||
| finishReason: { unified: "tool-calls", raw: "tool-calls" }, | ||
| usage: { | ||
| inputTokens: { total: 1, noCache: 1, cacheRead: 0, cacheWrite: 0 }, | ||
| outputTokens: { total: 1, text: 1, reasoning: 0 }, | ||
| }, | ||
| warnings: [], | ||
| }, | ||
| }), | ||
| prompt: "Save marketplace-review-voice", | ||
| tools: { | ||
| createSkill: tool({ | ||
| inputSchema: z.object({ name: z.string() }), | ||
| execute: async ({ name }) => { | ||
| saved = true; | ||
| return { name, status: "created" }; | ||
| }, | ||
| }), | ||
| }, | ||
| toolApproval: ({ toolCall }) => | ||
| approvalTools.has(toolCall.toolName) ? "user-approval" : undefined, |
There was a problem hiding this comment.
Test bypasses production wiring
This test calls getStandaloneApprovalToolNames directly and recreates the approval callback instead of exercising either changed integration point. It would still pass if the API transport stopped forwarding false or orchestration ignored the option, leaving the intended API-versus-interactive behavior without regression coverage. Exercise createDirectStandaloneChatResponse or orchestrateStandaloneChat through the real approval wiring.
Knowledge Base Used: AI orchestration and model services
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
API chats could stop at
createSkillor post creation waiting for interactive approval, but the API has no approval-response endpoint. Follow-up messages never executed the save.Derive native write permissions from the authenticated OAuth scopes or API-key permissions. Expose and execute skill creation only with
skills.write, and post creation/updates only withposts.write; preserve legacyapi.writeand wildcard grants. Missing permissions default to no native writes. Interactive chat approvals and external MCP approval rules remain unchanged. Clarify that the agent must callcreateSkilldirectly and only claim a save after it returnscreated.Validation: all 91 API tests pass, including 17 integration regressions exercising the real transport, orchestration, and skill tool for OAuth/API-key scope combinations and interactive approval. The 3 code-mode tests, API and AI type checks, targeted lint, and diff checks also pass.
Companion MCP fix: usenotra/notra-mcp#42 surfaces unresolved approvals, failed/denied tool outputs, and stream failures instead of reporting progress text as a successful reply.