mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-10-12 20:49:53 +08:00
2f92936f03c81a009c959fe83a045255b4583e8b
3
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
458d8050cc |
refactor(providers): one record per provider, one place for the key-and-URL decision (#988)
Every fact about a provider lives in one record in lib/providers.ts (SDK kind, credential kind, env var prefix, default URL, picker group, four-language notes, and a short model list for the six providers that cannot list models). The thirteen tables keyed by provider name are gone. resolveEndpoint decides whose key a call uses and where it goes; usesServerCredentials reads its answer instead of mirroring getAIModel's branches; serverCredentialError holds the server credential check once. The UI, the connection test and the routes read the record's credential and sdk fields instead of comparing provider names (44 such checks before, 6 after, in the admin panel's fixed-variable branches). Intended behavior changes: providers that can list their models have no hand-written list; the settings dialog fetches the live list in the background once credentials are entered for a provider without models and offers it behind "Browse models". Azure has no placeholder default URL (old entries that hold it still count as unset); the base URL field of Azure and of the new "custom" OpenAI-compatible preset (CUSTOM_API_KEY, CUSTOM_BASE_URL) is labelled required. The connection test answers 400 for an unknown provider name; prototype names are refused everywhere. Provider lists in error messages and the admin "add provider" dropdown follow the picker's order. Also fixed, from before the refactor: the redirect guard drops x-access-code on cross-origin redirects, and edgeOneEndpoint accepts the Origin header only when it matches Host or X-Forwarded-Host. Verification: a behavior snapshot of getAIModel's SDK factory calls and the quota functions over 25 providers, 22 client override shapes and 9 server environments (5843 rows), recorded on the old code and unchanged apart from the intended changes; 752 unit tests, 65 provider e2e tests, tsc, biome, next build. Reviewed by five models from one brief; their findings and the resulting fixes are recorded in docs/plans/2026-10-provider-refactor.md. |
||
|
|
99ced88e5b |
fix(chat): use the AI SDK's own mechanisms for quota, retries, stops and notices (#987)
## Problem
A review of how the app uses the Vercel AI SDK (two Claude reviewers and Codex, each finding checked against the SDK's type definitions and source) found five behaviours that are wrong and a set of places where the app re-implements what the SDK already provides:
1. Quota tokens were recorded in `onFinish`, which the SDK does not call when a later step fails; only a user stop was handled (`onAbort`), and the write was not awaited.
2. An automatic retry after a tool error re-sent the request body as it was when the message was sent, so the model was told the "authoritative" canvas XML was the diagram from before the turn, although `display_diagram` commits a drawing before its screenshot check can fail.
3. The screenshot check and the connection test ran their model call on `AbortSignal.timeout` only, so pressing Stop (or closing the dialog) did not stop a paid model call.
4. The client ignored `finishReason`; a reasoning model that spent the whole output budget before calling a tool left the user with no diagram and no message.
5. The connection test counted an `invalid` tool call (a tool that does not exist, unreadable input) as proof of tool support.
## Change
- `onStepFinish` records each step's `usage.totalTokens` and awaits the write; the copies in `onFinish` and `onAbort` are gone.
- `DefaultChatTransport.prepareSendMessagesRequest` sends the current canvas page XML on every request after the first of a turn; the first keeps the exported (or snapshot) XML.
- `validate-diagram` and the connection test pass `req.signal` and use the SDK's `timeout` option; `validate-diagram` reports to Langfuse under `functionId: "validate-diagram"`.
- The connection test only counts a valid tool call.
- The client's `onFinish` shows a notice (with Retry) when `finishReason === "length"` and no tool was called.
- The server validates incoming messages with `safeValidateUIMessages` (400 otherwise), drops client system messages explicitly and prunes empty model messages with `pruneMessages`.
- The chat's tools live in `lib/chat-tools.ts` with an `outputSchema` for the client-side ones; `lib/chat-message.ts` defines `ChatUIMessage` (metadata, a `data-notice` part, `InferUITools`) so `useChat`, `addToolOutput` and the tool handlers are typed.
- Error notices are assistant messages with a `data-notice` part instead of role `system` UI messages.
- Regenerate, edit and retry use `sendMessage({ messageId })`; `isResending` and `flushSync` are gone.
- `isToolUIPart` / `getToolName` replace slicing `"tool-"` off part types; `ToolPartLike` derives from the SDK's part types.
Net: 578 insertions, 439 deletions over 16 files.
## Testing
- New unit tests: a step that fails after a finished step still counts that step's tokens; the screenshot check's model call ends when the request is aborted; an invalid tool call in the connection test gives the warning; malformed messages get a 400. The first and third confirm SDK behaviour the review relied on.
- `tsc`, `biome ci` (0 errors), root `vitest run` 723 passed on the branch rebased onto #986, `next build`: clean
- Playwright, 10 chat-related specs on the dev server: 199 passed, 0 failed, both before and after the rebase onto #986
|
||
|
|
60105ddb51 |
refactor: remove dead code and over-engineering found by two audits (#986)
## Problem
Two audits of the repository (a workflow of finder, dedup and per-file verifier agents, run on 2026-10-11 against 1f4141e and again against
|