@agentick/core 0.5.0 → 0.6.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 +3 -9
- package/dist/.tsbuildinfo.build +1 -1
- package/dist/app/session.d.ts.map +1 -1
- package/dist/app/session.js +147 -75
- package/dist/app/session.js.map +1 -1
- package/dist/com/object-model.d.ts +12 -0
- package/dist/com/object-model.d.ts.map +1 -1
- package/dist/com/object-model.js +27 -0
- package/dist/com/object-model.js.map +1 -1
- package/dist/compiler/collector.js +1 -0
- package/dist/compiler/collector.js.map +1 -1
- package/dist/engine/tool-executor.d.ts +6 -1
- package/dist/engine/tool-executor.d.ts.map +1 -1
- package/dist/engine/tool-executor.js +16 -1
- package/dist/engine/tool-executor.js.map +1 -1
- package/dist/hooks/lifecycle.d.ts +14 -30
- package/dist/hooks/lifecycle.d.ts.map +1 -1
- package/dist/hooks/lifecycle.js +15 -31
- package/dist/hooks/lifecycle.js.map +1 -1
- package/dist/hooks/runtime-context.d.ts +6 -7
- package/dist/hooks/runtime-context.d.ts.map +1 -1
- package/dist/hooks/runtime-context.js +18 -9
- package/dist/hooks/runtime-context.js.map +1 -1
- package/dist/hooks/types.d.ts +47 -14
- package/dist/hooks/types.d.ts.map +1 -1
- package/dist/hooks/types.js.map +1 -1
- package/dist/jsx/components/timeline.d.ts.map +1 -1
- package/dist/jsx/components/timeline.js +5 -10
- package/dist/jsx/components/timeline.js.map +1 -1
- package/dist/model/adapter-helpers.d.ts +0 -4
- package/dist/model/adapter-helpers.d.ts.map +1 -1
- package/dist/model/adapter-helpers.js +0 -9
- package/dist/model/adapter-helpers.js.map +1 -1
- package/dist/model/stream-accumulator.d.ts +4 -0
- package/dist/model/stream-accumulator.d.ts.map +1 -1
- package/dist/model/stream-accumulator.js +59 -0
- package/dist/model/stream-accumulator.js.map +1 -1
- package/dist/testing/mocks.d.ts +10 -0
- package/dist/testing/mocks.d.ts.map +1 -1
- package/dist/testing/mocks.js +30 -0
- package/dist/testing/mocks.js.map +1 -1
- package/dist/testing/render-agent.d.ts.map +1 -1
- package/dist/testing/render-agent.js +3 -11
- package/dist/testing/render-agent.js.map +1 -1
- package/dist/tool/tool.d.ts +18 -0
- package/dist/tool/tool.d.ts.map +1 -1
- package/dist/tool/tool.js +14 -0
- package/dist/tool/tool.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/app/session.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAGL,OAAO,EAKP,KAAK,SAAS,EAGf,MAAM,kBAAkB,CAAC;AAa1B,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAG9C,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/app/session.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAGL,OAAO,EAKP,KAAK,SAAS,EAGf,MAAM,kBAAkB,CAAC;AAa1B,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAG9C,OAAO,KAAK,EAGV,OAAO,EAIR,MAAM,kBAAkB,CAAC;AAmB1B,OAAO,KAAK,EACV,OAAO,EACP,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EAEjB,WAAW,EACX,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,sBAAsB,EACtB,SAAS,EACT,YAAY,EAIb,MAAM,SAAS,CAAC;AA2DjB;;;;;GAKG;AACH,qBAAa,WAAW,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAE,SAAQ,YAAa,YAAW,OAAO,CAAC,CAAC,CAAC;IAC9F,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA6B;IAGjD,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,mBAAmB,CAAuB;IAGlD,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,GAAG,CAAoB;IAC/B,OAAO,CAAC,iBAAiB,CAAkC;IAC3D,OAAO,CAAC,SAAS,CAAwC;IAGzD,OAAO,CAAC,mBAAmB,CAAyB;IACpD,OAAO,CAAC,cAAc,CAA0B;IAGhD,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,mBAAmB,CAAqB;IAGhD,OAAO,CAAC,uBAAuB,CAAC,CAAS;IAGzC,OAAO,CAAC,4BAA4B,CAAK;IAGzC,OAAO,CAAC,eAAe,CAAiB;IAGxC,OAAO,CAAC,sBAAsB,CAAkB;IAChD,OAAO,CAAC,wBAAwB,CAAgC;IAChE,OAAO,CAAC,qBAAqB,CAAyB;IAGtD,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,eAAe,CAA2D;IAClF,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,SAAS,CAAK;IAGtB,OAAO,CAAC,WAAW,CAKjB;IAGF,OAAO,CAAC,gBAAgB,CAAgE;IAGxF,OAAO,CAAC,UAAU,CAAiC;IACnD,OAAO,CAAC,cAAc,CAA8B;IACpD,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,UAAU,CAAsB;IAGxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuB;IACjD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAGhD,OAAO,CAAC,UAAU,CAAkB;IAGpC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA4B;IAG7D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8B;IAGxD,OAAO,CAAC,cAAc,CAAuC;IAC7D,OAAO,CAAC,qBAAqB,CAA+C;IAC5E,OAAO,CAAC,oBAAoB,CAAyC;IAGrE,OAAO,CAAC,gBAAgB,CAA+D;IAGvF,OAAO,CAAC,mBAAmB,CAAgC;IAG3D,OAAO,CAAC,kBAAkB,CAAS;IAGnC,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAM;gBAG3C,SAAS,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAC/B,UAAU,EAAE,UAAU,EACtB,cAAc,GAAE,cAAmB;IAqDrC,IAAI,MAAM,IAAI,aAAa,CAE1B;IAED,2DAA2D;IAC3D,OAAO,KAAK,UAAU,GAErB;IAED,oEAAoE;IACpE,OAAO,KAAK,aAAa,GAExB;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,MAAM,IAAI,OAAO,GAAG,IAAI,CAE3B;IAED,IAAI,QAAQ,IAAI,SAAS,OAAO,EAAE,CAEjC;IAED,IAAI,cAAc,IAAI,SAAS,OAAO,EAAE,CAEvC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,IAAI,cAAc,gDAEjB;IAMD,KAAK,EAAG,SAAS,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;IAC7D,IAAI,EAAG,SAAS,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,sBAAsB,EAAE,IAAI,CAAC,CAAC;IACxE,MAAM,EAAG,SAAS,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,gBAAgB,KAAK,sBAAsB,EAAE,IAAI,CAAC,CAAC;IAC3F,KAAK,EAAG,SAAS,CACf,CACE,SAAS,EAAE,iBAAiB,GAAG,GAAG,CAAC,OAAO,EAC1C,KAAK,CAAC,EAAE,SAAS,EACjB,OAAO,CAAC,EAAE,YAAY,KACnB,sBAAsB,EAC3B,IAAI,CACL,CAAC;IAEF,OAAO,CAAC,cAAc;IAmOtB;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAiK3B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAgEzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA0B1B,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAS9B,gBAAgB,CACd,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAC5F,IAAI;IAaP,SAAS,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAoBnD,UAAU,IAAI,IAAI;IAIlB,OAAO,CAAC,mBAAmB;IAU3B,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,oBAAoB;IAU5B,MAAM,IAAI,aAAa,CAAC,WAAW,CAAC;IAqBpC;;OAEG;IACH,OAAO,KAAK,SAAS,GAQpB;IAED,OAAO,CAAC,SAAS;IAiEjB,QAAQ,IAAI,eAAe;IAe3B;;;;OAIG;IACH,kBAAkB,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAIhF;;;OAGG;IACH,qBAAqB,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;IAItD,OAAO,IAAI,iBAAiB;IAyC5B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAwB7B,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI;IAwBzC,aAAa,IAAI,IAAI;IAWrB,YAAY,IAAI,gBAAgB,GAAG,IAAI;IASvC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAIhD;;OAEG;IACH,OAAO,CAAC,cAAc;IA2GtB,OAAO,CAAC,kBAAkB;IAK1B,OAAO,CAAC,eAAe;IAOvB;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IA2I5B;;;;;;;OAOG;IACH,OAAO,CAAC,iBAAiB;IAsEnB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAsDd,cAAc;IA8C5B;;;;;;;OAOG;YACW,WAAW;IA0iBzB;;OAEG;YACW,+BAA+B;IA6F7C;;OAEG;YACW,cAAc;IAgC5B;;OAEG;YACW,WAAW;IAkIzB;;;OAGG;IACH,OAAO,CAAC,UAAU;IAmBlB;;OAEG;YACW,YAAY;IAkJ1B;;OAEG;YACW,gBAAgB;IA+H9B;;;;OAIG;YACW,QAAQ;CAmBvB"}
|
package/dist/app/session.js
CHANGED
|
@@ -24,6 +24,8 @@ import { jsx } from "../jsx/jsx-runtime";
|
|
|
24
24
|
import { devToolsEmitter, forwardToDevTools, FrameworkChannels, getEffectiveModelInfo, getContextUtilization, } from "@agentick/shared";
|
|
25
25
|
import { computeTokenSummary } from "../utils/token-estimate";
|
|
26
26
|
import React from "react";
|
|
27
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
28
|
+
const log = Logger.for("Session");
|
|
27
29
|
/**
|
|
28
30
|
* Get session context from the current ALS context.
|
|
29
31
|
*/
|
|
@@ -44,6 +46,17 @@ function ensureMessageId(message) {
|
|
|
44
46
|
return message;
|
|
45
47
|
return { ...message, id: randomUUID() };
|
|
46
48
|
}
|
|
49
|
+
function tryDisplaySummary(tool, input) {
|
|
50
|
+
if (!tool?.metadata?.displaySummary)
|
|
51
|
+
return undefined;
|
|
52
|
+
try {
|
|
53
|
+
return tool.metadata.displaySummary(input);
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
log.warn({ error: err, tool: tool.metadata.name }, "displaySummary threw");
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
47
60
|
/**
|
|
48
61
|
* Session implementation.
|
|
49
62
|
*
|
|
@@ -1345,6 +1358,7 @@ export class SessionImpl extends EventEmitter {
|
|
|
1345
1358
|
timestamp: timestamp(),
|
|
1346
1359
|
});
|
|
1347
1360
|
const executionStartTimelineIndex = this._timeline.length;
|
|
1361
|
+
let executionError;
|
|
1348
1362
|
try {
|
|
1349
1363
|
// Tick loop
|
|
1350
1364
|
let shouldContinue = true;
|
|
@@ -1549,12 +1563,15 @@ export class SessionImpl extends EventEmitter {
|
|
|
1549
1563
|
toolStartTime = Date.now();
|
|
1550
1564
|
for (const call of response.toolCalls) {
|
|
1551
1565
|
const toolCallTimestamp = timestamp();
|
|
1566
|
+
const toolDef = compiled.tools?.find((t) => t.metadata?.name === call.name);
|
|
1567
|
+
const summary = tryDisplaySummary(toolDef, call.input);
|
|
1552
1568
|
this.emitEvent({
|
|
1553
1569
|
type: "tool_call",
|
|
1554
1570
|
callId: call.id,
|
|
1555
1571
|
blockIndex: 0,
|
|
1556
1572
|
name: call.name,
|
|
1557
1573
|
input: call.input,
|
|
1574
|
+
summary,
|
|
1558
1575
|
startedAt: toolCallTimestamp,
|
|
1559
1576
|
completedAt: toolCallTimestamp,
|
|
1560
1577
|
});
|
|
@@ -1572,9 +1589,11 @@ export class SessionImpl extends EventEmitter {
|
|
|
1572
1589
|
tickText = textContent.text;
|
|
1573
1590
|
}
|
|
1574
1591
|
}
|
|
1575
|
-
// Build TickResult with data and control methods
|
|
1592
|
+
// Build TickResult with data and control methods.
|
|
1593
|
+
// shouldContinue is initialized from ingestResult so callbacks see the framework default.
|
|
1576
1594
|
const tickResult = {
|
|
1577
1595
|
tick: currentTick,
|
|
1596
|
+
shouldContinue: ingestResult.shouldContinue,
|
|
1578
1597
|
text: tickText,
|
|
1579
1598
|
content: modelOutput?.message?.content ?? [],
|
|
1580
1599
|
toolCalls: response.toolCalls ?? [],
|
|
@@ -1599,8 +1618,9 @@ export class SessionImpl extends EventEmitter {
|
|
|
1599
1618
|
}
|
|
1600
1619
|
},
|
|
1601
1620
|
};
|
|
1602
|
-
// Run useTickEnd/useContinuation callbacks
|
|
1603
|
-
//
|
|
1621
|
+
// Run useTickEnd/useContinuation callbacks.
|
|
1622
|
+
// storeRunTickEndCallbacks chains shouldContinue through each callback
|
|
1623
|
+
// via _resolveCurrentShouldContinue, so each sees the accumulated decision.
|
|
1604
1624
|
const tickEndState = {
|
|
1605
1625
|
tick: currentTick,
|
|
1606
1626
|
current: this._currentOutput,
|
|
@@ -1609,11 +1629,11 @@ export class SessionImpl extends EventEmitter {
|
|
|
1609
1629
|
stop: () => { }, // No-op at tick end - use tickResult.stop() instead
|
|
1610
1630
|
};
|
|
1611
1631
|
await this.compiler?.notifyTickEnd(tickEndState, tickResult);
|
|
1612
|
-
//
|
|
1613
|
-
//
|
|
1614
|
-
|
|
1615
|
-
const
|
|
1616
|
-
shouldContinue =
|
|
1632
|
+
// Final decision comes from tickResult.shouldContinue (already resolved
|
|
1633
|
+
// incrementally through callbacks). Fall back to _resolveTickControl for
|
|
1634
|
+
// any remaining requests not consumed by chaining (shouldn't happen, but safe).
|
|
1635
|
+
const remainingDecision = this.ctx?._resolveTickControl(tickResult.shouldContinue ? "continue" : "completed", ingestResult.stopReason) ?? { status: tickResult.shouldContinue ? "continue" : "completed" };
|
|
1636
|
+
shouldContinue = remainingDecision.status === "continue";
|
|
1617
1637
|
// Get actual model ID: prefer response model, then metadata.model, then metadata.id
|
|
1618
1638
|
const actualModelId = modelOutput?.model || model?.metadata?.model || model?.metadata?.id || "unknown";
|
|
1619
1639
|
this.emitEvent({
|
|
@@ -1666,6 +1686,10 @@ export class SessionImpl extends EventEmitter {
|
|
|
1666
1686
|
timestamp: timestamp(),
|
|
1667
1687
|
});
|
|
1668
1688
|
}
|
|
1689
|
+
catch (e) {
|
|
1690
|
+
executionError = e instanceof Error ? e : new Error(String(e));
|
|
1691
|
+
throw e;
|
|
1692
|
+
}
|
|
1669
1693
|
finally {
|
|
1670
1694
|
this._executionComplete = true;
|
|
1671
1695
|
// Ensure queued messages are cleared even on error/abort paths
|
|
@@ -1684,6 +1708,10 @@ export class SessionImpl extends EventEmitter {
|
|
|
1684
1708
|
executionId,
|
|
1685
1709
|
stopReason,
|
|
1686
1710
|
aborted: this._isAborted,
|
|
1711
|
+
// Include error details for non-abort failures (abort is intentional, not an error)
|
|
1712
|
+
error: executionError && !this._isAborted
|
|
1713
|
+
? { message: executionError.message, name: executionError.name }
|
|
1714
|
+
: undefined,
|
|
1687
1715
|
usage,
|
|
1688
1716
|
output: output ?? null,
|
|
1689
1717
|
newTimelineEntries: this._timeline.slice(executionStartTimelineIndex),
|
|
@@ -1727,6 +1755,11 @@ export class SessionImpl extends EventEmitter {
|
|
|
1727
1755
|
}
|
|
1728
1756
|
this._eventResolvers = [];
|
|
1729
1757
|
this._status = "idle";
|
|
1758
|
+
// Auto-resume if messages were queued during execution
|
|
1759
|
+
if (this._queuedMessages.length > 0) {
|
|
1760
|
+
const tickProps = (this._lastProps ?? {});
|
|
1761
|
+
void this.render(tickProps);
|
|
1762
|
+
}
|
|
1730
1763
|
}
|
|
1731
1764
|
return {
|
|
1732
1765
|
response: responseText,
|
|
@@ -1965,80 +1998,117 @@ export class SessionImpl extends EventEmitter {
|
|
|
1965
1998
|
async executeTools(executor, toolCalls, configTools, outputs, currentTick, timestamp) {
|
|
1966
1999
|
const results = [];
|
|
1967
2000
|
const executableTools = configTools.filter((t) => "run" in t);
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
2001
|
+
// Subscribe to tool_confirmation channel to forward responses to the coordinator
|
|
2002
|
+
const confirmationChannel = this.channel("tool_confirmation");
|
|
2003
|
+
const coordinator = executor.getConfirmationCoordinator();
|
|
2004
|
+
const unsubscribe = confirmationChannel.subscribe((event) => {
|
|
2005
|
+
if (event.type === "response" && event.id) {
|
|
2006
|
+
const payload = event.payload;
|
|
2007
|
+
if (payload) {
|
|
2008
|
+
coordinator.resolveConfirmation(event.id, payload.approved, payload.always ?? false);
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
2011
|
+
});
|
|
2012
|
+
// Confirmation callbacks for stream event emission
|
|
2013
|
+
const confirmationCallbacks = {
|
|
2014
|
+
onConfirmationRequired: async (call, message, metadata) => {
|
|
1976
2015
|
this.emitEvent({
|
|
1977
|
-
type: "
|
|
2016
|
+
type: "tool_confirmation_required",
|
|
1978
2017
|
callId: call.id,
|
|
1979
2018
|
name: call.name,
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
startedAt,
|
|
1984
|
-
completedAt,
|
|
2019
|
+
input: call.input,
|
|
2020
|
+
message,
|
|
2021
|
+
metadata,
|
|
1985
2022
|
});
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
// Execute tool (optionally wrapped by execution runner)
|
|
1989
|
-
try {
|
|
1990
|
-
const runner = this.appOptions.runner;
|
|
1991
|
-
let toolResult;
|
|
1992
|
-
if (runner?.executeToolCall) {
|
|
1993
|
-
toolResult = await runner.executeToolCall(call, tool, async () => {
|
|
1994
|
-
const r = await executor.processToolWithConfirmation(call, this.ctx, executableTools);
|
|
1995
|
-
return r.result;
|
|
1996
|
-
});
|
|
1997
|
-
}
|
|
1998
|
-
else {
|
|
1999
|
-
const r = await executor.processToolWithConfirmation(call, this.ctx, executableTools);
|
|
2000
|
-
toolResult = r.result;
|
|
2001
|
-
}
|
|
2002
|
-
results.push(toolResult);
|
|
2003
|
-
const completedAt = timestamp();
|
|
2004
|
-
this.emitEvent({
|
|
2005
|
-
type: "tool_result",
|
|
2006
|
-
callId: toolResult.toolUseId,
|
|
2007
|
-
name: toolResult.name,
|
|
2008
|
-
result: toolResult,
|
|
2009
|
-
isError: !toolResult.success,
|
|
2010
|
-
executedBy: "engine",
|
|
2011
|
-
startedAt,
|
|
2012
|
-
completedAt,
|
|
2013
|
-
});
|
|
2014
|
-
}
|
|
2015
|
-
catch (error) {
|
|
2016
|
-
const errorResult = {
|
|
2017
|
-
id: randomUUID(),
|
|
2018
|
-
toolUseId: call.id,
|
|
2019
|
-
name: call.name,
|
|
2020
|
-
success: false,
|
|
2021
|
-
content: [
|
|
2022
|
-
{
|
|
2023
|
-
type: "text",
|
|
2024
|
-
text: `Tool execution failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
2025
|
-
},
|
|
2026
|
-
],
|
|
2027
|
-
};
|
|
2028
|
-
results.push(errorResult);
|
|
2029
|
-
const completedAt = timestamp();
|
|
2023
|
+
},
|
|
2024
|
+
onConfirmationResult: async (confirmation, call) => {
|
|
2030
2025
|
this.emitEvent({
|
|
2031
|
-
type: "
|
|
2026
|
+
type: "tool_confirmation_result",
|
|
2032
2027
|
callId: call.id,
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
isError: true,
|
|
2036
|
-
executedBy: "engine",
|
|
2037
|
-
startedAt,
|
|
2038
|
-
completedAt,
|
|
2028
|
+
confirmed: confirmation.confirmed,
|
|
2029
|
+
always: confirmation.always,
|
|
2039
2030
|
});
|
|
2031
|
+
},
|
|
2032
|
+
};
|
|
2033
|
+
try {
|
|
2034
|
+
for (const call of toolCalls) {
|
|
2035
|
+
const startedAt = timestamp();
|
|
2036
|
+
// Check if OUTPUT tool
|
|
2037
|
+
const tool = executableTools.find((t) => t.metadata?.name === call.name);
|
|
2038
|
+
const isOutputTool = tool && tool.metadata?.type === "output";
|
|
2039
|
+
if (isOutputTool) {
|
|
2040
|
+
outputs[call.name] = call.input;
|
|
2041
|
+
const completedAt = timestamp();
|
|
2042
|
+
this.emitEvent({
|
|
2043
|
+
type: "tool_result",
|
|
2044
|
+
callId: call.id,
|
|
2045
|
+
name: call.name,
|
|
2046
|
+
result: call.input,
|
|
2047
|
+
isError: false,
|
|
2048
|
+
executedBy: "engine",
|
|
2049
|
+
startedAt,
|
|
2050
|
+
completedAt,
|
|
2051
|
+
});
|
|
2052
|
+
continue;
|
|
2053
|
+
}
|
|
2054
|
+
// Execute tool (optionally wrapped by execution runner)
|
|
2055
|
+
try {
|
|
2056
|
+
const runner = this.appOptions.runner;
|
|
2057
|
+
let toolResult;
|
|
2058
|
+
if (runner?.executeToolCall) {
|
|
2059
|
+
toolResult = await runner.executeToolCall(call, tool, async () => {
|
|
2060
|
+
const r = await executor.processToolWithConfirmation(call, this.ctx, executableTools, confirmationCallbacks);
|
|
2061
|
+
return r.result;
|
|
2062
|
+
});
|
|
2063
|
+
}
|
|
2064
|
+
else {
|
|
2065
|
+
const r = await executor.processToolWithConfirmation(call, this.ctx, executableTools, confirmationCallbacks);
|
|
2066
|
+
toolResult = r.result;
|
|
2067
|
+
}
|
|
2068
|
+
results.push(toolResult);
|
|
2069
|
+
const completedAt = timestamp();
|
|
2070
|
+
this.emitEvent({
|
|
2071
|
+
type: "tool_result",
|
|
2072
|
+
callId: toolResult.toolUseId,
|
|
2073
|
+
name: toolResult.name,
|
|
2074
|
+
result: toolResult,
|
|
2075
|
+
isError: !toolResult.success,
|
|
2076
|
+
executedBy: "engine",
|
|
2077
|
+
startedAt,
|
|
2078
|
+
completedAt,
|
|
2079
|
+
});
|
|
2080
|
+
}
|
|
2081
|
+
catch (error) {
|
|
2082
|
+
const errorResult = {
|
|
2083
|
+
id: randomUUID(),
|
|
2084
|
+
toolUseId: call.id,
|
|
2085
|
+
name: call.name,
|
|
2086
|
+
success: false,
|
|
2087
|
+
content: [
|
|
2088
|
+
{
|
|
2089
|
+
type: "text",
|
|
2090
|
+
text: `Tool execution failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
2091
|
+
},
|
|
2092
|
+
],
|
|
2093
|
+
};
|
|
2094
|
+
results.push(errorResult);
|
|
2095
|
+
const completedAt = timestamp();
|
|
2096
|
+
this.emitEvent({
|
|
2097
|
+
type: "tool_result",
|
|
2098
|
+
callId: call.id,
|
|
2099
|
+
name: call.name,
|
|
2100
|
+
result: errorResult,
|
|
2101
|
+
isError: true,
|
|
2102
|
+
executedBy: "engine",
|
|
2103
|
+
startedAt,
|
|
2104
|
+
completedAt,
|
|
2105
|
+
});
|
|
2106
|
+
}
|
|
2040
2107
|
}
|
|
2041
2108
|
}
|
|
2109
|
+
finally {
|
|
2110
|
+
unsubscribe();
|
|
2111
|
+
}
|
|
2042
2112
|
return results;
|
|
2043
2113
|
}
|
|
2044
2114
|
/**
|
|
@@ -2141,11 +2211,13 @@ export class SessionImpl extends EventEmitter {
|
|
|
2141
2211
|
this.log.debug({ removed, remaining: this._timeline.length }, "Timeline trimmed (maxTimelineEntries)");
|
|
2142
2212
|
}
|
|
2143
2213
|
this._currentOutput = current;
|
|
2144
|
-
// Resolve tick control
|
|
2214
|
+
// Resolve tick control: continue if tool calls pending OR messages queued
|
|
2145
2215
|
const shouldStop = response.shouldStop || false;
|
|
2146
2216
|
const stopReason = response.stopReason?.reason;
|
|
2217
|
+
const hasToolCalls = (response.toolCalls?.length ?? 0) > 0;
|
|
2218
|
+
const hasPendingMessages = (this.ctx?.getQueuedMessages().length ?? 0) > 0 || this._queuedMessages.length > 0;
|
|
2147
2219
|
return {
|
|
2148
|
-
shouldContinue: !shouldStop && (
|
|
2220
|
+
shouldContinue: !shouldStop && (hasToolCalls || hasPendingMessages),
|
|
2149
2221
|
stopReason,
|
|
2150
2222
|
timeline: current.timeline,
|
|
2151
2223
|
};
|