Compare commits

...
Author SHA1 Message Date
Aiden Cline a2594ddefb fix(tui): sync model preferences across clients (#49611) 2026-09-17 14:54:34 -05:00
Aiden Cline 3555cef1c8 chore(client): regenerate policy types (#49613) 2026-09-17 14:38:09 -05:00
opencode 0fa881efd0 sync release versions for v2.0.7 2026-09-17 19:29:59 +00:00
opencode-agent[bot]andrekram1-node 37ff501cc6 fix(cli): keep updates client-owned (#49577)
Co-authored-by: rekram1-node <rekram1-node@users.noreply.github.com>
2026-09-17 12:47:49 -04:00
Dax fa126d68e8 feat(core): enforce permission policies 2026-09-17 12:39:20 -04:00
opencode-agent[bot]andJames Long a0571a8b14 fix(tui): keep upgrade as a search keyword (#49567)
Co-authored-by: James Long <17031+jlongster@users.noreply.github.com>
2026-09-17 11:32:16 -04:00
Dax Raad cae475df37 sync 2026-09-17 10:47:52 -04:00
Shoubhit Dash 19781a4447 fix(acp): propagate request cancellation and close sessions cleanly (#49563) 2026-09-17 20:16:07 +05:30
Brendan Allan e32de90d88 fix(app): prevent settings project cache reload loop (#49564) 2026-09-17 14:45:03 +00:00
Kit Langton 0ee5ef6c43 fix(tui): keep spinner glyph from shrinking beside long labels (#49395) 2026-09-17 07:43:07 -07:00
a72f988c90 fix(tui): switch vertical tabs sooner (#49440)
Co-authored-by: rekram1-node <rekram1-node@users.noreply.github.com>
Co-authored-by: Aiden Cline <aidenpcline@gmail.com>
2026-09-17 09:43:02 -05:00
Dax Raad 2a132d6f50 fix(tui): include provider latency in TPS 2026-09-17 10:40:12 -04:00
Dax Raad 23418b3885 docs: reorder sidebar navigation 2026-09-17 10:20:57 -04:00
Dax Raad b4ac938c3d docs: improve installation guide 2026-09-17 10:10:20 -04:00
Dax Raad 4b25739e93 docs(cli): drop command-name leads in command descriptions 2026-09-17 09:44:31 -04:00
Dax Raad 2f97e1324f fix(www): restore OpenTUI Mono docs font 2026-09-17 09:31:40 -04:00
Dax Raad 0018f08832 feat(cli): add reload command 2026-09-17 09:21:41 -04:00
Dax Raad b52f241294 feat(location): reload configuration 2026-09-17 09:18:51 -04:00
Dax Raad 254ace8594 docs: add CLI settings reference 2026-09-17 09:17:14 -04:00
usrnk1 657f700f5d feat(desktop): disable security code autofill (#49531) 2026-09-17 20:35:14 +08:00
Victor Navarro 7e1d28b549 feat(cli): support custom Console logins (#49542) 2026-09-17 13:50:32 +02:00
opencode 040d2ffb48 sync release versions for v2.0.6 2026-09-17 11:17:33 +00:00
usrnk1 0675975f98 feat(desktop): remove pointer cursor from non-link elements (#49323) 2026-09-17 20:41:24 +10:00
opencode-agent[bot]andiamdavidhill 130232feb6 chore(desktop): update bundled themes (#48713)
Co-authored-by: iamdavidhill <iamdavidhill@users.noreply.github.com>
2026-09-17 20:40:07 +10:00
opencode-agent[bot]andiamdavidhill 54f2356166 fix(app): remove Anthropic Pro and Max copy (#49369)
Co-authored-by: iamdavidhill <1879069+iamdavidhill@users.noreply.github.com>
2026-09-17 20:39:39 +10:00
David Hill ac0dd75c6a fix(app): hide browser when the right panel closes (#49425) 2026-09-17 20:39:02 +10:00
David Hill 430886142b fix(app): center start screen beside summary panels (#49429) 2026-09-17 20:38:36 +10:00
David Hill 5a02ec776e fix(app): use muted worktree icon in session timeline (#49459) 2026-09-17 20:37:37 +10:00
David Hill c303a11725 fix(app): mute session tab hover and active backgrounds (#49465) 2026-09-17 20:37:13 +10:00
David Hill dfceca8de7 fix(app): refine start-screen logo (#49475) 2026-09-17 20:36:45 +10:00
Luke Parker f04c3fd82b feat(app): attach any file and deliver unsupported ones by path (#49467) 2026-09-17 20:35:00 +10:00
Luke Parker 1685e70c4b feat(server): add fs.write endpoint (#49466) 2026-09-17 20:17:14 +10:00
Chris Yang 73e7b7bc79 fix(app): derive directory names from listed paths (#49122) 2026-09-17 18:46:07 +10:00
David Hill a5b3802ca3 fix(app): keep compact tab icons visible (#49460) 2026-09-17 14:48:47 +08:00
Dax Raad f28d1b44e3 fix(core): serialize MCP endpoint startup 2026-09-17 00:52:34 -04:00
Dax Raad b81be469c8 fix(client): preserve state during location reload 2026-09-17 00:52:34 -04:00
opencode-agent[bot]andkitlangton fca4a8fa3b feat(tui): show explicit subagent model (#49388)
Co-authored-by: kitlangton <7587245+kitlangton@users.noreply.github.com>
2026-09-16 22:50:28 -05:00
Aiden Cline 8520617ca8 fix(core): retry provider failures for about 84s with 10s gap cap (#49441) 2026-09-16 20:59:16 -05:00
Dax Raad ab3566ab82 feat(server): expose server info endpoint 2026-09-16 21:43:58 -04:00
Dax Raad b642c1d9ea docs: add CLI settings reference 2026-09-16 21:18:35 -04:00
David HillandLukeParkerDev c8cc984aa0 feat(app): improve project settings and actions (#49423)
Co-authored-by: LukeParkerDev <10430890+Hona@users.noreply.github.com>
2026-09-17 00:39:21 +00:00
Luke Parker 5a9448acbb fix(app): retry transport errors wrapped by the client (#49426) 2026-09-17 10:34:52 +10:00
David Hill f6604cd367 feat(desktop): add animated first-launch loading screen (#49408) 2026-09-17 10:02:09 +10:00
Luke Parker acfacede2d fix(app): preserve native clipboard paste (#49424) 2026-09-17 09:47:00 +10:00
Aiden Cline 4a27842fe6 fix(ai): classify gateway account limits as quota and keep 4xx non-retryable (#49195) 2026-09-16 16:14:09 -05:00
Aiden Cline d797722187 feat(codemode): carry cause and own data across the error boundary (#49390) 2026-09-16 15:58:05 -05:00
Dax 7390832f13 feat(tui): reload all locations
Add a global location reload endpoint, shared shutdown lifecycle, client resynchronization, and the TUI /reload command.\n\nfrom OpenCode
2026-09-16 16:47:44 -04:00
Kit Langton 7689c3654e fix(tui): hide error hint when MCP Enter starts sign-in (#49403) 2026-09-16 19:33:08 +00:00
Dax 7df0935ada fix(tui): apply model selection on blank submit (#49374)
Apply the selected model on blank Enter and simplify shared prompt submission setup and recovery.\n\nfrom OpenCode
2026-09-16 19:32:45 +00:00
Dax bcd43760df feat(cli): support inline config content (#49399) 2026-09-16 19:18:55 +00:00
348 changed files with 4611 additions and 1870 deletions
+2 -2
View File
@@ -54,7 +54,7 @@ Review endpoints in document order. For each endpoint, select one disposition an
### [x] `GET /api/health` and `GET /api/server`
- **Decision:** Merge and rename
- **Replacement:** `GET /api/status` with operation ID `server.status`.
- **Replacement:** `GET /api/info` with operation ID `server.info`.
- **Notes:** Returns `version`, `pid`, and connection `urls`; readiness is conveyed by HTTP status.
### [x] `GET /api/project/current`
@@ -74,7 +74,7 @@ Review endpoints in document order. For each endpoint, select one disposition an
| Done | Method | Path | Operation ID | Decision | Notes |
|---|---|---|---|---|---|
| [x] 001002 | `GET` | `/api/status` | `server.status` | Keep | Replaces the former health and server endpoints. |
| [x] 001002 | `GET` | `/api/info` | `server.info` | Keep | Replaces the former health and server endpoints. |
| [x] 003 | `GET` | `/api/location` | `location.get` | Keep | Workspace selectors and response fields removed until workspace support ships. |
| [x] 004 | `GET` | `/api/project` | `project.list` | Keep | Removed unused `time.initialized`; the database column remains for migration data. |
| [x] 005 | `PATCH` | `/api/project/{projectID}` | `project.update` | Keep | Request and response accepted as-is. |
+35 -35
View File
@@ -32,7 +32,7 @@
},
"packages/ai": {
"name": "@opencode/ai",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@aws-sdk/credential-providers": "3.1057.0",
"@opencode/schema": "workspace:*",
@@ -54,7 +54,7 @@
},
"packages/app": {
"name": "@opencode/app",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@corvu/drawer": "catalog:",
"@dnd-kit/abstract": "0.5.0",
@@ -113,7 +113,7 @@
},
"packages/cli": {
"name": "@opencode/cli",
"version": "2.0.5",
"version": "2.0.7",
"bin": {
"opencode2": "./bin/opencode2.cjs",
},
@@ -177,7 +177,7 @@
},
"packages/client": {
"name": "@opencode/client",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@opencode/protocol": "workspace:*",
"@opencode/schema": "workspace:*",
@@ -203,7 +203,7 @@
},
"packages/codemode": {
"name": "@opencode/codemode",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"acorn": "8.15.0",
"effect": "catalog:",
@@ -217,7 +217,7 @@
},
"packages/console/app": {
"name": "@opencode/console-app",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@cloudflare/vite-plugin": "1.15.2",
"@ibm/plex": "6.4.1",
@@ -253,7 +253,7 @@
},
"packages/console/core": {
"name": "@opencode/console-core",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@aws-sdk/client-sts": "3.782.0",
"@jsx-email/render": "1.1.1",
@@ -280,7 +280,7 @@
},
"packages/console/function": {
"name": "@opencode/console-function",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@openauthjs/openauth": "0.0.0-20250322224806",
"@opencode/console-core": "workspace:*",
@@ -297,7 +297,7 @@
},
"packages/console/mail": {
"name": "@opencode/console-mail",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@jsx-email/all": "2.2.3",
"@jsx-email/cli": "1.4.3",
@@ -321,7 +321,7 @@
},
"packages/console/support": {
"name": "@opencode/console-support",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@cloudflare/vite-plugin": "1.15.2",
"@opencode/console-core": "workspace:*",
@@ -341,7 +341,7 @@
},
"packages/core": {
"name": "@opencode/core",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@ai-sdk/cohere": "3.0.27",
"@ai-sdk/gateway": "3.0.104",
@@ -409,7 +409,7 @@
},
"packages/desktop": {
"name": "@opencode/desktop",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@zip.js/zip.js": "2.7.62",
"electron-context-menu": "4.1.2",
@@ -461,7 +461,7 @@
},
"packages/enterprise": {
"name": "@opencode/enterprise",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@hono/standard-validator": "catalog:",
"@opencode-ai/sdk": "1.18.21",
@@ -498,7 +498,7 @@
},
"packages/function": {
"name": "@opencode/function",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@octokit/auth-app": "8.0.1",
"@octokit/rest": "catalog:",
@@ -514,7 +514,7 @@
},
"packages/http-recorder": {
"name": "@opencode/http-recorder",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@effect/platform-node-shared": "4.0.0-rc.112",
},
@@ -533,7 +533,7 @@
},
"packages/httpapi-codegen": {
"name": "@opencode/httpapi-codegen",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"effect": "catalog:",
"prettier": "3.6.2",
@@ -546,7 +546,7 @@
},
"packages/latex": {
"name": "@opencode/latex",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@opencode/plugin": "workspace:*",
"@opentui/core": "catalog:",
@@ -560,7 +560,7 @@
},
"packages/merman": {
"name": "@opencode/merman",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@opencode/plugin": "workspace:*",
"@opentui/core": "catalog:",
@@ -575,7 +575,7 @@
},
"packages/plugin": {
"name": "@opencode/plugin",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@ai-sdk/provider": "3.0.8",
"@opencode/ai": "workspace:*",
@@ -614,7 +614,7 @@
},
"packages/plugin-browser": {
"name": "@opencode/plugin-browser",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@opencode/plugin": "workspace:*",
"@opencode/schema": "workspace:*",
@@ -644,7 +644,7 @@
},
"packages/protocol": {
"name": "@opencode/protocol",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@opencode/schema": "workspace:*",
"effect": "catalog:",
@@ -659,7 +659,7 @@
},
"packages/schema": {
"name": "@opencode/schema",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@standard-schema/spec": "catalog:",
"effect": "catalog:",
@@ -683,7 +683,7 @@
},
"packages/sdk": {
"name": "@opencode/sdk",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@opencode/client": "workspace:*",
"@opencode/core": "workspace:*",
@@ -704,7 +704,7 @@
},
"packages/server": {
"name": "@opencode/server",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@effect/platform-node": "catalog:",
"@effect/platform-node-shared": "catalog:",
@@ -726,7 +726,7 @@
},
"packages/session-ui": {
"name": "@opencode/session-ui",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@kobalte/core": "catalog:",
"@opencode/client": "workspace:*",
@@ -761,7 +761,7 @@
},
"packages/simulation": {
"name": "@opencode/simulation",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@opencode/ai": "workspace:*",
"@opencode/core": "workspace:*",
@@ -781,7 +781,7 @@
},
"packages/stats/app": {
"name": "@opencode/stats-app",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@ibm/plex": "6.4.1",
"@kobalte/core": "catalog:",
@@ -815,7 +815,7 @@
},
"packages/stats/core": {
"name": "@opencode/stats-core",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@aws-sdk/client-athena": "3.933.0",
"@planetscale/database": "1.19.0",
@@ -834,7 +834,7 @@
},
"packages/stats/server": {
"name": "@opencode/stats-server",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@aws-sdk/client-firehose": "3.933.0",
"@effect/platform-node": "catalog:",
@@ -880,7 +880,7 @@
},
"packages/theme": {
"name": "@opencode/theme",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@opentui/core": "catalog:",
"effect": "catalog:",
@@ -894,7 +894,7 @@
},
"packages/tui": {
"name": "@opencode/tui",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@opencode/client": "workspace:*",
"@opencode/core": "workspace:*",
@@ -929,7 +929,7 @@
},
"packages/ui": {
"name": "@opencode/ui",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@kobalte/core": "catalog:",
"@pierre/diffs": "catalog:",
@@ -964,7 +964,7 @@
},
"packages/util": {
"name": "@opencode/util",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@effect/opentelemetry": "catalog:",
"@effect/platform-node": "catalog:",
@@ -997,7 +997,7 @@
},
"packages/web": {
"name": "@opencode/web",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"@astrojs/cloudflare": "12.6.3",
"@astrojs/markdown-remark": "6.3.1",
@@ -1038,7 +1038,7 @@
},
"services/update": {
"name": "@opencode/update",
"version": "2.0.5",
"version": "2.0.7",
"dependencies": {
"jose": "6.0.11",
"semver": "catalog:",
+1 -1
View File
@@ -2,7 +2,7 @@
"$schema": "https://json.schemastore.org/package.json",
"name": "opencode",
"description": "AI-powered development tool",
"version": "2.0.5",
"version": "2.0.7",
"private": true,
"type": "module",
"packageManager": "bun@1.4.2",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"$schema": "https://json.schemastore.org/package.json",
"version": "2.0.5",
"version": "2.0.7",
"name": "@opencode/ai",
"type": "module",
"license": "MIT",
+21 -6
View File
@@ -59,7 +59,15 @@ export const isContextOverflowFailure = (failure: unknown) =>
: Schema.is(ProviderErrorEvent)(failure) && failure.classification === "context-overflow"
const decodeJson = Schema.decodeUnknownOption(Schema.fromJsonString(Schema.Unknown))
const QUOTA_CODES = new Set(["insufficient_quota", "usage_not_included", "billing_error"])
// OpenCode Zen reports account caps as typed 429/402 errors that are not throttles.
const QUOTA_CODES = new Set([
"insufficient_quota",
"usage_not_included",
"billing_error",
"gousagelimiterror",
"freeusagelimiterror",
"creditlimitexceeded",
])
const AUTH_CODES = new Set(["authentication_error", "permission_error"])
const SERVER_CODES = new Set([
"api_error",
@@ -87,7 +95,8 @@ const CONTENT_POLICY_CODES = new Set([
// as a `[code]` label at the start of the rewritten message.
const GATEWAY_CODE_LABEL = /^[^:\n]+: \[([A-Za-z0-9_.-]+)\]/
const RATE_LIMIT_TEXT = /rate increased too quickly|rate[-_\s]?limit|too[_\s]?many[_\s]?requests/i
const QUOTA_TEXT = /insufficient[-_\s]?quota|quota[-_\s]?exceeded/i
// Only consulted on 429, where throttles and account caps share a status.
const QUOTA_TEXT = /insufficient[-_\s]?quota|quota[-_\s]?exceeded|budget exceeded|usage limit/i
// Policy rejections without a dedicated code, matched against the provider's own
// explanation only. OpenAI reuses `invalid_prompt` for usage-policy rejections while
// Bedrock Mantle reuses it for schema validation; Anthropic reports blocked output
@@ -143,7 +152,11 @@ export function classifyProviderFailure(input: ProviderFailure): AIError["reason
return new InvalidRequestError({ ...details, classification: "payload-too-large" })
if (codes.some((code) => CONTENT_POLICY_CODES.has(code)) || (clientScoped && CONTENT_POLICY_TEXT.test(input.message)))
return new ContentPolicyError(details)
if (codes.some((code) => QUOTA_CODES.has(code)) || (input.status === 429 && QUOTA_TEXT.test(text)))
if (
input.status === 402 ||
codes.some((code) => QUOTA_CODES.has(code)) ||
(input.status === 429 && QUOTA_TEXT.test(text))
)
return new QuotaExceededError(details)
if (input.status === 401 || input.status === 403 || codes.some((code) => AUTH_CODES.has(code)))
return new AuthenticationError(details)
@@ -163,10 +176,12 @@ export function classifyProviderFailure(input: ProviderFailure): AIError["reason
input.status === 408 ||
input.status === 409 ||
(input.status !== undefined && input.status >= 500) ||
// Server codes and phrasing only decide when no HTTP status contradicts them:
// gateways such as OpenCode Zen substitute `server_error` for codes they do
// not forward, so a 4xx with a server code is still a rejected request.
((input.status === undefined || input.status < 400) &&
!codes.some((code) => INVALID_REQUEST_CODES.has(code)) &&
SERVER_ERROR_TEXT.test(text)) ||
codes.some((code) => SERVER_CODES.has(code) || code.includes("exhausted") || code.includes("unavailable"))
((!codes.some((code) => INVALID_REQUEST_CODES.has(code)) && SERVER_ERROR_TEXT.test(text)) ||
codes.some((code) => SERVER_CODES.has(code) || code.includes("exhausted") || code.includes("unavailable"))))
)
return new ProviderInternalError({
...details,
+3 -3
View File
@@ -309,7 +309,7 @@ describe("RequestExecutor", () => {
}),
)
it.effect("classifies provider overloads hidden behind HTTP 400", () =>
it.effect("does not let server codes override a 4xx rejection", () =>
Effect.gen(function* () {
const classify = (body: string) =>
Effect.gen(function* () {
@@ -317,11 +317,11 @@ describe("RequestExecutor", () => {
const error = yield* executor.execute(request).pipe(Effect.flip)
expectAIError(error)
expect(error.reason).toMatchObject({ _tag: "ProviderInternal" })
expect(error.reason).toMatchObject({ _tag: "InvalidRequest" })
}).pipe(Effect.provide(fixedResponse(body, { status: 400 })))
yield* classify('{"code":"resource_exhausted"}')
yield* classify('{"code":"service_unavailable"}')
yield* classify('{"error":{"type":"server_error","message":"Upstream request failed: Model is unavailable."}}')
}),
)
+47 -3
View File
@@ -249,10 +249,54 @@ describe("provider error classification", () => {
test("classifies any remaining 4xx status as an invalid request", () => {
expect(
[400, 402, 404, 418, 422, 451].map(
(status) => classifyProviderFailure({ message: `HTTP ${status}`, status })._tag,
[400, 404, 418, 422, 451].map((status) => classifyProviderFailure({ message: `HTTP ${status}`, status })._tag),
).toEqual(Array(5).fill("InvalidRequest"))
})
test("classifies 402 as exhausted quota", () => {
expect(classifyProviderFailure({ message: "Payment Required", status: 402 })._tag).toBe("QuotaExceeded")
})
test("classifies OpenCode Zen account limits as quota rather than throttling", () => {
const typed = (type: string, message: string) => ({ type: "error", error: { type, message } })
const substituted = (message: string) => ({
error: { type: "server_error", message: `Upstream request failed: ${message}` },
})
const cases: ReadonlyArray<[number, { error: { message: string } }]> = [
[429, typed("GoUsageLimitError", "Go usage limit exceeded")],
[429, typed("FreeUsageLimitError", "Rate limit exceeded. Please try again later.")],
[402, typed("CreditLimitExceeded", "Credit limit exceeded.")],
[402, substituted("Insufficient account funds")],
[402, substituted("Account invoice is overdue")],
[429, substituted("Account budget exceeded")],
]
expect(
cases.map(
([status, body]) =>
classifyProviderFailure({ message: body.error.message, status, rawBody: JSON.stringify(body) })._tag,
),
).toEqual(Array(6).fill("InvalidRequest"))
).toEqual(Array(6).fill("QuotaExceeded"))
})
test("does not let substituted server codes make a 4xx retryable", () => {
const openai = { error: { type: "server_error", message: "Upstream request failed: Model is unavailable." } }
const anthropic = {
type: "error",
error: { type: "api_error", message: "Upstream request failed: Model is unavailable." },
}
expect(
[openai, anthropic].map(
(body) =>
classifyProviderFailure({ message: body.error.message, status: 400, rawBody: JSON.stringify(body) })._tag,
),
).toEqual(["InvalidRequest", "InvalidRequest"])
// Without a contradicting status the same codes still mark provider trouble.
expect(classifyProviderFailure({ message: openai.error.message, rawBody: JSON.stringify(openai) })._tag).toBe(
"ProviderInternal",
)
expect(
classifyProviderFailure({ message: openai.error.message, status: 200, rawBody: JSON.stringify(openai) })._tag,
).toBe("ProviderInternal")
})
test("classifies nested provider codes when a top-level code is also present", () => {
@@ -42,3 +42,18 @@ story("hides and restores the same registration for Review tabs and unmount", as
await root.getByRole("button", { name: "Unmount pane", exact: true }).click()
await expect(root.getByTestId("native-Alpha")).toHaveAttribute("data-visible", "false")
})
story("hides the native view immediately while the pane stays mounted", async ({ page }) => {
const root = page.getByTestId("browser-pane-fixture")
const toggle = root.getByRole("button", { name: "Toggle Review tab", exact: true })
await expect(toggle).toBeEnabled()
// Read in the same task as the click so a deferred animation-frame hide cannot pass.
const visible = await toggle.evaluate((element) => {
element.dispatchEvent(new MouseEvent("click", { bubbles: true }))
return document.querySelector('[data-testid="native-Alpha"]')?.getAttribute("data-visible")
})
expect(visible).toBe("false")
await expect(root.locator("#browser-panel")).toHaveCount(1)
await toggle.click()
await expect(root.getByTestId("native-Alpha")).toHaveAttribute("data-visible", "true")
})
@@ -9,12 +9,17 @@ for (const theme of ["light", "dark"]) {
const reveal = logo.locator('[data-slot="wordmark-reveal"]')
const shimmer = logo.locator(".wordmark-shimmer")
const base = logo.locator("svg").first()
await expect(base).toHaveCSS("opacity", theme === "dark" ? "0.5" : "0.6")
await expect(base).toHaveCSS("opacity", "0.16")
await expect(shimmer).toHaveCSS("animation-iteration-count", "1")
await expect(logo.locator("g[mask]")).toHaveCount(0)
await expect(shimmer).toHaveCSS("color", "rgb(255, 255, 255)")
await expect(shimmer).toHaveCSS("mix-blend-mode", "screen")
await expect(base.locator("g[fill]")).toHaveAttribute("fill", "currentColor")
await expect(base.locator("path").nth(1)).toHaveAttribute("fill", "var(--icon-base)")
await expect(base.locator("path").nth(9)).toHaveCSS(
"fill",
await base.locator("path").nth(1).evaluate((element) => getComputedStyle(element).fill),
)
await expect(base.locator('path[fill="var(--icon-weak-base)"]')).toHaveCount(8)
await logo.evaluate((element) => {
element.getAnimations({ subtree: true }).forEach((animation) => {
@@ -77,7 +82,7 @@ for (const theme of ["light", "dark"]) {
await page.setViewportSize({ width: 360, height: 640 })
const component = await mount("app-new-session-wordmark--reveal", { globals: { theme } })
const logo = component.locator('[data-component="new-session-wordmark"]')
await expect(logo.locator("svg").first()).toHaveCSS("opacity", theme === "dark" ? "0.5" : "0.6")
await expect(logo.locator("svg").first()).toHaveCSS("opacity", "0.16")
await expect(logo.locator('[data-slot="wordmark-reveal"]')).toHaveCSS("opacity", "1")
await expect(logo.locator(".wordmark-shimmer")).toHaveCSS("opacity", "0")
expect(await logo.evaluate((element) => element.getAnimations({ subtree: true }).length)).toBe(0)
@@ -62,7 +62,8 @@ async function mockServers(page: Page, requests: string[]) {
const current = url.origin === serverA ? sessionA : sessionB
const directory = url.searchParams.get("directory")
if (directory && directory !== current.directory) return json(route, { name: "InvalidDirectory" }, 500)
if (url.pathname === "/api/status") return json(route, { version: "test", pid: 1, urls: [url.origin] })
if (url.pathname === "/api/info")
return json(route, { version: "test", pid: 1, urls: [url.origin], paths: { tmp: "/tmp/opencode" } })
if (url.pathname === "/api/session") return json(route, { data: [currentSession(current)], cursor: {} })
if (url.pathname === "/api/session/active") return json(route, { data: {} })
if (url.pathname === `/api/session/${current.id}`) return json(route, { data: currentSession(current) })
@@ -16,8 +16,13 @@ test("server dialog keeps focus above fullscreen settings", async ({ page }) =>
body: 'data: {"id":"evt_connected","type":"server.connected","data":{}}\n\n',
})
}
if (url.pathname === "/api/status") {
return json(route, { version: "2.0.0", pid: 1, urls: [url.origin] })
if (url.pathname === "/api/info") {
return json(route, {
version: "2.0.0",
pid: 1,
urls: [url.origin],
paths: { tmp: "/tmp/opencode" },
})
}
return json(route, {})
})
@@ -138,7 +138,14 @@ test("MCP authentication starts before a slow resource catalog finishes", async
test("multiple desktop connections show the session's server name", async ({ page }) => {
await mockStressTimeline(page)
await page.route("http://secondary.test/**", (route) =>
route.fulfill({ json: { version: "2.0.0", pid: 1, urls: ["http://secondary.test"] } }),
route.fulfill({
json: {
version: "2.0.0",
pid: 1,
urls: ["http://secondary.test"],
paths: { tmp: "/tmp/opencode" },
},
}),
)
await page.addInitScript(
({ directory, server }) => {
@@ -109,11 +109,11 @@ test("passes through non-event fetches", async ({ page }) => {
const timeline = await setupTimeline(page)
const health = await page.evaluate(async () => {
const response = await fetch("/api/status")
const response = await fetch("/api/info")
return response.json()
})
expect(health).toEqual({ version: "2.0.0", pid: 1, urls: [] })
expect(health).toEqual({ version: "2.0.0", pid: 1, urls: [], paths: { tmp: "/tmp/opencode" } })
await expect.poll(async () => (await timeline.transport.connections()).length).toBe(1)
})
@@ -172,64 +172,6 @@ test("Models and Shortcuts autofocus their filters on normal navigation", async
await expect(result).toBeFocused()
})
for (const count of [7, 8]) {
test(`Projects search uses the full list threshold with ${count} projects`, async ({ page }) => {
await page.route("**/api/project", (route) => route.fulfill({ json: projectList(count) }))
await page.reload()
const view = ui(page)
await view.search.fill("OpenCode")
await expect(view.results.getByRole("option")).toHaveCount(count)
await view.search.clear()
await view.settings.getByRole("tab", { name: "Projects", exact: true }).click()
const search = view.settings.getByRole("searchbox", { name: "Search projects", exact: true })
const projects = view.settings.getByRole("button", { name: /^OpenCode / })
await expect(projects).toHaveCount(count)
if (count === 7) {
await expect(search).toHaveCount(0)
return
}
await expect(search).toBeFocused()
await search.fill(" CODE 06 ")
await expect(projects).toHaveCount(1)
await expect(projects).toHaveAccessibleName("OpenCode 06")
await expect(search).toBeVisible()
await search.fill("missing-project")
await expect(projects).toHaveCount(0)
await expect(view.settings.getByText("No projects found", { exact: true })).toBeVisible()
await view.settings.getByRole("button", { name: "Clear", exact: true }).click()
await expect(search).toBeFocused()
await expect(projects).toHaveCount(count)
await view.settings.getByRole("tab", { name: "Models", exact: true }).click()
await view.settings.getByRole("tab", { name: "Projects", exact: true }).click()
await expect(search).toBeFocused()
await search.fill("OpenCode 06")
await projects.click()
await expect(view.settings.getByRole("heading", { name: "OpenCode 06", exact: true })).toBeVisible()
})
}
test("Projects search focuses when the qualifying inventory arrives after opening", async ({ page }) => {
const inventory = Promise.withResolvers<void>()
await page.route("**/api/project", async (route) => {
await inventory.promise
await route.fulfill({ json: projectList(8) })
})
const requested = page.waitForRequest((request) => new URL(request.url()).pathname === "/api/project")
await page.reload()
await requested
const view = ui(page)
const search = view.settings.getByRole("searchbox", { name: "Search projects", exact: true })
try {
await view.settings.getByRole("tab", { name: "Projects", exact: true }).click()
await expect(view.settings.getByRole("heading", { name: "Projects", exact: true })).toBeVisible()
await expect(search).toHaveCount(0)
} finally {
inventory.resolve()
}
await expect(search).toBeFocused()
await expect(view.settings.getByRole("button", { name: /^OpenCode / })).toHaveCount(8)
})
test("all indexed client controls resolve to visible production controls", async ({ page }) => {
const view = ui(page)
for (const entry of clientSettings.filter((entry) => entry.target && !entry.available)) {
@@ -81,10 +81,10 @@ const fixture = test.extend<{ site: Site }, { builds: Record<string, Record<stri
response.setHeader("cache-control", "no-store")
if (path === "/observer.html")
return void response.writeHead(200, { "content-type": "text/html" }).end("<title>Worker observer</title>")
if (path === "/api/status")
if (path === "/api/info")
return void response
.writeHead(200, { "content-type": "application/json" })
.end(`{"version":"test","pid":1,"urls":["${url.origin}"]}`)
.end(`{"version":"test","pid":1,"urls":["${url.origin}"],"paths":{"tmp":"/tmp/opencode"}}`)
if (path === "/sw.js" && state.legacy && state.version === "old") {
// Model the shipped worker's shared precache name and cache-first navigation behavior.
const urls = Object.keys(builds.old).filter(
@@ -334,8 +334,13 @@ fixture("upgrades the legacy shared precache only after old tabs close", async (
fixture("does not substitute cached HTML for API or missing asset navigations", async ({ page, site }) => {
await install(page, site.url)
const api = await page.goto(`${site.url}/api/status`)
expect(await api?.json()).toEqual({ version: "test", pid: 1, urls: ["http://localhost"] })
const api = await page.goto(`${site.url}/api/info`)
expect(await api?.json()).toEqual({
version: "test",
pid: 1,
urls: ["http://localhost"],
paths: { tmp: "/tmp/opencode" },
})
expect(api?.fromServiceWorker()).toBe(false)
const asset = await page.goto(`${site.url}/_assets/missing.js`)
expect(asset?.status()).toBe(404)
+1 -1
View File
@@ -33,7 +33,7 @@ export class MockBadRequest extends Schema.TaggedError<MockBadRequest>()("MockBa
}) {}
const Group = HttpApiGroup.make("mock")
.add(HttpApiEndpoint.get("status", "/api/status", { success: Json }))
.add(HttpApiEndpoint.get("info", "/api/info", { success: Json }))
.add(
HttpApiEndpoint.get("event", "/api/event", {
success: Schema.String.pipe(HttpApiSchema.asText({ contentType: "text/event-stream" })),
+7 -1
View File
@@ -219,7 +219,13 @@ function mockHandlers(config: MockServerConfig, state: { cursors: Map<string, st
}),
)
.handleAll({
status: () => Effect.succeed({ version: "2.0.0", pid: 1, urls: config.server ? [config.server] : [] }),
info: () =>
Effect.succeed({
version: "2.0.0",
pid: 1,
urls: config.server ? [config.server] : [],
paths: { tmp: "/tmp/opencode" },
}),
config: () => Effect.succeed(configEntries),
reference: () =>
Effect.succeed({
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@opencode/app",
"version": "2.0.5",
"version": "2.0.7",
"description": "",
"type": "module",
"exports": {
@@ -4,64 +4,6 @@ import { createBlobReference } from "@/runtime/persistence/drafts"
import { uuid } from "@/runtime/persistence/uuid"
import type { ComposerAttachment, ComposerPrompt } from "../types"
const accepted = [
"image/png",
"image/jpeg",
"image/gif",
"image/webp",
"application/pdf",
"text/*",
"application/json",
"application/ld+json",
"application/toml",
"application/x-toml",
"application/x-yaml",
"application/xml",
"application/yaml",
".c",
".cc",
".cjs",
".conf",
".cpp",
".css",
".csv",
".cts",
".env",
".go",
".gql",
".graphql",
".h",
".hh",
".hpp",
".htm",
".html",
".ini",
".java",
".js",
".json",
".jsx",
".log",
".md",
".mdx",
".mjs",
".mts",
".py",
".rb",
".rs",
".sass",
".scss",
".sh",
".sql",
".toml",
".ts",
".tsx",
".txt",
".xml",
".yaml",
".yml",
".zsh",
]
type PromptTarget = {
current: () => ComposerPrompt
cursor: () => number | undefined
@@ -75,7 +17,6 @@ export type ComposerAttachmentConfig = {
) => Promise<void>
directory: () => string
isDialogActive: () => boolean
warn: () => void
duplicate: () => void
onError: (error: unknown) => void
readClipboardImage?: () => Promise<File | null>
@@ -102,13 +43,9 @@ export function createComposerAttachments(
if (!editor) return
return { prompt, cursor: prompt.cursor() ?? cursorPosition(editor) }
}
const add = async (file: File, toast = true, target = capture(), clipboard = false) => {
const add = async (file: File, target = capture(), clipboard = false) => {
if (!target) return false
const mime = await attachmentMime(file)
if (!mime) {
if (toast) input.warn()
return false
}
const blob = input.store ? await input.store(file) : await createBlobReference(file)
const sourcePath = input.getPathForFile?.(file) || undefined
// Native clipboard images arrive with a fresh timestamped filename on every paste, so identical
@@ -138,13 +75,11 @@ export function createComposerAttachments(
target.prompt.set([...target.prompt.current(), attachment], target.cursor)
return true
}
const addAttachments = async (files: File[], toast = true, target = capture()) => {
const found = await files.reduce(async (result, file) => {
const addAttachments = async (files: File[], target = capture()) => {
return files.reduce(async (result, file) => {
const previous = await result
return (await add(file, false, target)) || previous
return (await add(file, target)) || previous
}, Promise.resolve(false))
if (!found && files.length > 0 && toast) input.warn()
return found
}
const handlePaste = async (event: ClipboardEvent) => {
const clipboardData = event.clipboardData
@@ -159,13 +94,13 @@ export function createComposerAttachments(
return file ? [file] : []
})
if (files.length > 0) {
await addAttachments(files, true, target)
await addAttachments(files, target)
return
}
const plainText = clipboardData.getData("text/plain") ?? ""
if (input.readClipboardImage && !plainText) {
const file = await input.readClipboardImage()
if (file && (await add(file, true, target, true))) return
if (file && (await add(file, target, true))) return
}
if (!plainText) return
const text = plainText.includes("\r") ? plainText.replace(/\r\n?/g, "\n") : plainText
@@ -223,9 +158,7 @@ export function createComposerAttachments(
fallback()
return
}
void input
.picker({ defaultPath: input.directory(), multiple: true, accept: accepted }, (file) => add(file))
.catch(input.onError)
void input.picker({ defaultPath: input.directory(), multiple: true }, (file) => add(file)).catch(input.onError)
},
}
}
@@ -249,6 +182,8 @@ const textMimes = new Set([
"application/yaml",
])
// Text-like files normalize to text/plain so the server inlines their content; every other
// file keeps a binary type and is delivered to the model by path or as native media.
async function attachmentMime(file: File) {
const type = file.type.split(";", 1)[0]?.trim().toLowerCase() ?? ""
if (imageMimes.has(type) || type === "application/pdf") return type
@@ -259,10 +194,11 @@ async function attachmentMime(file: File) {
if (type.startsWith("text/") || textMimes.has(type) || type.endsWith("+json") || type.endsWith("+xml")) {
return "text/plain"
}
const binary = type || "application/octet-stream"
const bytes = new Uint8Array(await file.slice(0, 4096).arrayBuffer())
if (bytes.some((byte) => byte === 0)) return
if (bytes.some((byte) => byte === 0)) return binary
const control = bytes.filter((byte) => byte < 9 || (byte > 13 && byte < 32)).length
if (bytes.length > 0 && control / bytes.length > 0.3) return
if (bytes.length > 0 && control / bytes.length > 0.3) return binary
return "text/plain"
}
@@ -0,0 +1,70 @@
import type { Accessor } from "solid-js"
import { blobBytes, blobDataUrl } from "@/runtime/persistence/drafts"
import { useServer } from "@/runtime/server/current"
import { useServerSDK } from "@/runtime/server/client"
import { useWorkspaceLocation } from "@/workspaces/location"
import type { ComposerControls } from "../adapter"
import type { ImageAttachmentPart } from "../state"
// Where a prompt is headed: the model that reads it and the server that runs its tools.
export type AttachmentDestination = {
/** Input modalities the selected model reads natively. */
input: { image: boolean; pdf: boolean }
/** The server shares the client's filesystem, so an attachment's source path resolves as-is. */
local: boolean
/** Copies a file into the server's temporary directory and returns its absolute path there. */
upload: (file: { name: string; data: Uint8Array }) => Promise<string>
}
export type DeliveredAttachment =
| { type: "inline"; attachment: ImageAttachmentPart; dataUrl: string }
| { type: "path"; attachment: ImageAttachmentPart; path: string }
// An attachment travels inline when the model reads its bytes natively. Anything else reaches
// the model as a path on the server, which its tools can open, instead of being rejected.
export function deliverAttachments(attachments: ImageAttachmentPart[], destination: AttachmentDestination) {
return Promise.all(attachments.map((attachment) => deliver(attachment, destination)))
}
async function deliver(
attachment: ImageAttachmentPart,
destination: AttachmentDestination,
): Promise<DeliveredAttachment> {
if (native(attachment.mime, destination.input)) {
return { type: "inline", attachment, dataUrl: await blobDataUrl(attachment.blob, attachment.mime) }
}
if (destination.local && attachment.sourcePath) return { type: "path", attachment, path: attachment.sourcePath }
const path = await destination.upload({ name: attachment.filename, data: await blobBytes(attachment.blob) })
return { type: "path", attachment, path }
}
const imageMimes = new Set(["image/png", "image/jpeg", "image/gif", "image/webp"])
// Mirrors the attachment kinds the server forwards to the model as message content.
function native(mime: string, input: AttachmentDestination["input"]) {
if (mime === "text/plain") return true
if (imageMimes.has(mime)) return input.image
if (mime === "application/pdf") return input.pdf
return false
}
export function useAttachmentDestination(controls: Accessor<ComposerControls>) {
const server = useServer()
const sdk = useServerSDK()
const location = useWorkspaceLocation()
return (): AttachmentDestination => ({
input: controls().model.selection.current()?.capabilities.input ?? { image: false, pdf: false },
local: server.isLocal,
upload: async (file) => {
const info = await sdk.api.server.info()
// One directory per upload keeps the original filename without collisions; the server
// normalizes the separators and returns the resolved path.
const written = await sdk.api.file.write({
location: { directory: location().directory },
path: `${info.paths.tmp}/uploads/${crypto.randomUUID()}/${file.name}`,
payload: file.data,
})
return written.data.path
},
})
}
+20
View File
@@ -8,6 +8,13 @@ export type PromptComment = {
origin?: "review" | "file"
}
/** An attachment the model receives as a path on the server rather than inline bytes. */
export type PromptAttachmentReference = {
name: string
mime: string
path: string
}
function selection(selection: unknown) {
if (!selection || typeof selection !== "object") return undefined
const startLine = Number((selection as FileSelection).startLine)
@@ -58,8 +65,17 @@ export function readPromptPresentation(value: unknown) {
const displayText = (value as { displayText?: unknown }).displayText
const comments = (value as { comments?: unknown }).comments
if (typeof displayText !== "string" || !Array.isArray(comments)) return
const attachments = (value as { attachments?: unknown }).attachments
return {
displayText,
attachments: (Array.isArray(attachments) ? attachments : []).flatMap((item): PromptAttachmentReference[] => {
if (!item || typeof item !== "object") return []
const name = (item as { name?: unknown }).name
const mime = (item as { mime?: unknown }).mime
const path = (item as { path?: unknown }).path
if (typeof name !== "string" || typeof mime !== "string" || typeof path !== "string") return []
return [{ name, mime, path }]
}),
comments: comments.flatMap((item): PromptComment[] => {
if (!item || typeof item !== "object") return []
const path = (item as { path?: unknown }).path
@@ -80,6 +96,10 @@ export function readPromptPresentation(value: unknown) {
}
}
export function formatAttachmentReference(input: PromptAttachmentReference) {
return `Attached file: \`${input.path}\``
}
export function formatCommentNote(input: { path: string; selection?: FileSelection; comment: string }) {
const start = input.selection ? Math.min(input.selection.startLine, input.selection.endLine) : undefined
const end = input.selection ? Math.max(input.selection.startLine, input.selection.endLine) : undefined
@@ -167,7 +167,7 @@ function ComposerStory(props: {
? buildPromptRequest({
prompt: draft.prompt,
context: draft.context.items,
images: [],
attachments: [],
text: value,
sessionDirectory: "C:/repo",
})
@@ -102,7 +102,6 @@ export function ComposerEditor(props: ComposerEditorProps) {
ref={props.controller.setFileInput}
type="file"
multiple
accept="image/png,image/jpeg,image/gif,image/webp,application/pdf,text/*,application/json,application/ld+json,application/toml,application/x-toml,application/x-yaml,application/xml,application/yaml,.c,.cc,.cjs,.conf,.cpp,.css,.csv,.cts,.env,.go,.gql,.graphql,.h,.hh,.hpp,.htm,.html,.ini,.java,.js,.json,.jsx,.log,.md,.mdx,.mjs,.mts,.py,.rb,.rs,.sass,.scss,.sh,.sql,.toml,.ts,.tsx,.txt,.xml,.yaml,.yml,.zsh"
class="hidden"
onChange={(event) => {
const list = event.currentTarget.files
@@ -0,0 +1,19 @@
import { expect, test } from "bun:test"
import { shouldHandlePasteAsAttachment } from "./interaction"
test("leaves paste to the browser when web clipboard data is unavailable", () => {
expect(shouldHandlePasteAsAttachment(clipboard(), false)).toBe(false)
})
test("uses native image reading only when the clipboard has no text", () => {
expect(shouldHandlePasteAsAttachment(clipboard(), true)).toBe(true)
expect(shouldHandlePasteAsAttachment(clipboard(["text/plain"]), true)).toBe(false)
})
test("handles clipboard files as attachments", () => {
expect(shouldHandlePasteAsAttachment(clipboard([], [{ kind: "file" }]), false)).toBe(true)
})
function clipboard(types: string[] = [], items: Array<{ kind: string }> = []) {
return { types, items } as unknown as DataTransfer
}
@@ -384,20 +384,20 @@ export function createComposerEditor(input: {
},
onPaste(event: ClipboardEvent) {
const clipboard = event.clipboardData
if (
attachments &&
(Array.from(clipboard?.items ?? []).some((item) => item.kind === "file") || !clipboard?.getData("text/plain"))
) {
const text = clipboard?.getData("text/plain")
if (attachments && shouldHandlePasteAsAttachment(clipboard, !!input.attachments?.readClipboardImage)) {
void attachments.handlePaste(event)
return
}
const text = clipboard?.getData("text/plain").replace(/\r\n?/g, "\n")
if (!text) return
event.preventDefault()
// insertText emits input events per line, repeatedly parsing and saving the draft.
// Escaped HTML inserts multiline text once and preserves native selection and undo.
const multiline = text.includes("\n")
const value = multiline ? text.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;") : text
const normalized = text.replace(/\r\n?/g, "\n")
const multiline = normalized.includes("\n")
const value = multiline
? normalized.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;")
: normalized
if (
typeof document.execCommand === "function" &&
document.execCommand(multiline ? "insertHTML" : "insertText", false, value)
@@ -408,13 +408,13 @@ export function createComposerEditor(input: {
if (!(target instanceof HTMLElement) || !selection?.rangeCount || !target.contains(selection.anchorNode)) return
const range = selection.getRangeAt(0)
range.deleteContents()
const node = document.createTextNode(text)
const node = document.createTextNode(normalized)
range.insertNode(node)
range.setStartAfter(node)
range.collapse(true)
selection.removeAllRanges()
selection.addRange(range)
target.dispatchEvent(new InputEvent("input", { bubbles: true, inputType: "insertFromPaste", data: text }))
target.dispatchEvent(new InputEvent("input", { bubbles: true, inputType: "insertFromPaste", data: normalized }))
},
onDragEnter(event: DragEvent) {
event.preventDefault()
@@ -450,6 +450,12 @@ export function createComposerEditor(input: {
export type ComposerEditorModel = ReturnType<typeof createComposerEditor>
export function shouldHandlePasteAsAttachment(clipboard: DataTransfer | null, readClipboardImage: boolean) {
if (Array.from(clipboard?.items ?? []).some((item) => item.kind === "file")) return true
if (Array.from(clipboard?.types ?? []).some((type) => type.startsWith("text/"))) return false
return readClipboardImage
}
function canNavigateHistory(direction: "up" | "down", text: string, cursor: number, inHistory: boolean) {
const position = Math.max(0, Math.min(cursor, text.length))
if (inHistory) return position === 0 || position === text.length
+2 -5
View File
@@ -22,6 +22,7 @@ import type { PromptHistoryComment } from "./history/entry"
import { createComposerHistory } from "./history/store"
import { composerPlaceholder } from "./placeholder"
import { createComposerSubmit } from "./submit"
import { useAttachmentDestination } from "./attachments/deliver"
export type ComposerModel = ComposerEditorModel & {
readonly model: ComposerControls["model"]
@@ -265,6 +266,7 @@ export function createComposerModel(adapter: ComposerAdapter, options?: { queue?
resetHistory: () => controller.resetHistory(),
setMode: (next) => controller.dispatch({ type: next === "shell" ? "mode.shell" : "mode.normal" }),
closePopover: () => controller.dispatch({ type: "popover.close" }),
destination: useAttachmentDestination(adapter.controls),
delivery: (alternate) => {
const queue = options?.queue
if (!queue) return "steer"
@@ -339,11 +341,6 @@ export function createComposerModel(adapter: ComposerAdapter, options?: { queue?
picker: platform.openAttachmentPickerDialog,
directory: () => sdk().directory,
isDialogActive: () => !!dialog.active,
warn: () =>
showToast({
title: language.t("prompt.toast.pasteUnsupported.title"),
description: language.t("prompt.toast.pasteUnsupported.description"),
}),
duplicate: () => showToast({ title: language.t("prompt.toast.attachmentDuplicate.title") }),
onError: (error) =>
showToast({
+27 -34
View File
@@ -1,8 +1,17 @@
import { describe, expect, test } from "bun:test"
import { Skill } from "@opencode/schema/skill"
import type { Prompt } from "@/composer/state"
import type { ImageAttachmentPart, Prompt } from "@/composer/state"
import type { DeliveredAttachment } from "./attachments/deliver"
import { buildPromptRequest } from "./request"
function inline(filename: string, mime: string, extra?: Partial<ImageAttachmentPart>): DeliveredAttachment {
return {
type: "inline",
attachment: { type: "image", id: `img_${filename}`, filename, mime, blob: { id: filename, url: "" }, ...extra },
dataUrl: `data:${mime};base64,AAA`,
}
}
describe("buildPromptRequest", () => {
test("builds text, files, and agents from the prompt", () => {
const prompt: Prompt = [
@@ -21,9 +30,7 @@ describe("buildPromptRequest", () => {
const result = buildPromptRequest({
prompt,
context: [{ key: "ctx:1", type: "file", path: "src/bar.ts", comment: "check this" }],
images: [
{ type: "image", id: "img_1", filename: "a.png", mime: "image/png", dataUrl: "data:image/png;base64,AAA" },
],
attachments: [inline("a.png", "image/png")],
text: "hello @src/foo.ts @planner",
sessionDirectory: "/repo",
})
@@ -45,16 +52,7 @@ describe("buildPromptRequest", () => {
const result = buildPromptRequest({
prompt: [{ type: "text", content: "check these", start: 0, end: 11 }],
context: [],
images: [
{ type: "image", id: "img_1", filename: "a.png", mime: "image/png", dataUrl: "data:image/png;base64,AAA" },
{
type: "image",
id: "img_2",
filename: "b.pdf",
mime: "application/pdf",
dataUrl: "data:application/pdf;base64,BBB",
},
],
attachments: [inline("a.png", "image/png"), inline("b.pdf", "application/pdf")],
text: "check these",
sessionDirectory: "/repo",
})
@@ -69,15 +67,10 @@ describe("buildPromptRequest", () => {
const result = buildPromptRequest({
prompt: [],
context: [],
images: [
{
type: "image",
id: "img_external",
filename: "opencode.global.dat",
attachments: [
inline("opencode.global.dat", "text/plain", {
sourcePath: "C:\\Users\\Luke\\AppData\\Roaming\\ai.opencode.desktop.beta\\opencode.global.dat",
mime: "text/plain",
dataUrl: "data:text/plain;base64,AAA",
},
}),
],
text: "inspect this",
sessionDirectory: "C:\\Repos\\sst\\opencode",
@@ -102,7 +95,7 @@ describe("buildPromptRequest", () => {
},
],
context: [],
images: [],
attachments: [],
text: "@docs",
sessionDirectory: "/repo/app",
})
@@ -124,7 +117,7 @@ describe("buildPromptRequest", () => {
{ key: "ctx:dup", type: "file", path: "src/foo.ts" },
{ key: "ctx:comment", type: "file", path: "src/foo.ts", comment: "focus here" },
],
images: [],
attachments: [],
text: "@src/foo.ts",
sessionDirectory: "/repo",
})
@@ -146,7 +139,7 @@ describe("buildPromptRequest", () => {
comment: "Compare with @src/shared.ts and @src/review.ts.",
},
],
images: [],
attachments: [],
text: "look",
sessionDirectory: "/repo",
})
@@ -162,7 +155,7 @@ describe("buildPromptRequest", () => {
const result = buildPromptRequest({
prompt,
context: [],
images: [],
attachments: [],
text: "@src\\foo.ts",
sessionDirectory: "D:\\projects\\myapp", // Windows path
})
@@ -183,7 +176,7 @@ describe("buildPromptRequest", () => {
const result = buildPromptRequest({
prompt,
context: [],
images: [],
attachments: [],
text: "@file#name.txt",
sessionDirectory: "C:\\Users\\test\\Documents", // Windows path
})
@@ -204,7 +197,7 @@ describe("buildPromptRequest", () => {
const result = buildPromptRequest({
prompt,
context: [],
images: [],
attachments: [],
text: "@src/app.ts",
sessionDirectory: "/home/user/project",
})
@@ -218,7 +211,7 @@ describe("buildPromptRequest", () => {
const result = buildPromptRequest({
prompt,
context: [],
images: [],
attachments: [],
text: "@README.md",
sessionDirectory: "/Users/kelvin/Projects/opencode",
})
@@ -233,7 +226,7 @@ describe("buildPromptRequest", () => {
{ key: "ctx:1", type: "file", path: "src\\utils\\helper.ts" },
{ key: "ctx:2", type: "file", path: "test\\unit.test.ts", comment: "check tests" },
],
images: [],
attachments: [],
text: "test",
sessionDirectory: "D:\\workspace\\app",
})
@@ -255,7 +248,7 @@ describe("buildPromptRequest", () => {
const result = buildPromptRequest({
prompt,
context: [],
images: [],
attachments: [],
text: "@D:\\other\\project\\file.ts",
sessionDirectory: "C:\\current\\project",
})
@@ -282,7 +275,7 @@ describe("buildPromptRequest", () => {
const result = buildPromptRequest({
prompt,
context: [],
images: [],
attachments: [],
text: "@src\\App.tsx",
sessionDirectory: "C:\\project",
})
@@ -307,7 +300,7 @@ describe("buildPromptRequest", () => {
const result = buildPromptRequest({
prompt,
context: [],
images: [],
attachments: [],
text: "@..\\..\\shared\\util.ts",
sessionDirectory: "C:\\projects\\myapp\\src",
})
@@ -337,7 +330,7 @@ describe("buildPromptRequest", () => {
},
],
context: [],
images: [],
attachments: [],
text: "@review",
sessionDirectory: "/repo",
})
+26 -10
View File
@@ -1,8 +1,14 @@
import { getFilename } from "@opencode/util/path"
import type { FileSelection } from "@/workspaces/files/model"
import { encodeFilePath } from "@/workspaces/files/path"
import type { AgentPart, FileAttachmentPart, ImageAttachmentPart, Prompt, SkillPart } from "@/composer/state"
import { formatCommentNote, type PromptComment } from "@/composer/comment-note"
import type { AgentPart, FileAttachmentPart, Prompt, SkillPart } from "@/composer/state"
import {
formatAttachmentReference,
formatCommentNote,
type PromptAttachmentReference,
type PromptComment,
} from "@/composer/comment-note"
import type { DeliveredAttachment } from "@/composer/attachments/deliver"
// Network fields feed both boundaries; display fields keep desktop-only rendering details in the local echo.
type PromptRequest = {
@@ -12,6 +18,7 @@ type PromptRequest = {
agents: { name: string; mention?: { start: number; end: number; text: string } }[]
skills: { id: string; name: string; mention?: { start: number; end: number; text: string } }[]
comments: PromptComment[]
attachments: PromptAttachmentReference[]
}
type ContextFile = {
@@ -28,7 +35,7 @@ type ContextFile = {
type BuildPromptRequestInput = {
prompt: Prompt
context: ContextFile[]
images: (Omit<ImageAttachmentPart, "blob"> & { dataUrl: string })[]
attachments: DeliveredAttachment[]
text: string
sessionDirectory: string
}
@@ -106,18 +113,27 @@ export function buildPromptRequest(input: BuildPromptRequestInput): PromptReques
return [file, ...mentions]
})
const images = input.images.map((attachment) => ({
uri: attachment.dataUrl,
mime: attachment.mime,
name: attachment.sourcePath ?? attachment.filename,
}))
const inline = input.attachments.flatMap((item) =>
item.type === "inline"
? [{ uri: item.dataUrl, mime: item.attachment.mime, name: item.attachment.sourcePath ?? item.attachment.filename }]
: [],
)
// Like comments, path references reach the model as text and the message UI through metadata.
const attachments = input.attachments.flatMap((item) =>
item.type === "path" ? [{ name: item.attachment.filename, mime: item.attachment.mime, path: item.path }] : [],
)
return {
text: [...(input.text.trim() ? [input.text] : []), ...comments.map(formatCommentNote)].join("\n"),
text: [
...(input.text.trim() ? [input.text] : []),
...attachments.map(formatAttachmentReference),
...comments.map(formatCommentNote),
].join("\n"),
displayText: input.text,
files: [...files, ...context, ...images],
files: [...files, ...context, ...inline],
agents,
skills,
comments,
attachments,
}
}
+10
View File
@@ -3,6 +3,7 @@ import type { ModelSelection } from "@/providers/models/selection"
import type { SessionMessageUser } from "@opencode/client/promise"
import { Skill } from "@opencode/schema/skill"
import type { ActiveComposerAdapter, ComposerControls, ComposerSession, NewSessionComposerAdapter } from "./adapter"
import type { AttachmentDestination } from "./attachments/deliver"
import { createMemoryComposerState } from "./state"
import { createComposerSubmit } from "./submit"
@@ -48,6 +49,14 @@ function controls(): ComposerControls {
}
}
const destination: AttachmentDestination = {
input: { image: true, pdf: true },
local: false,
upload: async () => {
throw new Error("native attachments must not upload")
},
}
function submitInput(
adapter: ActiveComposerAdapter | NewSessionComposerAdapter,
notify = { missingSelection() {}, failed(_kind: "shell" | "command" | "prompt", _error: unknown) {} },
@@ -64,6 +73,7 @@ function submitInput(
resetHistory() {},
setMode() {},
closePopover() {},
destination: () => destination,
notify,
comments: { capture: () => [], clear() {}, restore() {} },
})
+31 -20
View File
@@ -8,7 +8,7 @@ import type { ComposerAdapter, ComposerDelivery, ComposerSelection, ComposerSess
import { createComposerSubmission } from "./submission-state"
import { buildPromptRequest } from "./request"
import { setCursorPosition } from "./editor/dom"
import { blobDataUrl } from "@/runtime/persistence/drafts"
import { deliverAttachments, type AttachmentDestination } from "./attachments/deliver"
import type { ModelSelection } from "@/providers/models/selection"
const submitting = new WeakSet<object>()
@@ -34,6 +34,7 @@ type ComposerSubmitInput = {
resetHistory: () => void
setMode: (mode: "normal" | "shell") => void
closePopover: () => void
destination: () => AttachmentDestination
delivery?: (alternate: boolean) => ComposerDelivery
notify: {
missingSelection: () => void
@@ -86,10 +87,16 @@ export function createComposerSubmit(input: ComposerSubmitInput) {
const optimisticBusy = !input.adapter.working()
if (optimisticBusy && input.adapter.kind === "new-session")
session.data.session.setStatus(session.id, "running")
const sending = sendPrompt(session, value, input.adapter.controls().model.selection.trackSessionCommit, () => {
if (optimisticBusy && input.adapter.kind === "active-session")
session.data.session.setStatus(session.id, "running")
}).then(
const sending = sendPrompt(
session,
value,
input.destination(),
input.adapter.controls().model.selection.trackSessionCommit,
() => {
if (optimisticBusy && input.adapter.kind === "active-session")
session.data.session.setStatus(session.id, "running")
},
).then(
() => ({ ok: true as const }),
(error) => ({ ok: false as const, error }),
)
@@ -122,9 +129,13 @@ export function createComposerSubmit(input: ComposerSubmitInput) {
if (command) {
clearSubmission(input, submission)
void sendCommand(session, value, command, input.adapter.controls().model.selection.trackSessionCommit).catch(
(error) => failSubmission(input, session, "command", error, restore, value.id),
)
void sendCommand(
session,
value,
command,
input.destination(),
input.adapter.controls().model.selection.trackSessionCommit,
).catch((error) => failSubmission(input, session, "command", error, restore, value.id))
return
}
} finally {
@@ -293,9 +304,10 @@ async function sendCommand(
session: ComposerSession,
value: ComposerSubmission,
command: { command: string; arguments: string },
destination: AttachmentDestination,
track?: ModelSelection["trackSessionCommit"],
) {
const request = await buildSubmissionRequest(session, value)
const request = await buildSubmissionRequest(session, value, destination)
// Like queued prompts, queued commands must not apply the composer's selection to active work.
if (value.delivery === "steer") await applySelection(session, value.selection, track)
await session.api.command({
@@ -334,10 +346,11 @@ async function applySelection(
async function sendPrompt(
session: ComposerSession,
value: ComposerSubmission,
destination: AttachmentDestination,
track: ModelSelection["trackSessionCommit"] | undefined,
onAdmit: () => void,
) {
const request = await buildSubmissionRequest(session, value)
const request = await buildSubmissionRequest(session, value, destination)
// Switching agent or model reconfigures the session immediately, and with it
// the remainder of a running turn. A steer targets that turn, so its
// selection applies now; a queued follow-up must not reconfigure the turn it
@@ -358,6 +371,7 @@ async function sendPrompt(
metadata: {
displayText: request.displayText,
comments: request.comments,
attachments: request.attachments,
agent: value.selection.agent,
model: {
...value.selection.model,
@@ -370,21 +384,18 @@ async function sendPrompt(
await sending
}
async function buildSubmissionRequest(session: ComposerSession, value: ComposerSubmission) {
const images = await Promise.all(
value.images.map(async (attachment) => ({
...attachment,
dataUrl: await blobDataUrl(attachment.blob, attachment.mime),
})),
)
const request = buildPromptRequest({
async function buildSubmissionRequest(
session: ComposerSession,
value: ComposerSubmission,
destination: AttachmentDestination,
) {
return buildPromptRequest({
prompt: value.prompt,
context: value.context,
images,
attachments: await deliverAttachments(value.images, destination),
text: value.text,
sessionDirectory: session.directory,
})
return request
}
function failSubmission(
+1 -1
View File
@@ -1,5 +1,4 @@
export { AppBaseProviders, AppInterface, preloadRoute } from "./app"
export { ACCEPTED_FILE_EXTENSIONS } from "./runtime/platform/file-picker"
export { useCommand } from "./shell/commands/command"
export { currentRoute, type LayoutRoute, useCurrentRoute } from "./shell/state/layout"
export { loadLocaleDict, normalizeLocale, type Locale, useLanguage } from "./runtime/i18n/language"
@@ -15,6 +14,7 @@ export type {
BrowserPaneTarget,
} from "./runtime/platform/browser-pane"
export { ServerConnection, useServers } from "./runtime/server/registry"
export { useGlobal } from "./runtime/server/runtime"
export { useTabs } from "./shell/tabs/tabs"
export { createDraftStore } from "./runtime/persistence/drafts"
export { createNamespaceStorage, type NamespaceStorage } from "./runtime/persistence/namespace"
+21 -2
View File
@@ -42,8 +42,14 @@
container-name: session-chat;
}
[data-component="new-session"] {
container-type: inline-size;
container-name: new-session;
}
[data-slot="session-chat-panel"]
:is([data-timeline-virtual-content], [data-component="session-composer-dock"] > div) {
:is([data-timeline-virtual-content], [data-component="session-composer-dock"] > div),
[data-slot="new-session-content"] {
translate: var(--session-summary-resize-translate, var(--session-summary-translate, none));
transition: translate 240ms cubic-bezier(0.4, 0, 0.2, 1);
@@ -53,7 +59,8 @@
}
[data-slot="session-chat-panel"][data-summary-resizing="true"]
:is([data-timeline-virtual-content], [data-component="session-composer-dock"] > div) {
:is([data-timeline-virtual-content], [data-component="session-composer-dock"] > div),
[data-component="new-session"][data-summary-resizing="true"] [data-slot="new-session-content"] {
transition: none;
}
@@ -70,6 +77,18 @@
}
}
/* Shift only while centered content overlaps the 280px summary cards and their 16px edge inset:
880px + 2 * (280px + 16px) = 1472px. Center it in the remaining space, reserving 320px. */
@container new-session (min-width: 1200px) and (width < 1472px) {
[data-component="new-session"][data-summary-open="true"] [data-slot="new-session-content"] {
--session-summary-translate: -160px;
&:dir(rtl) {
--session-summary-translate: 160px;
}
}
}
[data-slot="session-chat-panel"][data-scrollbar-hidden="true"]
[data-slot="session-timeline-scroll"]
> .scroll-view__thumb {
+26 -3
View File
@@ -1,8 +1,10 @@
import { useDialog } from "@opencode/ui/context/dialog"
import { Tooltip } from "@opencode/ui/tooltip"
import { Icon } from "@opencode/ui/icon"
import { Show, Suspense, createMemo, createSignal, lazy } from "solid-js"
import { Show, Suspense, createMemo, createSignal, lazy, onMount } from "solid-js"
import { createStore } from "solid-js/store"
import { makeEventListener } from "@solid-primitives/event-listener"
import { debounce } from "@solid-primitives/scheduled"
import { Schema } from "effect"
import createPresence from "solid-presence"
import { Composer } from "@/composer/composer"
@@ -48,7 +50,21 @@ export function NewSessionView(props: {
workspace: NewSessionWorkspaceController
mcp: DraftMcpControls
}) {
const [store, setStore] = createStore({ summary: false })
const [store, setStore] = createStore({
summary: false,
content: undefined as HTMLDivElement | undefined,
summaryResizeTranslate: undefined as string | undefined,
})
const finishWindowResize = debounce(() => setStore("summaryResizeTranslate", undefined), 150)
onMount(() => {
makeEventListener(window, "resize", () => {
if (store.summaryResizeTranslate === undefined) {
// Freeze the painted offset, including an in-flight slide, until resizing settles.
setStore("summaryResizeTranslate", store.content ? getComputedStyle(store.content).translate : "none")
}
finishWindowResize()
})
})
const [onboarding, setOnboarding, , onboardingReady] = persisted(
Persist.global("workspace-onboarding"),
WorkspaceOnboardingSchema,
@@ -63,6 +79,9 @@ export function NewSessionView(props: {
<div class="@container relative flex flex-col min-h-0 h-full flex-1">
<div
data-component="new-session"
data-summary-open={store.summary}
data-summary-resizing={store.summaryResizeTranslate !== undefined}
style={{ "--session-summary-resize-translate": store.summaryResizeTranslate }}
class="relative flex-1 min-h-0 overflow-hidden rounded-[10px] bg-v2-background-bg-base shadow-[var(--v2-elevation-raised)]"
>
<ComposerDropzone
@@ -89,7 +108,11 @@ export function NewSessionView(props: {
</SummaryPopover>
</div>
<div class="absolute inset-x-0 top-[25.375%] flex justify-center px-6">
<div class={NEW_SESSION_CONTENT_WIDTH}>
<div
ref={(element) => setStore("content", element)}
data-slot="new-session-content"
class={NEW_SESSION_CONTENT_WIDTH}
>
<NewSessionWordmark />
<div class="mt-8 flex flex-col gap-8">
<Composer model={props.composer} />
@@ -1,7 +1,12 @@
[data-component="new-session-wordmark"] {
--icon-strong-base: var(--icon-base);
--wordmark-shimmer-opacity: 0.45;
.wordmark-shimmer {
--icon-base: white;
--icon-strong-base: white;
--icon-weak-base: transparent;
/* Blend above the base logo's opacity so the sweep only adds light in either theme. */
color: white;
mix-blend-mode: screen;
@@ -13,6 +18,10 @@
}
}
[data-color-scheme="light"] [data-component="new-session-wordmark"] {
--icon-weak-base: color-mix(in srgb, var(--icon-base) 30%, transparent);
}
[data-color-scheme="dark"] [data-component="new-session-wordmark"] {
/* Preserve the previous dark highlight strength: 0.16 × 0.7 × 0.6. */
--wordmark-shimmer-opacity: 0.0672;
+4 -4
View File
@@ -1,4 +1,4 @@
import { Wordmark } from "@opencode/ui/wordmark"
import { Logo } from "@opencode/ui/logo"
import "./wordmark.css"
export function NewSessionWordmark() {
@@ -8,9 +8,9 @@ export function NewSessionWordmark() {
aria-hidden="true"
class="pointer-events-none mx-auto w-full max-w-[720px] text-v2-background-bg-inverse"
>
<div data-slot="wordmark-reveal" class="relative">
<Wordmark fade={false} class="block h-auto w-full opacity-60 [[data-color-scheme=dark]_&]:opacity-50" />
<Wordmark fade={false} muted={false} class="wordmark-shimmer absolute inset-0 h-auto w-full" />
<div data-slot="wordmark-reveal" class="relative mx-auto w-4/5">
<Logo class="block aspect-[720/129] w-full opacity-[0.16]" />
<Logo class="wordmark-shimmer absolute inset-0 aspect-[720/129] w-full" />
</div>
</div>
)
-4
View File
@@ -191,7 +191,6 @@ export const dict = {
"dialog.provider.opencode.note": "Claude፣ GPT፣ Gemini እና ሌሎችንም ጨምሮ የተስተካከሉ ሞዴሎች",
"dialog.provider.opencode.tagline": "ታማኝ የተመቻቹ ሞዴሎች",
"dialog.provider.opencodeGo.tagline": "ዝቅተኛ ወጪ ለሁሉም ሰው",
"dialog.provider.anthropic.note": "የቀጥታ የClaude ሞዴሎች፣ ፕሮ እና ማክስን ጨምሮ",
"dialog.provider.copilot.note": "AI ሞዴሎች በGitHub Copilot] በኩል ኮድ ለማድረግ እገዛ",
"dialog.provider.openai.note": "GPT ሞዴሎች ለፈጣን እና ችሎታ ላለው አጠቃላይ AI ተግባራት",
"dialog.provider.google.note": "Gemini ለፈጣን፣ የተዋቀሩ ምላሾች ሞዴሎች",
@@ -208,7 +207,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "ከ70+ በላይ አቅራቢዎችን ይመልከቱ",
"dialog.provider.viewAll": "ተጨማሪ አቅራቢዎችን አሳይ",
"provider.connect.title": "{{provider}} አገናኝ",
"provider.connect.title.anthropicProMax": "በClaude Pro/Max ይግቡ",
"provider.connect.selectMethod": "የመግቢያ ዘዴን ለ{{provider}} ምረጥ።",
"provider.connect.method.apiKey": "API ቁልፍ",
"provider.connect.method.browser": "አሳሽ",
@@ -371,8 +369,6 @@ export const dict = {
"prompt.attachment.remove": "ዓባሪን አስወግድ",
"prompt.action.send": "ላክ",
"prompt.action.stop": "አቁም",
"prompt.toast.pasteUnsupported.title": "የማይደገፍ ዓባሪ",
"prompt.toast.pasteUnsupported.description": "ምስሎች፣ ፒዲኤፎች ወይም የጽሑፍ ፋይሎች ብቻ እዚህ ጋር ሊጣመሩ ይችላሉ።",
"prompt.toast.attachmentDuplicate.title": "ይህ ፋይል አስቀድሞ ተሰቅሏል",
"prompt.toast.modelAgentRequired.title": "ወኪል እና ሞዴል ይምረጡ",
"prompt.toast.modelAgentRequired.description": "ፕሮምፕት ከመላክዎ በፊት ወኪል እና ሞዴል ይምረጡ።",
-4
View File
@@ -198,7 +198,6 @@ export const dict = {
"dialog.provider.opencode.note": "نماذج مختارة تتضمن Claude و GPT و Gemini والمزيد",
"dialog.provider.opencode.tagline": "نماذج موثوقة ومحسنة",
"dialog.provider.opencodeGo.tagline": "اشتراك منخفض التكلفة للجميع",
"dialog.provider.anthropic.note": "وصول مباشر إلى نماذج Claude، بما فيها Pro و Max",
"dialog.provider.copilot.note": "نماذج ذكاء اصطناعي للمساعدة في البرمجة عبر GitHub Copilot",
"dialog.provider.openai.note": "نماذج GPT لمهام الذكاء الاصطناعي العامة السريعة والمتقدمة",
"dialog.provider.google.note": "نماذج Gemini لاستجابات سريعة ومنظمة",
@@ -215,7 +214,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "عرض أكثر من 70 موفرًا إضافيًا",
"dialog.provider.viewAll": "عرض المزيد من الموفرين",
"provider.connect.title": "الاتصال بـ {{provider}}",
"provider.connect.title.anthropicProMax": "تسجيل الدخول باستخدام Claude Pro/Max",
"provider.connect.selectMethod": "حدد طريقة تسجيل الدخول لـ {{provider}}.",
"provider.connect.method.apiKey": "مفتاح API",
"provider.connect.method.browser": "المتصفح",
@@ -380,9 +378,7 @@ export const dict = {
"prompt.attachment.remove": "إزالة المرفق",
"prompt.action.send": "إرسال",
"prompt.action.stop": "إيقاف",
"prompt.toast.pasteUnsupported.title": "مرفق غير مدعوم",
"prompt.toast.attachmentDuplicate.title": "تم تحميل هذا الملف بالفعل",
"prompt.toast.pasteUnsupported.description": "يمكن إرفاق الصور أو ملفات PDF أو الملفات النصية فقط هنا.",
"prompt.toast.modelAgentRequired.title": "حدد وكيلاً ونموذجاً",
"prompt.toast.modelAgentRequired.description": "اختر وكيلاً ونموذجاً قبل إرسال الموجه.",
"prompt.toast.worktreeCreateFailed.title": "فشل إنشاء شجرة العمل",
-4
View File
@@ -194,7 +194,6 @@ export const dict = {
"dialog.provider.opencode.note": "Claude, GPT, Gemini və daha çoxu daxil olmaqla seçilmiş modellər",
"dialog.provider.opencode.tagline": "Etibarlı optimallaşdırılmış modellər",
"dialog.provider.opencodeGo.tagline": "Hamı üçün aşağı qiymətli abunəlik",
"dialog.provider.anthropic.note": "Pro və Max daxil olmaqla Claude modellərinə birbaşa giriş",
"dialog.provider.copilot.note": "GitHub Copilot vasitəsilə kodlaşdırma yardımı üçün AI modelləri",
"dialog.provider.openai.note": "Sürətli və bacarıqlı ümumi AI tapşırıqları üçün GPT modelləri",
"dialog.provider.google.note": "Sürətli, strukturlaşdırılmış cavablar üçün Gemini modelləri",
@@ -211,7 +210,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Daha 70+ provayderə baxın",
"dialog.provider.viewAll": "Daha çox provayder göstər",
"provider.connect.title": "{{provider}} provayderini qoş",
"provider.connect.title.anthropicProMax": "Claude Pro/Max ilə daxil ol",
"provider.connect.selectMethod": "{{provider}} üçün giriş üsulunu seçin.",
"provider.connect.method.apiKey": "API açarı",
"provider.connect.method.browser": "Brauzer",
@@ -378,8 +376,6 @@ export const dict = {
"prompt.attachment.remove": "Əlavəni sil",
"prompt.action.send": "Göndər",
"prompt.action.stop": "Dayandır",
"prompt.toast.pasteUnsupported.title": "Dəstəklənməyən əlavə",
"prompt.toast.pasteUnsupported.description": "Buraya yalnız şəkillər, PDF-lər və ya mətn faylları əlavə edilə bilər.",
"prompt.toast.attachmentDuplicate.title": "Bu fayl artıq yüklənib",
"prompt.toast.modelAgentRequired.title": "Agent və model seçin",
"prompt.toast.modelAgentRequired.description": "Prompt göndərməzdən əvvəl agent və model seçin.",
-4
View File
@@ -194,7 +194,6 @@ export const dict = {
"dialog.provider.opencode.note": "Подбрани модели, включително Claude, GPT, Gemini и други",
"dialog.provider.opencode.tagline": "Надеждни оптимизирани модели",
"dialog.provider.opencodeGo.tagline": "Абонамент на ниска цена за всеки",
"dialog.provider.anthropic.note": "Директен достъп до Claude модели, включително Pro и Max",
"dialog.provider.copilot.note": "AI модели за помощ при кодиране чрез GitHub Copilot",
"dialog.provider.openai.note": "GPT модели за бързи, способни общи задачи с изкуствен интелект",
"dialog.provider.google.note": "Gemini модели за бързи, структурирани отговори",
@@ -211,7 +210,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Вижте още 70+ доставчици",
"dialog.provider.viewAll": "Показване на още доставчици",
"provider.connect.title": "Свържете {{provider}}",
"provider.connect.title.anthropicProMax": "Влезте с Claude Pro/Max",
"provider.connect.selectMethod": "Изберете метод за влизане за {{provider}}.",
"provider.connect.method.apiKey": "API ключ",
"provider.connect.method.browser": "Браузър",
@@ -378,8 +376,6 @@ export const dict = {
"prompt.attachment.remove": "Премахване на прикачения файл",
"prompt.action.send": "Изпратете",
"prompt.action.stop": "Спрете",
"prompt.toast.pasteUnsupported.title": "Неподдържан прикачен файл",
"prompt.toast.pasteUnsupported.description": "Тук могат да се прикачват само изображения, PDF или текстови файлове.",
"prompt.toast.attachmentDuplicate.title": "Този файл вече е качен",
"prompt.toast.modelAgentRequired.title": "Изберете агент и модел",
"prompt.toast.modelAgentRequired.description": "Изберете агент и модел, преди да изпратите подкана.",
-4
View File
@@ -192,7 +192,6 @@ export const dict: Record<string, string> = {
"dialog.provider.opencode.note": "Claude, GPT, Gemini এবং আরও অনেক কিছু সহ কিউরেট করা মডেল",
"dialog.provider.opencode.tagline": "নির্ভরযোগ্য অপ্টিমাইজ করা মডেল",
"dialog.provider.opencodeGo.tagline": "সবার জন্য কম খরচে সাবস্ক্রিপশন",
"dialog.provider.anthropic.note": "প্রো এবং ম্যাক্স সহ Claude মডেলগুলিতে সরাসরি অ্যাক্সেস",
"dialog.provider.copilot.note": "GitHub Copilot এর মাধ্যমে কোডিং সহায়তার জন্য AI মডেল",
"dialog.provider.openai.note": "দ্রুত, সক্ষম সাধারণ AI কার্যগুলির জন্য GPT মডেল",
"dialog.provider.google.note": "দ্রুত, কাঠামোগত প্রতিক্রিয়ার জন্য Gemini মডেল",
@@ -209,7 +208,6 @@ export const dict: Record<string, string> = {
"dialog.model.unpaid.viewMoreProviders": "আরও 70+ প্রদানকারী দেখুন",
"dialog.provider.viewAll": "আরো প্রদানকারী দেখান",
"provider.connect.title": "{{provider}} সংযোগ করুন",
"provider.connect.title.anthropicProMax": "Claude Pro/Max দিয়ে লগইন করুন",
"provider.connect.selectMethod": "{{provider}} এর জন্য লগইন পদ্ধতি নির্বাচন করুন।",
"provider.connect.method.apiKey": "API কী",
"provider.connect.method.browser": "ব্রাউজার",
@@ -375,8 +373,6 @@ export const dict: Record<string, string> = {
"prompt.attachment.remove": "সংযুক্তি সরান",
"prompt.action.send": "পাঠান",
"prompt.action.stop": "থামো",
"prompt.toast.pasteUnsupported.title": "অসমর্থিত সংযুক্তি",
"prompt.toast.pasteUnsupported.description": "এখানে শুধুমাত্র ছবি, পিডিএফ বা টেক্সট ফাইল সংযুক্ত করা যাবে।",
"prompt.toast.attachmentDuplicate.title": "এই ফাইল ইতিমধ্যে আপলোড করা হয়েছে",
"prompt.toast.modelAgentRequired.title": "একটি এজেন্ট এবং মডেল নির্বাচন করুন",
"prompt.toast.modelAgentRequired.description": "প্রম্পট পাঠানোর আগে একটি এজেন্ট এবং মডেল বেছে নিন।",
-4
View File
@@ -200,7 +200,6 @@ export const dict = {
"dialog.provider.opencode.note": "Modelos selecionados incluindo Claude, GPT, Gemini e mais",
"dialog.provider.opencode.tagline": "Modelos otimizados e confiáveis",
"dialog.provider.opencodeGo.tagline": "Assinatura de baixo custo para todos",
"dialog.provider.anthropic.note": "Acesso direto aos modelos Claude, incluindo Pro e Max",
"dialog.provider.copilot.note": "Modelos de IA para auxílio à programação pelo GitHub Copilot",
"dialog.provider.openai.note": "Modelos GPT rápidos e avançados para tarefas gerais de IA",
"dialog.provider.google.note": "Modelos Gemini para respostas rápidas e estruturadas",
@@ -217,7 +216,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Ver mais de 70 provedores",
"dialog.provider.viewAll": "Ver mais provedores",
"provider.connect.title": "Conectar {{provider}}",
"provider.connect.title.anthropicProMax": "Entrar com Claude Pro/Max",
"provider.connect.selectMethod": "Selecionar método de login para {{provider}}.",
"provider.connect.method.apiKey": "Chave de API",
"provider.connect.method.browser": "Navegador",
@@ -382,9 +380,7 @@ export const dict = {
"prompt.attachment.remove": "Remover anexo",
"prompt.action.send": "Enviar",
"prompt.action.stop": "Parar",
"prompt.toast.pasteUnsupported.title": "Anexo não suportado",
"prompt.toast.attachmentDuplicate.title": "Este arquivo já foi enviado",
"prompt.toast.pasteUnsupported.description": "Apenas imagens, PDFs ou arquivos de texto podem ser anexados aqui.",
"prompt.toast.modelAgentRequired.title": "Selecione um agente e modelo",
"prompt.toast.modelAgentRequired.description": "Escolha um agente e modelo antes de enviar um prompt.",
"prompt.toast.worktreeCreateFailed.title": "Falha ao criar worktree",
-4
View File
@@ -208,7 +208,6 @@ export const dict = {
"dialog.provider.opencode.note": "Kurirani modeli uključujući Claude, GPT, Gemini i druge",
"dialog.provider.opencode.tagline": "Pouzdani optimizovani modeli",
"dialog.provider.opencodeGo.tagline": "Povoljna pretplata za sve",
"dialog.provider.anthropic.note": "Direktan pristup Claude modelima, uključujući Pro i Max",
"dialog.provider.copilot.note": "AI modeli za pomoć pri kodiranju putem GitHub Copilot",
"dialog.provider.openai.note": "GPT modeli za brze, sposobne opšte AI zadatke",
"dialog.provider.google.note": "Gemini modeli za brze, strukturirane odgovore",
@@ -229,7 +228,6 @@ export const dict = {
"dialog.provider.viewAll": "Prikaži više provajdera",
"provider.connect.title": "Poveži {{provider}}",
"provider.connect.title.anthropicProMax": "Prijavi se putem Claude Pro/Max",
"provider.connect.selectMethod": "Odaberi način prijave za {{provider}}.",
"provider.connect.method.apiKey": "API ključ",
"provider.connect.method.browser": "Preglednik",
@@ -403,9 +401,7 @@ export const dict = {
"prompt.action.send": "Pošalji",
"prompt.action.stop": "Zaustavi",
"prompt.toast.pasteUnsupported.title": "Nepodržan prilog",
"prompt.toast.attachmentDuplicate.title": "Ova datoteka je već učitana",
"prompt.toast.pasteUnsupported.description": "Ovdje se mogu priložiti samo slike, PDF-ovi ili tekstualne datoteke.",
"prompt.toast.modelAgentRequired.title": "Odaberi agenta i model",
"prompt.toast.modelAgentRequired.description": "Odaberi agenta i model prije slanja upita.",
"prompt.toast.worktreeCreateFailed.title": "Neuspješno kreiranje worktree-a",
-4
View File
@@ -193,7 +193,6 @@ export const dict = {
"dialog.provider.opencode.note": "Models seleccionats que inclouen Claude, GPT, Gemini i més",
"dialog.provider.opencode.tagline": "Models optimitzats fiables",
"dialog.provider.opencodeGo.tagline": "Subscripció de baix cost per a tothom",
"dialog.provider.anthropic.note": "Accés directe a Claude models, inclosos Pro i Max",
"dialog.provider.copilot.note": "Models d'IA per a l'assistència de codificació mitjançant GitHub Copilot",
"dialog.provider.openai.note": "GPT models per a tasques d'IA generals ràpides i capaces",
"dialog.provider.google.note": "Gemini models per a respostes ràpides i estructurades",
@@ -210,7 +209,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Consulta més de 70 proveïdors més",
"dialog.provider.viewAll": "Mostra més proveïdors",
"provider.connect.title": "Connecta {{provider}}",
"provider.connect.title.anthropicProMax": "Inicieu sessió amb Claude Pro/Max",
"provider.connect.selectMethod": "Seleccioneu el mètode d'inici de sessió per a {{provider}}.",
"provider.connect.method.apiKey": "tecla API.",
"provider.connect.method.browser": "Navegador",
@@ -377,8 +375,6 @@ export const dict = {
"prompt.attachment.remove": "Elimina el fitxer adjunt",
"prompt.action.send": "Enviar",
"prompt.action.stop": "Atureu-vos",
"prompt.toast.pasteUnsupported.title": "Fitxer adjunt no compatible",
"prompt.toast.pasteUnsupported.description": "Aquí només es poden adjuntar imatges, PDFs o fitxers de text.",
"prompt.toast.attachmentDuplicate.title": "Aquest fitxer ja s'ha penjat",
"prompt.toast.modelAgentRequired.title": "Seleccioneu un agent i un model",
"prompt.toast.modelAgentRequired.description": "Trieu un agent i un model abans d'enviar una sol·licitud.",
-4
View File
@@ -191,7 +191,6 @@ export const dict = {
"dialog.provider.opencode.note": "Vybrané modely včetně Claude, GPT, Gemini a dalších",
"dialog.provider.opencode.tagline": "Spolehlivé optimalizované modely",
"dialog.provider.opencodeGo.tagline": "Nízkonákladové předplatné pro každého",
"dialog.provider.anthropic.note": "Přímý přístup k modelům Claude, včetně modelů Pro a Max",
"dialog.provider.copilot.note": "Modely umělé inteligence pro pomoc s kódováním prostřednictvím GitHub Copilot",
"dialog.provider.openai.note": "GPT modely pro rychlé a schopné obecné úlohy umělé inteligence",
"dialog.provider.google.note": "Gemini modely pro rychlé, strukturované odpovědi",
@@ -208,7 +207,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Zobrazit více než 70 dalších poskytovatelů",
"dialog.provider.viewAll": "Zobrazit další poskytovatele",
"provider.connect.title": "Připojit {{provider}}",
"provider.connect.title.anthropicProMax": "Přihlaste se pomocí Claude Pro/Max",
"provider.connect.selectMethod": "Vyberte způsob přihlášení pro {{provider}}.",
"provider.connect.method.apiKey": "API klíč",
"provider.connect.method.browser": "Prohlížeč",
@@ -375,8 +373,6 @@ export const dict = {
"prompt.attachment.remove": "Odstraňte přílohu",
"prompt.action.send": "Odeslat",
"prompt.action.stop": "Přestaň",
"prompt.toast.pasteUnsupported.title": "Nepodporovaná příloha",
"prompt.toast.pasteUnsupported.description": "Zde lze připojit pouze obrázky, PDFs nebo textové soubory.",
"prompt.toast.attachmentDuplicate.title": "Tento soubor již byl nahrán",
"prompt.toast.modelAgentRequired.title": "Vyberte agenta a model",
"prompt.toast.modelAgentRequired.description": "Před odesláním výzvy vyberte zástupce a model.",
-4
View File
@@ -107,7 +107,6 @@ export const dict = {
"dialog.provider.opencode.note": "Udvalgte modeller inklusive Claude, GPT, Gemini og flere",
"dialog.provider.opencode.tagline": "Pålidelige optimerede modeller",
"dialog.provider.opencodeGo.tagline": "Billigt abonnement for alle",
"dialog.provider.anthropic.note": "Direkte adgang til Claude-modeller, inklusive Pro og Max",
"dialog.provider.copilot.note": "AI-modeller til kodningsassistance via GitHub Copilot",
"dialog.provider.openai.note": "GPT-modeller til hurtige, kompetente generelle AI-opgaver",
"dialog.provider.google.note": "Gemini-modeller til hurtige, strukturerede svar",
@@ -128,7 +127,6 @@ export const dict = {
"dialog.provider.viewAll": "Vis flere udbydere",
"provider.connect.title": "Forbind {{provider}}",
"provider.connect.title.anthropicProMax": "Log ind med Claude Pro/Max",
"provider.connect.selectMethod": "Vælg loginmetode for {{provider}}.",
"provider.connect.method.apiKey": "API-nøgle",
"provider.connect.method.browser": "Browser",
@@ -300,9 +298,7 @@ export const dict = {
"prompt.action.send": "Send",
"prompt.action.stop": "Stop",
"prompt.toast.pasteUnsupported.title": "Ikke understøttet vedhæftning",
"prompt.toast.attachmentDuplicate.title": "Denne fil er allerede uploadet",
"prompt.toast.pasteUnsupported.description": "Kun billeder, PDF'er eller tekstfiler kan vedhæftes her.",
"prompt.toast.modelAgentRequired.title": "Vælg en agent og model",
"prompt.toast.modelAgentRequired.description": "Vælg en agent og model før du sender en forespørgsel.",
"prompt.toast.worktreeCreateFailed.title": "Kunne ikke oprette worktree",
-4
View File
@@ -103,7 +103,6 @@ export const dict = {
"dialog.provider.opencode.note": "Kuratierte Modelle inklusive Claude, GPT, Gemini und mehr",
"dialog.provider.opencode.tagline": "Zuverlässige, optimierte Modelle",
"dialog.provider.opencodeGo.tagline": "Kostengünstiges Abo für alle",
"dialog.provider.anthropic.note": "Direkter Zugriff auf Claude-Modelle, einschließlich Pro und Max",
"dialog.provider.copilot.note": "KI-Modelle zur Programmierunterstützung über GitHub Copilot",
"dialog.provider.openai.note": "GPT-Modelle für schnelle, leistungsfähige allgemeine KI-Aufgaben",
"dialog.provider.google.note": "Gemini-Modelle für schnelle, strukturierte Antworten",
@@ -120,7 +119,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Über 70 weitere Anbieter anzeigen",
"dialog.provider.viewAll": "Mehr Anbieter anzeigen",
"provider.connect.title": "{{provider}} verbinden",
"provider.connect.title.anthropicProMax": "Mit Claude Pro/Max anmelden",
"provider.connect.selectMethod": "Anmeldemethode für {{provider}} auswählen.",
"provider.connect.method.apiKey": "API-Schlüssel",
"provider.connect.method.browser": "Browser",
@@ -286,9 +284,7 @@ export const dict = {
"prompt.attachment.remove": "Anhang entfernen",
"prompt.action.send": "Senden",
"prompt.action.stop": "Stoppen",
"prompt.toast.pasteUnsupported.title": "Nicht unterstützter Anhang",
"prompt.toast.attachmentDuplicate.title": "Diese Datei wurde bereits hochgeladen",
"prompt.toast.pasteUnsupported.description": "Hier können nur Bilder, PDFs oder Textdateien angehängt werden.",
"prompt.toast.modelAgentRequired.title": "Wählen Sie einen Agenten und ein Modell",
"prompt.toast.modelAgentRequired.description":
"Wählen Sie einen Agenten und ein Modell, bevor Sie eine Eingabe senden.",
-5
View File
@@ -195,7 +195,6 @@ export const dict = {
"ކިއުރެޓް ކުރެވިފައިވާ މޮޑެލްތަކުގެ ތެރޭގައި Claude، GPT، Gemini އަދި އެހެނިހެން މޮޑެލްތައް ހިމެނެއެވެ",
"dialog.provider.opencode.tagline": "އިތުބާރު ހުރި އޮޕްޓިމައިޒްޑް މޮޑެލްތަކެވެ",
"dialog.provider.opencodeGo.tagline": "އެންމެންނަށް ކުޑަ އަގެއްގައި ސަބްސްކްރިޕްޝަން ދިނުމެވެ",
"dialog.provider.anthropic.note": "ޕްރޯ އަދި މެކްސް ހިމެނޭ ގޮތަށް Claude މޮޑެލްތަކަށް ސީދާ އެކްސެސް ލިބޭނެ އެވެ",
"dialog.provider.copilot.note": "GitHub Copilot މެދުވެރިކޮށް ކޯޑިންގ އެހީތެރިވުމަށް AI މޮޑެލްތައް",
"dialog.provider.openai.note": "އަވަސް، ގާބިލް އާންމު AI ޓާސްކްތަކަށް GPT މޮޑެލްތަކެވެ",
"dialog.provider.google.note": "އަވަސް، ސްޓްރަކްޗަރޑް ރެސްޕޮންސްތަކަށް Gemini މޮޑެލްތަކެވެ",
@@ -212,7 +211,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "އިތުރު 70+ ޕްރޮވައިޑަރުން ބައްލަވާށެވެ",
"dialog.provider.viewAll": "އިތުރު ޕްރޮވައިޑަރުން ދައްކާށެވެ",
"provider.connect.title": "{{provider}} ގުޅުވާށެވެ",
"provider.connect.title.anthropicProMax": "Claude ޕްރޯ/މެކްސް އިން ލޮގިން ވާނެއެވެ",
"provider.connect.selectMethod": "{{provider}} އަށް ލޮގިން މެތޯޑް ހޮވާށެވެ.",
"provider.connect.method.apiKey": "API ކީ އެވެ",
"provider.connect.method.browser": "ބްރައުޒާ އެވެ",
@@ -380,9 +378,6 @@ export const dict = {
"prompt.attachment.remove": "އެޓޭޗްމަންޓް ނަގާށެވެ",
"prompt.action.send": "ފޮނުވުން",
"prompt.action.stop": "ހުއްޓުން",
"prompt.toast.pasteUnsupported.title": "ސަޕޯޓް ނުކުރާ އެޓޭޗްމަންޓެވެ",
"prompt.toast.pasteUnsupported.description":
"މިތަނުގައި އެޓޭޗް ކުރެވޭނީ ހަމައެކަނި ތަސްވީރު، PDFs، ނުވަތަ ޓެކްސްޓް ފައިލްތަކެވެ.",
"prompt.toast.attachmentDuplicate.title": "މި ފައިލް މިހާރު ވަނީ އަޕްލޯޑްކޮށްފައެވެ",
"prompt.toast.modelAgentRequired.title": "އޭޖެންޓަކާއި މޮޑެލްއެއް ހޮވުން",
"prompt.toast.modelAgentRequired.description": "ޕްރޮމްޕްޓެއް ފޮނުވުމުގެ ކުރިން އޭޖެންޓަކާއި މޮޑެލްއެއް ހޮވުން.",
-5
View File
@@ -194,7 +194,6 @@ export const dict: Record<string, string> = {
"dialog.provider.opencode.note": "Claude དང་ GPT དེ་ལས་ Gemini དང་དེ་ལས་ལྷག་སྟེ་ བཀོད་སྒྲིག་འབད་ཡོད་པའི་དཔེ་ཚད།",
"dialog.provider.opencode.tagline": "བློ་གཏད་ཅན་གྱི་ཡར་རྒྱས་ཅན་གྱི་དཔེ་ཚད་ཚུ།",
"dialog.provider.opencodeGo.tagline": "མི་ཚང་མའི་དོན་ལུ་ གོང་ཚད་དམའ་བའི་ མཁོ་མངགས་འབད་ནི།",
"dialog.provider.anthropic.note": "པྲོ་དང་མེགསི་ཚུ་རྩིས་ཏེ་ Claudeདཔེ་ཚད་ཚུ་ལུ་ཐད་ཀར་དུ་འཛུལ་སྤྱོད།",
"dialog.provider.copilot.note": "GitHub Copilot བརྒྱུད་དེ་ ཀོ་ཌིང་གྲོགས་རམ་གྱི་དོན་ལུ་ AI དཔེ་ཚད།",
"dialog.provider.openai.note": "GPT མགྱོགས་དྲགས་དང་ལྕོགས་གྲུབ་ཅན་གྱི་སྤྱིར་བཏང་ཨེ་ཨའི་ལས་འགན་ཚུ་གི་དོན་ལུ་དཔེ་ཚད།",
"dialog.provider.google.note": "Gemini མགྱོགས་དྲགས་དང་སྒྲིག་བཀོད་ཅན་གྱི་ལན་འདེབས་ཀྱི་དཔེ་ཚད།",
@@ -212,7 +211,6 @@ export const dict: Record<string, string> = {
"dialog.model.unpaid.viewMoreProviders": "70+ མཁོ་སྤྲོད་འབད་མི་ཚུ་བལྟ།",
"dialog.provider.viewAll": "བྱིན་མི་མངམ་སྟོན།",
"provider.connect.title": "{{provider}}མཐུད།",
"provider.connect.title.anthropicProMax": "Claude Pro/Max དང་ཅིག་ཁར་ནང་བསྐྱོན།",
"provider.connect.selectMethod": "{{provider}}གི་དོན་ལུ་ ནང་བསྐྱོད་ཐབས་ལམ་སེལ་འཐུ་འབད།",
"provider.connect.method.apiKey": "APIལྡེ་མིག།",
"provider.connect.method.browser": "བརའུ་ཟར།",
@@ -379,9 +377,6 @@ export const dict: Record<string, string> = {
"prompt.attachment.remove": "མཉམ་སྦྲགས་རྩ་བསྐྲད་གཏང་།",
"prompt.action.send": "བཏང༌ནི",
"prompt.action.stop": "བཀག་པ",
"prompt.toast.pasteUnsupported.title": "རྒྱབ་སྐྱོར་མེད་པའི་མཉམ་སྦྲགས།",
"prompt.toast.pasteUnsupported.description":
"པར་རིས་དང་པི་ཌི་ཨེཕ་ ཡང་ན་ ཚིག་ཡིག་ཡིག་སྣོད་ཚུ་རྐྱངམ་ཅིག་ ནཱ་ལུ་མཉམ་སྦྲགས་འབད་བཏུབ།",
"prompt.toast.attachmentDuplicate.title": "ཡིག་སྣོད་འདི་ཧེ་མ་ལས་སྐྱེལ་བཙུགས་འབད་ཡི།",
"prompt.toast.modelAgentRequired.title": "ལས་ཚབ་དང་དཔེ་ཚད་ཅིག་སེལ་འཐུ་འབད།",
"prompt.toast.modelAgentRequired.description": "བརྡ་སྟོན་མ་གཏང་པའི་ཧེ་མ་ ལས་ཚབ་དང་དཔེ་ཚད་གདམ་ཁ་རྐྱབས།",
-4
View File
@@ -192,7 +192,6 @@ export const dict = {
"dialog.provider.opencode.note": "Επιμελημένα μοντέλα συμπεριλαμβανομένων των Claude, GPT, Gemini και άλλων",
"dialog.provider.opencode.tagline": "Αξιόπιστα βελτιστοποιημένα μοντέλα",
"dialog.provider.opencodeGo.tagline": "Συνδρομή χαμηλού κόστους για όλους",
"dialog.provider.anthropic.note": "Άμεση πρόσβαση σε Claude μοντέλα, συμπεριλαμβανομένων των Pro και Max",
"dialog.provider.copilot.note": "Μοντέλα AI για βοήθεια κωδικοποίησης μέσω GitHub Copilot",
"dialog.provider.openai.note": "GPT μοντέλα για γρήγορες, ικανές εργασίες γενικής τεχνητής νοημοσύνης",
"dialog.provider.google.note": "Gemini μοντέλα για γρήγορες, δομημένες απαντήσεις",
@@ -209,7 +208,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Δείτε 70+ ακόμη παρόχους",
"dialog.provider.viewAll": "Εμφάνιση περισσότερων παρόχων",
"provider.connect.title": "Σύνδεση {{provider}}",
"provider.connect.title.anthropicProMax": "Σύνδεση με Claude Pro/Max",
"provider.connect.selectMethod": "Επιλογή μεθόδου σύνδεσης για {{provider}}.",
"provider.connect.method.apiKey": "API κλειδί",
"provider.connect.method.browser": "Πρόγραμμα περιήγησης",
@@ -376,8 +374,6 @@ export const dict = {
"prompt.attachment.remove": "Κατάργηση συνημμένου",
"prompt.action.send": "Αποστολή",
"prompt.action.stop": "Διακοπή",
"prompt.toast.pasteUnsupported.title": "Μη υποστηριζόμενο συνημμένο",
"prompt.toast.pasteUnsupported.description": "Εδώ επισυνάπτονται μόνο εικόνες, αρχεία PDF ή αρχεία κειμένου.",
"prompt.toast.attachmentDuplicate.title": "Αυτό το αρχείο έχει ήδη μεταφορτωθεί",
"prompt.toast.modelAgentRequired.title": "Επιλέξτε έναν πράκτορα και μοντέλο",
"prompt.toast.modelAgentRequired.description":
+2 -4
View File
@@ -170,7 +170,7 @@ export const dict = {
"dialog.provider.opencode.note": "Curated models including Claude, GPT, Gemini and more",
"dialog.provider.opencode.tagline": "Reliable optimized models",
"dialog.provider.opencodeGo.tagline": "Low cost subscription for everyone",
"dialog.provider.anthropic.note": "Direct access to Claude models, including Pro and Max",
"dialog.provider.anthropic.note": "Direct access to Claude models via API key",
"dialog.provider.copilot.note": "AI models for coding assistance via GitHub Copilot",
"dialog.provider.openai.note": "GPT models for fast, capable general AI tasks",
"dialog.provider.google.note": "Gemini models for fast, structured responses",
@@ -191,7 +191,7 @@ export const dict = {
"dialog.provider.viewAll": "Show more providers",
"provider.connect.title": "Connect {{provider}}",
"provider.connect.title.anthropicProMax": "Login with Claude Pro/Max",
"provider.connect.title.anthropicProMax": "Login with Anthropic",
"provider.connect.selectMethod": "Select login method for {{provider}}.",
"provider.connect.method.apiKey": "API key",
"provider.connect.method.browser": "Browser",
@@ -365,8 +365,6 @@ export const dict = {
"prompt.action.send": "Send",
"prompt.action.stop": "Stop",
"prompt.toast.pasteUnsupported.title": "Unsupported attachment",
"prompt.toast.pasteUnsupported.description": "Only images, PDFs, or text files can be attached here.",
"prompt.toast.attachmentDuplicate.title": "This file has already been uploaded",
"prompt.toast.modelAgentRequired.title": "Select an agent and model",
"prompt.toast.modelAgentRequired.description": "Choose an agent and model before sending a prompt.",
-5
View File
@@ -208,7 +208,6 @@ export const dict = {
"dialog.provider.opencode.note": "Selección de modelos como Claude, GPT, Gemini y otros",
"dialog.provider.opencode.tagline": "Modelos optimizados y fiables",
"dialog.provider.opencodeGo.tagline": "Suscripción económica para todos",
"dialog.provider.anthropic.note": "Acceso directo a modelos Claude, incluidos Pro y Max",
"dialog.provider.copilot.note": "Modelos de IA para asistencia de codificación a través de GitHub Copilot",
"dialog.provider.openai.note": "Modelos GPT para tareas de IA generales rápidas y capaces",
"dialog.provider.google.note": "Modelos Gemini para respuestas rápidas y estructuradas",
@@ -229,7 +228,6 @@ export const dict = {
"dialog.provider.viewAll": "Ver más proveedores",
"provider.connect.title": "Conectar {{provider}}",
"provider.connect.title.anthropicProMax": "Iniciar sesión con Claude Pro/Max",
"provider.connect.selectMethod": "Seleccionar método de inicio de sesión para {{provider}}.",
"provider.connect.method.apiKey": "Clave API",
"provider.connect.method.browser": "Navegador",
@@ -403,10 +401,7 @@ export const dict = {
"prompt.action.send": "Enviar",
"prompt.action.stop": "Detener",
"prompt.toast.pasteUnsupported.title": "Adjunto no compatible",
"prompt.toast.attachmentDuplicate.title": "Este archivo ya se ha subido",
"prompt.toast.pasteUnsupported.description":
"Aquí solo se pueden adjuntar imágenes, archivos PDF o archivos de texto.",
"prompt.toast.modelAgentRequired.title": "Selecciona un agente y modelo",
"prompt.toast.modelAgentRequired.description": "Elige un agente y modelo antes de enviar un prompt.",
"prompt.toast.worktreeCreateFailed.title": "Fallo al crear el árbol de trabajo",
-4
View File
@@ -191,7 +191,6 @@ export const dict = {
"dialog.provider.opencode.note": "Kureeritud mudelid, sealhulgas Claude, GPT, Gemini ja palju muud",
"dialog.provider.opencode.tagline": "Usaldusväärsed optimeeritud mudelid",
"dialog.provider.opencodeGo.tagline": "Madala hinnaga tellimus kõigile",
"dialog.provider.anthropic.note": "Otsene juurdepääs Claude mudelile, sealhulgas Pro ja Max",
"dialog.provider.copilot.note": "AI mudelid kodeerimisabiks GitHub Copilot kaudu",
"dialog.provider.openai.note": "GPT mudelid kiirete ja võimekate üldiste AI-ülesannete jaoks",
"dialog.provider.google.note": "Gemini mudelid kiirete ja struktureeritud vastuste jaoks",
@@ -208,7 +207,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Vaadake veel 70+ pakkujat",
"dialog.provider.viewAll": "Kuva rohkem teenusepakkujaid",
"provider.connect.title": "Ühenda {{provider}}",
"provider.connect.title.anthropicProMax": "Logi sisse Claude Pro/Max",
"provider.connect.selectMethod": "Valige {{provider}} jaoks sisselogimisviis.",
"provider.connect.method.apiKey": "API klahv",
"provider.connect.method.browser": "Brauser",
@@ -374,8 +372,6 @@ export const dict = {
"prompt.attachment.remove": "Eemalda manus",
"prompt.action.send": "Saada",
"prompt.action.stop": "Peatus",
"prompt.toast.pasteUnsupported.title": "Toetamata manus",
"prompt.toast.pasteUnsupported.description": "Siia saab lisada ainult pilte, PDFs või tekstifaile.",
"prompt.toast.attachmentDuplicate.title": "See fail on juba üles laaditud",
"prompt.toast.modelAgentRequired.title": "Valige agent ja mudel",
"prompt.toast.modelAgentRequired.description": "Enne viipa saatmist valige agent ja mudel.",
-4
View File
@@ -192,7 +192,6 @@ export const dict = {
"dialog.provider.opencode.note": "مدل های انتخاب شده از جمله Claude، GPT، Gemini و موارد دیگر",
"dialog.provider.opencode.tagline": "مدل های بهینه شده قابل اعتماد",
"dialog.provider.opencodeGo.tagline": "اشتراک کم هزینه برای همه",
"dialog.provider.anthropic.note": "دسترسی مستقیم به مدل های Claude، از جمله Pro و Max",
"dialog.provider.copilot.note": "مدل های AI برای کمک به کدنویسی از طریق GitHub Copilot",
"dialog.provider.openai.note": "مدل های GPT برای کارهای عمومی سریع و با قابلیت AI",
"dialog.provider.google.note": "مدل های Gemini برای پاسخ های سریع و ساختاریافته",
@@ -209,7 +208,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "70+ ارائه‌دهنده دیگر را ببینید",
"dialog.provider.viewAll": "نمایش ارائه دهندگان بیشتر",
"provider.connect.title": "{{provider}} را وصل کنید",
"provider.connect.title.anthropicProMax": "با Claude Pro/Max وارد شوید",
"provider.connect.selectMethod": "روش ورود برای {{provider}} را انتخاب کنید.",
"provider.connect.method.apiKey": "کلید API",
"provider.connect.method.browser": "مرورگر",
@@ -375,8 +373,6 @@ export const dict = {
"prompt.attachment.remove": "حذف پیوست",
"prompt.action.send": "ارسال کنید",
"prompt.action.stop": "توقف کنید",
"prompt.toast.pasteUnsupported.title": "پیوست پشتیبانی نشده است",
"prompt.toast.pasteUnsupported.description": "فقط تصاویر، PDFs، یا فایل های متنی را می توان در اینجا پیوست کرد.",
"prompt.toast.attachmentDuplicate.title": "این فایل قبلا آپلود شده است",
"prompt.toast.modelAgentRequired.title": "یک عامل و مدل را انتخاب کنید",
"prompt.toast.modelAgentRequired.description": "قبل از ارسال درخواست، یک عامل و مدل را انتخاب کنید.",
-4
View File
@@ -99,7 +99,6 @@ export const dict = {
"dialog.provider.opencode.note": "Kuratoituja malleja, kuten Claude, GPT, Gemini ja muita",
"dialog.provider.opencode.tagline": "Luotettavat optimoidut mallit",
"dialog.provider.opencodeGo.tagline": "Edullinen tilaus kaikille",
"dialog.provider.anthropic.note": "Suora pääsy Claude-malleihin, mukaan lukien Pro ja Max",
"dialog.provider.copilot.note": "AI-malleja koodausapuun GitHub Copilotin kautta",
"dialog.provider.openai.note": "GPT-mallit nopeisiin, suorituskykyisiin yleisiin tekoälytehtäviin",
"dialog.provider.google.note": "Gemini-mallit nopeisiin, jäsenneltyihin vastauksiin",
@@ -116,7 +115,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Katso yli 70 muuta palveluntarjoajaa",
"dialog.provider.viewAll": "Näytä lisää palveluntarjoajia",
"provider.connect.title": "Yhdistä {{provider}}",
"provider.connect.title.anthropicProMax": "Kirjaudu sisään Claude Pro/Maxilla",
"provider.connect.selectMethod": "Valitse kirjautumistapa palvelulle {{provider}}.",
"provider.connect.method.apiKey": "API-avain",
"provider.connect.method.browser": "Selain",
@@ -282,8 +280,6 @@ export const dict = {
"prompt.attachment.remove": "Poista liite",
"prompt.action.send": "Lähetä",
"prompt.action.stop": "Pysäytä",
"prompt.toast.pasteUnsupported.title": "Liitettä ei tueta",
"prompt.toast.pasteUnsupported.description": "Vain kuvia, PDF-tiedostoja tai tekstitiedostoja voi liittää tähän.",
"prompt.toast.attachmentDuplicate.title": "Tämä tiedosto on jo ladattu",
"prompt.toast.modelAgentRequired.title": "Valitse agentti ja malli",
"prompt.toast.modelAgentRequired.description": "Valitse agentti ja malli ennen kehotteen lähettämistä.",
-4
View File
@@ -191,7 +191,6 @@ export const dict = {
"dialog.provider.opencode.note": "Kuraterað modell íroknað Claude, GPT, Gemini og fleiri",
"dialog.provider.opencode.tagline": "Álítandi optimerað modell",
"dialog.provider.opencodeGo.tagline": "Lágkostnaðarhald fyri øll",
"dialog.provider.anthropic.note": "Beinleiðis atgongd til Claude modellir, eisini Pro og Max .",
"dialog.provider.copilot.note": "AI modellir til koduhjálp umvegis GitHub Copilot",
"dialog.provider.openai.note": "GPT modellir til skjótar, førar almennar AI uppgávur",
"dialog.provider.google.note": "Gemini modellir til skjót, strukturerað svar",
@@ -208,7 +207,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Sí 70+ fleiri veitarar",
"dialog.provider.viewAll": "Vís fleiri veitarar",
"provider.connect.title": "Samband {{provider}}",
"provider.connect.title.anthropicProMax": "Rita inn við Claude Pro/Max",
"provider.connect.selectMethod": "Vel innritanarhátt til {{provider}}.",
"provider.connect.method.apiKey": "API lykil",
"provider.connect.method.browser": "Kagari",
@@ -374,8 +372,6 @@ export const dict = {
"prompt.attachment.remove": "Strika viðheftið",
"prompt.action.send": "Send",
"prompt.action.stop": "Steðga",
"prompt.toast.pasteUnsupported.title": "Óstuðlað viðhefti",
"prompt.toast.pasteUnsupported.description": "Bert myndir, PDFs, ella tekstfílur kunnu viðheftast her.",
"prompt.toast.attachmentDuplicate.title": "Hendan fílan er longu løgd upp.",
"prompt.toast.modelAgentRequired.title": "Vel agent og modell",
"prompt.toast.modelAgentRequired.description": "Vel agent og modell, áðrenn tú sendir ein prompt.",
-5
View File
@@ -200,7 +200,6 @@ export const dict = {
"dialog.provider.opencode.note": "Modèles sélectionnés incluant Claude, GPT, Gemini et plus",
"dialog.provider.opencode.tagline": "Modèles optimisés et fiables",
"dialog.provider.opencodeGo.tagline": "Abonnement abordable pour tous",
"dialog.provider.anthropic.note": "Connectez-vous avec Claude Pro/Max ou une clé API",
"dialog.provider.copilot.note": "Connectez-vous avec Copilot ou une clé API",
"dialog.provider.openai.note": "Connectez-vous avec ChatGPT Pro/Plus ou une clé API",
"dialog.provider.google.note": "Modèles Gemini pour des réponses rapides et structurées",
@@ -217,7 +216,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Voir plus de 70 autres fournisseurs",
"dialog.provider.viewAll": "Voir plus de fournisseurs",
"provider.connect.title": "Connecter {{provider}}",
"provider.connect.title.anthropicProMax": "Connexion avec Claude Pro/Max",
"provider.connect.selectMethod": "Sélectionnez la méthode de connexion pour {{provider}}.",
"provider.connect.method.apiKey": "Clé API",
"provider.connect.method.browser": "Navigateur",
@@ -385,10 +383,7 @@ export const dict = {
"prompt.attachment.remove": "Supprimer la pièce jointe",
"prompt.action.send": "Envoyer",
"prompt.action.stop": "Arrêter",
"prompt.toast.pasteUnsupported.title": "Pièce jointe non prise en charge",
"prompt.toast.attachmentDuplicate.title": "Ce fichier a déjà été téléversé",
"prompt.toast.pasteUnsupported.description":
"Seules les images, les PDF ou les fichiers texte peuvent être joints ici.",
"prompt.toast.modelAgentRequired.title": "Sélectionnez un agent et un modèle",
"prompt.toast.modelAgentRequired.description": "Choisissez un agent et un modèle avant d'envoyer une invite.",
"prompt.toast.worktreeCreateFailed.title": "Échec de la création de l'arbre de travail",
-4
View File
@@ -192,7 +192,6 @@ export const dict = {
"dialog.provider.opencode.note": "מבחר מודלים, בהם Claude, GPT, Gemini ועוד",
"dialog.provider.opencode.tagline": "מודלים אמינים שעברו אופטימיזציה",
"dialog.provider.opencodeGo.tagline": "מנוי בעלות נמוכה לכולם",
"dialog.provider.anthropic.note": "גישה ישירה למודלי Claude, כולל Pro ו-Max",
"dialog.provider.copilot.note": "מודלי AI לסיוע בכתיבת קוד באמצעות GitHub Copilot",
"dialog.provider.openai.note": "מודלי GPT למשימות AI כלליות, מהירות ומתקדמות",
"dialog.provider.google.note": "מודלי Gemini לתגובות מהירות ומובנות",
@@ -209,7 +208,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "הצגת יותר מ-70 ספקים נוספים",
"dialog.provider.viewAll": "הצג עוד ספקים",
"provider.connect.title": "חבר את {{provider}}",
"provider.connect.title.anthropicProMax": "התחבר עם Claude Pro/Max",
"provider.connect.selectMethod": "בחר שיטת התחברות עבור {{provider}}.",
"provider.connect.method.apiKey": "מפתח API",
"provider.connect.method.browser": "דפדפן",
@@ -373,8 +371,6 @@ export const dict = {
"prompt.attachment.remove": "הסר את הקובץ המצורף",
"prompt.action.send": "שלח",
"prompt.action.stop": "עצור",
"prompt.toast.pasteUnsupported.title": "קובץ מצורף לא נתמך",
"prompt.toast.pasteUnsupported.description": "ניתן לצרף כאן רק תמונות, קובצי PDF או קבצי טקסט.",
"prompt.toast.attachmentDuplicate.title": "הקובץ הזה כבר הועלה",
"prompt.toast.modelAgentRequired.title": "בחר סוכן ומודל",
"prompt.toast.modelAgentRequired.description": "יש לבחור סוכן ומודל לפני שליחת פרומפט.",
-4
View File
@@ -199,7 +199,6 @@ export const dict = {
"dialog.provider.opencode.note": "Claude, GPT, Gemini और अधिक सहित क्यूरेटेड मॉडल",
"dialog.provider.opencode.tagline": "विश्वसनीय अनुकूलित मॉडल",
"dialog.provider.opencodeGo.tagline": "सभी के लिए कम लागत वाली सदस्यता",
"dialog.provider.anthropic.note": "प्रो और मैक्स सहित Claude मॉडल तक सीधी पहुँच",
"dialog.provider.copilot.note": "GitHub Copilot के माध्यम से कोडिंग सहायता के लिए AI मॉडल",
"dialog.provider.openai.note": "तेज़, सक्षम सामान्य AI कार्यों के लिए GPT मॉडल",
"dialog.provider.google.note": "तेज़, संरचित प्रतिक्रियाओं के लिए Gemini मॉडल",
@@ -216,7 +215,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "70+ अधिक प्रोवाइडर देखें",
"dialog.provider.viewAll": "और प्रोवाइडर दिखाएँ",
"provider.connect.title": "{{provider}} कनेक्ट करें",
"provider.connect.title.anthropicProMax": "Claude प्रो/मैक्स के साथ लॉगिन करें",
"provider.connect.selectMethod": "{{provider}} के लिए लॉगिन विधि चुनें।",
"provider.connect.method.apiKey": "API कुंजी",
"provider.connect.method.browser": "ब्राउज़र",
@@ -382,8 +380,6 @@ export const dict = {
"prompt.attachment.remove": "अनुलग्नक हटाएँ",
"prompt.action.send": "भेजें",
"prompt.action.stop": "रोकें",
"prompt.toast.pasteUnsupported.title": "असमर्थित अनुलग्नक",
"prompt.toast.pasteUnsupported.description": "यहां केवल छवियां, PDFs, या टेक्स्ट फ़ाइलें संलग्न की जा सकती हैं।",
"prompt.toast.attachmentDuplicate.title": "यह फ़ाइल पहले ही अपलोड की जा चुकी है",
"prompt.toast.modelAgentRequired.title": "एक एजेंट और मॉडल चुनें",
"prompt.toast.modelAgentRequired.description": "प्रॉम्प्ट भेजने से पहले एक एजेंट और मॉडल चुनें।",
-4
View File
@@ -195,7 +195,6 @@ export const dict = {
"dialog.provider.opencode.note": "Odabrani modeli uključujući Claude, GPT, Gemini i druge",
"dialog.provider.opencode.tagline": "Pouzdani optimizirani modeli",
"dialog.provider.opencodeGo.tagline": "Niska cijena pretplate za sve",
"dialog.provider.anthropic.note": "Izravan pristup Claude modelima, uključujući Pro i Max",
"dialog.provider.copilot.note": "AI modeli za pomoć kodiranja putem GitHub Copilot",
"dialog.provider.openai.note": "GPT modeli za brze, sposobne opće AI zadatke",
"dialog.provider.google.note": "Gemini modeli za brze, strukturirane odgovore",
@@ -212,7 +211,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Pogledajte više od 70 pružatelja usluga",
"dialog.provider.viewAll": "Prikaži više pružatelja usluga",
"provider.connect.title": "Povežite {{provider}}",
"provider.connect.title.anthropicProMax": "Prijavite se sa Claude Pro/Max",
"provider.connect.selectMethod": "Odaberite način prijave za {{provider}}.",
"provider.connect.method.apiKey": "Ključ API",
"provider.connect.method.browser": "preglednik",
@@ -379,8 +377,6 @@ export const dict = {
"prompt.attachment.remove": "Ukloni privitak",
"prompt.action.send": "Poslati",
"prompt.action.stop": "Zaustavi",
"prompt.toast.pasteUnsupported.title": "Nepodržani privitak",
"prompt.toast.pasteUnsupported.description": "Ovdje se mogu priložiti samo slike, PDF-ovi ili tekstualne datoteke.",
"prompt.toast.attachmentDuplicate.title": "Ova datoteka je već učitana",
"prompt.toast.modelAgentRequired.title": "Odaberite agenta i model",
"prompt.toast.modelAgentRequired.description": "Odaberite agenta i model prije slanja upita.",
-4
View File
@@ -195,7 +195,6 @@ export const dict = {
"dialog.provider.opencode.note": "Összeválogatott modellek, köztük Claude, GPT, Gemini és még sok más",
"dialog.provider.opencode.tagline": "Megbízható optimalizált modellek",
"dialog.provider.opencodeGo.tagline": "Olcsó előfizetés mindenki számára",
"dialog.provider.anthropic.note": "Közvetlen hozzáférés a Claude modellekhez, beleértve a Pro és Max modelleket",
"dialog.provider.copilot.note": "AI modellek a kódoláshoz a GitHub Copilot segítségével",
"dialog.provider.openai.note": "GPT modellek a gyors, általános AI-feladatokhoz",
"dialog.provider.google.note": "Gemini modellek a gyors, strukturált válaszokhoz",
@@ -212,7 +211,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "További 70+ szolgáltató megtekintése",
"dialog.provider.viewAll": "További szolgáltatók megjelenítése",
"provider.connect.title": "Csatlakoztassa a {{provider}}-t",
"provider.connect.title.anthropicProMax": "Jelentkezzen be a Claude Pro/Max",
"provider.connect.selectMethod": "Válassza ki a {{provider}} bejelentkezési módját.",
"provider.connect.method.apiKey": "API kulcs",
"provider.connect.method.browser": "Böngésző",
@@ -379,8 +377,6 @@ export const dict = {
"prompt.attachment.remove": "Távolítsa el a mellékletet",
"prompt.action.send": "Elküld",
"prompt.action.stop": "Leállítás",
"prompt.toast.pasteUnsupported.title": "Nem támogatott melléklet",
"prompt.toast.pasteUnsupported.description": "Ide csak képeket, PDF-eket vagy szöveges fájlokat lehet csatolni.",
"prompt.toast.attachmentDuplicate.title": "Ezt a fájlt már feltöltötték",
"prompt.toast.modelAgentRequired.title": "Válasszon egy ügynököt és modellt",
"prompt.toast.modelAgentRequired.description": "A felszólítás elküldése előtt válasszon ügynököt és modellt.",
-4
View File
@@ -193,7 +193,6 @@ export const dict = {
"dialog.provider.opencode.note": "Ընտրված մոդելներ, ներառյալ՝ Claude, GPT, Gemini և ավելին",
"dialog.provider.opencode.tagline": "Վստահելի օպտիմիզացված մոդելներ",
"dialog.provider.opencodeGo.tagline": "Ցածր գնով բաժանորդագրություն բոլորի համար",
"dialog.provider.anthropic.note": "Ուղիղ մուտք դեպի Claude մոդելներ, ներառյալ Pro և Max",
"dialog.provider.copilot.note": "AI մոդելներ կոդավորման օգնության համար՝ GitHub Copilot",
"dialog.provider.openai.note": "GPT մոդելներ արագ, ունակ ընդհանուր AI առաջադրանքների համար",
"dialog.provider.google.note": "Gemini մոդելներ արագ, կառուցվածքային պատասխանների համար",
@@ -210,7 +209,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Տես 70+ այլ մատակարարներ",
"dialog.provider.viewAll": "Ցույց տալ ավելի շատ մատակարարներ",
"provider.connect.title": "Միացեք {{provider}}",
"provider.connect.title.anthropicProMax": "Մուտք գործեք Claude Pro/Max-ով",
"provider.connect.selectMethod": "Ընտրեք մուտքի եղանակը {{provider}}-ի համար։",
"provider.connect.method.apiKey": "API բանալի",
"provider.connect.method.browser": "Դիտարկիչ",
@@ -377,8 +375,6 @@ export const dict = {
"prompt.attachment.remove": "Հեռացնել հավելվածը",
"prompt.action.send": "Ուղարկել",
"prompt.action.stop": "Կանգնեցնել",
"prompt.toast.pasteUnsupported.title": "Չաջակցվող հավելված",
"prompt.toast.pasteUnsupported.description": "Այստեղ կարող են կցվել միայն պատկերներ, PDF կամ տեքստային ֆայլեր։",
"prompt.toast.attachmentDuplicate.title": "Այս ֆայլն արդեն վերբեռնվել է",
"prompt.toast.modelAgentRequired.title": "Ընտրեք գործակալ և մոդել",
"prompt.toast.modelAgentRequired.description": "Ընտրեք գործակալ և մոդել՝ նախքան հուշում ուղարկելը։",
-4
View File
@@ -208,7 +208,6 @@ export const dict = {
"dialog.provider.opencode.note": "Model pilihan, termasuk Claude, GPT, Gemini, dan lainnya",
"dialog.provider.opencode.tagline": "Model andal yang dioptimalkan",
"dialog.provider.opencodeGo.tagline": "Langganan terjangkau untuk semua orang",
"dialog.provider.anthropic.note": "Akses langsung ke model Claude, termasuk Pro dan Max",
"dialog.provider.copilot.note": "Model AI untuk bantuan pengodean melalui GitHub Copilot",
"dialog.provider.openai.note": "Model GPT untuk tugas AI umum yang cepat dan mumpuni",
"dialog.provider.google.note": "Model Gemini untuk respons cepat dan terstruktur",
@@ -229,7 +228,6 @@ export const dict = {
"dialog.provider.viewAll": "Tampilkan lebih banyak penyedia",
"provider.connect.title": "Hubungkan {{provider}}",
"provider.connect.title.anthropicProMax": "Masuk dengan Claude Pro/Max",
"provider.connect.selectMethod": "Pilih metode masuk untuk {{provider}}.",
"provider.connect.method.apiKey": "Kunci API",
"provider.connect.method.browser": "Peramban",
@@ -403,8 +401,6 @@ export const dict = {
"prompt.action.send": "Kirim",
"prompt.action.stop": "Hentikan",
"prompt.toast.pasteUnsupported.title": "Lampiran tidak didukung",
"prompt.toast.pasteUnsupported.description": "Hanya gambar, PDF, atau berkas teks yang dapat dilampirkan di sini.",
"prompt.toast.attachmentDuplicate.title": "Berkas ini sudah diunggah",
"prompt.toast.modelAgentRequired.title": "Pilih agen dan model",
"prompt.toast.modelAgentRequired.description": "Pilih agen dan model sebelum mengirim prompt.",
-4
View File
@@ -195,7 +195,6 @@ export const dict = {
"dialog.provider.opencode.note": "Sýndar gerðir þar á meðal Claude, GPT, Gemini og fleira",
"dialog.provider.opencode.tagline": "Áreiðanleg bjartsýni módel",
"dialog.provider.opencodeGo.tagline": "Lággjaldaáskrift fyrir alla",
"dialog.provider.anthropic.note": "Beinn aðgangur að Claude gerðum, þar á meðal Pro og Max",
"dialog.provider.copilot.note": "AI módel fyrir kóðaaðstoð í gegnum GitHub Copilot",
"dialog.provider.openai.note": "GPT gerðir fyrir hröð, fær almenn gervigreind verkefni",
"dialog.provider.google.note": "Gemini módel fyrir hröð, skipulögð viðbrögð",
@@ -212,7 +211,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Sjáðu 70+ þjónustuveitendur í viðbót",
"dialog.provider.viewAll": "Sýna fleiri veitendur",
"provider.connect.title": "Tengdu {{provider}}",
"provider.connect.title.anthropicProMax": "Skráðu þig inn með Claude Pro/Max",
"provider.connect.selectMethod": "Veldu innskráningaraðferð fyrir {{provider}}.",
"provider.connect.method.apiKey": "API lykill",
"provider.connect.method.browser": "Vafri",
@@ -379,8 +377,6 @@ export const dict = {
"prompt.attachment.remove": "Fjarlægðu viðhengi",
"prompt.action.send": "Senda",
"prompt.action.stop": "Stöðva",
"prompt.toast.pasteUnsupported.title": "Óstudd viðhengi",
"prompt.toast.pasteUnsupported.description": "Aðeins er hægt að hengja myndir, PDF-skjöl eða textaskrár hér við.",
"prompt.toast.attachmentDuplicate.title": "Þessari skrá hefur þegar verið hlaðið upp",
"prompt.toast.modelAgentRequired.title": "Veldu fulltrúa og líkan",
"prompt.toast.modelAgentRequired.description": "Veldu fulltrúa og líkan áður en þú sendir kvaðningu.",
-4
View File
@@ -100,7 +100,6 @@ export const dict = {
"dialog.provider.opencode.note": "Modelli selezionati tra cui Claude, GPT, Gemini e altri",
"dialog.provider.opencode.tagline": "Modelli affidabili e ottimizzati",
"dialog.provider.opencodeGo.tagline": "Abbonamento economico per tutti",
"dialog.provider.anthropic.note": "Accesso diretto ai modelli Claude, inclusi Pro e Max",
"dialog.provider.copilot.note": "Modelli di IA per assistere nella programmazione tramite GitHub Copilot",
"dialog.provider.openai.note": "Modelli GPT veloci e potenti per attività generiche di IA",
"dialog.provider.google.note": "Modelli Gemini per risposte rapide e strutturate",
@@ -117,7 +116,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Scopri oltre 70 provider",
"dialog.provider.viewAll": "Mostra altri provider",
"provider.connect.title": "Connetti {{provider}}",
"provider.connect.title.anthropicProMax": "Accedi con Claude Pro/Max",
"provider.connect.selectMethod": "Seleziona il metodo di accesso per {{provider}}.",
"provider.connect.method.apiKey": "Chiave API",
"provider.connect.method.browser": "Browser",
@@ -284,8 +282,6 @@ export const dict = {
"prompt.attachment.remove": "Rimuovi l'allegato",
"prompt.action.send": "Invia",
"prompt.action.stop": "Interrompi",
"prompt.toast.pasteUnsupported.title": "Allegato non supportato",
"prompt.toast.pasteUnsupported.description": "Qui è possibile allegare solo immagini, PDF o file di testo.",
"prompt.toast.attachmentDuplicate.title": "Questo file è già stato caricato",
"prompt.toast.modelAgentRequired.title": "Seleziona un agente e un modello",
"prompt.toast.modelAgentRequired.description": "Scegli un agente e un modello prima di inviare un prompt.",
-4
View File
@@ -198,7 +198,6 @@ export const dict = {
"dialog.provider.opencode.note": "Claude, GPT, Geminiなどを含む厳選されたモデル",
"dialog.provider.opencode.tagline": "信頼性の高い最適化モデル",
"dialog.provider.opencodeGo.tagline": "すべての人に低価格のサブスクリプション",
"dialog.provider.anthropic.note": "ProやMaxを含むClaudeモデルに直接アクセス",
"dialog.provider.copilot.note": "GitHub Copilotを通じてコーディングを支援するAIモデル",
"dialog.provider.openai.note": "高速で高性能な汎用AIタスク向けのGPTモデル",
"dialog.provider.google.note": "高速で構造化された応答のためのGeminiモデル",
@@ -215,7 +214,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "その他70以上のプロバイダーを見る",
"dialog.provider.viewAll": "さらにプロバイダーを表示",
"provider.connect.title": "{{provider}}を接続",
"provider.connect.title.anthropicProMax": "Claude Pro/Maxでログイン",
"provider.connect.selectMethod": "{{provider}}のログイン方法を選択してください。",
"provider.connect.method.apiKey": "APIキー",
"provider.connect.method.browser": "ブラウザ",
@@ -379,9 +377,7 @@ export const dict = {
"prompt.attachment.remove": "添付ファイルを削除",
"prompt.action.send": "送信",
"prompt.action.stop": "停止",
"prompt.toast.pasteUnsupported.title": "サポートされていない添付ファイル",
"prompt.toast.attachmentDuplicate.title": "このファイルはすでにアップロードされています",
"prompt.toast.pasteUnsupported.description": "画像、PDF、またはテキストファイルのみ添付できます。",
"prompt.toast.modelAgentRequired.title": "エージェントとモデルを選択",
"prompt.toast.modelAgentRequired.description": "プロンプトを送信する前にエージェントとモデルを選択してください。",
"prompt.toast.worktreeCreateFailed.title": "ワークツリーの作成に失敗しました",
-4
View File
@@ -191,7 +191,6 @@ export const dict = {
"dialog.provider.opencode.note": "კურირებული მოდელები, მათ შორის Claude, GPT, Gemini და სხვა",
"dialog.provider.opencode.tagline": "სანდო ოპტიმიზებული მოდელები",
"dialog.provider.opencodeGo.tagline": "დაბალფასიანი გამოწერა ყველასთვის",
"dialog.provider.anthropic.note": "პირდაპირი წვდომა Claude მოდელზე, მათ შორის Pro და Max",
"dialog.provider.copilot.note": "AI მოდელები კოდირების დახმარებისთვის GitHub Copilot",
"dialog.provider.openai.note": "GPT მოდელები სწრაფი, ზოგადი AI ამოცანების შესასრულებლად",
"dialog.provider.google.note": "Gemini მოდელები სწრაფი, სტრუქტურირებული პასუხებისთვის",
@@ -208,7 +207,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "იხილეთ 70+ სხვა პროვაიდერი",
"dialog.provider.viewAll": "აჩვენე მეტი პროვაიდერი",
"provider.connect.title": "დაკავშირება {{provider}}",
"provider.connect.title.anthropicProMax": "შესვლა Claude Pro/Max-ით",
"provider.connect.selectMethod": "აირჩიეთ შესვლის მეთოდი {{provider}}-ისთვის.",
"provider.connect.method.apiKey": "API გასაღები",
"provider.connect.method.browser": "ბრაუზერი",
@@ -375,8 +373,6 @@ export const dict = {
"prompt.attachment.remove": "დანართის წაშლა",
"prompt.action.send": "გაგზავნა",
"prompt.action.stop": "შეჩერება",
"prompt.toast.pasteUnsupported.title": "მხარდაუჭერელი დანართი",
"prompt.toast.pasteUnsupported.description": "აქ შეიძლება დაერთოს მხოლოდ სურათები, PDF ან ტექსტური ფაილები.",
"prompt.toast.attachmentDuplicate.title": "ეს ფაილი უკვე ატვირთულია",
"prompt.toast.modelAgentRequired.title": "აირჩიეთ აგენტი და მოდელი",
"prompt.toast.modelAgentRequired.description": "აირჩიეთ აგენტი და მოდელი მოთხოვნის გაგზავნამდე.",
-4
View File
@@ -191,7 +191,6 @@ export const dict = {
"dialog.provider.opencode.note": "ម៉ូដែលដែលបានជ្រើសរើសរួមមាន Claude, GPT, Gemini និងច្រើនទៀត",
"dialog.provider.opencode.tagline": "ម៉ូដែលដែលបានកែលម្អដែលអាចទុកចិត្តបាន។",
"dialog.provider.opencodeGo.tagline": "ការជាវតម្លៃទាបសម្រាប់អ្នករាល់គ្នា",
"dialog.provider.anthropic.note": "ការចូលប្រើដោយផ្ទាល់ទៅកាន់ម៉ូដែល Claude រួមទាំង Pro និង Max",
"dialog.provider.copilot.note": "ម៉ូដែល AI សម្រាប់ជំនួយការសរសេរកូដតាមរយៈ GitHub Copilot",
"dialog.provider.openai.note": "ម៉ូដែល GPT សម្រាប់កិច្ចការ AI ទូទៅដែលមានល្បឿនលឿន និងមានសមត្ថភាព",
"dialog.provider.google.note": "ម៉ូដែល Gemini សម្រាប់ការឆ្លើយតបរហ័ស និងមានរចនាសម្ព័ន្ធ",
@@ -208,7 +207,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "មើលអ្នកផ្តល់សេវា 70+ ទៀត។",
"dialog.provider.viewAll": "បង្ហាញអ្នកផ្តល់សេវាបន្ថែម",
"provider.connect.title": "ភ្ជាប់ {{provider}}",
"provider.connect.title.anthropicProMax": "ចូលដោយប្រើ Claude Pro/Max",
"provider.connect.selectMethod": "ជ្រើសរើសវិធីសាស្ត្រចូលសម្រាប់ {{provider}} ។",
"provider.connect.method.apiKey": "សោ API",
"provider.connect.method.browser": "កម្មវិធីរុករក",
@@ -374,8 +372,6 @@ export const dict = {
"prompt.attachment.remove": "លុបឯកសារភ្ជាប់ចេញ",
"prompt.action.send": "ផ្ញើ",
"prompt.action.stop": "ឈប់",
"prompt.toast.pasteUnsupported.title": "ឯកសារភ្ជាប់ដែលមិនគាំទ្រ",
"prompt.toast.pasteUnsupported.description": "មានតែរូបភាព PDF ឬឯកសារអត្ថបទប៉ុណ្ណោះដែលអាចភ្ជាប់មកទីនេះបាន។",
"prompt.toast.attachmentDuplicate.title": "ឯកសារនេះត្រូវបានផ្ទុកឡើងរួចហើយ",
"prompt.toast.modelAgentRequired.title": "ជ្រើសរើសភ្នាក់ងារ និងម៉ូដែល",
"prompt.toast.modelAgentRequired.description": "ជ្រើសរើសភ្នាក់ងារ និងម៉ូដែលមុនពេលផ្ញើប្រអប់បញ្ចូល។",
-4
View File
@@ -95,7 +95,6 @@ export const dict = {
"dialog.provider.opencode.note": "Claude, GPT, Gemini 등을 포함한 엄선된 모델",
"dialog.provider.opencode.tagline": "신뢰할 수 있는 최적화 모델",
"dialog.provider.opencodeGo.tagline": "모두를 위한 저렴한 구독",
"dialog.provider.anthropic.note": "Pro 및 Max를 포함한 Claude 모델에 직접 액세스",
"dialog.provider.copilot.note": "GitHub Copilot을 통한 코딩 지원용 AI 모델",
"dialog.provider.openai.note": "빠르고 강력한 범용 AI 작업을 위한 GPT 모델",
"dialog.provider.google.note": "빠르고 구조화된 응답을 위한 Gemini 모델",
@@ -112,7 +111,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "70개 이상의 공급자 더 보기",
"dialog.provider.viewAll": "더 많은 공급자 보기",
"provider.connect.title": "{{provider}} 연결",
"provider.connect.title.anthropicProMax": "Claude Pro/Max로 로그인",
"provider.connect.selectMethod": "{{provider}} 로그인 방법 선택",
"provider.connect.method.apiKey": "API 키",
"provider.connect.method.browser": "브라우저",
@@ -268,9 +266,7 @@ export const dict = {
"prompt.attachment.remove": "첨부 파일 제거",
"prompt.action.send": "전송",
"prompt.action.stop": "중지",
"prompt.toast.pasteUnsupported.title": "지원되지 않는 첨부 파일",
"prompt.toast.attachmentDuplicate.title": "이 파일은 이미 업로드되었습니다",
"prompt.toast.pasteUnsupported.description": "이미지, PDF 또는 텍스트 파일만 첨부할 수 있습니다.",
"prompt.toast.modelAgentRequired.title": "에이전트 및 모델 선택",
"prompt.toast.modelAgentRequired.description": "프롬프트를 보내기 전에 에이전트와 모델을 선택하세요.",
"prompt.toast.worktreeCreateFailed.title": "작업 트리 생성 실패",
-4
View File
@@ -191,7 +191,6 @@ export const dict = {
"dialog.provider.opencode.note": "ແບບທີ່ຄັດສັນມາລວມທັງ Claude, GPT, Gemini ແລະອື່ນໆ",
"dialog.provider.opencode.tagline": "ຮູບແບບການເພີ່ມປະສິດທິພາບທີ່ເຊື່ອຖືໄດ້",
"dialog.provider.opencodeGo.tagline": "ການສະໝັກໃຊ້ລາຄາຕໍ່າສຳລັບທຸກຄົນ",
"dialog.provider.anthropic.note": "ເຂົ້າເຖິງຕົວແບບ Claude ໂດຍກົງ, ລວມທັງ Pro ແລະ Max",
"dialog.provider.copilot.note": "ຮູບແບບ AI ສໍາລັບການຊ່ວຍເຫຼືອການເຂົ້າລະຫັດຜ່ານ GitHub Copilot",
"dialog.provider.openai.note": "ແບບ GPT ສໍາລັບວຽກງານ AI ທົ່ວໄປທີ່ໄວ, ມີຄວາມສາມາດ",
"dialog.provider.google.note": "ແບບ Gemini ສໍາລັບການຕອບສະຫນອງໄວ, ມີໂຄງສ້າງ",
@@ -208,7 +207,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "ເບິ່ງ 70+ ຜູ້ໃຫ້ບໍລິການເພີ່ມເຕີມ",
"dialog.provider.viewAll": "ສະແດງຜູ້ໃຫ້ບໍລິການເພີ່ມເຕີມ",
"provider.connect.title": "ເຊື່ອມຕໍ່ {{provider}}",
"provider.connect.title.anthropicProMax": "ເຂົ້າສູ່ລະບົບດ້ວຍ Claude Pro/Max",
"provider.connect.selectMethod": "ເລືອກວິທີການເຂົ້າສູ່ລະບົບສໍາລັບ {{provider}}.",
"provider.connect.method.apiKey": "ລະຫັດ API",
"provider.connect.method.browser": "ຕົວທ່ອງເວັບ",
@@ -374,8 +372,6 @@ export const dict = {
"prompt.attachment.remove": "ເອົາໄຟລ໌ແນບອອກ",
"prompt.action.send": "ສົ່ງ",
"prompt.action.stop": "ຢຸດ",
"prompt.toast.pasteUnsupported.title": "ບໍ່ຮອງຮັບໄຟລ໌ແນບ",
"prompt.toast.pasteUnsupported.description": "ພຽງແຕ່ຮູບພາບ, PDFs, ຫຼືໄຟລ໌ຂໍ້ຄວາມສາມາດຕິດຢູ່ນີ້.",
"prompt.toast.attachmentDuplicate.title": "ໄຟລ໌ນີ້ໄດ້ຖືກອັບໂຫລດໄປກ່ອນແລ້ວ",
"prompt.toast.modelAgentRequired.title": "ເລືອກຕົວແທນ ແລະຕົວແບບ",
"prompt.toast.modelAgentRequired.description": "ເລືອກຕົວແທນ ແລະຕົວແບບກ່ອນສົ່ງ prompt.",
-4
View File
@@ -195,7 +195,6 @@ export const dict = {
"dialog.provider.opencode.note": "Kuruojami modeliai, įskaitant Claude, GPT, Gemini ir kt.",
"dialog.provider.opencode.tagline": "Patikimi optimizuoti modeliai",
"dialog.provider.opencodeGo.tagline": "Mažos kainos abonementas visiems",
"dialog.provider.anthropic.note": "Tiesioginė prieiga prie Claude modelių, įskaitant Pro ir Max",
"dialog.provider.copilot.note": "AI modeliai, skirti kodavimo pagalbai per GitHub Copilot",
"dialog.provider.openai.note": "GPT modeliai, skirti greitoms, bendroms AI užduotims atlikti",
"dialog.provider.google.note": "Gemini modeliai greitiems, struktūriniams atsakymams",
@@ -212,7 +211,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Žr. daugiau nei 70 tiekėjų",
"dialog.provider.viewAll": "Rodyti daugiau teikėjų",
"provider.connect.title": "Prijunkite {{provider}}",
"provider.connect.title.anthropicProMax": "Prisijunkite naudodami Claude Pro/Max",
"provider.connect.selectMethod": "Pasirinkite {{provider}} prisijungimo būdą.",
"provider.connect.method.apiKey": "API raktas",
"provider.connect.method.browser": "Naršyklė",
@@ -380,8 +378,6 @@ export const dict = {
"prompt.attachment.remove": "Pašalinti priedą",
"prompt.action.send": "Siųsti",
"prompt.action.stop": "Stabdyti",
"prompt.toast.pasteUnsupported.title": "Nepalaikomas priedas",
"prompt.toast.pasteUnsupported.description": "Čia galima pridėti tik vaizdus, PDF arba tekstinius failus.",
"prompt.toast.attachmentDuplicate.title": "Šis failas jau buvo įkeltas",
"prompt.toast.modelAgentRequired.title": "Pasirinkite agentą ir modelį",
"prompt.toast.modelAgentRequired.description": "Prieš siųsdami raginimą, pasirinkite agentą ir modelį.",
-4
View File
@@ -191,7 +191,6 @@ export const dict = {
"dialog.provider.opencode.note": "Atlasīti modeļi, tostarp Claude, GPT, Gemini un citi",
"dialog.provider.opencode.tagline": "Uzticami optimizēti modeļi",
"dialog.provider.opencodeGo.tagline": "Zemas cenas abonements visiem",
"dialog.provider.anthropic.note": "Tieša piekļuve Claude modeļiem, tostarp Pro un Max",
"dialog.provider.copilot.note": "AI modeļi programmēšanas atbalstam ar GitHub Copilot",
"dialog.provider.openai.note": "GPT modeļi ātriem, spējīgiem vispārējiem AI uzdevumiem",
"dialog.provider.google.note": "Gemini modeļi ātrām, strukturētām atbildēm",
@@ -208,7 +207,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Skatīt vēl 70+ nodrošinātājus",
"dialog.provider.viewAll": "Rādīt vairāk nodrošinātāju",
"provider.connect.title": "Savienot {{provider}}",
"provider.connect.title.anthropicProMax": "Pieteikties ar Claude Pro/Max",
"provider.connect.selectMethod": "Izvēlieties pieteikšanās metodi pakalpojumam {{provider}}.",
"provider.connect.method.apiKey": "API atslēga",
"provider.connect.method.browser": "Pārlūks",
@@ -375,8 +373,6 @@ export const dict = {
"prompt.attachment.remove": "Noņemt pielikumu",
"prompt.action.send": "Sūtīt",
"prompt.action.stop": "Apturēt",
"prompt.toast.pasteUnsupported.title": "Neatbalstīts pielikums",
"prompt.toast.pasteUnsupported.description": "Šeit var pievienot tikai attēlus, PDF vai teksta failus.",
"prompt.toast.attachmentDuplicate.title": "Šis fails jau ir augšupielādēts",
"prompt.toast.modelAgentRequired.title": "Izvēlieties aģentu un modeli",
"prompt.toast.modelAgentRequired.description": "Pirms nosūtīšanas izvēlieties aģentu un modeli.",
-4
View File
@@ -192,7 +192,6 @@ export const dict = {
"dialog.provider.opencode.note": "Курирани модели вклучувајќи Claude, GPT, Gemini и повеќе",
"dialog.provider.opencode.tagline": "Сигурни оптимизирани модели",
"dialog.provider.opencodeGo.tagline": "Ниска цена претплата за секого",
"dialog.provider.anthropic.note": "Директен пристап до Claude модели, вклучувајќи ги Pro и Max",
"dialog.provider.copilot.note": "Модели со вештачка интелигенција за помош за кодирање преку GitHub Copilot",
"dialog.provider.openai.note": "GPT модели за брзи, способни општи задачи со вештачка интелигенција",
"dialog.provider.google.note": "Gemini модели за брзи, структурирани одговори",
@@ -209,7 +208,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Видете повеќе од 70 провајдери",
"dialog.provider.viewAll": "Прикажи повеќе провајдери",
"provider.connect.title": "Поврзете се {{provider}}",
"provider.connect.title.anthropicProMax": "Најавете се со Claude Pro/Max",
"provider.connect.selectMethod": "Изберете метод за најавување за {{provider}}.",
"provider.connect.method.apiKey": "клуч API",
"provider.connect.method.browser": "Прелистувач",
@@ -376,8 +374,6 @@ export const dict = {
"prompt.attachment.remove": "Отстранете го прилогот",
"prompt.action.send": "Испрати",
"prompt.action.stop": "Стоп",
"prompt.toast.pasteUnsupported.title": "Неподдржан прилог",
"prompt.toast.pasteUnsupported.description": "Овде може да се прикачат само слики, PDFs или текстуални датотеки.",
"prompt.toast.attachmentDuplicate.title": "Оваа датотека е веќе поставена",
"prompt.toast.modelAgentRequired.title": "Изберете агент и модел",
"prompt.toast.modelAgentRequired.description": "Изберете агент и модел пред да испратите известување.",
-4
View File
@@ -194,7 +194,6 @@ export const dict = {
"dialog.provider.opencode.note": "Claude, GPT, Gemini болон бусад загваруудыг сонгон шалгаруулсан",
"dialog.provider.opencode.tagline": "Найдвартай оновчтой загварууд",
"dialog.provider.opencodeGo.tagline": "Хүн бүрт зориулсан хямд өртөгтэй захиалга",
"dialog.provider.anthropic.note": "Pro болон Max зэрэг Claude загварт шууд хандах",
"dialog.provider.copilot.note": "GitHub Copilot-ээр дамжуулан кодлоход туслах хиймэл оюун ухааны загварууд",
"dialog.provider.openai.note": "GPT AI-ийн хурдан, чадвартай ерөнхий ажлуудад зориулсан загварууд",
"dialog.provider.google.note": "Gemini хурдан, бүтэцтэй хариулт өгөх загварууд",
@@ -211,7 +210,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Өөр 70 гаруй үйлчилгээ үзүүлэгчийг харна уу",
"dialog.provider.viewAll": "Илүү олон үйлчилгээ үзүүлэгчийг харуулах",
"provider.connect.title": "Холбох {{provider}}",
"provider.connect.title.anthropicProMax": "Claude Pro/Max-аар нэвтэрнэ үү",
"provider.connect.selectMethod": "{{provider}}-д нэвтрэх аргыг сонгоно уу.",
"provider.connect.method.apiKey": "API түлхүүр",
"provider.connect.method.browser": "Хөтөч",
@@ -378,8 +376,6 @@ export const dict = {
"prompt.attachment.remove": "Хавсралтыг устгана уу",
"prompt.action.send": "Илгээх",
"prompt.action.stop": "Зогс",
"prompt.toast.pasteUnsupported.title": "Дэмжигдээгүй хавсралт",
"prompt.toast.pasteUnsupported.description": "Энд зөвхөн зураг, PDFс, эсвэл текст файлыг хавсаргах боломжтой.",
"prompt.toast.attachmentDuplicate.title": "Энэ файлыг аль хэдийн байршуулсан байна",
"prompt.toast.modelAgentRequired.title": "Агент болон загварыг сонгоно уу",
"prompt.toast.modelAgentRequired.description": "Промпт илгээхээсээ өмнө агент болон загварыг сонгоно уу.",
-4
View File
@@ -191,7 +191,6 @@ export const dict = {
"dialog.provider.opencode.note": "Model terpilih termasuk Claude, GPT, Gemini dan banyak lagi",
"dialog.provider.opencode.tagline": "Model dioptimumkan yang boleh dipercayai",
"dialog.provider.opencodeGo.tagline": "Langganan kos rendah untuk semua",
"dialog.provider.anthropic.note": "Akses terus ke model Claude, termasuk Pro dan Max",
"dialog.provider.copilot.note": "Model AI untuk bantuan pengekodan melalui GitHub Copilot",
"dialog.provider.openai.note": "Model GPT untuk tugasan AI umum yang pantas dan berkeupayaan",
"dialog.provider.google.note": "Model Gemini untuk respons pantas dan berstruktur",
@@ -208,7 +207,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Lihat 70+ lagi penyedia",
"dialog.provider.viewAll": "Tunjukkan lebih banyak penyedia",
"provider.connect.title": "Sambungkan {{provider}}",
"provider.connect.title.anthropicProMax": "Log masuk dengan Claude Pro/Max",
"provider.connect.selectMethod": "Pilih kaedah log masuk untuk {{provider}}.",
"provider.connect.method.apiKey": "Kunci API",
"provider.connect.method.browser": "Pelayar",
@@ -375,8 +373,6 @@ export const dict = {
"prompt.attachment.remove": "Buang lampiran",
"prompt.action.send": "Hantar",
"prompt.action.stop": "Henti",
"prompt.toast.pasteUnsupported.title": "Lampiran tidak disokong",
"prompt.toast.pasteUnsupported.description": "Hanya imej, PDF, atau fail teks boleh dilampirkan di sini.",
"prompt.toast.attachmentDuplicate.title": "Fail ini telah dimuat naik",
"prompt.toast.modelAgentRequired.title": "Pilih ejen dan model",
"prompt.toast.modelAgentRequired.description": "Pilih ejen dan model sebelum menghantar prompt.",
-5
View File
@@ -193,7 +193,6 @@ export const dict = {
"dialog.provider.opencode.note": "Claude၊ GPT၊ Gemini နှင့် အခြားအရာများ အပါအဝင် ရွေးချယ်ထားသော မော်ဒယ်များ",
"dialog.provider.opencode.tagline": "ယုံကြည်စိတ်ချရသော အကောင်းဆုံးပြင်ဆင်ထားသော မော်ဒယ်များ",
"dialog.provider.opencodeGo.tagline": "လူတိုင်းအတွက် ကုန်ကျစရိတ်သက်သာသော စာရင်းသွင်းမှု",
"dialog.provider.anthropic.note": "Pro နှင့် Max အပါအဝင် Claude မော်ဒယ်များသို့ တိုက်ရိုက်ဝင်ရောက်ခွင့်",
"dialog.provider.copilot.note": "GitHub Copilot မှတစ်ဆင့် ကုဒ်ရေးနည်းအကူအညီအတွက် AI မော်ဒယ်များ",
"dialog.provider.openai.note": "လျင်မြန်ပြီး လုပ်ဆောင်နိုင်သော အထွေထွေ AI လုပ်ဆောင်ချက်များအတွက် GPT မော်ဒယ်များ",
"dialog.provider.google.note": "မြန်ဆန်ပြီး ဖွဲ့စည်းတည်ဆောက်ထားသော တုံ့ပြန်မှုများအတွက် Gemini မော်ဒယ်များ",
@@ -210,7 +209,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "နောက်ထပ်ပံ့ပိုးပေးသူ 70+ ကိုကြည့်ပါ။",
"dialog.provider.viewAll": "နောက်ထပ်ဝန်ဆောင်မှုပေးသူများကို ပြပါ။",
"provider.connect.title": "{{provider}} ကို ချိတ်ဆက်ပါ။",
"provider.connect.title.anthropicProMax": "Claude Pro/Max ဖြင့် ဝင်ရောက်ပါ။",
"provider.connect.selectMethod": "{{provider}} အတွက် အကောင့်ဝင်နည်းလမ်းကို ရွေးပါ။",
"provider.connect.method.apiKey": "API သော့",
"provider.connect.method.browser": "ဘရောက်ဆာ",
@@ -378,9 +376,6 @@ export const dict = {
"prompt.attachment.remove": "ပူးတွဲပါဖိုင်ကို ဖယ်ရှားပါ။",
"prompt.action.send": "ပို့ပါ။",
"prompt.action.stop": "ရပ်ပါ။",
"prompt.toast.pasteUnsupported.title": "ပူးတွဲပါဖိုင်ကို ပံ့ပိုးမထားပါ။",
"prompt.toast.pasteUnsupported.description":
"ရုပ်ပုံများ၊ PDF များ သို့မဟုတ် စာသားဖိုင်များကိုသာ ဤနေရာတွင် ပူးတွဲနိုင်ပါသည်။",
"prompt.toast.attachmentDuplicate.title": "ဤဖိုင်ကို အပ်လုဒ်လုပ်ပြီးပါပြီ။",
"prompt.toast.modelAgentRequired.title": "အေးဂျင့်နှင့် မော်ဒယ်ကို ရွေးပါ။",
"prompt.toast.modelAgentRequired.description": "Prompt မပို့မီ အေးဂျင့်နှင့် မော်ဒယ်ကို ရွေးပါ။",
-4
View File
@@ -192,7 +192,6 @@ export const dict: Record<string, string> = {
"dialog.provider.opencode.note": "Claude, GPT, Gemini र थप सहित क्युरेट गरिएका मोडेलहरू",
"dialog.provider.opencode.tagline": "भरपर्दो अनुकूलित मोडेलहरू",
"dialog.provider.opencodeGo.tagline": "सबैको लागि कम लागत सदस्यता",
"dialog.provider.anthropic.note": "प्रो र म्याक्स सहित Claude मोडेलहरूमा प्रत्यक्ष पहुँच",
"dialog.provider.copilot.note": "GitHub Copilot मार्फत कोडिङ सहायताका लागि AI मोडेलहरू",
"dialog.provider.openai.note": "छिटो, सक्षम सामान्य AI कार्यहरूको लागि GPT मोडेलहरू",
"dialog.provider.google.note": "छिटो, संरचित प्रतिक्रियाहरूको लागि Gemini मोडेलहरू",
@@ -209,7 +208,6 @@ export const dict: Record<string, string> = {
"dialog.model.unpaid.viewMoreProviders": "70+ थप प्रदायकहरू हेर्नुहोस्",
"dialog.provider.viewAll": "थप प्रदायकहरू देखाउनुहोस्",
"provider.connect.title": "जडान गर्नुहोस् {{provider}}",
"provider.connect.title.anthropicProMax": "Claude Pro/Max सँग लगइन गर्नुहोस्",
"provider.connect.selectMethod": "{{provider}} का लागि लगइन विधि चयन गर्नुहोस्।",
"provider.connect.method.apiKey": "API कुञ्जी",
"provider.connect.method.browser": "ब्राउजर",
@@ -376,8 +374,6 @@ export const dict: Record<string, string> = {
"prompt.attachment.remove": "संलग्नक हटाउनुहोस्",
"prompt.action.send": "पठाउनुहोस्",
"prompt.action.stop": "रोक्नुहोस्",
"prompt.toast.pasteUnsupported.title": "असमर्थित संलग्नक",
"prompt.toast.pasteUnsupported.description": "केवल छविहरू, PDF हरू, वा पाठ फाइलहरू यहाँ संलग्न गर्न सकिन्छ।",
"prompt.toast.attachmentDuplicate.title": "यो फाइल पहिले नै अपलोड गरिएको छ",
"prompt.toast.modelAgentRequired.title": "एक एजेन्ट र मोडेल चयन गर्नुहोस्",
"prompt.toast.modelAgentRequired.description": "प्रम्प्ट पठाउनु अघि एजेन्ट र मोडेल छान्नुहोस्।",
-5
View File
@@ -192,7 +192,6 @@ export const dict = {
"dialog.provider.opencode.note": "Samengestelde modellen, waaronder Claude, GPT, Gemini en meer",
"dialog.provider.opencode.tagline": "Betrouwbare geoptimaliseerde modellen",
"dialog.provider.opencodeGo.tagline": "Goedkoop abonnement voor iedereen",
"dialog.provider.anthropic.note": "Directe toegang tot Claude-modellen, inclusief Pro en Max",
"dialog.provider.copilot.note": "AI-modellen voor codeerondersteuning via GitHub Copilot",
"dialog.provider.openai.note": "GPT-modellen voor snelle, capabele algemene AI-taken",
"dialog.provider.google.note": "Gemini-modellen voor snelle, gestructureerde reacties",
@@ -209,7 +208,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Bekijk nog 70+ aanbieders",
"dialog.provider.viewAll": "Toon meer aanbieders",
"provider.connect.title": "Verbinding maken met {{provider}}",
"provider.connect.title.anthropicProMax": "Inloggen met Claude Pro/Max",
"provider.connect.selectMethod": "Selecteer de aanmeldingsmethode voor {{provider}}.",
"provider.connect.method.apiKey": "API-sleutel",
"provider.connect.method.browser": "Browser",
@@ -375,9 +373,6 @@ export const dict = {
"prompt.attachment.remove": "Bijlage verwijderen",
"prompt.action.send": "Verzenden",
"prompt.action.stop": "Stop",
"prompt.toast.pasteUnsupported.title": "Niet-ondersteunde bijlage",
"prompt.toast.pasteUnsupported.description":
"Hier kunnen alleen afbeeldingen, pdf's of tekstbestanden worden bijgevoegd.",
"prompt.toast.attachmentDuplicate.title": "Dit bestand is al geüpload",
"prompt.toast.modelAgentRequired.title": "Selecteer een agent en model",
"prompt.toast.modelAgentRequired.description": "Kies een agent en model voordat je een prompt verzendt.",
-4
View File
@@ -206,7 +206,6 @@ export const dict = {
"dialog.provider.opencode.note": "Utvalgte modeller inkludert Claude, GPT, Gemini og mer",
"dialog.provider.opencode.tagline": "Pålitelige, optimaliserte modeller",
"dialog.provider.opencodeGo.tagline": "Rimelig abonnement for alle",
"dialog.provider.anthropic.note": "Direkte tilgang til Claude-modeller, inkludert Pro og Max",
"dialog.provider.copilot.note": "AI-modeller for kodeassistanse via GitHub Copilot",
"dialog.provider.openai.note": "GPT-modeller for raske, dyktige generelle AI-oppgaver",
"dialog.provider.google.note": "Gemini-modeller for raske, strukturerte svar",
@@ -227,7 +226,6 @@ export const dict = {
"dialog.provider.viewAll": "Vis flere leverandører",
"provider.connect.title": "Koble til {{provider}}",
"provider.connect.title.anthropicProMax": "Logg inn med Claude Pro/Max",
"provider.connect.selectMethod": "Velg innloggingsmetode for {{provider}}.",
"provider.connect.method.apiKey": "API-nøkkel",
"provider.connect.method.browser": "Nettleser",
@@ -393,9 +391,7 @@ export const dict = {
"prompt.action.send": "Send",
"prompt.action.stop": "Stopp",
"prompt.toast.pasteUnsupported.title": "Ikke støttet vedlegg",
"prompt.toast.attachmentDuplicate.title": "Denne filen er allerede lastet opp",
"prompt.toast.pasteUnsupported.description": "Kun bilder, PDF-er eller tekstfiler kan legges ved her.",
"prompt.toast.modelAgentRequired.title": "Velg en agent og modell",
"prompt.toast.modelAgentRequired.description": "Velg en agent og modell før du sender en forespørsel.",
"prompt.toast.worktreeCreateFailed.title": "Kunne ikke opprette worktree",
-5
View File
@@ -198,7 +198,6 @@ export const dict = {
"dialog.provider.opencode.note": "Claude، GPT، Gemini تے ہور سمیت کیوریٹڈ ماڈل",
"dialog.provider.opencode.tagline": "قابل اعتماد اصلاح شدہ ماڈل",
"dialog.provider.opencodeGo.tagline": "ہر اک لئی گھٹ قیمت دی رکنیت",
"dialog.provider.anthropic.note": "پرو تے میکس سمیت Claude ماڈل تک براہ راست رسائی",
"dialog.provider.copilot.note": "GitHub Copilot دے ذریعے کوڈنگ دی مدد لئی اے آئی ماڈل",
"dialog.provider.openai.note": "تیز تے صلاحیت والے عام AI کماں لئی GPT ماڈل",
"dialog.provider.google.note": "تیز تے منظم جواباں لئی Gemini ماڈل",
@@ -215,7 +214,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "70+ ہور پرووائیڈر ویکھو",
"dialog.provider.viewAll": "ہور پرووائیڈر وکھاؤ",
"provider.connect.title": "{{provider}} نال جڑو",
"provider.connect.title.anthropicProMax": "Claude پرو/میکس دے نال لاگ ان کرو",
"provider.connect.selectMethod": "{{provider}} لئی لاگ ان دا طریقہ منتخب کرو۔",
"provider.connect.method.apiKey": "API کلید",
"provider.connect.method.browser": "براؤزر",
@@ -381,9 +379,6 @@ export const dict = {
"prompt.attachment.remove": "منسلکہ ہٹا دیو",
"prompt.action.send": "گھلو",
"prompt.action.stop": "روکو",
"prompt.toast.pasteUnsupported.title": "غیر تعاون یافتہ منسلکہ",
"prompt.toast.pasteUnsupported.description":
"ایتھے صرف تصویراں، پی ڈی ایف، یا ٹیکسٹ فائلاں منسلک کیتیاں جا سکدیاں نیں۔",
"prompt.toast.attachmentDuplicate.title": "ایہہ فائل پہلے ای اپ لوڈ ہو چکی اے",
"prompt.toast.modelAgentRequired.title": "اک ایجنٹ تے ماڈل چنو",
"prompt.toast.modelAgentRequired.description": "پرامپٹ بھیجن توں پہلاں اک ایجنٹ تے ماڈل دا انتخاب کرو۔",
-4
View File
@@ -199,7 +199,6 @@ export const dict = {
"dialog.provider.opencode.note": "Starannie dobrane modele, w tym Claude, GPT, Gemini i inne",
"dialog.provider.opencode.tagline": "Niezawodne, zoptymalizowane modele",
"dialog.provider.opencodeGo.tagline": "Niedroga subskrypcja dla każdego",
"dialog.provider.anthropic.note": "Bezpośredni dostęp do modeli Claude, w tym Pro i Max",
"dialog.provider.copilot.note": "Modele AI do pomocy w kodowaniu przez GitHub Copilot",
"dialog.provider.openai.note": "Modele GPT do szybkich i wszechstronnych zadań AI",
"dialog.provider.google.note": "Modele Gemini do szybkich i ustrukturyzowanych odpowiedzi",
@@ -216,7 +215,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Zobacz ponad 70 innych dostawców",
"dialog.provider.viewAll": "Zobacz więcej dostawców",
"provider.connect.title": "Połącz {{provider}}",
"provider.connect.title.anthropicProMax": "Zaloguj się za pomocą konta Claude Pro/Max",
"provider.connect.selectMethod": "Wybierz metodę logowania dla {{provider}}.",
"provider.connect.method.apiKey": "Klucz API",
"provider.connect.method.browser": "Przeglądarka",
@@ -382,9 +380,7 @@ export const dict = {
"prompt.attachment.remove": "Usuń załącznik",
"prompt.action.send": "Wyślij",
"prompt.action.stop": "Zatrzymaj",
"prompt.toast.pasteUnsupported.title": "Nieobsługiwany załącznik",
"prompt.toast.attachmentDuplicate.title": "Ten plik został już przesłany",
"prompt.toast.pasteUnsupported.description": "Można tutaj załączać tylko obrazy, pliki PDF lub pliki tekstowe.",
"prompt.toast.modelAgentRequired.title": "Wybierz agenta i model",
"prompt.toast.modelAgentRequired.description": "Wybierz agenta i model przed wysłaniem zapytania.",
"prompt.toast.worktreeCreateFailed.title": "Nie udało się utworzyć drzewa roboczego",
-4
View File
@@ -191,7 +191,6 @@ export const dict = {
"dialog.provider.opencode.note": "Modele selectate, inclusiv Claude, GPT, Gemini și altele",
"dialog.provider.opencode.tagline": "Modele optimizate, fiabile",
"dialog.provider.opencodeGo.tagline": "Abonament accesibil pentru toți",
"dialog.provider.anthropic.note": "Acces direct la modelele Claude, inclusiv Pro și Max",
"dialog.provider.copilot.note": "Modele AI pentru asistență la programare prin GitHub Copilot",
"dialog.provider.openai.note": "Modele GPT pentru sarcini AI generale rapide și performante",
"dialog.provider.google.note": "Modele Gemini pentru răspunsuri rapide și structurate",
@@ -208,7 +207,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Vezi peste 70 de furnizori",
"dialog.provider.viewAll": "Afișează mai mulți furnizori",
"provider.connect.title": "Conectează {{provider}}",
"provider.connect.title.anthropicProMax": "Autentificare cu Claude Pro/Max",
"provider.connect.selectMethod": "Selectează metoda de autentificare pentru {{provider}}.",
"provider.connect.method.apiKey": "Cheie API",
"provider.connect.method.browser": "Navigator",
@@ -374,8 +372,6 @@ export const dict = {
"prompt.attachment.remove": "Elimină atașamentul",
"prompt.action.send": "Trimite",
"prompt.action.stop": "Oprește",
"prompt.toast.pasteUnsupported.title": "Atașament neacceptat",
"prompt.toast.pasteUnsupported.description": "Poți atașa doar imagini, PDF-uri sau fișiere text aici.",
"prompt.toast.attachmentDuplicate.title": "Acest fișier a fost deja încărcat",
"prompt.toast.modelAgentRequired.title": "Selectează un agent și un model",
"prompt.toast.modelAgentRequired.description": "Alege un agent și un model înainte de a trimite un prompt.",
-4
View File
@@ -207,7 +207,6 @@ export const dict = {
"dialog.provider.opencode.note": "Отобранные модели, включая Claude, GPT, Gemini и другие",
"dialog.provider.opencode.tagline": "Надёжные оптимизированные модели",
"dialog.provider.opencodeGo.tagline": "Доступная подписка для всех",
"dialog.provider.anthropic.note": "Прямой доступ к моделям Claude, включая Pro и Max",
"dialog.provider.copilot.note": "ИИ-модели для помощи в кодировании через GitHub Copilot",
"dialog.provider.openai.note": "Модели GPT для быстрых и мощных задач общего ИИ",
"dialog.provider.google.note": "Модели Gemini для быстрых и структурированных ответов",
@@ -228,7 +227,6 @@ export const dict = {
"dialog.provider.viewAll": "Показать больше провайдеров",
"provider.connect.title": "Подключить {{provider}}",
"provider.connect.title.anthropicProMax": "Войти с помощью Claude Pro/Max",
"provider.connect.selectMethod": "Выберите способ входа для {{provider}}.",
"provider.connect.method.apiKey": "Ключ API",
"provider.connect.method.browser": "Браузер",
@@ -401,9 +399,7 @@ export const dict = {
"prompt.action.send": "Отправить",
"prompt.action.stop": "Остановить",
"prompt.toast.pasteUnsupported.title": "Неподдерживаемое вложение",
"prompt.toast.attachmentDuplicate.title": "Этот файл уже загружен",
"prompt.toast.pasteUnsupported.description": "Здесь можно прикрепить только изображения, PDF или текстовые файлы.",
"prompt.toast.modelAgentRequired.title": "Выберите агента и модель",
"prompt.toast.modelAgentRequired.description": "Выберите агента и модель перед отправкой запроса.",
"prompt.toast.worktreeCreateFailed.title": "Не удалось создать worktree",
-4
View File
@@ -191,7 +191,6 @@ export const dict: Record<string, string> = {
"dialog.provider.opencode.note": "Claude, GPT, Gemini සහ තවත් දේ ඇතුළුව සංවෘත ආකෘති",
"dialog.provider.opencode.tagline": "විශ්වසනීය ප්රශස්ත මාදිලි",
"dialog.provider.opencodeGo.tagline": "සෑම කෙනෙකුටම අඩු වියදම් දායකත්වයක්",
"dialog.provider.anthropic.note": "Pro සහ Max ඇතුළුව Claude මාදිලි වෙත සෘජු ප්‍රවේශය",
"dialog.provider.copilot.note": "GitHub Copilot හරහා කේතීකරණ සහාය සඳහා AI ආකෘති",
"dialog.provider.openai.note": "වේගවත්, හැකියාව ඇති සාමාන්‍ය AI කාර්යයන් සඳහා GPT මාදිලි",
"dialog.provider.google.note": "වේගවත්, ව්‍යුහගත ප්‍රතිචාර සඳහා Gemini ආකෘති",
@@ -208,7 +207,6 @@ export const dict: Record<string, string> = {
"dialog.model.unpaid.viewMoreProviders": "තවත් සපයන්නන් 70+ බලන්න",
"dialog.provider.viewAll": "තවත් සපයන්නන් පෙන්වන්න",
"provider.connect.title": "{{provider}} සම්බන්ධ කරන්න",
"provider.connect.title.anthropicProMax": "Claude Pro/Max සමඟින් පුරනය වන්න",
"provider.connect.selectMethod": "{{provider}} සඳහා පිවිසුම් ක්‍රමය තෝරන්න.",
"provider.connect.method.apiKey": "API යතුර",
"provider.connect.method.browser": "බ්රවුසරය",
@@ -374,8 +372,6 @@ export const dict: Record<string, string> = {
"prompt.attachment.remove": "ඇමුණුම ඉවත් කරන්න",
"prompt.action.send": "යවන්න",
"prompt.action.stop": "නවත්වන්න",
"prompt.toast.pasteUnsupported.title": "සහාය නොදක්වන ඇමුණුම",
"prompt.toast.pasteUnsupported.description": "පින්තූර, PDF හෝ පෙළ ගොනු පමණක් මෙහි ඇමිණිය හැක.",
"prompt.toast.attachmentDuplicate.title": "මෙම ගොනුව දැනටමත් උඩුගත කර ඇත",
"prompt.toast.modelAgentRequired.title": "නියෝජිතයෙකු සහ ආකෘතියක් තෝරන්න",
"prompt.toast.modelAgentRequired.description": "ප්‍රොම්ප්ට් එකක් යැවීමට පෙර නියෝජිතයෙකු සහ ආකෘතියක් තෝරන්න.",
-4
View File
@@ -191,7 +191,6 @@ export const dict = {
"dialog.provider.opencode.note": "Vybrané modely vrátane Claude, GPT, Gemini a ďalších",
"dialog.provider.opencode.tagline": "Spoľahlivé optimalizované modely",
"dialog.provider.opencodeGo.tagline": "Nízkonákladové predplatné pre každého",
"dialog.provider.anthropic.note": "Priamy prístup k modelom Claude vrátane Pro a Max",
"dialog.provider.copilot.note": "AI modely na asistenciu pri kódovaní cez GitHub Copilot",
"dialog.provider.openai.note": "GPT modely na rýchle a výkonné všeobecné AI úlohy",
"dialog.provider.google.note": "Gemini modely na rýchle, štruktúrované odpovede",
@@ -208,7 +207,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Zobraziť viac ako 70 ďalších poskytovateľov",
"dialog.provider.viewAll": "Zobraziť viac poskytovateľov",
"provider.connect.title": "Pripojiť {{provider}}",
"provider.connect.title.anthropicProMax": "Prihlásiť sa cez Claude Pro/Max",
"provider.connect.selectMethod": "Vyberte spôsob prihlásenia pre {{provider}}.",
"provider.connect.method.apiKey": "API kľúč",
"provider.connect.method.browser": "Prehliadač",
@@ -374,8 +372,6 @@ export const dict = {
"prompt.attachment.remove": "Odstrániť prílohu",
"prompt.action.send": "Odoslať",
"prompt.action.stop": "Zastaviť",
"prompt.toast.pasteUnsupported.title": "Nepodporovaná príloha",
"prompt.toast.pasteUnsupported.description": "Pripojiť možno len obrázky, PDF alebo textové súbory.",
"prompt.toast.attachmentDuplicate.title": "Tento súbor už bol nahraný",
"prompt.toast.modelAgentRequired.title": "Vyberte agenta a model",
"prompt.toast.modelAgentRequired.description": "Pred odoslaním výzvy vyberte agenta a model.",
-4
View File
@@ -191,7 +191,6 @@ export const dict = {
"dialog.provider.opencode.note": "Izbrani modeli, vključno z Claude, GPT, Gemini in drugimi",
"dialog.provider.opencode.tagline": "Zanesljivi optimizirani modeli",
"dialog.provider.opencodeGo.tagline": "Poceni naročnina za vsakogar",
"dialog.provider.anthropic.note": "Neposreden dostop do modelov Claude, vključno s Pro in Max",
"dialog.provider.copilot.note": "Modeli AI za pomoč pri kodiranju prek GitHub Copilot",
"dialog.provider.openai.note": "Modeli GPT za hitre in zmogljive splošne naloge z umetno inteligenco",
"dialog.provider.google.note": "Modeli Gemini za hitre, strukturirane odzive",
@@ -208,7 +207,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Oglejte si več kot 70 ponudnikov",
"dialog.provider.viewAll": "Pokaži več ponudnikov",
"provider.connect.title": "Povežite {{provider}}",
"provider.connect.title.anthropicProMax": "Prijavite se z Claude Pro/Max",
"provider.connect.selectMethod": "Izberite način prijave za {{provider}}.",
"provider.connect.method.apiKey": "Ključ API",
"provider.connect.method.browser": "Brskalnik",
@@ -374,8 +372,6 @@ export const dict = {
"prompt.attachment.remove": "Odstrani prilogo",
"prompt.action.send": "Pošlji",
"prompt.action.stop": "Ustavi",
"prompt.toast.pasteUnsupported.title": "Nepodprta priloga",
"prompt.toast.pasteUnsupported.description": "Sem lahko priložite samo slike, datoteke PDF ali besedilne datoteke.",
"prompt.toast.attachmentDuplicate.title": "Ta datoteka je že naložena",
"prompt.toast.modelAgentRequired.title": "Izberite agenta in model",
"prompt.toast.modelAgentRequired.description": "Preden pošljete poziv, izberite agenta in model.",
-5
View File
@@ -192,7 +192,6 @@ export const dict = {
"dialog.provider.opencode.note": "Modele të kuruara duke përfshirë Claude, GPT, Gemini dhe më shumë",
"dialog.provider.opencode.tagline": "Modele të besueshme të optimizuara",
"dialog.provider.opencodeGo.tagline": "Abonim me kosto të ulët për të gjithë",
"dialog.provider.anthropic.note": "Qasje e drejtpërdrejtë në modelet Claude, duke përfshirë Pro dhe Max",
"dialog.provider.copilot.note": "Modele të AI për ndihmë kodimi përmes GitHub Copilot",
"dialog.provider.openai.note": "Modelet GPT për detyra të shpejta dhe të afta të përgjithshme të AI",
"dialog.provider.google.note": "Modele Gemini për përgjigje të shpejta dhe të strukturuara",
@@ -209,7 +208,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Shiko mbi 70 ofrues të tjerë",
"dialog.provider.viewAll": "Shfaq më shumë ofrues",
"provider.connect.title": "Lidhni {{provider}}",
"provider.connect.title.anthropicProMax": "Hyni me Claude Pro/Max",
"provider.connect.selectMethod": "Zgjidhni metodën e hyrjes për {{provider}}.",
"provider.connect.method.apiKey": "Tasti API",
"provider.connect.method.browser": "Shfletuesi",
@@ -375,9 +373,6 @@ export const dict = {
"prompt.attachment.remove": "Hiq shtojcën",
"prompt.action.send": "Dërgo",
"prompt.action.stop": "Ndalo",
"prompt.toast.pasteUnsupported.title": "Bashkëngjitje e pambështetur",
"prompt.toast.pasteUnsupported.description":
"Këtu mund të bashkëngjiten vetëm imazhe, skedarë PDF ose skedarë teksti.",
"prompt.toast.attachmentDuplicate.title": "Ky skedar tashmë është ngarkuar",
"prompt.toast.modelAgentRequired.title": "Zgjidhni një agjent dhe model",
"prompt.toast.modelAgentRequired.description": "Zgjidhni një agjent dhe model përpara se të dërgoni një kërkesë.",
-4
View File
@@ -192,7 +192,6 @@ export const dict = {
"dialog.provider.opencode.note": "одабрани модели укључујући Claude, GPT, Gemini и више",
"dialog.provider.opencode.tagline": "Поуздани оптимизовани модели",
"dialog.provider.opencodeGo.tagline": "Ниска цена претплате за све",
"dialog.provider.anthropic.note": "Директан приступ Claude моделима, укључујући Про и Мак",
"dialog.provider.copilot.note": "АИ модели за помоћ код кодирања преко GitHub Copilot",
"dialog.provider.openai.note": "GPT модела за брзе, способне опште задатке вештачке интелигенције",
"dialog.provider.google.note": "Gemini модела за брзе, структуриране одговоре",
@@ -209,7 +208,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Погледајте више од 70 провајдера",
"dialog.provider.viewAll": "Прикажи више добављача",
"provider.connect.title": "Повежи {{provider}}",
"provider.connect.title.anthropicProMax": "Пријавите се са Claude Про/Мак",
"provider.connect.selectMethod": "Изаберите метод пријаве за {{provider}}.",
"provider.connect.method.apiKey": "API кључ",
"provider.connect.method.browser": "Прегледач",
@@ -375,8 +373,6 @@ export const dict = {
"prompt.attachment.remove": "Уклоните прилог",
"prompt.action.send": "Пошаљи",
"prompt.action.stop": "Стоп",
"prompt.toast.pasteUnsupported.title": "Неподржани прилог",
"prompt.toast.pasteUnsupported.description": "Овде се могу приложити само слике, PDFс или текстуалне датотеке.",
"prompt.toast.attachmentDuplicate.title": "Ова датотека је већ отпремљена",
"prompt.toast.modelAgentRequired.title": "Изаберите агента и модел",
"prompt.toast.modelAgentRequired.description": "Одаберите агента и модел пре него што пошаљете упит.",
-4
View File
@@ -193,7 +193,6 @@ export const dict = {
"dialog.provider.opencode.note": "Kurerade modeller inklusive Claude, GPT, Gemini och mer",
"dialog.provider.opencode.tagline": "Pålitliga optimerade modeller",
"dialog.provider.opencodeGo.tagline": "Lågprisprenumeration för alla",
"dialog.provider.anthropic.note": "Direkt tillgång till Claude-modeller, inklusive Pro och Max",
"dialog.provider.copilot.note": "AI-modeller för kodningshjälp via GitHub Copilot",
"dialog.provider.openai.note": "GPT-modeller för snabba, kapabla allmänna AI-uppgifter",
"dialog.provider.google.note": "Gemini-modeller för snabba, strukturerade svar",
@@ -210,7 +209,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Se fler än 70 leverantörer",
"dialog.provider.viewAll": "Visa fler leverantörer",
"provider.connect.title": "Anslut {{provider}}",
"provider.connect.title.anthropicProMax": "Logga in med Claude Pro/Max",
"provider.connect.selectMethod": "Välj inloggningsmetod för {{provider}}.",
"provider.connect.method.apiKey": "API-nyckel",
"provider.connect.method.browser": "Webbläsare",
@@ -376,8 +374,6 @@ export const dict = {
"prompt.attachment.remove": "Ta bort bilagan",
"prompt.action.send": "Skicka",
"prompt.action.stop": "Stoppa",
"prompt.toast.pasteUnsupported.title": "Bilaga som inte stöds",
"prompt.toast.pasteUnsupported.description": "Endast bilder, PDF-filer eller textfiler kan bifogas här.",
"prompt.toast.attachmentDuplicate.title": "Den här filen har redan laddats upp",
"prompt.toast.modelAgentRequired.title": "Välj en agent och modell",
"prompt.toast.modelAgentRequired.description": "Välj en agent och modell innan du skickar en prompt.",
-5
View File
@@ -192,7 +192,6 @@ export const dict = {
"dialog.provider.opencode.note": "Моделҳои интихобшуда, аз ҷумла Claude, GPT, Gemini ва ғайра",
"dialog.provider.opencode.tagline": "Моделҳои боэътимоди оптимизатсияшуда",
"dialog.provider.opencodeGo.tagline": "Обунаи арзон барои ҳама",
"dialog.provider.anthropic.note": "Дастрасии мустақим ба моделҳои Claude, аз ҷумла Pro ва Max",
"dialog.provider.copilot.note": "Моделҳои AI барои кӯмаки рамзгузорӣ тавассути GitHub Copilot",
"dialog.provider.openai.note": "GPT моделҳо барои вазифаҳои зуд ва тавонои умумии AI",
"dialog.provider.google.note": "Gemini моделҳо барои посухҳои зуд ва сохторӣ",
@@ -209,7 +208,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Ба 70+ провайдерҳои дигар нигаред",
"dialog.provider.viewAll": "Провайдерҳои бештарро нишон диҳед",
"provider.connect.title": "Пайвастшавӣ {{provider}}",
"provider.connect.title.anthropicProMax": "Воридшавӣ бо Claude Pro/Max",
"provider.connect.selectMethod": "Усули воридшавиро барои {{provider}} интихоб кунед.",
"provider.connect.method.apiKey": "API калид",
"provider.connect.method.browser": "Браузер",
@@ -376,9 +374,6 @@ export const dict = {
"prompt.attachment.remove": "Замимаро хориҷ кунед",
"prompt.action.send": "Фиристодан",
"prompt.action.stop": "Ист",
"prompt.toast.pasteUnsupported.title": "Замимаи дастгирӣнашаванда",
"prompt.toast.pasteUnsupported.description":
"Дар ин ҷо танҳо тасвирҳо, PDFс ё файлҳои матнӣ замима кардан мумкин аст.",
"prompt.toast.attachmentDuplicate.title": "Ин файл аллакай бор карда шудааст",
"prompt.toast.modelAgentRequired.title": "Агент ва моделро интихоб кунед",
"prompt.toast.modelAgentRequired.description": "Пеш аз фиристодани промпт агент ва моделро интихоб кунед.",
-4
View File
@@ -206,7 +206,6 @@ export const dict = {
"dialog.provider.opencode.note": "โมเดลที่คัดสรร รวมถึง Claude, GPT, Gemini และอื่น ๆ",
"dialog.provider.opencode.tagline": "โมเดลที่เชื่อถือได้และปรับให้เหมาะสม",
"dialog.provider.opencodeGo.tagline": "การสมัครสมาชิกราคาประหยัดสำหรับทุกคน",
"dialog.provider.anthropic.note": "เข้าถึงโมเดล Claude โดยตรง รวมถึง Pro และ Max",
"dialog.provider.copilot.note": "โมเดล AI สำหรับการช่วยเหลือในการเขียนโค้ดผ่าน GitHub Copilot",
"dialog.provider.openai.note": "โมเดล GPT สำหรับงาน AI ทั่วไปที่รวดเร็วและมีความสามารถ",
"dialog.provider.google.note": "โมเดล Gemini สำหรับการตอบสนองที่รวดเร็วและมีโครงสร้าง",
@@ -227,7 +226,6 @@ export const dict = {
"dialog.provider.viewAll": "แสดงผู้ให้บริการเพิ่มเติม",
"provider.connect.title": "เชื่อมต่อ {{provider}}",
"provider.connect.title.anthropicProMax": "เข้าสู่ระบบด้วย Claude Pro/Max",
"provider.connect.selectMethod": "เลือกวิธีการเข้าสู่ระบบสำหรับ {{provider}}",
"provider.connect.method.apiKey": "คีย์ API",
"provider.connect.method.browser": "เบราว์เซอร์",
@@ -400,9 +398,7 @@ export const dict = {
"prompt.action.send": "ส่ง",
"prompt.action.stop": "หยุด",
"prompt.toast.pasteUnsupported.title": "ไฟล์แนบที่ไม่รองรับ",
"prompt.toast.attachmentDuplicate.title": "ไฟล์นี้ถูกอัปโหลดแล้ว",
"prompt.toast.pasteUnsupported.description": "แนบได้เฉพาะรูปภาพ PDF หรือไฟล์ข้อความเท่านั้น",
"prompt.toast.modelAgentRequired.title": "เลือกเอเจนต์และโมเดล",
"prompt.toast.modelAgentRequired.description": "เลือกเอเจนต์และโมเดลก่อนส่งพรอมต์",
"prompt.toast.worktreeCreateFailed.title": "ไม่สามารถสร้าง worktree",
-4
View File
@@ -192,7 +192,6 @@ export const dict = {
"dialog.provider.opencode.note": "Claude, GPT, Gemini we ş.m.",
"dialog.provider.opencode.tagline": "Ygtybarly optimal modeller",
"dialog.provider.opencodeGo.tagline": "Hemmeler üçin arzan bahaly abuna",
"dialog.provider.anthropic.note": "Pro we Max ýaly Claude modellerine göni giriş",
"dialog.provider.copilot.note": "GitHub Copilot arkaly kodlaşdyrmak üçin AI modelleri",
"dialog.provider.openai.note": "Çalt, başarnykly umumy AI meseleleri üçin GPT modelleri",
"dialog.provider.google.note": "Çalt, gurluşly jogaplar üçin Gemini modelleri",
@@ -209,7 +208,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Moreene-de 70+ üpjün edijä serediň",
"dialog.provider.viewAll": "Has köp üpjün edijini görkeziň",
"provider.connect.title": "{{provider}} birikdiriň",
"provider.connect.title.anthropicProMax": "Claude Pro / Maks bilen giriň",
"provider.connect.selectMethod": "{{provider}} üçin giriş usulyny saýlaň.",
"provider.connect.method.apiKey": "API açary",
"provider.connect.method.browser": "Brauzer",
@@ -375,8 +373,6 @@ export const dict = {
"prompt.attachment.remove": "Goşundyny aýyryň",
"prompt.action.send": "Iber",
"prompt.action.stop": "Dur",
"prompt.toast.pasteUnsupported.title": "Goldaw berilmeýän goşundy",
"prompt.toast.pasteUnsupported.description": "Bu ýerde diňe suratlar, PDF ýa-da tekst faýllary birikdirilip bilner.",
"prompt.toast.attachmentDuplicate.title": "Bu faýl eýýäm ýüklendi",
"prompt.toast.modelAgentRequired.title": "Agent we model saýlaň",
"prompt.toast.modelAgentRequired.description": "Sorag ibermezden ozal agent we model saýlaň.",
-4
View File
@@ -212,7 +212,6 @@ export const dict = {
"dialog.provider.opencode.note": "Claude, GPT, Gemini ve daha fazlasını içeren seçilmiş modeller",
"dialog.provider.opencode.tagline": "Güvenilir, optimize edilmiş modeller",
"dialog.provider.opencodeGo.tagline": "Herkes için düşük maliyetli abonelik",
"dialog.provider.anthropic.note": "Pro ve Max dahil Claude modellerine doğrudan erişim",
"dialog.provider.copilot.note": "GitHub Copilot üzerinden kodlama yardımı için yapay zekâ modelleri",
"dialog.provider.openai.note": "Hızlı ve yetenekli genel yapay zekâ görevleri için GPT modelleri",
"dialog.provider.google.note": "Hızlı ve yapılandırılmış yanıtlar için Gemini modelleri",
@@ -233,7 +232,6 @@ export const dict = {
"dialog.provider.viewAll": "Daha fazla sağlayıcı göster",
"provider.connect.title": "{{provider}} bağla",
"provider.connect.title.anthropicProMax": "Claude Pro/Max ile giriş yap",
"provider.connect.selectMethod": "{{provider}} için giriş yöntemini seçin.",
"provider.connect.method.apiKey": "API anahtarı",
"provider.connect.method.browser": "Tarayıcı",
@@ -407,9 +405,7 @@ export const dict = {
"prompt.action.send": "Gönder",
"prompt.action.stop": "Durdur",
"prompt.toast.pasteUnsupported.title": "Desteklenmeyen ek",
"prompt.toast.attachmentDuplicate.title": "Bu dosya zaten yüklendi",
"prompt.toast.pasteUnsupported.description": "Buraya yalnızca resimler, PDF'ler veya metin dosyaları eklenebilir.",
"prompt.toast.modelAgentRequired.title": "Bir ajan ve model seçin",
"prompt.toast.modelAgentRequired.description": "İstem göndermeden önce bir ajan ve model seçin.",
"prompt.toast.worktreeCreateFailed.title": "Çalışma ağacı oluşturulamadı",
-4
View File
@@ -208,7 +208,6 @@ export const dict = {
"dialog.provider.opencode.note": "Відібрані моделі, включаючи Claude, GPT, Gemini та інші",
"dialog.provider.opencode.tagline": "Надійні оптимізовані моделі",
"dialog.provider.opencodeGo.tagline": "Недорога підписка для всіх",
"dialog.provider.anthropic.note": "Прямий доступ до моделей Claude, включаючи Pro та Max",
"dialog.provider.copilot.note": "Моделі ШІ для допомоги в кодуванні через GitHub Copilot",
"dialog.provider.openai.note": "Моделі GPT для швидких і універсальних завдань ШІ",
"dialog.provider.google.note": "Моделі Gemini для швидких структурованих відповідей",
@@ -229,7 +228,6 @@ export const dict = {
"dialog.provider.viewAll": "Показати більше провайдерів",
"provider.connect.title": "Підключити {{provider}}",
"provider.connect.title.anthropicProMax": "Увійти з Claude Pro/Max",
"provider.connect.selectMethod": "Виберіть спосіб входу для {{provider}}.",
"provider.connect.method.apiKey": "Ключ API",
"provider.connect.method.browser": "Браузер",
@@ -404,9 +402,7 @@ export const dict = {
"prompt.action.send": "Надіслати",
"prompt.action.stop": "Зупинити",
"prompt.toast.pasteUnsupported.title": "Непідтримуване вкладення",
"prompt.toast.attachmentDuplicate.title": "Цей файл уже завантажено",
"prompt.toast.pasteUnsupported.description": "Сюди можна прикріплювати лише зображення, PDF або текстові файли.",
"prompt.toast.modelAgentRequired.title": "Виберіть агента та модель",
"prompt.toast.modelAgentRequired.description": "Виберіть агента та модель перед надсиланням запиту.",
"prompt.toast.worktreeCreateFailed.title": "Не вдалося створити робоче дерево",
-4
View File
@@ -200,7 +200,6 @@ export const dict = {
"dialog.provider.opencode.note": "کیوریٹ شدہ ماڈلز بشمول Claude، GPT، Gemini اور مزید",
"dialog.provider.opencode.tagline": "قابل اعتماد آپٹمائزڈ ماڈلز",
"dialog.provider.opencodeGo.tagline": "سب کے لیے کم لاگت کی رکنیت",
"dialog.provider.anthropic.note": "پرو اور میکس سمیت Claude ماڈلز تک براہ راست رسائی",
"dialog.provider.copilot.note": "GitHub Copilot کے ذریعے کوڈنگ امداد کے لیے AI ماڈلز",
"dialog.provider.openai.note": "تیز رفتار اور مؤثر عمومی AI کاموں کے لیے GPT ماڈلز",
"dialog.provider.google.note": "تیز، منظم جوابات کے لیے Gemini ماڈل",
@@ -217,7 +216,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "مزید 70 فراہم کنندگان دیکھیں",
"dialog.provider.viewAll": "مزید فراہم کنندگان دکھائیں۔",
"provider.connect.title": "{{provider}} سے منسلک ہوں",
"provider.connect.title.anthropicProMax": "Claude Pro/Max کے ساتھ لاگ ان کریں۔",
"provider.connect.selectMethod": "{{provider}} کے لیے لاگ ان کا طریقہ منتخب کریں۔",
"provider.connect.method.apiKey": "API کلید",
"provider.connect.method.browser": "براؤزر",
@@ -384,8 +382,6 @@ export const dict = {
"prompt.attachment.remove": "منسلکہ کو ہٹا دیں۔",
"prompt.action.send": "بھیجیں۔",
"prompt.action.stop": "روکیں",
"prompt.toast.pasteUnsupported.title": "غیر تعاون یافتہ منسلکہ",
"prompt.toast.pasteUnsupported.description": "یہاں صرف تصاویر، PDFs، یا ٹیکسٹ فائلیں منسلک کی جا سکتی ہیں۔",
"prompt.toast.attachmentDuplicate.title": "یہ فائل پہلے ہی اپ لوڈ ہو چکی ہے",
"prompt.toast.modelAgentRequired.title": "ایک ایجنٹ اور ماڈل منتخب کریں۔",
"prompt.toast.modelAgentRequired.description": "پرامپٹ بھیجنے سے پہلے ایک ایجنٹ اور ماڈل کا انتخاب کریں۔",
-4
View File
@@ -193,7 +193,6 @@ export const dict = {
"dialog.provider.opencode.note": "Tanlangan modellar, jumladan Claude, GPT, Gemini va boshqalar",
"dialog.provider.opencode.tagline": "Ishonchli optimallashtirilgan modellar",
"dialog.provider.opencodeGo.tagline": "Hamma uchun arzon obuna",
"dialog.provider.anthropic.note": "Claude modellariga, jumladan Pro va Maksga to'g'ridan-to'g'ri kirish",
"dialog.provider.copilot.note": "GitHub Copilot orqali kodlash yordami uchun AI modellari",
"dialog.provider.openai.note": "Tez, qobiliyatli umumiy AI vazifalari uchun GPT modellari",
"dialog.provider.google.note": "Tez, tuzilgan javoblar uchun Gemini modellari",
@@ -210,7 +209,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Yana 70 dan ortiq provayderlarni koʻring",
"dialog.provider.viewAll": "Ko'proq provayderlarni ko'rsatish",
"provider.connect.title": "{{provider}} ni ulang",
"provider.connect.title.anthropicProMax": "Claude Pro/Maks bilan tizimga kiring",
"provider.connect.selectMethod": "{{provider}} uchun kirish usulini tanlang.",
"provider.connect.method.apiKey": "API kaliti",
"provider.connect.method.browser": "Brauzer",
@@ -377,8 +375,6 @@ export const dict = {
"prompt.attachment.remove": "Qo'shimchani olib tashlang",
"prompt.action.send": "Yuborish",
"prompt.action.stop": "To'xtang",
"prompt.toast.pasteUnsupported.title": "Qoʻllab-quvvatlanmaydigan biriktirma",
"prompt.toast.pasteUnsupported.description": "Bu yerda faqat rasmlar, PDF yoki matnli fayllar biriktirilishi mumkin.",
"prompt.toast.attachmentDuplicate.title": "Bu fayl allaqachon yuklangan",
"prompt.toast.modelAgentRequired.title": "Agent va modelni tanlang",
"prompt.toast.modelAgentRequired.description": "So'rov yuborishdan oldin agent va modelni tanlang.",
-4
View File
@@ -199,7 +199,6 @@ export const dict = {
"dialog.provider.opencode.note": "Các mô hình được tuyển chọn, gồm Claude, GPT, Gemini và nhiều mô hình khác",
"dialog.provider.opencode.tagline": "Các mô hình tối ưu hóa đáng tin cậy",
"dialog.provider.opencodeGo.tagline": "Đăng ký chi phí thấp cho mọi người",
"dialog.provider.anthropic.note": "Truy cập trực tiếp các mô hình Claude, bao gồm Pro và Max",
"dialog.provider.copilot.note": "Các mô hình AI hỗ trợ lập trình qua GitHub Copilot",
"dialog.provider.openai.note": "Các mô hình GPT nhanh và mạnh mẽ cho tác vụ AI đa dụng",
"dialog.provider.google.note": "Các mô hình Gemini cho phản hồi nhanh, có cấu trúc",
@@ -216,7 +215,6 @@ export const dict = {
"dialog.model.unpaid.viewMoreProviders": "Xem hơn 70 nhà cung cấp khác",
"dialog.provider.viewAll": "Hiển thị thêm nhà cung cấp",
"provider.connect.title": "Kết nối {{provider}}",
"provider.connect.title.anthropicProMax": "Đăng nhập bằng Claude Pro/Max",
"provider.connect.selectMethod": "Chọn phương thức đăng nhập cho {{provider}}.",
"provider.connect.method.apiKey": "Khóa API",
"provider.connect.method.browser": "Trình duyệt",
@@ -382,8 +380,6 @@ export const dict = {
"prompt.attachment.remove": "Xóa tệp đính kèm",
"prompt.action.send": "Gửi",
"prompt.action.stop": "Dừng",
"prompt.toast.pasteUnsupported.title": "Tệp đính kèm không được hỗ trợ",
"prompt.toast.pasteUnsupported.description": "Chỉ có thể đính kèm hình ảnh, tệp PDF hoặc tệp văn bản ở đây.",
"prompt.toast.attachmentDuplicate.title": "Tệp này đã được tải lên",
"prompt.toast.modelAgentRequired.title": "Chọn tác nhân và mô hình",
"prompt.toast.modelAgentRequired.description": "Chọn một tác nhân và mô hình trước khi gửi lời nhắc.",
-4
View File
@@ -233,7 +233,6 @@ export const dict = {
"dialog.provider.opencode.note": "精选模型,包括 Claude、GPT、Gemini 等",
"dialog.provider.opencode.tagline": "可靠的优化模型",
"dialog.provider.opencodeGo.tagline": "适合所有人的低成本订阅",
"dialog.provider.anthropic.note": "直接使用 Claude 模型,包括 Pro 和 Max",
"dialog.provider.copilot.note": "通过 GitHub Copilot 使用辅助编程 AI 模型",
"dialog.provider.openai.note": "适合快速处理各类 AI 任务的 GPT 模型",
"dialog.provider.google.note": "可快速生成结构化回复的 Gemini 模型",
@@ -253,7 +252,6 @@ export const dict = {
"dialog.provider.viewAll": "查看更多提供商",
"provider.connect.title": "连接 {{provider}}",
"provider.connect.title.anthropicProMax": "使用 Claude Pro/Max 登录",
"provider.connect.selectMethod": "选择 {{provider}} 的登录方式。",
"provider.connect.method.apiKey": "API 密钥",
"provider.connect.method.browser": "浏览器",
@@ -419,9 +417,7 @@ export const dict = {
"prompt.attachment.remove": "移除附件",
"prompt.action.send": "发送",
"prompt.action.stop": "停止",
"prompt.toast.pasteUnsupported.title": "不支持的附件",
"prompt.toast.attachmentDuplicate.title": "此文件已上传",
"prompt.toast.pasteUnsupported.description": "此处仅能附加图片、PDF 或文本文件。",
"prompt.toast.modelAgentRequired.title": "请选择智能体和模型",
"prompt.toast.modelAgentRequired.description": "发送提示前请先选择智能体和模型。",
"prompt.toast.worktreeCreateFailed.title": "创建工作区失败",
-4
View File
@@ -210,7 +210,6 @@ export const dict = {
"dialog.provider.opencode.note": "精選模型,包含 Claude、GPT、Gemini 等等",
"dialog.provider.opencode.tagline": "經過最佳化的可靠模型",
"dialog.provider.opencodeGo.tagline": "適合所有人的低成本訂閱",
"dialog.provider.anthropic.note": "直接存取 Claude 模型,包括 Pro 和 Max",
"dialog.provider.openai.note": "適合快速且功能強大的通用 AI 工作之 GPT 模型",
"dialog.provider.copilot.note": "透過 GitHub Copilot 使用程式設計輔助 AI 模型",
"dialog.provider.google.note": "Gemini 模型,提供快速且結構化的回應",
@@ -231,7 +230,6 @@ export const dict = {
"dialog.provider.viewAll": "查看更多提供者",
"provider.connect.title": "連線 {{provider}}",
"provider.connect.title.anthropicProMax": "使用 Claude Pro/Max 登入",
"provider.connect.selectMethod": "選擇 {{provider}} 的登入方式。",
"provider.connect.method.apiKey": "API 金鑰",
"provider.connect.method.browser": "瀏覽器",
@@ -400,9 +398,7 @@ export const dict = {
"prompt.action.send": "傳送",
"prompt.action.stop": "停止",
"prompt.toast.pasteUnsupported.title": "不支援的附件",
"prompt.toast.attachmentDuplicate.title": "此檔案已上傳",
"prompt.toast.pasteUnsupported.description": "此處僅能附加圖片、PDF 或文字檔案。",
"prompt.toast.modelAgentRequired.title": "請選擇代理程式和模型",
"prompt.toast.modelAgentRequired.description": "傳送提示前請先選擇代理程式和模型。",
"prompt.toast.worktreeCreateFailed.title": "建立工作樹失敗",
+10 -2
View File
@@ -421,9 +421,17 @@ function referenced(json: string) {
return ids
}
export async function blobDataUrl(blob: BlobReference, mime: string) {
async function blobData(blob: BlobReference) {
const kept = retained.get(aliases.get(blob.id) ?? blob.id)
const data = kept ? kept.blob : await fetch(blob.url).then((response) => response.blob())
return kept ? kept.blob : await fetch(blob.url).then((response) => response.blob())
}
export async function blobBytes(blob: BlobReference) {
return new Uint8Array(await (await blobData(blob)).arrayBuffer())
}
export async function blobDataUrl(blob: BlobReference, mime: string) {
const data = await blobData(blob)
return new Promise<string>((resolve, reject) => {
const reader = new FileReader()
reader.addEventListener("error", () => reject(reader.error))
+10 -5
View File
@@ -90,7 +90,12 @@ test("rotates HTTP and PTY clients together", async () => {
const fetch = (async (input: string | URL | Request, init?: RequestInit) => {
const request = input instanceof Request ? input : new Request(input, init)
requests.push({ url: request.url, authorization: request.headers.get("authorization") })
return Response.json({ version: "2.0.0-test", pid: 1, urls: [request.url] })
return Response.json({
version: "2.0.0-test",
pid: 1,
urls: [request.url],
paths: { tmp: "/tmp/opencode" },
})
}) as typeof globalThis.fetch
const transport = createServerTransport({
http: { url: "http://127.0.0.1:4100", password: "first" },
@@ -98,23 +103,23 @@ test("rotates HTTP and PTY clients together", async () => {
})
const initialPty = transport.pty
await transport.api.server.status()
await transport.api.server.info()
const replacement = transport.update({
url: "http://127.0.0.1:4200",
password: "second",
})
await transport.api.server.status()
await transport.api.server.info()
expect(replacement).toBe(transport.api)
expect(transport.pty).not.toBe(initialPty)
expect(transport.url).toBe("http://127.0.0.1:4200")
expect(requests).toEqual([
{
url: "http://127.0.0.1:4100/api/status",
url: "http://127.0.0.1:4100/api/info",
authorization: `Basic ${btoa("opencode:first")}`,
},
{
url: "http://127.0.0.1:4200/api/status",
url: "http://127.0.0.1:4200/api/info",
authorization: `Basic ${btoa("opencode:second")}`,
},
])

Some files were not shown because too many files have changed in this diff Show More