@datasynx/agentic-crm 1.0.0 → 1.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/README.md +8 -1
- package/dist/{ask-D8iYqDAr.js → ask-CDysGnRg.js} +2 -2
- package/dist/{ask-D8iYqDAr.js.map → ask-CDysGnRg.js.map} +1 -1
- package/dist/attachments-CX2GAtsw.cjs +517 -0
- package/dist/attachments-CX2GAtsw.cjs.map +1 -0
- package/dist/attachments-D207gXfN.js +514 -0
- package/dist/attachments-D207gXfN.js.map +1 -0
- package/dist/attachments-rLa96rOK.js +514 -0
- package/dist/attachments-rLa96rOK.js.map +1 -0
- package/dist/chunk-BfDYWZQ8.cjs +32 -0
- package/dist/chunk-BfDYWZQ8.cjs.map +1 -0
- package/dist/chunk-BhUZmQg5.js +32 -0
- package/dist/chunk-BhUZmQg5.js.map +1 -0
- package/dist/chunk-ChC83jai.js +2 -0
- package/dist/chunk-e_w8qqtP.js +32 -0
- package/dist/chunk-e_w8qqtP.js.map +1 -0
- package/dist/cli.js +16 -15
- package/dist/cli.js.map +1 -1
- package/dist/daemon/worker.js +3 -3
- package/dist/email-body-BFSRa0AW.cjs +42 -0
- package/dist/email-body-BFSRa0AW.cjs.map +1 -0
- package/dist/email-body-BOd7U-D2.js +42 -0
- package/dist/email-body-BOd7U-D2.js.map +1 -0
- package/dist/{gmail-sync-DueE6tl5.js → gmail-sync-B4Iu3AQb.js} +45 -15
- package/dist/gmail-sync-B4Iu3AQb.js.map +1 -0
- package/dist/{gmail-sync-GEy3oVvw.cjs → gmail-sync-BpSVESSe.cjs} +45 -15
- package/dist/gmail-sync-BpSVESSe.cjs.map +1 -0
- package/dist/{gmail-sync-C-NmibzS.js → gmail-sync-DIbrPnTK.js} +45 -15
- package/dist/gmail-sync-DIbrPnTK.js.map +1 -0
- package/dist/{gmail-webhook-handler-kGKpbY9h.js → gmail-webhook-handler-BzOFbvgh.js} +2 -2
- package/dist/{gmail-webhook-handler-kGKpbY9h.js.map → gmail-webhook-handler-BzOFbvgh.js.map} +1 -1
- package/dist/{gmail-webhook-handler-B26COilD.js → gmail-webhook-handler-CvSDW_Js.js} +1 -1
- package/dist/{google-drive-sync-D1n7WKZn.js → google-drive-sync-B_I1d54Y.js} +2 -2
- package/dist/{google-drive-sync-D1n7WKZn.js.map → google-drive-sync-B_I1d54Y.js.map} +1 -1
- package/dist/html-BaeOCZKE.js +36 -0
- package/dist/html-BaeOCZKE.js.map +1 -0
- package/dist/html-CmOku6jS.cjs +47 -0
- package/dist/html-CmOku6jS.cjs.map +1 -0
- package/dist/{import-hubspot-DB4n89jy.js → import-hubspot-CTId9IGV.js} +2 -2
- package/dist/{import-hubspot-DB4n89jy.js.map → import-hubspot-CTId9IGV.js.map} +1 -1
- package/dist/{index-pY7tYXwH.d.cts → index-BAutNcAT.d.cts} +13 -9
- package/dist/index-BAutNcAT.d.cts.map +1 -0
- package/dist/{index-B0IMMrp_.d.ts → index-FzDsNSSb.d.ts} +5 -1
- package/dist/index-FzDsNSSb.d.ts.map +1 -0
- package/dist/index.d.cts +13 -9
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/{interactions-writer-RJB8SWf2.js → interactions-writer-B2y-73lh.js} +1 -1
- package/dist/{interactions-writer-DbSyI2rt.js → interactions-writer-B8XAzdqR.js} +3 -2
- package/dist/interactions-writer-B8XAzdqR.js.map +1 -0
- package/dist/{interactions-writer-a2yzBd7T.cjs → interactions-writer-BRJNrefF.cjs} +3 -2
- package/dist/interactions-writer-BRJNrefF.cjs.map +1 -0
- package/dist/{interactions-writer-BZzUIgJd.js → interactions-writer-ZQcpFOh9.js} +3 -2
- package/dist/interactions-writer-ZQcpFOh9.js.map +1 -0
- package/dist/{knowledge-base-DHNc4hVj.js → knowledge-base--063Kpa3.js} +9 -7
- package/dist/{knowledge-base-DHNc4hVj.js.map → knowledge-base--063Kpa3.js.map} +1 -1
- package/dist/mcp.cjs +44 -22
- package/dist/mcp.cjs.map +1 -1
- package/dist/mcp.js +44 -22
- package/dist/mcp.js.map +1 -1
- package/dist/{microsoft-calendar-jIu9K5zX.js → microsoft-calendar-BgVR8GDv.js} +3 -3
- package/dist/{microsoft-calendar-jIu9K5zX.js.map → microsoft-calendar-BgVR8GDv.js.map} +1 -1
- package/dist/{microsoft-sync-R_r8HL-B.js → microsoft-sync-D30_XksI.js} +3 -3
- package/dist/{microsoft-sync-R_r8HL-B.js.map → microsoft-sync-D30_XksI.js.map} +1 -1
- package/dist/{nba-mTJ4yEqD.js → nba-DwdfM93s.js} +2 -2
- package/dist/{nba-mTJ4yEqD.js.map → nba-DwdfM93s.js.map} +1 -1
- package/dist/{server-DqSMYhSA.js → server-DoRPPOeR.js} +39 -19
- package/dist/server-DoRPPOeR.js.map +1 -0
- package/dist/{transcript-watcher-0mh2ZhmH.js → transcript-watcher-BoClrJAz.js} +2 -2
- package/dist/{transcript-watcher-0mh2ZhmH.js.map → transcript-watcher-BoClrJAz.js.map} +1 -1
- package/package.json +12 -1
- package/dist/gmail-sync-C-NmibzS.js.map +0 -1
- package/dist/gmail-sync-DueE6tl5.js.map +0 -1
- package/dist/gmail-sync-GEy3oVvw.cjs.map +0 -1
- package/dist/index-B0IMMrp_.d.ts.map +0 -1
- package/dist/index-pY7tYXwH.d.cts.map +0 -1
- package/dist/interactions-writer-BZzUIgJd.js.map +0 -1
- package/dist/interactions-writer-DbSyI2rt.js.map +0 -1
- package/dist/interactions-writer-a2yzBd7T.cjs.map +0 -1
- package/dist/server-DqSMYhSA.js.map +0 -1
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//#region src/core/chunk.ts
|
|
2
|
+
/**
|
|
3
|
+
* Split long text into overlapping chunks for embedding/indexing. Each chunk is
|
|
4
|
+
* at most `maxChars`; chunks overlap by `overlap` characters so a query that
|
|
5
|
+
* straddles a boundary still matches. Splits prefer the nearest whitespace
|
|
6
|
+
* before the limit to avoid cutting words mid-token. Short text returns a single
|
|
7
|
+
* trimmed chunk; empty/whitespace-only text returns no chunks.
|
|
8
|
+
*/
|
|
9
|
+
function chunkText(text, options = {}) {
|
|
10
|
+
const maxChars = options.maxChars ?? 1500;
|
|
11
|
+
const overlap = Math.min(options.overlap ?? 150, Math.floor(maxChars / 2));
|
|
12
|
+
const trimmed = text.trim();
|
|
13
|
+
if (!trimmed) return [];
|
|
14
|
+
if (trimmed.length <= maxChars) return [trimmed];
|
|
15
|
+
const chunks = [];
|
|
16
|
+
let start = 0;
|
|
17
|
+
while (start < trimmed.length) {
|
|
18
|
+
let end = Math.min(start + maxChars, trimmed.length);
|
|
19
|
+
if (end < trimmed.length) {
|
|
20
|
+
const lastSpace = trimmed.lastIndexOf(" ", end);
|
|
21
|
+
if (lastSpace > start + maxChars / 2) end = lastSpace;
|
|
22
|
+
}
|
|
23
|
+
chunks.push(trimmed.slice(start, end).trim());
|
|
24
|
+
if (end >= trimmed.length) break;
|
|
25
|
+
start = end - overlap;
|
|
26
|
+
}
|
|
27
|
+
return chunks.filter((c) => c.length > 0);
|
|
28
|
+
}
|
|
29
|
+
//#endregion
|
|
30
|
+
export { chunkText };
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=chunk-e_w8qqtP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk-e_w8qqtP.js","names":[],"sources":["../src/core/chunk.ts"],"sourcesContent":["// src/core/chunk.ts\n\nexport interface ChunkOptions {\n /** Target maximum characters per chunk. */\n maxChars?: number;\n /** Characters of overlap carried from the end of one chunk into the next. */\n overlap?: number;\n}\n\n/**\n * Split long text into overlapping chunks for embedding/indexing. Each chunk is\n * at most `maxChars`; chunks overlap by `overlap` characters so a query that\n * straddles a boundary still matches. Splits prefer the nearest whitespace\n * before the limit to avoid cutting words mid-token. Short text returns a single\n * trimmed chunk; empty/whitespace-only text returns no chunks.\n */\nexport function chunkText(text: string, options: ChunkOptions = {}): string[] {\n const maxChars = options.maxChars ?? 1500;\n const overlap = Math.min(options.overlap ?? 150, Math.floor(maxChars / 2));\n const trimmed = text.trim();\n if (!trimmed) return [];\n if (trimmed.length <= maxChars) return [trimmed];\n\n const chunks: string[] = [];\n let start = 0;\n while (start < trimmed.length) {\n let end = Math.min(start + maxChars, trimmed.length);\n // Prefer breaking on whitespace, but only if it doesn't shrink the chunk too much.\n if (end < trimmed.length) {\n const lastSpace = trimmed.lastIndexOf(\" \", end);\n if (lastSpace > start + maxChars / 2) end = lastSpace;\n }\n chunks.push(trimmed.slice(start, end).trim());\n if (end >= trimmed.length) break;\n start = end - overlap;\n }\n return chunks.filter((c) => c.length > 0);\n}\n"],"mappings":";;;;;;;;AAgBA,SAAgB,UAAU,MAAc,UAAwB,CAAC,GAAa;CAC5E,MAAM,WAAW,QAAQ,YAAY;CACrC,MAAM,UAAU,KAAK,IAAI,QAAQ,WAAW,KAAK,KAAK,MAAM,WAAW,CAAC,CAAC;CACzE,MAAM,UAAU,KAAK,KAAK;CAC1B,IAAI,CAAC,SAAS,OAAO,CAAC;CACtB,IAAI,QAAQ,UAAU,UAAU,OAAO,CAAC,OAAO;CAE/C,MAAM,SAAmB,CAAC;CAC1B,IAAI,QAAQ;CACZ,OAAO,QAAQ,QAAQ,QAAQ;EAC7B,IAAI,MAAM,KAAK,IAAI,QAAQ,UAAU,QAAQ,MAAM;EAEnD,IAAI,MAAM,QAAQ,QAAQ;GACxB,MAAM,YAAY,QAAQ,YAAY,KAAK,GAAG;GAC9C,IAAI,YAAY,QAAQ,WAAW,GAAG,MAAM;EAC9C;EACA,OAAO,KAAK,QAAQ,MAAM,OAAO,GAAG,EAAE,KAAK,CAAC;EAC5C,IAAI,OAAO,QAAQ,QAAQ;EAC3B,QAAQ,MAAM;CAChB;CACA,OAAO,OAAO,QAAQ,MAAM,EAAE,SAAS,CAAC;AAC1C"}
|
package/dist/cli.js
CHANGED
|
@@ -5,12 +5,12 @@ import { i as writeJsonFile } from "./json-store-WWsFzXub.js";
|
|
|
5
5
|
import { a as warning, i as success, n as error, r as info, t as bold } from "./colors-BG07TZQz.js";
|
|
6
6
|
import { n as getSession } from "./session-store-CEa39Dxs.js";
|
|
7
7
|
import { i as sessionCommand, r as readAllSessions } from "./session-BgGDyP2C.js";
|
|
8
|
-
import { a as searchKbSimple, i as listKbArticles, n as getKbArticle, o as writeKbArticle, s as CAPABILITIES_TEXT, t as deleteKbArticle } from "./knowledge-base
|
|
8
|
+
import { a as searchKbSimple, i as listKbArticles, n as getKbArticle, o as writeKbArticle, s as CAPABILITIES_TEXT, t as deleteKbArticle } from "./knowledge-base--063Kpa3.js";
|
|
9
9
|
import { a as restoreCommand, t as backupCommand } from "./backup-CTlIxUdO.js";
|
|
10
10
|
import { n as readSyncState } from "./sync-state-DMZgzpez.js";
|
|
11
11
|
import { n as readUnmatched } from "./unmatched-transcripts-DC-VQ9YS.js";
|
|
12
12
|
import { t as AgentConfigSchema } from "./agent-config-zPvcqu07.js";
|
|
13
|
-
import { n as appendInteraction, t as InteractionDedup } from "./interactions-writer-
|
|
13
|
+
import { n as appendInteraction, t as InteractionDedup } from "./interactions-writer-B8XAzdqR.js";
|
|
14
14
|
import { i as writeAuditEntry, n as getActor, r as readAuditLog, t as filterAuditLog } from "./audit-log-DNMY9mUZ.js";
|
|
15
15
|
import { d as setActorRole, i as canWrite, s as getRbacConfig } from "./rbac-msmBc_tK.js";
|
|
16
16
|
import { t as withJsonFile } from "./file-lock-CcHotQkZ.js";
|
|
@@ -240,10 +240,10 @@ mcpCommand.command("start").description("Start MCP server (stdio by default)").o
|
|
|
240
240
|
if (opts.http) {
|
|
241
241
|
const port = parseInt(opts.port, 10);
|
|
242
242
|
console.error(info(`Starting MCP server in HTTP mode on port ${port}...`));
|
|
243
|
-
const { startHttp } = await import("./server-
|
|
243
|
+
const { startHttp } = await import("./server-DoRPPOeR.js");
|
|
244
244
|
await startHttp(port);
|
|
245
245
|
} else {
|
|
246
|
-
const { startStdio } = await import("./server-
|
|
246
|
+
const { startStdio } = await import("./server-DoRPPOeR.js");
|
|
247
247
|
await startStdio();
|
|
248
248
|
}
|
|
249
249
|
});
|
|
@@ -1604,7 +1604,7 @@ const initCommand = new Command("init").description("Initialize CRM and configur
|
|
|
1604
1604
|
});
|
|
1605
1605
|
//#endregion
|
|
1606
1606
|
//#region src/commands/sync.ts
|
|
1607
|
-
const syncCommand = new Command("sync").argument("<slug>", "Customer slug to sync").description("Sync Gmail and transcripts for a customer").option("--since <date>", "Only sync emails/files after this date (YYYY-MM-DD)").option("--gmail", "Sync Gmail only").option("--transcripts", "Sync transcripts only").option("--provider <provider>", "Sync provider: gmail | microsoft | transcripts").action(async (slug, opts) => {
|
|
1607
|
+
const syncCommand = new Command("sync").argument("<slug>", "Customer slug to sync").description("Sync Gmail and transcripts for a customer").option("--since <date>", "Only sync emails/files after this date (YYYY-MM-DD)").option("--gmail", "Sync Gmail only").option("--transcripts", "Sync transcripts only").option("--provider <provider>", "Sync provider: gmail | microsoft | transcripts").option("--no-attachments", "Skip downloading/converting/indexing email attachments").action(async (slug, opts) => {
|
|
1608
1608
|
const dataDir = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
1609
1609
|
const customerDir = path.join(dataDir, "customers", slug);
|
|
1610
1610
|
if (!fs.existsSync(customerDir)) {
|
|
@@ -1631,13 +1631,14 @@ const syncCommand = new Command("sync").argument("<slug>", "Customer slug to syn
|
|
|
1631
1631
|
else try {
|
|
1632
1632
|
console.log(info(` Syncing Gmail for ${bold(slug)}...`));
|
|
1633
1633
|
const { getGmailAuth } = await import("./gmail-auth-OComS92L.js");
|
|
1634
|
-
const { syncGmail: doGmailSync } = await import("./gmail-sync-
|
|
1634
|
+
const { syncGmail: doGmailSync } = await import("./gmail-sync-B4Iu3AQb.js");
|
|
1635
1635
|
const result = await doGmailSync({
|
|
1636
1636
|
slug,
|
|
1637
1637
|
dataDir,
|
|
1638
1638
|
auth: await getGmailAuth(credPath, tokenPath),
|
|
1639
1639
|
query: sources.gmail.query,
|
|
1640
|
-
since
|
|
1640
|
+
since,
|
|
1641
|
+
includeAttachments: opts.attachments !== false
|
|
1641
1642
|
});
|
|
1642
1643
|
totalSynced += result.synced;
|
|
1643
1644
|
console.log(success(` ✓ Gmail: +${result.synced} synced, ${result.skipped} skipped`));
|
|
@@ -1651,7 +1652,7 @@ const syncCommand = new Command("sync").argument("<slug>", "Customer slug to syn
|
|
|
1651
1652
|
const token = await getMicrosoftToken(dataDir);
|
|
1652
1653
|
if (!token) console.log(info(" Microsoft: no token found (.agentic/microsoft-token.json)"));
|
|
1653
1654
|
else {
|
|
1654
|
-
const { syncMicrosoft: doMsSync } = await import("./microsoft-sync-
|
|
1655
|
+
const { syncMicrosoft: doMsSync } = await import("./microsoft-sync-D30_XksI.js");
|
|
1655
1656
|
const emailResult = await doMsSync({
|
|
1656
1657
|
slug,
|
|
1657
1658
|
dataDir,
|
|
@@ -1660,7 +1661,7 @@ const syncCommand = new Command("sync").argument("<slug>", "Customer slug to syn
|
|
|
1660
1661
|
});
|
|
1661
1662
|
totalSynced += emailResult.synced;
|
|
1662
1663
|
console.log(success(` ✓ Microsoft Email: +${emailResult.synced} synced, ${emailResult.skipped} skipped`));
|
|
1663
|
-
const { syncMicrosoftCalendar } = await import("./microsoft-calendar-
|
|
1664
|
+
const { syncMicrosoftCalendar } = await import("./microsoft-calendar-BgVR8GDv.js");
|
|
1664
1665
|
const calResult = await syncMicrosoftCalendar({
|
|
1665
1666
|
slug,
|
|
1666
1667
|
dataDir,
|
|
@@ -1678,7 +1679,7 @@ const syncCommand = new Command("sync").argument("<slug>", "Customer slug to syn
|
|
|
1678
1679
|
if (fs.existsSync(agenticSourcesPath)) try {
|
|
1679
1680
|
const agenticSources = JSON.parse(fs.readFileSync(agenticSourcesPath, "utf-8"));
|
|
1680
1681
|
if (agenticSources.transcripts?.enabled && agenticSources.transcripts.paths?.length) {
|
|
1681
|
-
const { processTranscriptFile } = await import("./transcript-watcher-
|
|
1682
|
+
const { processTranscriptFile } = await import("./transcript-watcher-BoClrJAz.js");
|
|
1682
1683
|
const exts = agenticSources.transcripts.extensions ?? [".txt", ".vtt"];
|
|
1683
1684
|
let transcriptSynced = 0;
|
|
1684
1685
|
for (const watchPath of agenticSources.transcripts.paths) {
|
|
@@ -1707,7 +1708,7 @@ const syncCommand = new Command("sync").argument("<slug>", "Customer slug to syn
|
|
|
1707
1708
|
if (!accessToken) console.log(info(" Google Drive: accessToken not found in token file"));
|
|
1708
1709
|
else {
|
|
1709
1710
|
console.log(info(` Syncing Google Drive for ${bold(slug)}...`));
|
|
1710
|
-
const { syncGoogleDriveFiles } = await import("./google-drive-sync-
|
|
1711
|
+
const { syncGoogleDriveFiles } = await import("./google-drive-sync-B_I1d54Y.js");
|
|
1711
1712
|
const result = await syncGoogleDriveFiles({
|
|
1712
1713
|
slug,
|
|
1713
1714
|
dataDir,
|
|
@@ -2229,7 +2230,7 @@ async function runImport(sourcePath, opts, dataDir) {
|
|
|
2229
2230
|
if (opts.from === "salesforce" && opts.mode === "api") return runSalesforceApiImport(opts, dir);
|
|
2230
2231
|
if (opts.from === "pipedrive" && opts.mode === "api") return runPipedriveApiImport(opts, dir);
|
|
2231
2232
|
if (opts.from === "hubspot" && sourcePath && fs.existsSync(sourcePath) && fs.statSync(sourcePath).isDirectory()) {
|
|
2232
|
-
const { runHubSpotCsvImport } = await import("./import-hubspot-
|
|
2233
|
+
const { runHubSpotCsvImport } = await import("./import-hubspot-CTId9IGV.js");
|
|
2233
2234
|
const r = await runHubSpotCsvImport(sourcePath, dir, {
|
|
2234
2235
|
...opts.dryRun ? { dryRun: true } : {},
|
|
2235
2236
|
...opts.resume ? { resume: true } : {},
|
|
@@ -2745,7 +2746,7 @@ const importCommand = new Command("import").description("Import customers and in
|
|
|
2745
2746
|
if (hs && rep) ownerMap[hs.trim()] = rep.trim();
|
|
2746
2747
|
}
|
|
2747
2748
|
if (opts.analyze && opts.from === "hubspot" && sourcePath) {
|
|
2748
|
-
const { analyzeHubSpotExport } = await import("./import-hubspot-
|
|
2749
|
+
const { analyzeHubSpotExport } = await import("./import-hubspot-CTId9IGV.js");
|
|
2749
2750
|
const analysis = await analyzeHubSpotExport(sourcePath);
|
|
2750
2751
|
console.log(bold("\nDatasynxOpenCRM — HubSpot Import Analysis"));
|
|
2751
2752
|
console.log("==========================================");
|
|
@@ -4229,7 +4230,7 @@ function dataDir$5() {
|
|
|
4229
4230
|
return process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4230
4231
|
}
|
|
4231
4232
|
const askCommand = new Command("ask").description("Ask your CRM a natural-language question").argument("<question>", "The question").option("--slug <slug>", "Scope to a customer").action(async (question, opts) => {
|
|
4232
|
-
const { askCrm } = await import("./ask-
|
|
4233
|
+
const { askCrm } = await import("./ask-CDysGnRg.js");
|
|
4233
4234
|
const res = await askCrm(dataDir$5(), question, opts.slug);
|
|
4234
4235
|
if (res.answer) {
|
|
4235
4236
|
console.log(bold("Answer:"));
|
|
@@ -4248,7 +4249,7 @@ function dataDir$4() {
|
|
|
4248
4249
|
return process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4249
4250
|
}
|
|
4250
4251
|
const nbaCommand = new Command("nba").description("Next-best-action recommendations for a customer").argument("<slug>", "Customer slug").action(async (slug) => {
|
|
4251
|
-
const { nextBestAction } = await import("./nba-
|
|
4252
|
+
const { nextBestAction } = await import("./nba-DwdfM93s.js");
|
|
4252
4253
|
const actions = await nextBestAction(dataDir$4(), slug);
|
|
4253
4254
|
if (actions.length === 0) {
|
|
4254
4255
|
console.log(info("No recommendations."));
|