Skip to content

Commit 5e6be89

Browse files
refactor: github controls, other enhancements.
1 parent 69fbded commit 5e6be89

6 files changed

Lines changed: 99 additions & 43 deletions

File tree

src/index.html

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ <h1>
3737
class="app-grid-ai-controls"
3838
id="github-ai-controls"
3939
role="group"
40-
aria-label="GitHub AI controls"
40+
aria-label="GitHub controls"
4141
hidden
4242
>
4343
<div class="github-token-control-wrap">
@@ -161,7 +161,7 @@ <h1>
161161
aria-controls="github-ai-controls"
162162
hidden
163163
>
164-
Agent
164+
GitHub
165165
</button>
166166
</div>
167167

@@ -544,9 +544,6 @@ <h2>AI Chat</h2>
544544
</div>
545545

546546
<div class="ai-chat-drawer__meta">
547-
<p class="ai-chat-drawer__repo" id="ai-chat-repository">
548-
No repository selected
549-
</p>
550547
<p class="ai-chat-drawer__status" id="ai-chat-status" data-level="neutral">
551548
Idle
552549
</p>
@@ -560,7 +557,7 @@ <h2>AI Chat</h2>
560557
class="ai-chat-prompt"
561558
id="ai-chat-prompt"
562559
rows="4"
563-
placeholder="Ask about your selected repository context"
560+
placeholder="Ask for help developing your component and styles"
564561
></textarea>
565562

566563
<label class="ai-chat-context-toggle" for="ai-chat-include-editors">

src/modules/github-api.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
const githubApiBaseUrl = 'https://api.github.com'
22
const githubModelsApiUrl = 'https://models.github.ai/inference/chat/completions'
33

