@ouraihub/aether-ui 0.1.0 → 0.1.2
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/package.json +3 -3
- package/src/chat/ApprovalCard.svelte +8 -2
- package/src/chat/ChatComposer.svelte +319 -0
- package/src/chat/ChatMessage.svelte +262 -0
- package/src/chat/ChatPanel.css +386 -0
- package/src/chat/ChatPanel.svelte +276 -1880
- package/src/chat/ChatPanelApprovals.svelte +28 -0
- package/src/chat/ChatPanelComposer.svelte +336 -0
- package/src/chat/ChatPanelDialogs.svelte +242 -0
- package/src/chat/ChatPanelHeader.svelte +108 -0
- package/src/chat/ChatPanelMessages.svelte +166 -0
- package/src/chat/ChatPanelMode.svelte +190 -0
- package/src/chat/ChatPanelState.svelte.ts +1 -0
- package/src/chat/ChatPanelToolbar.svelte +436 -0
- package/src/chat/ChatSurface.svelte +168 -0
- package/src/chat/ContextUsageStatus.svelte +97 -0
- package/src/chat/MessageItem.svelte +111 -214
- package/src/chat/ModelEffortPicker.svelte +326 -0
- package/src/chat/PickerEffort.svelte +71 -0
- package/src/chat/ReasoningControl.svelte +184 -0
- package/src/chat/ReasoningSlider.svelte +174 -0
- package/src/chat/SkillPicker.svelte +14 -6
- package/src/chat/UsageControl.svelte +223 -0
- package/src/chat/UsageDetails.svelte +44 -90
- package/src/chat/chat-attachments.svelte.ts +78 -0
- package/src/chat/chat-panel-history.svelte.ts +430 -0
- package/src/chat/chat-panel-models.svelte.ts +97 -0
- package/src/chat/chat-panel-props.ts +38 -0
- package/src/chat/context-status.ts +101 -0
- package/src/chat/icons/LICENSE-REMIX +186 -0
- package/src/chat/icons/LICENSE-SIMPLE-ICONS +30 -0
- package/src/chat/icons/PathIcon.svelte +8 -0
- package/src/chat/icons/effort-icons.ts +65 -0
- package/src/chat/icons/status-icons.ts +105 -0
- package/src/chat/index.ts +25 -1
- package/src/chat/model-effort.ts +177 -0
- package/src/chat/run-session-history.ts +56 -0
- package/src/chat/run-session-types.ts +69 -0
- package/src/chat/run-session.svelte.ts +73 -135
- package/src/chat/test-support/chat-fixture.ts +194 -0
- package/src/chat/test-support/conversation-fixtures.ts +32 -0
- package/src/chat/test-support/run-session-fixture.ts +112 -0
- package/src/dev/Demo.svelte +3 -1
- package/src/i18n/en-chat.d.ts +1 -0
- package/src/i18n/en-chat.js +201 -0
- package/src/i18n/en.ts +58 -180
- package/src/i18n/index.ts +7 -2
- package/src/i18n/zh-CN-chat.d.ts +1 -0
- package/src/i18n/zh-CN-chat.js +190 -0
- package/src/i18n/zh-CN.ts +8 -153
- package/src/logs/LogPanel.svelte +9 -3
- package/src/logs/LogSettings.svelte +3 -1
- package/src/mcp/McpClientEditor.svelte +204 -0
- package/src/mcp/McpClientSettings.svelte +57 -130
- package/src/mcp/McpServerSettings.svelte +47 -11
- package/src/mcp/input.ts +2 -1
- package/src/ports/contract.ts +11 -2
- package/src/ports/fake-optional.ts +81 -0
- package/src/ports/fake.ts +90 -86
- package/src/ports/search.ts +11 -2
- package/src/ports/test-support/fake-fixture.ts +63 -0
- package/src/providers/EndpointKeysDialog.svelte +27 -13
- package/src/providers/EndpointModels.svelte +311 -0
- package/src/providers/EndpointPanel.svelte +33 -258
- package/src/providers/ModelPickerDialog.svelte +59 -16
- package/src/providers/ModelPricing.svelte +125 -0
- package/src/providers/ModelSelect.svelte +22 -8
- package/src/providers/ModelSettingsDialog.svelte +61 -126
- package/src/providers/ProviderDialogs.svelte +120 -0
- package/src/providers/ProviderList.svelte +159 -0
- package/src/providers/ProvidersSettings.svelte +67 -207
- package/src/providers/RequestConfigDialog.svelte +40 -12
- package/src/providers/SecretInput.svelte +11 -3
- package/src/providers/draft.ts +39 -13
- package/src/providers/edit-session.ts +31 -7
- package/src/providers/reasoning.ts +18 -4
- package/src/providers/revision.svelte.ts +3 -1
- package/src/providers/test-support/providers-fixture.ts +120 -0
- package/src/search/SearchAdvancedTools.svelte +182 -0
- package/src/search/SearchProviderCard.svelte +195 -0
- package/src/search/SearchSettings.svelte +62 -265
- package/src/search/settings-flow.ts +8 -3
- package/src/skills/SkillAdd.svelte +51 -18
- package/src/skills/SkillAuthoring.svelte +69 -20
- package/src/skills/SkillEditor.svelte +13 -3
- package/src/skills/SkillPreviewDialog.svelte +19 -5
- package/src/skills/SkillsSettings.svelte +11 -4
- package/src/skills/test-support/skills-fixture.ts +139 -0
- package/src/tauri/index.ts +23 -7
- package/src/web/index.ts +90 -25
package/src/web/index.ts
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
// Browser HTTP adapter. Only enabled capabilities are exposed; desktop/IPC never enter this module.
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
isContract,
|
|
4
|
+
validateRunAccepted,
|
|
5
|
+
validateRunEvent,
|
|
6
|
+
validateRunSnapshot,
|
|
7
|
+
} from '@ouraihub/aether-contracts'
|
|
8
|
+
import type {
|
|
9
|
+
ContractMap,
|
|
10
|
+
ContractName,
|
|
11
|
+
KitError,
|
|
12
|
+
RunAccepted,
|
|
13
|
+
RunEvent,
|
|
14
|
+
} from '@ouraihub/aether-contracts'
|
|
4
15
|
import { KitClientError } from '../ports/contract'
|
|
5
16
|
import type { CallOptions, KitPorts } from '../ports/contract'
|
|
6
17
|
|
|
@@ -44,19 +55,34 @@ const failure = (code: KitError['code'], message: string, reason?: string): KitC
|
|
|
44
55
|
const invalidResponse = () => failure('upstream', 'Invalid server response', 'invalid_response')
|
|
45
56
|
const normalize = (error: unknown, signal?: AbortSignal): KitClientError => {
|
|
46
57
|
if (error instanceof KitClientError) return error
|
|
47
|
-
return signal?.aborted
|
|
58
|
+
return signal?.aborted
|
|
59
|
+
? failure('cancelled', 'Request cancelled')
|
|
60
|
+
: failure('network', 'Unable to contact server')
|
|
48
61
|
}
|
|
49
62
|
const id = encodeURIComponent
|
|
50
63
|
|
|
51
64
|
export function createWebPorts(options: WebPortsOptions): KitPorts {
|
|
52
65
|
const base = new URL(options.baseURL)
|
|
53
|
-
if (
|
|
66
|
+
if (
|
|
67
|
+
!['http:', 'https:'].includes(base.protocol) ||
|
|
68
|
+
base.username ||
|
|
69
|
+
base.password ||
|
|
70
|
+
base.search ||
|
|
71
|
+
base.hash
|
|
72
|
+
)
|
|
54
73
|
throw failure('bad_request', 'Invalid API base URL')
|
|
55
74
|
const api = new URL('/api/v1/', base)
|
|
56
|
-
const request = async (
|
|
75
|
+
const request = async (
|
|
76
|
+
path: string,
|
|
77
|
+
method: string,
|
|
78
|
+
body?: unknown,
|
|
79
|
+
signal?: AbortSignal,
|
|
80
|
+
): Promise<Response> => {
|
|
57
81
|
if (signal?.aborted) throw failure('cancelled', 'Request cancelled')
|
|
58
82
|
try {
|
|
59
|
-
const headers = new Headers({
|
|
83
|
+
const headers = new Headers({
|
|
84
|
+
Accept: path.endsWith('/events') ? 'text/event-stream' : 'application/json',
|
|
85
|
+
})
|
|
60
86
|
if (method !== 'GET') {
|
|
61
87
|
const csrf = typeof options.csrf === 'function' ? await options.csrf() : options.csrf
|
|
62
88
|
headers.set('X-CSRF-Token', csrf)
|
|
@@ -79,7 +105,8 @@ export function createWebPorts(options: WebPortsOptions): KitPorts {
|
|
|
79
105
|
throw invalidResponse()
|
|
80
106
|
}
|
|
81
107
|
if (isContract('KitError', value)) throw new KitClientError(value)
|
|
82
|
-
if (record(value) && isContract('KitError', value.error))
|
|
108
|
+
if (record(value) && isContract('KitError', value.error))
|
|
109
|
+
throw new KitClientError(value.error)
|
|
83
110
|
throw invalidResponse()
|
|
84
111
|
}
|
|
85
112
|
return response
|
|
@@ -127,7 +154,9 @@ export function createWebPorts(options: WebPortsOptions): KitPorts {
|
|
|
127
154
|
if (!accepted || ended || dispatched) return
|
|
128
155
|
dispatched = true
|
|
129
156
|
const runId = accepted.runId
|
|
130
|
-
void cancel(runId).catch((error: unknown) =>
|
|
157
|
+
void cancel(runId).catch((error: unknown) =>
|
|
158
|
+
options.onStreamError?.(runId, normalize(error)),
|
|
159
|
+
)
|
|
131
160
|
}
|
|
132
161
|
const abort = () => {
|
|
133
162
|
requested = true
|
|
@@ -176,13 +205,22 @@ export function createWebPorts(options: WebPortsOptions): KitPorts {
|
|
|
176
205
|
try {
|
|
177
206
|
if (requested || signal?.aborted) {
|
|
178
207
|
dispatched = true
|
|
179
|
-
await cancel(runId).catch((error: unknown) =>
|
|
208
|
+
await cancel(runId).catch((error: unknown) =>
|
|
209
|
+
options.onStreamError?.(runId, normalize(error)),
|
|
210
|
+
)
|
|
180
211
|
}
|
|
181
212
|
const stream = await request(`runs/${id(runId)}/events`, 'GET')
|
|
182
|
-
if (
|
|
213
|
+
if (
|
|
214
|
+
!stream.headers
|
|
215
|
+
.get('Content-Type')
|
|
216
|
+
?.toLowerCase()
|
|
217
|
+
.startsWith('text/event-stream') ||
|
|
218
|
+
!stream.body
|
|
219
|
+
)
|
|
183
220
|
throw invalidResponse()
|
|
184
221
|
await consumeEvents(stream.body, emit, () => ended)
|
|
185
|
-
if (!ended)
|
|
222
|
+
if (!ended)
|
|
223
|
+
throw failure('network', 'Event stream disconnected', 'stream_disconnected')
|
|
186
224
|
} catch (error) {
|
|
187
225
|
if (!ended) {
|
|
188
226
|
dispatchCancel()
|
|
@@ -193,7 +231,9 @@ export function createWebPorts(options: WebPortsOptions): KitPorts {
|
|
|
193
231
|
kind: 'end',
|
|
194
232
|
status: snapshot.status,
|
|
195
233
|
...(snapshot.error ? { error: snapshot.error } : {}),
|
|
196
|
-
...(snapshot.exhausted !== undefined
|
|
234
|
+
...(snapshot.exhausted !== undefined
|
|
235
|
+
? { exhausted: snapshot.exhausted }
|
|
236
|
+
: {}),
|
|
197
237
|
})
|
|
198
238
|
} catch {
|
|
199
239
|
/* A missing snapshot is unknown, never a fabricated completion. */
|
|
@@ -228,7 +268,11 @@ export function createWebPorts(options: WebPortsOptions): KitPorts {
|
|
|
228
268
|
rename: (conversationId, title) =>
|
|
229
269
|
json(`${path(conversationId)}/rename`, 'POST', contract('ConversationSummary'), { title }),
|
|
230
270
|
editTurn: (conversationId, turnId, text, expectedText) =>
|
|
231
|
-
json(`${path(conversationId)}/edit-turn`, 'POST', contract('Conversation'), {
|
|
271
|
+
json(`${path(conversationId)}/edit-turn`, 'POST', contract('Conversation'), {
|
|
272
|
+
turnId,
|
|
273
|
+
text,
|
|
274
|
+
expectedText,
|
|
275
|
+
}),
|
|
232
276
|
removeTurn: (conversationId, turnId) =>
|
|
233
277
|
json(`${path(conversationId)}/remove-turn`, 'POST', contract('Conversation'), { turnId }),
|
|
234
278
|
fork: (conversationId, turnId) =>
|
|
@@ -245,16 +289,20 @@ export function createWebPorts(options: WebPortsOptions): KitPorts {
|
|
|
245
289
|
list: () => json('providers', 'GET', providers),
|
|
246
290
|
save: (input) => json('providers', 'POST', providers, input),
|
|
247
291
|
remove: (providerId) => json(`providers/${id(providerId)}`, 'DELETE', providers),
|
|
248
|
-
setEnabled: (providerId, enabled) =>
|
|
292
|
+
setEnabled: (providerId, enabled) =>
|
|
293
|
+
json(`providers/${id(providerId)}/enabled`, 'POST', providers, { enabled }),
|
|
249
294
|
modelOptions: (filter = {}) => {
|
|
250
295
|
const query = new URLSearchParams()
|
|
251
296
|
if (filter.modelType !== undefined) query.set('modelType', filter.modelType)
|
|
252
|
-
if (filter.supportsTools !== undefined)
|
|
297
|
+
if (filter.supportsTools !== undefined)
|
|
298
|
+
query.set('supportsTools', String(filter.supportsTools))
|
|
253
299
|
return json(`providers/model-options?${query}`, 'GET', array(contract('ModelOption')))
|
|
254
300
|
},
|
|
255
|
-
probe: (target, call) =>
|
|
301
|
+
probe: (target, call) =>
|
|
302
|
+
json('providers/probe', 'POST', contract('ProbeResult'), target, call),
|
|
256
303
|
saveKey: (input) => json('providers/keys', 'POST', providers, input),
|
|
257
|
-
removeKey: (endpointId, keyId) =>
|
|
304
|
+
removeKey: (endpointId, keyId) =>
|
|
305
|
+
json(`providers/${id(endpointId)}/keys/${id(keyId)}`, 'DELETE', providers),
|
|
258
306
|
revealKey: (keyId, currentPassword) =>
|
|
259
307
|
json(`providers/keys/${id(keyId)}/reveal`, 'POST', string, { currentPassword }),
|
|
260
308
|
}
|
|
@@ -268,16 +316,26 @@ export function createWebPorts(options: WebPortsOptions): KitPorts {
|
|
|
268
316
|
save: (input, call) => json('search/settings', 'POST', settings, input, call),
|
|
269
317
|
setDefault: (capability, provider, call) =>
|
|
270
318
|
json('search/default', 'POST', settings, { capability, provider }, call),
|
|
271
|
-
savePreferences: (input, call) =>
|
|
319
|
+
savePreferences: (input, call) =>
|
|
320
|
+
json('search/preferences', 'PUT', contract('SearchPreferences'), input, call),
|
|
272
321
|
saveKey: (capability, provider, value, keyId, call) =>
|
|
273
322
|
json('search/keys', 'POST', settings, { capability, provider, value, keyId }, call),
|
|
274
323
|
removeKey: (capability, provider, keyId, call) =>
|
|
275
324
|
json('search/keys', 'DELETE', settings, { capability, provider, keyId }, call),
|
|
276
325
|
reveal: (capability, provider, keyId, currentPassword, call) =>
|
|
277
|
-
json(
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
326
|
+
json(
|
|
327
|
+
'search/keys/reveal',
|
|
328
|
+
'POST',
|
|
329
|
+
string,
|
|
330
|
+
{ capability, provider, keyId, currentPassword },
|
|
331
|
+
call,
|
|
332
|
+
),
|
|
333
|
+
check: (capability, provider, call) =>
|
|
334
|
+
json('search/check', 'POST', count, { capability, provider }, call),
|
|
335
|
+
search: (query, call) =>
|
|
336
|
+
json('search/search', 'POST', contract('SearchResult'), { query }, call),
|
|
337
|
+
fetch: (target, call) =>
|
|
338
|
+
json('search/fetch', 'POST', contract('SearchPage'), { url: target }, call),
|
|
281
339
|
}
|
|
282
340
|
}
|
|
283
341
|
if (options.skills) {
|
|
@@ -289,7 +347,8 @@ export function createWebPorts(options: WebPortsOptions): KitPorts {
|
|
|
289
347
|
install: (source, confirmedDigest, replace) =>
|
|
290
348
|
json('skills/install', 'POST', skills, { source, confirmedDigest, replace }),
|
|
291
349
|
save: (input) => json('skills/save', 'POST', skills, input),
|
|
292
|
-
duplicate: (skillId, newName) =>
|
|
350
|
+
duplicate: (skillId, newName) =>
|
|
351
|
+
json(`skills/${id(skillId)}/duplicate`, 'POST', skills, { newName }),
|
|
293
352
|
reorder: (ids) => json('skills/reorder', 'POST', skills, { ids }),
|
|
294
353
|
remove: (skillId) => json(`skills/${id(skillId)}`, 'DELETE', skills),
|
|
295
354
|
}
|
|
@@ -299,9 +358,15 @@ export function createWebPorts(options: WebPortsOptions): KitPorts {
|
|
|
299
358
|
ports.mcpClient = {
|
|
300
359
|
list: () => json('mcp/servers', 'GET', servers),
|
|
301
360
|
save: (input) =>
|
|
302
|
-
json(
|
|
361
|
+
json(
|
|
362
|
+
input.id ? `mcp/servers/${id(input.id)}` : 'mcp/servers',
|
|
363
|
+
input.id ? 'PUT' : 'POST',
|
|
364
|
+
servers,
|
|
365
|
+
input,
|
|
366
|
+
),
|
|
303
367
|
remove: (serverId) => json(`mcp/servers/${id(serverId)}`, 'DELETE', servers),
|
|
304
|
-
refresh: (serverId) =>
|
|
368
|
+
refresh: (serverId) =>
|
|
369
|
+
json(`mcp/servers/${id(serverId)}/refresh`, 'POST', array(contract('ToolDto')), {}),
|
|
305
370
|
setToolApproval: (serverId, tool, approval) =>
|
|
306
371
|
ack(`mcp/servers/${id(serverId)}/tools/${id(tool)}/approval`, 'PUT', { approval }),
|
|
307
372
|
}
|