@flutchai/flutch-sdk 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -4448,7 +4448,9 @@ exports.EventProcessor = class EventProcessor {
4448
4448
  llmCalls: [],
4449
4449
  traceEvents: [],
4450
4450
  traceStartedAt: null,
4451
- traceCompletedAt: null
4451
+ traceCompletedAt: null,
4452
+ currentReasoningSteps: [],
4453
+ currentToolUse: null
4452
4454
  };
4453
4455
  }
4454
4456
  /**
@@ -4476,6 +4478,51 @@ exports.EventProcessor = class EventProcessor {
4476
4478
  }
4477
4479
  return [];
4478
4480
  }
4481
+ /**
4482
+ * Groups tool_use and input_json_delta into proper structure
4483
+ * tool_use.input → output (tool execution result)
4484
+ * input_json_delta.input → output (tool execution result, accumulated)
4485
+ */
4486
+ mapReasoningSteps(rawSteps) {
4487
+ const steps = [];
4488
+ let currentToolUse = null;
4489
+ for (const raw of rawSteps) {
4490
+ if (raw.type === "tool_use" || raw.type === "tool_call") {
4491
+ if (currentToolUse) {
4492
+ steps.push(currentToolUse);
4493
+ }
4494
+ currentToolUse = {
4495
+ index: raw.index || 0,
4496
+ type: "tool_use",
4497
+ name: raw.name,
4498
+ id: raw.id,
4499
+ input: "",
4500
+ // Parameters (IN) - filled separately or empty
4501
+ output: raw.input || ""
4502
+ // Result (OUT) - comes in tool_use.input
4503
+ };
4504
+ } else if (raw.type === "input_json_delta") {
4505
+ if (currentToolUse) {
4506
+ currentToolUse.output = (currentToolUse.output || "") + (raw.input || "");
4507
+ }
4508
+ } else {
4509
+ if (currentToolUse) {
4510
+ steps.push(currentToolUse);
4511
+ currentToolUse = null;
4512
+ }
4513
+ steps.push({
4514
+ index: raw.index || 0,
4515
+ type: raw.type,
4516
+ text: raw.text || "",
4517
+ metadata: raw.metadata
4518
+ });
4519
+ }
4520
+ }
4521
+ if (currentToolUse) {
4522
+ steps.push(currentToolUse);
4523
+ }
4524
+ return steps;
4525
+ }
4479
4526
  /**
4480
4527
  * Process a LangGraph stream event
4481
4528
  * Mutates accumulator to collect data from different channels
@@ -4498,8 +4545,44 @@ exports.EventProcessor = class EventProcessor {
4498
4545
  if (event.event === "on_chat_model_stream" && event.metadata?.stream_channel === "processing" /* PROCESSING */ && event.data?.chunk?.content) {
4499
4546
  const chunk = event.data.chunk.content;
4500
4547
  const blocks = this.normalizeContentBlocks(chunk);
4501
- if (blocks.length > 0 && onPartial) {
4502
- onPartial(JSON.stringify({ processing: blocks }));
4548
+ for (const block of blocks) {
4549
+ if (block.type === "tool_use" || block.type === "tool_call") {
4550
+ if (acc.currentToolUse) {
4551
+ acc.currentReasoningSteps.push(acc.currentToolUse);
4552
+ }
4553
+ acc.currentToolUse = {
4554
+ index: acc.currentReasoningSteps.length,
4555
+ type: "tool_use",
4556
+ name: block.name,
4557
+ id: block.id,
4558
+ input: block.input || "",
4559
+ output: ""
4560
+ };
4561
+ if (onPartial) {
4562
+ onPartial(
4563
+ JSON.stringify({
4564
+ processing_delta: {
4565
+ type: "step_started",
4566
+ step: acc.currentToolUse
4567
+ }
4568
+ })
4569
+ );
4570
+ }
4571
+ } else if (block.type === "input_json_delta") {
4572
+ if (acc.currentToolUse && onPartial) {
4573
+ const chunk2 = block.input || "";
4574
+ acc.currentToolUse.output += chunk2;
4575
+ onPartial(
4576
+ JSON.stringify({
4577
+ processing_delta: {
4578
+ type: "output_chunk",
4579
+ stepId: acc.currentToolUse.id,
4580
+ chunk: chunk2
4581
+ }
4582
+ })
4583
+ );
4584
+ }
4585
+ }
4503
4586
  }
4504
4587
  return;
4505
4588
  }
@@ -4536,29 +4619,59 @@ exports.EventProcessor = class EventProcessor {
4536
4619
  );
4537
4620
  }
4538
4621
  if (event.metadata?.stream_channel === "processing" /* PROCESSING */) {
4539
- const stepsRaw = output?.content || // AIMessageChunk object (direct)
4540
- output?.kwargs?.content || // Serialized LangChain format
4541
- event.data?.chunk?.content || // Older version
4542
- [];
4543
- let steps;
4544
- if (Array.isArray(stepsRaw)) {
4545
- steps = stepsRaw;
4546
- } else if (typeof stepsRaw === "string" && stepsRaw.trim().length > 0) {
4547
- steps = [
4548
- {
4549
- index: 0,
4550
- type: "text",
4551
- text: stepsRaw.trim()
4552
- }
4553
- ];
4554
- } else {
4555
- steps = [];
4622
+ if (acc.currentToolUse) {
4623
+ acc.currentReasoningSteps.push(acc.currentToolUse);
4624
+ acc.currentToolUse = null;
4556
4625
  }
4557
- if (steps.length > 0) {
4626
+ if (acc.currentReasoningSteps.length > 0) {
4558
4627
  acc.reasoningChains.push({
4559
- steps,
4628
+ steps: acc.currentReasoningSteps,
4560
4629
  isComplete: true
4561
4630
  });
4631
+ if (onPartial) {
4632
+ onPartial(
4633
+ JSON.stringify({
4634
+ processing_delta: {
4635
+ type: "chain_completed"
4636
+ }
4637
+ })
4638
+ );
4639
+ }
4640
+ acc.currentReasoningSteps = [];
4641
+ } else {
4642
+ const stepsRaw = output?.content || // AIMessageChunk object (direct)
4643
+ output?.kwargs?.content || // Serialized LangChain format
4644
+ event.data?.chunk?.content || // Older version
4645
+ [];
4646
+ let steps;
4647
+ if (Array.isArray(stepsRaw)) {
4648
+ steps = this.mapReasoningSteps(stepsRaw);
4649
+ } else if (typeof stepsRaw === "string" && stepsRaw.trim().length > 0) {
4650
+ steps = [
4651
+ {
4652
+ index: 0,
4653
+ type: "text",
4654
+ text: stepsRaw.trim()
4655
+ }
4656
+ ];
4657
+ } else {
4658
+ steps = [];
4659
+ }
4660
+ if (steps.length > 0) {
4661
+ acc.reasoningChains.push({
4662
+ steps,
4663
+ isComplete: true
4664
+ });
4665
+ if (onPartial) {
4666
+ onPartial(
4667
+ JSON.stringify({
4668
+ processing_delta: {
4669
+ type: "chain_completed"
4670
+ }
4671
+ })
4672
+ );
4673
+ }
4674
+ }
4562
4675
  }
4563
4676
  }
4564
4677
  return;