4+
export const defaultGitHubChatModel = 'openai/gpt-4.1-mini'
5+
46
const parseNextPageUrlFromLinkHeader = linkHeader => {
57
if (typeof linkHeader !== 'string' || !linkHeader.trim()) {
68
return null
@@ -352,7 +354,7 @@ export const streamGitHubChatCompletion = async ({
352354
messages,
353355
signal,
354356
onToken,
355-
model = 'openai/gpt-4.1-mini',
357+
model = defaultGitHubChatModel,
356358
}) => {
357359
if (typeof token !== 'string' || token.trim().length === 0) {
358360
throw new Error('A GitHub token is required to start a chat request.')
@@ -385,6 +387,7 @@ export const streamGitHubChatCompletion = async ({
385387
const reader = response.body.getReader()
386388
let buffered = ''
387389
let combined = ''
390+
let responseModel = ''
388391

389392
while (true) {
390393
// eslint-disable-next-line no-await-in-loop
@@ -403,6 +406,10 @@ export const streamGitHubChatCompletion = async ({
403406
continue
404407
}
405408

409+
if (!responseModel && typeof body.model === 'string') {
410+
responseModel = body.model
411+
}
412+
406413
const chunk = extractStreamingDeltaText(body)
407414
if (!chunk) {
408415
continue
@@ -415,6 +422,9 @@ export const streamGitHubChatCompletion = async ({
415422

416423
if (buffered.trim()) {
417424
const body = parseSseDataLine(buffered)
425+
if (body && !responseModel && typeof body.model === 'string') {
426+
responseModel = body.model
427+
}
418428
const chunk = body ? extractStreamingDeltaText(body) : ''
419429
if (chunk) {
420430
combined += chunk
@@ -428,6 +438,7 @@ export const streamGitHubChatCompletion = async ({
428438

429439
return {
430440
content: combined,
441+
model: responseModel || model,
431442
rateLimit: parseRateMetadata({ headers: response.headers, body: null }),
432443
}
433444
}
@@ -436,7 +447,7 @@ export const requestGitHubChatCompletion = async ({
436447
token,
437448
messages,
438449
signal,
439-
model = 'openai/gpt-4.1-mini',
450+
model = defaultGitHubChatModel,
440451
}) => {
441452
if (typeof token !== 'string' || token.trim().length === 0) {
442453
throw new Error('A GitHub token is required to start a chat request.')
@@ -470,6 +481,7 @@ export const requestGitHubChatCompletion = async ({
470481

471482
return {
472483
content,
484+
model: typeof body?.model === 'string' && body.model ? body.model : model,
473485
rateLimit: parseRateMetadata({ headers: response.headers, body }),
474486
}
475487
}

src/modules/github-chat-drawer.js

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { requestGitHubChatCompletion, streamGitHubChatCompletion } from './github-api.js'
1+
import {
2+
defaultGitHubChatModel,
3+
requestGitHubChatCompletion,
4+
streamGitHubChatCompletion,
5+
} from './github-api.js'
26

37
const toChatText = value => {
48
if (typeof value !== 'string') {
@@ -8,6 +12,19 @@ const toChatText = value => {
812
return value.trim()
913
}
1014

15+
const toModelLabelText = value => {
16+
if (typeof value !== 'string') {
17+
return ''
18+
}
19+
20+
const model = value.trim()
21+
if (!model) {
22+
return ''
23+
}
24+
25+
return `(${model})`
26+
}
27+
1128
const toRepositoryLabel = repository => {
1229
if (!repository || typeof repository !== 'object') {
1330
return 'No repository selected'
@@ -207,7 +224,8 @@ export const createGitHubChatDrawer = ({
207224
if (messages.length === 0) {
208225
const emptyNode = document.createElement('p')
209226
emptyNode.className = 'ai-chat-empty'
210-
emptyNode.textContent = 'Ask a question about your selected repository.'
227+
emptyNode.textContent =
228+
'Ask for help developing your component, styles, or repository workflow.'
211229
messagesNode.append(emptyNode)
212230
return
213231
}
@@ -219,6 +237,17 @@ export const createGitHubChatDrawer = ({
219237
const label = document.createElement('h3')
220238
label.className = 'ai-chat-message__label'
221239
label.textContent = message.role === 'assistant' ? 'Assistant' : 'You'
240+
241+
if (message.role === 'assistant') {
242+
const modelLabelText = toModelLabelText(message.model)
243+
if (modelLabelText) {
244+
const modelLabel = document.createElement('span')
245+
modelLabel.className = 'ai-chat-message__label-model'
246+
modelLabel.textContent = modelLabelText
247+
label.append(modelLabel)
248+
}
249+
}
250+
222251
item.append(label)
223252

224253
const body = document.createElement('p')
@@ -366,7 +395,7 @@ export const createGitHubChatDrawer = ({
366395
pendingAbortController = requestAbortController
367396

368397
appendMessage({ role: 'user', content: prompt })
369-
appendMessage({ role: 'assistant', content: '' })
398+
appendMessage({ role: 'assistant', content: '', model: defaultGitHubChatModel })
370399
if (promptInput instanceof HTMLTextAreaElement) {
371400
promptInput.value = ''
372401
}
@@ -397,6 +426,14 @@ export const createGitHubChatDrawer = ({
397426
})
398427

399428
streamSucceeded = true
429+
const streamedModel = toChatText(streamResult?.model)
430+
if (streamedModel) {
431+
const lastMessage = messages[messages.length - 1]
432+
if (lastMessage?.role === 'assistant' && lastMessage.model !== streamedModel) {
433+
lastMessage.model = streamedModel
434+
renderMessages()
435+
}
436+
}
400437
setChatStatus('Response streamed from GitHub.', 'ok')
401438
setRateMetadata(streamResult?.rateLimit)
402439
} catch (streamError) {
@@ -432,6 +469,14 @@ export const createGitHubChatDrawer = ({
432469
})
433470

434471
updateLastAssistantMessage(fallbackResult.content)
472+
const fallbackModel = toChatText(fallbackResult.model)
473+
if (fallbackModel) {
474+
const lastMessage = messages[messages.length - 1]
475+
if (lastMessage?.role === 'assistant' && lastMessage.model !== fallbackModel) {
476+
lastMessage.model = fallbackModel
477+
renderMessages()
478+
}
479+
}
435480
setChatStatus('Fallback response loaded.', 'ok')
436481
setRateMetadata(fallbackResult.rateLimit)
437482
} catch (fallbackError) {

src/styles/ai-controls.css

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@
192192
position: fixed;
193193
top: 82px;
194194
left: auto;
195-
right: 18px;
195+
right: 24px;
196196
width: min(560px, calc(100vw - 24px));
197197
max-height: min(78vh, 820px);
198198
padding: 14px;
@@ -209,12 +209,12 @@
209209
}
210210

211211
.ai-chat-drawer.ai-chat-drawer--right {
212-
right: 18px;
212+
right: 24px;
213213
left: auto;
214214
}
215215

216216
.ai-chat-drawer.ai-chat-drawer--left {
217-
left: 18px;
217+
left: 24px;
218218
right: auto;
219219
}
220220

@@ -237,30 +237,21 @@
237237
.ai-chat-drawer__meta {
238238
display: flex;
239239
align-items: center;
240-
justify-content: space-between;
240+
justify-content: flex-start;
241241
gap: 10px;
242242
border-top: 1px solid var(--border-subtle);
243243
border-bottom: 1px solid var(--border-subtle);
244244
padding: 8px 0;
245245
}
246246

247-
.ai-chat-drawer__repo,
248247
.ai-chat-drawer__status {
249248
margin: 0;
250249
font-size: 0.78rem;
251250
}
252251

253-
.ai-chat-drawer__repo {
254-
color: var(--text-muted);
255-
max-width: 66%;
256-
text-overflow: ellipsis;
257-
overflow: hidden;
258-
white-space: nowrap;
259-
}
260-
261252
.ai-chat-drawer__status {
262253
color: var(--text-subtle);
263-
text-align: right;
254+
text-align: left;
264255
}
265256

266257
.ai-chat-drawer__status[data-level='pending'] {
@@ -278,6 +269,7 @@
278269
.ai-chat-drawer__rate {
279270
margin: -2px 0 0;
280271
font-size: 0.74rem;
272+
font-style: italic;
281273
color: var(--text-muted);
282274
align-self: start;
283275
}
@@ -328,6 +320,14 @@
328320
color: var(--text-muted);
329321
}
330322

323+
.ai-chat-message__label-model {
324+
margin-left: 6px;
325+
font-size: 0.64rem;
326+
letter-spacing: 0;
327+
text-transform: none;
328+
color: color-mix(in srgb, var(--text-muted) 72%, var(--panel-text));
329+
}
330+
331331
.ai-chat-message__body {
332332
margin: 4px 0 0;
333333
font-size: 0.85rem;
@@ -446,21 +446,19 @@
446446
max-width: min(58vw, 260px);
447447
}
448448

449-
.ai-chat-drawer {
449+
.ai-chat-drawer,
450+
.ai-chat-drawer.ai-chat-drawer--right,
451+
.ai-chat-drawer.ai-chat-drawer--left {
450452
top: auto;
451-
right: 12px;
452-
left: 12px;
453-
bottom: 12px;
454-
width: auto;
455-
max-height: 68vh;
453+
right: 24px;
454+
left: 24px;
455+
bottom: auto;
456+
width: calc(100vw - 48px);
457+
max-width: none;
458+
max-height: min(68vh, calc(100dvh - 100px));
456459
}
457460

458461
.ai-chat-drawer__meta {
459-
flex-direction: column;
460462
align-items: flex-start;
461463
}
462-
463-
.ai-chat-drawer__repo {
464-
max-width: 100%;
465-
}
466464
}

src/styles/diagnostics.css

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -216,10 +216,10 @@
216216
@media (max-width: 900px) {
217217
.diagnostics-drawer {
218218
top: auto;
219-
right: 12px;
220-
left: 12px;
221-
bottom: 12px;
222-
width: auto;
223-
max-height: 58vh;
219+
right: 24px;
220+
left: 24px;
221+
bottom: auto;
222+
width: calc(100vw - 48px);
223+
max-height: min(58vh, calc(100dvh - 100px));
224224
}
225225
}

src/styles/layout-shell.css

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,10 @@
245245
display: none;
246246
}
247247

248+
.app-grid-ai-toggle[hidden] {
249+
display: none;
250+
}
251+
248252
.app-grid-theme-controls {
249253
display: inline-flex;
250254
gap: 10px;
@@ -306,7 +310,7 @@
306310
}
307311

308312
.app-grid-view-controls[hidden] {
309-
display: none !important;
313+
display: none;
310314
}
311315

312316
.app-grid-theme-controls {
@@ -324,7 +328,7 @@
324328
}
325329

326330
@media (max-width: 900px) {
327-
.app-grid-ai-toggle {
331+
.app-grid-ai-toggle:not([hidden]) {
328332
display: inline-flex;
329333
}
330334
}

0 commit comments

Comments
 (0)