opencode-openwebui-authentik 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +7 -0
  2. package/index.js +26 -5
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -20,6 +20,13 @@ you don't need an Open WebUI API key.
20
20
  you: right after login and every 5 minutes. Models from `/api/models` that aren't in your
21
21
  config are added; configured models that Open WebUI no longer serves are removed. Models
22
22
  you configure keep your settings (name, limits), so list a model only to override them.
23
+ - A model's effort levels (opencode variants) come from its Open WebUI model control: the
24
+ one keyed `thinking`, or the model's only control. Each option becomes a variant, such as
25
+ `opencode run -m home-ai/deepseek-v4.1-flash#max`, and Open WebUI applies the params the
26
+ admin set for it. These variants replace any variants from your config or opencode's
27
+ catalog. Models without a control keep their own variants. Non-admin users need the
28
+ `chat.controls` and `chat.params` permissions; otherwise Open WebUI ignores the choice and
29
+ uses the default.
23
30
  - Tokens refresh automatically. If authentik rejects a request, the plugin asks authentik
24
31
  whether the token is still valid. Only a dead token marks the login as needing a new
25
32
  sign-in; a passing glitch is retried once and clears itself.
package/index.js CHANGED
@@ -2,6 +2,7 @@ const MARKER = "openwebuiAuthentik"
2
2
  const SETTINGS = ["authentikURL", "cliClientID", "proxyClientID"]
3
3
  const DEFAULT_CLI_CLIENT_ID = "open-webui-cli"
4
4
  const MODELS_REFRESH_MINUTES = 5
5
+ const EFFORT_CONTROL = "thinking"
5
6
 
6
7
  const METHOD_ID = "authentik"
7
8
  const AUTHORIZE_PATH = "/application/o/authorize/"
@@ -96,10 +97,11 @@ async function manage(ctx, settings, shutdown) {
96
97
  if (!models) return
97
98
  const configured = new Set(editor.list(config.providerID).map((model) => model.id))
98
99
  for (const id of configured) if (!models.has(id)) editor.remove(config.providerID, id)
99
- for (const [id, name] of models) {
100
- if (configured.has(id)) continue
100
+ for (const [id, served] of models) {
101
+ if (configured.has(id) && !served.variants.length) continue
101
102
  editor.update(config.providerID, id, (model) => {
102
- model.name = name
103
+ if (!configured.has(id)) model.name = served.name
104
+ if (served.variants.length) model.variants = structuredClone(served.variants)
103
105
  })
104
106
  }
105
107
  }),
@@ -281,7 +283,20 @@ async function onEvents(ctx, handlers, signal) {
281
283
  }
282
284
 
283
285
  function sameModels(a, b) {
284
- return a.size === b.size && [...a].every(([id, name]) => b.get(id) === name)
286
+ return JSON.stringify([...a]) === JSON.stringify([...b])
287
+ }
288
+
289
+ function effortVariants(model) {
290
+ const controls = model.info?.params?.model_controls
291
+ if (!isObject(controls)) return []
292
+ const keys = Object.keys(controls)
293
+ const key = keys.includes(EFFORT_CONTROL) ? EFFORT_CONTROL : keys.length === 1 ? keys[0] : undefined
294
+ const options = controls[key]?.options
295
+ if (!isObject(options)) return []
296
+ return Object.keys(options).map((option) => ({
297
+ id: option,
298
+ body: { params: { model_controls: { [model.id]: { [key]: option } } } },
299
+ }))
285
300
  }
286
301
 
287
302
  function createAuthentik(config, relogin, shutdown, reread) {
@@ -562,7 +577,13 @@ function createOpenWebUI(config, shutdown, rejection) {
562
577
  return new Map(
563
578
  body.data
564
579
  .filter((model) => typeof model?.id === "string" && model.id && !model.info?.meta?.hidden)
565
- .map((model) => [model.id, typeof model.name === "string" && model.name ? model.name : model.id]),
580
+ .map((model) => [
581
+ model.id,
582
+ {
583
+ name: typeof model.name === "string" && model.name ? model.name : model.id,
584
+ variants: effortVariants(model),
585
+ },
586
+ ]),
566
587
  )
567
588
  }
568
589
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-openwebui-authentik",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "opencode plugin: use Open WebUI behind authentik forward auth with your authentik login",
5
5
  "keywords": ["opencode", "opencode-plugin", "open-webui", "authentik"],
6
6
  "license": "MIT",