@datasynx/agentic-crm 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 (251) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +767 -0
  3. package/dist/agent-config-zPvcqu07.js +14 -0
  4. package/dist/agent-config-zPvcqu07.js.map +1 -0
  5. package/dist/approvals-DpjxGHFp.js +67 -0
  6. package/dist/approvals-DpjxGHFp.js.map +1 -0
  7. package/dist/ask-CID3jnuL.js +52 -0
  8. package/dist/ask-CID3jnuL.js.map +1 -0
  9. package/dist/audit-log-DNMY9mUZ.js +49 -0
  10. package/dist/audit-log-DNMY9mUZ.js.map +1 -0
  11. package/dist/auth-CyFuu9X_.js +2 -0
  12. package/dist/auth-DFWwWcYD.js +93 -0
  13. package/dist/auth-DFWwWcYD.js.map +1 -0
  14. package/dist/autofill-Di_-SP7t.js +51 -0
  15. package/dist/autofill-Di_-SP7t.js.map +1 -0
  16. package/dist/backup-CeMk9z86.js +417 -0
  17. package/dist/backup-CeMk9z86.js.map +1 -0
  18. package/dist/backup-f_hC7rBV.js +2 -0
  19. package/dist/calendly-Bft_wwji.js +52 -0
  20. package/dist/calendly-Bft_wwji.js.map +1 -0
  21. package/dist/calendly-D3coO92o.cjs +53 -0
  22. package/dist/calendly-D3coO92o.cjs.map +1 -0
  23. package/dist/chunk-DakpK96I.cjs +43 -0
  24. package/dist/churn-C28IgnAj.js +54 -0
  25. package/dist/churn-C28IgnAj.js.map +1 -0
  26. package/dist/cli.js +4396 -0
  27. package/dist/cli.js.map +1 -0
  28. package/dist/colors-BG07TZQz.js +11 -0
  29. package/dist/colors-BG07TZQz.js.map +1 -0
  30. package/dist/compliance-B1kk5-YS.js +115 -0
  31. package/dist/compliance-B1kk5-YS.js.map +1 -0
  32. package/dist/compliance-B91zNvCR.cjs +156 -0
  33. package/dist/compliance-B91zNvCR.cjs.map +1 -0
  34. package/dist/compliance-CKSBoQUe.js +118 -0
  35. package/dist/compliance-CKSBoQUe.js.map +1 -0
  36. package/dist/compliance-CujOqAKk.js +2 -0
  37. package/dist/context-builder-BzWAp3Zs.js +96 -0
  38. package/dist/context-builder-BzWAp3Zs.js.map +1 -0
  39. package/dist/context-builder-DlrRcqmJ.js +2 -0
  40. package/dist/conversation-intel-mm7Lhemh.js +72 -0
  41. package/dist/conversation-intel-mm7Lhemh.js.map +1 -0
  42. package/dist/custom-fields-CzNeD3_v.js +2 -0
  43. package/dist/custom-fields-Pl2t9xzp.js +73 -0
  44. package/dist/custom-fields-Pl2t9xzp.js.map +1 -0
  45. package/dist/custom-objects-BHgn1GEX.js +78 -0
  46. package/dist/custom-objects-BHgn1GEX.js.map +1 -0
  47. package/dist/custom-objects-CIFrmQ2V.js +2 -0
  48. package/dist/customer-dir-DIylZ8Q6.js +75 -0
  49. package/dist/customer-dir-DIylZ8Q6.js.map +1 -0
  50. package/dist/daemon/worker.js +207 -0
  51. package/dist/daemon/worker.js.map +1 -0
  52. package/dist/enrichment-3XvgGDfB.js +103 -0
  53. package/dist/enrichment-3XvgGDfB.js.map +1 -0
  54. package/dist/file-lock-B_zi7NQl.js +22 -0
  55. package/dist/file-lock-B_zi7NQl.js.map +1 -0
  56. package/dist/gmail-auth-BP6cJwfw.js +40 -0
  57. package/dist/gmail-auth-BP6cJwfw.js.map +1 -0
  58. package/dist/gmail-auth-DxakCtGm.cjs +44 -0
  59. package/dist/gmail-auth-DxakCtGm.cjs.map +1 -0
  60. package/dist/gmail-auth-OComS92L.js +40 -0
  61. package/dist/gmail-auth-OComS92L.js.map +1 -0
  62. package/dist/gmail-push-watch-DELQFMPk.js +20 -0
  63. package/dist/gmail-push-watch-DELQFMPk.js.map +1 -0
  64. package/dist/gmail-sender-StTpJ9Ub.js +32 -0
  65. package/dist/gmail-sender-StTpJ9Ub.js.map +1 -0
  66. package/dist/gmail-sync-DIaxInDT.js +204 -0
  67. package/dist/gmail-sync-DIaxInDT.js.map +1 -0
  68. package/dist/gmail-sync-hHm9gaWd.cjs +218 -0
  69. package/dist/gmail-sync-hHm9gaWd.cjs.map +1 -0
  70. package/dist/gmail-sync-rQaVqKWd.js +214 -0
  71. package/dist/gmail-sync-rQaVqKWd.js.map +1 -0
  72. package/dist/gmail-webhook-handler-DS7OlRPX.js +3 -0
  73. package/dist/gmail-webhook-handler-e5Od25FX.js +97 -0
  74. package/dist/gmail-webhook-handler-e5Od25FX.js.map +1 -0
  75. package/dist/goal-engine-CUZSpERI.js +2 -0
  76. package/dist/goal-engine-KpBftn4V.js +295 -0
  77. package/dist/goal-engine-KpBftn4V.js.map +1 -0
  78. package/dist/google-drive-sync-DEPcqFca.js +105 -0
  79. package/dist/google-drive-sync-DEPcqFca.js.map +1 -0
  80. package/dist/hybrid-search-BmHttLrR.js +40 -0
  81. package/dist/hybrid-search-BmHttLrR.js.map +1 -0
  82. package/dist/hygiene-DZqfYpFf.js +38 -0
  83. package/dist/hygiene-DZqfYpFf.js.map +1 -0
  84. package/dist/identity-CI6olMNm.js +41 -0
  85. package/dist/identity-CI6olMNm.js.map +1 -0
  86. package/dist/identity-gyfWdrcX.js +2 -0
  87. package/dist/import-hubspot-BaK71U_K.js +588 -0
  88. package/dist/import-hubspot-BaK71U_K.js.map +1 -0
  89. package/dist/index-V8BFaH-b.d.ts +539 -0
  90. package/dist/index-V8BFaH-b.d.ts.map +1 -0
  91. package/dist/index-YqwMd6aQ.d.cts +538 -0
  92. package/dist/index-YqwMd6aQ.d.cts.map +1 -0
  93. package/dist/index.cjs +185 -0
  94. package/dist/index.cjs.map +1 -0
  95. package/dist/index.d.cts +538 -0
  96. package/dist/index.d.cts.map +1 -0
  97. package/dist/index.d.ts +539 -0
  98. package/dist/index.d.ts.map +1 -0
  99. package/dist/index.js +165 -0
  100. package/dist/index.js.map +1 -0
  101. package/dist/interactions-writer-CrPStUll.cjs +77 -0
  102. package/dist/interactions-writer-CrPStUll.cjs.map +1 -0
  103. package/dist/interactions-writer-DO3KcSR3.js +52 -0
  104. package/dist/interactions-writer-DO3KcSR3.js.map +1 -0
  105. package/dist/interactions-writer-SLHnoEeE.js +46 -0
  106. package/dist/interactions-writer-SLHnoEeE.js.map +1 -0
  107. package/dist/interactions-writer-dSPy1XfO.js +2 -0
  108. package/dist/knowledge-base-D0Fh40kc.js +1013 -0
  109. package/dist/knowledge-base-D0Fh40kc.js.map +1 -0
  110. package/dist/lancedb-CCBbpulq.js +2 -0
  111. package/dist/lancedb-rlvWoPwl.js +98 -0
  112. package/dist/lancedb-rlvWoPwl.js.map +1 -0
  113. package/dist/lead-model-BCFzyktm.js +109 -0
  114. package/dist/lead-model-BCFzyktm.js.map +1 -0
  115. package/dist/llm-DEjWcqmW.js +2 -0
  116. package/dist/llm-DvzZqva0.js +372 -0
  117. package/dist/llm-DvzZqva0.js.map +1 -0
  118. package/dist/llm-Z8RIYkpF.js +174 -0
  119. package/dist/llm-Z8RIYkpF.js.map +1 -0
  120. package/dist/llm-iijeXmgq.cjs +198 -0
  121. package/dist/llm-iijeXmgq.cjs.map +1 -0
  122. package/dist/mcp-CdTJWTJf.d.cts +12 -0
  123. package/dist/mcp-CdTJWTJf.d.cts.map +1 -0
  124. package/dist/mcp-CdTJWTJf.d.ts +12 -0
  125. package/dist/mcp-CdTJWTJf.d.ts.map +1 -0
  126. package/dist/mcp.cjs +7464 -0
  127. package/dist/mcp.cjs.map +1 -0
  128. package/dist/mcp.d.cts +12 -0
  129. package/dist/mcp.d.cts.map +1 -0
  130. package/dist/mcp.d.ts +12 -0
  131. package/dist/mcp.d.ts.map +1 -0
  132. package/dist/mcp.js +7448 -0
  133. package/dist/mcp.js.map +1 -0
  134. package/dist/memory-Bb6ky3kb.js +58 -0
  135. package/dist/memory-Bb6ky3kb.js.map +1 -0
  136. package/dist/memory-Cy6-Tbyl.js +2 -0
  137. package/dist/metrics-DH8wHvya.js +26 -0
  138. package/dist/metrics-DH8wHvya.js.map +1 -0
  139. package/dist/microsoft-auth-B8_S45gh.js +17 -0
  140. package/dist/microsoft-auth-B8_S45gh.js.map +1 -0
  141. package/dist/microsoft-calendar-B6MMtUQK.js +67 -0
  142. package/dist/microsoft-calendar-B6MMtUQK.js.map +1 -0
  143. package/dist/microsoft-sync-CpZVoSuq.js +68 -0
  144. package/dist/microsoft-sync-CpZVoSuq.js.map +1 -0
  145. package/dist/nba-3wanmJ0U.js +48 -0
  146. package/dist/nba-3wanmJ0U.js.map +1 -0
  147. package/dist/notification-dispatcher-0vYNngWe.js +97 -0
  148. package/dist/notification-dispatcher-0vYNngWe.js.map +1 -0
  149. package/dist/opportunity-score-BTMOQSTV.js +47 -0
  150. package/dist/opportunity-score-BTMOQSTV.js.map +1 -0
  151. package/dist/pipedrive-client-CdGKpH9b.js +17 -0
  152. package/dist/pipedrive-client-CdGKpH9b.js.map +1 -0
  153. package/dist/pipeline-writer-BqBrYrQc.js +2 -0
  154. package/dist/pipeline-writer-BvVquKIe.js +96 -0
  155. package/dist/pipeline-writer-BvVquKIe.js.map +1 -0
  156. package/dist/pipeline-writer-N2omexxp.cjs +121 -0
  157. package/dist/pipeline-writer-N2omexxp.cjs.map +1 -0
  158. package/dist/pipeline-writer-eufx_0o1.js +102 -0
  159. package/dist/pipeline-writer-eufx_0o1.js.map +1 -0
  160. package/dist/proactive-agent-BgQXw3ac.js +96 -0
  161. package/dist/proactive-agent-BgQXw3ac.js.map +1 -0
  162. package/dist/proactive-worker-BrLHNhjH.js +229 -0
  163. package/dist/proactive-worker-BrLHNhjH.js.map +1 -0
  164. package/dist/push-manager-CdqIIkuh.js +108 -0
  165. package/dist/push-manager-CdqIIkuh.js.map +1 -0
  166. package/dist/push-manager-CowY-0IK.js +2 -0
  167. package/dist/quote-generator-BfwENXzg.js +133 -0
  168. package/dist/quote-generator-BfwENXzg.js.map +1 -0
  169. package/dist/quote-generator-OhSFsi3x.js +2 -0
  170. package/dist/rbac-C7c8tcES.js +2 -0
  171. package/dist/rbac-CTIktZaC.js +91 -0
  172. package/dist/rbac-CTIktZaC.js.map +1 -0
  173. package/dist/relationship-health-odxEoQdJ.js +454 -0
  174. package/dist/relationship-health-odxEoQdJ.js.map +1 -0
  175. package/dist/revenue-simulation-BJdRTEHc.js +2 -0
  176. package/dist/revenue-simulation-Bqf2DLVB.js +251 -0
  177. package/dist/revenue-simulation-Bqf2DLVB.js.map +1 -0
  178. package/dist/rolldown-runtime-D7D4PA-g.js +13 -0
  179. package/dist/salesforce-client-rhZFa_p5.js +51 -0
  180. package/dist/salesforce-client-rhZFa_p5.js.map +1 -0
  181. package/dist/segments-BqcD5HIl.js +61 -0
  182. package/dist/segments-BqcD5HIl.js.map +1 -0
  183. package/dist/sequence-engine-CCTHEBgi.js +2 -0
  184. package/dist/sequence-engine-J1lTW_in.js +91 -0
  185. package/dist/sequence-engine-J1lTW_in.js.map +1 -0
  186. package/dist/sequence-store-DaaWr0Os.js +221 -0
  187. package/dist/sequence-store-DaaWr0Os.js.map +1 -0
  188. package/dist/server-Dyva03K8.js +4287 -0
  189. package/dist/server-Dyva03K8.js.map +1 -0
  190. package/dist/session-B9AilxOE.js +81 -0
  191. package/dist/session-B9AilxOE.js.map +1 -0
  192. package/dist/session-D0qFkBla.cjs +82 -0
  193. package/dist/session-D0qFkBla.cjs.map +1 -0
  194. package/dist/session-D9ub6Wl1.js +79 -0
  195. package/dist/session-D9ub6Wl1.js.map +1 -0
  196. package/dist/session-mWHA71Lw.js +2 -0
  197. package/dist/session-store-B0QZE8Bx.cjs +697 -0
  198. package/dist/session-store-B0QZE8Bx.cjs.map +1 -0
  199. package/dist/session-store-C8tEvMPw.js +543 -0
  200. package/dist/session-store-C8tEvMPw.js.map +1 -0
  201. package/dist/session-store-CEa39Dxs.js +15 -0
  202. package/dist/session-store-CEa39Dxs.js.map +1 -0
  203. package/dist/sla-engine-5IhTsBUR.js +2 -0
  204. package/dist/sla-engine-BqX-7u-7.js +53 -0
  205. package/dist/sla-engine-BqX-7u-7.js.map +1 -0
  206. package/dist/sop-DkhVChGy.js +2 -0
  207. package/dist/sop-Vp0UPWFW.js +70 -0
  208. package/dist/sop-Vp0UPWFW.js.map +1 -0
  209. package/dist/survey-engine-C06hcQt3.js +2 -0
  210. package/dist/survey-engine-DBjCYqCv.js +147 -0
  211. package/dist/survey-engine-DBjCYqCv.js.map +1 -0
  212. package/dist/sync-state-ChaLbamC.js +33 -0
  213. package/dist/sync-state-ChaLbamC.js.map +1 -0
  214. package/dist/sync-state-CwLSt_1m.js +2 -0
  215. package/dist/ticket-writer-CjqKeIRD.js +2 -0
  216. package/dist/ticket-writer-j2oX_Wal.js +134 -0
  217. package/dist/ticket-writer-j2oX_Wal.js.map +1 -0
  218. package/dist/tone-Bdm5uaht.js +48 -0
  219. package/dist/tone-Bdm5uaht.js.map +1 -0
  220. package/dist/tone-DRKlZgPr.cjs +43 -0
  221. package/dist/tone-DRKlZgPr.cjs.map +1 -0
  222. package/dist/tone-vNb2DAAD.js +39 -0
  223. package/dist/tone-vNb2DAAD.js.map +1 -0
  224. package/dist/transcript-watcher-CL2QUygI.js +132 -0
  225. package/dist/transcript-watcher-CL2QUygI.js.map +1 -0
  226. package/dist/unmatched-transcripts-BsH5bhkU.js +26 -0
  227. package/dist/unmatched-transcripts-BsH5bhkU.js.map +1 -0
  228. package/dist/unmatched-transcripts-D0PrJ9iz.js +2 -0
  229. package/dist/update-deal-BNwPGaTV.js +2 -0
  230. package/dist/update-deal-DKC79skb.js +91 -0
  231. package/dist/update-deal-DKC79skb.js.map +1 -0
  232. package/dist/usage-CClTf5e6.cjs +57 -0
  233. package/dist/usage-CClTf5e6.cjs.map +1 -0
  234. package/dist/usage-D0-TYJkw.js +93 -0
  235. package/dist/usage-D0-TYJkw.js.map +1 -0
  236. package/dist/usage-D0u9a-lV.js +54 -0
  237. package/dist/usage-D0u9a-lV.js.map +1 -0
  238. package/dist/vault-C1D3zScD.js +2 -0
  239. package/dist/vault-DXCg29W-.js +86 -0
  240. package/dist/vault-DXCg29W-.js.map +1 -0
  241. package/dist/webhooks-7EpA05Qr.js +138 -0
  242. package/dist/webhooks-7EpA05Qr.js.map +1 -0
  243. package/dist/webhooks-BO2UAnmn.js +94 -0
  244. package/dist/webhooks-BO2UAnmn.js.map +1 -0
  245. package/dist/webhooks-Xn6zO6kd.cjs +97 -0
  246. package/dist/webhooks-Xn6zO6kd.cjs.map +1 -0
  247. package/dist/write-queue-BDolUxfs.cjs +26 -0
  248. package/dist/write-queue-BDolUxfs.cjs.map +1 -0
  249. package/dist/write-queue-IbsAjUnh.js +21 -0
  250. package/dist/write-queue-IbsAjUnh.js.map +1 -0
  251. package/package.json +142 -0
