@bubblelab/bubble-core 0.1.212 → 0.1.213
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/bubble-bundle.d.ts +150 -150
- package/dist/bubbles/service-bubble/agi-inc.d.ts +112 -112
- package/dist/bubbles/service-bubble/ai-agent.d.ts +72 -72
- package/dist/bubbles/service-bubble/ai-agent.d.ts.map +1 -1
- package/dist/bubbles/service-bubble/ai-agent.js +192 -25
- package/dist/bubbles/service-bubble/ai-agent.js.map +1 -1
- package/dist/bubbles/service-bubble/airtable.d.ts +158 -158
- package/dist/bubbles/service-bubble/apify/apify.d.ts +26 -26
- package/dist/bubbles/service-bubble/ashby/ashby.d.ts +90 -90
- package/dist/bubbles/service-bubble/ashby/ashby.schema.d.ts +70 -70
- package/dist/bubbles/service-bubble/assembled/assembled.d.ts +55 -55
- package/dist/bubbles/service-bubble/assembled/assembled.schema.d.ts +24 -24
- package/dist/bubbles/service-bubble/attio/attio.d.ts +66 -66
- package/dist/bubbles/service-bubble/attio/attio.schema.d.ts +2 -2
- package/dist/bubbles/service-bubble/browserbase/browserbase.d.ts +58 -58
- package/dist/bubbles/service-bubble/browserbase/browserbase.schema.d.ts +12 -12
- package/dist/bubbles/service-bubble/confluence/confluence.d.ts +43 -43
- package/dist/bubbles/service-bubble/confluence/confluence.schema.d.ts +4 -4
- package/dist/bubbles/service-bubble/crustdata/crustdata.d.ts +94 -94
- package/dist/bubbles/service-bubble/crustdata/crustdata.schema.d.ts +158 -158
- package/dist/bubbles/service-bubble/eleven-labs.d.ts +48 -48
- package/dist/bubbles/service-bubble/firecrawl.d.ts +284 -284
- package/dist/bubbles/service-bubble/followupboss.d.ts +260 -260
- package/dist/bubbles/service-bubble/fullenrich/fullenrich.d.ts +44 -44
- package/dist/bubbles/service-bubble/fullenrich/fullenrich.schema.d.ts +124 -124
- package/dist/bubbles/service-bubble/github.d.ts +102 -102
- package/dist/bubbles/service-bubble/gmail.d.ts +238 -238
- package/dist/bubbles/service-bubble/google-calendar.d.ts +132 -132
- package/dist/bubbles/service-bubble/google-drive.d.ts +146 -146
- package/dist/bubbles/service-bubble/google-sheets/google-sheets.d.ts +52 -52
- package/dist/bubbles/service-bubble/google-sheets/google-sheets.schema.d.ts +26 -26
- package/dist/bubbles/service-bubble/hello-world.d.ts +4 -4
- package/dist/bubbles/service-bubble/http.d.ts +10 -10
- package/dist/bubbles/service-bubble/hubspot/hubspot.d.ts +20 -20
- package/dist/bubbles/service-bubble/insforge-db.d.ts +12 -12
- package/dist/bubbles/service-bubble/jira/jira.d.ts +62 -62
- package/dist/bubbles/service-bubble/jira/jira.schema.d.ts +31 -31
- package/dist/bubbles/service-bubble/linear/linear.d.ts +44 -44
- package/dist/bubbles/service-bubble/linear/linear.schema.d.ts +15 -15
- package/dist/bubbles/service-bubble/notion/notion.d.ts +184 -184
- package/dist/bubbles/service-bubble/postgresql.d.ts +12 -12
- package/dist/bubbles/service-bubble/posthog/posthog.d.ts +33 -33
- package/dist/bubbles/service-bubble/posthog/posthog.schema.d.ts +30 -30
- package/dist/bubbles/service-bubble/resend.d.ts +24 -24
- package/dist/bubbles/service-bubble/s3/s3.d.ts +44 -44
- package/dist/bubbles/service-bubble/s3/s3.schema.d.ts +14 -14
- package/dist/bubbles/service-bubble/sendsafely/sendsafely.d.ts +18 -18
- package/dist/bubbles/service-bubble/sendsafely/sendsafely.schema.d.ts +6 -6
- package/dist/bubbles/service-bubble/slack/slack.d.ts +224 -224
- package/dist/bubbles/service-bubble/storage.d.ts +88 -88
- package/dist/bubbles/service-bubble/stripe/stripe.d.ts +123 -123
- package/dist/bubbles/service-bubble/stripe/stripe.schema.d.ts +87 -87
- package/dist/bubbles/service-bubble/telegram.d.ts +120 -120
- package/dist/bubbles/tool-bubble/amazon-shopping-tool/amazon-shopping-tool.d.ts +28 -28
- package/dist/bubbles/tool-bubble/amazon-shopping-tool/amazon-shopping-tool.schema.d.ts +5 -5
- package/dist/bubbles/tool-bubble/browser-tools/linkedin-accept-invitations/tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/browser-tools/linkedin-connection/tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/browser-tools/linkedin-received-invitations/tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/browser-tools/linkedin-sent-invitations/tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/bubbleflow-validation-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/chart-js-tool.d.ts +8 -8
- package/dist/bubbles/tool-bubble/code-edit-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/company-enrichment-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/get-bubble-details-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/get-trigger-detail-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/google-maps-tool.d.ts +8 -8
- package/dist/bubbles/tool-bubble/instagram-tool.d.ts +8 -8
- package/dist/bubbles/tool-bubble/linkedin-tool.d.ts +345 -345
- package/dist/bubbles/tool-bubble/list-airtable-bases-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/list-airtable-tables-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/list-bubbles-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/list-capabilities-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/people-search-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/reddit-scrape-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/research-agent-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/sql-query-tool.d.ts +8 -8
- package/dist/bubbles/tool-bubble/tiktok-tool.d.ts +60 -60
- package/dist/bubbles/tool-bubble/tool-template.d.ts +4 -4
- package/dist/bubbles/tool-bubble/twitter-tool.d.ts +132 -132
- package/dist/bubbles/tool-bubble/web-crawl-tool.d.ts +8 -8
- package/dist/bubbles/tool-bubble/web-extract-tool.d.ts +8 -8
- package/dist/bubbles/tool-bubble/web-scrape-tool.d.ts +8 -8
- package/dist/bubbles/tool-bubble/web-search-tool.d.ts +8 -8
- package/dist/bubbles/tool-bubble/yc-scraper-tool.d.ts +12 -12
- package/dist/bubbles/tool-bubble/youtube-tool.d.ts +28 -28
- package/dist/bubbles/workflow-bubble/database-analyzer.workflow.d.ts +4 -4
- package/dist/bubbles/workflow-bubble/generate-document.workflow.d.ts +16 -16
- package/dist/bubbles/workflow-bubble/parse-document.workflow.d.ts +8 -8
- package/dist/bubbles/workflow-bubble/pdf-form-operations.workflow.d.ts +58 -58
- package/dist/bubbles/workflow-bubble/pdf-ocr.workflow.d.ts +8 -8
- package/dist/bubbles/workflow-bubble/slack-data-assistant.workflow.d.ts +4 -4
- package/dist/bubbles/workflow-bubble/slack-formatter-agent.d.ts +12 -12
- package/dist/bubbles/workflow-bubble/slack-notifier.workflow.d.ts +4 -4
- package/dist/bubbles.json +1 -1
- package/package.json +2 -2
|
@@ -1163,8 +1163,9 @@ export class AIAgentBubble extends ServiceBubble {
|
|
|
1163
1163
|
capabilityTask: task,
|
|
1164
1164
|
};
|
|
1165
1165
|
this._trace('use-capability', `snapshotted master state before delegating`, {
|
|
1166
|
-
|
|
1166
|
+
masterMessageCount: this._currentGraphMessages.length,
|
|
1167
1167
|
capabilityId,
|
|
1168
|
+
capabilityTask: task,
|
|
1168
1169
|
});
|
|
1169
1170
|
}
|
|
1170
1171
|
const subAgent = new AIAgentBubble({
|
|
@@ -1460,6 +1461,19 @@ export class AIAgentBubble extends ServiceBubble {
|
|
|
1460
1461
|
messages: currentMessages,
|
|
1461
1462
|
bubbleContext: this.context,
|
|
1462
1463
|
});
|
|
1464
|
+
// Trace hook result
|
|
1465
|
+
if (beforeHook) {
|
|
1466
|
+
this._trace('hook', `beforeToolCall:${toolCall.name}`, {
|
|
1467
|
+
toolName: toolCall.name,
|
|
1468
|
+
shouldSkip: hookResult_before?.shouldSkip ?? false,
|
|
1469
|
+
messagesModified: !!hookResult_before?.messages,
|
|
1470
|
+
});
|
|
1471
|
+
}
|
|
1472
|
+
this._trace('tool', `start:${toolCall.name}`, {
|
|
1473
|
+
toolName: toolCall.name,
|
|
1474
|
+
toolCallId: toolCall.id ?? '',
|
|
1475
|
+
input: toolCall.args,
|
|
1476
|
+
});
|
|
1463
1477
|
this.streamingCallback?.({
|
|
1464
1478
|
type: 'tool_call_start',
|
|
1465
1479
|
data: {
|
|
@@ -1480,6 +1494,13 @@ export class AIAgentBubble extends ServiceBubble {
|
|
|
1480
1494
|
toolCall.args = hookResult_before.toolInput;
|
|
1481
1495
|
// If hook requests skipping, create synthetic ToolMessage and stop agent loop
|
|
1482
1496
|
if (hookResult_before.shouldSkip) {
|
|
1497
|
+
this._trace('tool', `skipped:${toolCall.name}`, {
|
|
1498
|
+
toolName: toolCall.name,
|
|
1499
|
+
toolCallId: toolCall.id ?? '',
|
|
1500
|
+
input: toolCall.args,
|
|
1501
|
+
skipMessage: hookResult_before.skipMessage || 'Tool execution was skipped.',
|
|
1502
|
+
reason: 'beforeToolCall hook requested skip',
|
|
1503
|
+
});
|
|
1483
1504
|
const skipMsg = new ToolMessage({
|
|
1484
1505
|
content: hookResult_before.skipMessage || 'Tool execution was skipped.',
|
|
1485
1506
|
tool_call_id: toolCall.id,
|
|
@@ -1507,6 +1528,14 @@ export class AIAgentBubble extends ServiceBubble {
|
|
|
1507
1528
|
});
|
|
1508
1529
|
toolMessages.push(toolMessage);
|
|
1509
1530
|
currentMessages = [...currentMessages, toolMessage];
|
|
1531
|
+
const toolDurationMs = Date.now() - startTime;
|
|
1532
|
+
this._trace('tool', `complete:${toolCall.name}`, {
|
|
1533
|
+
toolName: toolCall.name,
|
|
1534
|
+
toolCallId: toolCall.id ?? '',
|
|
1535
|
+
input: toolCall.args,
|
|
1536
|
+
output: toolOutput,
|
|
1537
|
+
durationMs: toolDurationMs,
|
|
1538
|
+
});
|
|
1510
1539
|
// Call afterToolCall hook — capability-scoped hook takes priority, then global
|
|
1511
1540
|
const afterHook = this.capabilityAfterHooks.get(toolCall.name) ??
|
|
1512
1541
|
this.afterToolCallHook;
|
|
@@ -1517,6 +1546,14 @@ export class AIAgentBubble extends ServiceBubble {
|
|
|
1517
1546
|
messages: currentMessages,
|
|
1518
1547
|
bubbleContext: this.context,
|
|
1519
1548
|
});
|
|
1549
|
+
// Trace hook result
|
|
1550
|
+
if (afterHook) {
|
|
1551
|
+
this._trace('hook', `afterToolCall:${toolCall.name}`, {
|
|
1552
|
+
toolName: toolCall.name,
|
|
1553
|
+
shouldStop: hookResult_after?.shouldStop ?? false,
|
|
1554
|
+
messagesModified: !!hookResult_after?.messages,
|
|
1555
|
+
});
|
|
1556
|
+
}
|
|
1520
1557
|
// If hook returns modified messages, update current messages
|
|
1521
1558
|
if (hookResult_after) {
|
|
1522
1559
|
if (hookResult_after.messages) {
|
|
@@ -1535,7 +1572,7 @@ export class AIAgentBubble extends ServiceBubble {
|
|
|
1535
1572
|
input: toolCall.args,
|
|
1536
1573
|
tool: toolCall.name,
|
|
1537
1574
|
output: toolOutput,
|
|
1538
|
-
duration:
|
|
1575
|
+
duration: toolDurationMs,
|
|
1539
1576
|
variableId: this.context?.variableId,
|
|
1540
1577
|
},
|
|
1541
1578
|
});
|
|
@@ -1543,6 +1580,13 @@ export class AIAgentBubble extends ServiceBubble {
|
|
|
1543
1580
|
catch (error) {
|
|
1544
1581
|
console.error(`Error executing tool ${toolCall.name}:`, error);
|
|
1545
1582
|
const errorContent = `Error: ${error instanceof Error ? error.message : 'Unknown error'}`;
|
|
1583
|
+
this._trace('tool', `error:${toolCall.name}`, {
|
|
1584
|
+
toolName: toolCall.name,
|
|
1585
|
+
toolCallId: toolCall.id ?? '',
|
|
1586
|
+
input: toolCall.args,
|
|
1587
|
+
error: errorContent,
|
|
1588
|
+
durationMs: Date.now() - startTime,
|
|
1589
|
+
});
|
|
1546
1590
|
const errorMessage = new ToolMessage({
|
|
1547
1591
|
content: errorContent,
|
|
1548
1592
|
tool_call_id: toolCall.id,
|
|
@@ -1584,17 +1628,27 @@ export class AIAgentBubble extends ServiceBubble {
|
|
|
1584
1628
|
// Define the agent node
|
|
1585
1629
|
const agentNode = async ({ messages }) => {
|
|
1586
1630
|
this._trace('agentNode', `LLM CALL`, {
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1631
|
+
model: this.params.model.model,
|
|
1632
|
+
temperature: this.params.model.temperature,
|
|
1633
|
+
messageCount: messages.length,
|
|
1634
|
+
messages: messages.map((m) => {
|
|
1635
|
+
const role = m._getType();
|
|
1636
|
+
const content = typeof m.content === 'string'
|
|
1637
|
+
? m.content
|
|
1638
|
+
: JSON.stringify(m.content);
|
|
1639
|
+
const entry = { role, content };
|
|
1640
|
+
if ('tool_calls' in m && Array.isArray(m.tool_calls) && m.tool_calls.length > 0) {
|
|
1641
|
+
entry.toolCalls = m.tool_calls.map((tc) => ({
|
|
1642
|
+
name: tc.name,
|
|
1643
|
+
id: tc.id,
|
|
1644
|
+
args: tc.args,
|
|
1645
|
+
}));
|
|
1646
|
+
}
|
|
1647
|
+
if ('tool_call_id' in m) {
|
|
1648
|
+
entry.toolCallId = m.tool_call_id;
|
|
1649
|
+
}
|
|
1650
|
+
return entry;
|
|
1651
|
+
}),
|
|
1598
1652
|
});
|
|
1599
1653
|
// systemPrompt is already enhanced by beforeAction() if expectedOutputSchema was provided
|
|
1600
1654
|
// Use cache_control for Anthropic models to cache the system prompt across iterations
|
|
@@ -1702,11 +1756,45 @@ export class AIAgentBubble extends ServiceBubble {
|
|
|
1702
1756
|
},
|
|
1703
1757
|
],
|
|
1704
1758
|
});
|
|
1759
|
+
this._trace('agentNode', 'LLM RESPONSE', {
|
|
1760
|
+
content: typeof response.content === 'string'
|
|
1761
|
+
? response.content
|
|
1762
|
+
: JSON.stringify(response.content),
|
|
1763
|
+
toolCalls: ('tool_calls' in response && Array.isArray(response.tool_calls))
|
|
1764
|
+
? response.tool_calls.map((tc) => ({
|
|
1765
|
+
name: tc.name, id: tc.id, args: tc.args,
|
|
1766
|
+
}))
|
|
1767
|
+
: undefined,
|
|
1768
|
+
tokenUsage: response.usage_metadata
|
|
1769
|
+
? {
|
|
1770
|
+
inputTokens: response.usage_metadata.input_tokens,
|
|
1771
|
+
outputTokens: response.usage_metadata.output_tokens,
|
|
1772
|
+
totalTokens: response.usage_metadata.total_tokens,
|
|
1773
|
+
}
|
|
1774
|
+
: undefined,
|
|
1775
|
+
});
|
|
1705
1776
|
return { messages: [response] };
|
|
1706
1777
|
}
|
|
1707
1778
|
else {
|
|
1708
1779
|
// Non-streaming fallback
|
|
1709
1780
|
const response = await modelWithTools.invoke(allMessages);
|
|
1781
|
+
this._trace('agentNode', 'LLM RESPONSE', {
|
|
1782
|
+
content: typeof response.content === 'string'
|
|
1783
|
+
? response.content
|
|
1784
|
+
: JSON.stringify(response.content),
|
|
1785
|
+
toolCalls: ('tool_calls' in response && Array.isArray(response.tool_calls))
|
|
1786
|
+
? response.tool_calls.map((tc) => ({
|
|
1787
|
+
name: tc.name, id: tc.id, args: tc.args,
|
|
1788
|
+
}))
|
|
1789
|
+
: undefined,
|
|
1790
|
+
tokenUsage: response.usage_metadata
|
|
1791
|
+
? {
|
|
1792
|
+
inputTokens: response.usage_metadata.input_tokens,
|
|
1793
|
+
outputTokens: response.usage_metadata.output_tokens,
|
|
1794
|
+
totalTokens: response.usage_metadata.total_tokens,
|
|
1795
|
+
}
|
|
1796
|
+
: undefined,
|
|
1797
|
+
});
|
|
1710
1798
|
return { messages: [response] };
|
|
1711
1799
|
}
|
|
1712
1800
|
}
|
|
@@ -1798,37 +1886,46 @@ export class AIAgentBubble extends ServiceBubble {
|
|
|
1798
1886
|
// Check if the last AI message has tool calls
|
|
1799
1887
|
if (lastAIMessage?.tool_calls && lastAIMessage.tool_calls.length > 0) {
|
|
1800
1888
|
this._trace('afterLLMCheck', `→ tools`, {
|
|
1889
|
+
result: 'tools',
|
|
1890
|
+
toolCallCount: lastAIMessage.tool_calls.length,
|
|
1801
1891
|
toolCalls: lastAIMessage.tool_calls
|
|
1802
1892
|
.map((tc) => `${tc.name}(${tc.id?.slice(-8)})`)
|
|
1803
1893
|
.join(', '),
|
|
1804
1894
|
});
|
|
1805
1895
|
return 'tools';
|
|
1806
1896
|
}
|
|
1807
|
-
this._trace('afterLLMCheck', `→ __end__ (no tool calls)
|
|
1897
|
+
this._trace('afterLLMCheck', `→ __end__ (no tool calls)`, {
|
|
1898
|
+
result: '__end__',
|
|
1899
|
+
reason: 'no tool calls',
|
|
1900
|
+
});
|
|
1808
1901
|
return '__end__';
|
|
1809
1902
|
};
|
|
1810
1903
|
// Define conditional edge after tools to check if we should stop
|
|
1811
1904
|
const shouldContinueAfterTools = () => {
|
|
1812
1905
|
const execMeta = this.context?.executionMeta;
|
|
1813
1906
|
this._trace('shouldContinueAfterTools', `CHECK`, {
|
|
1814
|
-
|
|
1907
|
+
shouldStopAfterTools: this.shouldStopAfterTools,
|
|
1815
1908
|
pendingApproval: !!execMeta?._pendingApproval,
|
|
1816
1909
|
});
|
|
1817
1910
|
// Check if the afterToolCall hook requested stopping
|
|
1818
1911
|
if (this.shouldStopAfterTools) {
|
|
1819
|
-
this._trace('shouldContinueAfterTools', `→ __end__ (shouldStopAfterTools)
|
|
1912
|
+
this._trace('shouldContinueAfterTools', `→ __end__ (shouldStopAfterTools)`, { result: '__end__', reason: 'shouldStopAfterTools', shouldStopAfterTools: true });
|
|
1820
1913
|
return '__end__';
|
|
1821
1914
|
}
|
|
1822
1915
|
// Check for pending approval signal from sub-agent (shared via executionMeta).
|
|
1823
1916
|
// In multi-capability mode the master and sub-agent share the same BubbleContext,
|
|
1824
1917
|
// so a sub-agent setting _pendingApproval is visible here.
|
|
1825
1918
|
if (execMeta?._pendingApproval) {
|
|
1826
|
-
this._trace('shouldContinueAfterTools', `→ __end__ (pendingApproval)
|
|
1919
|
+
this._trace('shouldContinueAfterTools', `→ __end__ (pendingApproval)`, {
|
|
1920
|
+
result: '__end__', reason: 'pendingApproval', pendingApproval: true,
|
|
1921
|
+
});
|
|
1827
1922
|
this.shouldStopAfterTools = true;
|
|
1828
1923
|
return '__end__';
|
|
1829
1924
|
}
|
|
1830
1925
|
// Otherwise continue back to agent
|
|
1831
|
-
this._trace('shouldContinueAfterTools', `→ agent (continue)
|
|
1926
|
+
this._trace('shouldContinueAfterTools', `→ agent (continue)`, {
|
|
1927
|
+
result: 'agent',
|
|
1928
|
+
});
|
|
1832
1929
|
return 'agent';
|
|
1833
1930
|
};
|
|
1834
1931
|
// Build the graph
|
|
@@ -1976,19 +2073,62 @@ export class AIAgentBubble extends ServiceBubble {
|
|
|
1976
2073
|
shouldStopAfterTools: this.shouldStopAfterTools,
|
|
1977
2074
|
});
|
|
1978
2075
|
// If a new approval was triggered during V2 resume (subagent set _pendingApproval),
|
|
1979
|
-
//
|
|
2076
|
+
// skip the agent loop entirely. The subagent is blocked on approval — running the
|
|
2077
|
+
// master LLM would just see an empty response and re-delegate, creating duplicate
|
|
2078
|
+
// approvals. Return the last AI message from the repaired messages as the response.
|
|
1980
2079
|
if (resumeExecMeta?._pendingApproval) {
|
|
1981
|
-
|
|
1982
|
-
this.
|
|
2080
|
+
const approval = resumeExecMeta._pendingApproval;
|
|
2081
|
+
this._trace('v2-resume', `_pendingApproval detected — skipping agent loop`, {
|
|
2082
|
+
action: approval.action,
|
|
2083
|
+
targetFlowName: approval.targetFlowName,
|
|
2084
|
+
});
|
|
2085
|
+
// Use the subagent's last AI text (captured in _pendingApproval)
|
|
2086
|
+
// as the response. Do NOT use the master's original AI text — that
|
|
2087
|
+
// would cause the same stale message to be posted to Slack on every resume.
|
|
2088
|
+
const lastAIText = resumeExecMeta._pendingApproval.lastAIText;
|
|
2089
|
+
const action = approval.action ?? 'proceed';
|
|
2090
|
+
const flowName = approval.targetFlowName;
|
|
2091
|
+
const resumeResponse = lastAIText
|
|
2092
|
+
? lastAIText
|
|
2093
|
+
: flowName
|
|
2094
|
+
? `Requesting approval to **${action}** "${flowName}".`
|
|
2095
|
+
: `Requesting approval to **${action}**.`;
|
|
2096
|
+
const formattedResult = formatFinalResponse(resumeResponse, modelConfig.model, jsonMode);
|
|
2097
|
+
return {
|
|
2098
|
+
response: formattedResult.response,
|
|
2099
|
+
toolCalls: [],
|
|
2100
|
+
iterations: 0,
|
|
2101
|
+
error: '',
|
|
2102
|
+
success: true,
|
|
2103
|
+
};
|
|
1983
2104
|
}
|
|
1984
2105
|
initialMessages.push(...repairedMessages);
|
|
1985
2106
|
}
|
|
1986
2107
|
else if (resumeState &&
|
|
1987
2108
|
Array.isArray(resumeState) &&
|
|
1988
2109
|
resumeState.length > 0) {
|
|
1989
|
-
this._trace('v1-resume', `restoring ${resumeState.length} messages (single-cap/subagent path)`);
|
|
1990
2110
|
const { mapStoredMessagesToChatMessages } = await import('@langchain/core/messages');
|
|
1991
2111
|
const restored = mapStoredMessagesToChatMessages(resumeState);
|
|
2112
|
+
this._trace('v1-resume', `START`, {
|
|
2113
|
+
savedMessageCount: resumeState.length,
|
|
2114
|
+
restoredMessageCount: restored.length,
|
|
2115
|
+
restoredMessages: restored.map((m) => {
|
|
2116
|
+
const role = m._getType();
|
|
2117
|
+
const content = typeof m.content === 'string'
|
|
2118
|
+
? m.content
|
|
2119
|
+
: JSON.stringify(m.content);
|
|
2120
|
+
const entry = { role, content };
|
|
2121
|
+
if ('tool_calls' in m && Array.isArray(m.tool_calls) && m.tool_calls.length > 0) {
|
|
2122
|
+
entry.toolCalls = m.tool_calls.map((tc) => ({
|
|
2123
|
+
name: tc.name, id: tc.id, args: tc.args,
|
|
2124
|
+
}));
|
|
2125
|
+
}
|
|
2126
|
+
if ('tool_call_id' in m) {
|
|
2127
|
+
entry.toolCallId = m.tool_call_id;
|
|
2128
|
+
}
|
|
2129
|
+
return entry;
|
|
2130
|
+
}),
|
|
2131
|
+
});
|
|
1992
2132
|
// Collect existing tool_call_ids that already have ToolMessage responses
|
|
1993
2133
|
const existingToolResultIds = new Set();
|
|
1994
2134
|
for (const msg of restored) {
|
|
@@ -2034,6 +2174,13 @@ export class AIAgentBubble extends ServiceBubble {
|
|
|
2034
2174
|
if (i === approvalAiMsgIndex && toolsByName.has(tc.name)) {
|
|
2035
2175
|
// This is the approval-triggering AIMessage — execute the tool directly
|
|
2036
2176
|
// This bypasses beforeToolCall (no re-approval check) and gives real results
|
|
2177
|
+
const resumeStartTime = Date.now();
|
|
2178
|
+
this._trace('tool', `start:${tc.name}`, {
|
|
2179
|
+
toolName: tc.name,
|
|
2180
|
+
toolCallId: tc.id ?? '',
|
|
2181
|
+
input: tc.args,
|
|
2182
|
+
resumeDirect: true,
|
|
2183
|
+
});
|
|
2037
2184
|
try {
|
|
2038
2185
|
console.log(`[AIAgent] Resume: executing approved tool "${tc.name}" directly`);
|
|
2039
2186
|
const tool = toolsByName.get(tc.name);
|
|
@@ -2044,10 +2191,26 @@ export class AIAgentBubble extends ServiceBubble {
|
|
|
2044
2191
|
content.slice(0, AIAgentBubble.MAX_TOOL_RESULT_CHARS) +
|
|
2045
2192
|
`\n\n[... truncated — result was ${content.length} chars, limit is ${AIAgentBubble.MAX_TOOL_RESULT_CHARS}]`;
|
|
2046
2193
|
}
|
|
2194
|
+
this._trace('tool', `complete:${tc.name}`, {
|
|
2195
|
+
toolName: tc.name,
|
|
2196
|
+
toolCallId: tc.id ?? '',
|
|
2197
|
+
input: tc.args,
|
|
2198
|
+
output: result,
|
|
2199
|
+
durationMs: Date.now() - resumeStartTime,
|
|
2200
|
+
resumeDirect: true,
|
|
2201
|
+
});
|
|
2047
2202
|
repairedMessages.push(new ToolMessage({ content, tool_call_id: tc.id }));
|
|
2048
2203
|
}
|
|
2049
2204
|
catch (err) {
|
|
2050
2205
|
console.warn(`[AIAgent] Resume: direct tool execution failed for "${tc.name}":`, err);
|
|
2206
|
+
this._trace('tool', `error:${tc.name}`, {
|
|
2207
|
+
toolName: tc.name,
|
|
2208
|
+
toolCallId: tc.id ?? '',
|
|
2209
|
+
input: tc.args,
|
|
2210
|
+
error: err instanceof Error ? err.message : String(err),
|
|
2211
|
+
durationMs: Date.now() - resumeStartTime,
|
|
2212
|
+
resumeDirect: true,
|
|
2213
|
+
});
|
|
2051
2214
|
repairedMessages.push(new ToolMessage({
|
|
2052
2215
|
content: `Tool execution failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
2053
2216
|
tool_call_id: tc.id,
|
|
@@ -2070,6 +2233,10 @@ export class AIAgentBubble extends ServiceBubble {
|
|
|
2070
2233
|
if (approvalAiMsgIndex >= 0 && resumeExecMeta?._approvedAction) {
|
|
2071
2234
|
delete resumeExecMeta._approvedAction;
|
|
2072
2235
|
}
|
|
2236
|
+
this._trace('v1-resume', `DONE`, {
|
|
2237
|
+
repairedMessageCount: repairedMessages.length,
|
|
2238
|
+
types: repairedMessages.map((m) => m._getType()).join(','),
|
|
2239
|
+
});
|
|
2073
2240
|
initialMessages.push(...repairedMessages);
|
|
2074
2241
|
}
|
|
2075
2242
|
else if (conversationHistory && conversationHistory.length > 0) {
|
|
@@ -2164,15 +2331,15 @@ export class AIAgentBubble extends ServiceBubble {
|
|
|
2164
2331
|
initialMessages.push(humanMessage);
|
|
2165
2332
|
}
|
|
2166
2333
|
this._trace('agent-loop', `STARTING graph.invoke`, {
|
|
2167
|
-
|
|
2168
|
-
initialMsgTypes: initialMessages.map((m) => m._getType()).join(','),
|
|
2169
|
-
shouldStopAfterTools: this.shouldStopAfterTools,
|
|
2334
|
+
initialMessageCount: initialMessages.length,
|
|
2170
2335
|
maxIterations,
|
|
2336
|
+
model: this.params.model.model,
|
|
2171
2337
|
});
|
|
2172
2338
|
const result = await graph.invoke({ messages: initialMessages }, { recursionLimit: maxIterations });
|
|
2173
2339
|
this._trace('agent-loop', `graph.invoke COMPLETED`, {
|
|
2174
2340
|
totalMessages: result.messages.length,
|
|
2175
2341
|
pendingApproval: !!this.context?.executionMeta?._pendingApproval,
|
|
2342
|
+
model: this.params.model.model,
|
|
2176
2343
|
});
|
|
2177
2344
|
console.log('[AIAgent] Graph execution completed');
|
|
2178
2345
|
console.log('[AIAgent] Total messages:', result.messages.length);
|