@stina/extension-api 0.36.0 → 0.44.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/dist/{chunk-K53YNG2W.js → chunk-ZB7GJUPS.js} +1 -1
- package/dist/chunk-ZB7GJUPS.js.map +1 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -6
- package/dist/index.d.ts +34 -6
- package/dist/index.js +1 -1
- package/dist/runtime.cjs +26 -5
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.d.cts +2 -2
- package/dist/runtime.d.ts +2 -2
- package/dist/runtime.js +27 -6
- package/dist/runtime.js.map +1 -1
- package/dist/schemas/index.cjs +4 -0
- package/dist/schemas/index.cjs.map +1 -1
- package/dist/schemas/index.d.cts +3 -0
- package/dist/schemas/index.d.ts +3 -0
- package/dist/schemas/index.js +4 -0
- package/dist/schemas/index.js.map +1 -1
- package/dist/{types.tools-BYgcVNP4.d.cts → types.tools-BZQrEs91.d.cts} +227 -3
- package/dist/{types.tools-BYgcVNP4.d.ts → types.tools-BZQrEs91.d.ts} +227 -3
- package/package.json +1 -1
- package/schema/extension-manifest.schema.json +4 -0
- package/src/background.test.ts +6 -5
- package/src/background.ts +17 -10
- package/src/index.ts +7 -0
- package/src/messages.ts +29 -1
- package/src/runtime.ts +40 -0
- package/src/schemas/manifest.schema.ts +4 -0
- package/src/types.context.ts +105 -2
- package/src/types.contributions.ts +11 -0
- package/src/types.manifest.ts +7 -0
- package/src/types.provider.ts +112 -0
- package/src/types.ts +5 -0
- package/dist/chunk-K53YNG2W.js.map +0 -1
package/src/types.context.ts
CHANGED
|
@@ -8,6 +8,8 @@ import type { AIProvider } from './types.provider.js'
|
|
|
8
8
|
import type { Tool, ToolResult, Action } from './types.tools.js'
|
|
9
9
|
import type { ToolDefinition } from './types.contributions.js'
|
|
10
10
|
import type { StorageAPI, SecretsAPI } from './types.storage.js'
|
|
11
|
+
import type { LocalizedString } from './types.localization.js'
|
|
12
|
+
import type { HugeIconName } from './types.components.js'
|
|
11
13
|
|
|
12
14
|
/**
|
|
13
15
|
* Disposable resource that can be cleaned up
|
|
@@ -322,6 +324,79 @@ export interface UserAPI {
|
|
|
322
324
|
listIds(): Promise<string[]>
|
|
323
325
|
}
|
|
324
326
|
|
|
327
|
+
/**
|
|
328
|
+
* Visual presentation for a conversation Stina starts proactively in response to
|
|
329
|
+
* an event reported by an extension.
|
|
330
|
+
*
|
|
331
|
+
* The extension owns the *chrome* of the list entry — icon, label, framing,
|
|
332
|
+
* accent and badge — while Stina authors the *content* (title and opening
|
|
333
|
+
* message). Every field is optional: omitted fields fall back to sensible
|
|
334
|
+
* defaults, and `icon` falls back to the reporting extension's manifest icon.
|
|
335
|
+
*
|
|
336
|
+
* Colour is intentionally a small set of theme tokens rather than free-form so
|
|
337
|
+
* the conversation list stays visually coherent across light/dark themes.
|
|
338
|
+
*/
|
|
339
|
+
export interface ConversationPresentation {
|
|
340
|
+
/**
|
|
341
|
+
* Structural shape of the list entry — *what kind of thing* this is, not how
|
|
342
|
+
* urgent it is. Urgency is Stina's call alone (see `severityGuidance`).
|
|
343
|
+
* Defaults to `note`. Each variant renders a different set of fields:
|
|
344
|
+
* - `note` — icon, title and a two-line preview. The general-purpose default.
|
|
345
|
+
* - `event` — something happening at a point in time; renders `at` as a time
|
|
346
|
+
* block with a countdown. Meetings, reminders, deadlines.
|
|
347
|
+
* - `message` — something a person or system sent; renders `sender` on its own
|
|
348
|
+
* line with the subject as the title. Mail, chat, comments.
|
|
349
|
+
* - `digest` — several things collected into one entry; renders `items` as a
|
|
350
|
+
* short bullet list with a count. Morning briefs, weekly summaries.
|
|
351
|
+
* - `status` — a transactional outcome; renders `statusLabel` as a pill and no
|
|
352
|
+
* preview. Finished builds, deliveries, completed jobs.
|
|
353
|
+
* - `insight` — Stina's own observation or suggestion rather than an extension's
|
|
354
|
+
* report. Rendered in her own voice with a soft accent panel.
|
|
355
|
+
*/
|
|
356
|
+
variant?: 'note' | 'event' | 'message' | 'digest' | 'status' | 'insight'
|
|
357
|
+
/**
|
|
358
|
+
* Leading icon, as a Hugeicons name in lower case with hyphens (`sun-03`,
|
|
359
|
+
* `cloud-angled-rain`). Hugeicons documents its names in PascalCase; those are
|
|
360
|
+
* accepted and translated, but the hyphenated form is what the icon set uses.
|
|
361
|
+
* An unknown name falls back to a default rather than rendering blank.
|
|
362
|
+
* Falls back to the extension's manifest icon when omitted.
|
|
363
|
+
*/
|
|
364
|
+
icon?: HugeIconName
|
|
365
|
+
/** Small eyebrow label above the content, e.g. "Mail" or "Reminder". */
|
|
366
|
+
label?: LocalizedString
|
|
367
|
+
/** Accent colour as a theme token. Defaults to `default`. */
|
|
368
|
+
accent?: 'default' | 'info' | 'warning' | 'success' | 'danger'
|
|
369
|
+
/** Optional short badge, e.g. the account a mail arrived in. */
|
|
370
|
+
badge?: LocalizedString
|
|
371
|
+
/**
|
|
372
|
+
* When the event happens (ISO 8601). Only used by `variant: 'event'`, which
|
|
373
|
+
* renders it as a time block and derives a relative countdown from it.
|
|
374
|
+
*/
|
|
375
|
+
at?: string
|
|
376
|
+
/** Who sent it. Only used by `variant: 'message'`. */
|
|
377
|
+
sender?: LocalizedString
|
|
378
|
+
/**
|
|
379
|
+
* The collected items. Only used by `variant: 'digest'`; at most three are
|
|
380
|
+
* rendered, and `count` reports the true total when there are more.
|
|
381
|
+
*/
|
|
382
|
+
items?: LocalizedString[]
|
|
383
|
+
/** Total number of collected items, when it exceeds what `items` lists. */
|
|
384
|
+
count?: number
|
|
385
|
+
/** Short outcome label for the pill, e.g. "Delivered". Only used by `variant: 'status'`. */
|
|
386
|
+
statusLabel?: LocalizedString
|
|
387
|
+
/**
|
|
388
|
+
* Guidance to Stina on how to judge how much this deserves the user's attention
|
|
389
|
+
* — *not* a severity value. Extensions describe what would make an event
|
|
390
|
+
* important ("urgent when the sender is on the user's team, or the deadline is
|
|
391
|
+
* today"); Stina weighs that against everything else she knows and picks the
|
|
392
|
+
* level herself. She may disregard it entirely.
|
|
393
|
+
*
|
|
394
|
+
* Plain text in any language, one or two sentences. It is shown to Stina during
|
|
395
|
+
* her deliberation and never to the user.
|
|
396
|
+
*/
|
|
397
|
+
severityGuidance?: string
|
|
398
|
+
}
|
|
399
|
+
|
|
325
400
|
/**
|
|
326
401
|
* Chat instruction message
|
|
327
402
|
*/
|
|
@@ -329,6 +404,24 @@ export interface ChatInstructionMessage {
|
|
|
329
404
|
text: string
|
|
330
405
|
conversationId?: string
|
|
331
406
|
userId?: string
|
|
407
|
+
/**
|
|
408
|
+
* When true, the message is treated as a system event reported by the extension
|
|
409
|
+
* rather than a plain instruction. Instead of being appended to a conversation,
|
|
410
|
+
* Stina runs a hidden deliberation over it and decides herself whether to notify
|
|
411
|
+
* the user (by starting a new conversation via the `core_init_chat_session` tool).
|
|
412
|
+
*/
|
|
413
|
+
deliberate?: boolean
|
|
414
|
+
/**
|
|
415
|
+
* Identifier of the source that reported the event (typically the extension id).
|
|
416
|
+
* Used for logging/tracing of proactive decisions.
|
|
417
|
+
*/
|
|
418
|
+
source?: string
|
|
419
|
+
/**
|
|
420
|
+
* Optional visual presentation for the conversation Stina may start from this
|
|
421
|
+
* event. Only meaningful together with `deliberate: true`; ignored if Stina
|
|
422
|
+
* decides not to notify the user.
|
|
423
|
+
*/
|
|
424
|
+
presentation?: ConversationPresentation
|
|
332
425
|
}
|
|
333
426
|
|
|
334
427
|
/**
|
|
@@ -371,11 +464,14 @@ export interface ExtensionModule {
|
|
|
371
464
|
/**
|
|
372
465
|
* Restart policy for background tasks.
|
|
373
466
|
* Controls how tasks are restarted after failures.
|
|
467
|
+
*
|
|
468
|
+
* A task that returns from its callback without having been aborted is
|
|
469
|
+
* considered finished on purpose and is never restarted, regardless of policy.
|
|
374
470
|
*/
|
|
375
471
|
export interface BackgroundRestartPolicy {
|
|
376
472
|
/**
|
|
377
473
|
* When to restart the task:
|
|
378
|
-
* - 'always':
|
|
474
|
+
* - 'always': Restart if the task threw, or stopped without anyone asking it to
|
|
379
475
|
* - 'on-failure': Only restart if the task threw an error
|
|
380
476
|
* - 'never': Never restart automatically
|
|
381
477
|
*/
|
|
@@ -469,6 +565,11 @@ export interface BackgroundTaskContext extends ExecutionContext {
|
|
|
469
565
|
* Callback function for background tasks.
|
|
470
566
|
* The function should run until the signal is aborted, then clean up and return.
|
|
471
567
|
*
|
|
568
|
+
* Returning before the signal is aborted means the task has finished on purpose:
|
|
569
|
+
* it is marked as completed and is not restarted, whatever the restart policy says.
|
|
570
|
+
* A task that has nothing to do right now but wants to be retried later should
|
|
571
|
+
* therefore keep running (and wait on the signal) rather than return early.
|
|
572
|
+
*
|
|
472
573
|
* @example
|
|
473
574
|
* ```typescript
|
|
474
575
|
* const callback: BackgroundTaskCallback = async (ctx) => {
|
|
@@ -508,8 +609,10 @@ export interface BackgroundTaskHealth {
|
|
|
508
609
|
|
|
509
610
|
/**
|
|
510
611
|
* Current task status.
|
|
612
|
+
* 'completed' means the task returned on its own and will not be restarted,
|
|
613
|
+
* while 'stopped' means someone asked it to stop.
|
|
511
614
|
*/
|
|
512
|
-
status: 'pending' | 'running' | 'stopped' | 'failed' | 'restarting'
|
|
615
|
+
status: 'pending' | 'running' | 'stopped' | 'completed' | 'failed' | 'restarting'
|
|
513
616
|
|
|
514
617
|
/**
|
|
515
618
|
* Number of times the task has been restarted.
|
|
@@ -234,6 +234,17 @@ export interface ProviderDefinition {
|
|
|
234
234
|
* to call extension actions (e.g. OAuth, "Test connection").
|
|
235
235
|
*/
|
|
236
236
|
configView?: ProviderConfigView
|
|
237
|
+
/**
|
|
238
|
+
* Extra settings shown only for models that report
|
|
239
|
+
* `capabilities.voiceDuplex` — voice selection, transcription model, and
|
|
240
|
+
* whatever else is specific to this provider's realtime backend.
|
|
241
|
+
*
|
|
242
|
+
* Same DSL and same `$settings.<key>` binding as {@link configView}; the host
|
|
243
|
+
* renders it in its own section of the model editor and stores the values in
|
|
244
|
+
* the same settingsOverride. Keep general provider settings in `configView`
|
|
245
|
+
* so they stay visible for models without voice.
|
|
246
|
+
*/
|
|
247
|
+
voiceConfigView?: ProviderConfigView
|
|
237
248
|
}
|
|
238
249
|
|
|
239
250
|
/**
|
package/src/types.manifest.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import type { Permission } from './types.permissions.js'
|
|
8
8
|
import type { ExtensionContributions } from './types.contributions.js'
|
|
9
|
+
import type { HugeIconName } from './types.components.js'
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Extension manifest format (manifest.json)
|
|
@@ -19,6 +20,12 @@ export interface ExtensionManifest {
|
|
|
19
20
|
version: string
|
|
20
21
|
/** Short description */
|
|
21
22
|
description: string
|
|
23
|
+
/**
|
|
24
|
+
* Optional icon (Hugeicons name) representing the extension. Used as the default
|
|
25
|
+
* icon for proactive conversation list entries this extension triggers, and as a
|
|
26
|
+
* general visual identity for the extension in the UI.
|
|
27
|
+
*/
|
|
28
|
+
icon?: HugeIconName
|
|
22
29
|
/** Author information */
|
|
23
30
|
author: {
|
|
24
31
|
name: string
|
package/src/types.provider.ts
CHANGED
|
@@ -33,6 +33,22 @@ export interface AIProvider {
|
|
|
33
33
|
* Optional: Generate embeddings
|
|
34
34
|
*/
|
|
35
35
|
embed?(texts: string[]): Promise<number[][]>
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Optional: Open a duplex voice session for a model that reports
|
|
39
|
+
* `capabilities.voiceDuplex`.
|
|
40
|
+
*
|
|
41
|
+
* The provider is responsible for authenticating with its backend and
|
|
42
|
+
* returning everything the client needs to connect. Audio flows directly
|
|
43
|
+
* between the client and the provider — it never passes through Stina — but
|
|
44
|
+
* the session is configured here, on the server, so the instructions and
|
|
45
|
+
* tools cannot be tampered with client-side.
|
|
46
|
+
*
|
|
47
|
+
* Implementations must not put long-lived credentials in the returned
|
|
48
|
+
* descriptor. Either complete the handshake here (`webrtc`) or mint a
|
|
49
|
+
* short-lived secret (`websocket`).
|
|
50
|
+
*/
|
|
51
|
+
createVoiceSession?(options: VoiceSessionOptions): Promise<VoiceSessionDescriptor>
|
|
36
52
|
}
|
|
37
53
|
|
|
38
54
|
/**
|
|
@@ -47,6 +63,102 @@ export interface ModelInfo {
|
|
|
47
63
|
description?: string
|
|
48
64
|
/** Context window size */
|
|
49
65
|
contextLength?: number
|
|
66
|
+
/** What this model can do beyond plain text chat */
|
|
67
|
+
capabilities?: ModelCapabilities
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Optional model capabilities.
|
|
72
|
+
*
|
|
73
|
+
* Absent or `false` means "not supported" — a provider that says nothing keeps
|
|
74
|
+
* behaving exactly as before.
|
|
75
|
+
*/
|
|
76
|
+
export interface ModelCapabilities {
|
|
77
|
+
/**
|
|
78
|
+
* The model can hold a real-time two-way voice conversation, with the user
|
|
79
|
+
* and the model able to speak at the same time.
|
|
80
|
+
*
|
|
81
|
+
* Report this per model *and* per auth mode: the same provider may support
|
|
82
|
+
* voice with one kind of credential and not another.
|
|
83
|
+
*/
|
|
84
|
+
voiceDuplex?: boolean
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* How the client wants to connect to the voice session.
|
|
89
|
+
*
|
|
90
|
+
* Clients ask for the transport they can actually implement — browsers do
|
|
91
|
+
* WebRTC, a native app may prefer a plain socket — and providers implement the
|
|
92
|
+
* ones their backend offers. A provider that is handed a transport it does not
|
|
93
|
+
* support should throw with a message naming the transports it does.
|
|
94
|
+
*/
|
|
95
|
+
export type VoiceTransportRequest =
|
|
96
|
+
/** Client has created an offer and wants the provider to complete the handshake. */
|
|
97
|
+
| { transport: 'webrtc'; sdpOffer: string }
|
|
98
|
+
/** Client will open a socket itself and needs a short-lived credential for it. */
|
|
99
|
+
| { transport: 'websocket' }
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Everything the client needs to connect, and nothing it needs to decide.
|
|
103
|
+
*
|
|
104
|
+
* `sessionConfig` is the provider-shaped session object (instructions, tools,
|
|
105
|
+
* voice, transcription). The client forwards it verbatim once the connection is
|
|
106
|
+
* up — it is a transport, not a decision-maker.
|
|
107
|
+
*/
|
|
108
|
+
export type VoiceSessionDescriptor =
|
|
109
|
+
| {
|
|
110
|
+
transport: 'webrtc'
|
|
111
|
+
/** Answer to the client's offer. */
|
|
112
|
+
sdpAnswer: string
|
|
113
|
+
sessionConfig: unknown
|
|
114
|
+
/** Provider-side ID for the call, useful for logging and teardown. */
|
|
115
|
+
providerSessionId?: string
|
|
116
|
+
}
|
|
117
|
+
| {
|
|
118
|
+
transport: 'websocket'
|
|
119
|
+
/** Socket URL to connect to. */
|
|
120
|
+
url: string
|
|
121
|
+
/** Short-lived credential. Must not be a long-lived API key. */
|
|
122
|
+
clientSecret: string
|
|
123
|
+
/** ISO timestamp after which `clientSecret` stops working. */
|
|
124
|
+
expiresAt: string
|
|
125
|
+
sessionConfig: unknown
|
|
126
|
+
providerSessionId?: string
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Options for opening a voice session.
|
|
131
|
+
*
|
|
132
|
+
* Mirrors {@link ChatOptions} where it can, so a provider that already
|
|
133
|
+
* implements `chat` finds the same shapes here.
|
|
134
|
+
*/
|
|
135
|
+
export interface VoiceSessionOptions {
|
|
136
|
+
/** How the client wants to connect */
|
|
137
|
+
transport: VoiceTransportRequest
|
|
138
|
+
/** Model to use — must be one that reported `capabilities.voiceDuplex` */
|
|
139
|
+
model?: string
|
|
140
|
+
/**
|
|
141
|
+
* System instructions for the session. This is how the assistant keeps her
|
|
142
|
+
* identity in voice mode; providers must pass it through unchanged.
|
|
143
|
+
*/
|
|
144
|
+
instructions?: string
|
|
145
|
+
/** Tools the model may call during the conversation */
|
|
146
|
+
tools?: ToolDefinition[]
|
|
147
|
+
/**
|
|
148
|
+
* The user's language as an ISO-639-1 code, when known.
|
|
149
|
+
*
|
|
150
|
+
* Pass it to the transcription model rather than letting it detect the
|
|
151
|
+
* language per utterance. Detection is unreliable on short or quiet audio and
|
|
152
|
+
* fails in a way that looks like nonsense rather than an error — a Swedish
|
|
153
|
+
* "hej" coming back as Indonesian, for instance.
|
|
154
|
+
*/
|
|
155
|
+
language?: string
|
|
156
|
+
/** Provider-specific settings from model configuration */
|
|
157
|
+
settings?: Record<string, unknown>
|
|
158
|
+
/** Request context (user info, session metadata — not provider config) */
|
|
159
|
+
context?: { userId?: string; [key: string]: unknown }
|
|
160
|
+
/** Abort signal for cancellation */
|
|
161
|
+
signal?: AbortSignal
|
|
50
162
|
}
|
|
51
163
|
|
|
52
164
|
/**
|
package/src/types.ts
CHANGED
|
@@ -55,11 +55,15 @@ export type { ExtensionManifest, Platform } from './types.manifest.js'
|
|
|
55
55
|
export type {
|
|
56
56
|
AIProvider,
|
|
57
57
|
ModelInfo,
|
|
58
|
+
ModelCapabilities,
|
|
58
59
|
ChatMessage,
|
|
59
60
|
ToolCall,
|
|
60
61
|
ChatOptions,
|
|
61
62
|
GetModelsOptions,
|
|
62
63
|
StreamEvent,
|
|
64
|
+
VoiceSessionOptions,
|
|
65
|
+
VoiceSessionDescriptor,
|
|
66
|
+
VoiceTransportRequest,
|
|
63
67
|
} from './types.provider.js'
|
|
64
68
|
|
|
65
69
|
// Tools and Actions
|
|
@@ -83,6 +87,7 @@ export type {
|
|
|
83
87
|
UserProfile,
|
|
84
88
|
UserAPI,
|
|
85
89
|
ChatInstructionMessage,
|
|
90
|
+
ConversationPresentation,
|
|
86
91
|
ChatAPI,
|
|
87
92
|
LogAPI,
|
|
88
93
|
ExtensionModule,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/messages.ts"],"sourcesContent":["/**\n * Message protocol between Extension Host and Extension Workers\n */\n\nimport type {\n ChatMessage,\n ChatOptions,\n GetModelsOptions,\n StreamEvent,\n ToolResult,\n ActionResult,\n ModelInfo,\n SchedulerFirePayload,\n} from './types.js'\n\n// ============================================================================\n// Host → Worker Messages\n// ============================================================================\n\nexport type HostToWorkerMessage =\n | ActivateMessage\n | DeactivateMessage\n | SettingsChangedMessage\n | SchedulerFireMessage\n | ProviderChatRequestMessage\n | ProviderModelsRequestMessage\n | ToolExecuteRequestMessage\n | ActionExecuteRequestMessage\n | ResponseMessage\n | StreamingFetchChunkMessage\n | BackgroundTaskStartMessage\n | BackgroundTaskStopMessage\n\nexport interface ActivateMessage {\n type: 'activate'\n id: string\n payload: {\n extensionId: string\n extensionVersion: string\n storagePath: string\n permissions: string[]\n settings: Record<string, unknown>\n }\n}\n\nexport interface DeactivateMessage {\n type: 'deactivate'\n id: string\n}\n\nexport interface SettingsChangedMessage {\n type: 'settings-changed'\n id: string\n payload: {\n key: string\n value: unknown\n }\n}\n\nexport interface SchedulerFireMessage {\n type: 'scheduler-fire'\n id: string\n payload: SchedulerFirePayload\n}\n\nexport interface ProviderChatRequestMessage {\n type: 'provider-chat-request'\n id: string\n payload: {\n providerId: string\n messages: ChatMessage[]\n options: ChatOptions\n }\n}\n\nexport interface ProviderModelsRequestMessage {\n type: 'provider-models-request'\n id: string\n payload: {\n providerId: string\n options?: GetModelsOptions\n }\n}\n\nexport interface ToolExecuteRequestMessage {\n type: 'tool-execute-request'\n id: string\n payload: {\n toolId: string\n params: Record<string, unknown>\n /** User ID if the tool is executed in a user context */\n userId?: string\n }\n}\n\nexport interface ActionExecuteRequestMessage {\n type: 'action-execute-request'\n id: string\n payload: {\n actionId: string\n params: Record<string, unknown>\n /** User ID if the action is executed in a user context */\n userId?: string\n }\n}\n\nexport interface ResponseMessage {\n type: 'response'\n id: string\n payload: {\n requestId: string\n success: boolean\n data?: unknown\n error?: string\n }\n}\n\n/**\n * Message sent from host to worker with streaming fetch data chunks.\n * Used for streaming network responses (e.g., NDJSON streams from Ollama).\n */\nexport interface StreamingFetchChunkMessage {\n type: 'streaming-fetch-chunk'\n id: string\n payload: {\n requestId: string\n chunk: string\n done: boolean\n error?: string\n }\n}\n\n/**\n * Message sent from host to worker to start a registered background task.\n */\nexport interface BackgroundTaskStartMessage {\n type: 'background-task-start'\n id: string\n payload: {\n taskId: string\n }\n}\n\n/**\n * Message sent from host to worker to stop a running background task.\n */\nexport interface BackgroundTaskStopMessage {\n type: 'background-task-stop'\n id: string\n payload: {\n taskId: string\n }\n}\n\n// ============================================================================\n// Worker → Host Messages\n// ============================================================================\n\nexport type WorkerToHostMessage =\n | ReadyMessage\n | RequestMessage\n | ProviderRegisteredMessage\n | ToolRegisteredMessage\n | ActionRegisteredMessage\n | StreamEventMessage\n | LogMessage\n | ProviderModelsResponseMessage\n | ToolExecuteResponseMessage\n | ActionExecuteResponseMessage\n | StreamingFetchAckMessage\n | BackgroundTaskRegisteredMessage\n | BackgroundTaskStatusMessage\n | BackgroundTaskHealthMessage\n\nexport interface ReadyMessage {\n type: 'ready'\n}\n\n/**\n * Message sent from worker to host to acknowledge receipt of a streaming fetch chunk.\n * This enables backpressure control to prevent unbounded memory growth.\n */\nexport interface StreamingFetchAckMessage {\n type: 'streaming-fetch-ack'\n payload: {\n requestId: string\n }\n}\n\nexport interface RequestMessage {\n type: 'request'\n id: string\n method: RequestMethod\n payload: unknown\n}\n\nexport type RequestMethod =\n | 'network.fetch'\n | 'network.fetch-stream'\n | 'settings.getAll'\n | 'settings.get'\n | 'settings.set'\n | 'user.getProfile'\n | 'user.listIds'\n | 'events.emit'\n | 'scheduler.schedule'\n | 'scheduler.cancel'\n | 'scheduler.reportFireResult'\n | 'chat.appendInstruction'\n | 'database.execute'\n // Simple key-value storage methods\n | 'storage.set'\n | 'storage.keys'\n | 'storage.setForUser'\n | 'storage.keysForUser'\n // Collection-based storage methods\n | 'storage.put'\n | 'storage.get'\n | 'storage.delete'\n | 'storage.find'\n | 'storage.findOne'\n | 'storage.count'\n | 'storage.putMany'\n | 'storage.deleteMany'\n | 'storage.dropCollection'\n | 'storage.listCollections'\n | 'storage.putForUser'\n | 'storage.getForUser'\n | 'storage.deleteForUser'\n | 'storage.findForUser'\n | 'storage.findOneForUser'\n | 'storage.countForUser'\n | 'storage.putManyForUser'\n | 'storage.deleteManyForUser'\n | 'storage.dropCollectionForUser'\n | 'storage.listCollectionsForUser'\n // Secrets methods\n | 'secrets.set'\n | 'secrets.get'\n | 'secrets.delete'\n | 'secrets.list'\n | 'secrets.setForUser'\n | 'secrets.getForUser'\n | 'secrets.deleteForUser'\n | 'secrets.listForUser'\n // Tools cross-extension methods\n | 'tools.list'\n | 'tools.execute'\n\nexport interface ProviderRegisteredMessage {\n type: 'provider-registered'\n payload: {\n id: string\n name: string\n }\n}\n\nexport interface ToolRegisteredMessage {\n type: 'tool-registered'\n payload: {\n id: string\n name: string\n description: string\n parameters?: Record<string, unknown>\n }\n}\n\nexport interface ActionRegisteredMessage {\n type: 'action-registered'\n payload: {\n id: string\n }\n}\n\nexport interface StreamEventMessage {\n type: 'stream-event'\n payload: {\n requestId: string\n event: StreamEvent\n }\n}\n\nexport interface ProviderModelsResponseMessage {\n type: 'provider-models-response'\n payload: {\n requestId: string\n models: ModelInfo[]\n error?: string\n }\n}\n\nexport interface ToolExecuteResponseMessage {\n type: 'tool-execute-response'\n payload: {\n requestId: string\n result: ToolResult\n error?: string\n }\n}\n\nexport interface ActionExecuteResponseMessage {\n type: 'action-execute-response'\n payload: {\n requestId: string\n result: ActionResult\n error?: string\n }\n}\n\nexport interface LogMessage {\n type: 'log'\n payload: {\n level: 'debug' | 'info' | 'warn' | 'error'\n message: string\n data?: Record<string, unknown>\n }\n}\n\n/**\n * Message sent from worker to host when a background task is registered.\n */\nexport interface BackgroundTaskRegisteredMessage {\n type: 'background-task-registered'\n payload: {\n taskId: string\n name: string\n userId: string\n restartPolicy: {\n type: 'always' | 'on-failure' | 'never'\n maxRestarts?: number\n initialDelayMs?: number\n maxDelayMs?: number\n backoffMultiplier?: number\n }\n payload?: Record<string, unknown>\n }\n}\n\n/**\n * Message sent from worker to host with background task status updates.\n */\nexport interface BackgroundTaskStatusMessage {\n type: 'background-task-status'\n payload: {\n taskId: string\n status: 'running' | 'stopped' | 'failed'\n error?: string\n }\n}\n\n/**\n * Message sent from worker to host with background task health reports.\n */\nexport interface BackgroundTaskHealthMessage {\n type: 'background-task-health'\n payload: {\n taskId: string\n status: string\n timestamp: string\n }\n}\n\n// ============================================================================\n// Utility Types\n// ============================================================================\n\nexport interface PendingRequest<T = unknown> {\n resolve: (value: T) => void\n reject: (error: Error) => void\n timeout: ReturnType<typeof setTimeout>\n}\n\n/**\n * Generate a unique message ID\n */\nexport function generateMessageId(): string {\n return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`\n}\n"],"mappings":";AAuXO,SAAS,oBAA4B;AAC1C,SAAO,GAAG,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC;AACjE;","names":[]}
|