iobroker.ai-usage 0.1.0 → 0.3.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 (68) hide show
  1. package/README.md +84 -12
  2. package/admin/custom/assets/Components-Bq1fGAd7.js +1 -0
  3. package/admin/custom/assets/ConfigPanel-DGMF4_qT.js +1 -0
  4. package/admin/custom/assets/_virtual_mf-localSharedImportMap___mfe_internal__AiUsageComponentSet__mf_owner__1-DKcsNxEw.js +1 -0
  5. package/admin/custom/assets/_virtual_mf___mfe_internal__AiUsageComponentSet__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-DzPBJWNQ.js +1243 -0
  6. package/admin/custom/assets/_virtual_mf___mfe_internal__AiUsageComponentSet__mf_owner__1__loadShare___mf_0_iobroker_mf_1_json_mf_2_config__loadShare__.js-DEdJInQG.js +1494 -0
  7. package/admin/custom/assets/_virtual_mf___mfe_internal__AiUsageComponentSet__mf_owner__1__loadShare__react_mf_2_dom_mf_1_client__loadShare__.js-CFn_lBXc.js +9 -0
  8. package/admin/custom/assets/_virtual_mf___mfe_internal__AiUsageComponentSet__mf_owner__1__prebuild___mf_0_iobroker_mf_1_gui_mf_2_components__prebuild__-DeLUTSLT.js +1 -0
  9. package/admin/custom/assets/hostInit-DoGxgbHj.js +1 -0
  10. package/admin/custom/assets/index-CKngiVu3.js +1 -0
  11. package/admin/custom/assets/lib-MY71LxhX.js +3 -0
  12. package/admin/custom/assets/mf-entry-bootstrap-0-eec08a33.js +35 -0
  13. package/admin/custom/assets/rolldown-runtime-C0FnF6B9.js +1 -0
  14. package/admin/custom/assets/virtualExposes-Dc9myzsk.js +1 -0
  15. package/admin/custom/assets/virtual_mf-REMOTE_ENTRY_ID___mfe_internal__AiUsageComponentSet__customComponents_js-CP4YA3u3.js +1 -0
  16. package/admin/custom/assets/virtual_mf-exposes-ssr___mfe_internal__AiUsageComponentSet__customComponents_js-DlNU_Z38.js +2 -0
  17. package/admin/custom/assets/virtual_mf-exposes___mfe_internal__AiUsageComponentSet__customComponents_js-CEfffc0D.js +2 -0
  18. package/admin/custom/assets/vite-preload-helper-B7qeedMF.js +1 -0
  19. package/admin/custom/customComponents.js +1 -0
  20. package/admin/custom/i18n/de.json +32 -0
  21. package/admin/custom/i18n/en.json +32 -0
  22. package/admin/custom/i18n/es.json +32 -0
  23. package/admin/custom/i18n/fr.json +32 -0
  24. package/admin/custom/i18n/it.json +32 -0
  25. package/admin/custom/i18n/nl.json +32 -0
  26. package/admin/custom/i18n/pl.json +32 -0
  27. package/admin/custom/i18n/pt.json +32 -0
  28. package/admin/custom/i18n/ru.json +32 -0
  29. package/admin/custom/i18n/uk.json +32 -0
  30. package/admin/custom/i18n/zh-cn.json +32 -0
  31. package/admin/custom/mf-manifest.json +1 -0
  32. package/admin/i18n/de.json +9 -27
  33. package/admin/i18n/en.json +9 -27
  34. package/admin/i18n/es.json +9 -27
  35. package/admin/i18n/fr.json +9 -27
  36. package/admin/i18n/it.json +9 -27
  37. package/admin/i18n/nl.json +9 -27
  38. package/admin/i18n/pl.json +9 -27
  39. package/admin/i18n/pt.json +9 -27
  40. package/admin/i18n/ru.json +9 -27
  41. package/admin/i18n/uk.json +9 -27
  42. package/admin/i18n/zh-cn.json +9 -27
  43. package/admin/jsonConfig.json +7 -166
  44. package/build/lib/http.js +29 -0
  45. package/build/lib/http.js.map +2 -2
  46. package/build/lib/jwt.js +59 -0
  47. package/build/lib/jwt.js.map +7 -0
  48. package/build/lib/poll-engine.js +14 -0
  49. package/build/lib/poll-engine.js.map +2 -2
  50. package/build/lib/provider.js.map +2 -2
  51. package/build/lib/providers/chatgpt-auth.js +125 -0
  52. package/build/lib/providers/chatgpt-auth.js.map +7 -0
  53. package/build/lib/providers/chatgpt-sub.js +121 -0
  54. package/build/lib/providers/chatgpt-sub.js.map +7 -0
  55. package/build/lib/providers/claude-auth.js.map +2 -2
  56. package/build/lib/providers/claude-sub.js.map +2 -2
  57. package/build/lib/providers/gemini-auth.js +135 -0
  58. package/build/lib/providers/gemini-auth.js.map +7 -0
  59. package/build/lib/providers/gemini-sub.js +147 -0
  60. package/build/lib/providers/gemini-sub.js.map +7 -0
  61. package/build/lib/pure-helpers.js +42 -7
  62. package/build/lib/pure-helpers.js.map +2 -2
  63. package/build/lib/sign-in.js +38 -0
  64. package/build/lib/sign-in.js.map +7 -0
  65. package/build/main.js +299 -69
  66. package/build/main.js.map +2 -2
  67. package/io-package.json +42 -26
  68. package/package.json +5 -2