@@ -0,0 +1,198 @@
1
+ const require_chunk = require("./chunk-DakpK96I.cjs");
2
+ const require_compliance = require("./compliance-B91zNvCR.cjs");
3
+ let _anthropic_ai_sdk = require("@anthropic-ai/sdk");
4
+ _anthropic_ai_sdk = require_chunk.__toESM(_anthropic_ai_sdk, 1);
5
+ //#region src/core/resilience.ts
6
+ var CircuitBreaker = class {
7
+ opts;
8
+ failures = 0;
9
+ openedAt = null;
10
+ _state = "closed";
11
+ constructor(opts) {
12
+ this.opts = opts;
13
+ }
14
+ get state() {
15
+ return this._state;
16
+ }
17
+ async call(fn) {
18
+ if (this._state === "open") if (Date.now() - (this.openedAt ?? 0) >= this.opts.halfOpenAfter) this._state = "half-open";
19
+ else throw new Error("Circuit open");
20
+ try {
21
+ const result = await fn();
22
+ this.failures = 0;
23
+ this._state = "closed";
24
+ this.openedAt = null;
25
+ return result;
26
+ } catch (err) {
27
+ this.failures++;
28
+ if (this._state === "half-open" || this.failures >= this.opts.threshold) {
29
+ this._state = "open";
30
+ this.openedAt = Date.now();
31
+ this.failures = 0;
32
+ }
33
+ throw err;
34
+ }
35
+ }
36
+ };
37
+ //#endregion
38
+ //#region src/core/input-guard.ts
39
+ function guardIsoDate(val, field) {
40
+ if (typeof val !== "string" || !val) throw new Error(`${field}: invalid date`);
41
+ const d = new Date(val);
42
+ if (isNaN(d.getTime())) throw new Error(`${field}: invalid date`);
43
+ if (/^\d{4}-\d{2}-\d{2}/.test(val)) {
44
+ const [year, month, day] = val.slice(0, 10).split("-").map(Number);
45
+ if (month < 1 || month > 12 || day < 1 || day > 31) throw new Error(`${field}: invalid date`);
46
+ const reparse = /* @__PURE__ */ new Date(`${year}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")}`);
47
+ if (isNaN(reparse.getTime()) || reparse.getMonth() + 1 !== month) throw new Error(`${field}: invalid date`);
48
+ }
49
+ return val;
50
+ }
51
+ const DEFAULT_LLM_MAX_BYTES = 512 * 1024;
52
+ function guardLlmResponse(response, maxBytes = DEFAULT_LLM_MAX_BYTES) {
53
+ if (typeof response !== "string") throw new Error("LLM response: expected string");
54
+ const byteLen = Buffer.byteLength(response, "utf-8");
55
+ if (byteLen > maxBytes) throw new Error(`LLM response exceeds ${maxBytes} bytes (got ${byteLen})`);
56
+ return response;
57
+ }
58
+ //#endregion
59
+ //#region src/core/llm.ts
60
+ var llm_exports = /* @__PURE__ */ require_chunk.__exportAll({
61
+ callLlm: () => callLlm,
62
+ summarizeEmail: () => summarizeEmail
63
+ });
64
+ const MODEL = "claude-haiku-4-5-20251001";
65
+ let _client = null;
66
+ let llmCircuit = new CircuitBreaker({
67
+ threshold: 3,
68
+ timeoutMs: 3e4,
69
+ halfOpenAfter: 3e4
70
+ });
71
+ function getClient() {
72
+ if (!process.env["ANTHROPIC_API_KEY"]) return null;
73
+ if (!_client) _client = new _anthropic_ai_sdk.default();
74
+ return _client;
75
+ }
76
+ function emailFallback(snippet) {
77
+ return {
78
+ summary: snippet.slice(0, 300),
79
+ sentiment: "neutral",
80
+ nextSteps: []
81
+ };
82
+ }
83
+ async function summarizeEmail(subject, snippet, from) {
84
+ const client = getClient();
85
+ if (!client) return emailFallback(snippet);
86
+ try {
87
+ const textBlock = (await client.messages.create({
88
+ model: MODEL,
89
+ max_tokens: 200,
90
+ system: [{
91
+ type: "text",
92
+ text: "You are a CRM assistant. Extract structured information from email metadata.\nReturn ONLY valid JSON matching: { \"summary\": string (2 sentences, German), \"sentiment\": \"positive\"|\"neutral\"|\"negative\"|\"urgent\", \"nextSteps\": string[] }",
93
+ cache_control: { type: "ephemeral" }
94
+ }],
95
+ messages: [{
96
+ role: "user",
97
+ content: `Subject: ${subject}\nFrom: ${from}\nContent: ${snippet}`
98
+ }]
99
+ })).content.find((b) => b.type === "text");
100
+ if (!textBlock || textBlock.type !== "text") return emailFallback(snippet);
101
+ try {
102
+ return JSON.parse(textBlock.text);
103
+ } catch {
104
+ return emailFallback(snippet);
105
+ }
106
+ } catch {
107
+ return emailFallback(snippet);
108
+ }
109
+ }
110
+ function recordCall(model, inputTokens, outputTokens, ctx) {
111
+ const dataDir = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
112
+ Promise.resolve().then(() => require("./usage-CClTf5e6.cjs")).then(({ recordUsage }) => recordUsage(dataDir, {
113
+ ...ctx?.slug ? { slug: ctx.slug } : {},
114
+ ...ctx?.tool ? { tool: ctx.tool } : {},
115
+ model,
116
+ inputTokens,
117
+ outputTokens
118
+ }));
119
+ }
120
+ /**
121
+ * Local-LLM path (D17): call an OpenAI-compatible endpoint (Ollama/local) via
122
+ * fetch — no extra dependency — so customer data can stay on-machine. Usage is
123
+ * still recorded for cost/observability parity with the Anthropic path.
124
+ */
125
+ async function callLocalLlm(masked, ctx) {
126
+ const { baseUrl, model } = require_compliance.localLlmConfig();
127
+ const res = await fetch(`${baseUrl.replace(/\/$/, "")}/chat/completions`, {
128
+ method: "POST",
129
+ headers: { "Content-Type": "application/json" },
130
+ body: JSON.stringify({
131
+ model,
132
+ max_tokens: 500,
133
+ messages: [{
134
+ role: "user",
135
+ content: masked
136
+ }]
137
+ })
138
+ });
139
+ if (!res.ok) throw new Error(`Local LLM error ${res.status}`);
140
+ const data = await res.json();
141
+ const text = data.choices?.[0]?.message?.content;
142
+ if (!text) throw new Error("No text response from local LLM");
143
+ if (data.usage) recordCall(model, data.usage.prompt_tokens ?? 0, data.usage.completion_tokens ?? 0, ctx);
144
+ return text;
145
+ }
146
+ async function callLlm(prompt, ctx) {
147
+ const provider = require_compliance.llmProvider();
148
+ const client = provider === "anthropic" ? getClient() : null;
149
+ if (provider === "anthropic" && !client) throw new Error("ANTHROPIC_API_KEY not set");
150
+ const guarded = require_compliance.guardrailsEnabled() ? require_compliance.neutralizeUntrusted(prompt) : prompt;
151
+ const { masked, unmask } = require_compliance.piiMaskingEnabled() ? require_compliance.maskPii(guarded) : {
152
+ masked: guarded,
153
+ unmask: (t) => t
154
+ };
155
+ if (provider !== "anthropic") return llmCircuit.call(async () => unmask(guardLlmResponse(await callLocalLlm(masked, ctx))));
156
+ return llmCircuit.call(async () => {
157
+ const response = await client.messages.create({
158
+ model: MODEL,
159
+ max_tokens: 500,
160
+ messages: [{
161
+ role: "user",
162
+ content: masked
163
+ }]
164
+ });
165
+ const usage = response.usage;
166
+ if (usage) recordCall(MODEL, usage.input_tokens, usage.output_tokens, ctx);
167
+ const textBlock = response.content.find((b) => b.type === "text");
168
+ if (!textBlock || textBlock.type !== "text") throw new Error("No text response from LLM");
169
+ return unmask(guardLlmResponse(textBlock.text));
170
+ });
171
+ }
172
+ //#endregion
173
+ Object.defineProperty(exports, "callLlm", {
174
+ enumerable: true,
175
+ get: function() {
176
+ return callLlm;
177
+ }
178
+ });
179
+ Object.defineProperty(exports, "guardIsoDate", {
180
+ enumerable: true,
181
+ get: function() {
182
+ return guardIsoDate;
183
+ }
184
+ });
185
+ Object.defineProperty(exports, "llm_exports", {
186
+ enumerable: true,
187
+ get: function() {
188
+ return llm_exports;
189
+ }
190
+ });
191
+ Object.defineProperty(exports, "summarizeEmail", {
192
+ enumerable: true,
193
+ get: function() {
194
+ return summarizeEmail;
195
+ }
196
+ });
197
+
198
+ //# sourceMappingURL=llm-iijeXmgq.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-iijeXmgq.cjs","names":["Anthropic","localLlmConfig","llmProvider","guardrailsEnabled","neutralizeUntrusted","piiMaskingEnabled","maskPii"],"sources":["../src/core/resilience.ts","../src/core/input-guard.ts","../src/core/llm.ts"],"sourcesContent":["export interface RetryOptions {\n attempts: number;\n backoffMs: number;\n maxBackoffMs?: number;\n shouldRetry?: (err: Error) => boolean;\n}\n\nexport async function withRetry<T>(fn: () => Promise<T>, opts: RetryOptions): Promise<T> {\n const { attempts, backoffMs, maxBackoffMs, shouldRetry } = opts;\n let lastError!: Error;\n\n for (let attempt = 0; attempt < attempts; attempt++) {\n try {\n return await fn();\n } catch (err) {\n lastError = err as Error;\n if (shouldRetry && !shouldRetry(lastError)) throw lastError;\n if (attempt < attempts - 1) {\n const delay = maxBackoffMs\n ? Math.min(backoffMs * 2 ** attempt, maxBackoffMs)\n : backoffMs * 2 ** attempt;\n await new Promise((r) => setTimeout(r, delay));\n }\n }\n }\n throw lastError;\n}\n\nexport type CircuitState = \"closed\" | \"open\" | \"half-open\";\n\nexport interface CircuitBreakerOptions {\n threshold: number;\n timeoutMs: number;\n halfOpenAfter: number;\n}\n\nexport class CircuitBreaker {\n private failures = 0;\n private openedAt: number | null = null;\n private _state: CircuitState = \"closed\";\n\n constructor(private readonly opts: CircuitBreakerOptions) {}\n\n get state(): CircuitState {\n return this._state;\n }\n\n async call<T>(fn: () => Promise<T>): Promise<T> {\n if (this._state === \"open\") {\n const elapsed = Date.now() - (this.openedAt ?? 0);\n if (elapsed >= this.opts.halfOpenAfter) {\n this._state = \"half-open\";\n } else {\n throw new Error(\"Circuit open\");\n }\n }\n\n try {\n const result = await fn();\n // Success — reset\n this.failures = 0;\n this._state = \"closed\";\n this.openedAt = null;\n return result;\n } catch (err) {\n this.failures++;\n if (this._state === \"half-open\" || this.failures >= this.opts.threshold) {\n this._state = \"open\";\n this.openedAt = Date.now();\n this.failures = 0;\n }\n throw err;\n }\n }\n}\n","export interface StringGuardOptions {\n maxLen?: number;\n pattern?: RegExp;\n trim?: boolean;\n}\n\nexport function guardString(val: unknown, field: string, opts: StringGuardOptions = {}): string {\n if (typeof val !== \"string\") throw new Error(`${field}: expected string, got ${typeof val}`);\n const trimmed = opts.trim !== false ? val.trim() : val;\n if (opts.maxLen !== undefined && trimmed.length > opts.maxLen) {\n throw new Error(`${field}: exceeds max length ${opts.maxLen}`);\n }\n if (opts.pattern && !opts.pattern.test(trimmed)) {\n throw new Error(`${field}: invalid format`);\n }\n return trimmed;\n}\n\nexport interface NumberGuardOptions {\n min?: number;\n max?: number;\n}\n\nexport function guardNumber(val: unknown, field: string, opts: NumberGuardOptions = {}): number {\n if (typeof val !== \"number\" || !isFinite(val)) {\n throw new Error(\n `${field}: expected number, got ${typeof val === \"number\" ? \"NaN/Infinity\" : typeof val}`\n );\n }\n if (opts.min !== undefined && val < opts.min) {\n throw new Error(`${field}: must be >= ${opts.min}`);\n }\n if (opts.max !== undefined && val > opts.max) {\n throw new Error(`${field}: must be <= ${opts.max}`);\n }\n return val;\n}\n\nexport function guardPositiveInt(val: unknown, field: string): number {\n const n = guardNumber(val, field);\n if (!Number.isInteger(n)) throw new Error(`${field}: must be integer`);\n if (n < 1) throw new Error(`${field}: must be >= 1`);\n return n;\n}\n\nexport function guardIsoDate(val: unknown, field: string): string {\n if (typeof val !== \"string\" || !val) throw new Error(`${field}: invalid date`);\n const d = new Date(val);\n if (isNaN(d.getTime())) throw new Error(`${field}: invalid date`);\n // Reject clearly invalid month/day combinations (e.g., 2026-13-01)\n if (/^\\d{4}-\\d{2}-\\d{2}/.test(val)) {\n const [year, month, day] = val.slice(0, 10).split(\"-\").map(Number) as [number, number, number];\n if (month < 1 || month > 12 || day < 1 || day > 31) {\n throw new Error(`${field}: invalid date`);\n }\n // Cross-check with Date parsing\n const reparse = new Date(\n `${year}-${String(month).padStart(2, \"0\")}-${String(day).padStart(2, \"0\")}`\n );\n if (isNaN(reparse.getTime()) || reparse.getMonth() + 1 !== month) {\n throw new Error(`${field}: invalid date`);\n }\n }\n return val;\n}\n\nconst DEFAULT_LLM_MAX_BYTES = 512 * 1024; // 512 KB\n\nexport function guardLlmResponse(\n response: unknown,\n maxBytes: number = DEFAULT_LLM_MAX_BYTES\n): string {\n if (typeof response !== \"string\") {\n throw new Error(\"LLM response: expected string\");\n }\n const byteLen = Buffer.byteLength(response, \"utf-8\");\n if (byteLen > maxBytes) {\n throw new Error(`LLM response exceeds ${maxBytes} bytes (got ${byteLen})`);\n }\n return response;\n}\n","import Anthropic from \"@anthropic-ai/sdk\";\nimport { CircuitBreaker } from \"./resilience.js\";\nimport { guardLlmResponse } from \"./input-guard.js\";\nimport { maskPii, piiMaskingEnabled } from \"./pii.js\";\nimport { neutralizeUntrusted, guardrailsEnabled } from \"./guardrails.js\";\nimport { llmProvider, localLlmConfig } from \"./compliance.js\";\n\nconst MODEL = \"claude-haiku-4-5-20251001\";\n\nlet _client: Anthropic | null = null;\nlet llmCircuit = new CircuitBreaker({ threshold: 3, timeoutMs: 30_000, halfOpenAfter: 30_000 });\n\nexport function resetLlmCircuit(): void {\n llmCircuit = new CircuitBreaker({ threshold: 3, timeoutMs: 30_000, halfOpenAfter: 30_000 });\n}\n\nfunction getClient(): Anthropic | null {\n if (!process.env[\"ANTHROPIC_API_KEY\"]) return null;\n if (!_client) _client = new Anthropic();\n return _client;\n}\n\nexport interface EmailSummary {\n summary: string;\n sentiment: \"positive\" | \"neutral\" | \"negative\" | \"urgent\";\n nextSteps: string[];\n}\n\nexport interface CustomerMatch {\n slug: string | null;\n confidence: \"high\" | \"medium\" | \"low\";\n}\n\nfunction emailFallback(snippet: string): EmailSummary {\n return {\n summary: snippet.slice(0, 300),\n sentiment: \"neutral\",\n nextSteps: [],\n };\n}\n\nexport async function summarizeEmail(\n subject: string,\n snippet: string,\n from: string\n): Promise<EmailSummary> {\n const client = getClient();\n if (!client) return emailFallback(snippet);\n\n try {\n const response = await client.messages.create({\n model: MODEL,\n max_tokens: 200,\n system: [\n {\n type: \"text\",\n text: 'You are a CRM assistant. Extract structured information from email metadata.\\nReturn ONLY valid JSON matching: { \"summary\": string (2 sentences, German), \"sentiment\": \"positive\"|\"neutral\"|\"negative\"|\"urgent\", \"nextSteps\": string[] }',\n cache_control: { type: \"ephemeral\" },\n },\n ],\n messages: [\n {\n role: \"user\",\n content: `Subject: ${subject}\\nFrom: ${from}\\nContent: ${snippet}`,\n },\n ],\n });\n\n const textBlock = response.content.find((b) => b.type === \"text\");\n if (!textBlock || textBlock.type !== \"text\") return emailFallback(snippet);\n\n try {\n const parsed = JSON.parse(textBlock.text) as {\n summary: string;\n sentiment: \"positive\" | \"neutral\" | \"negative\" | \"urgent\";\n nextSteps: string[];\n };\n return parsed;\n } catch {\n return emailFallback(snippet);\n }\n } catch {\n return emailFallback(snippet);\n }\n}\n\nexport async function recognizeCustomer(\n transcriptContent: string,\n candidates: Array<{ slug: string; name: string }>\n): Promise<CustomerMatch> {\n if (candidates.length === 0) return { slug: null, confidence: \"low\" };\n\n const client = getClient();\n if (!client) return { slug: null, confidence: \"low\" };\n\n try {\n const response = await client.messages.create({\n model: MODEL,\n max_tokens: 100,\n system: [\n {\n type: \"text\",\n text: 'You are a CRM assistant. Match a meeting transcript to the most likely customer.\\nReturn ONLY valid JSON: { \"slug\": string|null, \"confidence\": \"high\"|\"medium\"|\"low\" }\\nslug must be one of the provided candidates or null if no match.',\n cache_control: { type: \"ephemeral\" },\n },\n ],\n messages: [\n {\n role: \"user\",\n content: `Available customers: ${candidates.map((c) => `${c.slug} (${c.name})`).join(\", \")}\\nTranscript (first 1000 chars): ${transcriptContent.slice(0, 1000)}`,\n },\n ],\n });\n\n const textBlock = response.content.find((b) => b.type === \"text\");\n if (!textBlock || textBlock.type !== \"text\") return { slug: null, confidence: \"low\" };\n\n try {\n const parsed = JSON.parse(textBlock.text) as {\n slug: string | null;\n confidence: \"high\" | \"medium\" | \"low\";\n };\n return parsed;\n } catch {\n return { slug: null, confidence: \"low\" };\n }\n } catch {\n return { slug: null, confidence: \"low\" };\n }\n}\n\nexport function resetLlmClient(): void {\n _client = null;\n}\n\nfunction recordCall(\n model: string,\n inputTokens: number,\n outputTokens: number,\n ctx?: { slug?: string; tool?: string }\n): void {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n void import(\"./usage.js\").then(({ recordUsage }) =>\n recordUsage(dataDir, {\n ...(ctx?.slug ? { slug: ctx.slug } : {}),\n ...(ctx?.tool ? { tool: ctx.tool } : {}),\n model,\n inputTokens,\n outputTokens,\n })\n );\n}\n\n/**\n * Local-LLM path (D17): call an OpenAI-compatible endpoint (Ollama/local) via\n * fetch — no extra dependency — so customer data can stay on-machine. Usage is\n * still recorded for cost/observability parity with the Anthropic path.\n */\nasync function callLocalLlm(\n masked: string,\n ctx?: { slug?: string; tool?: string }\n): Promise<string> {\n const { baseUrl, model } = localLlmConfig();\n const res = await fetch(`${baseUrl.replace(/\\/$/, \"\")}/chat/completions`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n model,\n max_tokens: 500,\n messages: [{ role: \"user\", content: masked }],\n }),\n });\n if (!res.ok) throw new Error(`Local LLM error ${res.status}`);\n const data = (await res.json()) as {\n choices?: Array<{ message?: { content?: string } }>;\n usage?: { prompt_tokens?: number; completion_tokens?: number };\n };\n const text = data.choices?.[0]?.message?.content;\n if (!text) throw new Error(\"No text response from local LLM\");\n if (data.usage)\n recordCall(model, data.usage.prompt_tokens ?? 0, data.usage.completion_tokens ?? 0, ctx);\n return text;\n}\n\nexport async function callLlm(\n prompt: string,\n ctx?: { slug?: string; tool?: string }\n): Promise<string> {\n const provider = llmProvider();\n const client = provider === \"anthropic\" ? getClient() : null;\n if (provider === \"anthropic\" && !client) throw new Error(\"ANTHROPIC_API_KEY not set\");\n\n // Opt-in guardrails (neutralize prompt-injection) + PII masking, then restore.\n const guarded = guardrailsEnabled() ? neutralizeUntrusted(prompt) : prompt;\n const { masked, unmask } = piiMaskingEnabled()\n ? maskPii(guarded)\n : { masked: guarded, unmask: (t: string) => t };\n\n if (provider !== \"anthropic\") {\n return llmCircuit.call(async () => unmask(guardLlmResponse(await callLocalLlm(masked, ctx))));\n }\n\n return llmCircuit.call(async () => {\n const response = await client!.messages.create({\n model: MODEL,\n max_tokens: 500,\n messages: [{ role: \"user\", content: masked }],\n });\n\n // Token-cost observability (D3): record usage per customer/tool.\n const usage = response.usage;\n if (usage) recordCall(MODEL, usage.input_tokens, usage.output_tokens, ctx);\n\n const textBlock = response.content.find((b) => b.type === \"text\");\n if (!textBlock || textBlock.type !== \"text\") throw new Error(\"No text response from LLM\");\n return unmask(guardLlmResponse(textBlock.text));\n });\n}\n\nexport type FieldMapping = Record<string, string | null>;\n\n// Alias table: CRM field name → list of CSV column patterns (lowercased substrings)\nconst FIELD_ALIASES: Record<string, string[]> = {\n name: [\n \"company name\",\n \"company\",\n \"organization\",\n \"organisation\",\n \"account name\",\n \"name\",\n \"firma\",\n ],\n email: [\"email address\", \"e-mail\", \"email\", \"e-mail address\", \"mail\"],\n domain: [\"company domain\", \"website\", \"domain\", \"url\", \"web\", \"homepage\"],\n phone: [\"phone number\", \"phone\", \"tel\", \"telephone\", \"mobile\", \"cell\"],\n industry: [\"industry\", \"sector\", \"branche\", \"vertical\"],\n primary_contact: [\"contact name\", \"contact person\", \"contact\", \"ansprechpartner\", \"kontakt\"],\n timezone: [\"timezone\", \"time zone\", \"tz\"],\n // Import-specific fields\n notes: [\n \"notes\",\n \"description\",\n \"body\",\n \"comment\",\n \"details\",\n \"note\",\n \"inhalt\",\n \"subject\",\n \"summary\",\n ],\n date: [\"activity date\", \"activity_date\", \"due date\", \"date\", \"created_at\", \"timestamp\", \"time\"],\n activityType: [\"activity type\", \"activity_type\", \"activitytype\", \"type\", \"category\", \"art\"],\n sourceId: [\n \"record id\",\n \"record_id\",\n \"source id\",\n \"source_id\",\n \"external id\",\n \"external_id\",\n \"activity id\",\n ],\n};\n\nexport function mapCsvFieldsHeuristic(headers: string[], targetFields: string[]): FieldMapping {\n const result: FieldMapping = {};\n const usedHeaders = new Set<string>();\n\n for (const field of targetFields) {\n const aliases = FIELD_ALIASES[field] ?? [field];\n let matched: string | null = null;\n\n for (const header of headers) {\n if (usedHeaders.has(header)) continue;\n const lower = header.toLowerCase();\n if (aliases.some((alias) => lower === alias || lower.includes(alias))) {\n matched = header;\n break;\n }\n }\n\n result[field] = matched;\n if (matched) usedHeaders.add(matched);\n }\n\n return result;\n}\n\nconst FIELD_SEMANTICS = `CRM field semantics:\n- name: Company or organization name (required)\n- email: Contact email address\n- domain: Company website or domain (e.g. \"acme.com\")\n- notes: Interaction notes, description, or subject text\n- date: Date of activity/interaction (ISO 8601 or YYYY-MM-DD)\n- activityType: Type of interaction — Call, Email, Meeting, Note\n- sourceId: Unique ID from the source system used for deduplication`;\n\nexport async function mapCsvFields(\n headers: string[],\n targetFields: string[]\n): Promise<FieldMapping> {\n const client = getClient();\n if (!client) return mapCsvFieldsHeuristic(headers, targetFields);\n\n try {\n const response = await client.messages.create({\n model: MODEL,\n max_tokens: 300,\n system: [\n {\n type: \"text\",\n text: `You are a CRM data-import assistant. Map CSV column headers to internal CRM field names.\n\n${FIELD_SEMANTICS}\n\nRules:\n1. Return ONLY valid JSON: { \"<crmField>\": \"<csvColumn>\" | null, ... }\n2. Every requested CRM field must appear as a key in the response.\n3. Use null when no column is a reasonable match.\n4. Each CSV column may only be assigned to one CRM field.\n5. Only use column names that appear exactly in the provided CSV columns list.`,\n cache_control: { type: \"ephemeral\" },\n },\n ],\n messages: [\n {\n role: \"user\",\n content: `CSV columns: ${JSON.stringify(headers)}\\nMap to CRM fields: ${JSON.stringify(targetFields)}`,\n },\n ],\n });\n\n const textBlock = response.content.find((b) => b.type === \"text\");\n if (!textBlock || textBlock.type !== \"text\")\n return mapCsvFieldsHeuristic(headers, targetFields);\n\n try {\n const raw = JSON.parse(\n textBlock.text\n .replace(/^```(?:json)?\\n?/, \"\")\n .replace(/\\n?```$/, \"\")\n .trim()\n ) as Record<string, string | null>;\n const validated: FieldMapping = {};\n const headerSet = new Set(headers);\n for (const field of targetFields) {\n const col = raw[field] ?? null;\n validated[field] = col !== null && headerSet.has(col) ? col : null;\n }\n // Require at least 'name' to be mapped; fall back otherwise\n if (!validated[\"name\"]) return mapCsvFieldsHeuristic(headers, targetFields);\n return validated;\n } catch {\n return mapCsvFieldsHeuristic(headers, targetFields);\n }\n } catch {\n return mapCsvFieldsHeuristic(headers, targetFields);\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+
3
+ //#region src/mcp/server.d.ts
4
+ declare function surveyThankYouPage(score: number, comment?: string): string;
5
+ declare function createMcpServer(): McpServer;
6
+ declare function startStdio(): Promise<void>;
7
+ declare function startHttp(port?: number): Promise<void>;
8
+ //# sourceMappingURL=server.d.ts.map
9
+
10
+ //#endregion
11
+ export { createMcpServer, startHttp, startStdio, surveyThankYouPage };
12
+ //# sourceMappingURL=mcp-CdTJWTJf.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-CdTJWTJf.d.cts","names":[],"sources":["../src/mcp/server.ts"],"mappings":";;;iBAoFgB,kBAAA;iBAWA,eAAA,CAAA,GAAmB;AAXnB,iBAgFM,UAAA,CAAA,CAhFY,EAgFE,OAhFF,CAAA,IAAA,CAAA;AAWlB,iBA8EM,SAAA,CA9Ea,IAAS,CAAT,EAAS,MAAA,CAAA,EA8EE,OA9EF,CAAA,IAAA,CAAA;AAqE5C"}
@@ -0,0 +1,12 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+
3
+ //#region src/mcp/server.d.ts
4
+ declare function surveyThankYouPage(score: number, comment?: string): string;
5
+ declare function createMcpServer(): McpServer;
6
+ declare function startStdio(): Promise<void>;
7
+ declare function startHttp(port?: number): Promise<void>;
8
+ //# sourceMappingURL=server.d.ts.map
9
+
10
+ //#endregion
11
+ export { createMcpServer, startHttp, startStdio, surveyThankYouPage };
12
+ //# sourceMappingURL=mcp-CdTJWTJf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-CdTJWTJf.d.ts","names":[],"sources":["../src/mcp/server.ts"],"mappings":";;;iBAoFgB,kBAAA;iBAWA,eAAA,CAAA,GAAmB;AAXnB,iBAgFM,UAAA,CAAA,CAhFY,EAgFE,OAhFF,CAAA,IAAA,CAAA;AAWlB,iBA8EM,SAAA,CA9Ea,IAAS,CAAT,EAAS,MAAA,CAAA,EA8EE,OA9EF,CAAA,IAAA,CAAA;AAqE5C"}