@worca/app 1.6.0-rc.1 → 1.6.0-rc.3
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 +1 -1
- package/package.json +1 -1
- package/src/core/ask/events.mjs +18 -3
- package/src/core/ask/models.mjs +8 -1
- package/src/core/ask/turn.mjs +52 -2
- package/src/core/bridge/provider-ops.mjs +40 -4
- package/src/core/bridge/upstream.mjs +29 -0
- package/src/core/failure-policy.mjs +3 -0
- package/src/core/model-test.mjs +1 -0
- package/src/core/recoverable-error.mjs +11 -2
- package/ui/public/app.js +27 -11
- package/ui/public/ask-model.mjs +3 -0
- package/ui/public/ask-panel.mjs +46 -10
- package/ui/public/bridge-view.mjs +42 -4
- package/ui/public/index.html +277 -245
- package/ui/public/style.css +20 -4
|
@@ -106,11 +106,48 @@ export function needsSignInPill(m, { doc = globalThis.document } = {}) {
|
|
|
106
106
|
// ── Providers card (§8.1) ────────────────────────────────────────────────────
|
|
107
107
|
|
|
108
108
|
function providerStatePill(doc, c) {
|
|
109
|
-
if (!c.termsCurrent)
|
|
109
|
+
if (!c.termsCurrent) {
|
|
110
|
+
// What unblocks sign-in, in the "Read notice" button's own words — and it opens that notice.
|
|
111
|
+
const pill = h(doc, 'button', 'badge grey mv-cp-terms mv-cp-terms-pill',
|
|
112
|
+
c.acknowledgedTerms ? 'please re-read the updated notice' : 'please read the notice first');
|
|
113
|
+
pill.type = 'button';
|
|
114
|
+
pill.title = 'Sign-in is blocked until you acknowledge the GitHub Copilot notice. Click to read it.';
|
|
115
|
+
return pill;
|
|
116
|
+
}
|
|
110
117
|
if (!c.connected) return h(doc, 'span', 'badge grey', 'not connected');
|
|
111
118
|
return h(doc, 'span', 'badge green', `connected${c.login ? ` as @${c.login}` : ''}`);
|
|
112
119
|
}
|
|
113
120
|
|
|
121
|
+
/**
|
|
122
|
+
* With the credential broker: the viewer's own state in the slot `name` spends from (key page),
|
|
123
|
+
* not worca's settings, which hold no key. A missing key links to the key page.
|
|
124
|
+
*/
|
|
125
|
+
function brokerPill(doc, b, name) {
|
|
126
|
+
const p = (b.providers || {})[name] || {};
|
|
127
|
+
const what = name === 'copilot' ? 'sign-in' : 'key';
|
|
128
|
+
if (b.signInNeeded) return h(doc, 'span', 'badge grey', `sign in to see your ${what}`);
|
|
129
|
+
if (p.state === 'none') {
|
|
130
|
+
const x = h(doc, 'span', 'badge red', 'no broker slot for this URL');
|
|
131
|
+
x.title = p.error || 'The credential broker has no slot for this base URL.';
|
|
132
|
+
return x;
|
|
133
|
+
}
|
|
134
|
+
if (p.state === 'keyless') return h(doc, 'span', 'badge green', 'local — no key needed');
|
|
135
|
+
if (b.error) {
|
|
136
|
+
const x = h(doc, 'span', 'badge grey', 'key page unreachable');
|
|
137
|
+
x.title = b.error;
|
|
138
|
+
return x;
|
|
139
|
+
}
|
|
140
|
+
if (p.state === 'set') return h(doc, 'span', 'badge green', `your ${what}${p.suffix ? ` ••••${p.suffix}` : ''}`);
|
|
141
|
+
if (p.state === 'operator') return h(doc, 'span', 'badge green', 'team key');
|
|
142
|
+
const label = p.state === 'invalid' ? `your ${what} was rejected` : `add your ${what} on the key page`;
|
|
143
|
+
const cls = p.state === 'invalid' ? 'badge red' : 'badge grey';
|
|
144
|
+
if (!b.keyPage) return h(doc, 'span', cls, label);
|
|
145
|
+
const a = h(doc, 'a', `${cls} mv-broker-pill`, label);
|
|
146
|
+
a.href = b.keyPage; a.target = '_blank'; a.rel = 'noopener';
|
|
147
|
+
a.title = 'Opens the key page in a new tab. Reopen this tab afterwards to see the change.';
|
|
148
|
+
return a;
|
|
149
|
+
}
|
|
150
|
+
|
|
114
151
|
function quotaLine(q) {
|
|
115
152
|
if (!q) return '';
|
|
116
153
|
if (q.unlimited) return 'Premium requests: unlimited on this plan';
|
|
@@ -181,7 +218,9 @@ export function renderProvidersCard(providers, { doc = globalThis.document, sign
|
|
|
181
218
|
const cpMain = h(doc, 'div', 'mv-pv-main');
|
|
182
219
|
const cpHead = h(doc, 'div', 'mv-head');
|
|
183
220
|
cpHead.appendChild(h(doc, 'b', 'mv-name', 'GitHub Copilot'));
|
|
184
|
-
|
|
221
|
+
const brokered = !!(p.broker && p.broker.enabled);
|
|
222
|
+
// The notice gates Copilot models either way; past it, the broker's view of your sign-in.
|
|
223
|
+
cpHead.appendChild(brokered && c.termsCurrent ? brokerPill(doc, p.broker, 'copilot') : providerStatePill(doc, c));
|
|
185
224
|
cpMain.appendChild(cpHead);
|
|
186
225
|
cpMain.appendChild(h(doc, 'small', 'hint',
|
|
187
226
|
c.acknowledgedTerms
|
|
@@ -215,7 +254,6 @@ export function renderProvidersCard(providers, { doc = globalThis.document, sign
|
|
|
215
254
|
const cpBtns = h(doc, 'div', 'mv-pv-btns');
|
|
216
255
|
const imp = h(doc, 'button', 'btn-ghost mv-cp-fetch-models', 'Import models…');
|
|
217
256
|
// With the broker, the import runs with the viewer's own Copilot sign-in (on the key page).
|
|
218
|
-
const brokered = !!(p.broker && p.broker.enabled);
|
|
219
257
|
imp.type = 'button'; imp.disabled = !c.connected && !brokered;
|
|
220
258
|
if (imp.disabled) imp.title = 'Sign in first';
|
|
221
259
|
cpBtns.appendChild(imp);
|
|
@@ -245,7 +283,7 @@ export function renderProvidersCard(providers, { doc = globalThis.document, sign
|
|
|
245
283
|
const main = h(doc, 'div', 'mv-pv-main');
|
|
246
284
|
const rh = h(doc, 'div', 'mv-head');
|
|
247
285
|
rh.appendChild(h(doc, 'b', 'mv-name', PROVIDER_LABELS[name]));
|
|
248
|
-
rh.appendChild(k.configured ? h(doc, 'span', 'badge green', 'key set')
|
|
286
|
+
rh.appendChild(p.broker && p.broker.enabled ? brokerPill(doc, p.broker, name) : k.configured ? h(doc, 'span', 'badge green', 'key set')
|
|
249
287
|
: k.keySet ? h(doc, 'span', 'badge red', 'key ${VAR} not set')
|
|
250
288
|
: k.keyOptional ? h(doc, 'span', 'badge green', 'local — no key needed') : h(doc, 'span', 'badge grey', 'no key'));
|
|
251
289
|
main.appendChild(rh);
|