@moxxy/sdk 0.1.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/agent.d.ts +39 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +2 -0
- package/dist/agent.js.map +1 -0
- package/dist/cache-strategy.d.ts +35 -0
- package/dist/cache-strategy.d.ts.map +1 -0
- package/dist/cache-strategy.js +2 -0
- package/dist/cache-strategy.js.map +1 -0
- package/dist/channel.d.ts +146 -0
- package/dist/channel.d.ts.map +1 -0
- package/dist/channel.js +2 -0
- package/dist/channel.js.map +1 -0
- package/dist/client-session.d.ts +83 -0
- package/dist/client-session.d.ts.map +1 -0
- package/dist/client-session.js +2 -0
- package/dist/client-session.js.map +1 -0
- package/dist/command.d.ts +90 -0
- package/dist/command.d.ts.map +1 -0
- package/dist/command.js +15 -0
- package/dist/command.js.map +1 -0
- package/dist/compactor-helpers.d.ts +34 -0
- package/dist/compactor-helpers.d.ts.map +1 -0
- package/dist/compactor-helpers.js +156 -0
- package/dist/compactor-helpers.js.map +1 -0
- package/dist/compactor.d.ts +20 -0
- package/dist/compactor.d.ts.map +1 -0
- package/dist/compactor.js +2 -0
- package/dist/compactor.js.map +1 -0
- package/dist/define.d.ts +51 -0
- package/dist/define.d.ts.map +1 -0
- package/dist/define.js +71 -0
- package/dist/define.js.map +1 -0
- package/dist/elision-helpers.d.ts +27 -0
- package/dist/elision-helpers.d.ts.map +1 -0
- package/dist/elision-helpers.js +109 -0
- package/dist/elision-helpers.js.map +1 -0
- package/dist/elision-state.d.ts +49 -0
- package/dist/elision-state.d.ts.map +1 -0
- package/dist/elision-state.js +144 -0
- package/dist/elision-state.js.map +1 -0
- package/dist/embedding-cache.d.ts +32 -0
- package/dist/embedding-cache.d.ts.map +1 -0
- package/dist/embedding-cache.js +0 -0
- package/dist/embedding-cache.js.map +1 -0
- package/dist/embedding.d.ts +21 -0
- package/dist/embedding.d.ts.map +1 -0
- package/dist/embedding.js +2 -0
- package/dist/embedding.js.map +1 -0
- package/dist/errors.d.ts +81 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +241 -0
- package/dist/errors.js.map +1 -0
- package/dist/events.d.ts +193 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +2 -0
- package/dist/events.js.map +1 -0
- package/dist/hooks.d.ts +52 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +2 -0
- package/dist/hooks.js.map +1 -0
- package/dist/ids.d.ts +18 -0
- package/dist/ids.d.ts.map +1 -0
- package/dist/ids.js +7 -0
- package/dist/ids.js.map +1 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/install-hints.d.ts +26 -0
- package/dist/install-hints.d.ts.map +1 -0
- package/dist/install-hints.js +15 -0
- package/dist/install-hints.js.map +1 -0
- package/dist/isolation.d.ts +125 -0
- package/dist/isolation.d.ts.map +1 -0
- package/dist/isolation.js +11 -0
- package/dist/isolation.js.map +1 -0
- package/dist/log.d.ts +11 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +2 -0
- package/dist/log.js.map +1 -0
- package/dist/mode-helpers.d.ts +99 -0
- package/dist/mode-helpers.d.ts.map +1 -0
- package/dist/mode-helpers.js +368 -0
- package/dist/mode-helpers.js.map +1 -0
- package/dist/mode.d.ts +133 -0
- package/dist/mode.d.ts.map +1 -0
- package/dist/mode.js +2 -0
- package/dist/mode.js.map +1 -0
- package/dist/permission.d.ts +35 -0
- package/dist/permission.d.ts.map +1 -0
- package/dist/permission.js +2 -0
- package/dist/permission.js.map +1 -0
- package/dist/plugin.d.ts +88 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +2 -0
- package/dist/plugin.js.map +1 -0
- package/dist/provider-utils.d.ts +40 -0
- package/dist/provider-utils.d.ts.map +1 -0
- package/dist/provider-utils.js +163 -0
- package/dist/provider-utils.js.map +1 -0
- package/dist/provider.d.ts +219 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +2 -0
- package/dist/provider.js.map +1 -0
- package/dist/requirements.d.ts +22 -0
- package/dist/requirements.d.ts.map +1 -0
- package/dist/requirements.js +2 -0
- package/dist/requirements.js.map +1 -0
- package/dist/schemas.d.ts +228 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +88 -0
- package/dist/schemas.js.map +1 -0
- package/dist/session-like.d.ts +111 -0
- package/dist/session-like.d.ts.map +1 -0
- package/dist/session-like.js +2 -0
- package/dist/session-like.js.map +1 -0
- package/dist/skill.d.ts +30 -0
- package/dist/skill.d.ts.map +1 -0
- package/dist/skill.js +2 -0
- package/dist/skill.js.map +1 -0
- package/dist/subagent.d.ts +45 -0
- package/dist/subagent.d.ts.map +1 -0
- package/dist/subagent.js +11 -0
- package/dist/subagent.js.map +1 -0
- package/dist/token-accounting.d.ts +73 -0
- package/dist/token-accounting.d.ts.map +1 -0
- package/dist/token-accounting.js +129 -0
- package/dist/token-accounting.js.map +1 -0
- package/dist/tool-dispatch.d.ts +19 -0
- package/dist/tool-dispatch.d.ts.map +1 -0
- package/dist/tool-dispatch.js +118 -0
- package/dist/tool-dispatch.js.map +1 -0
- package/dist/tool-gating.d.ts +32 -0
- package/dist/tool-gating.d.ts.map +1 -0
- package/dist/tool-gating.js +83 -0
- package/dist/tool-gating.js.map +1 -0
- package/dist/tool.d.ts +166 -0
- package/dist/tool.d.ts.map +1 -0
- package/dist/tool.js +2 -0
- package/dist/tool.js.map +1 -0
- package/dist/transcriber.d.ts +64 -0
- package/dist/transcriber.d.ts.map +1 -0
- package/dist/transcriber.js +21 -0
- package/dist/transcriber.js.map +1 -0
- package/dist/tunnel.d.ts +25 -0
- package/dist/tunnel.d.ts.map +1 -0
- package/dist/tunnel.js +2 -0
- package/dist/tunnel.js.map +1 -0
- package/dist/type-contracts.d.ts +2 -0
- package/dist/type-contracts.d.ts.map +1 -0
- package/dist/type-contracts.js +4 -0
- package/dist/type-contracts.js.map +1 -0
- package/dist/types.test-d.d.ts +2 -0
- package/dist/types.test-d.d.ts.map +1 -0
- package/dist/types.test-d.js +22 -0
- package/dist/types.test-d.js.map +1 -0
- package/dist/view-renderer.d.ts +97 -0
- package/dist/view-renderer.d.ts.map +1 -0
- package/dist/view-renderer.js +72 -0
- package/dist/view-renderer.js.map +1 -0
- package/package.json +38 -0
- package/src/agent.ts +38 -0
- package/src/cache-strategy.ts +39 -0
- package/src/channel.ts +158 -0
- package/src/client-session.ts +88 -0
- package/src/command.ts +86 -0
- package/src/compactor-helpers.test.ts +206 -0
- package/src/compactor-helpers.ts +163 -0
- package/src/compactor.ts +20 -0
- package/src/define.test.ts +76 -0
- package/src/define.ts +113 -0
- package/src/elision-helpers.ts +143 -0
- package/src/elision-state.ts +170 -0
- package/src/embedding-cache.ts +0 -0
- package/src/embedding.ts +22 -0
- package/src/errors.test.ts +176 -0
- package/src/errors.ts +308 -0
- package/src/events.ts +250 -0
- package/src/hooks.ts +54 -0
- package/src/ids.ts +16 -0
- package/src/index.ts +304 -0
- package/src/install-hints.ts +43 -0
- package/src/isolation.ts +148 -0
- package/src/log.ts +11 -0
- package/src/loop-helpers.test.ts +78 -0
- package/src/mode-helpers.ts +483 -0
- package/src/mode.ts +139 -0
- package/src/package-root.test.ts +40 -0
- package/src/permission.ts +37 -0
- package/src/plugin.ts +92 -0
- package/src/provider-utils.test.ts +84 -0
- package/src/provider-utils.ts +171 -0
- package/src/provider.ts +195 -0
- package/src/requirements.ts +35 -0
- package/src/schemas.test.ts +106 -0
- package/src/schemas.ts +97 -0
- package/src/session-like.ts +118 -0
- package/src/skill.ts +34 -0
- package/src/subagent.ts +46 -0
- package/src/token-accounting.test.ts +93 -0
- package/src/token-accounting.ts +202 -0
- package/src/token-efficiency.test.ts +459 -0
- package/src/tool-dispatch.ts +137 -0
- package/src/tool-gating.ts +107 -0
- package/src/tool.ts +175 -0
- package/src/transcriber.ts +71 -0
- package/src/tunnel.ts +26 -0
- package/src/type-contracts.ts +4 -0
- package/src/types.test-d.ts +29 -0
- package/src/view-renderer.test.ts +90 -0
- package/src/view-renderer.ts +156 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transcribers convert audio bytes into text. They are a separate capability
|
|
3
|
+
* from `LLMProvider` because (a) most providers (Anthropic today) do not yet
|
|
4
|
+
* accept native audio, (b) users frequently want to pair a text provider with
|
|
5
|
+
* a dedicated STT backend (Whisper, Deepgram, AssemblyAI, local whisper.cpp),
|
|
6
|
+
* and (c) the same transcript may be used in many places — channels feeding
|
|
7
|
+
* voice notes into a turn, skills processing recorded meetings, etc.
|
|
8
|
+
*
|
|
9
|
+
* Plugins register a `TranscriberDef` via `PluginSpec.transcribers`. The
|
|
10
|
+
* core `TranscriberRegistry` holds them; channels call
|
|
11
|
+
* `session.transcribers.getActive()` (or `.get(name)`) to use one.
|
|
12
|
+
*
|
|
13
|
+
* Audio input is represented in two places once a `Transcriber` is wired:
|
|
14
|
+
* - `UserPromptAttachment` with `kind: 'audio'` — channel-level handoff,
|
|
15
|
+
* consumed by the channel and either transcribed or sent through as a
|
|
16
|
+
* native audio block (provider-permitting).
|
|
17
|
+
* - `ContentBlock` with `type: 'audio'` — provider-level wire format, only
|
|
18
|
+
* used by models that advertise `supportsAudio: true`.
|
|
19
|
+
*/
|
|
20
|
+
export interface TranscriptionSegment {
|
|
21
|
+
/** Segment start, in seconds from the start of the clip. */
|
|
22
|
+
readonly start: number;
|
|
23
|
+
/** Segment end, in seconds. */
|
|
24
|
+
readonly end: number;
|
|
25
|
+
readonly text: string;
|
|
26
|
+
/** Optional speaker label when the backend supports diarization. */
|
|
27
|
+
readonly speaker?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface TranscriptionResult {
|
|
30
|
+
/** Full concatenated transcript. */
|
|
31
|
+
readonly text: string;
|
|
32
|
+
/** BCP-47 language tag when the backend reports one (e.g. `en`, `pl`). */
|
|
33
|
+
readonly language?: string;
|
|
34
|
+
/** Clip length in seconds when known. */
|
|
35
|
+
readonly durationSec?: number;
|
|
36
|
+
/** Optional per-segment breakdown for richer downstream use. */
|
|
37
|
+
readonly segments?: ReadonlyArray<TranscriptionSegment>;
|
|
38
|
+
}
|
|
39
|
+
export interface TranscribeOptions {
|
|
40
|
+
/** MIME type of the audio bytes (e.g. `audio/ogg`, `audio/webm`). */
|
|
41
|
+
readonly mimeType?: string;
|
|
42
|
+
/** Hint the recognizer with a BCP-47 language tag. */
|
|
43
|
+
readonly language?: string;
|
|
44
|
+
/** Vocabulary / context hint passed to backends that support it (Whisper). */
|
|
45
|
+
readonly prompt?: string;
|
|
46
|
+
/** Cancellation signal — channels propagate the turn's abort here. */
|
|
47
|
+
readonly signal?: AbortSignal;
|
|
48
|
+
}
|
|
49
|
+
export interface Transcriber {
|
|
50
|
+
/** Short stable name, e.g. `openai-whisper-1`. */
|
|
51
|
+
readonly name: string;
|
|
52
|
+
transcribe(audio: Uint8Array | ArrayBuffer, opts?: TranscribeOptions): Promise<TranscriptionResult>;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Plugin-side definition. Mirrors `ProviderDef`: a `createClient(config)`
|
|
56
|
+
* factory the registry calls when the user activates this transcriber.
|
|
57
|
+
*/
|
|
58
|
+
export interface TranscriberDef {
|
|
59
|
+
readonly name: string;
|
|
60
|
+
/** Optional human-readable label for UI surfaces. */
|
|
61
|
+
readonly displayName?: string;
|
|
62
|
+
createClient(config: Record<string, unknown>): Transcriber;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=transcriber.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcriber.d.ts","sourceRoot":"","sources":["../src/transcriber.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,WAAW,oBAAoB;IACnC,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,+BAA+B;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,0EAA0E;IAC1E,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,yCAAyC;IACzC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,iBAAiB;IAChC,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,sDAAsD;IACtD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,8EAA8E;IAC9E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,sEAAsE;IACtE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,kDAAkD;IAClD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,UAAU,CACR,KAAK,EAAE,UAAU,GAAG,WAAW,EAC/B,IAAI,CAAC,EAAE,iBAAiB,GACvB,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACjC;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,WAAW,CAAC;CAC5D"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transcribers convert audio bytes into text. They are a separate capability
|
|
3
|
+
* from `LLMProvider` because (a) most providers (Anthropic today) do not yet
|
|
4
|
+
* accept native audio, (b) users frequently want to pair a text provider with
|
|
5
|
+
* a dedicated STT backend (Whisper, Deepgram, AssemblyAI, local whisper.cpp),
|
|
6
|
+
* and (c) the same transcript may be used in many places — channels feeding
|
|
7
|
+
* voice notes into a turn, skills processing recorded meetings, etc.
|
|
8
|
+
*
|
|
9
|
+
* Plugins register a `TranscriberDef` via `PluginSpec.transcribers`. The
|
|
10
|
+
* core `TranscriberRegistry` holds them; channels call
|
|
11
|
+
* `session.transcribers.getActive()` (or `.get(name)`) to use one.
|
|
12
|
+
*
|
|
13
|
+
* Audio input is represented in two places once a `Transcriber` is wired:
|
|
14
|
+
* - `UserPromptAttachment` with `kind: 'audio'` — channel-level handoff,
|
|
15
|
+
* consumed by the channel and either transcribed or sent through as a
|
|
16
|
+
* native audio block (provider-permitting).
|
|
17
|
+
* - `ContentBlock` with `type: 'audio'` — provider-level wire format, only
|
|
18
|
+
* used by models that advertise `supportsAudio: true`.
|
|
19
|
+
*/
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=transcriber.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcriber.js","sourceRoot":"","sources":["../src/transcriber.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG"}
|
package/dist/tunnel.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A swappable way to expose a locally-bound surface (the web channel) to the
|
|
3
|
+
* user over the public internet — so an agent on Telegram/TUI can hand the user
|
|
4
|
+
* a URL they can open. One provider is active per session (registered via
|
|
5
|
+
* plugins, like every other block); core seeds a `localhost` no-op provider so
|
|
6
|
+
* `getActive()` is non-null.
|
|
7
|
+
*/
|
|
8
|
+
export interface TunnelOpenOptions {
|
|
9
|
+
readonly port: number;
|
|
10
|
+
readonly host: string;
|
|
11
|
+
}
|
|
12
|
+
export interface TunnelHandle {
|
|
13
|
+
/** The publicly reachable base URL (e.g. https://abc.trycloudflare.com). */
|
|
14
|
+
readonly url: string;
|
|
15
|
+
/** Tear the tunnel down (kill the subprocess, close the connection). */
|
|
16
|
+
close(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
export interface TunnelProviderDef {
|
|
19
|
+
readonly name: string;
|
|
20
|
+
/** Open a tunnel to `http://host:port`, resolving once the public URL is known. */
|
|
21
|
+
open(opts: TunnelOpenOptions): Promise<TunnelHandle>;
|
|
22
|
+
/** Optional readiness gate (e.g. the `cloudflared` binary is installed). */
|
|
23
|
+
isAvailable?(): Promise<boolean>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=tunnel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel.d.ts","sourceRoot":"","sources":["../src/tunnel.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,4EAA4E;IAC5E,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,mFAAmF;IACnF,IAAI,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IACrD,4EAA4E;IAC5E,WAAW,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAClC"}
|
package/dist/tunnel.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel.js","sourceRoot":"","sources":["../src/tunnel.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-contracts.d.ts","sourceRoot":"","sources":["../src/type-contracts.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-contracts.js","sourceRoot":"","sources":["../src/type-contracts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,+FAA+F;AAC/F,YAAY,CAAC,EAAE,IAAI,EAAE,0BAA0B,EAAE,SAAS,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.test-d.d.ts","sourceRoot":"","sources":["../src/types.test-d.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { describe, expectTypeOf, it } from 'vitest';
|
|
2
|
+
describe('event union narrowing', () => {
|
|
3
|
+
it('MoxxyEventOfType narrows correctly', () => {
|
|
4
|
+
expectTypeOf().toEqualTypeOf();
|
|
5
|
+
expectTypeOf().toEqualTypeOf();
|
|
6
|
+
});
|
|
7
|
+
it('switch on type narrows the union', () => {
|
|
8
|
+
const handle = (e) => {
|
|
9
|
+
if (e.type === 'user_prompt') {
|
|
10
|
+
expectTypeOf(e).toEqualTypeOf();
|
|
11
|
+
return e.text;
|
|
12
|
+
}
|
|
13
|
+
if (e.type === 'tool_call_requested') {
|
|
14
|
+
expectTypeOf(e).toEqualTypeOf();
|
|
15
|
+
return e.name;
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
};
|
|
19
|
+
expectTypeOf(handle).returns.toEqualTypeOf();
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
//# sourceMappingURL=types.test-d.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.test-d.js","sourceRoot":"","sources":["../src/types.test-d.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAQpD,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,YAAY,EAAmC,CAAC,aAAa,EAAmB,CAAC;QACjF,YAAY,EAA2C,CAAC,aAAa,EAA0B,CAAC;IAClG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,MAAM,GAAG,CAAC,CAAa,EAAE,EAAE;YAC/B,IAAI,CAAC,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;gBAC7B,YAAY,CAAC,CAAC,CAAC,CAAC,aAAa,EAAmB,CAAC;gBACjD,OAAO,CAAC,CAAC,IAAI,CAAC;YAChB,CAAC;YACD,IAAI,CAAC,CAAC,IAAI,KAAK,qBAAqB,EAAE,CAAC;gBACrC,YAAY,CAAC,CAAC,CAAC,CAAC,aAAa,EAA0B,CAAC;gBACxD,OAAO,CAAC,CAAC,IAAI,CAAC;YAChB,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QACF,YAAY,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,aAAa,EAAiB,CAAC;IAC9D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent-authored UI view-spec — the contract shared by the parser (core) and
|
|
3
|
+
* the renderer (web channel frontend).
|
|
4
|
+
*
|
|
5
|
+
* An agent emits a small JSX/XML-like document; a {@link ViewRendererDef} parses
|
|
6
|
+
* it into a validated {@link ViewDoc} AST against a strict tag/attribute
|
|
7
|
+
* **allow-list** (no raw HTML / script passthrough). One renderer is active per
|
|
8
|
+
* session, registered via plugins exactly like compactors / cache-strategies.
|
|
9
|
+
*
|
|
10
|
+
* The tag vocabulary ({@link VIEW_PRIMITIVES} / {@link VIEW_COMPONENTS}) is plain
|
|
11
|
+
* data so the browser frontend can import the SAME allow-list the parser
|
|
12
|
+
* validates against — preventing the two-list drift that would open an XSS gap.
|
|
13
|
+
*/
|
|
14
|
+
/** A node in the validated view AST. After parsing, only primitives remain. */
|
|
15
|
+
export type ViewNode = {
|
|
16
|
+
readonly kind: 'element';
|
|
17
|
+
readonly tag: string;
|
|
18
|
+
readonly props: Readonly<Record<string, string | number | boolean>>;
|
|
19
|
+
readonly children: ReadonlyArray<ViewNode>;
|
|
20
|
+
/** Present on interactive elements (`form`, `button`) — drives an agent turn. */
|
|
21
|
+
readonly action?: ViewAction;
|
|
22
|
+
/**
|
|
23
|
+
* Client-side navigation target (a `view` `name`). Set from a `to` attr on
|
|
24
|
+
* `link`/`button`. The frontend switches to the named cached view WITHOUT an
|
|
25
|
+
* agent turn; if it isn't cached yet it falls back to a `navigate:<name>` turn.
|
|
26
|
+
*/
|
|
27
|
+
readonly nav?: string;
|
|
28
|
+
} | {
|
|
29
|
+
readonly kind: 'text';
|
|
30
|
+
readonly value: string;
|
|
31
|
+
};
|
|
32
|
+
/** Declared on an interactive element; the transport turns it into a turn. */
|
|
33
|
+
export interface ViewAction {
|
|
34
|
+
/** Opaque name the agent chose, e.g. `search_flights`, `select:UA42`. */
|
|
35
|
+
readonly name: string;
|
|
36
|
+
/** Input `name`s whose current values this action carries back. */
|
|
37
|
+
readonly fields: ReadonlyArray<string>;
|
|
38
|
+
}
|
|
39
|
+
export interface ViewDoc {
|
|
40
|
+
readonly root: ViewNode;
|
|
41
|
+
readonly title?: string;
|
|
42
|
+
}
|
|
43
|
+
export interface ViewParseError {
|
|
44
|
+
readonly message: string;
|
|
45
|
+
readonly line?: number;
|
|
46
|
+
readonly col?: number;
|
|
47
|
+
}
|
|
48
|
+
export type ViewParseResult = {
|
|
49
|
+
readonly ok: true;
|
|
50
|
+
readonly doc: ViewDoc;
|
|
51
|
+
} | {
|
|
52
|
+
readonly ok: false;
|
|
53
|
+
readonly errors: ReadonlyArray<ViewParseError>;
|
|
54
|
+
};
|
|
55
|
+
export type AttrType = 'string' | 'number' | 'boolean' | 'enum';
|
|
56
|
+
export interface AttrSpec {
|
|
57
|
+
readonly type: AttrType;
|
|
58
|
+
readonly required?: boolean;
|
|
59
|
+
/** Allowed values when `type === 'enum'`. */
|
|
60
|
+
readonly values?: ReadonlyArray<string>;
|
|
61
|
+
/** Inclusive bounds when `type === 'number'`. */
|
|
62
|
+
readonly min?: number;
|
|
63
|
+
readonly max?: number;
|
|
64
|
+
}
|
|
65
|
+
export interface ViewTagSpec {
|
|
66
|
+
readonly tag: string;
|
|
67
|
+
readonly attrs: Readonly<Record<string, AttrSpec>>;
|
|
68
|
+
/** Allowed child tags; `'any'` = any element + text, `'none'` = void. */
|
|
69
|
+
readonly allowedChildren: ReadonlyArray<string> | 'any' | 'none';
|
|
70
|
+
/** Carries a {@link ViewAction} (the parser synthesizes `node.action`). */
|
|
71
|
+
readonly interactive?: boolean;
|
|
72
|
+
/** A rich component the renderer expands into primitives at parse time. */
|
|
73
|
+
readonly component?: boolean;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* A swappable view-spec renderer. `parse` turns source into a validated AST
|
|
77
|
+
* (rich components already expanded to primitives); `validate` re-checks an
|
|
78
|
+
* already-built AST against {@link allowList} — note it runs on EXPANDED
|
|
79
|
+
* primitives, a contract replacement renderers must preserve.
|
|
80
|
+
*/
|
|
81
|
+
export interface ViewRendererDef {
|
|
82
|
+
readonly name: string;
|
|
83
|
+
readonly allowList: ReadonlyArray<ViewTagSpec>;
|
|
84
|
+
parse(source: string): ViewParseResult;
|
|
85
|
+
validate(doc: ViewDoc): ReadonlyArray<ViewParseError>;
|
|
86
|
+
}
|
|
87
|
+
/** Primitives — the frontend renders these directly (keymap === these tags). */
|
|
88
|
+
export declare const VIEW_PRIMITIVES: ReadonlyArray<ViewTagSpec>;
|
|
89
|
+
/**
|
|
90
|
+
* Rich components — accepted by the parser, expanded to primitives, never reach the
|
|
91
|
+
* frontend. Generic + domain-agnostic: a `results` list of selectable `result`s is
|
|
92
|
+
* the backbone of any "search engine / platform for X" the agent builds.
|
|
93
|
+
*/
|
|
94
|
+
export declare const VIEW_COMPONENTS: ReadonlyArray<ViewTagSpec>;
|
|
95
|
+
/** The default renderer's full allow-list (primitives + components). */
|
|
96
|
+
export declare const DEFAULT_VIEW_TAGS: ReadonlyArray<ViewTagSpec>;
|
|
97
|
+
//# sourceMappingURL=view-renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view-renderer.d.ts","sourceRoot":"","sources":["../src/view-renderer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent-authored UI view-spec — the contract shared by the parser (core) and
|
|
3
|
+
* the renderer (web channel frontend).
|
|
4
|
+
*
|
|
5
|
+
* An agent emits a small JSX/XML-like document; a {@link ViewRendererDef} parses
|
|
6
|
+
* it into a validated {@link ViewDoc} AST against a strict tag/attribute
|
|
7
|
+
* **allow-list** (no raw HTML / script passthrough). One renderer is active per
|
|
8
|
+
* session, registered via plugins exactly like compactors / cache-strategies.
|
|
9
|
+
*
|
|
10
|
+
* The tag vocabulary ({@link VIEW_PRIMITIVES} / {@link VIEW_COMPONENTS}) is plain
|
|
11
|
+
* data so the browser frontend can import the SAME allow-list the parser
|
|
12
|
+
* validates against — preventing the two-list drift that would open an XSS gap.
|
|
13
|
+
*/
|
|
14
|
+
const TONE = ['default', 'muted', 'success', 'warn', 'danger'];
|
|
15
|
+
const GAP = ['none', 'sm', 'md', 'lg'];
|
|
16
|
+
/** Primitives — the frontend renders these directly (keymap === these tags). */
|
|
17
|
+
export const VIEW_PRIMITIVES = [
|
|
18
|
+
// layout / containers
|
|
19
|
+
{ tag: 'view', attrs: { title: { type: 'string' }, name: { type: 'string' } }, allowedChildren: 'any' },
|
|
20
|
+
{ tag: 'stack', attrs: { gap: { type: 'enum', values: GAP }, align: { type: 'enum', values: ['start', 'center', 'end', 'stretch'] } }, allowedChildren: 'any' },
|
|
21
|
+
{ tag: 'row', attrs: { gap: { type: 'enum', values: GAP }, align: { type: 'enum', values: ['start', 'center', 'end', 'stretch'] }, justify: { type: 'enum', values: ['start', 'center', 'end', 'between'] } }, allowedChildren: 'any' },
|
|
22
|
+
{ tag: 'grid', attrs: { cols: { type: 'number', required: true, min: 1, max: 6 }, gap: { type: 'enum', values: GAP } }, allowedChildren: 'any' },
|
|
23
|
+
{ tag: 'card', attrs: { title: { type: 'string' }, accent: { type: 'enum', values: TONE } }, allowedChildren: 'any' },
|
|
24
|
+
{ tag: 'divider', attrs: {}, allowedChildren: 'none' },
|
|
25
|
+
// loading states (show while fetching real data, then replace with results)
|
|
26
|
+
{ tag: 'spinner', attrs: { label: { type: 'string' } }, allowedChildren: 'none' },
|
|
27
|
+
{ tag: 'skeleton', attrs: { rows: { type: 'number', min: 1, max: 12 } }, allowedChildren: 'none' },
|
|
28
|
+
// display
|
|
29
|
+
{ tag: 'heading', attrs: { level: { type: 'number', min: 1, max: 3 } }, allowedChildren: 'any' },
|
|
30
|
+
{ tag: 'text', attrs: { tone: { type: 'enum', values: TONE }, weight: { type: 'enum', values: ['normal', 'bold'] } }, allowedChildren: 'any' },
|
|
31
|
+
{ tag: 'badge', attrs: { tone: { type: 'enum', values: TONE } }, allowedChildren: 'any' },
|
|
32
|
+
{ tag: 'image', attrs: { src: { type: 'string', required: true }, alt: { type: 'string' }, w: { type: 'number' }, h: { type: 'number' } }, allowedChildren: 'none' },
|
|
33
|
+
{ tag: 'link', attrs: { href: { type: 'string' }, to: { type: 'string' } }, allowedChildren: 'any' },
|
|
34
|
+
{ tag: 'list', attrs: { ordered: { type: 'boolean' } }, allowedChildren: ['item'] },
|
|
35
|
+
{ tag: 'item', attrs: {}, allowedChildren: 'any' },
|
|
36
|
+
{ tag: 'table', attrs: {}, allowedChildren: ['tr'] },
|
|
37
|
+
{ tag: 'tr', attrs: {}, allowedChildren: ['th', 'td'] },
|
|
38
|
+
{ tag: 'th', attrs: { align: { type: 'enum', values: ['left', 'center', 'right'] } }, allowedChildren: 'any' },
|
|
39
|
+
{ tag: 'td', attrs: { align: { type: 'enum', values: ['left', 'center', 'right'] } }, allowedChildren: 'any' },
|
|
40
|
+
// inputs (only meaningful inside `form`)
|
|
41
|
+
{ tag: 'form', attrs: { action: { type: 'string', required: true }, submit: { type: 'string' } }, allowedChildren: 'any', interactive: true },
|
|
42
|
+
{ tag: 'input', attrs: { name: { type: 'string', required: true }, type: { type: 'enum', values: ['text', 'number', 'date', 'email'] }, label: { type: 'string' }, placeholder: { type: 'string' }, value: { type: 'string' }, required: { type: 'boolean' } }, allowedChildren: 'none' },
|
|
43
|
+
{ tag: 'select', attrs: { name: { type: 'string', required: true }, label: { type: 'string' }, value: { type: 'string' }, required: { type: 'boolean' } }, allowedChildren: ['option'] },
|
|
44
|
+
{ tag: 'option', attrs: { value: { type: 'string', required: true }, selected: { type: 'boolean' } }, allowedChildren: 'any' },
|
|
45
|
+
{ tag: 'checkbox', attrs: { name: { type: 'string', required: true }, label: { type: 'string' }, checked: { type: 'boolean' } }, allowedChildren: 'none' },
|
|
46
|
+
// `action` drives an agent turn; `to` navigates client-side to a named view.
|
|
47
|
+
{ tag: 'button', attrs: { action: { type: 'string' }, to: { type: 'string' }, label: { type: 'string', required: true }, variant: { type: 'enum', values: ['primary', 'secondary', 'danger'] }, fields: { type: 'string' } }, allowedChildren: 'none', interactive: true },
|
|
48
|
+
];
|
|
49
|
+
/**
|
|
50
|
+
* Rich components — accepted by the parser, expanded to primitives, never reach the
|
|
51
|
+
* frontend. Generic + domain-agnostic: a `results` list of selectable `result`s is
|
|
52
|
+
* the backbone of any "search engine / platform for X" the agent builds.
|
|
53
|
+
*/
|
|
54
|
+
export const VIEW_COMPONENTS = [
|
|
55
|
+
{ tag: 'results', attrs: {}, allowedChildren: ['result'], component: true },
|
|
56
|
+
{
|
|
57
|
+
tag: 'result',
|
|
58
|
+
attrs: {
|
|
59
|
+
title: { type: 'string', required: true },
|
|
60
|
+
subtitle: { type: 'string' },
|
|
61
|
+
badge: { type: 'string' },
|
|
62
|
+
id: { type: 'string' },
|
|
63
|
+
action: { type: 'string' }, // agent turn on select (default: open:<id>)
|
|
64
|
+
to: { type: 'string' }, // or client-side nav to a named view
|
|
65
|
+
},
|
|
66
|
+
allowedChildren: 'none',
|
|
67
|
+
component: true,
|
|
68
|
+
},
|
|
69
|
+
];
|
|
70
|
+
/** The default renderer's full allow-list (primitives + components). */
|
|
71
|
+
export const DEFAULT_VIEW_TAGS = [...VIEW_PRIMITIVES, ...VIEW_COMPONENTS];
|
|
72
|
+
//# sourceMappingURL=view-renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view-renderer.js","sourceRoot":"","sources":["../src/view-renderer.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@moxxy/sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Typed public surface for the moxxy framework: event types, define* factories, lifecycle hook signatures.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"src"
|
|
17
|
+
],
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"zod": "^3.24.0"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"typescript": "^5.7.3",
|
|
26
|
+
"vitest": "^2.1.8",
|
|
27
|
+
"zod": "^3.24.0",
|
|
28
|
+
"@moxxy/tsconfig": "0.0.0",
|
|
29
|
+
"@moxxy/vitest-preset": "0.0.0"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsc -p tsconfig.json",
|
|
33
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
34
|
+
"test": "vitest run",
|
|
35
|
+
"test:watch": "vitest",
|
|
36
|
+
"clean": "rm -rf dist .turbo"
|
|
37
|
+
}
|
|
38
|
+
}
|
package/src/agent.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent definitions — typed templates for subagent spawning. Each
|
|
3
|
+
* `AgentDef` describes a flavor of subagent (researcher, code-reviewer,
|
|
4
|
+
* summarizer, …) so plugins can register named agent kinds and the
|
|
5
|
+
* `dispatch_agent` tool can spawn them by type instead of relying on
|
|
6
|
+
* ad-hoc prompts.
|
|
7
|
+
*
|
|
8
|
+
* Why this lives in SDK (not core): the interface is the cross-package
|
|
9
|
+
* contract. Plugins import `AgentDef` from `@moxxy/sdk`, register
|
|
10
|
+
* agents via `PluginSpec.agents`, and the core's `AgentRegistry`
|
|
11
|
+
* surfaces them at runtime.
|
|
12
|
+
*/
|
|
13
|
+
export interface AgentDef {
|
|
14
|
+
/** Stable name; what `dispatch_agent({ agentType })` looks up. */
|
|
15
|
+
readonly name: string;
|
|
16
|
+
/** One-line user-visible summary — surfaced in the `/agents` modal. */
|
|
17
|
+
readonly description: string;
|
|
18
|
+
/**
|
|
19
|
+
* System prompt prepended to the child's first message. Use to set
|
|
20
|
+
* persona, output format, hard constraints, etc.
|
|
21
|
+
*/
|
|
22
|
+
readonly systemPrompt?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Mode name for the child. Defaults to `'tool-use'`. The
|
|
25
|
+
* spawner falls back to tool-use if the named strategy isn't
|
|
26
|
+
* registered (no point failing a child over a missing block).
|
|
27
|
+
*/
|
|
28
|
+
readonly mode?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Restrict the child to these tools by name. Omit for full
|
|
31
|
+
* inheritance from the parent's registry.
|
|
32
|
+
*/
|
|
33
|
+
readonly allowedTools?: ReadonlyArray<string>;
|
|
34
|
+
/** Default model id; overrides the parent's active model. */
|
|
35
|
+
readonly model?: string;
|
|
36
|
+
/** Per-child iteration cap. Defaults to 50. */
|
|
37
|
+
readonly maxIterations?: number;
|
|
38
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { EventLogReader } from './log.js';
|
|
2
|
+
import type { CacheHint, ProviderMessage } from './provider.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Context handed to a CacheStrategy when it plans breakpoints for one call.
|
|
6
|
+
*/
|
|
7
|
+
export interface CacheStrategyContext {
|
|
8
|
+
readonly model: string;
|
|
9
|
+
/** Active model's context window, for strategies that scale behavior to it. */
|
|
10
|
+
readonly contextWindow: number;
|
|
11
|
+
readonly log: EventLogReader;
|
|
12
|
+
/**
|
|
13
|
+
* Index (into the `messages` array passed to `plan`) of the last message
|
|
14
|
+
* belonging to the stable, cacheable prefix — everything at or before it is
|
|
15
|
+
* byte-identical across the inner iterations of the current turn, so a
|
|
16
|
+
* rolling breakpoint placed here yields cache reads on every iteration.
|
|
17
|
+
* Undefined when the mode can't compute a boundary (e.g. no elision active);
|
|
18
|
+
* strategies should then fall back to a conservative breakpoint.
|
|
19
|
+
*/
|
|
20
|
+
readonly stablePrefixMessageIndex?: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* A swappable prompt-caching strategy. One is active per session (registered
|
|
25
|
+
* via plugins, exactly like compactors/modes). It decides *where* cache
|
|
26
|
+
* breakpoints go and returns provider-neutral {@link CacheHint}s; the provider
|
|
27
|
+
* is responsible for *how* to express them (Anthropic → `cache_control`).
|
|
28
|
+
*
|
|
29
|
+
* `plan` MUST be deterministic given identical inputs — a non-deterministic
|
|
30
|
+
* breakpoint placement shifts the cached prefix between calls and silently
|
|
31
|
+
* defeats the cache (paying 1.25x writes for 0 reads).
|
|
32
|
+
*/
|
|
33
|
+
export interface CacheStrategyDef {
|
|
34
|
+
readonly name: string;
|
|
35
|
+
plan(
|
|
36
|
+
messages: ReadonlyArray<ProviderMessage>,
|
|
37
|
+
ctx: CacheStrategyContext,
|
|
38
|
+
): ReadonlyArray<CacheHint>;
|
|
39
|
+
}
|