From 477af8a84f8c9c3d0fbc511b4f96eb2e1bf8d561 Mon Sep 17 00:00:00 2001 From: xenophobentx Date: Fri, 25 Sep 2026 21:51:25 +0200 Subject: [PATCH 1/4] Rebuild chat-with-agent bundle with esbuild 0.28.1 No source change. The committed bundle was built with esbuild 0.24.2, while package.json pins 0.28.1 since #27, so any rebuild produces this diff. Keeping it separate makes the next change reviewable. --- scripts/chat-with-agent.bundle.js | 277 +++++++++++++++--------------- 1 file changed, 143 insertions(+), 134 deletions(-) diff --git a/scripts/chat-with-agent.bundle.js b/scripts/chat-with-agent.bundle.js index c0b2ec8..9b71a7f 100644 --- a/scripts/chat-with-agent.bundle.js +++ b/scripts/chat-with-agent.bundle.js @@ -3,11 +3,20 @@ var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; -var __esm = (fn, res) => function __init() { - return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; +var __esm = (fn, res, err) => function __init() { + if (err) throw err[0]; + try { + return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; + } catch (e) { + throw err = [e], e; + } }; var __commonJS = (cb, mod) => function __require() { - return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; + try { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; + } catch (e) { + throw mod = 0, e; + } }; var __export = (target, all) => { for (var name in all) @@ -2629,7 +2638,7 @@ var require_dumper = __commonJS({ return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE; } function writeScalar(state, string, level, iskey, inblock) { - state.dump = function() { + state.dump = (function() { if (string.length === 0) { return state.quotingType === QUOTING_TYPE_DOUBLE ? '""' : "''"; } @@ -2668,7 +2677,7 @@ var require_dumper = __commonJS({ default: throw new YAMLException("impossible error: invalid scalar style"); } - }(); + })(); } function blockHeader(string, indentPerLevel) { const indentIndicator = needIndentIndicator(string) ? String(indentPerLevel) : ""; @@ -2682,12 +2691,12 @@ var require_dumper = __commonJS({ } function foldString(string, width) { const lineRe = /(\n+)([^\n]*)/g; - let result = function() { + let result = (function() { let nextLF = string.indexOf("\n"); nextLF = nextLF !== -1 ? nextLF : string.length; lineRe.lastIndex = nextLF; return foldLine(string.slice(0, nextLF), width); - }(); + })(); let prevMoreIndented = string[0] === "\n" || string[0] === " "; let moreIndented; let match; @@ -5353,7 +5362,7 @@ var require_range = __commonJS({ var require_comparator = __commonJS({ "node_modules/semver/classes/comparator.js"(exports2, module2) { "use strict"; - var ANY = Symbol("SemVer ANY"); + var ANY = /* @__PURE__ */ Symbol("SemVer ANY"); var Comparator = class _Comparator { static get ANY() { return ANY; @@ -18447,7 +18456,7 @@ var init_global_utils = __esm({ init_version(); init_semver(); major = VERSION.split(".")[0]; - GLOBAL_OPENTELEMETRY_API_KEY = Symbol.for(`opentelemetry.js.api.${major}`); + GLOBAL_OPENTELEMETRY_API_KEY = /* @__PURE__ */ Symbol.for(`opentelemetry.js.api.${major}`); _global = typeof globalThis === "object" ? globalThis : typeof self === "object" ? self : typeof window === "object" ? window : typeof global === "object" ? global : {}; } }); @@ -18648,7 +18657,7 @@ var init_baggage_impl = __esm({ var baggageEntryMetadataSymbol; var init_symbol = __esm({ "node_modules/@opentelemetry/api/build/esm/baggage/internal/symbol.js"() { - baggageEntryMetadataSymbol = Symbol("BaggageEntryMetadata"); + baggageEntryMetadataSymbol = /* @__PURE__ */ Symbol("BaggageEntryMetadata"); } }); @@ -19930,7 +19939,7 @@ var require_global_utils = __commonJS({ "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.API_BACKWARDS_COMPATIBILITY_VERSION = exports2.makeGetter = exports2._global = exports2.GLOBAL_LOGS_API_KEY = void 0; - exports2.GLOBAL_LOGS_API_KEY = Symbol.for("io.opentelemetry.js.api.logs"); + exports2.GLOBAL_LOGS_API_KEY = /* @__PURE__ */ Symbol.for("io.opentelemetry.js.api.logs"); exports2._global = globalThis; function makeGetter(requiredVersion, instance, fallback) { return (version) => version === requiredVersion ? instance : fallback; @@ -24691,7 +24700,7 @@ var require_types = __commonJS({ ...processCreateParams(params) }); }; - exports2.BRAND = Symbol("zod_brand"); + exports2.BRAND = /* @__PURE__ */ Symbol("zod_brand"); var ZodBranded = class extends ZodType { _parse(input) { const { ctx } = this._processInputParams(input); @@ -24935,14 +24944,14 @@ var require_types = __commonJS({ var oboolean = () => booleanType().optional(); exports2.oboolean = oboolean; exports2.coerce = { - string: (arg) => ZodString.create({ ...arg, coerce: true }), - number: (arg) => ZodNumber.create({ ...arg, coerce: true }), - boolean: (arg) => ZodBoolean.create({ + string: ((arg) => ZodString.create({ ...arg, coerce: true })), + number: ((arg) => ZodNumber.create({ ...arg, coerce: true })), + boolean: ((arg) => ZodBoolean.create({ ...arg, coerce: true - }), - bigint: (arg) => ZodBigInt.create({ ...arg, coerce: true }), - date: (arg) => ZodDate.create({ ...arg, coerce: true }) + })), + bigint: ((arg) => ZodBigInt.create({ ...arg, coerce: true })), + date: ((arg) => ZodDate.create({ ...arg, coerce: true })) }; exports2.NEVER = parseUtil_js_1.INVALID; } @@ -24952,7 +24961,7 @@ var require_types = __commonJS({ var require_external = __commonJS({ "node_modules/zod/v3/external.cjs"(exports2) { "use strict"; - var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { @@ -24961,10 +24970,10 @@ var require_external = __commonJS({ } }; } Object.defineProperty(o, k2, desc); - } : function(o, m, k, k2) { + }) : (function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; - }); + })); var __exportStar = exports2 && exports2.__exportStar || function(m, exports3) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p); }; @@ -24982,7 +24991,7 @@ var require_external = __commonJS({ var require_zod = __commonJS({ "node_modules/zod/index.cjs"(exports2) { "use strict"; - var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { @@ -24991,13 +25000,13 @@ var require_zod = __commonJS({ } }; } Object.defineProperty(o, k2, desc); - } : function(o, m, k, k2) { + }) : (function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; - }); - var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + })); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); - } : function(o, v) { + }) : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod) { @@ -26226,7 +26235,7 @@ var require_activity = __commonJS({ var require_src5 = __commonJS({ "node_modules/@microsoft/agents-activity/dist/src/index.js"(exports2) { "use strict"; - var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { @@ -26235,10 +26244,10 @@ var require_src5 = __commonJS({ } }; } Object.defineProperty(o, k2, desc); - } : function(o, m, k, k2) { + }) : (function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; - }); + })); var __exportStar = exports2 && exports2.__exportStar || function(m, exports3) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p); }; @@ -26743,7 +26752,7 @@ var require_traces = __commonJS({ var require_observability = __commonJS({ "node_modules/@microsoft/agents-copilotstudio-client/dist/src/observability/index.js"(exports2) { "use strict"; - var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { @@ -26752,10 +26761,10 @@ var require_observability = __commonJS({ } }; } Object.defineProperty(o, k2, desc); - } : function(o, m, k, k2) { + }) : (function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; - }); + })); var __exportStar = exports2 && exports2.__exportStar || function(m, exports3) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p); }; @@ -27288,7 +27297,7 @@ var require_Subscription = __commonJS({ var isFunction_1 = require_isFunction(); var UnsubscriptionError_1 = require_UnsubscriptionError(); var arrRemove_1 = require_arrRemove(); - var Subscription = function() { + var Subscription = (function() { function Subscription2(initialTeardown) { this.initialTeardown = initialTeardown; this.closed = false; @@ -27401,13 +27410,13 @@ var require_Subscription = __commonJS({ teardown._removeParent(this); } }; - Subscription2.EMPTY = function() { + Subscription2.EMPTY = (function() { var empty = new Subscription2(); empty.closed = true; return empty; - }(); + })(); return Subscription2; - }(); + })(); exports2.Subscription = Subscription; exports2.EMPTY_SUBSCRIPTION = Subscription.EMPTY; function isSubscription(value) { @@ -27529,9 +27538,9 @@ var require_NotificationFactories = __commonJS({ "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.createNotification = exports2.nextNotification = exports2.errorNotification = exports2.COMPLETE_NOTIFICATION = void 0; - exports2.COMPLETE_NOTIFICATION = function() { + exports2.COMPLETE_NOTIFICATION = (function() { return createNotification("C", void 0, void 0); - }(); + })(); function errorNotification(error) { return createNotification("E", void 0, error); } @@ -27592,7 +27601,7 @@ var require_errorContext = __commonJS({ var require_Subscriber = __commonJS({ "node_modules/rxjs/dist/cjs/internal/Subscriber.js"(exports2) { "use strict"; - var __extends = exports2 && exports2.__extends || /* @__PURE__ */ function() { + var __extends = exports2 && exports2.__extends || /* @__PURE__ */ (function() { var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { d2.__proto__ = b2; @@ -27610,7 +27619,7 @@ var require_Subscriber = __commonJS({ } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; - }(); + })(); Object.defineProperty(exports2, "__esModule", { value: true }); exports2.EMPTY_OBSERVER = exports2.SafeSubscriber = exports2.Subscriber = void 0; var isFunction_1 = require_isFunction(); @@ -27621,7 +27630,7 @@ var require_Subscriber = __commonJS({ var NotificationFactories_1 = require_NotificationFactories(); var timeoutProvider_1 = require_timeoutProvider(); var errorContext_1 = require_errorContext(); - var Subscriber = function(_super) { + var Subscriber = (function(_super) { __extends(Subscriber2, _super); function Subscriber2(destination) { var _this = _super.call(this) || this; @@ -27687,13 +27696,13 @@ var require_Subscriber = __commonJS({ } }; return Subscriber2; - }(Subscription_1.Subscription); + })(Subscription_1.Subscription); exports2.Subscriber = Subscriber; var _bind = Function.prototype.bind; function bind(fn, thisArg) { return _bind.call(fn, thisArg); } - var ConsumerObserver = function() { + var ConsumerObserver = (function() { function ConsumerObserver2(partialObserver) { this.partialObserver = partialObserver; } @@ -27730,8 +27739,8 @@ var require_Subscriber = __commonJS({ } }; return ConsumerObserver2; - }(); - var SafeSubscriber = function(_super) { + })(); + var SafeSubscriber = (function(_super) { __extends(SafeSubscriber2, _super); function SafeSubscriber2(observerOrNext, error, complete) { var _this = _super.call(this) || this; @@ -27762,7 +27771,7 @@ var require_Subscriber = __commonJS({ return _this; } return SafeSubscriber2; - }(Subscriber); + })(Subscriber); exports2.SafeSubscriber = SafeSubscriber; function handleUnhandledError(error) { if (config_1.config.useDeprecatedSynchronousErrorHandling) { @@ -27795,9 +27804,9 @@ var require_observable = __commonJS({ "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.observable = void 0; - exports2.observable = function() { + exports2.observable = (function() { return typeof Symbol === "function" && Symbol.observable || "@@observable"; - }(); + })(); } }); @@ -27859,7 +27868,7 @@ var require_Observable = __commonJS({ var config_1 = require_config(); var isFunction_1 = require_isFunction(); var errorContext_1 = require_errorContext(); - var Observable = function() { + var Observable = (function() { function Observable2(subscribe) { if (subscribe) { this._subscribe = subscribe; @@ -27938,7 +27947,7 @@ var require_Observable = __commonJS({ return new Observable2(subscribe); }; return Observable2; - }(); + })(); exports2.Observable = Observable; function getPromiseCtor(promiseCtor) { var _a; @@ -27986,7 +27995,7 @@ var require_lift = __commonJS({ var require_OperatorSubscriber = __commonJS({ "node_modules/rxjs/dist/cjs/internal/operators/OperatorSubscriber.js"(exports2) { "use strict"; - var __extends = exports2 && exports2.__extends || /* @__PURE__ */ function() { + var __extends = exports2 && exports2.__extends || /* @__PURE__ */ (function() { var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { d2.__proto__ = b2; @@ -28004,7 +28013,7 @@ var require_OperatorSubscriber = __commonJS({ } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; - }(); + })(); Object.defineProperty(exports2, "__esModule", { value: true }); exports2.OperatorSubscriber = exports2.createOperatorSubscriber = void 0; var Subscriber_1 = require_Subscriber(); @@ -28012,7 +28021,7 @@ var require_OperatorSubscriber = __commonJS({ return new OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize); } exports2.createOperatorSubscriber = createOperatorSubscriber; - var OperatorSubscriber = function(_super) { + var OperatorSubscriber = (function(_super) { __extends(OperatorSubscriber2, _super); function OperatorSubscriber2(destination, onNext, onComplete, onError, onFinalize, shouldUnsubscribe) { var _this = _super.call(this, destination) || this; @@ -28054,7 +28063,7 @@ var require_OperatorSubscriber = __commonJS({ } }; return OperatorSubscriber2; - }(Subscriber_1.Subscriber); + })(Subscriber_1.Subscriber); exports2.OperatorSubscriber = OperatorSubscriber; } }); @@ -28098,7 +28107,7 @@ var require_refCount = __commonJS({ var require_ConnectableObservable = __commonJS({ "node_modules/rxjs/dist/cjs/internal/observable/ConnectableObservable.js"(exports2) { "use strict"; - var __extends = exports2 && exports2.__extends || /* @__PURE__ */ function() { + var __extends = exports2 && exports2.__extends || /* @__PURE__ */ (function() { var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { d2.__proto__ = b2; @@ -28116,7 +28125,7 @@ var require_ConnectableObservable = __commonJS({ } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; - }(); + })(); Object.defineProperty(exports2, "__esModule", { value: true }); exports2.ConnectableObservable = void 0; var Observable_1 = require_Observable(); @@ -28124,7 +28133,7 @@ var require_ConnectableObservable = __commonJS({ var refCount_1 = require_refCount(); var OperatorSubscriber_1 = require_OperatorSubscriber(); var lift_1 = require_lift(); - var ConnectableObservable = function(_super) { + var ConnectableObservable = (function(_super) { __extends(ConnectableObservable2, _super); function ConnectableObservable2(source, subjectFactory) { var _this = _super.call(this) || this; @@ -28180,7 +28189,7 @@ var require_ConnectableObservable = __commonJS({ return refCount_1.refCount()(this); }; return ConnectableObservable2; - }(Observable_1.Observable); + })(Observable_1.Observable); exports2.ConnectableObservable = ConnectableObservable; } }); @@ -28331,7 +28340,7 @@ var require_ObjectUnsubscribedError = __commonJS({ var require_Subject = __commonJS({ "node_modules/rxjs/dist/cjs/internal/Subject.js"(exports2) { "use strict"; - var __extends = exports2 && exports2.__extends || /* @__PURE__ */ function() { + var __extends = exports2 && exports2.__extends || /* @__PURE__ */ (function() { var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { d2.__proto__ = b2; @@ -28349,7 +28358,7 @@ var require_Subject = __commonJS({ } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; - }(); + })(); var __values = exports2 && exports2.__values || function(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); @@ -28368,7 +28377,7 @@ var require_Subject = __commonJS({ var ObjectUnsubscribedError_1 = require_ObjectUnsubscribedError(); var arrRemove_1 = require_arrRemove(); var errorContext_1 = require_errorContext(); - var Subject = function(_super) { + var Subject = (function(_super) { __extends(Subject2, _super); function Subject2() { var _this = _super.call(this) || this; @@ -28494,9 +28503,9 @@ var require_Subject = __commonJS({ return new AnonymousSubject(destination, source); }; return Subject2; - }(Observable_1.Observable); + })(Observable_1.Observable); exports2.Subject = Subject; - var AnonymousSubject = function(_super) { + var AnonymousSubject = (function(_super) { __extends(AnonymousSubject2, _super); function AnonymousSubject2(destination, source) { var _this = _super.call(this) || this; @@ -28521,7 +28530,7 @@ var require_Subject = __commonJS({ return (_b = (_a = this.source) === null || _a === void 0 ? void 0 : _a.subscribe(subscriber)) !== null && _b !== void 0 ? _b : Subscription_1.EMPTY_SUBSCRIPTION; }; return AnonymousSubject2; - }(Subject); + })(Subject); exports2.AnonymousSubject = AnonymousSubject; } }); @@ -28530,7 +28539,7 @@ var require_Subject = __commonJS({ var require_BehaviorSubject = __commonJS({ "node_modules/rxjs/dist/cjs/internal/BehaviorSubject.js"(exports2) { "use strict"; - var __extends = exports2 && exports2.__extends || /* @__PURE__ */ function() { + var __extends = exports2 && exports2.__extends || /* @__PURE__ */ (function() { var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { d2.__proto__ = b2; @@ -28548,11 +28557,11 @@ var require_BehaviorSubject = __commonJS({ } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; - }(); + })(); Object.defineProperty(exports2, "__esModule", { value: true }); exports2.BehaviorSubject = void 0; var Subject_1 = require_Subject(); - var BehaviorSubject = function(_super) { + var BehaviorSubject = (function(_super) { __extends(BehaviorSubject2, _super); function BehaviorSubject2(_value) { var _this = _super.call(this) || this; @@ -28583,7 +28592,7 @@ var require_BehaviorSubject = __commonJS({ _super.prototype.next.call(this, this._value = value); }; return BehaviorSubject2; - }(Subject_1.Subject); + })(Subject_1.Subject); exports2.BehaviorSubject = BehaviorSubject; } }); @@ -28607,7 +28616,7 @@ var require_dateTimestampProvider = __commonJS({ var require_ReplaySubject = __commonJS({ "node_modules/rxjs/dist/cjs/internal/ReplaySubject.js"(exports2) { "use strict"; - var __extends = exports2 && exports2.__extends || /* @__PURE__ */ function() { + var __extends = exports2 && exports2.__extends || /* @__PURE__ */ (function() { var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { d2.__proto__ = b2; @@ -28625,12 +28634,12 @@ var require_ReplaySubject = __commonJS({ } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; - }(); + })(); Object.defineProperty(exports2, "__esModule", { value: true }); exports2.ReplaySubject = void 0; var Subject_1 = require_Subject(); var dateTimestampProvider_1 = require_dateTimestampProvider(); - var ReplaySubject = function(_super) { + var ReplaySubject = (function(_super) { __extends(ReplaySubject2, _super); function ReplaySubject2(_bufferSize, _windowTime, _timestampProvider) { if (_bufferSize === void 0) { @@ -28688,7 +28697,7 @@ var require_ReplaySubject = __commonJS({ } }; return ReplaySubject2; - }(Subject_1.Subject); + })(Subject_1.Subject); exports2.ReplaySubject = ReplaySubject; } }); @@ -28697,7 +28706,7 @@ var require_ReplaySubject = __commonJS({ var require_AsyncSubject = __commonJS({ "node_modules/rxjs/dist/cjs/internal/AsyncSubject.js"(exports2) { "use strict"; - var __extends = exports2 && exports2.__extends || /* @__PURE__ */ function() { + var __extends = exports2 && exports2.__extends || /* @__PURE__ */ (function() { var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { d2.__proto__ = b2; @@ -28715,11 +28724,11 @@ var require_AsyncSubject = __commonJS({ } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; - }(); + })(); Object.defineProperty(exports2, "__esModule", { value: true }); exports2.AsyncSubject = void 0; var Subject_1 = require_Subject(); - var AsyncSubject = function(_super) { + var AsyncSubject = (function(_super) { __extends(AsyncSubject2, _super); function AsyncSubject2() { var _this = _super !== null && _super.apply(this, arguments) || this; @@ -28752,7 +28761,7 @@ var require_AsyncSubject = __commonJS({ } }; return AsyncSubject2; - }(Subject_1.Subject); + })(Subject_1.Subject); exports2.AsyncSubject = AsyncSubject; } }); @@ -28761,7 +28770,7 @@ var require_AsyncSubject = __commonJS({ var require_Action = __commonJS({ "node_modules/rxjs/dist/cjs/internal/scheduler/Action.js"(exports2) { "use strict"; - var __extends = exports2 && exports2.__extends || /* @__PURE__ */ function() { + var __extends = exports2 && exports2.__extends || /* @__PURE__ */ (function() { var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { d2.__proto__ = b2; @@ -28779,11 +28788,11 @@ var require_Action = __commonJS({ } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; - }(); + })(); Object.defineProperty(exports2, "__esModule", { value: true }); exports2.Action = void 0; var Subscription_1 = require_Subscription(); - var Action = function(_super) { + var Action = (function(_super) { __extends(Action2, _super); function Action2(scheduler, work) { return _super.call(this) || this; @@ -28795,7 +28804,7 @@ var require_Action = __commonJS({ return this; }; return Action2; - }(Subscription_1.Subscription); + })(Subscription_1.Subscription); exports2.Action = Action; } }); @@ -28853,7 +28862,7 @@ var require_intervalProvider = __commonJS({ var require_AsyncAction = __commonJS({ "node_modules/rxjs/dist/cjs/internal/scheduler/AsyncAction.js"(exports2) { "use strict"; - var __extends = exports2 && exports2.__extends || /* @__PURE__ */ function() { + var __extends = exports2 && exports2.__extends || /* @__PURE__ */ (function() { var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { d2.__proto__ = b2; @@ -28871,13 +28880,13 @@ var require_AsyncAction = __commonJS({ } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; - }(); + })(); Object.defineProperty(exports2, "__esModule", { value: true }); exports2.AsyncAction = void 0; var Action_1 = require_Action(); var intervalProvider_1 = require_intervalProvider(); var arrRemove_1 = require_arrRemove(); - var AsyncAction = function(_super) { + var AsyncAction = (function(_super) { __extends(AsyncAction2, _super); function AsyncAction2(scheduler, work) { var _this = _super.call(this, scheduler, work) || this; @@ -28964,7 +28973,7 @@ var require_AsyncAction = __commonJS({ } }; return AsyncAction2; - }(Action_1.Action); + })(Action_1.Action); exports2.AsyncAction = AsyncAction; } }); @@ -29062,7 +29071,7 @@ var require_immediateProvider = __commonJS({ var require_AsapAction = __commonJS({ "node_modules/rxjs/dist/cjs/internal/scheduler/AsapAction.js"(exports2) { "use strict"; - var __extends = exports2 && exports2.__extends || /* @__PURE__ */ function() { + var __extends = exports2 && exports2.__extends || /* @__PURE__ */ (function() { var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { d2.__proto__ = b2; @@ -29080,12 +29089,12 @@ var require_AsapAction = __commonJS({ } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; - }(); + })(); Object.defineProperty(exports2, "__esModule", { value: true }); exports2.AsapAction = void 0; var AsyncAction_1 = require_AsyncAction(); var immediateProvider_1 = require_immediateProvider(); - var AsapAction = function(_super) { + var AsapAction = (function(_super) { __extends(AsapAction2, _super); function AsapAction2(scheduler, work) { var _this = _super.call(this, scheduler, work) || this; @@ -29121,7 +29130,7 @@ var require_AsapAction = __commonJS({ return void 0; }; return AsapAction2; - }(AsyncAction_1.AsyncAction); + })(AsyncAction_1.AsyncAction); exports2.AsapAction = AsapAction; } }); @@ -29133,7 +29142,7 @@ var require_Scheduler = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.Scheduler = void 0; var dateTimestampProvider_1 = require_dateTimestampProvider(); - var Scheduler = function() { + var Scheduler = (function() { function Scheduler2(schedulerActionCtor, now) { if (now === void 0) { now = Scheduler2.now; @@ -29149,7 +29158,7 @@ var require_Scheduler = __commonJS({ }; Scheduler2.now = dateTimestampProvider_1.dateTimestampProvider.now; return Scheduler2; - }(); + })(); exports2.Scheduler = Scheduler; } }); @@ -29158,7 +29167,7 @@ var require_Scheduler = __commonJS({ var require_AsyncScheduler = __commonJS({ "node_modules/rxjs/dist/cjs/internal/scheduler/AsyncScheduler.js"(exports2) { "use strict"; - var __extends = exports2 && exports2.__extends || /* @__PURE__ */ function() { + var __extends = exports2 && exports2.__extends || /* @__PURE__ */ (function() { var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { d2.__proto__ = b2; @@ -29176,11 +29185,11 @@ var require_AsyncScheduler = __commonJS({ } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; - }(); + })(); Object.defineProperty(exports2, "__esModule", { value: true }); exports2.AsyncScheduler = void 0; var Scheduler_1 = require_Scheduler(); - var AsyncScheduler = function(_super) { + var AsyncScheduler = (function(_super) { __extends(AsyncScheduler2, _super); function AsyncScheduler2(SchedulerAction, now) { if (now === void 0) { @@ -29213,7 +29222,7 @@ var require_AsyncScheduler = __commonJS({ } }; return AsyncScheduler2; - }(Scheduler_1.Scheduler); + })(Scheduler_1.Scheduler); exports2.AsyncScheduler = AsyncScheduler; } }); @@ -29222,7 +29231,7 @@ var require_AsyncScheduler = __commonJS({ var require_AsapScheduler = __commonJS({ "node_modules/rxjs/dist/cjs/internal/scheduler/AsapScheduler.js"(exports2) { "use strict"; - var __extends = exports2 && exports2.__extends || /* @__PURE__ */ function() { + var __extends = exports2 && exports2.__extends || /* @__PURE__ */ (function() { var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { d2.__proto__ = b2; @@ -29240,11 +29249,11 @@ var require_AsapScheduler = __commonJS({ } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; - }(); + })(); Object.defineProperty(exports2, "__esModule", { value: true }); exports2.AsapScheduler = void 0; var AsyncScheduler_1 = require_AsyncScheduler(); - var AsapScheduler = function(_super) { + var AsapScheduler = (function(_super) { __extends(AsapScheduler2, _super); function AsapScheduler2() { return _super !== null && _super.apply(this, arguments) || this; @@ -29270,7 +29279,7 @@ var require_AsapScheduler = __commonJS({ } }; return AsapScheduler2; - }(AsyncScheduler_1.AsyncScheduler); + })(AsyncScheduler_1.AsyncScheduler); exports2.AsapScheduler = AsapScheduler; } }); @@ -29305,7 +29314,7 @@ var require_async = __commonJS({ var require_QueueAction = __commonJS({ "node_modules/rxjs/dist/cjs/internal/scheduler/QueueAction.js"(exports2) { "use strict"; - var __extends = exports2 && exports2.__extends || /* @__PURE__ */ function() { + var __extends = exports2 && exports2.__extends || /* @__PURE__ */ (function() { var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { d2.__proto__ = b2; @@ -29323,11 +29332,11 @@ var require_QueueAction = __commonJS({ } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; - }(); + })(); Object.defineProperty(exports2, "__esModule", { value: true }); exports2.QueueAction = void 0; var AsyncAction_1 = require_AsyncAction(); - var QueueAction = function(_super) { + var QueueAction = (function(_super) { __extends(QueueAction2, _super); function QueueAction2(scheduler, work) { var _this = _super.call(this, scheduler, work) || this; @@ -29361,7 +29370,7 @@ var require_QueueAction = __commonJS({ return 0; }; return QueueAction2; - }(AsyncAction_1.AsyncAction); + })(AsyncAction_1.AsyncAction); exports2.QueueAction = QueueAction; } }); @@ -29370,7 +29379,7 @@ var require_QueueAction = __commonJS({ var require_QueueScheduler = __commonJS({ "node_modules/rxjs/dist/cjs/internal/scheduler/QueueScheduler.js"(exports2) { "use strict"; - var __extends = exports2 && exports2.__extends || /* @__PURE__ */ function() { + var __extends = exports2 && exports2.__extends || /* @__PURE__ */ (function() { var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { d2.__proto__ = b2; @@ -29388,17 +29397,17 @@ var require_QueueScheduler = __commonJS({ } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; - }(); + })(); Object.defineProperty(exports2, "__esModule", { value: true }); exports2.QueueScheduler = void 0; var AsyncScheduler_1 = require_AsyncScheduler(); - var QueueScheduler = function(_super) { + var QueueScheduler = (function(_super) { __extends(QueueScheduler2, _super); function QueueScheduler2() { return _super !== null && _super.apply(this, arguments) || this; } return QueueScheduler2; - }(AsyncScheduler_1.AsyncScheduler); + })(AsyncScheduler_1.AsyncScheduler); exports2.QueueScheduler = QueueScheduler; } }); @@ -29420,7 +29429,7 @@ var require_queue = __commonJS({ var require_AnimationFrameAction = __commonJS({ "node_modules/rxjs/dist/cjs/internal/scheduler/AnimationFrameAction.js"(exports2) { "use strict"; - var __extends = exports2 && exports2.__extends || /* @__PURE__ */ function() { + var __extends = exports2 && exports2.__extends || /* @__PURE__ */ (function() { var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { d2.__proto__ = b2; @@ -29438,12 +29447,12 @@ var require_AnimationFrameAction = __commonJS({ } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; - }(); + })(); Object.defineProperty(exports2, "__esModule", { value: true }); exports2.AnimationFrameAction = void 0; var AsyncAction_1 = require_AsyncAction(); var animationFrameProvider_1 = require_animationFrameProvider(); - var AnimationFrameAction = function(_super) { + var AnimationFrameAction = (function(_super) { __extends(AnimationFrameAction2, _super); function AnimationFrameAction2(scheduler, work) { var _this = _super.call(this, scheduler, work) || this; @@ -29479,7 +29488,7 @@ var require_AnimationFrameAction = __commonJS({ return void 0; }; return AnimationFrameAction2; - }(AsyncAction_1.AsyncAction); + })(AsyncAction_1.AsyncAction); exports2.AnimationFrameAction = AnimationFrameAction; } }); @@ -29488,7 +29497,7 @@ var require_AnimationFrameAction = __commonJS({ var require_AnimationFrameScheduler = __commonJS({ "node_modules/rxjs/dist/cjs/internal/scheduler/AnimationFrameScheduler.js"(exports2) { "use strict"; - var __extends = exports2 && exports2.__extends || /* @__PURE__ */ function() { + var __extends = exports2 && exports2.__extends || /* @__PURE__ */ (function() { var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { d2.__proto__ = b2; @@ -29506,11 +29515,11 @@ var require_AnimationFrameScheduler = __commonJS({ } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; - }(); + })(); Object.defineProperty(exports2, "__esModule", { value: true }); exports2.AnimationFrameScheduler = void 0; var AsyncScheduler_1 = require_AsyncScheduler(); - var AnimationFrameScheduler = function(_super) { + var AnimationFrameScheduler = (function(_super) { __extends(AnimationFrameScheduler2, _super); function AnimationFrameScheduler2() { return _super !== null && _super.apply(this, arguments) || this; @@ -29541,7 +29550,7 @@ var require_AnimationFrameScheduler = __commonJS({ } }; return AnimationFrameScheduler2; - }(AsyncScheduler_1.AsyncScheduler); + })(AsyncScheduler_1.AsyncScheduler); exports2.AnimationFrameScheduler = AnimationFrameScheduler; } }); @@ -29563,7 +29572,7 @@ var require_animationFrame = __commonJS({ var require_VirtualTimeScheduler = __commonJS({ "node_modules/rxjs/dist/cjs/internal/scheduler/VirtualTimeScheduler.js"(exports2) { "use strict"; - var __extends = exports2 && exports2.__extends || /* @__PURE__ */ function() { + var __extends = exports2 && exports2.__extends || /* @__PURE__ */ (function() { var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { d2.__proto__ = b2; @@ -29581,13 +29590,13 @@ var require_VirtualTimeScheduler = __commonJS({ } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; - }(); + })(); Object.defineProperty(exports2, "__esModule", { value: true }); exports2.VirtualAction = exports2.VirtualTimeScheduler = void 0; var AsyncAction_1 = require_AsyncAction(); var Subscription_1 = require_Subscription(); var AsyncScheduler_1 = require_AsyncScheduler(); - var VirtualTimeScheduler = function(_super) { + var VirtualTimeScheduler = (function(_super) { __extends(VirtualTimeScheduler2, _super); function VirtualTimeScheduler2(schedulerActionCtor, maxFrames) { if (schedulerActionCtor === void 0) { @@ -29624,9 +29633,9 @@ var require_VirtualTimeScheduler = __commonJS({ }; VirtualTimeScheduler2.frameTimeFactor = 10; return VirtualTimeScheduler2; - }(AsyncScheduler_1.AsyncScheduler); + })(AsyncScheduler_1.AsyncScheduler); exports2.VirtualTimeScheduler = VirtualTimeScheduler; - var VirtualAction = function(_super) { + var VirtualAction = (function(_super) { __extends(VirtualAction2, _super); function VirtualAction2(scheduler, work, index) { if (index === void 0) { @@ -29693,7 +29702,7 @@ var require_VirtualTimeScheduler = __commonJS({ } }; return VirtualAction2; - }(AsyncAction_1.AsyncAction); + })(AsyncAction_1.AsyncAction); exports2.VirtualAction = VirtualAction; } }); @@ -29768,9 +29777,9 @@ var require_isArrayLike = __commonJS({ "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.isArrayLike = void 0; - exports2.isArrayLike = function(x) { + exports2.isArrayLike = (function(x) { return x && typeof x.length === "number" && typeof x !== "function"; - }; + }); } }); @@ -30660,7 +30669,7 @@ var require_Notification = __commonJS({ NotificationKind2["ERROR"] = "E"; NotificationKind2["COMPLETE"] = "C"; })(NotificationKind = exports2.NotificationKind || (exports2.NotificationKind = {})); - var Notification = function() { + var Notification = (function() { function Notification2(kind, value, error) { this.kind = kind; this.value = value; @@ -30699,7 +30708,7 @@ var require_Notification = __commonJS({ }; Notification2.completeNotification = new Notification2("C"); return Notification2; - }(); + })(); exports2.Notification = Notification; function observeNotification(notification, observer) { var _a, _b, _c; @@ -32679,10 +32688,10 @@ var require_scanInternals = __commonJS({ var i = index++; state = hasState ? accumulator(state, value, i) : (hasState = true, value); emitOnNext && subscriber.next(state); - }, emitBeforeComplete && function() { + }, emitBeforeComplete && (function() { hasState && subscriber.next(state); subscriber.complete(); - })); + }))); }; } exports2.scanInternals = scanInternals; @@ -35286,13 +35295,13 @@ var require_timeInterval = __commonJS({ }); } exports2.timeInterval = timeInterval; - var TimeInterval = /* @__PURE__ */ function() { + var TimeInterval = /* @__PURE__ */ (function() { function TimeInterval2(value, interval) { this.value = value; this.interval = interval; } return TimeInterval2; - }(); + })(); exports2.TimeInterval = TimeInterval; } }); @@ -35867,15 +35876,15 @@ var require_zipWith = __commonJS({ var require_cjs = __commonJS({ "node_modules/rxjs/dist/cjs/index.js"(exports2) { "use strict"; - var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { if (k2 === void 0) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); - } : function(o, m, k, k2) { + }) : (function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; - }); + })); var __exportStar = exports2 && exports2.__exportStar || function(m, exports3) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p); }; @@ -36874,7 +36883,7 @@ var require_subscribeEvent = __commonJS({ var require_src6 = __commonJS({ "node_modules/@microsoft/agents-copilotstudio-client/dist/src/index.js"(exports2) { "use strict"; - var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { @@ -36883,10 +36892,10 @@ var require_src6 = __commonJS({ } }; } Object.defineProperty(o, k2, desc); - } : function(o, m, k, k2) { + }) : (function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; - }); + })); var __exportStar = exports2 && exports2.__exportStar || function(m, exports3) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p); }; From e775ce2cf850bc64882ca66ddd75bff2cfe3579e Mon Sep 17 00:00:00 2001 From: xenophobentx Date: Fri, 25 Sep 2026 21:51:25 +0200 Subject: [PATCH 2/4] Add tool_calls to the /chat turn summary The agenticruntime stream sends a toolCall entity when a tool starts and when it completes, with the parameters the model filled in, the result and the duration. The summary only kept the activity text. collectToolCalls merges those entities into one record per toolCallId, keeping the runtime's field names. A repeated "started" entity can't undo "completed", empty parameter objects don't overwrite real ones, results over 2000 characters are truncated with their full length recorded, and an error field is kept if the runtime sends one. The default JSON output includes tool_calls and --pretty lists the calls with their inputs. Fixes #43 --- commands/chat.md | 17 ++- scripts/chat-with-agent.bundle.js | 52 +++++++++ scripts/src/chat-with-agent.js | 4 +- scripts/src/response-format.js | 58 ++++++++++ scripts/src/terminal-render.js | 16 ++- scripts/test/response-format.test.js | 166 +++++++++++++++++++++++++++ 6 files changed, 307 insertions(+), 6 deletions(-) create mode 100644 scripts/test/response-format.test.js diff --git a/commands/chat.md b/commands/chat.md index bd0ad2d..2a10bb7 100644 --- a/commands/chat.md +++ b/commands/chat.md @@ -146,13 +146,23 @@ Present it to the user like a chat client would: clearly-secondary "thinking" notes (e.g. a collapsible/italic list), distinct from the answer. - `steps` — tool/status cues such as `"Running Bash..."`. Show them as lightweight progress/tool indicators, separate from both reasoning and the answer. +- `tool_calls` — one record per tool call: `{ id, name, category, status, filledParameters, + unfilledParameters, durationMs, result, error }`. The parameter and result field names follow the + runtime's `toolCall` entity, so they match `--raw`. `filledParameters` are the values the model sent. `result` is the + tool output as a string (JSON-stringified if the runtime sent an object), cut at 2000 characters + with `resultTruncated: true` and the full `resultLength`. `error` is only present if the runtime + sent one. Use these when the user is debugging a tool: show what was sent and what came back. + Don't dump full results by default; they can contain business data. A flow that failed can still + show up as `completed` with an empty result, so when a flow tool's result looks wrong or empty, + suggest checking that flow's run history. - `attachments` — files the agent produced, already **materialized to disk**. Each has `{ name, contentType, bytes, path }` (or `url` for external links). Give the user the `path`; the base64 is never inlined, so offer to open/preview the file rather than dumping its contents. - `activity_count` — raw activity count, for diagnostics only. Render **messages, reasoning, and tool steps differently** so the user can tell them apart — the -final `text` is the answer, `reasoning` is the agent's thinking, and `steps` are tool invocations. +final `text` is the answer, `reasoning` is the agent's thinking, `steps` are tool/status cues, and +`tool_calls` hold the details of each tool invocation. - If `status` is `"error"`, surface the `error` message. For `needsClientId`, run the setup workflow (step 4). For a non-CLI `recognizerKind`, stop per the gate (step 3). If the error carries @@ -165,8 +175,9 @@ final `text` is the answer, `reasoning` is the agent's thinking, and `steps` are **Output modes.** Add `--raw` to get the full, unfiltered activity payloads (start + turn) for debugging. Add `--pretty` for a colorized, live terminal chat experience (reasoning in cyan, tool -cues dimmed, the answer rendered as styled Markdown, attachments listed with their paths) — useful -when a human runs the script directly in a terminal rather than having the agent relay the JSON. +cues dimmed, the answer rendered as styled Markdown, attachments listed with their paths, tool +calls listed with their inputs) — useful when a human runs the script directly in a terminal +rather than having the agent relay the JSON. Keep the loop going: after each agent reply, ask the user for their next message and send it with the diff --git a/scripts/chat-with-agent.bundle.js b/scripts/chat-with-agent.bundle.js index 9b71a7f..7bb36bb 100644 --- a/scripts/chat-with-agent.bundle.js +++ b/scripts/chat-with-agent.bundle.js @@ -37029,6 +37029,44 @@ var require_response_format = __commonJS({ } return out; } + var MAX_TOOL_RESULT_CHARS = 2e3; + var toolStatusRank = (status) => status === "started" ? 0 : 1; + function collectToolCalls(activities) { + const byId = /* @__PURE__ */ new Map(); + let anonymous = 0; + for (const a of activities || []) { + for (const e of a.entities || []) { + if (e.type !== "toolCall") continue; + const id = e.toolCallId || `${e.toolName || "tool"}#${anonymous++}`; + const call = byId.get(id) || { id }; + if (e.toolName) call.name = e.toolName; + if (e.toolCategory) call.category = e.toolCategory; + if (e.status && (call.status === void 0 || toolStatusRank(e.status) >= toolStatusRank(call.status))) { + call.status = e.status; + } + const params = e.filledParameters; + if (params && typeof params === "object" && !Array.isArray(params) && Object.keys(params).length) { + call.filledParameters = e.filledParameters; + } + if (Array.isArray(e.unfilledParameters)) call.unfilledParameters = e.unfilledParameters; + if (typeof e.durationMs === "number") call.durationMs = e.durationMs; + if (e.result !== void 0 && e.result !== null) { + const r = typeof e.result === "string" ? e.result : JSON.stringify(e.result); + if (r.length > MAX_TOOL_RESULT_CHARS) { + call.result = r.slice(0, MAX_TOOL_RESULT_CHARS); + call.resultTruncated = true; + call.resultLength = r.length; + } else { + call.result = r; + } + } + const error = e.error ?? e.errorMessage; + if (error !== void 0 && error !== null && error !== "") call.error = error; + byId.set(id, call); + } + } + return [...byId.values()]; + } function finalText(activities) { const msg = (activities || []).filter((a) => a.type === "message" && a.text).pop(); if (msg) return msg.text; @@ -37125,6 +37163,7 @@ var require_response_format = __commonJS({ greeting, reasoning: collectReasoning(activities), steps: collectSteps(activities), + tool_calls: collectToolCalls(activities), text: finalText(activities), attachments }; @@ -37134,6 +37173,8 @@ var require_response_format = __commonJS({ // exported for reuse / testing collectReasoning, collectSteps, + collectToolCalls, + MAX_TOOL_RESULT_CHARS, finalText, materializeAttachments, decodeDataUrl @@ -37253,6 +37294,16 @@ var require_terminal_render = __commonJS({ w(dim(" \u{1F4CE} ") + (a.path || a.url) + (meta ? dim(" (" + meta + ")") : "")); } } + if (summary.tool_calls && summary.tool_calls.length) { + w("\n" + dim("tool calls:")); + for (const c of summary.tool_calls) { + const meta = [c.status, c.durationMs != null ? c.durationMs + " ms" : null].filter(Boolean).join(", "); + let input = JSON.stringify(c.filledParameters || {}); + if (input.length > 300) input = input.slice(0, 300) + "\u2026"; + w(dim(" \u2699 ") + c.name + dim(" (" + meta + ") in: " + input)); + if (c.error) w(dim(" error: " + (typeof c.error === "string" ? c.error : JSON.stringify(c.error)))); + } + } w(""); } return { onActivity, finishTurn, greeting, userEcho, enabled }; @@ -37847,6 +37898,7 @@ async function main() { greeting: summary.greeting, reasoning: summary.reasoning, steps: summary.steps, + tool_calls: summary.tool_calls, text: summary.text, attachments: summary.attachments, activity_count: result.activities.length diff --git a/scripts/src/chat-with-agent.js b/scripts/src/chat-with-agent.js index 2fa17d3..af4398b 100644 --- a/scripts/src/chat-with-agent.js +++ b/scripts/src/chat-with-agent.js @@ -25,7 +25,8 @@ * node chat-with-agent.bundle.js --raw "hello" (full activity dump) * * Output (stdout): by default a distilled JSON summary of the turn — { conversation_id, greeting, - * reasoning[], steps[] (tool/status cues), text (final answer), attachments[] }. Attachments the + * reasoning[], steps[] (tool/status cues), tool_calls[] (tool name, parameters, result, + * status, duration), text (final answer), attachments[] }. Attachments the * agent produces are materialized to disk (/chat-attachments//) and * only their file paths are returned, so large images never bloat the caller's context. Use * --raw for the full activity payloads, or --pretty for a colorized live terminal experience. @@ -794,6 +795,7 @@ async function main() { greeting: summary.greeting, reasoning: summary.reasoning, steps: summary.steps, + tool_calls: summary.tool_calls, text: summary.text, attachments: summary.attachments, activity_count: result.activities.length, diff --git a/scripts/src/response-format.js b/scripts/src/response-format.js index f895b0f..540ca4a 100644 --- a/scripts/src/response-format.js +++ b/scripts/src/response-format.js @@ -7,6 +7,8 @@ * - greeting : the start-conversation greeting (start turns only) * - reasoning : the agent's chain-of-thought steps (entities[].type === "thought") * - steps : tool/status cues (channelData.streamType === "informative") + * - tool_calls : one record per tool call (entities[].type === "toolCall"), with the + * parameters the model filled in, the result, status and duration * - text : the final answer markdown (the terminal `message` / streamType "final") * - attachments: files the agent produced, **materialized to disk** — the base64 blob * is written out and only { name, contentType, bytes, path } is returned, @@ -64,6 +66,59 @@ function collectSteps(activities) { return out; } +// Long tool results can carry large business payloads; keep the summary compact. +const MAX_TOOL_RESULT_CHARS = 2000; + +// A repeated "started" in the cumulative stream must not undo a later status. Any status +// other than "started" (completed, failed, or one we haven't seen) counts as later. +const toolStatusRank = (status) => (status === "started" ? 0 : 1); + +// Tool calls usually arrive as `toolCall` entities on informative activities: one with +// status "started" (filled/unfilled parameters) and one with status "completed" +// (result, durationMs). Merge them into one record per toolCallId, in call order. +// Parameter and result field names follow the runtime's own names so they can be matched +// against `--raw`. Entities without a toolCallId can't be paired, so each one becomes its +// own record rather than being merged with an unrelated call. +function collectToolCalls(activities) { + const byId = new Map(); + let anonymous = 0; + for (const a of activities || []) { + for (const e of a.entities || []) { + if (e.type !== "toolCall") continue; + const id = e.toolCallId || `${e.toolName || "tool"}#${anonymous++}`; + const call = byId.get(id) || { id }; + if (e.toolName) call.name = e.toolName; + if (e.toolCategory) call.category = e.toolCategory; + if ( + e.status && + (call.status === undefined || toolStatusRank(e.status) >= toolStatusRank(call.status)) + ) { + call.status = e.status; + } + const params = e.filledParameters; + if (params && typeof params === "object" && !Array.isArray(params) && Object.keys(params).length) { + call.filledParameters = e.filledParameters; + } + if (Array.isArray(e.unfilledParameters)) call.unfilledParameters = e.unfilledParameters; + if (typeof e.durationMs === "number") call.durationMs = e.durationMs; + if (e.result !== undefined && e.result !== null) { + const r = typeof e.result === "string" ? e.result : JSON.stringify(e.result); + if (r.length > MAX_TOOL_RESULT_CHARS) { + call.result = r.slice(0, MAX_TOOL_RESULT_CHARS); + call.resultTruncated = true; + call.resultLength = r.length; + } else { + call.result = r; + } + } + const error = e.error ?? e.errorMessage; + if (error !== undefined && error !== null && error !== "") call.error = error; + byId.set(id, call); + } + } + return [...byId.values()]; +} + function finalText(activities) { const msg = (activities || []).filter((a) => a.type === "message" && a.text).pop(); if (msg) return msg.text; @@ -176,6 +231,7 @@ function summarizeTurn({ greeting, reasoning: collectReasoning(activities), steps: collectSteps(activities), + tool_calls: collectToolCalls(activities), text: finalText(activities), attachments, }; @@ -186,6 +242,8 @@ module.exports = { // exported for reuse / testing collectReasoning, collectSteps, + collectToolCalls, + MAX_TOOL_RESULT_CHARS, finalText, materializeAttachments, decodeDataUrl, diff --git a/scripts/src/terminal-render.js b/scripts/src/terminal-render.js index a3f1aae..289ad33 100644 --- a/scripts/src/terminal-render.js +++ b/scripts/src/terminal-render.js @@ -4,8 +4,8 @@ * Only used when `--pretty` is passed (or stdout is a TTY). It renders, as the turn streams: * - reasoning (chain-of-thought) as dim cyan lines * - tool/status cues ("Running Bash...") as dim chips - * then, at the end of the turn, the final answer with lightweight Markdown -> ANSI styling - * and a list of any materialized attachment files. + * then, at the end of the turn, the final answer with lightweight Markdown -> ANSI styling, + * a list of any materialized attachment files, and the tool calls with their inputs. * * The default (machine) output path does NOT use this — it emits distilled JSON instead. */ @@ -142,6 +142,18 @@ function createLiveRenderer({ out = process.stdout } = {}) { w(dim(" 📎 ") + (a.path || a.url) + (meta ? dim(" (" + meta + ")") : "")); } } + if (summary.tool_calls && summary.tool_calls.length) { + w("\n" + dim("tool calls:")); + for (const c of summary.tool_calls) { + const meta = [c.status, c.durationMs != null ? c.durationMs + " ms" : null] + .filter(Boolean) + .join(", "); + let input = JSON.stringify(c.filledParameters || {}); + if (input.length > 300) input = input.slice(0, 300) + "…"; + w(dim(" ⚙ ") + c.name + dim(" (" + meta + ") in: " + input)); + if (c.error) w(dim(" error: " + (typeof c.error === "string" ? c.error : JSON.stringify(c.error)))); + } + } w(""); } diff --git a/scripts/test/response-format.test.js b/scripts/test/response-format.test.js new file mode 100644 index 0000000..ca1e1b7 --- /dev/null +++ b/scripts/test/response-format.test.js @@ -0,0 +1,166 @@ +const assert = require("node:assert/strict"); +const test = require("node:test"); + +const { + collectToolCalls, + summarizeTurn, + MAX_TOOL_RESULT_CHARS, +} = require("../src/response-format"); + +// Shape of the informative activities the agenticruntime sends for one flow tool call. +function toolActivity(text, entity) { + return { + type: "typing", + text, + channelData: { streamType: "informative" }, + entities: [ + { + type: "toolCall", + toolCallId: "toolu_01", + toolName: "GetPurchaseStatus", + toolDisplayName: "GetPurchaseStatus", + toolCategory: "Flow", + toolKind: "tool", + description: "Looks up a purchase request.", + ...entity, + }, + ], + }; +} + +const started = toolActivity("Calling GetPurchaseStatus...", { + status: "started", + filledParameters: { prNumber: "PR-1042" }, + unfilledParameters: ["ticketId"], +}); +const completed = toolActivity("GetPurchaseStatus completed", { + status: "completed", + filledParameters: { prNumber: "PR-1042" }, + durationMs: 6302, + result: '{"status":"approved"}', +}); + +test("merges started and completed toolCall entities into one record", () => { + assert.deepEqual(collectToolCalls([started, completed]), [ + { + id: "toolu_01", + name: "GetPurchaseStatus", + category: "Flow", + status: "completed", + filledParameters: { prNumber: "PR-1042" }, + unfilledParameters: ["ticketId"], + durationMs: 6302, + result: '{"status":"approved"}', + }, + ]); +}); + +test("keeps a call that only started", () => { + const [call] = collectToolCalls([started]); + assert.equal(call.status, "started"); + assert.equal(call.result, undefined); +}); + +test("keeps separate calls apart, in call order", () => { + const other = toolActivity("Calling CheckStock...", { + toolCallId: "toolu_02", + toolName: "CheckStock", + status: "started", + filledParameters: { partNo: "A-1" }, + }); + const calls = collectToolCalls([started, other, completed]); + assert.deepEqual( + calls.map((c) => [c.id, c.name, c.status]), + [ + ["toolu_01", "GetPurchaseStatus", "completed"], + ["toolu_02", "CheckStock", "started"], + ] + ); +}); + +test("truncates long results and reports the full length", () => { + const big = toolActivity("GetPurchaseStatus completed", { + status: "completed", + result: "x".repeat(5000), + }); + const [call] = collectToolCalls([big]); + assert.equal(call.result.length, MAX_TOOL_RESULT_CHARS); + assert.equal(call.resultTruncated, true); + assert.equal(call.resultLength, 5000); +}); + +test("a repeated started entity does not undo completed", () => { + const [call] = collectToolCalls([started, completed, started]); + assert.equal(call.status, "completed"); + assert.equal(call.result, '{"status":"approved"}'); +}); + +test("an empty filledParameters object keeps the earlier values", () => { + const emptyParams = toolActivity("GetPurchaseStatus completed", { + status: "completed", + filledParameters: {}, + }); + const [call] = collectToolCalls([started, emptyParams]); + assert.deepEqual(call.filledParameters, { prNumber: "PR-1042" }); +}); + +test("an empty unfilledParameters list replaces the earlier one", () => { + const nowFilled = toolActivity("GetPurchaseStatus completed", { + status: "completed", + unfilledParameters: [], + }); + const [call] = collectToolCalls([started, nowFilled]); + assert.deepEqual(call.unfilledParameters, []); +}); + +test("null results are left out and object results are stringified", () => { + const nullResult = toolActivity("GetPurchaseStatus completed", { status: "completed", result: null }); + assert.equal(collectToolCalls([nullResult])[0].result, undefined); + const objResult = toolActivity("GetPurchaseStatus completed", { + status: "completed", + result: { status: "approved" }, + }); + assert.equal(collectToolCalls([objResult])[0].result, '{"status":"approved"}'); +}); + +test("keeps an error field when the runtime sends one", () => { + const failed = toolActivity("GetPurchaseStatus failed", { + status: "failed", + error: { code: "FlowFailed", message: "boom" }, + }); + const [call] = collectToolCalls([started, failed]); + assert.equal(call.status, "failed"); + assert.deepEqual(call.error, { code: "FlowFailed", message: "boom" }); +}); + +test("keeps calls without a toolCallId as separate records", () => { + const noId = (status) => ({ + type: "typing", + entities: [{ type: "toolCall", toolName: "Lookup", status }], + }); + const calls = collectToolCalls([noId("started"), noId("completed")]); + assert.equal(calls.length, 2); + assert.ok(calls.every((c) => c.name === "Lookup")); +}); + +test("ignores activities without toolCall entities", () => { + const thought = { type: "typing", entities: [{ type: "thought", text: "thinking" }] }; + assert.deepEqual(collectToolCalls([thought, { type: "message", text: "hi" }]), []); +}); + +test("summarizeTurn exposes tool_calls next to steps", () => { + const summary = summarizeTurn({ activities: [started, completed] }); + assert.deepEqual(summary.steps, ["Calling GetPurchaseStatus...", "GetPurchaseStatus completed"]); + assert.equal(summary.tool_calls.length, 1); + assert.equal(summary.tool_calls[0].result, '{"status":"approved"}'); +}); + +test("an empty error string is treated as no error", () => { + const blank = toolActivity("GetPurchaseStatus completed", { status: "completed", error: "" }); + assert.equal(collectToolCalls([blank])[0].error, undefined); +}); + +test("a status the runtime adds later is not dropped after completed", () => { + const cancelled = toolActivity("GetPurchaseStatus cancelled", { status: "cancelled" }); + assert.equal(collectToolCalls([started, completed, cancelled])[0].status, "cancelled"); +}); From e74c2bc9c7e7aceaf2ba87f22d2f6635638fadbd Mon Sep 17 00:00:00 2001 From: xenophobentx Date: Fri, 25 Sep 2026 22:01:29 +0200 Subject: [PATCH 3/4] Address review: separate anonymous tool call keys, keep errorMessage Anonymous toolCall entities used a fallback id as the map key, which could collide with a real toolCallId of the same shape. They now use their own key space. An empty error field no longer hides a non-empty errorMessage. --- scripts/chat-with-agent.bundle.js | 13 ++++++++----- scripts/src/response-format.js | 14 +++++++++----- scripts/test/response-format.test.js | 20 ++++++++++++++++++++ 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/scripts/chat-with-agent.bundle.js b/scripts/chat-with-agent.bundle.js index 7bb36bb..5926881 100644 --- a/scripts/chat-with-agent.bundle.js +++ b/scripts/chat-with-agent.bundle.js @@ -37037,8 +37037,10 @@ var require_response_format = __commonJS({ for (const a of activities || []) { for (const e of a.entities || []) { if (e.type !== "toolCall") continue; - const id = e.toolCallId || `${e.toolName || "tool"}#${anonymous++}`; - const call = byId.get(id) || { id }; + const key = e.toolCallId ? `id:${e.toolCallId}` : `anon:${anonymous}`; + const id = e.toolCallId || `anon:${e.toolName || "tool"}#${anonymous}`; + if (!e.toolCallId) anonymous++; + const call = byId.get(key) || { id }; if (e.toolName) call.name = e.toolName; if (e.toolCategory) call.category = e.toolCategory; if (e.status && (call.status === void 0 || toolStatusRank(e.status) >= toolStatusRank(call.status))) { @@ -37060,9 +37062,10 @@ var require_response_format = __commonJS({ call.result = r; } } - const error = e.error ?? e.errorMessage; - if (error !== void 0 && error !== null && error !== "") call.error = error; - byId.set(id, call); + const present = (v) => v !== void 0 && v !== null && v !== ""; + const error = present(e.error) ? e.error : e.errorMessage; + if (present(error)) call.error = error; + byId.set(key, call); } } return [...byId.values()]; diff --git a/scripts/src/response-format.js b/scripts/src/response-format.js index 540ca4a..1d90888 100644 --- a/scripts/src/response-format.js +++ b/scripts/src/response-format.js @@ -85,8 +85,11 @@ function collectToolCalls(activities) { for (const a of activities || []) { for (const e of a.entities || []) { if (e.type !== "toolCall") continue; - const id = e.toolCallId || `${e.toolName || "tool"}#${anonymous++}`; - const call = byId.get(id) || { id }; + // Anonymous entries get their own map key space so they can never collide with a real id. + const key = e.toolCallId ? `id:${e.toolCallId}` : `anon:${anonymous}`; + const id = e.toolCallId || `anon:${e.toolName || "tool"}#${anonymous}`; + if (!e.toolCallId) anonymous++; + const call = byId.get(key) || { id }; if (e.toolName) call.name = e.toolName; if (e.toolCategory) call.category = e.toolCategory; if ( @@ -111,9 +114,10 @@ function collectToolCalls(activities) { call.result = r; } } - const error = e.error ?? e.errorMessage; - if (error !== undefined && error !== null && error !== "") call.error = error; - byId.set(id, call); + const present = (v) => v !== undefined && v !== null && v !== ""; + const error = present(e.error) ? e.error : e.errorMessage; + if (present(error)) call.error = error; + byId.set(key, call); } } return [...byId.values()]; diff --git a/scripts/test/response-format.test.js b/scripts/test/response-format.test.js index ca1e1b7..5031e71 100644 --- a/scripts/test/response-format.test.js +++ b/scripts/test/response-format.test.js @@ -164,3 +164,23 @@ test("a status the runtime adds later is not dropped after completed", () => { const cancelled = toolActivity("GetPurchaseStatus cancelled", { status: "cancelled" }); assert.equal(collectToolCalls([started, completed, cancelled])[0].status, "cancelled"); }); + +test("an anonymous call never merges with a real id that looks like its fallback", () => { + const anon = { type: "typing", entities: [{ type: "toolCall", toolName: "Lookup", status: "started" }] }; + const real = { + type: "typing", + entities: [{ type: "toolCall", toolCallId: "Lookup#0", toolName: "Lookup", status: "completed" }], + }; + const calls = collectToolCalls([anon, real]); + assert.equal(calls.length, 2); + assert.notEqual(calls[0].id, calls[1].id); +}); + +test("an empty error does not hide a non-empty errorMessage", () => { + const both = toolActivity("GetPurchaseStatus failed", { + status: "failed", + error: "", + errorMessage: "Flow run failed", + }); + assert.equal(collectToolCalls([both])[0].error, "Flow run failed"); +}); From d43970ddfc4e3a3923ff6b2717104dfcba2e7f9d Mon Sep 17 00:00:00 2001 From: xenophobentx Date: Fri, 25 Sep 2026 22:13:20 +0200 Subject: [PATCH 4/4] Address review: keep tool call records consistent across repeated entities - A later short result clears resultTruncated/resultLength. - A repeated "started" entity after a later status no longer overwrites parameters, duration or anything else; it can only fill gaps. - An error is dropped when the call moves to a new status without one. - --pretty falls back to the id for nameless calls and skips empty meta. - chat.md documents the anon: id and the {} result of a failed flow. --- commands/chat.md | 17 ++++++----- scripts/chat-with-agent.bundle.js | 27 ++++++++++------- scripts/src/response-format.js | 36 ++++++++++++++-------- scripts/src/terminal-render.js | 2 +- scripts/test/response-format.test.js | 45 ++++++++++++++++++++++++++++ 5 files changed, 96 insertions(+), 31 deletions(-) diff --git a/commands/chat.md b/commands/chat.md index 2a10bb7..c16b3a5 100644 --- a/commands/chat.md +++ b/commands/chat.md @@ -147,14 +147,15 @@ Present it to the user like a chat client would: - `steps` — tool/status cues such as `"Running Bash..."`. Show them as lightweight progress/tool indicators, separate from both reasoning and the answer. - `tool_calls` — one record per tool call: `{ id, name, category, status, filledParameters, - unfilledParameters, durationMs, result, error }`. The parameter and result field names follow the - runtime's `toolCall` entity, so they match `--raw`. `filledParameters` are the values the model sent. `result` is the - tool output as a string (JSON-stringified if the runtime sent an object), cut at 2000 characters - with `resultTruncated: true` and the full `resultLength`. `error` is only present if the runtime - sent one. Use these when the user is debugging a tool: show what was sent and what came back. - Don't dump full results by default; they can contain business data. A flow that failed can still - show up as `completed` with an empty result, so when a flow tool's result looks wrong or empty, - suggest checking that flow's run history. + unfilledParameters, durationMs, result, error }`. The parameter and result field names follow + the runtime's `toolCall` entity, so they match `--raw`. `id` is the runtime's `toolCallId`, or + `anon:#` when the runtime sent none. `filledParameters` are the values the model sent. + `result` is the tool output as a string (JSON-stringified if the runtime sent an object), cut at + 2000 characters with `resultTruncated: true` and the full `resultLength`. `error` is only present + if the runtime sent one. Use these when the user is debugging a tool: show what was sent and what + came back. Don't dump full results by default; they can contain business data. A flow that failed + can still show up as `completed` with an empty result such as `{}`, so when a flow tool's result + looks wrong or empty, suggest checking that flow's run history. - `attachments` — files the agent produced, already **materialized to disk**. Each has `{ name, contentType, bytes, path }` (or `url` for external links). Give the user the `path`; the base64 is never inlined, so offer to open/preview the file rather than dumping its contents. diff --git a/scripts/chat-with-agent.bundle.js b/scripts/chat-with-agent.bundle.js index 5926881..da6442d 100644 --- a/scripts/chat-with-agent.bundle.js +++ b/scripts/chat-with-agent.bundle.js @@ -37033,6 +37033,7 @@ var require_response_format = __commonJS({ var toolStatusRank = (status) => status === "started" ? 0 : 1; function collectToolCalls(activities) { const byId = /* @__PURE__ */ new Map(); + const present = (v) => v !== void 0 && v !== null && v !== ""; let anonymous = 0; for (const a of activities || []) { for (const e of a.entities || []) { @@ -37041,18 +37042,23 @@ var require_response_format = __commonJS({ const id = e.toolCallId || `anon:${e.toolName || "tool"}#${anonymous}`; if (!e.toolCallId) anonymous++; const call = byId.get(key) || { id }; - if (e.toolName) call.name = e.toolName; - if (e.toolCategory) call.category = e.toolCategory; - if (e.status && (call.status === void 0 || toolStatusRank(e.status) >= toolStatusRank(call.status))) { + const stale = e.status !== void 0 && call.status !== void 0 && toolStatusRank(e.status) < toolStatusRank(call.status); + const set = (field, value) => { + if (!stale || call[field] === void 0) call[field] = value; + }; + if (e.toolName) set("name", e.toolName); + if (e.toolCategory) set("category", e.toolCategory); + if (e.status && !stale && e.status !== call.status) { call.status = e.status; + delete call.error; } const params = e.filledParameters; if (params && typeof params === "object" && !Array.isArray(params) && Object.keys(params).length) { - call.filledParameters = e.filledParameters; + set("filledParameters", params); } - if (Array.isArray(e.unfilledParameters)) call.unfilledParameters = e.unfilledParameters; - if (typeof e.durationMs === "number") call.durationMs = e.durationMs; - if (e.result !== void 0 && e.result !== null) { + if (Array.isArray(e.unfilledParameters)) set("unfilledParameters", e.unfilledParameters); + if (typeof e.durationMs === "number") set("durationMs", e.durationMs); + if (!stale && e.result !== void 0 && e.result !== null) { const r = typeof e.result === "string" ? e.result : JSON.stringify(e.result); if (r.length > MAX_TOOL_RESULT_CHARS) { call.result = r.slice(0, MAX_TOOL_RESULT_CHARS); @@ -37060,11 +37066,12 @@ var require_response_format = __commonJS({ call.resultLength = r.length; } else { call.result = r; + delete call.resultTruncated; + delete call.resultLength; } } - const present = (v) => v !== void 0 && v !== null && v !== ""; const error = present(e.error) ? e.error : e.errorMessage; - if (present(error)) call.error = error; + if (present(error) && (!stale || call.error === void 0)) call.error = error; byId.set(key, call); } } @@ -37303,7 +37310,7 @@ var require_terminal_render = __commonJS({ const meta = [c.status, c.durationMs != null ? c.durationMs + " ms" : null].filter(Boolean).join(", "); let input = JSON.stringify(c.filledParameters || {}); if (input.length > 300) input = input.slice(0, 300) + "\u2026"; - w(dim(" \u2699 ") + c.name + dim(" (" + meta + ") in: " + input)); + w(dim(" \u2699 ") + (c.name || c.id) + (meta ? dim(" (" + meta + ")") : "") + dim(" in: " + input)); if (c.error) w(dim(" error: " + (typeof c.error === "string" ? c.error : JSON.stringify(c.error)))); } } diff --git a/scripts/src/response-format.js b/scripts/src/response-format.js index 1d90888..85311d2 100644 --- a/scripts/src/response-format.js +++ b/scripts/src/response-format.js @@ -81,6 +81,7 @@ const toolStatusRank = (status) => (status === "started" ? 0 : 1); // own record rather than being merged with an unrelated call. function collectToolCalls(activities) { const byId = new Map(); + const present = (v) => v !== undefined && v !== null && v !== ""; let anonymous = 0; for (const a of activities || []) { for (const e of a.entities || []) { @@ -90,21 +91,31 @@ function collectToolCalls(activities) { const id = e.toolCallId || `anon:${e.toolName || "tool"}#${anonymous}`; if (!e.toolCallId) anonymous++; const call = byId.get(key) || { id }; - if (e.toolName) call.name = e.toolName; - if (e.toolCategory) call.category = e.toolCategory; - if ( - e.status && - (call.status === undefined || toolStatusRank(e.status) >= toolStatusRank(call.status)) - ) { + // An entity from an earlier phase than the record's current status (a repeated + // "started" after "completed") must not overwrite anything; it may only fill gaps. + const stale = + e.status !== undefined && + call.status !== undefined && + toolStatusRank(e.status) < toolStatusRank(call.status); + const set = (field, value) => { + if (!stale || call[field] === undefined) call[field] = value; + }; + if (e.toolName) set("name", e.toolName); + if (e.toolCategory) set("category", e.toolCategory); + if (e.status && !stale && e.status !== call.status) { call.status = e.status; + // An error belongs to the status it came with; keep it only if this entity repeats it. + delete call.error; } + // An empty object means "nothing filled yet", so it must not erase real values; an empty + // unfilledParameters list means "all filled now", so it does replace the earlier list. const params = e.filledParameters; if (params && typeof params === "object" && !Array.isArray(params) && Object.keys(params).length) { - call.filledParameters = e.filledParameters; + set("filledParameters", params); } - if (Array.isArray(e.unfilledParameters)) call.unfilledParameters = e.unfilledParameters; - if (typeof e.durationMs === "number") call.durationMs = e.durationMs; - if (e.result !== undefined && e.result !== null) { + if (Array.isArray(e.unfilledParameters)) set("unfilledParameters", e.unfilledParameters); + if (typeof e.durationMs === "number") set("durationMs", e.durationMs); + if (!stale && e.result !== undefined && e.result !== null) { const r = typeof e.result === "string" ? e.result : JSON.stringify(e.result); if (r.length > MAX_TOOL_RESULT_CHARS) { call.result = r.slice(0, MAX_TOOL_RESULT_CHARS); @@ -112,11 +123,12 @@ function collectToolCalls(activities) { call.resultLength = r.length; } else { call.result = r; + delete call.resultTruncated; + delete call.resultLength; } } - const present = (v) => v !== undefined && v !== null && v !== ""; const error = present(e.error) ? e.error : e.errorMessage; - if (present(error)) call.error = error; + if (present(error) && (!stale || call.error === undefined)) call.error = error; byId.set(key, call); } } diff --git a/scripts/src/terminal-render.js b/scripts/src/terminal-render.js index 289ad33..ee99fcf 100644 --- a/scripts/src/terminal-render.js +++ b/scripts/src/terminal-render.js @@ -150,7 +150,7 @@ function createLiveRenderer({ out = process.stdout } = {}) { .join(", "); let input = JSON.stringify(c.filledParameters || {}); if (input.length > 300) input = input.slice(0, 300) + "…"; - w(dim(" ⚙ ") + c.name + dim(" (" + meta + ") in: " + input)); + w(dim(" ⚙ ") + (c.name || c.id) + (meta ? dim(" (" + meta + ")") : "") + dim(" in: " + input)); if (c.error) w(dim(" error: " + (typeof c.error === "string" ? c.error : JSON.stringify(c.error)))); } } diff --git a/scripts/test/response-format.test.js b/scripts/test/response-format.test.js index 5031e71..10e600f 100644 --- a/scripts/test/response-format.test.js +++ b/scripts/test/response-format.test.js @@ -184,3 +184,48 @@ test("an empty error does not hide a non-empty errorMessage", () => { }); assert.equal(collectToolCalls([both])[0].error, "Flow run failed"); }); + +test("a later short result clears the truncation fields", () => { + const long = toolActivity("GetPurchaseStatus completed", { status: "completed", result: "x".repeat(5000) }); + const short = toolActivity("GetPurchaseStatus completed", { status: "completed", result: "ok" }); + const [call] = collectToolCalls([long, short]); + assert.equal(call.result, "ok"); + assert.equal(call.resultTruncated, undefined); + assert.equal(call.resultLength, undefined); +}); + +test("a repeated started entity does not revert the parameters", () => { + const filled = toolActivity("GetPurchaseStatus completed", { + status: "completed", + filledParameters: { prNumber: "PR-1042", ticketId: "T-7" }, + unfilledParameters: [], + result: "ok", + }); + const [call] = collectToolCalls([started, filled, started]); + assert.deepEqual(call.filledParameters, { prNumber: "PR-1042", ticketId: "T-7" }); + assert.deepEqual(call.unfilledParameters, []); +}); + +test("an error is dropped when a later entity moves the call to a new status without one", () => { + const failed = toolActivity("GetPurchaseStatus failed", { status: "failed", error: "boom" }); + const done = toolActivity("GetPurchaseStatus completed", { status: "completed", result: "ok" }); + assert.equal(collectToolCalls([started, failed, done])[0].error, undefined); +}); + +test("a non-empty error wins over errorMessage", () => { + const both = toolActivity("GetPurchaseStatus failed", { + status: "failed", + error: "boom", + errorMessage: "other", + }); + assert.equal(collectToolCalls([both])[0].error, "boom"); +}); + +test("anonymous calls get an anon: id with the tool name", () => { + const anon = { type: "typing", entities: [{ type: "toolCall", toolName: "Lookup", status: "started" }] }; + const nameless = { type: "typing", entities: [{ type: "toolCall", status: "started" }] }; + assert.deepEqual( + collectToolCalls([anon, nameless]).map((c) => c.id), + ["anon:Lookup#0", "anon:tool#1"] + ); +});