ompchamber 2.0.2 → 3.0.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.
- package/README.md +7 -6
- package/bunfig.toml +11 -0
- package/dist/client/index.html +16 -5
- package/dist/client/index.js +1393 -0
- package/dist/client/static/js/index-prbmx3yj.js +5123 -0
- package/dist/client/static/js/index-ranztes9.css +1 -0
- package/index.html +54 -0
- package/package.json +9 -10
- package/public/apple-touch-icon.png +0 -0
- package/public/icon-192x192.png +0 -0
- package/public/icon.svg +60 -0
- package/public/manifest.webmanifest +38 -0
- package/src/cli/lib/commands/serve.js +9 -5
- package/src/cli/lib/runtime.js +18 -7
- package/src/client/components/common/provider-icon/glyphs.ts +118 -0
- package/src/client/components/common/provider-icon/index.tsx +85 -0
- package/src/client/components/layout/desktop-layout/WorkspacePanels.tsx +4 -0
- package/src/client/components/layout/desktop-layout/index.tsx +2 -0
- package/src/client/components/mobile/LayoutWrapper.tsx +16 -0
- package/src/client/components/mobile/SessionSidebar.tsx +10 -0
- package/src/client/components/mobile/mobile-right-sidebar/FullEditor.tsx +0 -1
- package/src/client/components/mobile/mobile-session-sidebar/Item.tsx +16 -1
- package/src/client/components/mobile/mobile-session-sidebar/List.tsx +3 -0
- package/src/client/components/settings/categories/ProviderSettings.tsx +45 -4
- package/src/client/components/settings/categories/UsageSettings.tsx +22 -7
- package/src/client/components/settings/categories/provider-settings/AddModelModal.tsx +322 -0
- package/src/client/components/settings/categories/provider-settings/AddProviderModal.tsx +152 -56
- package/src/client/components/settings/categories/provider-settings/AuthSection.tsx +52 -1
- package/src/client/components/settings/categories/provider-settings/DeleteProviderModal.tsx +133 -0
- package/src/client/components/settings/categories/provider-settings/DialectFields.tsx +136 -0
- package/src/client/components/settings/categories/provider-settings/EffortLadder.tsx +89 -0
- package/src/client/components/settings/categories/provider-settings/Header.tsx +2 -2
- package/src/client/components/settings/categories/provider-settings/LoginModal.tsx +2 -2
- package/src/client/components/settings/categories/provider-settings/ModelsList.tsx +22 -2
- package/src/client/components/settings/categories/provider-settings/PresetPicker.tsx +82 -0
- package/src/client/components/settings/categories/provider-settings/PriceFields.tsx +107 -0
- package/src/client/components/settings/categories/provider-settings/ReconnectModal.tsx +43 -22
- package/src/client/components/settings/categories/provider-settings/SidebarList.tsx +2 -2
- package/src/client/components/settings/categories/usage-settings/LimitsSection.tsx +115 -0
- package/src/client/components/settings/categories/usage-settings/ProviderCard.tsx +19 -26
- package/src/client/components/settings/categories/usage-settings/ProviderDetail.tsx +29 -22
- package/src/client/components/settings/categories/usage-settings/SidebarList.tsx +60 -48
- package/src/client/components/settings/categories/usage-settings/format.ts +36 -0
- package/src/client/components/settings/categories/usage-settings/providers.ts +52 -28
- package/src/client/components/workspace/chat-timeline/AiMessageFooter.tsx +1 -1
- package/src/client/components/workspace/chat-timeline/GeneratingIndicator.tsx +1 -1
- package/src/client/components/workspace/diff-panel/Toolbar.tsx +71 -38
- package/src/client/components/workspace/diff-panel/index.tsx +139 -53
- package/src/client/components/workspace/editor/Tabs.tsx +2 -2
- package/src/client/components/workspace/editor/Toolbar.tsx +111 -26
- package/src/client/components/workspace/editor/index.tsx +27 -9
- package/src/client/components/workspace/model-dropdown/Item.tsx +13 -23
- package/src/client/components/workspace/model-dropdown/Panel.tsx +1 -1
- package/src/client/components/workspace/model-dropdown/Section.tsx +13 -4
- package/src/client/components/workspace/model-dropdown/index.tsx +7 -3
- package/src/client/components/workspace/usage-panel/ProviderSelect.tsx +10 -5
- package/src/client/components/workspace/usage-panel/index.tsx +36 -18
- package/src/client/data/samples/dialogue-session.ts +1 -1
- package/src/client/data/samples/sample-tools/other.ts +1 -1
- package/src/client/data/settings/provider.ts +141 -9
- package/src/client/hooks/editor/use-file-editor.ts +24 -27
- package/src/client/hooks/models/use-provider-names.ts +1 -1
- package/src/client/hooks/settings/providers/actions.ts +337 -0
- package/src/client/hooks/settings/providers/api.ts +69 -0
- package/src/client/hooks/settings/providers/index.ts +138 -0
- package/src/client/hooks/settings/providers/messages.ts +77 -0
- package/src/client/hooks/settings/useUsageReport.ts +8 -3
- package/src/client/hooks/ui/theme.ts +3 -3
- package/src/client/hooks/workspace/file-tabs.ts +62 -11
- package/src/client/stubs/elkjs.ts +6 -1
- package/src/server/index.ts +20 -2
- package/src/server/lib/assets/font-css.server.ts +86 -0
- package/src/server/lib/assets/fonts.server.ts +117 -0
- package/src/server/lib/bundler/css.ts +116 -0
- package/src/server/lib/lifecycle/shell-route.ts +17 -0
- package/src/server/lib/models/provider-listing.server.ts +257 -0
- package/src/server/lib/models/provider-registry.server.test.ts +122 -0
- package/src/server/lib/models/provider-registry.server.ts +76 -25
- package/src/server/lib/omp/config/models-config.ts +11 -0
- package/src/server/lib/omp/config/models-validation.test.ts +137 -0
- package/src/server/lib/omp/config/models-validation.ts +111 -2
- package/src/server/lib/omp/config/provider-seeds.test.ts +167 -0
- package/src/server/lib/omp/config/provider-seeds.ts +176 -0
- package/src/server/lib/omp/config/providers.ts +94 -100
- package/src/server/lib/omp/core/auth-credentials.ts +45 -0
- package/src/server/lib/omp/session/{usage.ts → usage/aggregate.ts} +1 -118
- package/src/server/lib/omp/session/usage/shaping.ts +130 -0
- package/src/server/lib/usage/deepseek.ts +4 -5
- package/src/server/lib/usage/kenari.ts +7 -6
- package/src/server/lib/usage/omp-usage.server.test.ts +126 -0
- package/src/server/lib/usage/omp-usage.server.ts +194 -0
- package/src/server/lib/usage/provider-key.ts +81 -3
- package/src/server/lib/usage/providers.server.test.ts +47 -0
- package/src/server/lib/usage/providers.server.ts +208 -0
- package/src/server/lib/usage/vendor-balance.server.test.ts +104 -0
- package/src/server/lib/usage/vendor-balance.server.ts +284 -0
- package/src/server/plugins/shell.server.ts +56 -0
- package/src/server/plugins/ssr.ts +24 -36
- package/src/server/plugins/static.test.ts +26 -29
- package/src/server/plugins/static.ts +40 -19
- package/src/server/routes/settings/index.ts +2 -0
- package/src/server/routes/settings/provider-model.ts +107 -0
- package/src/server/routes/settings/provider-models.ts +65 -202
- package/src/server/routes/settings/providers.ts +22 -7
- package/src/server/routes/settings/usage.ts +125 -45
- package/src/server/routes/telemetry/tokens.ts +2 -1
- package/src/shared/lib/fs/diff-parser.test.ts +116 -0
- package/src/shared/lib/fs/diff-parser.ts +86 -33
- package/src/shared/lib/models/{provider-connection.ts → provider/connection.ts} +37 -0
- package/src/shared/lib/models/provider/dialect.ts +179 -0
- package/src/shared/lib/models/provider/glyph.test.ts +116 -0
- package/src/shared/lib/models/provider/glyph.ts +200 -0
- package/src/shared/lib/models/{provider-models.ts → provider/models.ts} +91 -6
- package/src/shared/lib/models/provider/presets.test.ts +172 -0
- package/src/shared/lib/models/provider/presets.ts +83 -0
- package/src/shared/lib/workspace/file-tab-id.ts +29 -0
- package/src/shared/types/settings/provider.ts +81 -0
- package/src/shared/types/settings/usage.ts +88 -14
- package/tsconfig.json +3 -1
- package/dist/client/static/css/index.5f630421b7.css +0 -2
- package/dist/client/static/font/KaTeX_AMS-Regular.a79f1c3119.woff2 +0 -0
- package/dist/client/static/font/KaTeX_Caligraphic-Bold.ec17d13264.woff2 +0 -0
- package/dist/client/static/font/KaTeX_Caligraphic-Regular.55fac25845.woff2 +0 -0
- package/dist/client/static/font/KaTeX_Fraktur-Bold.d42a5579b0.woff2 +0 -0
- package/dist/client/static/font/KaTeX_Fraktur-Regular.d3c882a649.woff2 +0 -0
- package/dist/client/static/font/KaTeX_Main-Bold.c3fb5ac22f.woff2 +0 -0
- package/dist/client/static/font/KaTeX_Main-BoldItalic.6f2bb1dff2.woff2 +0 -0
- package/dist/client/static/font/KaTeX_Main-Italic.8916142bec.woff2 +0 -0
- package/dist/client/static/font/KaTeX_Main-Regular.0462f03bdf.woff2 +0 -0
- package/dist/client/static/font/KaTeX_Math-BoldItalic.572d331f69.woff2 +0 -0
- package/dist/client/static/font/KaTeX_Math-Italic.f28c23acad.woff2 +0 -0
- package/dist/client/static/font/KaTeX_SansSerif-Bold.8c5b5494b6.woff2 +0 -0
- package/dist/client/static/font/KaTeX_SansSerif-Italic.3b1e59b3ba.woff2 +0 -0
- package/dist/client/static/font/KaTeX_SansSerif-Regular.ba21ed5f84.woff2 +0 -0
- package/dist/client/static/font/KaTeX_Script-Regular.03e9641d6f.woff2 +0 -0
- package/dist/client/static/font/KaTeX_Size1-Regular.eae34984b3.woff2 +0 -0
- package/dist/client/static/font/KaTeX_Size2-Regular.5916a24fa3.woff2 +0 -0
- package/dist/client/static/font/KaTeX_Size4-Regular.10d95fd3a2.woff2 +0 -0
- package/dist/client/static/font/KaTeX_Typewriter-Regular.a8709e3622.woff2 +0 -0
- package/dist/client/static/font/fira-code-latin-400-normal.2655b10c55.woff2 +0 -0
- package/dist/client/static/font/fira-code-latin-500-normal.92a991f204.woff2 +0 -0
- package/dist/client/static/font/fira-code-latin-600-normal.43788eb7f1.woff2 +0 -0
- package/dist/client/static/font/fira-code-latin-700-normal.2667215d33.woff2 +0 -0
- package/dist/client/static/js/77.0d81c74cf0.js +0 -139
- package/dist/client/static/js/77.0d81c74cf0.js.LICENSE.txt +0 -8
- package/dist/client/static/js/async/0.8e59f2eb5b.js +0 -1
- package/dist/client/static/js/async/0k.5852e6b4fa.js +0 -1
- package/dist/client/static/js/async/0w.9ed36d5860.js +0 -1
- package/dist/client/static/js/async/1.f387c12b63.js +0 -1
- package/dist/client/static/js/async/12.d091f91c99.js +0 -1
- package/dist/client/static/js/async/13.8f810a8a6c.js +0 -1
- package/dist/client/static/js/async/19.6fe909d55a.js +0 -160
- package/dist/client/static/js/async/1b.23f1141a38.js +0 -1
- package/dist/client/static/js/async/1k.973e8e21fc.js +0 -2
- package/dist/client/static/js/async/1k.973e8e21fc.js.LICENSE.txt +0 -11
- package/dist/client/static/js/async/1p.0d5cddda96.js +0 -1
- package/dist/client/static/js/async/2.b589f1733b.js +0 -1
- package/dist/client/static/js/async/2v.96165101de.js +0 -1
- package/dist/client/static/js/async/3.0cacc08423.js +0 -1
- package/dist/client/static/js/async/37.b28b2f61cd.js +0 -1
- package/dist/client/static/js/async/3d.5085fb913f.js +0 -1
- package/dist/client/static/js/async/3j.357c80ff38.js +0 -2
- package/dist/client/static/js/async/3j.357c80ff38.js.LICENSE.txt +0 -11
- package/dist/client/static/js/async/3p.bcf32a0983.js +0 -1
- package/dist/client/static/js/async/3r.3a69e98ee0.js +0 -64
- package/dist/client/static/js/async/3u.1228460e2a.js +0 -1
- package/dist/client/static/js/async/3y.3530b824ad.js +0 -198
- package/dist/client/static/js/async/3y.3530b824ad.js.LICENSE.txt +0 -5
- package/dist/client/static/js/async/4.9442eeb472.js +0 -1
- package/dist/client/static/js/async/4e.678285ca55.js +0 -1
- package/dist/client/static/js/async/4k.33a0c7eeb4.js +0 -1
- package/dist/client/static/js/async/4m.928a1dde85.js +0 -31
- package/dist/client/static/js/async/4m.928a1dde85.js.LICENSE.txt +0 -11
- package/dist/client/static/js/async/4q.aad20dab25.js +0 -1
- package/dist/client/static/js/async/5.ebaf8b89cc.js +0 -36
- package/dist/client/static/js/async/51.95bcae98af.js +0 -2
- package/dist/client/static/js/async/51.95bcae98af.js.LICENSE.txt +0 -6
- package/dist/client/static/js/async/5b.d88304bc13.js +0 -1
- package/dist/client/static/js/async/5j.d6407c4248.js +0 -287
- package/dist/client/static/js/async/5o.88316d4460.js +0 -62
- package/dist/client/static/js/async/6.f034c9b528.js +0 -1
- package/dist/client/static/js/async/66.5dfa29f957.js +0 -93
- package/dist/client/static/js/async/6o.5b1a06a382.js +0 -1
- package/dist/client/static/js/async/7.e4a9288dd0.js +0 -1
- package/dist/client/static/js/async/73.308dff4da8.js +0 -1
- package/dist/client/static/js/async/7e.a1cc9bfd88.js +0 -1
- package/dist/client/static/js/async/7g.a7814350c3.js +0 -1
- package/dist/client/static/js/async/7l.fadbbc0583.js +0 -1
- package/dist/client/static/js/async/8.5067439d8c.js +0 -1
- package/dist/client/static/js/async/8j.ea110663fb.js +0 -1
- package/dist/client/static/js/async/a.bce4542392.js +0 -1
- package/dist/client/static/js/async/aa.65d3852576.js +0 -1
- package/dist/client/static/js/async/ar.9303e5f2e8.js +0 -2
- package/dist/client/static/js/async/ar.9303e5f2e8.js.LICENSE.txt +0 -11
- package/dist/client/static/js/async/az.d656062b0f.js +0 -1
- package/dist/client/static/js/async/b.b4f6f06515.js +0 -1
- package/dist/client/static/js/async/bi.09688ba75c.js +0 -1
- package/dist/client/static/js/async/bq.586bc738d1.js +0 -1
- package/dist/client/static/js/async/c.797d933882.js +0 -1
- package/dist/client/static/js/async/c0.0af1e640d3.js +0 -24
- package/dist/client/static/js/async/ca.8a52cfd447.js +0 -1
- package/dist/client/static/js/async/cf.d34fff5d67.js +0 -1
- package/dist/client/static/js/async/ct.b74928f7a3.js +0 -1
- package/dist/client/static/js/async/cx.3cb0242a3a.js +0 -226
- package/dist/client/static/js/async/d.a5fc8fe1b3.js +0 -1
- package/dist/client/static/js/async/da.f62c70f6c8.js +0 -1
- package/dist/client/static/js/async/dp.1725d6432c.js +0 -1
- package/dist/client/static/js/async/e.93214d622b.js +0 -79
- package/dist/client/static/js/async/f.ab50467719.js +0 -19
- package/dist/client/static/js/async/f.ab50467719.js.LICENSE.txt +0 -12
- package/dist/client/static/js/async/f7.46971e9d6d.js +0 -2
- package/dist/client/static/js/async/f7.46971e9d6d.js.LICENSE.txt +0 -6
- package/dist/client/static/js/async/f8.bbf0dbae70.js +0 -1
- package/dist/client/static/js/async/g.cb81980498.js +0 -2
- package/dist/client/static/js/async/g.cb81980498.js.LICENSE.txt +0 -11
- package/dist/client/static/js/async/h.4e790471e4.js +0 -27
- package/dist/client/static/js/async/h1.393f066d09.js +0 -1
- package/dist/client/static/js/async/h3.216e9798ab.js +0 -148
- package/dist/client/static/js/async/hd.0da931b622.js +0 -1
- package/dist/client/static/js/async/hk.ba7fb04d41.js +0 -1
- package/dist/client/static/js/async/hn.b645041e00.js +0 -1
- package/dist/client/static/js/async/ho.475a5e1ae4.js +0 -1
- package/dist/client/static/js/async/hp.e9fe2e395a.js +0 -2
- package/dist/client/static/js/async/hp.e9fe2e395a.js.LICENSE.txt +0 -17
- package/dist/client/static/js/async/hs.e7c59d8090.js +0 -41
- package/dist/client/static/js/async/i.7c148e8440.js +0 -1
- package/dist/client/static/js/async/id.573df20f29.js +0 -1
- package/dist/client/static/js/async/j.ab925882d8.js +0 -1
- package/dist/client/static/js/async/jd.63886a1f09.js +0 -1
- package/dist/client/static/js/async/jg.d86ebd4013.js +0 -86
- package/dist/client/static/js/async/jl.874d352278.js +0 -1
- package/dist/client/static/js/async/jll.11313b455a.js +0 -1
- package/dist/client/static/js/async/js.67182759ef.js +0 -1
- package/dist/client/static/js/async/jsc.23b70d6f40.js +0 -1
- package/dist/client/static/js/async/jse.334588ff5d.js +0 -1
- package/dist/client/static/js/async/jz.72eb929106.js +0 -77
- package/dist/client/static/js/async/k.3210286401.js +0 -217
- package/dist/client/static/js/async/ka.c1990ecaa3.js +0 -115
- package/dist/client/static/js/async/katex-vendor.de6a87c308.js +0 -1
- package/dist/client/static/js/async/ku.29c8a59d0c.js +0 -1
- package/dist/client/static/js/async/ky.8dab1dade0.js +0 -1
- package/dist/client/static/js/async/l.12dd34e1be.js +0 -1
- package/dist/client/static/js/async/l9.949710adaf.js +0 -83
- package/dist/client/static/js/async/l9.949710adaf.js.LICENSE.txt +0 -13
- package/dist/client/static/js/async/ls.9d9a01026c.js +0 -104
- package/dist/client/static/js/async/m.eb2e6752e2.js +0 -28
- package/dist/client/static/js/async/m.eb2e6752e2.js.LICENSE.txt +0 -11
- package/dist/client/static/js/async/m3.d2b05f9604.js +0 -2
- package/dist/client/static/js/async/m3.d2b05f9604.js.LICENSE.txt +0 -6
- package/dist/client/static/js/async/ma.2c261b04dd.js +0 -2
- package/dist/client/static/js/async/ma.2c261b04dd.js.LICENSE.txt +0 -6
- package/dist/client/static/js/async/me.8ace414f80.js +0 -23
- package/dist/client/static/js/async/ms.98960af4eb.js +0 -67
- package/dist/client/static/js/async/ms.98960af4eb.js.LICENSE.txt +0 -12
- package/dist/client/static/js/async/mt.0352e976d8.js +0 -1
- package/dist/client/static/js/async/n.a9f1c51701.js +0 -1
- package/dist/client/static/js/async/na.a36cd532d6.js +0 -1
- package/dist/client/static/js/async/nk.fc7e58325e.js +0 -1
- package/dist/client/static/js/async/o.36353dfb88.js +0 -1
- package/dist/client/static/js/async/oc.b73042e8bd.js +0 -8
- package/dist/client/static/js/async/og.8eb577893a.js +0 -193
- package/dist/client/static/js/async/p.48ecfcd14e.js +0 -1
- package/dist/client/static/js/async/px.fc6877924b.js +0 -1
- package/dist/client/static/js/async/q.22588845a9.js +0 -21
- package/dist/client/static/js/async/q.22588845a9.js.LICENSE.txt +0 -6
- package/dist/client/static/js/async/q5.97dc1481b6.js +0 -286
- package/dist/client/static/js/async/qs.2a9ddb3c72.js +0 -1
- package/dist/client/static/js/async/r.51010ad87c.js +0 -1
- package/dist/client/static/js/async/rd.cb6bf495bb.js +0 -2
- package/dist/client/static/js/async/rd.cb6bf495bb.js.LICENSE.txt +0 -4
- package/dist/client/static/js/async/s.0f395cdda5.js +0 -94
- package/dist/client/static/js/async/t.4dca0e2ba8.js +0 -1
- package/dist/client/static/js/async/t9.d44f57d518.js +0 -1
- package/dist/client/static/js/async/ta.973534bbec.js +0 -1
- package/dist/client/static/js/async/tr.e878658140.js +0 -309
- package/dist/client/static/js/async/u.0871ac5b22.js +0 -1
- package/dist/client/static/js/async/ud.3065bfee31.js +0 -2
- package/dist/client/static/js/async/ud.3065bfee31.js.LICENSE.txt +0 -4
- package/dist/client/static/js/async/up.ea990da0ff.js +0 -32
- package/dist/client/static/js/async/uw.8890abbabc.js +0 -1
- package/dist/client/static/js/async/v.7d28d3c241.js +0 -34
- package/dist/client/static/js/async/vp.9b13bf8610.js +0 -1
- package/dist/client/static/js/async/vt.42416b707d.js +0 -1
- package/dist/client/static/js/async/w.08ac210f60.js +0 -1
- package/dist/client/static/js/async/wt.ad92393a90.js +0 -1
- package/dist/client/static/js/async/x.563f72ca6b.js +0 -1
- package/dist/client/static/js/async/x0.475516418f.js +0 -1
- package/dist/client/static/js/async/x1.da8687159b.js +0 -90
- package/dist/client/static/js/async/xe.da8dcc2015.js +0 -2
- package/dist/client/static/js/async/xe.da8dcc2015.js.LICENSE.txt +0 -11
- package/dist/client/static/js/async/xl.a3c562a58c.js +0 -1
- package/dist/client/static/js/async/xn.6510c0abe2.js +0 -2
- package/dist/client/static/js/async/xn.6510c0abe2.js.LICENSE.txt +0 -6
- package/dist/client/static/js/async/xn1.83a7784fe1.js +0 -10
- package/dist/client/static/js/async/xn1.83a7784fe1.js.LICENSE.txt +0 -11
- package/dist/client/static/js/async/xnl.feb0021e50.js +0 -2
- package/dist/client/static/js/async/xnl.feb0021e50.js.LICENSE.txt +0 -12
- package/dist/client/static/js/async/y.1a9ed7a5d8.js +0 -1
- package/dist/client/static/js/async/y6.43c57defe4.js +0 -1
- package/dist/client/static/js/async/yb.8c1342401d.js +0 -1
- package/dist/client/static/js/async/ybq.4491f2f2dc.js +0 -1
- package/dist/client/static/js/async/yg.35bebd6d0c.js +0 -149
- package/dist/client/static/js/async/yq.917ddd7ba2.js +0 -1
- package/dist/client/static/js/async/ys.00687cf82d.js +0 -38
- package/dist/client/static/js/async/yv.d99d829136.js +0 -1
- package/dist/client/static/js/async/z.56f61a4374.js +0 -1
- package/dist/client/static/js/async/zi.5fdb07b86a.js +0 -24
- package/dist/client/static/js/async/zj.654f37e8ff.js +0 -1
- package/dist/client/static/js/async/zn.966d6f1cc6.js +0 -1
- package/dist/client/static/js/async/zo.26213b40c0.js +0 -1
- package/dist/client/static/js/async/zx.e9f4105e00.js +0 -1
- package/dist/client/static/js/index.e6a257402a.js +0 -38
- package/dist/client/static/js/index.e6a257402a.js.LICENSE.txt +0 -4
- package/dist/client/static/js/markdown-vendor.71e43278b3.js +0 -144
- package/dist/client/static/js/shiki-vendor.cb8452ddcd.js +0 -1
- package/src/client/components/settings/categories/provider-settings/Icons.tsx +0 -35
- package/src/client/hooks/settings/providers.ts +0 -326
- package/src/server/plugins/dev-assets.ts +0 -49
- package/src/shared/lib/code/editor-utils.ts +0 -16
- package/src/shared/lib/models/provider-presets.ts +0 -29
- /package/dist/client/{apple-touch-icon.png → static/apple-touch-icon-dskx5sr3.png} +0 -0
- /package/dist/client/{icon-192x192.png → static/icon-192x192-6gn5cr2f.png} +0 -0
- /package/dist/client/{icon.svg → static/icon-d07z9dtz.svg} +0 -0
- /package/dist/client/{manifest.webmanifest → static/manifest-bnyy75kt.webmanifest} +0 -0
- /package/{dist/client → public}/icon-512x512.png +0 -0
- /package/{dist/client → public}/icon-maskable-512x512.png +0 -0
- /package/{dist/client → public}/sw.js +0 -0
- /package/src/shared/lib/models/{provider-cleanup.ts → provider/cleanup.ts} +0 -0
- /package/src/shared/lib/models/{provider-label.ts → provider/label.ts} +0 -0
|
@@ -1,47 +1,40 @@
|
|
|
1
1
|
import type { ReactNode } from 'preact/compat';
|
|
2
|
-
import { AlertCircle
|
|
2
|
+
import { AlertCircle } from 'lucide-preact';
|
|
3
3
|
|
|
4
4
|
interface ProviderCardProps {
|
|
5
5
|
providerName: string;
|
|
6
|
-
|
|
6
|
+
/** Where the credential was found, e.g. "models.yml · agent.db". */
|
|
7
|
+
credentialSources: string[];
|
|
8
|
+
/** Provider-side failure, already human-readable. */
|
|
7
9
|
error?: string;
|
|
8
10
|
note?: string;
|
|
9
11
|
children: ReactNode;
|
|
10
12
|
}
|
|
11
13
|
|
|
12
|
-
/** Provider shell: header,
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
export function ProviderCard({ providerName,
|
|
14
|
+
/** Provider shell: header, credential provenance, error line, and content slot.
|
|
15
|
+
* Every listed provider has a resolved credential — a keyless provider is never
|
|
16
|
+
* rendered at all — so there is no "not configured" state here. */
|
|
17
|
+
export function ProviderCard({ providerName, credentialSources, error, note, children }: ProviderCardProps) {
|
|
16
18
|
return (
|
|
17
19
|
<section className="bg-paper border border-ink/15 rounded-lg shadow-xs">
|
|
18
20
|
<header className="flex items-center justify-between gap-2 px-3.5 py-2.5 border-b border-ink/10">
|
|
19
21
|
<span className="text-xs font-semibold text-ink">{providerName}</span>
|
|
20
|
-
<span
|
|
21
|
-
|
|
22
|
+
<span
|
|
23
|
+
className="text-[10px] font-mono uppercase tracking-wider text-ink/50 truncate"
|
|
24
|
+
title={`Credentials from ${credentialSources.join(', ')}`}
|
|
25
|
+
>
|
|
26
|
+
{credentialSources.join(' · ')}
|
|
22
27
|
</span>
|
|
23
28
|
</header>
|
|
24
29
|
|
|
25
30
|
<div className="p-3.5 space-y-4">
|
|
26
|
-
{
|
|
27
|
-
<
|
|
28
|
-
<
|
|
29
|
-
<
|
|
30
|
-
|
|
31
|
-
Providers to see its balance, quota, and usage here.
|
|
32
|
-
</p>
|
|
33
|
-
</div>
|
|
34
|
-
) : (
|
|
35
|
-
<>
|
|
36
|
-
{error && (
|
|
37
|
-
<p className="flex items-start gap-2 text-error text-xs leading-relaxed">
|
|
38
|
-
<AlertCircle size={14} className="shrink-0 mt-0.5" />
|
|
39
|
-
<span className="break-words">{error}</span>
|
|
40
|
-
</p>
|
|
41
|
-
)}
|
|
42
|
-
{children}
|
|
43
|
-
</>
|
|
31
|
+
{error && (
|
|
32
|
+
<p className="flex items-start gap-2 text-error text-xs leading-relaxed">
|
|
33
|
+
<AlertCircle size={14} className="shrink-0 mt-0.5" />
|
|
34
|
+
<span className="break-words">{error}</span>
|
|
35
|
+
</p>
|
|
44
36
|
)}
|
|
37
|
+
{children}
|
|
45
38
|
|
|
46
39
|
{note && (
|
|
47
40
|
<p className="text-[10px] text-ink/50 leading-relaxed border-t border-ink/10 pt-2.5">{note}</p>
|
|
@@ -1,39 +1,46 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { UsageProviderSummary } from '@/shared/types';
|
|
2
2
|
import { ProviderCard } from '@/client/components/settings/categories/usage-settings/ProviderCard';
|
|
3
3
|
import { KenariCard } from '@/client/components/settings/categories/usage-settings/KenariCard';
|
|
4
4
|
import { DeepSeekCard } from '@/client/components/settings/categories/usage-settings/DeepSeekCard';
|
|
5
|
-
import
|
|
5
|
+
import { LimitsSection } from '@/client/components/settings/categories/usage-settings/LimitsSection';
|
|
6
6
|
|
|
7
7
|
const DEEPSEEK_NOTE =
|
|
8
8
|
'DeepSeek exposes no usage or quota API — only the prepaid balance (and the web console at platform.deepseek.com) is available.';
|
|
9
9
|
|
|
10
10
|
interface ProviderDetailProps {
|
|
11
|
-
|
|
12
|
-
report: UsageReport;
|
|
11
|
+
summary: UsageProviderSummary;
|
|
13
12
|
}
|
|
14
13
|
|
|
15
|
-
/**
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
error={report.kenari.error}
|
|
23
|
-
>
|
|
24
|
-
<KenariCard report={report.kenari} />
|
|
25
|
-
</ProviderCard>
|
|
26
|
-
);
|
|
27
|
-
}
|
|
14
|
+
/**
|
|
15
|
+
* Renders one provider's card. kenari and DeepSeek carry richer reports (wallet
|
|
16
|
+
* and Rupiah quota / prepaid balance); every other provider renders the generic
|
|
17
|
+
* quota windows, which for a pay-as-you-go vendor is its credit balance.
|
|
18
|
+
*/
|
|
19
|
+
export function ProviderDetail({ summary }: ProviderDetailProps) {
|
|
20
|
+
const hasRichReport = Boolean(summary.kenari || summary.deepseek);
|
|
28
21
|
|
|
29
22
|
return (
|
|
30
23
|
<ProviderCard
|
|
31
|
-
providerName=
|
|
32
|
-
|
|
33
|
-
error={
|
|
34
|
-
note={DEEPSEEK_NOTE}
|
|
24
|
+
providerName={summary.name}
|
|
25
|
+
credentialSources={summary.credentialSources}
|
|
26
|
+
error={summary.error}
|
|
27
|
+
note={summary.deepseek ? DEEPSEEK_NOTE : undefined}
|
|
35
28
|
>
|
|
36
|
-
<
|
|
29
|
+
{summary.kenari && <KenariCard report={summary.kenari} />}
|
|
30
|
+
{summary.deepseek && <DeepSeekCard report={summary.deepseek} />}
|
|
31
|
+
|
|
32
|
+
{/* The rich reports already render their own quota and usage tables, so
|
|
33
|
+
the generic windows would only duplicate them. When the provider
|
|
34
|
+
failed outright and reported no windows, the error line above already
|
|
35
|
+
says so — a second "no quota source" note would contradict it. */}
|
|
36
|
+
{!hasRichReport && (summary.limits.length > 0 || !summary.error) && (
|
|
37
|
+
<LimitsSection
|
|
38
|
+
limits={summary.limits}
|
|
39
|
+
tracked={summary.tracked}
|
|
40
|
+
unavailable={summary.limitsUnavailable}
|
|
41
|
+
notes={summary.notes}
|
|
42
|
+
/>
|
|
43
|
+
)}
|
|
37
44
|
</ProviderCard>
|
|
38
45
|
);
|
|
39
46
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Bot, Coins } from 'lucide-preact';
|
|
2
1
|
import type { UsageReport } from '@/shared/types';
|
|
3
|
-
import { buildProviders, statusLabel, type UsageProviderId } from '@/client/components/settings/categories/usage-settings/providers';
|
|
2
|
+
import { buildProviders, statusLabel, type ProviderEntry, type UsageProviderId } from '@/client/components/settings/categories/usage-settings/providers';
|
|
3
|
+
import { ProviderIcon } from '@/client/components/common/provider-icon';
|
|
4
4
|
|
|
5
5
|
interface UsageSidebarListProps {
|
|
6
6
|
report: UsageReport;
|
|
@@ -8,6 +8,14 @@ interface UsageSidebarListProps {
|
|
|
8
8
|
onSelectProvider: (providerId: UsageProviderId) => void;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
function ProviderBadge({ provider, selected }: { provider: ProviderEntry; selected: boolean }) {
|
|
12
|
+
return (
|
|
13
|
+
<span className={selected ? 'text-ink/80' : 'text-ink/60'}>
|
|
14
|
+
<ProviderIcon slug={provider.id} name={provider.name} size={14} />
|
|
15
|
+
</span>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
11
19
|
export function UsageSidebarList({
|
|
12
20
|
report,
|
|
13
21
|
selectedProviderId,
|
|
@@ -18,59 +26,63 @@ export function UsageSidebarList({
|
|
|
18
26
|
return (
|
|
19
27
|
<div className="w-56 sm:w-64 border-r border-ink/10 h-full flex flex-col bg-paper/50 flex-shrink-0 select-none">
|
|
20
28
|
<div className="px-3.5 py-2.5 border-b border-ink/10 flex items-center justify-between">
|
|
21
|
-
<span className="text-xs font-semibold text-ink">
|
|
29
|
+
<span className="text-xs font-semibold text-ink">
|
|
30
|
+
{providers.length} provider{providers.length === 1 ? '' : 's'} with keys
|
|
31
|
+
</span>
|
|
22
32
|
</div>
|
|
23
33
|
|
|
24
34
|
<div className="flex-1 scrollbar-overlay-container scrollbar-overlay-static p-1.5 space-y-3 text-xs">
|
|
25
|
-
|
|
26
|
-
<
|
|
27
|
-
Providers
|
|
28
|
-
</
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
{providers.length === 0 ? (
|
|
36
|
+
<p className="px-2.5 py-3 text-[11px] text-ink/50 leading-relaxed">
|
|
37
|
+
No provider credentials detected. Add an API key in Settings → Providers.
|
|
38
|
+
</p>
|
|
39
|
+
) : (
|
|
40
|
+
<div>
|
|
41
|
+
<div className="px-2.5 pt-1.5 pb-1 text-[10px] font-bold text-ink/50 uppercase tracking-wider">
|
|
42
|
+
Providers
|
|
43
|
+
</div>
|
|
44
|
+
<div className="space-y-0.5">
|
|
45
|
+
{providers.map((provider) => {
|
|
46
|
+
const isSelected = provider.id === selectedProviderId;
|
|
34
47
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
48
|
+
return (
|
|
49
|
+
<button
|
|
50
|
+
key={provider.id}
|
|
51
|
+
type="button"
|
|
52
|
+
onClick={() => onSelectProvider(provider.id)}
|
|
53
|
+
className={`w-full text-left px-2.5 py-2 rounded-lg transition-colors cursor-pointer flex flex-col gap-0.5 group ${
|
|
54
|
+
isSelected
|
|
55
|
+
? 'bg-ink/10 text-ink font-medium shadow-2xs'
|
|
56
|
+
: 'text-ink/80 hover:bg-ink/5 hover:text-ink'
|
|
57
|
+
}`}
|
|
58
|
+
>
|
|
59
|
+
<div className="flex items-center justify-between gap-1.5">
|
|
60
|
+
<div className="flex items-center gap-1.5 min-w-0">
|
|
61
|
+
<div className="relative">
|
|
62
|
+
<ProviderBadge provider={provider} selected={isSelected} />
|
|
63
|
+
<span
|
|
64
|
+
className={`absolute -top-0.5 -right-0.5 w-1.5 h-1.5 rounded-full ${
|
|
65
|
+
provider.error ? 'bg-error/60' : 'bg-ink'
|
|
66
|
+
}`}
|
|
67
|
+
/>
|
|
68
|
+
</div>
|
|
69
|
+
<span className="font-semibold text-xs text-ink truncate">{provider.name}</span>
|
|
57
70
|
</div>
|
|
58
|
-
<span
|
|
71
|
+
<span
|
|
72
|
+
className={`text-[10px] font-mono uppercase px-1.5 py-0.5 rounded bg-ink/10 font-medium ${
|
|
73
|
+
provider.error ? 'text-error' : 'text-ink/70'
|
|
74
|
+
}`}
|
|
75
|
+
>
|
|
76
|
+
{statusLabel(provider)}
|
|
77
|
+
</span>
|
|
59
78
|
</div>
|
|
60
|
-
<
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
{statusLabel(provider)}
|
|
66
|
-
</span>
|
|
67
|
-
</div>
|
|
68
|
-
<p className="text-[11px] text-ink/60 line-clamp-1 leading-snug pl-5">{provider.hint}</p>
|
|
69
|
-
</button>
|
|
70
|
-
);
|
|
71
|
-
})}
|
|
79
|
+
<p className="text-[11px] text-ink/60 line-clamp-1 leading-snug pl-5">{provider.hint}</p>
|
|
80
|
+
</button>
|
|
81
|
+
);
|
|
82
|
+
})}
|
|
83
|
+
</div>
|
|
72
84
|
</div>
|
|
73
|
-
|
|
85
|
+
)}
|
|
74
86
|
</div>
|
|
75
87
|
</div>
|
|
76
88
|
);
|
|
@@ -61,3 +61,39 @@ export function formatAmount(value: string): string {
|
|
|
61
61
|
if (value.trim() === '' || !Number.isFinite(parsed)) return value;
|
|
62
62
|
return formatNumber(parsed);
|
|
63
63
|
}
|
|
64
|
+
|
|
65
|
+
const usdFormatter = new Intl.NumberFormat('id-ID', {
|
|
66
|
+
minimumFractionDigits: 2,
|
|
67
|
+
maximumFractionDigits: 2,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
/** USD amounts from provider reports and local cost records. */
|
|
71
|
+
export function formatUsd(value: number): string {
|
|
72
|
+
if (!Number.isFinite(value)) return '$0,00';
|
|
73
|
+
return `$${usdFormatter.format(value)}`;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Render one quota amount in its own unit. `percent` amounts arrive as 0..100
|
|
78
|
+
* (omp's `used`/`limit` for percent units), everything else as a raw count.
|
|
79
|
+
*/
|
|
80
|
+
export function formatUsageAmount(value: number, unit: string): string {
|
|
81
|
+
if (!Number.isFinite(value)) return '—';
|
|
82
|
+
switch (unit) {
|
|
83
|
+
case 'percent':
|
|
84
|
+
return `${new Intl.NumberFormat('id-ID', { maximumFractionDigits: 1 }).format(value)}%`;
|
|
85
|
+
case 'usd':
|
|
86
|
+
return formatUsd(value);
|
|
87
|
+
case 'tokens':
|
|
88
|
+
case 'bytes':
|
|
89
|
+
return formatCompactTokens(value);
|
|
90
|
+
default:
|
|
91
|
+
return formatNumber(value);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Fraction (0..1) rendered as a whole-percent string. */
|
|
96
|
+
export function formatFractionPercent(fraction: number): string {
|
|
97
|
+
if (!Number.isFinite(fraction)) return '0%';
|
|
98
|
+
return `${new Intl.NumberFormat('id-ID', { maximumFractionDigits: 1 }).format(fraction * 100)}%`;
|
|
99
|
+
}
|
|
@@ -1,45 +1,69 @@
|
|
|
1
|
-
import type { UsageReport } from '@/shared/types';
|
|
2
|
-
import { formatAmount } from '@/client/components/settings/categories/usage-settings/format';
|
|
1
|
+
import type { UsageLimitWindow, UsageProviderSummary, UsageReport } from '@/shared/types';
|
|
2
|
+
import { formatAmount, formatUsd } from '@/client/components/settings/categories/usage-settings/format';
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Providers surfaced in the Settings → Usage sidebar and the Usage right panel.
|
|
6
|
+
* The id is the provider slug, so the set is open-ended: any provider omp can
|
|
7
|
+
* authenticate shows up here without a code change.
|
|
8
|
+
*/
|
|
9
|
+
export type UsageProviderId = string;
|
|
6
10
|
|
|
7
11
|
export interface ProviderEntry {
|
|
8
12
|
id: UsageProviderId;
|
|
9
13
|
name: string;
|
|
10
|
-
|
|
14
|
+
/** Provider-side failure, already human-readable. */
|
|
11
15
|
error?: string;
|
|
16
|
+
/** Short status line under the name. */
|
|
12
17
|
hint: string;
|
|
18
|
+
/** Provider-reported quota windows; empty when it exposes no usage endpoint. */
|
|
19
|
+
limits: UsageLimitWindow[];
|
|
20
|
+
/** Whether omp ships a usage adapter for this provider. */
|
|
21
|
+
tracked: boolean;
|
|
22
|
+
/** omp tracks this provider but its endpoint produced nothing. */
|
|
23
|
+
limitsUnavailable?: boolean;
|
|
24
|
+
summary: UsageProviderSummary;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Compact one-line summary of the most-used quota window. */
|
|
28
|
+
function limitHint(limits: UsageLimitWindow[]): string | undefined {
|
|
29
|
+
const used = limits.filter((limit) => limit.usedFraction !== undefined);
|
|
30
|
+
if (used.length === 0) {
|
|
31
|
+
// A credit balance has no limit to take a fraction of; the remaining
|
|
32
|
+
// amount IS the whole story.
|
|
33
|
+
const credit = limits.find((limit) => limit.unit === 'usd' && limit.remaining !== undefined);
|
|
34
|
+
if (credit) return `${formatUsd(credit.remaining ?? 0)} left`;
|
|
35
|
+
return limits[0]?.label;
|
|
36
|
+
}
|
|
37
|
+
const binding = used.reduce((worst, limit) =>
|
|
38
|
+
(limit.usedFraction ?? 0) > (worst.usedFraction ?? 0) ? limit : worst,
|
|
39
|
+
);
|
|
40
|
+
const percent = Math.round((binding.usedFraction ?? 0) * 100);
|
|
41
|
+
return binding.windowLabel ? `${percent}% · ${binding.windowLabel}` : `${percent}% used`;
|
|
13
42
|
}
|
|
14
43
|
|
|
15
44
|
/** Derives the provider list (status + hint) from a usage report. */
|
|
16
45
|
export function buildProviders(report: UsageReport): ProviderEntry[] {
|
|
17
|
-
|
|
18
|
-
|
|
46
|
+
return report.providers.map((summary) => ({
|
|
47
|
+
id: summary.id,
|
|
48
|
+
name: summary.name,
|
|
49
|
+
error: summary.error,
|
|
50
|
+
hint: providerHint(summary),
|
|
51
|
+
limits: summary.limits,
|
|
52
|
+
tracked: summary.tracked,
|
|
53
|
+
limitsUnavailable: summary.limitsUnavailable,
|
|
54
|
+
summary,
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
19
57
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
hint: kenariBalance ?? 'Wallet & quota',
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
id: 'deepseek',
|
|
30
|
-
name: 'DeepSeek',
|
|
31
|
-
configured: report.deepseek.configured,
|
|
32
|
-
error: report.deepseek.error,
|
|
33
|
-
hint: deepseekEntry
|
|
34
|
-
? `${deepseekEntry.currency} ${formatAmount(deepseekEntry.totalBalance)}`
|
|
35
|
-
: 'Prepaid balance',
|
|
36
|
-
},
|
|
37
|
-
];
|
|
58
|
+
function providerHint(summary: UsageProviderSummary): string {
|
|
59
|
+
const plan = summary.kenari?.quota?.planName;
|
|
60
|
+
if (plan) return plan;
|
|
61
|
+
const balance = summary.deepseek?.balance?.entries[0];
|
|
62
|
+
if (balance) return `${balance.currency} ${formatAmount(balance.totalBalance)}`;
|
|
63
|
+
return limitHint(summary.limits) ?? 'No quota reported';
|
|
38
64
|
}
|
|
39
65
|
|
|
40
66
|
/** Human-readable connection state for a provider entry. */
|
|
41
67
|
export function statusLabel(provider: ProviderEntry): string {
|
|
42
|
-
|
|
43
|
-
if (provider.error) return 'Error';
|
|
44
|
-
return 'Connected';
|
|
68
|
+
return provider.error ? 'Error' : 'Connected';
|
|
45
69
|
}
|
|
@@ -3,7 +3,7 @@ import type { ReactNode } from 'preact/compat';
|
|
|
3
3
|
import { Bot, Brain, Clock3, Coins, Hourglass, MessageSquarePlus, MoreHorizontal, RotateCcw, X } from 'lucide-preact';
|
|
4
4
|
import { CopyButton } from '@/client/components/common/CopyButton';
|
|
5
5
|
import { formatDuration } from '@/shared/lib/chat/duration';
|
|
6
|
-
import { providerLabel } from '@/shared/lib/models/provider
|
|
6
|
+
import { providerLabel } from '@/shared/lib/models/provider/label';
|
|
7
7
|
import { formatCompactTokens } from '@/shared/lib/format/number';
|
|
8
8
|
|
|
9
9
|
interface AiMessageFooterProps {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useEffect, useState } from 'preact/hooks';
|
|
2
2
|
import { Bot } from 'lucide-preact';
|
|
3
|
-
import { providerLabel } from '@/shared/lib/models/provider
|
|
3
|
+
import { providerLabel } from '@/shared/lib/models/provider/label';
|
|
4
4
|
|
|
5
5
|
interface GeneratingIndicatorProps {
|
|
6
6
|
modelName?: string;
|