@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.
Files changed (211) hide show
  1. package/dist/agent.d.ts +39 -0
  2. package/dist/agent.d.ts.map +1 -0
  3. package/dist/agent.js +2 -0
  4. package/dist/agent.js.map +1 -0
  5. package/dist/cache-strategy.d.ts +35 -0
  6. package/dist/cache-strategy.d.ts.map +1 -0
  7. package/dist/cache-strategy.js +2 -0
  8. package/dist/cache-strategy.js.map +1 -0
  9. package/dist/channel.d.ts +146 -0
  10. package/dist/channel.d.ts.map +1 -0
  11. package/dist/channel.js +2 -0
  12. package/dist/channel.js.map +1 -0
  13. package/dist/client-session.d.ts +83 -0
  14. package/dist/client-session.d.ts.map +1 -0
  15. package/dist/client-session.js +2 -0
  16. package/dist/client-session.js.map +1 -0
  17. package/dist/command.d.ts +90 -0
  18. package/dist/command.d.ts.map +1 -0
  19. package/dist/command.js +15 -0
  20. package/dist/command.js.map +1 -0
  21. package/dist/compactor-helpers.d.ts +34 -0
  22. package/dist/compactor-helpers.d.ts.map +1 -0
  23. package/dist/compactor-helpers.js +156 -0
  24. package/dist/compactor-helpers.js.map +1 -0
  25. package/dist/compactor.d.ts +20 -0
  26. package/dist/compactor.d.ts.map +1 -0
  27. package/dist/compactor.js +2 -0
  28. package/dist/compactor.js.map +1 -0
  29. package/dist/define.d.ts +51 -0
  30. package/dist/define.d.ts.map +1 -0
  31. package/dist/define.js +71 -0
  32. package/dist/define.js.map +1 -0
  33. package/dist/elision-helpers.d.ts +27 -0
  34. package/dist/elision-helpers.d.ts.map +1 -0
  35. package/dist/elision-helpers.js +109 -0
  36. package/dist/elision-helpers.js.map +1 -0
  37. package/dist/elision-state.d.ts +49 -0
  38. package/dist/elision-state.d.ts.map +1 -0
  39. package/dist/elision-state.js +144 -0
  40. package/dist/elision-state.js.map +1 -0
  41. package/dist/embedding-cache.d.ts +32 -0
  42. package/dist/embedding-cache.d.ts.map +1 -0
  43. package/dist/embedding-cache.js +0 -0
  44. package/dist/embedding-cache.js.map +1 -0
  45. package/dist/embedding.d.ts +21 -0
  46. package/dist/embedding.d.ts.map +1 -0
  47. package/dist/embedding.js +2 -0
  48. package/dist/embedding.js.map +1 -0
  49. package/dist/errors.d.ts +81 -0
  50. package/dist/errors.d.ts.map +1 -0
  51. package/dist/errors.js +241 -0
  52. package/dist/errors.js.map +1 -0
  53. package/dist/events.d.ts +193 -0
  54. package/dist/events.d.ts.map +1 -0
  55. package/dist/events.js +2 -0
  56. package/dist/events.js.map +1 -0
  57. package/dist/hooks.d.ts +52 -0
  58. package/dist/hooks.d.ts.map +1 -0
  59. package/dist/hooks.js +2 -0
  60. package/dist/hooks.js.map +1 -0
  61. package/dist/ids.d.ts +18 -0
  62. package/dist/ids.d.ts.map +1 -0
  63. package/dist/ids.js +7 -0
  64. package/dist/ids.js.map +1 -0
  65. package/dist/index.d.ts +45 -0
  66. package/dist/index.d.ts.map +1 -0
  67. package/dist/index.js +18 -0
  68. package/dist/index.js.map +1 -0
  69. package/dist/install-hints.d.ts +26 -0
  70. package/dist/install-hints.d.ts.map +1 -0
  71. package/dist/install-hints.js +15 -0
  72. package/dist/install-hints.js.map +1 -0
  73. package/dist/isolation.d.ts +125 -0
  74. package/dist/isolation.d.ts.map +1 -0
  75. package/dist/isolation.js +11 -0
  76. package/dist/isolation.js.map +1 -0
  77. package/dist/log.d.ts +11 -0
  78. package/dist/log.d.ts.map +1 -0
  79. package/dist/log.js +2 -0
  80. package/dist/log.js.map +1 -0
  81. package/dist/mode-helpers.d.ts +99 -0
  82. package/dist/mode-helpers.d.ts.map +1 -0
  83. package/dist/mode-helpers.js +368 -0
  84. package/dist/mode-helpers.js.map +1 -0
  85. package/dist/mode.d.ts +133 -0
  86. package/dist/mode.d.ts.map +1 -0
  87. package/dist/mode.js +2 -0
  88. package/dist/mode.js.map +1 -0
  89. package/dist/permission.d.ts +35 -0
  90. package/dist/permission.d.ts.map +1 -0
  91. package/dist/permission.js +2 -0
  92. package/dist/permission.js.map +1 -0
  93. package/dist/plugin.d.ts +88 -0
  94. package/dist/plugin.d.ts.map +1 -0
  95. package/dist/plugin.js +2 -0
  96. package/dist/plugin.js.map +1 -0
  97. package/dist/provider-utils.d.ts +40 -0
  98. package/dist/provider-utils.d.ts.map +1 -0
  99. package/dist/provider-utils.js +163 -0
  100. package/dist/provider-utils.js.map +1 -0
  101. package/dist/provider.d.ts +219 -0
  102. package/dist/provider.d.ts.map +1 -0
  103. package/dist/provider.js +2 -0
  104. package/dist/provider.js.map +1 -0
  105. package/dist/requirements.d.ts +22 -0
  106. package/dist/requirements.d.ts.map +1 -0
  107. package/dist/requirements.js +2 -0
  108. package/dist/requirements.js.map +1 -0
  109. package/dist/schemas.d.ts +228 -0
  110. package/dist/schemas.d.ts.map +1 -0
  111. package/dist/schemas.js +88 -0
  112. package/dist/schemas.js.map +1 -0
  113. package/dist/session-like.d.ts +111 -0
  114. package/dist/session-like.d.ts.map +1 -0
  115. package/dist/session-like.js +2 -0
  116. package/dist/session-like.js.map +1 -0
  117. package/dist/skill.d.ts +30 -0
  118. package/dist/skill.d.ts.map +1 -0
  119. package/dist/skill.js +2 -0
  120. package/dist/skill.js.map +1 -0
  121. package/dist/subagent.d.ts +45 -0
  122. package/dist/subagent.d.ts.map +1 -0
  123. package/dist/subagent.js +11 -0
  124. package/dist/subagent.js.map +1 -0
  125. package/dist/token-accounting.d.ts +73 -0
  126. package/dist/token-accounting.d.ts.map +1 -0
  127. package/dist/token-accounting.js +129 -0
  128. package/dist/token-accounting.js.map +1 -0
  129. package/dist/tool-dispatch.d.ts +19 -0
  130. package/dist/tool-dispatch.d.ts.map +1 -0
  131. package/dist/tool-dispatch.js +118 -0
  132. package/dist/tool-dispatch.js.map +1 -0
  133. package/dist/tool-gating.d.ts +32 -0
  134. package/dist/tool-gating.d.ts.map +1 -0
  135. package/dist/tool-gating.js +83 -0
  136. package/dist/tool-gating.js.map +1 -0
  137. package/dist/tool.d.ts +166 -0
  138. package/dist/tool.d.ts.map +1 -0
  139. package/dist/tool.js +2 -0
  140. package/dist/tool.js.map +1 -0
  141. package/dist/transcriber.d.ts +64 -0
  142. package/dist/transcriber.d.ts.map +1 -0
  143. package/dist/transcriber.js +21 -0
  144. package/dist/transcriber.js.map +1 -0
  145. package/dist/tunnel.d.ts +25 -0
  146. package/dist/tunnel.d.ts.map +1 -0
  147. package/dist/tunnel.js +2 -0
  148. package/dist/tunnel.js.map +1 -0
  149. package/dist/type-contracts.d.ts +2 -0
  150. package/dist/type-contracts.d.ts.map +1 -0
  151. package/dist/type-contracts.js +4 -0
  152. package/dist/type-contracts.js.map +1 -0
  153. package/dist/types.test-d.d.ts +2 -0
  154. package/dist/types.test-d.d.ts.map +1 -0
  155. package/dist/types.test-d.js +22 -0
  156. package/dist/types.test-d.js.map +1 -0
  157. package/dist/view-renderer.d.ts +97 -0
  158. package/dist/view-renderer.d.ts.map +1 -0
  159. package/dist/view-renderer.js +72 -0
  160. package/dist/view-renderer.js.map +1 -0
  161. package/package.json +38 -0
  162. package/src/agent.ts +38 -0
  163. package/src/cache-strategy.ts +39 -0
  164. package/src/channel.ts +158 -0
  165. package/src/client-session.ts +88 -0
  166. package/src/command.ts +86 -0
  167. package/src/compactor-helpers.test.ts +206 -0
  168. package/src/compactor-helpers.ts +163 -0
  169. package/src/compactor.ts +20 -0
  170. package/src/define.test.ts +76 -0
  171. package/src/define.ts +113 -0
  172. package/src/elision-helpers.ts +143 -0
  173. package/src/elision-state.ts +170 -0
  174. package/src/embedding-cache.ts +0 -0
  175. package/src/embedding.ts +22 -0
  176. package/src/errors.test.ts +176 -0
  177. package/src/errors.ts +308 -0
  178. package/src/events.ts +250 -0
  179. package/src/hooks.ts +54 -0
  180. package/src/ids.ts +16 -0
  181. package/src/index.ts +304 -0
  182. package/src/install-hints.ts +43 -0
  183. package/src/isolation.ts +148 -0
  184. package/src/log.ts +11 -0
  185. package/src/loop-helpers.test.ts +78 -0
  186. package/src/mode-helpers.ts +483 -0
  187. package/src/mode.ts +139 -0
  188. package/src/package-root.test.ts +40 -0
  189. package/src/permission.ts +37 -0
  190. package/src/plugin.ts +92 -0
  191. package/src/provider-utils.test.ts +84 -0
  192. package/src/provider-utils.ts +171 -0
  193. package/src/provider.ts +195 -0
  194. package/src/requirements.ts +35 -0
  195. package/src/schemas.test.ts +106 -0
  196. package/src/schemas.ts +97 -0
  197. package/src/session-like.ts +118 -0
  198. package/src/skill.ts +34 -0
  199. package/src/subagent.ts +46 -0
  200. package/src/token-accounting.test.ts +93 -0
  201. package/src/token-accounting.ts +202 -0
  202. package/src/token-efficiency.test.ts +459 -0
  203. package/src/tool-dispatch.ts +137 -0
  204. package/src/tool-gating.ts +107 -0
  205. package/src/tool.ts +175 -0
  206. package/src/transcriber.ts +71 -0
  207. package/src/tunnel.ts +26 -0
  208. package/src/type-contracts.ts +4 -0
  209. package/src/types.test-d.ts +29 -0
  210. package/src/view-renderer.test.ts +90 -0
  211. package/src/view-renderer.ts +156 -0
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Shared elision decision logic — the single source of truth for "is this event
3
+ * stubbed, and to what size", consumed by BOTH `projectMessagesFromLog` (what we
4
+ * send) and `estimateContextTokens` (what we think we send). Keeping them in one
5
+ * leaf module guarantees the estimate matches reality (no overflow from
6
+ * undercounting pinned recalls) and avoids a circular import between the
7
+ * projection and the estimate.
8
+ */
9
+ /** Below this size, eliding a turn/result saves nothing — keep it verbatim. */
10
+ export const TINY_TURN_CHARS = 200;
11
+ /** Bytes of a tool_result payload (for stub labels + the recall cap). */
12
+ export function toolResultBytes(output, errorMessage) {
13
+ if (errorMessage !== undefined)
14
+ return errorMessage.length;
15
+ if (typeof output === 'string')
16
+ return output.length;
17
+ try {
18
+ return JSON.stringify(output ?? '').length;
19
+ }
20
+ catch {
21
+ return 0;
22
+ }
23
+ }
24
+ /** Deterministic stub for an elided tool result. Stable bytes → cache-safe. */
25
+ export function toolResultStub(callId, bytes, recalled) {
26
+ if (recalled)
27
+ return `[output elided — already recalled below · call "${callId}"]`;
28
+ const label = bytes >= 1024 ? `${(Math.round(bytes / 102.4) / 10).toFixed(1)} KB` : `${bytes} B`;
29
+ return `[output elided — ${label} · recall("${callId}") to view]`;
30
+ }
31
+ /** Deterministic stub for an elided conversational (user/assistant) turn. */
32
+ export function conversationalStub(role, seq) {
33
+ return `[elided ${role} turn · recall({ seq: ${seq} }) to view]`;
34
+ }
35
+ const EMPTY_STATE = {
36
+ hwm: -1,
37
+ effectiveElideConversational: false,
38
+ neverElide: new Set(),
39
+ toolNameByCall: new Map(),
40
+ recalledCallIds: new Set(),
41
+ recalledSeqs: new Set(),
42
+ recallResultCallIds: new Set(),
43
+ unpinnedRecallCallIds: new Set(),
44
+ firstUserPromptSeq: -1,
45
+ };
46
+ /**
47
+ * Derive elision state purely from the log: the active high-water mark + flags
48
+ * (from the latest ElisionEvent), the callId→tool map, recall bookkeeping, the
49
+ * adaptive conversational auto-disable, and which pinned recalls exceed the cap.
50
+ */
51
+ export function computeElisionState(events) {
52
+ let hwm = -1;
53
+ let elideConversational = false;
54
+ let conversationalRecallThreshold = Number.POSITIVE_INFINITY;
55
+ let maxRecallBytes = Number.POSITIVE_INFINITY;
56
+ let neverElide = [];
57
+ for (const e of events) {
58
+ if (e.type === 'elision' && e.elidedThrough > hwm) {
59
+ hwm = e.elidedThrough;
60
+ elideConversational = e.elideConversational;
61
+ conversationalRecallThreshold = e.conversationalRecallThreshold;
62
+ maxRecallBytes = e.maxRecallBytes;
63
+ neverElide = e.neverElideTools;
64
+ }
65
+ }
66
+ if (hwm < 0)
67
+ return EMPTY_STATE;
68
+ const toolNameByCall = new Map();
69
+ const recalledCallIds = new Set();
70
+ const recalledSeqs = new Set();
71
+ const recallResultCallIds = new Set();
72
+ let seqRecalls = 0;
73
+ let firstUserPromptSeq = -1;
74
+ for (const e of events) {
75
+ if (e.type === 'tool_call_requested') {
76
+ toolNameByCall.set(e.callId, e.name);
77
+ if (e.name === 'recall') {
78
+ recallResultCallIds.add(e.callId);
79
+ const input = e.input;
80
+ if (input && typeof input === 'object') {
81
+ if (typeof input.callId === 'string')
82
+ recalledCallIds.add(input.callId);
83
+ if (typeof input.seq === 'number') {
84
+ recalledSeqs.add(input.seq);
85
+ seqRecalls += 1; // seq-recalls = signal that TEXT elision is hurting
86
+ }
87
+ }
88
+ }
89
+ }
90
+ else if (e.type === 'user_prompt' && firstUserPromptSeq < 0) {
91
+ firstUserPromptSeq = e.seq;
92
+ }
93
+ }
94
+ // Cap pinned recalls: keep the newest recall outputs within maxRecallBytes
95
+ // verbatim, stub the rest. Only matters once a recall result ages below HWM.
96
+ const unpinnedRecallCallIds = new Set();
97
+ const agedRecalls = events
98
+ .filter((e) => e.type === 'tool_result' && recallResultCallIds.has(e.callId) && e.seq <= hwm)
99
+ .sort((a, b) => b.seq - a.seq); // newest first
100
+ let pinned = 0;
101
+ for (const e of agedRecalls) {
102
+ pinned += toolResultBytes(e.output, e.error?.message);
103
+ if (pinned > maxRecallBytes)
104
+ unpinnedRecallCallIds.add(e.callId);
105
+ }
106
+ return {
107
+ hwm,
108
+ effectiveElideConversational: elideConversational && seqRecalls < conversationalRecallThreshold,
109
+ neverElide: new Set(neverElide),
110
+ toolNameByCall,
111
+ recalledCallIds,
112
+ recalledSeqs,
113
+ recallResultCallIds,
114
+ unpinnedRecallCallIds,
115
+ firstUserPromptSeq,
116
+ };
117
+ }
118
+ /** Is this tool_result sent as a stub? (Shared by projection + estimate.) */
119
+ export function toolResultStubbed(e, state) {
120
+ if (e.seq > state.hwm || e.error)
121
+ return false;
122
+ const name = state.toolNameByCall.get(e.callId);
123
+ if (name !== undefined && state.neverElide.has(name))
124
+ return false;
125
+ if (state.recallResultCallIds.has(e.callId)) {
126
+ // Recall outputs are pinned verbatim unless they blew the cap.
127
+ return state.unpinnedRecallCallIds.has(e.callId);
128
+ }
129
+ if (toolResultBytes(e.output) <= TINY_TURN_CHARS)
130
+ return false; // tiny: keep full
131
+ return true;
132
+ }
133
+ /** Is this user/assistant turn collapsed to a conversational stub? */
134
+ export function conversationalStubbed(e, state) {
135
+ if (e.seq > state.hwm || !state.effectiveElideConversational)
136
+ return false;
137
+ if (e.type === 'user_prompt' && e.seq === state.firstUserPromptSeq)
138
+ return false; // anchor
139
+ const len = e.type === 'user_prompt' ? e.text.length : e.content.length;
140
+ if (len <= TINY_TURN_CHARS)
141
+ return false;
142
+ return true;
143
+ }
144
+ //# sourceMappingURL=elision-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elision-state.js","sourceRoot":"","sources":["../src/elision-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { EmbeddingProvider } from './embedding.js';
2
+ /**
3
+ * Wraps any `EmbeddingProvider` with an in-memory content-hash cache.
4
+ * Useful when the same text gets re-embedded across calls (e.g., a memory
5
+ * body that doesn't change between recall invocations).
6
+ *
7
+ * Provider-agnostic — composes with the OpenAI plugin, the Transformers
8
+ * plugin, or anyone else implementing `EmbeddingProvider`.
9
+ *
10
+ * For cross-process persistence, use `serialize` + `hydrate`.
11
+ */
12
+ export declare class CachedEmbeddingProvider implements EmbeddingProvider {
13
+ private readonly upstream;
14
+ readonly name: string;
15
+ private cache;
16
+ constructor(upstream: EmbeddingProvider);
17
+ get dim(): number | 'dynamic';
18
+ embed(texts: ReadonlyArray<string>): Promise<ReadonlyArray<ReadonlyArray<number>>>;
19
+ serialize(): Record<string, ReadonlyArray<number>>;
20
+ hydrate(entries: Record<string, ReadonlyArray<number>>): void;
21
+ clear(): void;
22
+ get size(): number;
23
+ /**
24
+ * Namespace the cache key by the upstream's identity (name + dim). Without
25
+ * this, a serialized cache hydrated into a provider for a DIFFERENT model
26
+ * (or `dimensions` truncation) would serve the old model's vectors for the
27
+ * same text — wrong dimensionality / semantics. Namespacing makes a foreign
28
+ * provider's entries simply miss (and re-embed) instead of colliding.
29
+ */
30
+ private key;
31
+ }
32
+ //# sourceMappingURL=embedding-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedding-cache.d.ts","sourceRoot":"","sources":["../src/embedding-cache.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD;;;;;;;;;GASG;AACH,qBAAa,uBAAwB,YAAW,iBAAiB;IAInD,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAHrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,KAAK,CAA4C;gBAE5B,QAAQ,EAAE,iBAAiB;IAIxD,IAAI,GAAG,IAAI,MAAM,GAAG,SAAS,CAE5B;IAEK,KAAK,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;IAmBxF,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAIlD,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI;IAI7D,KAAK,IAAI,IAAI;IAIb,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;;;;OAMG;IACH,OAAO,CAAC,GAAG;CAGZ"}
Binary file
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedding-cache.js","sourceRoot":"","sources":["../src/embedding-cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC;;;;;;;;;GASG;AACH,MAAM,OAAO,uBAAuB;IAIL;IAHpB,IAAI,CAAS;IACd,KAAK,GAAG,IAAI,GAAG,EAAiC,CAAC;IAEzD,YAA6B,QAA2B;QAA3B,aAAQ,GAAR,QAAQ,CAAmB;QACtD,IAAI,CAAC,IAAI,GAAG,GAAG,QAAQ,CAAC,IAAI,QAAQ,CAAC;IACvC,CAAC;IAED,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,KAA4B;QACtC,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,WAAW,GAAa,EAAE,CAAC;QACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC;gBAChC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC;gBACvB,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAChD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC5C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAE,CAAE,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAE,CAAC,CAAC;IAC/C,CAAC;IAED,SAAS;QACP,OAAO,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,CAAC,OAA8C;QACpD,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;YAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACrE,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;IAED;;;;;;OAMG;IACK,GAAG,CAAC,IAAY;QACtB,OAAO,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC;IACpE,CAAC;CACF;AAED,SAAS,IAAI,CAAC,IAAY;IACxB,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACtE,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Provider of dense vector embeddings for text. Used by @moxxy/plugin-memory
3
+ * for semantic recall. Implementations might call OpenAI, Voyage, Anthropic
4
+ * (when available), or run a local model via transformers.js.
5
+ *
6
+ * @moxxy/plugin-memory ships a built-in TF-IDF embedder for zero-dep operation
7
+ * — set `mode: 'auto'` (default) and it picks the registered provider when
8
+ * available, else TF-IDF.
9
+ */
10
+ export interface EmbeddingProvider {
11
+ /** Short stable name, e.g. 'openai-text-embedding-3-small'. */
12
+ readonly name: string;
13
+ /**
14
+ * Vector dimensionality. Consumers may verify this matches their stored
15
+ * index. For TF-IDF this is the vocab size (dynamic).
16
+ */
17
+ readonly dim: number | 'dynamic';
18
+ /** Embed a batch of strings. Returns vectors in input order. */
19
+ embed(texts: ReadonlyArray<string>): Promise<ReadonlyArray<ReadonlyArray<number>>>;
20
+ }
21
+ //# sourceMappingURL=embedding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedding.d.ts","sourceRoot":"","sources":["../src/embedding.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IAEjC,gEAAgE;IAChE,KAAK,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;CACpF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=embedding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedding.js","sourceRoot":"","sources":["../src/embedding.ts"],"names":[],"mappings":""}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Structured error type used across moxxy. Anything that bubbles to the
3
+ * user (CLI top-level, channel renderers) should throw a `MoxxyError`
4
+ * with a stable `code`, an actionable `message`, and ideally a `hint` for
5
+ * recovery. The CLI's bin.ts top-level handler formats these as:
6
+ *
7
+ * error [CODE] <message>
8
+ * hint: <hint>
9
+ *
10
+ * For raw / unknown errors that aren't ours (e.g. a Node `fetch` rejection
11
+ * for ECONNREFUSED), call `classifyNetworkError(err, { url })` at the
12
+ * fetch boundary to wrap them — that's where "fetch failed" turns into
13
+ * `NETWORK_UNREACHABLE` + a useful message.
14
+ */
15
+ /**
16
+ * Stable error codes. Keep this set small and behavioural ("what does the
17
+ * user need to do?") rather than exhaustively granular. New codes should
18
+ * earn their place by mapping to a different recovery action than any
19
+ * existing one.
20
+ */
21
+ export type MoxxyErrorCode = 'NETWORK_UNREACHABLE' | 'NETWORK_TIMEOUT' | 'NETWORK_TLS_FAILURE' | 'NETWORK_ABORTED' | 'AUTH_NO_CREDENTIALS' | 'AUTH_EXPIRED' | 'AUTH_INVALID' | 'AUTH_DENIED' | 'OAUTH_FLOW_TIMEOUT' | 'OAUTH_FLOW_DENIED' | 'OAUTH_FLOW_STATE_MISMATCH' | 'OAUTH_FLOW_PORT_BUSY' | 'OAUTH_FLOW_NOT_SUPPORTED' | 'PROVIDER_NOT_CONFIGURED' | 'PROVIDER_RATE_LIMITED' | 'PROVIDER_SERVER_ERROR' | 'PROVIDER_BAD_REQUEST' | 'PROVIDER_UNKNOWN_RESPONSE' | 'VAULT_PASSPHRASE' | 'VAULT_CORRUPT' | 'CONFIG_INVALID' | 'PLUGIN_LOAD_FAILED' | 'UNKNOWN_COMMAND' | 'INTERNAL';
22
+ export interface MoxxyErrorInit {
23
+ readonly code: MoxxyErrorCode;
24
+ readonly message: string;
25
+ readonly hint?: string;
26
+ /**
27
+ * Stable structured context — surfaced to logs / debug output, NOT in
28
+ * the default user-facing message. Use for `provider`, `url`, `status`,
29
+ * `provider_id`, etc.
30
+ */
31
+ readonly context?: Readonly<Record<string, string | number>>;
32
+ /** Underlying error, for chained-cause stack traces. */
33
+ readonly cause?: unknown;
34
+ }
35
+ /**
36
+ * Tagged error class. Use the constructor directly for fresh errors, or
37
+ * `MoxxyError.wrap` to upgrade an unknown thrown value while preserving
38
+ * the original cause. The CLI's top-level handler keys off `instanceof
39
+ * MoxxyError` to render the structured form.
40
+ */
41
+ export declare class MoxxyError extends Error {
42
+ readonly code: MoxxyErrorCode;
43
+ readonly hint?: string;
44
+ readonly context?: Readonly<Record<string, string | number>>;
45
+ constructor(init: MoxxyErrorInit);
46
+ static isMoxxyError(err: unknown): err is MoxxyError;
47
+ /**
48
+ * Convert an unknown thrown value to a MoxxyError. If `err` is already
49
+ * one, returns it unchanged. Otherwise builds a new error with the
50
+ * given code/message/hint and attaches `err` as `cause`.
51
+ */
52
+ static wrap(err: unknown, init: Omit<MoxxyErrorInit, 'cause'>): MoxxyError;
53
+ }
54
+ /**
55
+ * Inspect a thrown value for Node networking signals and produce a
56
+ * MoxxyError when one matches. Returns `null` when the error doesn't
57
+ * look network-shaped — callers should fall through to other handlers
58
+ * (e.g. status-code mapping).
59
+ *
60
+ * Node's `fetch` (undici) hides the real reason inside `err.cause.code`
61
+ * (ECONNREFUSED, ENOTFOUND, ETIMEDOUT, CERT_HAS_EXPIRED, ...). Without
62
+ * unwrapping that we'd surface only "fetch failed" / "TypeError: failed
63
+ * to fetch", which is what triggered this whole error-rename effort.
64
+ */
65
+ export declare function classifyNetworkError(err: unknown, ctx?: {
66
+ readonly url?: string;
67
+ readonly provider?: string;
68
+ }): MoxxyError | null;
69
+ /**
70
+ * Build a MoxxyError from an HTTP response that came back with a 4xx/5xx.
71
+ * Maps common status codes to auth / rate-limit / server-error codes.
72
+ * Pass the response body text in `body` so the message can echo the
73
+ * provider's reason. Returns `null` for unmapped status codes (caller
74
+ * should fall back to a generic error).
75
+ */
76
+ export declare function classifyHttpStatus(status: number, ctx?: {
77
+ readonly url?: string;
78
+ readonly provider?: string;
79
+ readonly body?: string;
80
+ }): MoxxyError | null;
81
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAEtB,qBAAqB,GACrB,iBAAiB,GACjB,qBAAqB,GACrB,iBAAiB,GAEjB,qBAAqB,GACrB,cAAc,GACd,cAAc,GACd,aAAa,GAEb,oBAAoB,GACpB,mBAAmB,GACnB,2BAA2B,GAC3B,sBAAsB,GACtB,0BAA0B,GAE1B,yBAAyB,GACzB,uBAAuB,GACvB,uBAAuB,GACvB,sBAAsB,GACtB,2BAA2B,GAE3B,kBAAkB,GAClB,eAAe,GAEf,gBAAgB,GAChB,oBAAoB,GACpB,iBAAiB,GAEjB,UAAU,CAAC;AAEf,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;IAC7D,wDAAwD;IACxD,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;GAKG;AACH,qBAAa,UAAW,SAAQ,KAAK;IACnC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;gBAEjD,IAAI,EAAE,cAAc;IAQhC,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,UAAU;IAOpD;;;;OAIG;IACH,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,GAAG,UAAU;CAI3E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,OAAO,EACZ,GAAG,GAAE;IAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9D,UAAU,GAAG,IAAI,CA6GnB;AAgBD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,GAAG,GAAE;IAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GACtF,UAAU,GAAG,IAAI,CAgDnB"}
package/dist/errors.js ADDED
@@ -0,0 +1,241 @@
1
+ /**
2
+ * Structured error type used across moxxy. Anything that bubbles to the
3
+ * user (CLI top-level, channel renderers) should throw a `MoxxyError`
4
+ * with a stable `code`, an actionable `message`, and ideally a `hint` for
5
+ * recovery. The CLI's bin.ts top-level handler formats these as:
6
+ *
7
+ * error [CODE] <message>
8
+ * hint: <hint>
9
+ *
10
+ * For raw / unknown errors that aren't ours (e.g. a Node `fetch` rejection
11
+ * for ECONNREFUSED), call `classifyNetworkError(err, { url })` at the
12
+ * fetch boundary to wrap them — that's where "fetch failed" turns into
13
+ * `NETWORK_UNREACHABLE` + a useful message.
14
+ */
15
+ /**
16
+ * Tagged error class. Use the constructor directly for fresh errors, or
17
+ * `MoxxyError.wrap` to upgrade an unknown thrown value while preserving
18
+ * the original cause. The CLI's top-level handler keys off `instanceof
19
+ * MoxxyError` to render the structured form.
20
+ */
21
+ export class MoxxyError extends Error {
22
+ code;
23
+ hint;
24
+ context;
25
+ constructor(init) {
26
+ super(init.message, init.cause !== undefined ? { cause: init.cause } : undefined);
27
+ this.name = 'MoxxyError';
28
+ this.code = init.code;
29
+ if (init.hint !== undefined)
30
+ this.hint = init.hint;
31
+ if (init.context !== undefined)
32
+ this.context = init.context;
33
+ }
34
+ static isMoxxyError(err) {
35
+ // `instanceof` works in-process; the name check rescues cases where
36
+ // the error crosses a module-realm boundary (rare but possible with
37
+ // dynamic imports through different SDK copies).
38
+ return err instanceof MoxxyError || (err instanceof Error && err.name === 'MoxxyError');
39
+ }
40
+ /**
41
+ * Convert an unknown thrown value to a MoxxyError. If `err` is already
42
+ * one, returns it unchanged. Otherwise builds a new error with the
43
+ * given code/message/hint and attaches `err` as `cause`.
44
+ */
45
+ static wrap(err, init) {
46
+ if (MoxxyError.isMoxxyError(err))
47
+ return err;
48
+ return new MoxxyError({ ...init, cause: err });
49
+ }
50
+ }
51
+ /**
52
+ * Inspect a thrown value for Node networking signals and produce a
53
+ * MoxxyError when one matches. Returns `null` when the error doesn't
54
+ * look network-shaped — callers should fall through to other handlers
55
+ * (e.g. status-code mapping).
56
+ *
57
+ * Node's `fetch` (undici) hides the real reason inside `err.cause.code`
58
+ * (ECONNREFUSED, ENOTFOUND, ETIMEDOUT, CERT_HAS_EXPIRED, ...). Without
59
+ * unwrapping that we'd surface only "fetch failed" / "TypeError: failed
60
+ * to fetch", which is what triggered this whole error-rename effort.
61
+ */
62
+ export function classifyNetworkError(err, ctx = {}) {
63
+ if (MoxxyError.isMoxxyError(err))
64
+ return err;
65
+ if (!(err instanceof Error))
66
+ return null;
67
+ const code = extractNodeErrorCode(err);
68
+ const url = ctx.url;
69
+ const target = url ? new URL(url).host : (ctx.provider ?? 'the upstream service');
70
+ const baseContext = {};
71
+ if (url)
72
+ baseContext.url = url;
73
+ if (ctx.provider)
74
+ baseContext.provider = ctx.provider;
75
+ // Abort first — distinct UX from a real failure.
76
+ if (err.name === 'AbortError' ||
77
+ code === 'ABORT_ERR' ||
78
+ code === 'ERR_ABORTED') {
79
+ return new MoxxyError({
80
+ code: 'NETWORK_ABORTED',
81
+ message: `Request to ${target} was aborted.`,
82
+ context: baseContext,
83
+ cause: err,
84
+ });
85
+ }
86
+ if (code === 'ENOTFOUND' || code === 'EAI_AGAIN') {
87
+ return new MoxxyError({
88
+ code: 'NETWORK_UNREACHABLE',
89
+ message: `DNS lookup failed for ${target}.`,
90
+ hint: 'Check your internet connection. If you\'re on a corporate network, ' +
91
+ 'a DNS-blocking proxy may be in the way — set HTTPS_PROXY or try a different network.',
92
+ context: baseContext,
93
+ cause: err,
94
+ });
95
+ }
96
+ if (code === 'ECONNREFUSED') {
97
+ return new MoxxyError({
98
+ code: 'NETWORK_UNREACHABLE',
99
+ message: `Connection refused by ${target}.`,
100
+ hint: 'The host actively rejected the connection. If you\'re targeting a local ' +
101
+ 'server, make sure it\'s running and listening on the expected port.',
102
+ context: baseContext,
103
+ cause: err,
104
+ });
105
+ }
106
+ if (code === 'EHOSTUNREACH' || code === 'ENETUNREACH') {
107
+ return new MoxxyError({
108
+ code: 'NETWORK_UNREACHABLE',
109
+ message: `No route to ${target}.`,
110
+ hint: 'Check your internet connection or VPN.',
111
+ context: baseContext,
112
+ cause: err,
113
+ });
114
+ }
115
+ if (code === 'ETIMEDOUT' || code === 'UND_ERR_CONNECT_TIMEOUT' || code === 'UND_ERR_HEADERS_TIMEOUT') {
116
+ return new MoxxyError({
117
+ code: 'NETWORK_TIMEOUT',
118
+ message: `Request to ${target} timed out.`,
119
+ hint: 'The host accepted the connection but didn\'t respond in time. Retry, ' +
120
+ 'or check whether the service is experiencing an outage.',
121
+ context: baseContext,
122
+ cause: err,
123
+ });
124
+ }
125
+ if (code === 'CERT_HAS_EXPIRED' ||
126
+ code === 'DEPTH_ZERO_SELF_SIGNED_CERT' ||
127
+ code === 'UNABLE_TO_VERIFY_LEAF_SIGNATURE' ||
128
+ code === 'SELF_SIGNED_CERT_IN_CHAIN' ||
129
+ (typeof code === 'string' && code.startsWith('ERR_TLS'))) {
130
+ return new MoxxyError({
131
+ code: 'NETWORK_TLS_FAILURE',
132
+ message: `TLS handshake with ${target} failed (${code}).`,
133
+ hint: 'The server\'s certificate couldn\'t be verified. This usually means a ' +
134
+ 'self-signed cert or an MITM proxy on your network.',
135
+ context: baseContext,
136
+ cause: err,
137
+ });
138
+ }
139
+ if (code === 'ECONNRESET') {
140
+ return new MoxxyError({
141
+ code: 'NETWORK_UNREACHABLE',
142
+ message: `Connection to ${target} was reset.`,
143
+ hint: 'The server dropped the connection mid-request. Retry, or check the service status.',
144
+ context: baseContext,
145
+ cause: err,
146
+ });
147
+ }
148
+ // Last-chance heuristics on the message text. Node fetch's outer
149
+ // message is just "fetch failed"; the useful signal is in `cause`, but
150
+ // some libraries flatten that.
151
+ const msg = err.message.toLowerCase();
152
+ if (msg === 'fetch failed' || msg.includes('failed to fetch')) {
153
+ return new MoxxyError({
154
+ code: 'NETWORK_UNREACHABLE',
155
+ message: `Couldn't reach ${target}.`,
156
+ hint: 'Check your internet connection or any proxy/firewall settings.',
157
+ context: baseContext,
158
+ cause: err,
159
+ });
160
+ }
161
+ return null;
162
+ }
163
+ /**
164
+ * Walk `err.cause` chain looking for a Node-style `code` (e.g. on
165
+ * `SystemError`, `DOMException`, undici's `UND_*` codes). Node nests the
166
+ * real reason under `cause` for fetch errors.
167
+ */
168
+ function extractNodeErrorCode(err, depth = 0) {
169
+ if (depth > 4)
170
+ return undefined;
171
+ if (!err || typeof err !== 'object')
172
+ return undefined;
173
+ const e = err;
174
+ if (typeof e.code === 'string' && e.code.length > 0)
175
+ return e.code;
176
+ if (e.cause)
177
+ return extractNodeErrorCode(e.cause, depth + 1);
178
+ return undefined;
179
+ }
180
+ /**
181
+ * Build a MoxxyError from an HTTP response that came back with a 4xx/5xx.
182
+ * Maps common status codes to auth / rate-limit / server-error codes.
183
+ * Pass the response body text in `body` so the message can echo the
184
+ * provider's reason. Returns `null` for unmapped status codes (caller
185
+ * should fall back to a generic error).
186
+ */
187
+ export function classifyHttpStatus(status, ctx = {}) {
188
+ const target = ctx.provider ?? (ctx.url ? new URL(ctx.url).host : 'the upstream service');
189
+ const tail = ctx.body ? ` — ${truncate(ctx.body, 200)}` : '';
190
+ const context = { status };
191
+ if (ctx.url)
192
+ context.url = ctx.url;
193
+ if (ctx.provider)
194
+ context.provider = ctx.provider;
195
+ if (status === 401) {
196
+ return new MoxxyError({
197
+ code: 'AUTH_INVALID',
198
+ message: `${target} rejected the credentials (401).${tail}`,
199
+ hint: `Run \`moxxy login ${ctx.provider ?? '<provider>'}\` (OAuth) or check your API key.`,
200
+ context,
201
+ });
202
+ }
203
+ if (status === 403) {
204
+ return new MoxxyError({
205
+ code: 'AUTH_DENIED',
206
+ message: `${target} denied the request (403).${tail}`,
207
+ hint: 'Your credentials are valid but lack permission for this resource.',
208
+ context,
209
+ });
210
+ }
211
+ if (status === 429) {
212
+ return new MoxxyError({
213
+ code: 'PROVIDER_RATE_LIMITED',
214
+ message: `${target} is rate-limiting requests (429).${tail}`,
215
+ hint: 'Back off and retry. Check your plan limits if this keeps happening.',
216
+ context,
217
+ });
218
+ }
219
+ if (status >= 500 && status < 600) {
220
+ return new MoxxyError({
221
+ code: 'PROVIDER_SERVER_ERROR',
222
+ message: `${target} returned a server error (${status}).${tail}`,
223
+ hint: 'This is on the provider\'s side. Retry, or check their status page.',
224
+ context,
225
+ });
226
+ }
227
+ if (status === 400) {
228
+ return new MoxxyError({
229
+ code: 'PROVIDER_BAD_REQUEST',
230
+ message: `${target} rejected the request as malformed (400).${tail}`,
231
+ context,
232
+ });
233
+ }
234
+ return null;
235
+ }
236
+ function truncate(s, max) {
237
+ if (s.length <= max)
238
+ return s;
239
+ return `${s.slice(0, max - 1)}…`;
240
+ }
241
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}