summaryrefslogtreecommitdiffhomepage
path: root/packages
diff options
context:
space:
mode:
authorAiden Cline <[email protected]>2026-04-29 23:35:59 -0500
committerGitHub <[email protected]>2026-04-29 23:35:59 -0500
commit3ef0aaf768aa488db102454bee1df116c00f2c6f (patch)
treeb60b57be7b57480d6e0e0fda237e322af283d510 /packages
parentd7701dbfb6c80fa82948cae2ddaf4df3963b668e (diff)
downloadopencode-3ef0aaf768aa488db102454bee1df116c00f2c6f.tar.gz
opencode-3ef0aaf768aa488db102454bee1df116c00f2c6f.zip
tweak: make azure onboarding ux a bit better (#25057)
Diffstat (limited to 'packages')
-rw-r--r--packages/opencode/src/cli/cmd/providers.ts46
-rw-r--r--packages/opencode/src/plugin/azure.ts26
-rw-r--r--packages/opencode/src/plugin/index.ts2
-rw-r--r--packages/opencode/src/provider/provider.ts33
4 files changed, 82 insertions, 25 deletions
diff --git a/packages/opencode/src/cli/cmd/providers.ts b/packages/opencode/src/cli/cmd/providers.ts
index 61fe4b2da..278522555 100644
--- a/packages/opencode/src/cli/cmd/providers.ts
+++ b/packages/opencode/src/cli/cmd/providers.ts
@@ -156,28 +156,38 @@ async function handlePluginAuth(plugin: { auth: PluginAuth }, provider: string,
}
if (method.type === "api") {
- if (method.authorize) {
- const key = await prompts.password({
- message: "Enter your API key",
- validate: (x) => (x && x.length > 0 ? undefined : "Required"),
+ const key = await prompts.password({
+ message: "Enter your API key",
+ validate: (x) => (x && x.length > 0 ? undefined : "Required"),
+ })
+ if (prompts.isCancel(key)) throw new UI.CancelledError()
+
+ const metadata = Object.keys(inputs).length ? { metadata: inputs } : {}
+ if (!method.authorize) {
+ await put(provider, {
+ type: "api",
+ key,
+ ...metadata,
})
- if (prompts.isCancel(key)) throw new UI.CancelledError()
-
- const result = await method.authorize(inputs)
- if (result.type === "failed") {
- prompts.log.error("Failed to authorize")
- }
- if (result.type === "success") {
- const saveProvider = result.provider ?? provider
- await put(saveProvider, {
- type: "api",
- key: result.key ?? key,
- })
- prompts.log.success("Login successful")
- }
prompts.outro("Done")
return true
}
+
+ const result = await method.authorize(inputs)
+ if (result.type === "failed") {
+ prompts.log.error("Failed to authorize")
+ }
+ if (result.type === "success") {
+ const saveProvider = result.provider ?? provider
+ await put(saveProvider, {
+ type: "api",
+ key: result.key ?? key,
+ ...metadata,
+ })
+ prompts.log.success("Login successful")
+ }
+ prompts.outro("Done")
+ return true
}
return false
diff --git a/packages/opencode/src/plugin/azure.ts b/packages/opencode/src/plugin/azure.ts
new file mode 100644
index 000000000..62792b3bd
--- /dev/null
+++ b/packages/opencode/src/plugin/azure.ts
@@ -0,0 +1,26 @@
+import type { Hooks, PluginInput } from "@opencode-ai/plugin"
+
+export async function AzureAuthPlugin(_input: PluginInput): Promise<Hooks> {
+ const prompts = []
+ if (!process.env.AZURE_RESOURCE_NAME) {
+ prompts.push({
+ type: "text" as const,
+ key: "resourceName",
+ message: "Enter Azure Resource Name",
+ placeholder: "e.g. my-models",
+ })
+ }
+
+ return {
+ auth: {
+ provider: "azure",
+ methods: [
+ {
+ type: "api",
+ label: "API key",
+ prompts,
+ },
+ ],
+ },
+ }
+}
diff --git a/packages/opencode/src/plugin/index.ts b/packages/opencode/src/plugin/index.ts
index 0313022c3..ac37823c3 100644
--- a/packages/opencode/src/plugin/index.ts
+++ b/packages/opencode/src/plugin/index.ts
@@ -17,6 +17,7 @@ import { CopilotAuthPlugin } from "./github-copilot/copilot"
import { gitlabAuthPlugin as GitlabAuthPlugin } from "opencode-gitlab-auth"
import { PoeAuthPlugin } from "opencode-poe-auth"
import { CloudflareAIGatewayAuthPlugin, CloudflareWorkersAuthPlugin } from "./cloudflare"
+import { AzureAuthPlugin } from "./azure"
import { Effect, Layer, Context, Stream } from "effect"
import { EffectBridge } from "@/effect/bridge"
import { InstanceState } from "@/effect/instance-state"
@@ -61,6 +62,7 @@ const INTERNAL_PLUGINS: PluginInstance[] = [
PoeAuthPlugin,
CloudflareWorkersAuthPlugin,
CloudflareAIGatewayAuthPlugin,
+ AzureAuthPlugin,
]
function isServerPlugin(value: unknown): value is PluginInstance {
diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts
index 702435d7d..fc835cf5e 100644
--- a/packages/opencode/src/provider/provider.ts
+++ b/packages/opencode/src/provider/provider.ts
@@ -199,12 +199,26 @@ function custom(dep: CustomDep): Record<string, CustomLoader> {
}),
azure: Effect.fnUntraced(function* (provider: Info) {
const env = yield* dep.env()
+ const auth = yield* dep.auth(provider.id)
const resource = iife(() => {
- const name = provider.options?.resourceName
- if (typeof name === "string" && name.trim() !== "") return name
- return env["AZURE_RESOURCE_NAME"]
+ return [
+ provider.options?.resourceName,
+ auth?.type === "api" ? auth.metadata?.resourceName : undefined,
+ env["AZURE_RESOURCE_NAME"],
+ ].find((name) => typeof name === "string" && name.trim() !== "")
})
+ if (!resource && !provider.options?.baseURL) {
+ return {
+ autoload: false,
+ async getModel() {
+ throw new Error(
+ "AZURE_RESOURCE_NAME is missing, set it using env var or reconnecting the azure provider and setting it",
+ )
+ },
+ }
+ }
+
return {
autoload: false,
async getModel(sdk: any, modelID: string, options?: Record<string, any>) {
@@ -215,11 +229,16 @@ function custom(dep: CustomDep): Record<string, CustomLoader> {
return sdk.responses(modelID)
}
},
- options: {},
- vars(_options) {
- return {
- ...(resource && { AZURE_RESOURCE_NAME: resource }),
+ options: {
+ resourceName: resource,
+ },
+ vars(_options): Record<string, string> {
+ if (resource) {
+ return {
+ AZURE_RESOURCE_NAME: resource,
+ }
}
+ return {}
},
}
}),