package/README.md CHANGED
@@ -6,9 +6,10 @@
6
6
 
7
7
  **Support:** [![Ko-fi](https://img.shields.io/badge/Ko--fi-Support-ff5e5b?logo=ko-fi)](https://ko-fi.com/krobipd) [![PayPal](https://img.shields.io/badge/Donate-PayPal-blue.svg)](https://paypal.me/krobipd)
8
8
 
9
- Monitors your AI accounts in ioBroker: usage windows, limits, credits and costs of
10
- Claude, OpenAI, OpenRouter and DeepSeek as clean datapoints — for
11
- dashboards, history and automations ("send a message at 90 % of the weekly limit").
9
+ Monitors your AI accounts in ioBroker: usage windows, limits, credits and costs of your
10
+ Claude, ChatGPT and Google subscriptions plus OpenRouter, DeepSeek, OpenAI and Anthropic API
11
+ accounts — as clean datapoints for dashboards, history and automations ("send a message at
12
+ 90 % of the weekly limit").
12
13
 
13
14
  ---
14
15
 
@@ -17,6 +18,7 @@ dashboards, history and automations ("send a message at 90 % of the weekly limit
17
18
  - **Per-account monitoring** — one device node per AI account with harmonised datapoints: limit windows (percent + reset time), credits, costs and tokens
18
19
  - **Totals** — summed costs, the highest limit utilisation across all accounts, and one `limitReached` trigger for automations
19
20
  - **Warn threshold per account** — a single notification when an account crosses its threshold
21
+ - **Three subscriptions** — Claude, ChatGPT and Google are signed in with your own account; the settings page guides each sign-in step by step
20
22
  - **Central credentials** — API keys live in the admin's central credential storage and are shared with the admin AI assistant
21
23
  - **Read-only by design** — the adapter only reads usage data; it never calls, configures or writes to any AI service
22
24
  - **Throttle-safe polling** — a hard minimum interval and automatic backoff protect your accounts from provider rate-limit lockouts
@@ -27,15 +29,59 @@ dashboards, history and automations ("send a message at 90 % of the weekly limit
27
29
 
28
30
  - Node.js >= 22
29
31
  - ioBroker js-controller >= 7.2.2
30
- - **ioBroker Admin >= 8.0.0** — the adapter uses the admin's central credential storage
32
+ - **ioBroker Admin >= 8.0.1** — the adapter uses the admin's central credential storage
31
33
 
32
34
  ---
33
35
 
34
36
  ## Configuration
35
37
 
38
+ The instance settings show one list of AI accounts. Switch on what you want to monitor:
39
+
40
+ | Account | How it is connected |
41
+ |---------|---------------------|
42
+ | **Claude subscription** | Sign in once with your Claude account (guided, in the settings) |
43
+ | **ChatGPT subscription** | Sign in once with your ChatGPT account (guided, in the settings) |
44
+ | **Google/Gemini subscription** | Sign in once with your Google account (guided, in the settings) |
45
+ | **OpenRouter, DeepSeek** | Pick the stored key from the admin's central credential storage |
46
+ | **OpenAI, Anthropic (organisation)** | Needs an **admin key** of your organisation — see below |
47
+
48
+ ### Signing in to a subscription
49
+
50
+ Each provider needs a different last step, and the settings page tells you which one:
51
+
52
+ - **Claude** — open the sign-in page, log in, copy the code shown there and paste it back.
53
+ - **ChatGPT** — the adapter shows a short code; type it on the OpenAI page it links to. The
54
+ settings page notices by itself once you confirmed. The adapter signs in separately from the
55
+ Codex CLI and does not disturb its session.
56
+ - **Google/Gemini** — open the sign-in page and log in. Google then sends the result to
57
+ `localhost`, so **your browser shows an error page ("site cannot be reached"). That is expected**
58
+ — the address bar still carries the sign-in result. Copy the **whole address** and paste it back.
59
+
60
+ > The three subscription endpoints are **not officially documented**. They are the same ones the
61
+ > providers' own tools use, but they can change without notice. If a subscription stops delivering
62
+ > data, that is the likely reason.
63
+ >
64
+ > **Verification status:** the Claude sign-in and read-out were tested against a live subscription.
65
+ > ChatGPT and Google/Gemini were built from the requests those providers' own tools make, but no
66
+ > live subscription of either was available to test them on — please open an issue if a value looks
67
+ > wrong or a sign-in step behaves differently than described.
68
+
69
+ ### API accounts with a key
70
+
71
+ Keys come from the admin's central credential storage (Settings → Credentials) and are shared with
72
+ the admin AI assistant. Two of them need a **different** key than the assistant uses:
73
+
74
+ - **OpenAI** — the usage and cost reports are organisation endpoints and need an **admin key**
75
+ created in the organisation settings.
76
+ - **Anthropic** — same, an **admin key** (`sk-ant-admin…`), which only an organisation
77
+ administrator can create. Personal accounts without an organisation cannot deliver these reports
78
+ at all; use the Claude subscription row instead.
79
+
80
+ Add such a key as its own entry in the credential storage (template "Key") and pick it in the row.
81
+
36
82
  | Option | Description | Default |
37
83
  |--------|-------------|---------|
38
- | **Accounts** | One row per AI account: name, provider, credential from the central storage, warn threshold, active flag | — |
84
+ | **Warn at %** | Per account: one notification when a limit window crosses this utilisation | 80 |
39
85
  | **Poll interval** | How often each account is queried (seconds) | 300 |
40
86
  | **Notifications** | One notification on threshold crossing or broken credentials | on |
41
87
 
@@ -51,12 +97,14 @@ ai-usage.0.
51
97
  │ ├── maxLimitPercent — highest window utilisation of any account
52
98
  │ ├── warningsActive — number of accounts above their threshold
53
99
  │ └── limitReached — any window full (automation trigger)
54
- └── <account>. — one device per configured account
100
+ ├── claude / chatgpt / gemini — one node per subscription
101
+ │ ├── info.* — provider, reachable, signed in, last update
102
+ │ ├── limits.<window>.* — percent + reset time (session, week, per model, …)
103
+ │ └── credits.* — where the provider reports a balance
104
+ └── <name>-api — one node per key-based account
55
105
  ├── info.* — provider, reachable, last update
56
- ├── limits.<window>.* — percent + reset time (session, week, per model, …)
57
- ├── credits.* — granted budget: used / limit / remaining / percent
58
- ├── costs.* — real money: today / month / projected
59
- └── tokens.* — token counters (API accounts)
106
+ ├── credits.* / costs.* — granted budget and real money
107
+ └── tokens.* — token counters
60
108
  ```
61
109
 
62
110
  Only what an account's source actually delivers is created.
@@ -66,8 +114,19 @@ Only what an account's source actually delivers is created.
66
114
  ## Troubleshooting
67
115
 
68
116
  ### An account shows `reachable = false`
69
- Check the credential in the admin's central credential storage (Settings → Credentials)
70
- and the adapter log. Authentication errors raise one notification with the reason.
117
+ Check the adapter log — an authentication failure states the reason and raises one notification.
118
+ For a subscription this usually means the sign-in expired: sign in again in the settings. For an
119
+ OpenAI or Anthropic account it usually means the key is not an admin key (see Configuration).
120
+
121
+ ### A subscription says "not signed in" although you just signed in
122
+ Save the settings first, then sign in — the row needs a saved account to attach the sign-in to.
123
+ After a successful sign-in the adapter queries the account immediately, so values appear within
124
+ seconds.
125
+
126
+ ### The object tree changed after updating to 0.3.0
127
+ Accounts now live under fixed ids (`claude`, `chatgpt`, `gemini`, `<name>-api`) and the separate
128
+ `auth` branch is gone — the sign-in state moved into `<account>.info.signedIn`. Old nodes are
129
+ removed automatically, and an existing Claude sign-in is carried over.
71
130
 
72
131
  ---
73
132
 
@@ -77,6 +136,19 @@ and the adapter log. Authentication errors raise one notification with the reaso
77
136
  Placeholder for the next version (at the beginning of the line):
78
137
  ### **WORK IN PROGRESS**
79
138
  -->
139
+ ### 0.3.0 (2026-08-26)
140
+
141
+ - New: ChatGPT and Google/Gemini subscriptions can now be monitored like the Claude one — each with its own guided sign-in that the settings page walks you through step by step
142
+ - New: The ChatGPT and Gemini readouts use the same endpoints the providers' own tools use, but no live subscription was available to test them on — please report anything that looks wrong
143
+ - Changed: Each account now owns exactly one node in the object tree (`claude`, `chatgpt`, `gemini`, `<name>-api`); the separate sign-in branch is gone and old nodes are cleaned up automatically
144
+ - Fixed: After signing in, the account is queried immediately instead of waiting for the next poll — no restart needed
145
+ - Fixed: OpenAI and Anthropic rows now state that they need an organisation admin key, instead of failing with an unexplained rejection
146
+
147
+ ### 0.2.0 (2026-08-26)
148
+
149
+ - Changed: Completely new settings page — your stored AI credentials appear as simple on/off switches instead of a table, and new keys are picked up straight from the admin credential storage
150
+ - Fixed: The Claude subscription sign-in works reliably now — a guided card with live status, and the sign-in link stays valid until it is used instead of regenerating while you type
151
+
80
152
  ### 0.1.0 (2026-08-25)
81
153
 
82
154
  - New: First release — reads usage limits, credits and costs of your Claude, OpenAI, Anthropic, OpenRouter and DeepSeek accounts into datapoints, with one warning at your chosen threshold
@@ -0,0 +1 @@
1
+ import{t as e}from"./ConfigPanel-DGMF4_qT.js";var t={ConfigPanel:e};export{t as default};
@@ -0,0 +1 @@
1
+ import{t as e}from"./_virtual_mf___mfe_internal__AiUsageComponentSet__mf_owner__1__loadShare___mf_0_iobroker_mf_1_json_mf_2_config__loadShare__.js-DEdJInQG.js";import{Br as t,Dr as n,Er as r,Fi as i,Ha as a,Hi as o,Or as s,Ti as c,Tr as l,Va as u,Xr as d,_o as f,ai as p,ci as m,ei as h,ga as g,ii as _,in as v,kr as y,li as b,ni as x,oi as S}from"./_virtual_mf___mfe_internal__AiUsageComponentSet__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-DzPBJWNQ.js";f();var C=[{provider:`claude-sub`,label:`Claude`,captionKey:`aiu_capClaude`},{provider:`chatgpt-sub`,label:`ChatGPT`,captionKey:`aiu_capChatgpt`},{provider:`gemini-sub`,label:`Gemini`,captionKey:`aiu_capGemini`}];function w(e,t){let n=`${e} ${t}`.toLowerCase();return n.includes(`gemini`)?null:n.includes(`anthropic`)||n.includes(`claude`)?{provider:`anthropic-api`,label:`Anthropic`,needsAdminKey:!0}:n.includes(`chatgpt`)||n.includes(`openai`)?{provider:`openai`,label:`OpenAI`,needsAdminKey:!0}:n.includes(`deepseek`)?{provider:`deepseek`,label:`DeepSeek`,needsAdminKey:!1}:n.includes(`openrouter`)||n.includes(`router`)?{provider:`openrouter`,label:`OpenRouter`,needsAdminKey:!1}:null}var T=[{provider:`openrouter`,label:`OpenRouter`,needsAdminKey:!1},{provider:`deepseek`,label:`DeepSeek`,needsAdminKey:!1},{provider:`openai`,label:`OpenAI`,needsAdminKey:!0},{provider:`anthropic-api`,label:`Anthropic`,needsAdminKey:!0}];function E(e,t){return e.find(e=>e.provider===t)}function D(e,t,n,r){let i=e.filter(e=>e.provider!==t);return n?[...i,{name:r,provider:t,credentialId:``,warnThreshold:80,enabled:!0}]:i}function O(e,t,n,r){let i=e.filter(e=>e.credentialId!==t.id);return!r||!n?i:[...i,{name:t.name,provider:n,credentialId:t.id,warnThreshold:80,enabled:!0}]}function k(e,t,n){let r=Math.min(100,Math.max(10,Math.round(Number(n))||80));return e.map(e=>(t.credentialId?e.credentialId===t.credentialId:e.provider===t.provider)?{...e,warnThreshold:r}:e)}var A=class extends e{constructor(e){super(e),g(this,`timer`,null),this.state={...this.state,credentials:[],credentialsLoaded:!1,signIn:{},drafts:{},providerChoice:{},busy:``}}async componentDidMount(){var e;(e=super.componentDidMount)==null||e.call(this),await this.loadCredentials(),await this.refreshSignIn(),this.timer=setInterval(()=>void this.refreshSignIn(),4e3)}componentWillUnmount(){var e;this.timer&&=(clearInterval(this.timer),null),(e=super.componentWillUnmount)==null||e.call(this)}async loadCredentials(){try{let e=await this.props.oContext.socket.getObjectViewSystem(`config`,`system.credentials.`,`system.credentials.香`),t=Object.values(e||{}).filter(e=>{var t;return!!e&&((t=e.native)==null?void 0:t.type)===`ai`}).map(e=>{var t,n;let r=e._id.substring(19),i=(t=e.common)==null?void 0:t.name,a=typeof i==`string`?i:(i==null?void 0:i.en)||Object.values(i||{})[0]||r;return{id:e._id,suffix:r,name:a,icon:typeof((n=e.common)==null?void 0:n.icon)==`string`?e.common.icon:void 0}}).sort((e,t)=>e.name.localeCompare(t.name));this.setState({credentials:t,credentialsLoaded:!0})}catch{this.setState({credentialsLoaded:!0})}}async refreshSignIn(){if(!this.props.alive)return;let e={};for(let t of C){if(!E(this.accounts(),t.provider))continue;let n=await this.ask(`signInStatus`,t.provider);n&&(e[t.provider]=n)}this.setState({signIn:e})}async ask(e,t,n){let r=this.props.oContext;try{let i=await r.socket.sendTo(`${r.adapterName}.${r.instance}`,e,{provider:t,value:n});return!i||i.error?{status:`failed`,reason:(i==null?void 0:i.error)||v.t(`aiu_noAnswer`)}:i}catch{return null}}async run(e,t,n){this.setState({busy:t});let r=await this.ask(e,t,n);this.setState(e=>({busy:``,signIn:r?{...e.signIn,[t]:r}:e.signIn,drafts:{...e.drafts,[t]:``}}))}accounts(){let t=e.getValue(this.props.data,`accounts`);return Array.isArray(t)?t:[]}commit(e){this.onChange(`accounts`,e)}renderThreshold(e,t,n){return u(d,{size:`small`,type:`number`,label:v.t(`aiu_warnAt`),defaultValue:t.warnThreshold||80,onBlur:e=>this.commit(k(this.accounts(),n,e.target.value)),slotProps:{htmlInput:{min:10,max:100,style:{width:60}},inputLabel:{shrink:!0}},sx:{ml:`auto`}},e)}renderSignIn(e){let t=this.state.signIn[e],i=this.state.busy===e;if(!this.props.alive)return u(c,{severity:`warning`,children:v.t(`aiu_instanceNotRunning`)});if(this.props.changed)return u(c,{severity:`info`,children:v.t(`aiu_saveFirst`)});if(!t)return u(b,{size:20});if(t.status===`signed-in`)return a(x,{sx:{display:`flex`,alignItems:`center`,gap:1,flexWrap:`wrap`},children:[u(y,{color:`success`}),u(h,{sx:{color:`success.main`},children:v.t(`aiu_signedIn`)}),u(_,{size:`small`,startIcon:u(r,{}),disabled:i,onClick:()=>void this.run(`signOut`,e),children:v.t(`aiu_signOut`)})]});if(t.status===`awaiting-device`)return a(x,{sx:{display:`flex`,flexDirection:`column`,gap:1.5},children:[u(h,{variant:`body2`,children:v.t(`aiu_deviceStep1`)}),a(x,{sx:{display:`flex`,gap:1,alignItems:`center`,flexWrap:`wrap`},children:[u(m,{label:t.userCode,sx:{fontSize:20,fontFamily:`monospace`,py:2.5,px:1}}),u(_,{size:`small`,startIcon:u(s,{}),onClick:()=>{var e;(e=navigator.clipboard)==null||e.writeText(t.userCode)},children:v.t(`aiu_copyCode`)}),u(_,{variant:`contained`,startIcon:u(n,{}),href:t.verificationUrl,target:`_blank`,rel:`noopener noreferrer`,children:v.t(`aiu_openPage`)})]}),u(c,{severity:`info`,children:v.t(`aiu_deviceWaiting`)})]});if(t.status===`awaiting-paste`){let r=t.flow===`paste-url`;return a(x,{sx:{display:`flex`,flexDirection:`column`,gap:1.5},children:[u(h,{variant:`body2`,children:v.t(r?`aiu_googleStep1`:`aiu_claudeStep1`)}),a(x,{sx:{display:`flex`,gap:1,flexWrap:`wrap`},children:[u(_,{variant:`contained`,startIcon:u(n,{}),href:t.url,target:`_blank`,rel:`noopener noreferrer`,children:v.t(`aiu_openSignIn`)}),u(_,{variant:`outlined`,startIcon:u(s,{}),onClick:()=>{var e;(e=navigator.clipboard)==null||e.writeText(t.url)},children:v.t(`aiu_copyLink`)})]}),r?u(c,{severity:`warning`,children:v.t(`aiu_googleErrorPageHint`)}):null,u(h,{variant:`body2`,children:v.t(r?`aiu_googleStep2`:`aiu_claudeStep2`)}),a(x,{sx:{display:`flex`,gap:1,alignItems:`center`,flexWrap:`wrap`},children:[u(d,{size:`small`,label:v.t(r?`aiu_addressLabel`:`aiu_codeLabel`),value:this.state.drafts[e]??``,onChange:t=>this.setState(n=>({drafts:{...n.drafts,[e]:t.target.value}})),sx:{minWidth:340,flexGrow:1}}),u(_,{variant:`contained`,disabled:i||!(this.state.drafts[e]??``).trim(),onClick:()=>void this.run(`signInSubmit`,e,this.state.drafts[e]),children:i?u(b,{size:20}):v.t(`aiu_redeem`)})]})]})}return a(x,{sx:{display:`flex`,flexDirection:`column`,gap:1},children:[t.status===`failed`?u(c,{severity:`error`,children:t.reason}):null,u(x,{children:u(_,{variant:`contained`,startIcon:u(n,{}),disabled:i,onClick:()=>void this.run(`signInStart`,e),children:i?u(b,{size:20}):v.t(`aiu_startSignIn`)})})]})}renderSubscriptionRow(e){let n=E(this.accounts(),e.provider);return a(x,{children:[a(x,{sx:{display:`flex`,alignItems:`center`,gap:1.5,py:1,borderBottom:1,borderColor:`divider`},children:[u(o,{sx:{width:28,height:28,bgcolor:`transparent`},children:u(l,{fontSize:`small`,color:`primary`})}),a(x,{sx:{minWidth:180},children:[u(h,{children:e.label}),u(h,{variant:`caption`,sx:{opacity:.7},children:v.t(e.captionKey)})]}),n?this.renderThreshold(`${e.provider}-t`,n,{provider:e.provider}):null,u(t,{checked:!!n,onChange:t=>this.commit(D(this.accounts(),e.provider,t.target.checked,e.label)),sx:{ml:n?0:`auto`}})]}),n?u(x,{sx:{pl:6,py:1.5,borderBottom:1,borderColor:`divider`},children:this.renderSignIn(e.provider)}):null]},e.provider)}renderCredentialRow(e){var n;let r=this.accounts(),s=r.find(t=>t.credentialId===e.id),f=w(e.suffix,e.name),p=(s==null?void 0:s.provider)||(f==null?void 0:f.provider)||this.state.providerChoice[e.id]||``,m=((n=T.find(e=>e.provider===p))==null?void 0:n.needsAdminKey)??(f==null?void 0:f.needsAdminKey)??!1,g=!f&&!this.state.providerChoice[e.id]&&!s;return a(x,{sx:{borderBottom:1,borderColor:`divider`},children:[a(x,{sx:{display:`flex`,alignItems:`center`,gap:1.5,py:1},children:[u(o,{src:e.icon,sx:{width:28,height:28,bgcolor:`transparent`},children:u(l,{fontSize:`small`})}),a(x,{sx:{minWidth:180},children:[u(h,{children:e.name}),u(h,{variant:`caption`,sx:{opacity:.7},children:v.t(`aiu_storedKey`)})]}),g?u(d,{select:!0,size:`small`,label:v.t(`aiu_provider`),value:this.state.providerChoice[e.id]||``,onChange:t=>this.setState(n=>({providerChoice:{...n.providerChoice,[e.id]:t.target.value}})),sx:{minWidth:170},children:T.map(e=>u(i,{value:e.provider,children:e.label},e.provider))}):null,s?this.renderThreshold(`${e.id}-t`,s,{credentialId:e.id}):null,u(t,{checked:!!s,disabled:!p,onChange:t=>this.commit(O(r,e,p,t.target.checked)),sx:{ml:s?0:`auto`}})]}),s&&m?u(c,{severity:`info`,sx:{mb:1},children:v.t(`aiu_adminKeyHint`)}):null]},e.id)}renderItem(){return u(x,{"data-testid":`aiu-config`,sx:{maxWidth:760},children:u(p,{variant:`outlined`,children:a(S,{children:[u(h,{variant:`h6`,sx:{mb:.5},children:v.t(`aiu_storedTitle`)}),u(h,{variant:`body2`,sx:{opacity:.8,mb:1},children:v.t(`aiu_storedHint`)}),C.map(e=>this.renderSubscriptionRow(e)),this.state.credentialsLoaded?this.state.credentials.map(e=>this.renderCredentialRow(e)):u(b,{size:24,sx:{mt:1}}),this.state.credentialsLoaded&&this.state.credentials.length===0?u(c,{severity:`info`,sx:{mt:1},children:v.t(`aiu_noCredentials`)}):null]})})})}};export{A as t};
@@ -0,0 +1 @@
1
+ import{t as e}from"./vite-preload-helper-B7qeedMF.js";var t={react:async()=>await e(()=>import(`./_virtual_mf___mfe_internal__AiUsageComponentSet__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-DzPBJWNQ.js`).then(e=>(e.yo(),e.vo)),[],import.meta.url),"react/jsx-runtime":async()=>await e(()=>import(`./_virtual_mf___mfe_internal__AiUsageComponentSet__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-DzPBJWNQ.js`).then(e=>e.Ua),[],import.meta.url),"react-dom":async()=>await e(()=>import(`./_virtual_mf___mfe_internal__AiUsageComponentSet__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-DzPBJWNQ.js`).then(e=>(e.Xa(),e.Ya)),[],import.meta.url),"react-dom/client":async()=>await e(()=>import(`./_virtual_mf___mfe_internal__AiUsageComponentSet__mf_owner__1__loadShare__react_mf_2_dom_mf_1_client__loadShare__.js-CFn_lBXc.js`).then(e=>e.n),[],import.meta.url),"@mui/material":async()=>await e(()=>import(`./_virtual_mf___mfe_internal__AiUsageComponentSet__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-DzPBJWNQ.js`).then(e=>e.Wi),[],import.meta.url),"@mui/icons-material":async()=>await e(()=>import(`./_virtual_mf___mfe_internal__AiUsageComponentSet__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-DzPBJWNQ.js`).then(e=>e.wr),[],import.meta.url),"@iobroker/gui-components":async()=>await e(()=>import(`./_virtual_mf___mfe_internal__AiUsageComponentSet__mf_owner__1__prebuild___mf_0_iobroker_mf_1_gui_mf_2_components__prebuild__-DeLUTSLT.js`),[],import.meta.url),"@iobroker/json-config":async()=>await e(()=>import(`./_virtual_mf___mfe_internal__AiUsageComponentSet__mf_owner__1__loadShare___mf_0_iobroker_mf_1_json_mf_2_config__loadShare__.js-DEdJInQG.js`).then(e=>e.n),[],import.meta.url)},n={react:{name:`react`,version:`19.2.8`,scope:[`default`],loaded:!1,eager:!1,from:`AiUsageComponentSet`,canLiveRebind:!0,async get(){n.react.loaded=!0;let{react:e}=t,r={...await e()};return r.__esModule!==!0&&Object.defineProperty(r,"__esModule",{value:!0,enumerable:!1}),function(){return r}},shareConfig:{singleton:!0,requiredVersion:`*`,strictVersion:!1,eager:!1}},"react/jsx-runtime":{name:`react/jsx-runtime`,version:`19.2.8`,scope:[`default`],loaded:!1,eager:!1,from:`AiUsageComponentSet`,canLiveRebind:!0,async get(){n[`react/jsx-runtime`].loaded=!0;let{"react/jsx-runtime":e}=t,r={...await e()};return r.__esModule!==!0&&Object.defineProperty(r,"__esModule",{value:!0,enumerable:!1}),function(){return r}},shareConfig:{singleton:!0,requiredVersion:`*`,strictVersion:!1,eager:!1}},"react-dom":{name:`react-dom`,version:`19.2.8`,scope:[`default`],loaded:!1,eager:!1,from:`AiUsageComponentSet`,canLiveRebind:!0,async get(){n[`react-dom`].loaded=!0;let{"react-dom":e}=t,r={...await e()};return r.__esModule!==!0&&Object.defineProperty(r,"__esModule",{value:!0,enumerable:!1}),function(){return r}},shareConfig:{singleton:!0,requiredVersion:`*`,strictVersion:!1,eager:!1}},"react-dom/client":{name:`react-dom/client`,version:`19.2.8`,scope:[`default`],loaded:!1,eager:!1,from:`AiUsageComponentSet`,canLiveRebind:!0,async get(){n[`react-dom/client`].loaded=!0;let{"react-dom/client":e}=t,r={...await e()};return r.__esModule!==!0&&Object.defineProperty(r,"__esModule",{value:!0,enumerable:!1}),function(){return r}},shareConfig:{singleton:!0,requiredVersion:`*`,strictVersion:!1,eager:!1}},"@mui/material":{name:`@mui/material`,version:`9.3.1`,scope:[`default`],loaded:!1,eager:!1,from:`AiUsageComponentSet`,canLiveRebind:!0,async get(){n[`@mui/material`].loaded=!0;let{"@mui/material":e}=t,r={...await e()};return r.__esModule!==!0&&Object.defineProperty(r,"__esModule",{value:!0,enumerable:!1}),function(){return r}},shareConfig:{singleton:!0,requiredVersion:`*`,strictVersion:!1,eager:!1}},"@mui/icons-material":{name:`@mui/icons-material`,version:`9.3.1`,scope:[`default`],loaded:!1,eager:!1,from:`AiUsageComponentSet`,canLiveRebind:!0,async get(){n[`@mui/icons-material`].loaded=!0;let{"@mui/icons-material":e}=t,r={...await e()};return r.__esModule!==!0&&Object.defineProperty(r,"__esModule",{value:!0,enumerable:!1}),function(){return r}},shareConfig:{singleton:!0,requiredVersion:`*`,strictVersion:!1,eager:!1}},"@iobroker/gui-components":{name:`@iobroker/gui-components`,version:`10.1.0`,scope:[`default`],loaded:!1,eager:!1,from:`AiUsageComponentSet`,canLiveRebind:!1,async get(){n[`@iobroker/gui-components`].loaded=!0;let{"@iobroker/gui-components":e}=t,r={...await e()};return r.__esModule!==!0&&Object.defineProperty(r,"__esModule",{value:!0,enumerable:!1}),function(){return r}},shareConfig:{singleton:!0,requiredVersion:`*`,strictVersion:!1,eager:!1}},"@iobroker/json-config":{name:`@iobroker/json-config`,version:`9.0.22`,scope:[`default`],loaded:!1,eager:!1,from:`AiUsageComponentSet`,canLiveRebind:!0,async get(){n[`@iobroker/json-config`].loaded=!0;let{"@iobroker/json-config":e}=t,r={...await e()};return r.__esModule!==!0&&Object.defineProperty(r,"__esModule",{value:!0,enumerable:!1}),function(){return r}},shareConfig:{singleton:!0,requiredVersion:`*`,strictVersion:!1,eager:!1}}},r=[];export{r as usedRemotes,n as usedShared};