@bike4mind/cli 0.2.29-cli-resume-command.18763 → 0.2.29-feature-b4m-pi.18846
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 +1 -1
- package/dist/HydrationEngine-JFMYWWM6.js +9 -0
- package/dist/{artifactExtractor-36XHJYOZ.js → artifactExtractor-TFGRIG2Y.js} +1 -1
- package/dist/{chunk-ZEMWV6IR.js → chunk-2UFCM2T4.js} +2 -2
- package/dist/{chunk-UNOJBVD2.js → chunk-A3HXNIIZ.js} +4 -2
- package/dist/{chunk-JJBDHUGY.js → chunk-MUWN5G77.js} +2 -2
- package/dist/chunk-NHP3UPYU.js +765 -0
- package/dist/{chunk-VGYTNJXN.js → chunk-SZRU4SFM.js} +2 -2
- package/dist/{chunk-XJRPAAUS.js → chunk-WVQTZODT.js} +853 -197
- package/dist/{create-NGI7IIQ4.js → create-NFJQG4TE.js} +3 -3
- package/dist/index.js +856 -29
- package/dist/{llmMarkdownGenerator-JDYKJUEC.js → llmMarkdownGenerator-JCNIDUGQ.js} +1 -1
- package/dist/{markdownGenerator-QXBC2EW5.js → markdownGenerator-WWVICHFP.js} +1 -1
- package/dist/{mementoService-X35OMHVC.js → mementoService-UEMQTBIG.js} +3 -3
- package/dist/{src-CBU6EAO3.js → src-4V3OBX4H.js} +2 -2
- package/dist/{src-6NIYIWZD.js → src-DEQX27QN.js} +137 -1
- package/dist/{subtractCredits-RL6JVDMI.js → subtractCredits-RLGUIO6U.js} +3 -3
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -5,7 +5,8 @@ import {
|
|
|
5
5
|
getEffectiveApiKey,
|
|
6
6
|
getOpenWeatherKey,
|
|
7
7
|
getSerperKey
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-SZRU4SFM.js";
|
|
9
|
+
import "./chunk-NHP3UPYU.js";
|
|
9
10
|
import {
|
|
10
11
|
ConfigStore
|
|
11
12
|
} from "./chunk-23T2XGSZ.js";
|
|
@@ -13,8 +14,8 @@ import {
|
|
|
13
14
|
selectActiveBackgroundAgents,
|
|
14
15
|
useCliStore
|
|
15
16
|
} from "./chunk-TVW4ZESU.js";
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-MUWN5G77.js";
|
|
18
|
+
import "./chunk-2UFCM2T4.js";
|
|
18
19
|
import {
|
|
19
20
|
BFLImageService,
|
|
20
21
|
BaseStorage,
|
|
@@ -26,7 +27,7 @@ import {
|
|
|
26
27
|
OpenAIBackend,
|
|
27
28
|
OpenAIImageService,
|
|
28
29
|
XAIImageService
|
|
29
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-A3HXNIIZ.js";
|
|
30
31
|
import {
|
|
31
32
|
AiEvents,
|
|
32
33
|
ApiKeyEvents,
|
|
@@ -82,7 +83,7 @@ import {
|
|
|
82
83
|
XAI_IMAGE_MODELS,
|
|
83
84
|
b4mLLMTools,
|
|
84
85
|
getMcpProviderMetadata
|
|
85
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-WVQTZODT.js";
|
|
86
87
|
import {
|
|
87
88
|
Logger
|
|
88
89
|
} from "./chunk-OCYRD7D6.js";
|
|
@@ -551,9 +552,8 @@ var COMMANDS = [
|
|
|
551
552
|
args: "<name>"
|
|
552
553
|
},
|
|
553
554
|
{
|
|
554
|
-
name: "
|
|
555
|
-
description: "List
|
|
556
|
-
aliases: ["sessions"]
|
|
555
|
+
name: "sessions",
|
|
556
|
+
description: "List saved sessions"
|
|
557
557
|
},
|
|
558
558
|
{
|
|
559
559
|
name: "config",
|
|
@@ -3718,23 +3718,18 @@ Remember: You are an autonomous AGENT. Act independently and solve problems proa
|
|
|
3718
3718
|
async executeToolWithQueueFallback(toolUse) {
|
|
3719
3719
|
const queuedObs = this.observationQueue.find((obs) => obs.toolId === getToolId(toolUse));
|
|
3720
3720
|
if (queuedObs) {
|
|
3721
|
-
const
|
|
3721
|
+
const result2 = queuedObs.result;
|
|
3722
3722
|
const index = this.observationQueue.indexOf(queuedObs);
|
|
3723
3723
|
this.observationQueue.splice(index, 1);
|
|
3724
|
-
return typeof
|
|
3724
|
+
return typeof result2 === "string" ? result2 : JSON.stringify(result2);
|
|
3725
3725
|
}
|
|
3726
3726
|
const tool = this.context.tools.find((t) => t.toolSchema.name === toolUse.name);
|
|
3727
3727
|
if (!tool) {
|
|
3728
|
-
|
|
3729
|
-
}
|
|
3730
|
-
try {
|
|
3731
|
-
const params = this.parseToolArguments(toolUse.arguments);
|
|
3732
|
-
const result = await tool.toolFn(params);
|
|
3733
|
-
return typeof result === "string" ? result : JSON.stringify(result);
|
|
3734
|
-
} catch (error) {
|
|
3735
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
3736
|
-
return `Error: ${message}`;
|
|
3728
|
+
throw new Error(`Tool ${toolUse.name} not found in agent context`);
|
|
3737
3729
|
}
|
|
3730
|
+
const params = this.parseToolArguments(toolUse.arguments);
|
|
3731
|
+
const result = await tool.toolFn(params);
|
|
3732
|
+
return typeof result === "string" ? result : JSON.stringify(result);
|
|
3738
3733
|
}
|
|
3739
3734
|
/**
|
|
3740
3735
|
* Build and append tool call/result messages for the conversation history
|
|
@@ -5756,7 +5751,19 @@ import { z as z129 } from "zod";
|
|
|
5756
5751
|
var createArtifactSchema = z129.object({
|
|
5757
5752
|
id: z129.string().optional(),
|
|
5758
5753
|
// Allow custom ID for AI-generated artifacts
|
|
5759
|
-
type: z129.enum([
|
|
5754
|
+
type: z129.enum([
|
|
5755
|
+
"mermaid",
|
|
5756
|
+
"recharts",
|
|
5757
|
+
"python",
|
|
5758
|
+
"react",
|
|
5759
|
+
"html",
|
|
5760
|
+
"svg",
|
|
5761
|
+
"code",
|
|
5762
|
+
"quest",
|
|
5763
|
+
"file",
|
|
5764
|
+
"questmaster",
|
|
5765
|
+
"lattice"
|
|
5766
|
+
]),
|
|
5760
5767
|
title: z129.string().min(1).max(255),
|
|
5761
5768
|
description: z129.string().max(1e3).optional(),
|
|
5762
5769
|
content: z129.string().min(1),
|
|
@@ -10364,6 +10371,819 @@ BLOCKED OPERATIONS:
|
|
|
10364
10371
|
})
|
|
10365
10372
|
};
|
|
10366
10373
|
|
|
10374
|
+
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/lattice/index.js
|
|
10375
|
+
function createModelData(name, modelType, userId, description, sessionId) {
|
|
10376
|
+
const now = /* @__PURE__ */ new Date();
|
|
10377
|
+
return {
|
|
10378
|
+
name,
|
|
10379
|
+
description: description || "",
|
|
10380
|
+
modelType,
|
|
10381
|
+
userId,
|
|
10382
|
+
sessionId,
|
|
10383
|
+
data: { entities: [], relationships: [] },
|
|
10384
|
+
rules: { rules: [], rulesets: [] },
|
|
10385
|
+
views: { views: [] },
|
|
10386
|
+
settings: {
|
|
10387
|
+
currency: "USD",
|
|
10388
|
+
fiscalYearStart: "01-01",
|
|
10389
|
+
periodGrain: "quarter",
|
|
10390
|
+
defaultDecimalPlaces: 2,
|
|
10391
|
+
negativeFormat: "parentheses"
|
|
10392
|
+
},
|
|
10393
|
+
scenarios: [],
|
|
10394
|
+
operations: [],
|
|
10395
|
+
operationIndex: -1,
|
|
10396
|
+
version: 1,
|
|
10397
|
+
createdAt: now,
|
|
10398
|
+
updatedAt: now
|
|
10399
|
+
};
|
|
10400
|
+
}
|
|
10401
|
+
var latticeCreateModelTool = {
|
|
10402
|
+
name: "lattice_create_model",
|
|
10403
|
+
implementation: (context) => ({
|
|
10404
|
+
toolFn: async (params) => {
|
|
10405
|
+
const { name, description, modelType = "custom", initialData } = params;
|
|
10406
|
+
console.log("[LATTICE DEBUG] \u{1F3D7}\uFE0F lattice_create_model called:", {
|
|
10407
|
+
name,
|
|
10408
|
+
description,
|
|
10409
|
+
modelType,
|
|
10410
|
+
hasInitialData: !!initialData,
|
|
10411
|
+
entityCount: initialData?.entities?.length || 0,
|
|
10412
|
+
ruleCount: initialData?.rules?.length || 0
|
|
10413
|
+
});
|
|
10414
|
+
const modelData = createModelData(name, modelType, context.userId, description);
|
|
10415
|
+
if (initialData?.entities && modelData.data) {
|
|
10416
|
+
const now = /* @__PURE__ */ new Date();
|
|
10417
|
+
for (const entityDef of initialData.entities) {
|
|
10418
|
+
const entityId = entityDef.name.toLowerCase().replace(/\s+/g, "_");
|
|
10419
|
+
const attributes = [];
|
|
10420
|
+
if (entityDef.values) {
|
|
10421
|
+
for (const val of entityDef.values) {
|
|
10422
|
+
attributes.push({
|
|
10423
|
+
key: "period",
|
|
10424
|
+
value: val.period,
|
|
10425
|
+
dataType: "string",
|
|
10426
|
+
isComputed: false
|
|
10427
|
+
});
|
|
10428
|
+
attributes.push({
|
|
10429
|
+
key: "value",
|
|
10430
|
+
value: val.value,
|
|
10431
|
+
dataType: "currency",
|
|
10432
|
+
isComputed: false
|
|
10433
|
+
});
|
|
10434
|
+
attributes.push({
|
|
10435
|
+
key: "category",
|
|
10436
|
+
value: entityDef.name,
|
|
10437
|
+
dataType: "string",
|
|
10438
|
+
isComputed: false
|
|
10439
|
+
});
|
|
10440
|
+
modelData.data.entities.push({
|
|
10441
|
+
id: `${entityId}_${val.period.toLowerCase().replace(/\s+/g, "_")}`,
|
|
10442
|
+
type: entityDef.type || "line_item",
|
|
10443
|
+
name: `${entityDef.name} ${val.period}`,
|
|
10444
|
+
displayName: `${entityDef.name} ${val.period}`,
|
|
10445
|
+
attributes: [
|
|
10446
|
+
{ key: "period", value: val.period, dataType: "string", isComputed: false },
|
|
10447
|
+
{ key: "value", value: val.value, dataType: "currency", isComputed: false },
|
|
10448
|
+
{ key: "category", value: entityDef.name, dataType: "string", isComputed: false }
|
|
10449
|
+
],
|
|
10450
|
+
metadata: {},
|
|
10451
|
+
createdAt: now,
|
|
10452
|
+
updatedAt: now
|
|
10453
|
+
});
|
|
10454
|
+
}
|
|
10455
|
+
}
|
|
10456
|
+
console.log(`[LATTICE DEBUG] \u2795 Created entity: ${entityDef.name} with ${entityDef.values?.length || 0} period values`);
|
|
10457
|
+
}
|
|
10458
|
+
}
|
|
10459
|
+
if (initialData?.rules && modelData.rules) {
|
|
10460
|
+
const now = /* @__PURE__ */ new Date();
|
|
10461
|
+
for (const ruleDef of initialData.rules) {
|
|
10462
|
+
const ruleId = `rule_${Date.now()}_${Math.random().toString(36).substr(2, 5)}`;
|
|
10463
|
+
const parsedRule = parseFormula(ruleDef.formula);
|
|
10464
|
+
modelData.rules.rules.push({
|
|
10465
|
+
id: ruleId,
|
|
10466
|
+
name: ruleDef.name,
|
|
10467
|
+
description: ruleDef.formula,
|
|
10468
|
+
type: "formula",
|
|
10469
|
+
definition: {
|
|
10470
|
+
operation: parsedRule.operation,
|
|
10471
|
+
inputs: parsedRule.inputs.map((ref) => ({ type: "entity", ref })),
|
|
10472
|
+
output: {
|
|
10473
|
+
targetEntityId: parsedRule.outputEntity.toLowerCase().replace(/\s+/g, "_"),
|
|
10474
|
+
targetAttribute: "computed",
|
|
10475
|
+
dataType: "number"
|
|
10476
|
+
}
|
|
10477
|
+
},
|
|
10478
|
+
dependencies: parsedRule.inputs.map((i) => i.toLowerCase().replace(/\s+/g, "_")),
|
|
10479
|
+
priority: 0,
|
|
10480
|
+
enabled: true,
|
|
10481
|
+
createdAt: now,
|
|
10482
|
+
updatedAt: now
|
|
10483
|
+
});
|
|
10484
|
+
console.log(`[LATTICE DEBUG] \u{1F4D0} Created rule: ${ruleDef.name} = ${ruleDef.formula}`);
|
|
10485
|
+
}
|
|
10486
|
+
}
|
|
10487
|
+
let model;
|
|
10488
|
+
let persistenceStatus = "unknown";
|
|
10489
|
+
const dbKeys = Object.keys(context.db || {});
|
|
10490
|
+
const hasLatticeModels = !!context.db?.latticeModels;
|
|
10491
|
+
if (context.db.latticeModels) {
|
|
10492
|
+
try {
|
|
10493
|
+
model = await context.db.latticeModels.create(modelData);
|
|
10494
|
+
persistenceStatus = `PERSISTED to MongoDB (id: ${model.id})`;
|
|
10495
|
+
context.logger.info(`[Lattice] Created model ${model.id} in database`);
|
|
10496
|
+
} catch (error) {
|
|
10497
|
+
persistenceStatus = `FAILED: ${error instanceof Error ? error.message : String(error)}`;
|
|
10498
|
+
context.logger.error(`[Lattice] Failed to persist model to database:`, error);
|
|
10499
|
+
model = {
|
|
10500
|
+
...modelData,
|
|
10501
|
+
id: `lattice_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
|
|
10502
|
+
};
|
|
10503
|
+
}
|
|
10504
|
+
} else {
|
|
10505
|
+
persistenceStatus = `IN-MEMORY (no latticeModels adapter). DB keys: [${dbKeys.join(", ")}]`;
|
|
10506
|
+
context.logger.warn("[Lattice] No database adapter available, creating in-memory model");
|
|
10507
|
+
model = {
|
|
10508
|
+
...modelData,
|
|
10509
|
+
id: `lattice_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
|
|
10510
|
+
};
|
|
10511
|
+
}
|
|
10512
|
+
const artifactData = {
|
|
10513
|
+
type: "lattice",
|
|
10514
|
+
id: model.id,
|
|
10515
|
+
title: name,
|
|
10516
|
+
content: JSON.stringify(model),
|
|
10517
|
+
metadata: {
|
|
10518
|
+
modelType,
|
|
10519
|
+
periodGrain: model.settings?.periodGrain || "quarter",
|
|
10520
|
+
currency: model.settings?.currency || "USD",
|
|
10521
|
+
entityCount: model.data?.entities?.length || 0,
|
|
10522
|
+
ruleCount: model.rules?.rules?.length || 0,
|
|
10523
|
+
// DEBUG: Include persistence info in metadata
|
|
10524
|
+
_debug: {
|
|
10525
|
+
persistenceStatus,
|
|
10526
|
+
hasLatticeModels,
|
|
10527
|
+
dbKeys
|
|
10528
|
+
}
|
|
10529
|
+
},
|
|
10530
|
+
createdAt: model.createdAt?.toISOString?.() || (/* @__PURE__ */ new Date()).toISOString(),
|
|
10531
|
+
updatedAt: model.updatedAt?.toISOString?.() || (/* @__PURE__ */ new Date()).toISOString()
|
|
10532
|
+
};
|
|
10533
|
+
const entityCount = model.data?.entities?.length || 0;
|
|
10534
|
+
const ruleCount = model.rules?.rules?.length || 0;
|
|
10535
|
+
return `Created "${name}" model with ${entityCount} entities and ${ruleCount} rules.
|
|
10536
|
+
|
|
10537
|
+
<artifact identifier="${model.id}" type="application/vnd.b4m.lattice" title="${name}">
|
|
10538
|
+
${JSON.stringify(artifactData, null, 2)}
|
|
10539
|
+
</artifact>
|
|
10540
|
+
|
|
10541
|
+
The model is ready for viewing. You can add more data by asking to add line items or create formulas.`;
|
|
10542
|
+
},
|
|
10543
|
+
toolSchema: {
|
|
10544
|
+
name: "lattice_create_model",
|
|
10545
|
+
description: `Create a new Lattice financial model with optional initial data. Use initialData to populate entities and rules in ONE call.
|
|
10546
|
+
|
|
10547
|
+
**IMPORTANT**: Always include initialData when the user provides specific values! This creates a fully populated model immediately.
|
|
10548
|
+
|
|
10549
|
+
**When to use:** When the user wants to:
|
|
10550
|
+
- Create a new financial model, spreadsheet, or pro-forma
|
|
10551
|
+
- Start building an income statement, balance sheet, or cash flow
|
|
10552
|
+
- Set up a SaaS metrics dashboard
|
|
10553
|
+
|
|
10554
|
+
**Example with initialData:**
|
|
10555
|
+
User: "Create income statement with $100K revenue and $60K costs for Q1"
|
|
10556
|
+
Call: lattice_create_model with:
|
|
10557
|
+
- name: "Income Statement"
|
|
10558
|
+
- modelType: "income_statement"
|
|
10559
|
+
- initialData: {
|
|
10560
|
+
entities: [
|
|
10561
|
+
{ name: "Revenue", values: [{ period: "Q1", value: 100000 }] },
|
|
10562
|
+
{ name: "Costs", values: [{ period: "Q1", value: 60000 }] }
|
|
10563
|
+
],
|
|
10564
|
+
rules: [
|
|
10565
|
+
{ name: "Gross Profit", formula: "Gross Profit = Revenue - Costs" }
|
|
10566
|
+
]
|
|
10567
|
+
}`,
|
|
10568
|
+
parameters: {
|
|
10569
|
+
type: "object",
|
|
10570
|
+
properties: {
|
|
10571
|
+
name: {
|
|
10572
|
+
type: "string",
|
|
10573
|
+
description: 'Name of the model (e.g., "2024 Budget", "Q1 Forecast")'
|
|
10574
|
+
},
|
|
10575
|
+
description: {
|
|
10576
|
+
type: "string",
|
|
10577
|
+
description: "Optional description of what this model represents"
|
|
10578
|
+
},
|
|
10579
|
+
modelType: {
|
|
10580
|
+
type: "string",
|
|
10581
|
+
enum: ["income_statement", "balance_sheet", "cashflow", "saas_metrics", "custom"],
|
|
10582
|
+
description: "Type of financial model to create"
|
|
10583
|
+
},
|
|
10584
|
+
initialData: {
|
|
10585
|
+
type: "object",
|
|
10586
|
+
description: "Initial entities and rules to populate the model. ALWAYS use this when user provides data!",
|
|
10587
|
+
properties: {
|
|
10588
|
+
entities: {
|
|
10589
|
+
type: "array",
|
|
10590
|
+
description: "Line items with their period values",
|
|
10591
|
+
items: {
|
|
10592
|
+
type: "object",
|
|
10593
|
+
properties: {
|
|
10594
|
+
name: { type: "string", description: 'Entity name (e.g., "Revenue", "COGS")' },
|
|
10595
|
+
type: { type: "string", description: "Entity type (default: line_item)" },
|
|
10596
|
+
values: {
|
|
10597
|
+
type: "array",
|
|
10598
|
+
description: "Period-value pairs",
|
|
10599
|
+
items: {
|
|
10600
|
+
type: "object",
|
|
10601
|
+
properties: {
|
|
10602
|
+
period: { type: "string", description: 'Period name (e.g., "Q1", "Jan", "2024")' },
|
|
10603
|
+
value: { type: "number", description: "Numeric value" }
|
|
10604
|
+
},
|
|
10605
|
+
required: ["period", "value"]
|
|
10606
|
+
}
|
|
10607
|
+
}
|
|
10608
|
+
},
|
|
10609
|
+
required: ["name"]
|
|
10610
|
+
}
|
|
10611
|
+
},
|
|
10612
|
+
rules: {
|
|
10613
|
+
type: "array",
|
|
10614
|
+
description: "Formulas/calculations to create",
|
|
10615
|
+
items: {
|
|
10616
|
+
type: "object",
|
|
10617
|
+
properties: {
|
|
10618
|
+
name: { type: "string", description: 'Rule name (e.g., "Gross Profit Calculation")' },
|
|
10619
|
+
formula: {
|
|
10620
|
+
type: "string",
|
|
10621
|
+
description: 'Natural language formula (e.g., "Gross Profit = Revenue - Costs")'
|
|
10622
|
+
}
|
|
10623
|
+
},
|
|
10624
|
+
required: ["name", "formula"]
|
|
10625
|
+
}
|
|
10626
|
+
}
|
|
10627
|
+
}
|
|
10628
|
+
}
|
|
10629
|
+
},
|
|
10630
|
+
required: ["name"]
|
|
10631
|
+
}
|
|
10632
|
+
}
|
|
10633
|
+
})
|
|
10634
|
+
};
|
|
10635
|
+
var latticeAddEntityTool = {
|
|
10636
|
+
name: "lattice_add_entity",
|
|
10637
|
+
implementation: (context) => ({
|
|
10638
|
+
toolFn: async (params) => {
|
|
10639
|
+
const { modelId, name, type, displayName, initialValues = [] } = params;
|
|
10640
|
+
console.log("[LATTICE DEBUG] \u2795 lattice_add_entity called:", { modelId, name, type, initialValues });
|
|
10641
|
+
const entityId = name.toLowerCase().replace(/\s+/g, "_");
|
|
10642
|
+
const entityData = {
|
|
10643
|
+
id: entityId,
|
|
10644
|
+
type,
|
|
10645
|
+
name,
|
|
10646
|
+
displayName: displayName || name,
|
|
10647
|
+
attributes: initialValues.map((v) => ({
|
|
10648
|
+
key: v.key,
|
|
10649
|
+
value: v.value,
|
|
10650
|
+
dataType: v.dataType || (typeof v.value === "number" ? "number" : "string"),
|
|
10651
|
+
isComputed: false
|
|
10652
|
+
})),
|
|
10653
|
+
metadata: {},
|
|
10654
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
10655
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
10656
|
+
};
|
|
10657
|
+
if (context.db.latticeModels && modelId && /^[a-f0-9]{24}$/.test(modelId)) {
|
|
10658
|
+
try {
|
|
10659
|
+
const model = await context.db.latticeModels.findById(modelId);
|
|
10660
|
+
if (model) {
|
|
10661
|
+
const existingIndex = model.data.entities.findIndex((e) => e.id === entityId);
|
|
10662
|
+
if (existingIndex >= 0) {
|
|
10663
|
+
model.data.entities[existingIndex] = entityData;
|
|
10664
|
+
} else {
|
|
10665
|
+
model.data.entities.push(entityData);
|
|
10666
|
+
}
|
|
10667
|
+
await context.db.latticeModels.update({
|
|
10668
|
+
id: modelId,
|
|
10669
|
+
data: model.data,
|
|
10670
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
10671
|
+
});
|
|
10672
|
+
context.logger.info(`[Lattice] Added entity ${entityId} to model ${modelId}`);
|
|
10673
|
+
} else {
|
|
10674
|
+
context.logger.warn(`[Lattice] Model ${modelId} not found in database`);
|
|
10675
|
+
}
|
|
10676
|
+
} catch (error) {
|
|
10677
|
+
context.logger.error(`[Lattice] Failed to persist entity to database:`, error);
|
|
10678
|
+
}
|
|
10679
|
+
}
|
|
10680
|
+
return JSON.stringify({
|
|
10681
|
+
success: true,
|
|
10682
|
+
action: "ADD_ENTITY",
|
|
10683
|
+
modelId,
|
|
10684
|
+
entityId,
|
|
10685
|
+
data: entityData,
|
|
10686
|
+
message: `Added ${type} "${displayName || name}" to model. ${initialValues.length > 0 ? `Set initial values: ${initialValues.map((v) => `${v.key}=${v.value}`).join(", ")}` : "No initial values set."}`
|
|
10687
|
+
});
|
|
10688
|
+
},
|
|
10689
|
+
toolSchema: {
|
|
10690
|
+
name: "lattice_add_entity",
|
|
10691
|
+
description: `Add a line item, account, period, or other entity to a Lattice model.
|
|
10692
|
+
|
|
10693
|
+
**When to use:** When the user mentions:
|
|
10694
|
+
- Adding a revenue line, expense category, or account
|
|
10695
|
+
- Creating periods (Q1, Q2, Jan, Feb, etc.)
|
|
10696
|
+
- Adding any measurable item to their model
|
|
10697
|
+
|
|
10698
|
+
**Entity types:**
|
|
10699
|
+
- line_item: Revenue streams, expense lines, KPIs
|
|
10700
|
+
- account: Cash, AR, AP, inventory, etc.
|
|
10701
|
+
- period: Q1 2024, Jan, FY2025, etc.
|
|
10702
|
+
- category: Groups of line items (Operating Expenses)
|
|
10703
|
+
- scenario: Base case, upside, downside
|
|
10704
|
+
- custom: Any other structured element
|
|
10705
|
+
|
|
10706
|
+
**Examples:**
|
|
10707
|
+
- "Add Revenue" \u2192 line_item named "Revenue"
|
|
10708
|
+
- "Create a Marketing Expenses category" \u2192 category named "Marketing Expenses"
|
|
10709
|
+
- "Add quarters Q1 through Q4" \u2192 4 period entities`,
|
|
10710
|
+
parameters: {
|
|
10711
|
+
type: "object",
|
|
10712
|
+
properties: {
|
|
10713
|
+
modelId: {
|
|
10714
|
+
type: "string",
|
|
10715
|
+
description: "ID of the model to add the entity to"
|
|
10716
|
+
},
|
|
10717
|
+
name: {
|
|
10718
|
+
type: "string",
|
|
10719
|
+
description: "Internal name for the entity (used in formulas)"
|
|
10720
|
+
},
|
|
10721
|
+
type: {
|
|
10722
|
+
type: "string",
|
|
10723
|
+
enum: ["line_item", "account", "period", "category", "scenario", "custom"],
|
|
10724
|
+
description: "Type of entity"
|
|
10725
|
+
},
|
|
10726
|
+
displayName: {
|
|
10727
|
+
type: "string",
|
|
10728
|
+
description: "Human-readable display name (defaults to name)"
|
|
10729
|
+
},
|
|
10730
|
+
initialValues: {
|
|
10731
|
+
type: "array",
|
|
10732
|
+
items: {
|
|
10733
|
+
type: "object",
|
|
10734
|
+
properties: {
|
|
10735
|
+
key: { type: "string", description: 'Period or attribute key (e.g., "Q1_2024")' },
|
|
10736
|
+
value: { type: "string", description: "The value (number or string)" },
|
|
10737
|
+
dataType: {
|
|
10738
|
+
type: "string",
|
|
10739
|
+
enum: ["number", "currency", "percentage", "string"],
|
|
10740
|
+
description: "Data type for the value"
|
|
10741
|
+
}
|
|
10742
|
+
},
|
|
10743
|
+
required: ["key", "value"]
|
|
10744
|
+
},
|
|
10745
|
+
description: "Optional initial values for this entity"
|
|
10746
|
+
}
|
|
10747
|
+
},
|
|
10748
|
+
required: ["modelId", "name", "type"]
|
|
10749
|
+
}
|
|
10750
|
+
}
|
|
10751
|
+
})
|
|
10752
|
+
};
|
|
10753
|
+
var latticeSetValueTool = {
|
|
10754
|
+
name: "lattice_set_value",
|
|
10755
|
+
implementation: (context) => ({
|
|
10756
|
+
toolFn: async (params) => {
|
|
10757
|
+
const { modelId, entityName, attributeKey, value: rawValue } = params;
|
|
10758
|
+
console.log("[LATTICE DEBUG] \u{1F4DD} lattice_set_value called:", { modelId, entityName, attributeKey, rawValue });
|
|
10759
|
+
let value = rawValue;
|
|
10760
|
+
const numValue = parseFloat(rawValue);
|
|
10761
|
+
if (!isNaN(numValue)) {
|
|
10762
|
+
value = numValue;
|
|
10763
|
+
} else if (rawValue.toLowerCase() === "true") {
|
|
10764
|
+
value = true;
|
|
10765
|
+
} else if (rawValue.toLowerCase() === "false") {
|
|
10766
|
+
value = false;
|
|
10767
|
+
}
|
|
10768
|
+
const entityId = entityName.toLowerCase().replace(/\s+/g, "_");
|
|
10769
|
+
if (context.db.latticeModels && modelId && /^[a-f0-9]{24}$/.test(modelId)) {
|
|
10770
|
+
try {
|
|
10771
|
+
const model = await context.db.latticeModels.findById(modelId);
|
|
10772
|
+
if (model) {
|
|
10773
|
+
const entity = model.data.entities.find((e) => e.id === entityId || e.name === entityName);
|
|
10774
|
+
if (entity) {
|
|
10775
|
+
const attrIndex = entity.attributes.findIndex((a) => a.key === attributeKey);
|
|
10776
|
+
const dataType = typeof value === "number" ? "number" : typeof value === "boolean" ? "boolean" : "string";
|
|
10777
|
+
const attributeData = {
|
|
10778
|
+
key: attributeKey,
|
|
10779
|
+
value,
|
|
10780
|
+
dataType,
|
|
10781
|
+
isComputed: false
|
|
10782
|
+
};
|
|
10783
|
+
if (attrIndex >= 0) {
|
|
10784
|
+
entity.attributes[attrIndex] = attributeData;
|
|
10785
|
+
} else {
|
|
10786
|
+
entity.attributes.push(attributeData);
|
|
10787
|
+
}
|
|
10788
|
+
entity.updatedAt = /* @__PURE__ */ new Date();
|
|
10789
|
+
await context.db.latticeModels.update({
|
|
10790
|
+
id: modelId,
|
|
10791
|
+
data: model.data,
|
|
10792
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
10793
|
+
});
|
|
10794
|
+
context.logger.info(`[Lattice] Set ${entityId}.${attributeKey} = ${value} in model ${modelId}`);
|
|
10795
|
+
} else {
|
|
10796
|
+
context.logger.warn(`[Lattice] Entity ${entityName} not found in model ${modelId}`);
|
|
10797
|
+
}
|
|
10798
|
+
} else {
|
|
10799
|
+
context.logger.warn(`[Lattice] Model ${modelId} not found in database`);
|
|
10800
|
+
}
|
|
10801
|
+
} catch (error) {
|
|
10802
|
+
context.logger.error(`[Lattice] Failed to persist value to database:`, error);
|
|
10803
|
+
}
|
|
10804
|
+
}
|
|
10805
|
+
return JSON.stringify({
|
|
10806
|
+
success: true,
|
|
10807
|
+
action: "SET_VALUE",
|
|
10808
|
+
modelId,
|
|
10809
|
+
data: {
|
|
10810
|
+
entityName,
|
|
10811
|
+
attributeKey,
|
|
10812
|
+
value
|
|
10813
|
+
},
|
|
10814
|
+
message: `Set ${entityName}.${attributeKey} = ${value}`
|
|
10815
|
+
});
|
|
10816
|
+
},
|
|
10817
|
+
toolSchema: {
|
|
10818
|
+
name: "lattice_set_value",
|
|
10819
|
+
description: `Set a specific value in a Lattice model.
|
|
10820
|
+
|
|
10821
|
+
**When to use:** When the user provides a specific number:
|
|
10822
|
+
- "Revenue in Q1 is 150,000"
|
|
10823
|
+
- "Set marketing spend to 50k for January"
|
|
10824
|
+
- "COGS is 40% of revenue" (use lattice_create_rule for formulas)
|
|
10825
|
+
|
|
10826
|
+
**Important:** This tool is for setting raw input values. For calculated values (formulas), use \`lattice_create_rule\` instead.
|
|
10827
|
+
|
|
10828
|
+
**Examples:**
|
|
10829
|
+
- "Q1 revenue is $100,000" \u2192 entityName="Revenue", attributeKey="Q1", value=100000
|
|
10830
|
+
- "Set headcount to 25" \u2192 entityName="Headcount", attributeKey="current", value=25`,
|
|
10831
|
+
parameters: {
|
|
10832
|
+
type: "object",
|
|
10833
|
+
properties: {
|
|
10834
|
+
modelId: {
|
|
10835
|
+
type: "string",
|
|
10836
|
+
description: "ID of the model"
|
|
10837
|
+
},
|
|
10838
|
+
entityName: {
|
|
10839
|
+
type: "string",
|
|
10840
|
+
description: "Name of the entity (line item, account, etc.)"
|
|
10841
|
+
},
|
|
10842
|
+
attributeKey: {
|
|
10843
|
+
type: "string",
|
|
10844
|
+
description: 'Period or attribute key (e.g., "Q1_2024", "current", "budget")'
|
|
10845
|
+
},
|
|
10846
|
+
value: {
|
|
10847
|
+
type: "string",
|
|
10848
|
+
description: "The value to set (will be parsed as number if numeric)"
|
|
10849
|
+
}
|
|
10850
|
+
},
|
|
10851
|
+
required: ["modelId", "entityName", "attributeKey", "value"]
|
|
10852
|
+
}
|
|
10853
|
+
}
|
|
10854
|
+
})
|
|
10855
|
+
};
|
|
10856
|
+
var latticeCreateRuleTool = {
|
|
10857
|
+
name: "lattice_create_rule",
|
|
10858
|
+
implementation: (context) => ({
|
|
10859
|
+
toolFn: async (params) => {
|
|
10860
|
+
const { modelId, name, description, formula } = params;
|
|
10861
|
+
console.log("[LATTICE DEBUG] \u{1F4D0} lattice_create_rule called:", { modelId, name, formula });
|
|
10862
|
+
const parsedRule = parseFormula(formula);
|
|
10863
|
+
const ruleId = `rule_${Date.now()}`;
|
|
10864
|
+
const ruleData = {
|
|
10865
|
+
id: ruleId,
|
|
10866
|
+
name,
|
|
10867
|
+
description: description || formula,
|
|
10868
|
+
type: "formula",
|
|
10869
|
+
definition: {
|
|
10870
|
+
operation: parsedRule.operation,
|
|
10871
|
+
inputs: parsedRule.inputs.map((ref) => ({
|
|
10872
|
+
type: "entity",
|
|
10873
|
+
ref
|
|
10874
|
+
})),
|
|
10875
|
+
output: {
|
|
10876
|
+
targetEntityId: parsedRule.outputEntity.toLowerCase().replace(/\s+/g, "_"),
|
|
10877
|
+
targetAttribute: "computed",
|
|
10878
|
+
dataType: "number"
|
|
10879
|
+
}
|
|
10880
|
+
},
|
|
10881
|
+
dependencies: parsedRule.inputs.map((i) => i.toLowerCase().replace(/\s+/g, "_")),
|
|
10882
|
+
priority: 0,
|
|
10883
|
+
enabled: true,
|
|
10884
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
10885
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
10886
|
+
};
|
|
10887
|
+
const outputEntityId = parsedRule.outputEntity.toLowerCase().replace(/\s+/g, "_");
|
|
10888
|
+
let entityCreatedMessage = "";
|
|
10889
|
+
if (context.db.latticeModels && modelId && /^[a-f0-9]{24}$/.test(modelId)) {
|
|
10890
|
+
try {
|
|
10891
|
+
const model = await context.db.latticeModels.findById(modelId);
|
|
10892
|
+
if (model) {
|
|
10893
|
+
const outputEntityExists = model.data.entities.some((e) => e.id === outputEntityId || e.name.toLowerCase() === parsedRule.outputEntity.toLowerCase());
|
|
10894
|
+
if (!outputEntityExists && parsedRule.outputEntity !== "unknown") {
|
|
10895
|
+
const now = /* @__PURE__ */ new Date();
|
|
10896
|
+
const newEntity = {
|
|
10897
|
+
id: outputEntityId,
|
|
10898
|
+
type: "line_item",
|
|
10899
|
+
name: parsedRule.outputEntity,
|
|
10900
|
+
displayName: parsedRule.outputEntity,
|
|
10901
|
+
attributes: [
|
|
10902
|
+
{
|
|
10903
|
+
key: "value",
|
|
10904
|
+
value: 0,
|
|
10905
|
+
dataType: "currency",
|
|
10906
|
+
isComputed: true
|
|
10907
|
+
},
|
|
10908
|
+
{
|
|
10909
|
+
key: "category",
|
|
10910
|
+
value: "Computed",
|
|
10911
|
+
dataType: "string",
|
|
10912
|
+
isComputed: false
|
|
10913
|
+
}
|
|
10914
|
+
],
|
|
10915
|
+
metadata: { isComputed: true },
|
|
10916
|
+
createdAt: now,
|
|
10917
|
+
updatedAt: now
|
|
10918
|
+
};
|
|
10919
|
+
model.data.entities.push(newEntity);
|
|
10920
|
+
entityCreatedMessage = ` Created output entity "${parsedRule.outputEntity}".`;
|
|
10921
|
+
context.logger.info(`[Lattice] Auto-created output entity ${outputEntityId} for rule ${ruleId}`);
|
|
10922
|
+
}
|
|
10923
|
+
const existingIndex = model.rules.rules.findIndex((r) => r.id === ruleId || r.name === name);
|
|
10924
|
+
if (existingIndex >= 0) {
|
|
10925
|
+
model.rules.rules[existingIndex] = ruleData;
|
|
10926
|
+
} else {
|
|
10927
|
+
model.rules.rules.push(ruleData);
|
|
10928
|
+
}
|
|
10929
|
+
await context.db.latticeModels.update({
|
|
10930
|
+
id: modelId,
|
|
10931
|
+
data: model.data,
|
|
10932
|
+
rules: model.rules,
|
|
10933
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
10934
|
+
});
|
|
10935
|
+
context.logger.info(`[Lattice] Created rule ${ruleId} in model ${modelId}`);
|
|
10936
|
+
} else {
|
|
10937
|
+
context.logger.warn(`[Lattice] Model ${modelId} not found in database`);
|
|
10938
|
+
}
|
|
10939
|
+
} catch (error) {
|
|
10940
|
+
context.logger.error(`[Lattice] Failed to persist rule to database:`, error);
|
|
10941
|
+
}
|
|
10942
|
+
}
|
|
10943
|
+
return JSON.stringify({
|
|
10944
|
+
success: true,
|
|
10945
|
+
action: "CREATE_RULE",
|
|
10946
|
+
modelId,
|
|
10947
|
+
ruleId,
|
|
10948
|
+
data: {
|
|
10949
|
+
name,
|
|
10950
|
+
description,
|
|
10951
|
+
formula,
|
|
10952
|
+
parsed: parsedRule,
|
|
10953
|
+
outputEntityCreated: entityCreatedMessage !== ""
|
|
10954
|
+
},
|
|
10955
|
+
message: `Created rule "${name}": ${formula}.${entityCreatedMessage}`
|
|
10956
|
+
});
|
|
10957
|
+
},
|
|
10958
|
+
toolSchema: {
|
|
10959
|
+
name: "lattice_create_rule",
|
|
10960
|
+
description: `Create a formula or calculation rule in a Lattice model.
|
|
10961
|
+
|
|
10962
|
+
**When to use:** When the user defines a calculation:
|
|
10963
|
+
- "Gross profit equals revenue minus COGS"
|
|
10964
|
+
- "Net margin is net income divided by revenue times 100"
|
|
10965
|
+
- "Total expenses is the sum of all expense line items"
|
|
10966
|
+
|
|
10967
|
+
**IMPORTANT: For per-period calculations like "calculate X for each quarter", you MUST call this tool ONCE for EACH period.** For example, if asked to "calculate gross margin for each quarter", call this tool 4 times:
|
|
10968
|
+
1. lattice_create_rule with formula "Q1 Gross Margin = Q1 Revenue - Q1 COGS"
|
|
10969
|
+
2. lattice_create_rule with formula "Q2 Gross Margin = Q2 Revenue - Q2 COGS"
|
|
10970
|
+
3. lattice_create_rule with formula "Q3 Gross Margin = Q3 Revenue - Q3 COGS"
|
|
10971
|
+
4. lattice_create_rule with formula "Q4 Gross Margin = Q4 Revenue - Q4 COGS"
|
|
10972
|
+
|
|
10973
|
+
**Formula syntax (natural language):**
|
|
10974
|
+
- Arithmetic: "X equals Y plus Z", "A minus B", "C times D"
|
|
10975
|
+
- Aggregation: "sum of", "average of", "total"
|
|
10976
|
+
- Percentage: "X percent of Y", "as a percentage"
|
|
10977
|
+
- Comparison: "if X is greater than Y then A else B"
|
|
10978
|
+
|
|
10979
|
+
**Examples:**
|
|
10980
|
+
- "Gross Profit = Revenue - COGS"
|
|
10981
|
+
- "Gross Margin = Gross Profit / Revenue * 100"
|
|
10982
|
+
- "Total OpEx = sum of all Operating Expenses"
|
|
10983
|
+
- "YoY Growth = (Current Year - Prior Year) / Prior Year * 100"
|
|
10984
|
+
- "Q1 Gross Margin = Q1 Revenue - Q1 COGS" (per-period)`,
|
|
10985
|
+
parameters: {
|
|
10986
|
+
type: "object",
|
|
10987
|
+
properties: {
|
|
10988
|
+
modelId: {
|
|
10989
|
+
type: "string",
|
|
10990
|
+
description: "ID of the model"
|
|
10991
|
+
},
|
|
10992
|
+
name: {
|
|
10993
|
+
type: "string",
|
|
10994
|
+
description: 'Name for this rule (e.g., "Gross Profit Calculation")'
|
|
10995
|
+
},
|
|
10996
|
+
description: {
|
|
10997
|
+
type: "string",
|
|
10998
|
+
description: "Optional description of what this rule calculates"
|
|
10999
|
+
},
|
|
11000
|
+
formula: {
|
|
11001
|
+
type: "string",
|
|
11002
|
+
description: "The formula in natural language or equation format"
|
|
11003
|
+
}
|
|
11004
|
+
},
|
|
11005
|
+
required: ["modelId", "name", "formula"]
|
|
11006
|
+
}
|
|
11007
|
+
}
|
|
11008
|
+
})
|
|
11009
|
+
};
|
|
11010
|
+
var latticeQueryTool = {
|
|
11011
|
+
name: "lattice_query",
|
|
11012
|
+
implementation: () => ({
|
|
11013
|
+
toolFn: async (params) => {
|
|
11014
|
+
const { modelId, query } = params;
|
|
11015
|
+
const parsedQuery = parseQuery(query);
|
|
11016
|
+
return JSON.stringify({
|
|
11017
|
+
success: true,
|
|
11018
|
+
action: "QUERY",
|
|
11019
|
+
modelId,
|
|
11020
|
+
data: {
|
|
11021
|
+
query,
|
|
11022
|
+
parsed: parsedQuery
|
|
11023
|
+
},
|
|
11024
|
+
message: `Querying model for: ${query}`
|
|
11025
|
+
});
|
|
11026
|
+
},
|
|
11027
|
+
toolSchema: {
|
|
11028
|
+
name: "lattice_query",
|
|
11029
|
+
description: `Query a Lattice model for specific values or aggregations.
|
|
11030
|
+
|
|
11031
|
+
**When to use:** When the user asks about values in the model:
|
|
11032
|
+
- "What's Q1 gross margin?"
|
|
11033
|
+
- "Show me total revenue for 2024"
|
|
11034
|
+
- "What are all the expense categories?"
|
|
11035
|
+
- "Compare Q1 vs Q2 performance"
|
|
11036
|
+
|
|
11037
|
+
**Query types:**
|
|
11038
|
+
- Single value: "What is [entity] for [period]?"
|
|
11039
|
+
- Aggregation: "Total [entity] for [range]"
|
|
11040
|
+
- Comparison: "Compare [entity] across [periods]"
|
|
11041
|
+
- List: "Show all [entity type]"
|
|
11042
|
+
|
|
11043
|
+
**Examples:**
|
|
11044
|
+
- "What's Q2 revenue?" \u2192 Returns specific value
|
|
11045
|
+
- "Total revenue for 2024" \u2192 Sums Q1-Q4
|
|
11046
|
+
- "Compare gross margin Q1 vs Q2" \u2192 Side-by-side comparison`,
|
|
11047
|
+
parameters: {
|
|
11048
|
+
type: "object",
|
|
11049
|
+
properties: {
|
|
11050
|
+
modelId: {
|
|
11051
|
+
type: "string",
|
|
11052
|
+
description: "ID of the model to query"
|
|
11053
|
+
},
|
|
11054
|
+
query: {
|
|
11055
|
+
type: "string",
|
|
11056
|
+
description: "Natural language query about the model"
|
|
11057
|
+
}
|
|
11058
|
+
},
|
|
11059
|
+
required: ["modelId", "query"]
|
|
11060
|
+
}
|
|
11061
|
+
}
|
|
11062
|
+
})
|
|
11063
|
+
};
|
|
11064
|
+
var latticeExplainTool = {
|
|
11065
|
+
name: "lattice_explain",
|
|
11066
|
+
implementation: () => ({
|
|
11067
|
+
toolFn: async (params) => {
|
|
11068
|
+
const { modelId, entityName, attributeKey } = params;
|
|
11069
|
+
return JSON.stringify({
|
|
11070
|
+
success: true,
|
|
11071
|
+
action: "EXPLAIN",
|
|
11072
|
+
modelId,
|
|
11073
|
+
data: {
|
|
11074
|
+
entityName,
|
|
11075
|
+
attributeKey
|
|
11076
|
+
},
|
|
11077
|
+
message: `Explaining calculation for ${entityName}.${attributeKey}`
|
|
11078
|
+
});
|
|
11079
|
+
},
|
|
11080
|
+
toolSchema: {
|
|
11081
|
+
name: "lattice_explain",
|
|
11082
|
+
description: `Explain how a value in a Lattice model was calculated.
|
|
11083
|
+
|
|
11084
|
+
**When to use:** When the user wants to understand a calculation:
|
|
11085
|
+
- "How did you calculate gross profit?"
|
|
11086
|
+
- "Explain the Q2 margin number"
|
|
11087
|
+
- "Show me the formula for total expenses"
|
|
11088
|
+
- "Why is this number so high?"
|
|
11089
|
+
|
|
11090
|
+
This tool traces the calculation chain from the target value back through all its inputs and rules, providing a step-by-step explanation.`,
|
|
11091
|
+
parameters: {
|
|
11092
|
+
type: "object",
|
|
11093
|
+
properties: {
|
|
11094
|
+
modelId: {
|
|
11095
|
+
type: "string",
|
|
11096
|
+
description: "ID of the model"
|
|
11097
|
+
},
|
|
11098
|
+
entityName: {
|
|
11099
|
+
type: "string",
|
|
11100
|
+
description: "Name of the entity containing the value to explain"
|
|
11101
|
+
},
|
|
11102
|
+
attributeKey: {
|
|
11103
|
+
type: "string",
|
|
11104
|
+
description: "Period or attribute key of the value to explain"
|
|
11105
|
+
}
|
|
11106
|
+
},
|
|
11107
|
+
required: ["modelId", "entityName", "attributeKey"]
|
|
11108
|
+
}
|
|
11109
|
+
}
|
|
11110
|
+
})
|
|
11111
|
+
};
|
|
11112
|
+
function parseFormula(formula) {
|
|
11113
|
+
const normalized = formula.toLowerCase().trim();
|
|
11114
|
+
const equalsMatch = normalized.match(/^(.+?)\s*(?:=|equals?)\s*(.+)$/i);
|
|
11115
|
+
if (equalsMatch) {
|
|
11116
|
+
const [, output, expression] = equalsMatch;
|
|
11117
|
+
if (expression.includes("+") || expression.includes("plus")) {
|
|
11118
|
+
return {
|
|
11119
|
+
operation: "ADD",
|
|
11120
|
+
outputEntity: output,
|
|
11121
|
+
inputs: expression.split(/[+]|plus/i).map((s) => s.trim())
|
|
11122
|
+
};
|
|
11123
|
+
}
|
|
11124
|
+
if (expression.includes("-") || expression.includes("minus")) {
|
|
11125
|
+
return {
|
|
11126
|
+
operation: "SUBTRACT",
|
|
11127
|
+
outputEntity: output,
|
|
11128
|
+
inputs: expression.split(/[-]|minus/i).map((s) => s.trim())
|
|
11129
|
+
};
|
|
11130
|
+
}
|
|
11131
|
+
if (expression.includes("*") || expression.includes("times") || expression.includes("x")) {
|
|
11132
|
+
return {
|
|
11133
|
+
operation: "MULTIPLY",
|
|
11134
|
+
outputEntity: output,
|
|
11135
|
+
inputs: expression.split(/[*x]|times/i).map((s) => s.trim())
|
|
11136
|
+
};
|
|
11137
|
+
}
|
|
11138
|
+
if (expression.includes("/") || expression.includes("divided")) {
|
|
11139
|
+
return {
|
|
11140
|
+
operation: "DIVIDE",
|
|
11141
|
+
outputEntity: output,
|
|
11142
|
+
inputs: expression.split(/[/]|divided by/i).map((s) => s.trim())
|
|
11143
|
+
};
|
|
11144
|
+
}
|
|
11145
|
+
if (expression.includes("sum")) {
|
|
11146
|
+
return {
|
|
11147
|
+
operation: "SUM",
|
|
11148
|
+
outputEntity: output,
|
|
11149
|
+
inputs: [expression.replace(/sum of/i, "").trim()]
|
|
11150
|
+
};
|
|
11151
|
+
}
|
|
11152
|
+
}
|
|
11153
|
+
return {
|
|
11154
|
+
operation: "REFERENCE",
|
|
11155
|
+
outputEntity: "unknown",
|
|
11156
|
+
inputs: [formula]
|
|
11157
|
+
};
|
|
11158
|
+
}
|
|
11159
|
+
function parseQuery(query) {
|
|
11160
|
+
const normalized = query.toLowerCase();
|
|
11161
|
+
let type = "single_value";
|
|
11162
|
+
if (normalized.includes("total") || normalized.includes("sum")) {
|
|
11163
|
+
type = "aggregation";
|
|
11164
|
+
} else if (normalized.includes("compare") || normalized.includes("vs")) {
|
|
11165
|
+
type = "comparison";
|
|
11166
|
+
} else if (normalized.includes("list") || normalized.includes("show all")) {
|
|
11167
|
+
type = "list";
|
|
11168
|
+
}
|
|
11169
|
+
const entities = [];
|
|
11170
|
+
const periods = [];
|
|
11171
|
+
const periodPatterns = [/q[1-4]/gi, /\d{4}/g, /jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec/gi];
|
|
11172
|
+
for (const pattern of periodPatterns) {
|
|
11173
|
+
const matches = query.match(pattern);
|
|
11174
|
+
if (matches) {
|
|
11175
|
+
periods.push(...matches);
|
|
11176
|
+
}
|
|
11177
|
+
}
|
|
11178
|
+
const commonEntities = ["revenue", "expenses", "profit", "margin", "income", "cost", "cogs", "ebitda"];
|
|
11179
|
+
for (const entity of commonEntities) {
|
|
11180
|
+
if (normalized.includes(entity)) {
|
|
11181
|
+
entities.push(entity);
|
|
11182
|
+
}
|
|
11183
|
+
}
|
|
11184
|
+
return { type, entities, periods };
|
|
11185
|
+
}
|
|
11186
|
+
|
|
10367
11187
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/editLocalFile/index.js
|
|
10368
11188
|
import { promises as fs11 } from "fs";
|
|
10369
11189
|
import { existsSync as existsSync6 } from "fs";
|
|
@@ -10835,7 +11655,14 @@ var cliOnlyTools = {
|
|
|
10835
11655
|
// Shell execution
|
|
10836
11656
|
bash_execute: bashExecuteTool,
|
|
10837
11657
|
// Git operations
|
|
10838
|
-
recent_changes: recentChangesTool
|
|
11658
|
+
recent_changes: recentChangesTool,
|
|
11659
|
+
// Lattice financial modeling tools
|
|
11660
|
+
lattice_create_model: latticeCreateModelTool,
|
|
11661
|
+
lattice_add_entity: latticeAddEntityTool,
|
|
11662
|
+
lattice_set_value: latticeSetValueTool,
|
|
11663
|
+
lattice_create_rule: latticeCreateRuleTool,
|
|
11664
|
+
lattice_query: latticeQueryTool,
|
|
11665
|
+
lattice_explain: latticeExplainTool
|
|
10839
11666
|
};
|
|
10840
11667
|
var generateTools = (userId, user, logger2, { db }, storage, imageGenerateStorage, statusUpdate, onStart, onFinish, llm, config, model, imageProcessorLambdaName, tools = b4mTools) => {
|
|
10841
11668
|
const context = {
|
|
@@ -10961,6 +11788,7 @@ var QuestStartBodySchema = z139.object({
|
|
|
10961
11788
|
enableMementos: z139.boolean().optional(),
|
|
10962
11789
|
enableArtifacts: z139.boolean().optional(),
|
|
10963
11790
|
enableAgents: z139.boolean().optional(),
|
|
11791
|
+
enableLattice: z139.boolean().optional(),
|
|
10964
11792
|
promptMeta: PromptMetaZodSchema,
|
|
10965
11793
|
tools: z139.array(z139.union([b4mLLMTools, z139.string()])).optional(),
|
|
10966
11794
|
mcpServers: z139.array(z139.string()).optional(),
|
|
@@ -13807,7 +14635,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
|
|
|
13807
14635
|
// package.json
|
|
13808
14636
|
var package_default = {
|
|
13809
14637
|
name: "@bike4mind/cli",
|
|
13810
|
-
version: "0.2.29-
|
|
14638
|
+
version: "0.2.29-feature-b4m-pi.18846+9859d25d9",
|
|
13811
14639
|
type: "module",
|
|
13812
14640
|
description: "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
13813
14641
|
license: "UNLICENSED",
|
|
@@ -13915,10 +14743,10 @@ var package_default = {
|
|
|
13915
14743
|
},
|
|
13916
14744
|
devDependencies: {
|
|
13917
14745
|
"@bike4mind/agents": "0.1.0",
|
|
13918
|
-
"@bike4mind/common": "2.50.1-
|
|
13919
|
-
"@bike4mind/mcp": "1.29.1-
|
|
13920
|
-
"@bike4mind/services": "2.48.1-
|
|
13921
|
-
"@bike4mind/utils": "2.5.1-
|
|
14746
|
+
"@bike4mind/common": "2.50.1-feature-b4m-pi.18846+9859d25d9",
|
|
14747
|
+
"@bike4mind/mcp": "1.29.1-feature-b4m-pi.18846+9859d25d9",
|
|
14748
|
+
"@bike4mind/services": "2.48.1-feature-b4m-pi.18846+9859d25d9",
|
|
14749
|
+
"@bike4mind/utils": "2.5.1-feature-b4m-pi.18846+9859d25d9",
|
|
13922
14750
|
"@types/better-sqlite3": "^7.6.13",
|
|
13923
14751
|
"@types/diff": "^5.0.9",
|
|
13924
14752
|
"@types/jsonwebtoken": "^9.0.4",
|
|
@@ -13935,7 +14763,7 @@ var package_default = {
|
|
|
13935
14763
|
optionalDependencies: {
|
|
13936
14764
|
"@vscode/ripgrep": "^1.17.0"
|
|
13937
14765
|
},
|
|
13938
|
-
gitHead: "
|
|
14766
|
+
gitHead: "9859d25d9a50e23c155ed70c318a3edfe9573f2a"
|
|
13939
14767
|
};
|
|
13940
14768
|
|
|
13941
14769
|
// src/config/constants.ts
|
|
@@ -16681,7 +17509,7 @@ Available commands:
|
|
|
16681
17509
|
/whoami - Show current authenticated user
|
|
16682
17510
|
/usage - Show credit usage and balance
|
|
16683
17511
|
/save <name> - Save current session
|
|
16684
|
-
/
|
|
17512
|
+
/sessions - List saved sessions
|
|
16685
17513
|
/config - Show configuration
|
|
16686
17514
|
|
|
16687
17515
|
API Configuration:
|
|
@@ -16730,7 +17558,6 @@ Custom Commands:
|
|
|
16730
17558
|
console.log(`\u2705 Session saved as "${sessionName}"`);
|
|
16731
17559
|
break;
|
|
16732
17560
|
}
|
|
16733
|
-
case "resume":
|
|
16734
17561
|
case "sessions": {
|
|
16735
17562
|
const sessions = await state.sessionStore.list(20);
|
|
16736
17563
|
if (sessions.length === 0) {
|