@theokit/sdk-handoff 0.1.0 → 0.1.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 453ad2d: SE43 — system-design audit fixes (public-surface changes).
8
+
9
+ - **`@theokit/sdk` (minor):** the shared persistence kernel is now reachable from the sanctioned public `@theokit/sdk/persistence` barrel — `withCwdMutex`, `sanitizeFts5Query`, and `PersistenceSchema` are added (joining `replaceFileAtomic` / `openSqliteResilient` / `atomicWriteText` / `atomicWriteJson`). The `@theokit/sdk/internal/persistence` export is now **deprecated**: it re-exports its full surface unchanged for one release (back-compat) and is scheduled for removal in a future major. No breaking change; existing imports keep working.
10
+ - **Satellites (patch):** `sdk-tools` / `sdk-memory` / `sdk-cache` / `sdk-handoff` / `sdk-budget` tightened their `@theokit/sdk` peer-range floor from `>=1.7.0` to `>=4.0.0`, matching the v4-only surfaces they import (prevents a non-workspace install resolving an incompatible old sdk).
11
+
3
12
  All notable changes to `@theokit/sdk-handoff` are documented in this file.
4
13
 
5
14
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
package/dist/index.cjs CHANGED
@@ -444,7 +444,7 @@ var Handoff = class {
444
444
  const parent = opts.parentAgentId ?? "anonymous";
445
445
  const maxDepth = opts.maxHandoffDepth ?? 5;
446
446
  const targets = opts.targets;
447
- return sdk.definePlugin({
447
+ return sdk.Plugin.create({
448
448
  name: `handoff-${parent}`,
449
449
  version: "1.0.0",
450
450
  kind: "general",
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types/handoff.ts","../src/internal/registry.ts","../src/internal/telemetry.ts","../src/internal/dispatcher.ts","../src/internal/to-json-schema.ts","../src/internal/tool-injector.ts","../src/handoff.ts","../src/index.ts"],"names":["HandoffLoopError","HandoffPairLoopError","HandoffSelfReferenceError","HandoffReceiverDisposedError","HandoffNameCollisionError","createRequire","z","toJSONSchema","definePlugin","normalizeHandoffs","buildHandoffTool","dispatchHandoff","createChainState"],"mappings":";;;;;;;;;;;;;;;;;;AAyCaA,iCAAA,CAAA,CAeAC,qCAAA,CAAA,CAeAC,0CAAA,CAAA,CAaAC,6CAAA,CAAA,CAaAC;AAjGb,IAAA,YAAA,GAAA,KAAA,CAAA;AAAA,EAAA,sBAAA,GAAA;AAyCO,IAAMJ,wBAAA,GAAN,cAA+B,KAAA,CAAM;AAAA,MACxB,IAAA,GAAO,kBAAA;AAAA,MAChB,KAAA;AAAA,MACA,KAAA;AAAA,MACT,WAAA,CAAY,OAAe,KAAA,EAA8B;AACvD,QAAA,KAAA;AAAA,UACE,mCAAmC,KAAK,CAAA,SAAA,EAAY,KAAA,CAAM,IAAA,CAAK,MAAM,CAAC,CAAA,4DAAA;AAAA,SAExE;AACA,QAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AACb,QAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AAAA,MACf;AAAA,KACF;AAGO,IAAMC,4BAAA,GAAN,cAAmC,KAAA,CAAM;AAAA,MAC5B,IAAA,GAAO,sBAAA;AAAA,MAChB,aAAA;AAAA,MACA,eAAA;AAAA,MACT,WAAA,CAAY,eAAuB,eAAA,EAAyB;AAC1D,QAAA,KAAA;AAAA,UACE,CAAA,cAAA,EAAiB,aAAa,CAAA,IAAA,EAAO,eAAe,CAAA,+FAAA;AAAA,SAEtD;AACA,QAAA,IAAA,CAAK,aAAA,GAAgB,aAAA;AACrB,QAAA,IAAA,CAAK,eAAA,GAAkB,eAAA;AAAA,MACzB;AAAA,KACF;AAGO,IAAMC,iCAAA,GAAN,cAAwC,KAAA,CAAM;AAAA,MACjC,IAAA,GAAO,2BAAA;AAAA,MAChB,OAAA;AAAA,MACT,YAAY,OAAA,EAAiB;AAC3B,QAAA,KAAA;AAAA,UACE,UAAU,OAAO,CAAA,yHAAA;AAAA,SAEnB;AACA,QAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,MACjB;AAAA,KACF;AAGO,IAAMC,oCAAA,GAAN,cAA2C,KAAA,CAAM;AAAA,MACpC,IAAA,GAAO,8BAAA;AAAA,MAChB,eAAA;AAAA,MACT,YAAY,eAAA,EAAyB;AACnC,QAAA,KAAA;AAAA,UACE,yBAAyB,eAAe,CAAA,0EAAA;AAAA,SAE1C;AACA,QAAA,IAAA,CAAK,eAAA,GAAkB,eAAA;AAAA,MACzB;AAAA,KACF;AAGO,IAAMC,iCAAA,GAAN,cAAwC,KAAA,CAAM;AAAA,MACjC,IAAA,GAAO,2BAAA;AAAA,MAChB,eAAA;AAAA,MACT,YAAY,eAAA,EAAyB;AACnC,QAAA,KAAA;AAAA,UACE,0CAA0C,eAAe,CAAA,4DAAA;AAAA,SAE3D;AACA,QAAA,IAAA,CAAK,eAAA,GAAkB,eAAA;AAAA,MACzB;AAAA,KACF;AAAA,EAAA;AAAA,CAAA,CAAA;;;AC3GA,IAAA,gBAAA,GAAA,EAAA;AAAA,QAAA,CAAA,gBAAA,EAAA;AAAA,EAAA,gBAAA,EAAA,MAAA,gBAAA;AAAA,EAAA,YAAA,EAAA,MAAA,YAAA;AAAA,EAAA,SAAA,EAAA,MAAA;AAAA,CAAA,CAAA;AAoBO,SAAS,gBAAA,CAAiB,aAAqB,QAAA,EAAqC;AACzF,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,CAAC,WAAW,CAAA;AAAA,IACnB,SAAA,sBAAe,GAAA,EAAI;AAAA,IACnB;AAAA,GACF;AACF;AAMO,SAAS,SAAA,CACd,KAAA,EACA,aAAA,EACA,eAAA,EACM;AACN,EAAA,MAAM,OAAA,GAAU,CAAA,EAAG,aAAa,CAAA,EAAA,EAAK,eAAe,CAAA,CAAA;AACpD,EAAA,IAAI,KAAA,CAAM,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA,EAAG;AAChC,IAAA,MAAM,IAAIH,4BAAA,CAAqB,aAAA,EAAe,eAAe,CAAA;AAAA,EAC/D;AACA,EAAA,KAAA,CAAM,SAAA,CAAU,IAAI,OAAO,CAAA;AAC3B,EAAA,KAAA,CAAM,KAAA,CAAM,KAAK,eAAe,CAAA;AAEhC,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAA;AACnC,EAAA,IAAI,KAAA,GAAQ,MAAM,QAAA,EAAU;AAC1B,IAAA,MAAM,IAAID,yBAAiB,KAAA,CAAM,QAAA,EAAU,CAAC,GAAG,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,EAC7D;AACF;AAEO,SAAS,aAAa,KAAA,EAAkC;AAC7D,EAAA,OAAO,KAAA,CAAM,MAAM,MAAA,GAAS,CAAA;AAC9B;AApDA,IAAA,aAAA,GAAA,KAAA,CAAA;AAAA,EAAA,0BAAA,GAAA;AASA,IAAA,YAAA,EAAA;AAAA,EAAA;AAAA,CAAA,CAAA;ACyBA,SAAS,SAAA,CAAU,IAAA,EAAc,OAAA,GAAU,OAAA,EAAiC;AAC1E,EAAA,MAAM,MAAA,GAAS,WAAA,CAAY,GAAA,CAAI,IAAI,CAAA;AACnC,EAAA,IAAI,MAAA,KAAW,MAAA,EAAW,OAAO,MAAA,CAAO,MAAA,IAAU,MAAA;AAClD,EAAA,IAAI;AACF,IAAA,MAAM,CAAA,GAAIK,sBAAA,CAAc,2PAAe,CAAA;AACvC,IAAA,MAAM,IAAA,GAAO,EAAE,oBAAoB,CAAA;AAGnC,IAAA,IAAI,IAAA,CAAK,KAAA,EAAO,SAAA,KAAc,KAAA,CAAA,EAAW;AACvC,MAAA,WAAA,CAAY,GAAA,CAAI,IAAA,EAAM,EAAE,MAAA,EAAQ,MAAM,CAAA;AACtC,MAAA,OAAO,KAAA,CAAA;AAAA,IACT;AACA,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,SAAA,CAAU,MAAM,OAAO,CAAA;AACjD,IAAA,WAAA,CAAY,GAAA,CAAI,IAAA,EAAM,EAAE,MAAA,EAAQ,CAAA;AAChC,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,WAAA,CAAY,GAAA,CAAI,IAAA,EAAM,EAAE,MAAA,EAAQ,MAAM,CAAA;AACtC,IAAA,OAAO,MAAA;AAAA,EACT;AACF;AAeA,SAAS,IAAA,CAAQ,IAAa,QAAA,EAAgB;AAC5C,EAAA,IAAI;AACF,IAAA,OAAO,EAAA,EAAG;AAAA,EACZ,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,QAAA;AAAA,EACT;AACF;AAEO,SAAS,iBAAiB,KAAA,EAMX;AACpB,EAAA,MAAM,MAAA,GAAS,UAAU,WAAW,CAAA;AACpC,EAAA,IAAI,MAAA,KAAW,QAAW,OAAO,IAAA;AACjC,EAAA,MAAM,IAAA,GAA6B,IAAA;AAAA,IACjC,MACE,MAAA,CAAO,SAAA,CAAU,kBAAA,EAAoB;AAAA,MACnC,UAAA,EAAY;AAAA,QACV,gBAAgB,KAAA,CAAM,IAAA;AAAA,QACtB,cAAc,KAAA,CAAM,EAAA;AAAA,QACpB,kBAAkB,KAAA,CAAM,MAAA;AAAA,QACxB,iBAAiB,KAAA,CAAM,KAAA;AAAA,QACvB,qBAAqB,KAAA,CAAM;AAAA;AAC7B,KACD,CAAA;AAAA,IACH;AAAA,GACF;AACA,EAAA,IAAI,IAAA,KAAS,QAAW,OAAO,IAAA;AAC/B,EAAA,OAAO;AAAA,IACL,YAAA,EAAc,CAAC,CAAA,EAAG,CAAA,KAAM,IAAA,CAAK,MAAM,IAAA,CAAK,YAAA,CAAa,CAAA,EAAG,CAAC,CAAA,EAAG,MAAS,CAAA;AAAA,IACrE,KAAK,MAAM,IAAA,CAAK,MAAM,IAAA,CAAK,GAAA,IAAO,MAAS;AAAA,GAC7C;AACF;AAvGA,IAgCM,aA2BA,WAAA,EAOA,IAAA;AAlEN,IAAA,cAAA,GAAA,KAAA,CAAA;AAAA,EAAA,2BAAA,GAAA;AAgCA,IAAM,WAAA,uBAAkB,GAAA,EAA8B;AA2BtD,IAAM,WAAA,GAAc,qBAAA;AAOpB,IAAM,OAA0B,EAAE,YAAA,EAAc,MAAM,MAAA,EAAW,GAAA,EAAK,MAAM,MAAA,EAAU;AAAA,EAAA;AAAA,CAAA,CAAA;;;AClEtF,IAAA,kBAAA,GAAA,EAAA;AAAA,QAAA,CAAA,kBAAA,EAAA;AAAA,EAAA,eAAA,EAAA,MAAA;AAAA,CAAA,CAAA;AAgCA,eAAe,UAAA,CACb,QACA,OAAA,EACyB;AACzB,EAAA,IAAI,MAAA,KAAW,QAAW,OAAO,OAAA;AACjC,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,OAAO,OAAO,CAAA;AAC7B,IAAA,OAAO,MAAA,YAAkB,OAAA,GAAU,MAAM,MAAA,GAAS,MAAA;AAAA,EACpD,SAAS,GAAA,EAAK;AACZ,IAAA,IAAI,CAAC,gBAAA,EAAkB;AACrB,MAAA,gBAAA,GAAmB,IAAA;AACnB,MAAA,OAAA,CAAQ,MAAA,CAAO,KAAA;AAAA,QACb,8DAA8D,GAAA,YAAe,KAAA,GAAQ,IAAI,OAAA,GAAU,MAAA,CAAO,GAAG,CAAC;AAAA;AAAA,OAChH;AAAA,IACF;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AACF;AAOA,SAAS,iBAAA,CAAkB,YAA+B,GAAA,EAAuB;AAC/E,EAAA,MAAM,SAAA,GAAY,WAAW,OAAA,CAAQ,SAAA;AACrC,EAAA,IAAI,SAAA,KAAc,QAAW,OAAO,MAAA;AACpC,EAAA,MAAM,YAAY,GAAA,KAAQ,IAAA,IAAQ,GAAA,KAAQ,MAAA,GAAY,EAAC,GAAI,GAAA;AAC3D,EAAA,OAAO,SAAA,CAAU,MAAM,SAAS,CAAA;AAClC;AAEA,SAAS,gBAAgB,KAAA,EAA0B;AAGjD,EAAA,MAAM,KAAA,GAAQ,KAAA;AACd,EAAA,OAAO,MAAM,QAAA,KAAa,IAAA;AAC5B;AAiBA,eAAe,oBAAA,CACb,UAAA,EACA,GAAA,EACA,eAAA,EACe;AACf,EAAA,MAAM,GAAA,GAAM,WAAW,OAAA,CAAQ,SAAA;AAC/B,EAAA,IAAI,OAAA,GAAU,IAAA;AACd,EAAA,IAAI,OAAO,GAAA,KAAQ,SAAA,EAAW,OAAA,GAAU,GAAA;AAAA,OAAA,IAC/B,OAAO,QAAQ,UAAA,EAAY;AAClC,IAAA,MAAM,CAAA,GAAI,IAAI,GAAG,CAAA;AACjB,IAAA,OAAA,GAAU,CAAA,YAAa,OAAA,GAAU,MAAM,CAAA,GAAI,CAAA;AAAA,EAC7C;AACA,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,WAAA,EAAc,eAAe,CAAA,uCAAA,CAAyC,CAAA;AAAA,EACxF;AACF;AAEA,SAAS,gBAAA,CAAiB,YAA+B,YAAA,EAAgC;AACvF,EAAA,IAAI;AACF,IAAA,OAAO,iBAAA,CAAkB,YAAY,YAAY,CAAA;AAAA,EACnD,SAAS,GAAA,EAAK;AACZ,IAAA,MAAM,MAAA,GACJ,GAAA,YAAeC,KAAA,CAAE,QAAA,GACZ,IAAI,MAAA,CAAO,CAAC,CAAA,EAAG,OAAA,IAAW,mBAC3B,GAAA,YAAe,KAAA,GACb,GAAA,CAAI,OAAA,GACJ,OAAO,GAAG,CAAA;AAClB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iCAAA,EAAoC,MAAM,CAAA,CAAE,CAAA;AAAA,EAC9D;AACF;AAEA,eAAe,YAAA,CACb,UAAA,EACA,GAAA,EACA,WAAA,EACe;AACf,EAAA,MAAM,SAAA,GAAY,WAAW,OAAA,CAAQ,SAAA;AACrC,EAAA,IAAI,cAAc,MAAA,EAAW;AAE7B,EAAA,MAAM,MAAA,GAAS,SAAA,CAAU,GAAA,EAAK,WAAkB,CAAA;AAChD,EAAA,IAAI,MAAA,YAAkB,SAAS,MAAM,MAAA;AACvC;AAEA,SAAS,gBAAgB,OAAA,EAAsC;AAC7D,EAAA,IAAI,OAAO,OAAA,KAAY,QAAA,EAAU,OAAO,OAAA;AACxC,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,OAAO,GAAG,OAAO,MAAA;AACpC,EAAA,MAAM,OAAO,OAAA,CACV,MAAA,CAAO,CAAC,CAAA,KAA4C,GAAyB,IAAA,KAAS,MAAM,CAAA,CAC5F,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAA,CACjB,KAAK,IAAI,CAAA;AACZ,EAAA,OAAO,IAAA,CAAK,MAAA,GAAS,CAAA,GAAI,IAAA,GAAO,MAAA;AAClC;AAEA,SAAS,sBAAA,CAAuB,SAAyB,aAAA,EAA+B;AACtF,EAAA,KAAA,IAAS,CAAA,GAAI,QAAQ,QAAA,CAAS,MAAA,GAAS,GAAG,CAAA,IAAK,CAAA,EAAG,KAAK,CAAA,EAAG;AACxD,IAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,QAAA,CAAS,CAAC,CAAA;AAI5B,IAAA,IAAI,GAAG,IAAA,KAAS,MAAA,IAAU,CAAA,CAAE,OAAA,EAAS,SAAS,MAAA,EAAQ;AACtD,IAAA,MAAM,IAAA,GAAO,eAAA,CAAgB,CAAA,CAAE,OAAA,CAAQ,OAAO,CAAA;AAC9C,IAAA,IAAI,IAAA,KAAS,QAAW,OAAO,IAAA;AAAA,EACjC;AACA,EAAA,OAAO,iBAAiB,aAAa,CAAA,0CAAA,CAAA;AACvC;AAEA,eAAsB,gBAAgB,IAAA,EASgB;AACpD,EAAA,MAAM,EAAE,UAAA,EAAY,aAAA,EAAe,YAAY,YAAA,EAAc,OAAA,EAAS,iBAAgB,GAAI,IAAA;AAC1F,EAAA,MAAM,WAAW,UAAA,CAAW,MAAA;AAE5B,EAAA,IAAI,eAAA,CAAgB,QAAQ,CAAA,EAAG;AAC7B,IAAA,MAAM,IAAIH,oCAAA,CAA6B,QAAA,CAAS,OAAO,CAAA;AAAA,EACzD;AAEA,EAAA,MAAM,iBAAA,GAAoB,WAAW,KAAA,CAAM,MAAA;AAC3C,EAAA,MAAM,GAAA,GAAsB;AAAA,IAC1B,aAAA;AAAA,IACA,iBAAiB,QAAA,CAAS,OAAA;AAAA,IAC1B,YAAA,EAAc,iBAAA;AAAA,IACd,OAAO,CAAC,GAAG,UAAA,CAAW,KAAA,EAAO,SAAS,OAAO;AAAA,GAC/C;AAEA,EAAA,MAAM,oBAAA,CAAqB,UAAA,EAAY,GAAA,EAAK,QAAA,CAAS,OAAO,CAAA;AAC5D,EAAA,MAAM,WAAA,GAAc,gBAAA,CAAiB,UAAA,EAAY,YAAY,CAAA;AAC7D,EAAA,MAAM,YAAA,CAAa,UAAA,EAAY,GAAA,EAAK,WAAW,CAAA;AAG/C,EAAA,MAAM,kBAAkB,MAAM,UAAA,CAAW,UAAA,CAAW,OAAA,CAAQ,aAAa,OAAO,CAAA;AAGhF,EAAA,SAAA,CAAU,UAAA,EAAY,aAAA,EAAe,QAAA,CAAS,OAAO,CAAA;AAErD,EAAA,MAAM,eAAA,GAAkB,eAAA,IAAmB,sBAAA,CAAuB,eAAA,EAAiB,aAAa,CAAA;AAChG,EAAA,MAAM,MAAA,GAAS,cAAc,WAAW,CAAA;AAExC,EAAA,MAAM,OAAO,gBAAA,CAAiB;AAAA,IAC5B,IAAA,EAAM,aAAA;AAAA,IACN,IAAI,QAAA,CAAS,OAAA;AAAA,IACb,MAAA;AAAA,IACA,KAAA,EAAO,iBAAA;AAAA,IACP,UAAU,UAAA,CAAW;AAAA,GACtB,CAAA;AAED,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAM,QAAA,CAAS,IAAA,CAAK,eAAe,CAAA;AAC/C,IAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,IAAA,EAAK;AAC9B,IAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,MAAA,EAAQ,QAAA,CAAS,OAAO,CAAA;AACjD,IAAA,OAAO;AAAA,MACL,KAAA;AAAA,MACA,MAAA,EAAQ;AAAA,QACN,IAAA,EAAM,aAAA;AAAA,QACN,IAAI,QAAA,CAAS,OAAA;AAAA,QACb,KAAA,EAAO,iBAAA;AAAA,QACP,UAAU,UAAA,CAAW,gBAAA;AAAA,QACrB,GAAI,MAAA,KAAW,EAAA,GAAK,EAAE,aAAA,EAAe,MAAA,KAAW;AAAC;AACnD,KACF;AAAA,EACF,CAAA,SAAE;AACA,IAAA,IAAA,CAAK,GAAA,EAAI;AAAA,EACX;AACF;AAEA,SAAS,cAAc,WAAA,EAA8B;AACnD,EAAA,IAAI,OAAO,WAAA,KAAgB,QAAA,IAAY,WAAA,KAAgB,MAAM,OAAO,EAAA;AACpE,EAAA,IAAI,EAAE,QAAA,IAAY,WAAA,CAAA,EAAc,OAAO,EAAA;AACvC,EAAA,OAAO,MAAA,CAAQ,WAAA,CAAoC,MAAA,IAAU,EAAE,CAAA;AACjE;AAEA,SAAS,UAAA,CACP,QACA,eAAA,EACQ;AACR,EAAA,IAAI,OAAO,MAAA,KAAW,UAAA,IAAc,OAAO,MAAA,KAAW,MAAA,SAAkB,MAAA,CAAO,MAAA;AAC/E,EAAA,MAAM,MAAA,GAAS,OAAO,KAAA,KAAU,MAAA,GAAY,KAAK,MAAA,CAAO,KAAA,CAAM,OAAO,CAAA,CAAA,GAAK,EAAA;AAC1E,EAAA,OAAO,mBAAmB,eAAe,CAAA,iBAAA,EAAoB,MAAA,CAAO,MAAM,GAAG,MAAM,CAAA,CAAA,CAAA;AACrF;AArOA,IA+BI,gBAAA;AA/BJ,IAAA,eAAA,GAAA,KAAA,CAAA;AAAA,EAAA,4BAAA,GAAA;AAuBA,IAAA,YAAA,EAAA;AACA,IAAA,aAAA,EAAA;AACA,IAAA,cAAA,EAAA;AAMA,IAAI,gBAAA,GAAmB,KAAA;AAAA,EAAA;AAAA,CAAA,CAAA;ACVhB,SAAS,aACd,MAAA,EACA,OAAA,GAA+B,EAAE,eAAA,EAAiB,OAAM,EAC/B;AAEzB,EAAA,OAAOI,gBAAA,CAAa,QAAe,OAAO,CAAA;AAC5C;AA3BA,IAAA,mBAAA,GAAA,KAAA,CAAA;AAAA,EAAA,gCAAA,GAAA;AAAA,EAAA;AAAA,CAAA,CAAA;;;ACAA,IAAA,qBAAA,GAAA,EAAA;AAAA,QAAA,CAAA,qBAAA,EAAA;AAAA,EAAA,gBAAA,EAAA,MAAA,gBAAA;AAAA,EAAA,iBAAA,EAAA,MAAA;AAAA,CAAA,CAAA;AAgCO,SAAS,iBAAA,CACd,eACA,OAAA,EACqB;AACrB,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG,OAAO,EAAC;AAClC,EAAA,MAAM,MAA2B,EAAC;AAClC,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAY;AAClC,EAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAE3B,IAAA,MAAM,YAAA,GACJ,OAAO,KAAA,KAAU,QAAA,IACjB,KAAA,KAAU,QACV,QAAA,IAAY,KAAA,IACZ,SAAA,IAAa,KAAA,IACb,kBAAA,IAAsB,KAAA;AACxB,IAAA,MAAM,UAAA,GAAa,YAAA,GAAgB,KAAA,GAA8B,QAAA,CAAS,KAAiB,CAAA;AAC3F,IAAA,IAAI,UAAA,CAAW,MAAA,CAAO,OAAA,KAAY,aAAA,EAAe;AAC/C,MAAA,MAAM,IAAIL,kCAA0B,aAAa,CAAA;AAAA,IACnD;AACA,IAAA,MAAM,OAAO,UAAA,CAAW,gBAAA;AACxB,IAAA,IAAI,SAAA,CAAU,GAAA,CAAI,IAAI,CAAA,EAAG;AACvB,MAAA,MAAM,IAAIE,kCAA0B,IAAI,CAAA;AAAA,IAC1C;AACA,IAAA,SAAA,CAAU,IAAI,IAAI,CAAA;AAClB,IAAA,GAAA,CAAI,IAAA,CAAK,EAAE,UAAA,EAAY,CAAA;AAAA,EACzB;AACA,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,SAAS,KAAA,EAAoC;AACpD,EAAA,MAAM,IAAA,GAAO,kBAAkB,KAAK,CAAA;AACpC,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,KAAA;AAAA,IACR,SAAS,EAAC;AAAA,IACV,gBAAA,EAAkB,eAAe,IAAI,CAAA;AAAA,GACvC;AACF;AAEA,SAAS,kBAAkB,KAAA,EAAyB;AAElD,EAAA,MAAM,SAAA,GAAa,KAAA,CAAuC,IAAA,IAAQ,KAAA,CAAM,OAAA,IAAW,WAAA;AACnF,EAAA,OAAO,QAAQ,SAAS,CAAA;AAC1B;AAEA,SAAS,QAAQ,KAAA,EAAuB;AACtC,EAAA,OACE,MACG,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA,CACtB,QAAQ,kBAAA,EAAoB,GAAG,CAAA,CAC/B,OAAA,CAAQ,YAAY,EAAE,CAAA,CACtB,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,IAAK,WAAA;AAEvB;AAYO,SAAS,gBAAA,CACd,aAAA,EACA,UAAA,EACA,eAAA,EACY;AACZ,EAAA,MAAM,cACJ,UAAA,CAAW,OAAA,CAAQ,mBACnB,CAAA,iCAAA,EAAoC,UAAA,CAAW,OAAO,OAAO,CAAA,iEAAA,CAAA;AAG/D,EAAA,MAAM,QAAA,GACJ,UAAA,CAAW,OAAA,CAAQ,SAAA,IACnBE,MAAE,MAAA,CAAO;AAAA,IACP,QAAQA,KAAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,SAAS,qDAAqD;AAAA,GAC7F,CAAA;AAIH,EAAA,MAAM,WAAA,GAAc,aAAa,QAAQ,CAAA;AAEzC,EAAA,OAAO;AAAA,IACL,MAAM,UAAA,CAAW,gBAAA;AAAA,IACjB,WAAA;AAAA,IACA,WAAA;AAAA,IACA,OAAA,EAAS,OAAO,KAAA,KAAoC;AAClD,MAAA,MAAM,UAAA,GAAa,gBAAA,CAAiB,aAAA,EAAe,eAAe,CAAA;AAClE,MAAA,IAAI;AACF,QAAA,MAAM,EAAE,KAAA,EAAO,MAAA,EAAO,GAAI,MAAM,eAAA,CAAgB;AAAA,UAC9C,UAAA;AAAA,UACA,aAAA,EAAe,aAAA;AAAA,UACf,UAAA;AAAA,UACA,YAAA,EAAc,KAAA;AAAA,UACd,OAAA,EAAS,EAAE,QAAA,EAAU,EAAC;AAAE;AAAA,SACzB,CAAA;AACD,QAAA,OAAO,KAAK,SAAA,CAAU;AAAA,UACpB,EAAA,EAAI,IAAA;AAAA,UACJ,gBAAgB,MAAA,CAAO,EAAA;AAAA,UACvB,OAAO,MAAA,CAAO,KAAA;AAAA,UACd;AAAA,SACD,CAAA;AAAA,MACH,SAAS,GAAA,EAAK;AACZ,QAAA,OAAO,KAAK,SAAA,CAAU;AAAA,UACpB,EAAA,EAAI,KAAA;AAAA,UACJ,KAAA,EAAO,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,IAAA,GAAO,cAAA;AAAA,UACzC,SAAS,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG;AAAA,SACzD,CAAA;AAAA,MACH;AAAA,IACF;AAAA,GACF;AACF;AAjJA,IAAA,kBAAA,GAAA,KAAA,CAAA;AAAA,EAAA,+BAAA,GAAA;AAaA,IAAA,YAAA,EAAA;AAKA,IAAA,eAAA,EAAA;AACA,IAAA,aAAA,EAAA;AACA,IAAA,mBAAA,EAAA;AAAA,EAAA;AAAA,CAAA,CAAA;ACcO,IAAM,iCAAA,GAAoC;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAK/C,IAAA;AAEK,IAAM,UAAN,MAAc;AAAA,EACX,WAAA,GAAc;AAAA,EAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUvB,OAAO,MAAA,CACL,MAAA,EACA,OAAA,GAAkC,EAAC,EACR;AAC3B,IAAA,IAAI,MAAA,KAAW,MAAA,IAAa,MAAA,KAAW,IAAA,EAAM;AAC3C,MAAA,MAAM,IAAI,MAAM,0CAA0C,CAAA;AAAA,IAC5D;AACA,IAAA,IAAI,OAAO,MAAA,CAAO,IAAA,KAAS,UAAA,EAAY;AACrC,MAAA,MAAM,IAAI,MAAM,qDAAqD,CAAA;AAAA,IACvE;AACA,IAAA,MAAM,mBAAmB,OAAA,CAAQ,QAAA,IAAY,CAAA,YAAA,EAAe,WAAA,CAAY,MAAM,CAAC,CAAA,CAAA;AAC/E,IAAA,OAAO;AAAA,MACL,MAAA;AAAA,MACA,OAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,OAAO,SAAS,IAAA,EAA+B;AAC7C,IAAA,MAAM,MAAA,GAAS,KAAK,aAAA,IAAiB,WAAA;AACrC,IAAA,MAAM,QAAA,GAAW,KAAK,eAAA,IAAmB,CAAA;AACzC,IAAA,MAAM,UAAU,IAAA,CAAK,OAAA;AACrB,IAAA,OAAOE,gBAAA,CAAa;AAAA,MAClB,IAAA,EAAM,WAAW,MAAM,CAAA,CAAA;AAAA,MACvB,OAAA,EAAS,OAAA;AAAA,MACT,IAAA,EAAM,SAAA;AAAA,MACN,SAAS,GAAA,EAA0B;AACjC,QAAA,IAAI,QAAA,KAAa,CAAA,IAAK,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG;AAI5C,QAAA,KAAA,CAAM,YAAY;AAChB,UAAA,MAAM,EAAE,iBAAA,EAAAC,kBAAAA,EAAmB,gBAAA,EAAAC,iBAAAA,KAAqB,MAAM,OAAA,CAAA,OAAA,EAAA,CAAA,IAAA,CAAA,OAAA,kBAAA,EAAA,EAAA,qBAAA,CAAA,CAAA;AAGtD,UAAA,MAAM,UAAA,GAAaD,kBAAAA,CAAkB,MAAA,EAAQ,OAAO,CAAA;AACpD,UAAA,KAAA,MAAW,EAAE,UAAA,EAAW,IAAK,UAAA,EAAY;AACvC,YAAA,GAAA,CAAI,YAAA,CAAaC,iBAAAA,CAAiB,MAAA,EAAQ,UAAA,EAAY,QAAQ,CAAC,CAAA;AAAA,UACjE;AAAA,QACF,CAAA,GAAG;AAAA,MACL;AAAA,KACD,CAAA;AAAA,EACH;AACF;AAYA,SAAS,YAAY,KAAA,EAAyB;AAC5C,EAAA,MAAM,SAAA,GAAa,KAAA,CAAuC,IAAA,IAAQ,KAAA,CAAM,OAAA,IAAW,WAAA;AACnF,EAAA,OACE,UACG,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA,CACtB,QAAQ,kBAAA,EAAoB,GAAG,CAAA,CAC/B,OAAA,CAAQ,YAAY,EAAE,CAAA,CACtB,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,IAAK,WAAA;AAEvB;AAUA,eAAsB,UACpB,MAAA,EACA,MAAA,EACA,OAAA,EACA,OAAA,GAA0B,EAAC,EACV;AACjB,EAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,MAAA,CAAO,MAAA,EAAQ,OAAO,CAAA;AAEjD,EAAA,MAAM,EAAE,eAAA,EAAAC,gBAAAA,EAAgB,GAAI,MAAM,OAAA,CAAA,OAAA,EAAA,CAAA,IAAA,CAAA,OAAA,eAAA,EAAA,EAAA,kBAAA,CAAA,CAAA;AAClC,EAAA,MAAM,EAAE,gBAAA,EAAAC,iBAAAA,EAAiB,GAAI,MAAM,OAAA,CAAA,OAAA,EAAA,CAAA,IAAA,CAAA,OAAA,aAAA,EAAA,EAAA,gBAAA,CAAA,CAAA;AACnC,EAAA,MAAM,UAAA,GAAaA,iBAAAA,CAAiB,MAAA,CAAO,OAAA,EAAS,CAAC,CAAA;AACrD,EAAA,MAAM,EAAE,KAAA,EAAM,GAAI,MAAMD,gBAAAA,CAAgB;AAAA,IACtC,UAAA;AAAA,IACA,eAAe,MAAA,CAAO,OAAA;AAAA,IACtB,UAAA;AAAA,IACA,YAAA,EAAc,MAAA;AAAA,IACd,OAAA,EAAS,EAAE,QAAA,EAAU,EAAC,EAAE;AAAA,IACxB,eAAA,EAAiB;AAAA,GAClB,CAAA;AACD,EAAA,OAAO,KAAA;AACT;;;AC/IA,YAAA,EAAA","file":"index.cjs","sourcesContent":["/**\n * Public types for `Agent.create({ handoffs })` + `Handoff.create()` +\n * `Agent.handoffTo()` (Adoption Roadmap #4; ADRs D214-D229).\n *\n * Pattern: handoff-as-tool. Each handoff destination becomes a synthetic\n * `transfer_to_<receiver>` function tool exposed to the LLM. Runtime\n * intercepts the tool call and routes the next turn to the receiver.\n *\n * T4.1 follow-up (cycle #4 closed): `HandoffDescriptor` + its leaf-friendly\n * sibling types now live in `./handoff-descriptor.ts` (generic over\n * `TAgent`). This module re-exports the leaf types pinned to `SDKAgent`,\n * keeps the runtime error classes, and removes the back-edge to `agent.ts`.\n *\n * @public\n */\n\nimport type { SDKAgent } from \"@theokit/sdk\";\nimport type { ZodType } from \"zod\";\nimport type {\n HandoffContext,\n HandoffDescriptor as HandoffDescriptorGeneric,\n HandoffHistory,\n HandoffOptions,\n HandoffResult,\n} from \"./handoff-descriptor.js\";\n\nexport type { HandoffContext, HandoffHistory, HandoffOptions, HandoffResult };\n\n/**\n * `HandoffDescriptor` pinned to `SDKAgent` — back-compat shape for callers\n * that imported `import type { HandoffDescriptor } from \"@theokit/sdk\"`\n * before T4.1 follow-up.\n *\n * @public\n */\nexport type HandoffDescriptor<TInput extends ZodType = ZodType> = HandoffDescriptorGeneric<\n TInput,\n SDKAgent\n>;\n\n/** Throw when handoff depth exceeds `maxHandoffDepth` (default 5; D218). */\nexport class HandoffLoopError extends Error {\n override readonly name = \"HandoffLoopError\";\n readonly depth: number;\n readonly chain: ReadonlyArray<string>;\n constructor(depth: number, chain: ReadonlyArray<string>) {\n super(\n `Handoff loop exceeded max depth ${depth}. Chain: ${chain.join(\" -> \")}. ` +\n `Use Agent.create({ maxHandoffDepth: N }) to raise the cap.`,\n );\n this.depth = depth;\n this.chain = chain;\n }\n}\n\n/** Throw when the same (sender, receiver) pair invoked twice in one send() (D221). */\nexport class HandoffPairLoopError extends Error {\n override readonly name = \"HandoffPairLoopError\";\n readonly senderAgentId: string;\n readonly receiverAgentId: string;\n constructor(senderAgentId: string, receiverAgentId: string) {\n super(\n `Handoff loop: ${senderAgentId} -> ${receiverAgentId} already invoked in this send() call. ` +\n `Likely a ping-pong loop; revisit your handoff conditions.`,\n );\n this.senderAgentId = senderAgentId;\n this.receiverAgentId = receiverAgentId;\n }\n}\n\n/** Throw when an agent's `handoffs[]` includes a self-reference (EC-6). */\nexport class HandoffSelfReferenceError extends Error {\n override readonly name = \"HandoffSelfReferenceError\";\n readonly agentId: string;\n constructor(agentId: string) {\n super(\n `Agent \"${agentId}\" has a self-reference in its handoffs[]. ` +\n `Self-handoff causes infinite recursion; introduce a sibling agent for re-entry.`,\n );\n this.agentId = agentId;\n }\n}\n\n/** Throw when receiver is disposed at dispatch time (EC-5). */\nexport class HandoffReceiverDisposedError extends Error {\n override readonly name = \"HandoffReceiverDisposedError\";\n readonly receiverAgentId: string;\n constructor(receiverAgentId: string) {\n super(\n `Handoff target agent \"${receiverAgentId}\" is disposed. ` +\n `Don't dispose receivers while their parent is still active.`,\n );\n this.receiverAgentId = receiverAgentId;\n }\n}\n\n/** Throw when two handoffs in the same parent collide on tool name (D215). */\nexport class HandoffNameCollisionError extends Error {\n override readonly name = \"HandoffNameCollisionError\";\n readonly conflictingName: string;\n constructor(conflictingName: string) {\n super(\n `Two handoffs share the same tool name \"${conflictingName}\". ` +\n `Set { toolName } on at least one of them to disambiguate.`,\n );\n this.conflictingName = conflictingName;\n }\n}\n","/**\n * Handoff registry — pure state container per `Agent` instance.\n *\n * Holds the active dispatch chain (for depth + pair tracking) across the\n * lifetime of a single `agent.send()` call. Cleared between calls.\n *\n * @internal\n */\n\nimport { HandoffLoopError, HandoffPairLoopError } from \"../types/handoff.js\";\n\nexport interface HandoffChainState {\n /** Ordered chain of agentIds traversed so far (oldest first). */\n readonly chain: string[];\n /** Set of \"<sender>-><receiver>\" keys for pair-level loop detection (D221). */\n readonly seenPairs: Set<string>;\n /** Caller-supplied max depth (D218). */\n readonly maxDepth: number;\n}\n\nexport function createChainState(rootAgentId: string, maxDepth: number): HandoffChainState {\n return {\n chain: [rootAgentId],\n seenPairs: new Set(),\n maxDepth,\n };\n}\n\n/**\n * Record a handoff hop. Throws on depth-exceed (D218) or pair-loop (D221).\n * Mutates the state in place.\n */\nexport function recordHop(\n state: HandoffChainState,\n senderAgentId: string,\n receiverAgentId: string,\n): void {\n const pairKey = `${senderAgentId}->${receiverAgentId}`;\n if (state.seenPairs.has(pairKey)) {\n throw new HandoffPairLoopError(senderAgentId, receiverAgentId);\n }\n state.seenPairs.add(pairKey);\n state.chain.push(receiverAgentId);\n // chain.length = nodes; depth = hops = chain.length - 1.\n const depth = state.chain.length - 1;\n if (depth > state.maxDepth) {\n throw new HandoffLoopError(state.maxDepth, [...state.chain]);\n }\n}\n\nexport function currentDepth(state: HandoffChainState): number {\n return state.chain.length - 1;\n}\n","/**\n * D220 — Lazy-loaded OTel `handoff.transfer` span emitter.\n *\n * @internal\n */\n\n// Inline tracer-loader (same workaround as @theokit/sdk-cache/internal/telemetry.ts):\n// rollup-plugin-dts emits incomplete index.d.ts for newly-modified internal/ barrels\n// in @theokit/sdk. Runtime via the sub-path works; TypeScript users hit TS2305.\n// Inlining keeps sdk-handoff self-contained for the (small) observability hook.\nimport { createRequire } from \"node:module\";\n\ninterface SpanLike {\n setAttribute(key: string, value: string | number | boolean): SpanLike;\n end(): void;\n}\n\nconst _NOOP_SPAN: SpanLike = {\n setAttribute: () => _NOOP_SPAN,\n end: () => undefined,\n};\n\ninterface TracerLike {\n startSpan(\n name: string,\n options?: { attributes?: Record<string, string | number | boolean> },\n ): SpanLike;\n}\n\ninterface TracerCacheEntry {\n tracer: TracerLike | null;\n}\nconst tracerCache = new Map<string, TracerCacheEntry>();\n\nfunction getTracer(name: string, version = \"1.0.0\"): TracerLike | undefined {\n const cached = tracerCache.get(name);\n if (cached !== undefined) return cached.tracer ?? undefined;\n try {\n const r = createRequire(import.meta.url);\n const otel = r(\"@opentelemetry/api\") as {\n trace?: { getTracer: (n: string, v?: string) => TracerLike };\n };\n if (otel.trace?.getTracer === undefined) {\n tracerCache.set(name, { tracer: null });\n return undefined;\n }\n const tracer = otel.trace.getTracer(name, version);\n tracerCache.set(name, { tracer });\n return tracer;\n } catch {\n tracerCache.set(name, { tracer: null });\n return undefined;\n }\n}\n\nfunction resetTracerCacheForTests(): void {\n tracerCache.clear();\n}\n\nconst TRACER_NAME = \"theokit-sdk-handoff\";\n\ninterface HandoffSpanHandle {\n setAttribute(key: string, value: string | number | boolean): void;\n end(): void;\n}\n\nconst NOOP: HandoffSpanHandle = { setAttribute: () => undefined, end: () => undefined };\n\nfunction safe<T>(fn: () => T, fallback: T): T {\n try {\n return fn();\n } catch {\n return fallback;\n }\n}\n\nexport function startHandoffSpan(attrs: {\n from: string;\n to: string;\n reason: string;\n depth: number;\n toolName: string;\n}): HandoffSpanHandle {\n const tracer = getTracer(TRACER_NAME);\n if (tracer === undefined) return NOOP;\n const span: SpanLike | undefined = safe(\n () =>\n tracer.startSpan(\"handoff.transfer\", {\n attributes: {\n \"handoff.from\": attrs.from,\n \"handoff.to\": attrs.to,\n \"handoff.reason\": attrs.reason,\n \"handoff.depth\": attrs.depth,\n \"handoff.tool_name\": attrs.toolName,\n },\n }),\n undefined,\n );\n if (span === undefined) return NOOP;\n return {\n setAttribute: (k, v) => safe(() => span.setAttribute(k, v), undefined),\n end: () => safe(() => span.end(), undefined),\n };\n}\n\n/** Test-only — reset cached OTel handle. */\nfunction __resetHandoffOtelCacheForTests(): void {\n resetTracerCacheForTests();\n}\n","/**\n * Handoff dispatch orchestration.\n *\n * Pragmatic v1: when a handoff fires, the sender calls `receiver.send()`\n * with the (optionally filtered) history. The receiver's reply is returned\n * to the sender, which captures it as the answer to the user's question.\n *\n * NOTE: this is NOT pure peer-to-peer (the sender stays on the call stack\n * until the receiver returns). Pure intercept-and-swap requires deeper\n * agent-loop refactor; deferred to v2. v1 still validates the user-facing\n * value: \"agent A reasoned about routing, agent B answered.\"\n *\n * @internal\n */\n\nimport type { SDKAgent } from \"@theokit/sdk\";\nimport { z } from \"zod\";\nimport type {\n HandoffContext,\n HandoffDescriptor,\n HandoffHistory,\n HandoffResult,\n} from \"../types/handoff.js\";\nimport { HandoffReceiverDisposedError } from \"../types/handoff.js\";\nimport { type HandoffChainState, recordHop } from \"./registry.js\";\nimport { startHandoffSpan } from \"./telemetry.js\";\n\n/**\n * EC-2 / D228 — `safeFilter` wraps `inputFilter`. On exception, falls back\n * to the un-filtered history and warns to stderr once per process.\n */\nlet warnedFilterOnce = false;\nasync function safeFilter(\n filter: ((h: HandoffHistory) => HandoffHistory | Promise<HandoffHistory>) | undefined,\n history: HandoffHistory,\n): Promise<HandoffHistory> {\n if (filter === undefined) return history;\n try {\n const result = filter(history);\n return result instanceof Promise ? await result : result;\n } catch (err) {\n if (!warnedFilterOnce) {\n warnedFilterOnce = true;\n process.stderr.write(\n `[handoff] inputFilter threw, falling back to full history: ${err instanceof Error ? err.message : String(err)}\\n`,\n );\n }\n return history;\n }\n}\n\n/**\n * EC-4 / D229 — parse the LLM-provided JSON args. Returns undefined when\n * no `inputType` set; returns parsed value otherwise (default to `{}` on\n * empty/null input before Zod refinements).\n */\nfunction parseHandoffInput(descriptor: HandoffDescriptor, raw: unknown): unknown {\n const inputType = descriptor.options.inputType;\n if (inputType === undefined) return undefined;\n const candidate = raw === null || raw === undefined ? {} : raw;\n return inputType.parse(candidate);\n}\n\nfunction isAgentDisposed(agent: SDKAgent): boolean {\n // SDKAgent doesn't expose `disposed` publicly; check via duck-typing on\n // a known internal flag. Safe fallback: if we can't tell, assume alive.\n const maybe = agent as unknown as { disposed?: boolean };\n return maybe.disposed === true;\n}\n\n/**\n * Run a single handoff hop. Returns the receiver's reply text.\n *\n * Algorithm:\n * 1. EC-5: refuse if receiver disposed.\n * 2. Build HandoffContext.\n * 3. Check isEnabled() — if false, refuse with a clear error message.\n * 4. Parse inputType (D229).\n * 5. Run onHandoff(ctx, parsed) — throw aborts (D227).\n * 6. Apply inputFilter (safeFilter — D228).\n * 7. Record hop in chain state (depth + pair guards).\n * 8. Open OTel span (D220).\n * 9. Receiver: build the user-facing message and `await receiver.send(msg).then(wait)`.\n * 10. Close span + return reply.\n */\nasync function assertHandoffEnabled(\n descriptor: HandoffDescriptor,\n ctx: HandoffContext,\n receiverAgentId: string,\n): Promise<void> {\n const opt = descriptor.options.isEnabled;\n let enabled = true;\n if (typeof opt === \"boolean\") enabled = opt;\n else if (typeof opt === \"function\") {\n const r = opt(ctx);\n enabled = r instanceof Promise ? await r : r;\n }\n if (!enabled) {\n throw new Error(`Handoff to ${receiverAgentId} is disabled (isEnabled returned false)`);\n }\n}\n\nfunction parseAndValidate(descriptor: HandoffDescriptor, rawInputJson: unknown): unknown {\n try {\n return parseHandoffInput(descriptor, rawInputJson);\n } catch (err) {\n const detail =\n err instanceof z.ZodError\n ? (err.issues[0]?.message ?? \"schema_invalid\")\n : err instanceof Error\n ? err.message\n : String(err);\n throw new Error(`Handoff input validation failed: ${detail}`);\n }\n}\n\nasync function runOnHandoff(\n descriptor: HandoffDescriptor,\n ctx: HandoffContext,\n parsedInput: unknown,\n): Promise<void> {\n const onHandoff = descriptor.options.onHandoff;\n if (onHandoff === undefined) return;\n // biome-ignore lint/suspicious/noExplicitAny: parsedInput is typed unknown by design.\n const result = onHandoff(ctx, parsedInput as any);\n if (result instanceof Promise) await result;\n}\n\nfunction extractUserText(content: unknown): string | undefined {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return undefined;\n const text = content\n .filter((c): c is { type: \"text\"; text: string } => (c as { type?: string })?.type === \"text\")\n .map((c) => c.text)\n .join(\"\\n\");\n return text.length > 0 ? text : undefined;\n}\n\nfunction extractLastUserMessage(history: HandoffHistory, senderAgentId: string): string {\n for (let i = history.messages.length - 1; i >= 0; i -= 1) {\n const m = history.messages[i] as {\n type?: string;\n message?: { role?: string; content?: unknown };\n };\n if (m?.type !== \"user\" || m.message?.role !== \"user\") continue;\n const text = extractUserText(m.message.content);\n if (text !== undefined) return text;\n }\n return `(Handoff from ${senderAgentId} — no prior user message in history.)`;\n}\n\nexport async function dispatchHandoff(args: {\n descriptor: HandoffDescriptor;\n senderAgentId: string;\n chainState: HandoffChainState;\n rawInputJson: unknown;\n /** The conversation so far (history wrapper). v1: just the LAST user message. */\n history: HandoffHistory;\n /** Override the message text sent to the receiver. Used by `Agent.handoffTo` imperative. */\n messageOverride?: string;\n}): Promise<{ reply: string; result: HandoffResult }> {\n const { descriptor, senderAgentId, chainState, rawInputJson, history, messageOverride } = args;\n const receiver = descriptor.target;\n\n if (isAgentDisposed(receiver)) {\n throw new HandoffReceiverDisposedError(receiver.agentId);\n }\n\n const depthAfterThisHop = chainState.chain.length;\n const ctx: HandoffContext = {\n senderAgentId,\n receiverAgentId: receiver.agentId,\n currentDepth: depthAfterThisHop,\n chain: [...chainState.chain, receiver.agentId],\n };\n\n await assertHandoffEnabled(descriptor, ctx, receiver.agentId);\n const parsedInput = parseAndValidate(descriptor, rawInputJson);\n await runOnHandoff(descriptor, ctx, parsedInput);\n\n // Filter history (D228 — resilient)\n const filteredHistory = await safeFilter(descriptor.options.inputFilter, history);\n\n // Record hop — may throw HandoffLoopError or HandoffPairLoopError\n recordHop(chainState, senderAgentId, receiver.agentId);\n\n const lastUserMessage = messageOverride ?? extractLastUserMessage(filteredHistory, senderAgentId);\n const reason = extractReason(parsedInput);\n\n const span = startHandoffSpan({\n from: senderAgentId,\n to: receiver.agentId,\n reason,\n depth: depthAfterThisHop,\n toolName: descriptor.resolvedToolName,\n });\n\n try {\n const run = await receiver.send(lastUserMessage);\n const result = await run.wait();\n const reply = buildReply(result, receiver.agentId);\n return {\n reply,\n result: {\n from: senderAgentId,\n to: receiver.agentId,\n depth: depthAfterThisHop,\n toolName: descriptor.resolvedToolName,\n ...(reason !== \"\" ? { reasonFromLlm: reason } : {}),\n },\n };\n } finally {\n span.end();\n }\n}\n\nfunction extractReason(parsedInput: unknown): string {\n if (typeof parsedInput !== \"object\" || parsedInput === null) return \"\";\n if (!(\"reason\" in parsedInput)) return \"\";\n return String((parsedInput as { reason: unknown }).reason ?? \"\");\n}\n\nfunction buildReply(\n result: { status: string; result?: string; error?: { message: string } },\n receiverAgentId: string,\n): string {\n if (result.status === \"finished\" && result.result !== undefined) return result.result;\n const suffix = result.error !== undefined ? `: ${result.error.message}` : \"\";\n return `(Handoff target ${receiverAgentId} returned status=${result.status}${suffix})`;\n}\n","/**\n * Zod v4 → JSON Schema adapter for sdk-handoff.\n *\n * Uses Zod v4's native `z.toJSONSchema()` directly. v3 fallback removed\n * after zod-v4-migration plan (ADR D2).\n *\n * @internal\n */\n\nimport { toJSONSchema } from \"zod\";\n\ninterface ToJsonSchemaOptions {\n /** `\"any\"` keeps transforms/refinements as `{}` (loose). Default: `\"any\"`. */\n unrepresentable?: \"any\" | \"throw\";\n}\n\n/**\n * Convert a Zod schema to a JSON Schema object via Zod v4 native.\n *\n * @internal\n */\nexport function toJsonSchema(\n schema: unknown,\n options: ToJsonSchemaOptions = { unrepresentable: \"any\" },\n): Record<string, unknown> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- generic ZodType erasure\n return toJSONSchema(schema as any, options) as Record<string, unknown>;\n}\n","/**\n * Convert `handoffs[]` entries into synthetic `transfer_to_<receiver>` tools\n * for injection into the agent's tool registry at construction time.\n *\n * The synthesized tool's handler calls `dispatchHandoff` internally and\n * returns the receiver's reply as `tool_result`. v1 trade-off documented\n * in dispatcher.ts.\n *\n * @internal\n */\n\nimport type { CustomTool, SDKAgent } from \"@theokit/sdk\";\nimport { z } from \"zod\";\nimport {\n type HandoffDescriptor,\n HandoffNameCollisionError,\n HandoffSelfReferenceError,\n} from \"../types/handoff.js\";\nimport { dispatchHandoff } from \"./dispatcher.js\";\nimport { createChainState } from \"./registry.js\";\nimport { toJsonSchema } from \"./to-json-schema.js\";\n\ninterface NormalizedHandoff {\n descriptor: HandoffDescriptor;\n}\n\n/**\n * Normalize each `handoffs[]` entry to a `HandoffDescriptor`. Raw `SDKAgent`\n * instances are auto-wrapped with default options. Validates:\n * - EC-6: no self-reference (would cause infinite recursion).\n * - D215: resolved tool names must be unique.\n */\nexport function normalizeHandoffs(\n parentAgentId: string,\n entries: ReadonlyArray<SDKAgent | HandoffDescriptor>,\n): NormalizedHandoff[] {\n if (entries.length === 0) return [];\n const out: NormalizedHandoff[] = [];\n const seenNames = new Set<string>();\n for (const entry of entries) {\n // Detect raw Agent vs HandoffDescriptor by presence of `.target`.\n const isDescriptor =\n typeof entry === \"object\" &&\n entry !== null &&\n \"target\" in entry &&\n \"options\" in entry &&\n \"resolvedToolName\" in entry;\n const descriptor = isDescriptor ? (entry as HandoffDescriptor) : autoWrap(entry as SDKAgent);\n if (descriptor.target.agentId === parentAgentId) {\n throw new HandoffSelfReferenceError(parentAgentId);\n }\n const name = descriptor.resolvedToolName;\n if (seenNames.has(name)) {\n throw new HandoffNameCollisionError(name);\n }\n seenNames.add(name);\n out.push({ descriptor });\n }\n return out;\n}\n\nfunction autoWrap(agent: SDKAgent): HandoffDescriptor {\n const name = resolveTargetName(agent);\n return {\n target: agent,\n options: {},\n resolvedToolName: `transfer_to_${name}`,\n };\n}\n\nfunction resolveTargetName(agent: SDKAgent): string {\n // Prefer a `name` field if exposed; fall back to a short agentId slug.\n const candidate = (agent as unknown as { name?: string }).name ?? agent.agentId ?? \"anonymous\";\n return slugify(candidate);\n}\n\nfunction slugify(input: string): string {\n return (\n input\n .replace(/^agent-/i, \"\")\n .replace(/[^a-zA-Z0-9_-]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 64) || \"anonymous\"\n );\n}\n\n/**\n * Build a `CustomTool` for one handoff descriptor. The handler dispatches\n * the handoff using a fresh chain state per `send()`-level invocation.\n *\n * NOTE: this v1 builds a NEW chain state per tool invocation. Pure\n * cross-tool depth tracking within one send() requires per-Agent context\n * — deferred. The single-flight pair guard catches direct ping-pong even\n * without cross-invocation chain (since each call wraps the same depth\n * counter from 1).\n */\nexport function buildHandoffTool(\n parentAgentId: string,\n descriptor: HandoffDescriptor,\n maxHandoffDepth: number,\n): CustomTool {\n const description =\n descriptor.options.toolDescription ??\n `Transfer the conversation to the ${descriptor.target.agentId} agent. ` +\n `Use this when the user's request matches their specialty.`;\n\n const inputZod =\n descriptor.options.inputType ??\n z.object({\n reason: z.string().optional().describe(\"Brief reason for the transfer (one short sentence).\"),\n });\n // CustomTool.inputSchema expects a JSON schema (Record<string, unknown>),\n // not the raw Zod type. Convert lazily so we don't fail when Zod is missing.\n // Universal Zod 3+4 conversion (feature-detects native v4, falls back to lib on v3).\n const inputSchema = toJsonSchema(inputZod);\n\n return {\n name: descriptor.resolvedToolName,\n description,\n inputSchema,\n handler: async (input: unknown): Promise<string> => {\n const chainState = createChainState(parentAgentId, maxHandoffDepth);\n try {\n const { reply, result } = await dispatchHandoff({\n descriptor,\n senderAgentId: parentAgentId,\n chainState,\n rawInputJson: input,\n history: { messages: [] }, // v1: history replay deferred\n });\n return JSON.stringify({\n ok: true,\n transferred_to: result.to,\n depth: result.depth,\n reply,\n });\n } catch (err) {\n return JSON.stringify({\n ok: false,\n error: err instanceof Error ? err.name : \"HandoffError\",\n message: err instanceof Error ? err.message : String(err),\n });\n }\n },\n };\n}\n","/**\n * Public `Handoff` class — factory for handoff descriptors (Adoption\n * Roadmap #4; ADRs D214-D229).\n *\n * Usage:\n *\n * import { Agent, Handoff } from \"@theokit/sdk\";\n *\n * const billing = await Agent.create({\n * name: \"billing\",\n * systemPrompt: \"You handle billing questions.\",\n * model: { id: \"openai/gpt-4o-mini\" },\n * apiKey: process.env.OPENROUTER_API_KEY,\n * });\n *\n * const triage = await Agent.create({\n * name: \"triage\",\n * systemPrompt: \"Classify the user's intent and transfer to the right specialist.\",\n * model: { id: \"openai/gpt-4o-mini\" },\n * apiKey: process.env.OPENROUTER_API_KEY,\n * handoffs: [\n * billing, // auto-wrapped as Handoff.create(billing)\n * Handoff.create(supportAgent, { inputFilter: redactCreditCards }),\n * ],\n * });\n *\n * @public\n */\n\nimport { definePlugin, type Plugin, type PluginContext, type SDKAgent } from \"@theokit/sdk\";\nimport type { ZodType } from \"zod\";\nimport type { HandoffDescriptor, HandoffOptions } from \"./types/handoff.js\";\n\n/** Recommended system-prompt prefix for senders (D215 / EC-13). */\nexport const RECOMMENDED_HANDOFF_PROMPT_PREFIX = `\nYou can transfer the conversation to other specialist agents when their\nexpertise matches the user's request. Invoke the appropriate\ntransfer_to_<agent> tool with a short reason. The receiving agent will\ntake over the conversation; do not duplicate their work.\n`.trim();\n\nexport class Handoff {\n private constructor() {}\n\n /**\n * Build a `HandoffDescriptor` for a target agent. Wrap with custom options\n * (filter / inputType / callback / whitelist / etc); pass to\n * `Agent.create({ handoffs: [...] })`.\n *\n * Raw `SDKAgent` instances in `handoffs[]` are auto-wrapped by the runtime\n * — call `Handoff.create()` explicitly only when you need to customize.\n */\n static create<TInput extends ZodType = ZodType>(\n target: SDKAgent,\n options: HandoffOptions<TInput> = {} as HandoffOptions<TInput>,\n ): HandoffDescriptor<TInput> {\n if (target === undefined || target === null) {\n throw new Error(\"Handoff.create: target agent is required\");\n }\n if (typeof target.send !== \"function\") {\n throw new Error(\"Handoff.create: target must be an SDKAgent instance\");\n }\n const resolvedToolName = options.toolName ?? `transfer_to_${slugifyName(target)}`;\n return {\n target,\n options,\n resolvedToolName,\n };\n }\n\n /**\n * Plugin-based wiring (SDK 2.x preferred). Wraps `targets` in synthetic\n * `transfer_to_<receiver>` tools and registers them via `ctx.registerTool`\n * at agent init time.\n *\n * Replaces the legacy `Agent.create({ handoffs: [...] })` option (which is\n * still supported as a transitional convenience while sdk-handoff is\n * installed — the framework lazy-imports the tool-injector at runtime).\n *\n * @example\n * const support = await Agent.create({\n * name: \"support\",\n * plugins: [Handoff.asPlugin({ parentAgentId: \"support\", targets: [billing] })],\n * });\n */\n static asPlugin(opts: AsPluginOptions): Plugin {\n const parent = opts.parentAgentId ?? \"anonymous\";\n const maxDepth = opts.maxHandoffDepth ?? 5;\n const targets = opts.targets;\n return definePlugin({\n name: `handoff-${parent}`,\n version: \"1.0.0\",\n kind: \"general\" as const,\n register(ctx: PluginContext): void {\n if (maxDepth === 0 || targets.length === 0) return;\n // Lazy import — keeps cold path lean if asPlugin is constructed but\n // its register hook is never invoked (e.g., disabled by config).\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n void (async () => {\n const { normalizeHandoffs, buildHandoffTool } = await import(\n \"./internal/tool-injector.js\"\n );\n const normalized = normalizeHandoffs(parent, targets);\n for (const { descriptor } of normalized) {\n ctx.registerTool(buildHandoffTool(parent, descriptor, maxDepth));\n }\n })();\n },\n });\n }\n}\n\n/**\n * Options for `Handoff.asPlugin()`. `parentAgentId` defaults to `\"anonymous\"`;\n * pass the host agent's `name` for correct loop detection in chains.\n */\nexport interface AsPluginOptions {\n readonly targets: ReadonlyArray<SDKAgent | HandoffDescriptor>;\n readonly parentAgentId?: string;\n readonly maxHandoffDepth?: number;\n}\n\nfunction slugifyName(agent: SDKAgent): string {\n const candidate = (agent as unknown as { name?: string }).name ?? agent.agentId ?? \"anonymous\";\n return (\n candidate\n .replace(/^agent-/i, \"\")\n .replace(/[^a-zA-Z0-9_-]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 64) || \"anonymous\"\n );\n}\n\n/**\n * Imperative escape hatch (D225). Useful for tests / programmatic flows\n * that need deterministic handoff without LLM routing.\n *\n * NOTE: this is a STANDALONE helper rather than a method on `SDKAgent`\n * to avoid invasive refactor of the agent class. Behavior is identical\n * to invoking the corresponding synthetic tool would be.\n */\nexport async function handoffTo(\n sender: SDKAgent,\n target: SDKAgent,\n message: string,\n options: HandoffOptions = {},\n): Promise<string> {\n const descriptor = Handoff.create(target, options);\n // Lazy import to avoid loading internal module unless this is called.\n const { dispatchHandoff } = await import(\"./internal/dispatcher.js\");\n const { createChainState } = await import(\"./internal/registry.js\");\n const chainState = createChainState(sender.agentId, 5);\n const { reply } = await dispatchHandoff({\n descriptor,\n senderAgentId: sender.agentId,\n chainState,\n rawInputJson: undefined,\n history: { messages: [] },\n messageOverride: message,\n });\n return reply;\n}\n","/**\n * `@theokit/sdk-handoff` — inter-agent dispatch for `@theokit/sdk`.\n *\n * Extracted from `@theokit/sdk@1.7.0` as part of the SDK 2.0 package split\n * (Phase 4 / T4.1). Integrates with `Agent` via the Plugin protocol —\n * `Handoff.asPlugin({ targets })` returns a `Plugin` consumed by\n * `Agent.create({ plugins: [...] })`.\n *\n * @packageDocumentation\n */\n\nexport {\n type AsPluginOptions,\n Handoff,\n handoffTo,\n RECOMMENDED_HANDOFF_PROMPT_PREFIX,\n} from \"./handoff.js\";\nexport type { HandoffDescriptor, HandoffOptions } from \"./types/handoff.js\";\nexport {\n HandoffLoopError,\n HandoffNameCollisionError,\n HandoffPairLoopError,\n HandoffReceiverDisposedError,\n HandoffSelfReferenceError,\n} from \"./types/handoff.js\";\n"]}
1
+ {"version":3,"sources":["../src/types/handoff.ts","../src/internal/registry.ts","../src/internal/telemetry.ts","../src/internal/dispatcher.ts","../src/internal/to-json-schema.ts","../src/internal/tool-injector.ts","../src/handoff.ts","../src/index.ts"],"names":["HandoffLoopError","HandoffPairLoopError","HandoffSelfReferenceError","HandoffReceiverDisposedError","HandoffNameCollisionError","createRequire","z","toJSONSchema","Plugin","normalizeHandoffs","buildHandoffTool","dispatchHandoff","createChainState"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Public types for `Agent.create({ handoffs })` + `Handoff.create()` +\n * `Agent.handoffTo()` (Adoption Roadmap #4; ADRs D214-D229).\n *\n * Pattern: handoff-as-tool. Each handoff destination becomes a synthetic\n * `transfer_to_<receiver>` function tool exposed to the LLM. Runtime\n * intercepts the tool call and routes the next turn to the receiver.\n *\n * T4.1 follow-up (cycle #4 closed): `HandoffDescriptor` + its leaf-friendly\n * sibling types now live in `./handoff-descriptor.ts` (generic over\n * `TAgent`). This module re-exports the leaf types pinned to `SDKAgent`,\n * keeps the runtime error classes, and removes the back-edge to `agent.ts`.\n *\n * @public\n */\n\nimport type { SDKAgent } from \"@theokit/sdk\";\nimport type { ZodType } from \"zod\";\nimport type {\n HandoffContext,\n HandoffDescriptor as HandoffDescriptorGeneric,\n HandoffHistory,\n HandoffOptions,\n HandoffResult,\n} from \"./handoff-descriptor.js\";\n\nexport type { HandoffContext, HandoffHistory, HandoffOptions, HandoffResult };\n\n/**\n * `HandoffDescriptor` pinned to `SDKAgent` — back-compat shape for callers\n * that imported `import type { HandoffDescriptor } from \"@theokit/sdk\"`\n * before T4.1 follow-up.\n *\n * @public\n */\nexport type HandoffDescriptor<TInput extends ZodType = ZodType> = HandoffDescriptorGeneric<\n TInput,\n SDKAgent\n>;\n\n/** Throw when handoff depth exceeds `maxHandoffDepth` (default 5; D218). */\nexport class HandoffLoopError extends Error {\n override readonly name = \"HandoffLoopError\";\n readonly depth: number;\n readonly chain: ReadonlyArray<string>;\n constructor(depth: number, chain: ReadonlyArray<string>) {\n super(\n `Handoff loop exceeded max depth ${depth}. Chain: ${chain.join(\" -> \")}. ` +\n `Use Agent.create({ maxHandoffDepth: N }) to raise the cap.`,\n );\n this.depth = depth;\n this.chain = chain;\n }\n}\n\n/** Throw when the same (sender, receiver) pair invoked twice in one send() (D221). */\nexport class HandoffPairLoopError extends Error {\n override readonly name = \"HandoffPairLoopError\";\n readonly senderAgentId: string;\n readonly receiverAgentId: string;\n constructor(senderAgentId: string, receiverAgentId: string) {\n super(\n `Handoff loop: ${senderAgentId} -> ${receiverAgentId} already invoked in this send() call. ` +\n `Likely a ping-pong loop; revisit your handoff conditions.`,\n );\n this.senderAgentId = senderAgentId;\n this.receiverAgentId = receiverAgentId;\n }\n}\n\n/** Throw when an agent's `handoffs[]` includes a self-reference (EC-6). */\nexport class HandoffSelfReferenceError extends Error {\n override readonly name = \"HandoffSelfReferenceError\";\n readonly agentId: string;\n constructor(agentId: string) {\n super(\n `Agent \"${agentId}\" has a self-reference in its handoffs[]. ` +\n `Self-handoff causes infinite recursion; introduce a sibling agent for re-entry.`,\n );\n this.agentId = agentId;\n }\n}\n\n/** Throw when receiver is disposed at dispatch time (EC-5). */\nexport class HandoffReceiverDisposedError extends Error {\n override readonly name = \"HandoffReceiverDisposedError\";\n readonly receiverAgentId: string;\n constructor(receiverAgentId: string) {\n super(\n `Handoff target agent \"${receiverAgentId}\" is disposed. ` +\n `Don't dispose receivers while their parent is still active.`,\n );\n this.receiverAgentId = receiverAgentId;\n }\n}\n\n/** Throw when two handoffs in the same parent collide on tool name (D215). */\nexport class HandoffNameCollisionError extends Error {\n override readonly name = \"HandoffNameCollisionError\";\n readonly conflictingName: string;\n constructor(conflictingName: string) {\n super(\n `Two handoffs share the same tool name \"${conflictingName}\". ` +\n `Set { toolName } on at least one of them to disambiguate.`,\n );\n this.conflictingName = conflictingName;\n }\n}\n","/**\n * Handoff registry — pure state container per `Agent` instance.\n *\n * Holds the active dispatch chain (for depth + pair tracking) across the\n * lifetime of a single `agent.send()` call. Cleared between calls.\n *\n * @internal\n */\n\nimport { HandoffLoopError, HandoffPairLoopError } from \"../types/handoff.js\";\n\nexport interface HandoffChainState {\n /** Ordered chain of agentIds traversed so far (oldest first). */\n readonly chain: string[];\n /** Set of \"<sender>-><receiver>\" keys for pair-level loop detection (D221). */\n readonly seenPairs: Set<string>;\n /** Caller-supplied max depth (D218). */\n readonly maxDepth: number;\n}\n\nexport function createChainState(rootAgentId: string, maxDepth: number): HandoffChainState {\n return {\n chain: [rootAgentId],\n seenPairs: new Set(),\n maxDepth,\n };\n}\n\n/**\n * Record a handoff hop. Throws on depth-exceed (D218) or pair-loop (D221).\n * Mutates the state in place.\n */\nexport function recordHop(\n state: HandoffChainState,\n senderAgentId: string,\n receiverAgentId: string,\n): void {\n const pairKey = `${senderAgentId}->${receiverAgentId}`;\n if (state.seenPairs.has(pairKey)) {\n throw new HandoffPairLoopError(senderAgentId, receiverAgentId);\n }\n state.seenPairs.add(pairKey);\n state.chain.push(receiverAgentId);\n // chain.length = nodes; depth = hops = chain.length - 1.\n const depth = state.chain.length - 1;\n if (depth > state.maxDepth) {\n throw new HandoffLoopError(state.maxDepth, [...state.chain]);\n }\n}\n\nexport function currentDepth(state: HandoffChainState): number {\n return state.chain.length - 1;\n}\n","/**\n * D220 — Lazy-loaded OTel `handoff.transfer` span emitter.\n *\n * @internal\n */\n\n// Inline tracer-loader (same workaround as @theokit/sdk-cache/internal/telemetry.ts):\n// rollup-plugin-dts emits incomplete index.d.ts for newly-modified internal/ barrels\n// in @theokit/sdk. Runtime via the sub-path works; TypeScript users hit TS2305.\n// Inlining keeps sdk-handoff self-contained for the (small) observability hook.\nimport { createRequire } from \"node:module\";\n\ninterface SpanLike {\n setAttribute(key: string, value: string | number | boolean): SpanLike;\n end(): void;\n}\n\nconst _NOOP_SPAN: SpanLike = {\n setAttribute: () => _NOOP_SPAN,\n end: () => undefined,\n};\n\ninterface TracerLike {\n startSpan(\n name: string,\n options?: { attributes?: Record<string, string | number | boolean> },\n ): SpanLike;\n}\n\ninterface TracerCacheEntry {\n tracer: TracerLike | null;\n}\nconst tracerCache = new Map<string, TracerCacheEntry>();\n\nfunction getTracer(name: string, version = \"1.0.0\"): TracerLike | undefined {\n const cached = tracerCache.get(name);\n if (cached !== undefined) return cached.tracer ?? undefined;\n try {\n const r = createRequire(import.meta.url);\n const otel = r(\"@opentelemetry/api\") as {\n trace?: { getTracer: (n: string, v?: string) => TracerLike };\n };\n if (otel.trace?.getTracer === undefined) {\n tracerCache.set(name, { tracer: null });\n return undefined;\n }\n const tracer = otel.trace.getTracer(name, version);\n tracerCache.set(name, { tracer });\n return tracer;\n } catch {\n tracerCache.set(name, { tracer: null });\n return undefined;\n }\n}\n\nfunction resetTracerCacheForTests(): void {\n tracerCache.clear();\n}\n\nconst TRACER_NAME = \"theokit-sdk-handoff\";\n\ninterface HandoffSpanHandle {\n setAttribute(key: string, value: string | number | boolean): void;\n end(): void;\n}\n\nconst NOOP: HandoffSpanHandle = { setAttribute: () => undefined, end: () => undefined };\n\nfunction safe<T>(fn: () => T, fallback: T): T {\n try {\n return fn();\n } catch {\n return fallback;\n }\n}\n\nexport function startHandoffSpan(attrs: {\n from: string;\n to: string;\n reason: string;\n depth: number;\n toolName: string;\n}): HandoffSpanHandle {\n const tracer = getTracer(TRACER_NAME);\n if (tracer === undefined) return NOOP;\n const span: SpanLike | undefined = safe(\n () =>\n tracer.startSpan(\"handoff.transfer\", {\n attributes: {\n \"handoff.from\": attrs.from,\n \"handoff.to\": attrs.to,\n \"handoff.reason\": attrs.reason,\n \"handoff.depth\": attrs.depth,\n \"handoff.tool_name\": attrs.toolName,\n },\n }),\n undefined,\n );\n if (span === undefined) return NOOP;\n return {\n setAttribute: (k, v) => safe(() => span.setAttribute(k, v), undefined),\n end: () => safe(() => span.end(), undefined),\n };\n}\n\n/** Test-only — reset cached OTel handle. */\nfunction __resetHandoffOtelCacheForTests(): void {\n resetTracerCacheForTests();\n}\n","/**\n * Handoff dispatch orchestration.\n *\n * Pragmatic v1: when a handoff fires, the sender calls `receiver.send()`\n * with the (optionally filtered) history. The receiver's reply is returned\n * to the sender, which captures it as the answer to the user's question.\n *\n * NOTE: this is NOT pure peer-to-peer (the sender stays on the call stack\n * until the receiver returns). Pure intercept-and-swap requires deeper\n * agent-loop refactor; deferred to v2. v1 still validates the user-facing\n * value: \"agent A reasoned about routing, agent B answered.\"\n *\n * @internal\n */\n\nimport type { SDKAgent } from \"@theokit/sdk\";\nimport { z } from \"zod\";\nimport type {\n HandoffContext,\n HandoffDescriptor,\n HandoffHistory,\n HandoffResult,\n} from \"../types/handoff.js\";\nimport { HandoffReceiverDisposedError } from \"../types/handoff.js\";\nimport { type HandoffChainState, recordHop } from \"./registry.js\";\nimport { startHandoffSpan } from \"./telemetry.js\";\n\n/**\n * EC-2 / D228 — `safeFilter` wraps `inputFilter`. On exception, falls back\n * to the un-filtered history and warns to stderr once per process.\n */\nlet warnedFilterOnce = false;\nasync function safeFilter(\n filter: ((h: HandoffHistory) => HandoffHistory | Promise<HandoffHistory>) | undefined,\n history: HandoffHistory,\n): Promise<HandoffHistory> {\n if (filter === undefined) return history;\n try {\n const result = filter(history);\n return result instanceof Promise ? await result : result;\n } catch (err) {\n if (!warnedFilterOnce) {\n warnedFilterOnce = true;\n process.stderr.write(\n `[handoff] inputFilter threw, falling back to full history: ${err instanceof Error ? err.message : String(err)}\\n`,\n );\n }\n return history;\n }\n}\n\n/**\n * EC-4 / D229 — parse the LLM-provided JSON args. Returns undefined when\n * no `inputType` set; returns parsed value otherwise (default to `{}` on\n * empty/null input before Zod refinements).\n */\nfunction parseHandoffInput(descriptor: HandoffDescriptor, raw: unknown): unknown {\n const inputType = descriptor.options.inputType;\n if (inputType === undefined) return undefined;\n const candidate = raw === null || raw === undefined ? {} : raw;\n return inputType.parse(candidate);\n}\n\nfunction isAgentDisposed(agent: SDKAgent): boolean {\n // SDKAgent doesn't expose `disposed` publicly; check via duck-typing on\n // a known internal flag. Safe fallback: if we can't tell, assume alive.\n const maybe = agent as unknown as { disposed?: boolean };\n return maybe.disposed === true;\n}\n\n/**\n * Run a single handoff hop. Returns the receiver's reply text.\n *\n * Algorithm:\n * 1. EC-5: refuse if receiver disposed.\n * 2. Build HandoffContext.\n * 3. Check isEnabled() — if false, refuse with a clear error message.\n * 4. Parse inputType (D229).\n * 5. Run onHandoff(ctx, parsed) — throw aborts (D227).\n * 6. Apply inputFilter (safeFilter — D228).\n * 7. Record hop in chain state (depth + pair guards).\n * 8. Open OTel span (D220).\n * 9. Receiver: build the user-facing message and `await receiver.send(msg).then(wait)`.\n * 10. Close span + return reply.\n */\nasync function assertHandoffEnabled(\n descriptor: HandoffDescriptor,\n ctx: HandoffContext,\n receiverAgentId: string,\n): Promise<void> {\n const opt = descriptor.options.isEnabled;\n let enabled = true;\n if (typeof opt === \"boolean\") enabled = opt;\n else if (typeof opt === \"function\") {\n const r = opt(ctx);\n enabled = r instanceof Promise ? await r : r;\n }\n if (!enabled) {\n throw new Error(`Handoff to ${receiverAgentId} is disabled (isEnabled returned false)`);\n }\n}\n\nfunction parseAndValidate(descriptor: HandoffDescriptor, rawInputJson: unknown): unknown {\n try {\n return parseHandoffInput(descriptor, rawInputJson);\n } catch (err) {\n const detail =\n err instanceof z.ZodError\n ? (err.issues[0]?.message ?? \"schema_invalid\")\n : err instanceof Error\n ? err.message\n : String(err);\n throw new Error(`Handoff input validation failed: ${detail}`);\n }\n}\n\nasync function runOnHandoff(\n descriptor: HandoffDescriptor,\n ctx: HandoffContext,\n parsedInput: unknown,\n): Promise<void> {\n const onHandoff = descriptor.options.onHandoff;\n if (onHandoff === undefined) return;\n // biome-ignore lint/suspicious/noExplicitAny: parsedInput is typed unknown by design.\n const result = onHandoff(ctx, parsedInput as any);\n if (result instanceof Promise) await result;\n}\n\nfunction extractUserText(content: unknown): string | undefined {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return undefined;\n const text = content\n .filter((c): c is { type: \"text\"; text: string } => (c as { type?: string })?.type === \"text\")\n .map((c) => c.text)\n .join(\"\\n\");\n return text.length > 0 ? text : undefined;\n}\n\nfunction extractLastUserMessage(history: HandoffHistory, senderAgentId: string): string {\n for (let i = history.messages.length - 1; i >= 0; i -= 1) {\n const m = history.messages[i] as {\n type?: string;\n message?: { role?: string; content?: unknown };\n };\n if (m?.type !== \"user\" || m.message?.role !== \"user\") continue;\n const text = extractUserText(m.message.content);\n if (text !== undefined) return text;\n }\n return `(Handoff from ${senderAgentId} — no prior user message in history.)`;\n}\n\nexport async function dispatchHandoff(args: {\n descriptor: HandoffDescriptor;\n senderAgentId: string;\n chainState: HandoffChainState;\n rawInputJson: unknown;\n /** The conversation so far (history wrapper). v1: just the LAST user message. */\n history: HandoffHistory;\n /** Override the message text sent to the receiver. Used by `Agent.handoffTo` imperative. */\n messageOverride?: string;\n}): Promise<{ reply: string; result: HandoffResult }> {\n const { descriptor, senderAgentId, chainState, rawInputJson, history, messageOverride } = args;\n const receiver = descriptor.target;\n\n if (isAgentDisposed(receiver)) {\n throw new HandoffReceiverDisposedError(receiver.agentId);\n }\n\n const depthAfterThisHop = chainState.chain.length;\n const ctx: HandoffContext = {\n senderAgentId,\n receiverAgentId: receiver.agentId,\n currentDepth: depthAfterThisHop,\n chain: [...chainState.chain, receiver.agentId],\n };\n\n await assertHandoffEnabled(descriptor, ctx, receiver.agentId);\n const parsedInput = parseAndValidate(descriptor, rawInputJson);\n await runOnHandoff(descriptor, ctx, parsedInput);\n\n // Filter history (D228 — resilient)\n const filteredHistory = await safeFilter(descriptor.options.inputFilter, history);\n\n // Record hop — may throw HandoffLoopError or HandoffPairLoopError\n recordHop(chainState, senderAgentId, receiver.agentId);\n\n const lastUserMessage = messageOverride ?? extractLastUserMessage(filteredHistory, senderAgentId);\n const reason = extractReason(parsedInput);\n\n const span = startHandoffSpan({\n from: senderAgentId,\n to: receiver.agentId,\n reason,\n depth: depthAfterThisHop,\n toolName: descriptor.resolvedToolName,\n });\n\n try {\n const run = await receiver.send(lastUserMessage);\n const result = await run.wait();\n const reply = buildReply(result, receiver.agentId);\n return {\n reply,\n result: {\n from: senderAgentId,\n to: receiver.agentId,\n depth: depthAfterThisHop,\n toolName: descriptor.resolvedToolName,\n ...(reason !== \"\" ? { reasonFromLlm: reason } : {}),\n },\n };\n } finally {\n span.end();\n }\n}\n\nfunction extractReason(parsedInput: unknown): string {\n if (typeof parsedInput !== \"object\" || parsedInput === null) return \"\";\n if (!(\"reason\" in parsedInput)) return \"\";\n return String((parsedInput as { reason: unknown }).reason ?? \"\");\n}\n\nfunction buildReply(\n result: { status: string; result?: string; error?: { message: string } },\n receiverAgentId: string,\n): string {\n if (result.status === \"finished\" && result.result !== undefined) return result.result;\n const suffix = result.error !== undefined ? `: ${result.error.message}` : \"\";\n return `(Handoff target ${receiverAgentId} returned status=${result.status}${suffix})`;\n}\n","/**\n * Zod v4 → JSON Schema adapter for sdk-handoff.\n *\n * Uses Zod v4's native `z.toJSONSchema()` directly. v3 fallback removed\n * after zod-v4-migration plan (ADR D2).\n *\n * @internal\n */\n\nimport { toJSONSchema } from \"zod\";\n\ninterface ToJsonSchemaOptions {\n /** `\"any\"` keeps transforms/refinements as `{}` (loose). Default: `\"any\"`. */\n unrepresentable?: \"any\" | \"throw\";\n}\n\n/**\n * Convert a Zod schema to a JSON Schema object via Zod v4 native.\n *\n * @internal\n */\nexport function toJsonSchema(\n schema: unknown,\n options: ToJsonSchemaOptions = { unrepresentable: \"any\" },\n): Record<string, unknown> {\n // The schema param is `unknown` (callers pass `T extends ZodType` generics that\n // don't structurally satisfy Zod v4's `$ZodType`); cast to the exact parameter\n // type `toJSONSchema` expects rather than `any` — any z.* schema IS valid at runtime.\n return toJSONSchema(schema as Parameters<typeof toJSONSchema>[0], options) as Record<\n string,\n unknown\n >;\n}\n","/**\n * Convert `handoffs[]` entries into synthetic `transfer_to_<receiver>` tools\n * for injection into the agent's tool registry at construction time.\n *\n * The synthesized tool's handler calls `dispatchHandoff` internally and\n * returns the receiver's reply as `tool_result`. v1 trade-off documented\n * in dispatcher.ts.\n *\n * @internal\n */\n\nimport type { CustomTool, SDKAgent } from \"@theokit/sdk\";\nimport { z } from \"zod\";\nimport {\n type HandoffDescriptor,\n HandoffNameCollisionError,\n HandoffSelfReferenceError,\n} from \"../types/handoff.js\";\nimport { dispatchHandoff } from \"./dispatcher.js\";\nimport { createChainState } from \"./registry.js\";\nimport { toJsonSchema } from \"./to-json-schema.js\";\n\ninterface NormalizedHandoff {\n descriptor: HandoffDescriptor;\n}\n\n/**\n * Normalize each `handoffs[]` entry to a `HandoffDescriptor`. Raw `SDKAgent`\n * instances are auto-wrapped with default options. Validates:\n * - EC-6: no self-reference (would cause infinite recursion).\n * - D215: resolved tool names must be unique.\n */\nexport function normalizeHandoffs(\n parentAgentId: string,\n entries: ReadonlyArray<SDKAgent | HandoffDescriptor>,\n): NormalizedHandoff[] {\n if (entries.length === 0) return [];\n const out: NormalizedHandoff[] = [];\n const seenNames = new Set<string>();\n for (const entry of entries) {\n // Detect raw Agent vs HandoffDescriptor by presence of `.target`.\n const isDescriptor =\n typeof entry === \"object\" &&\n entry !== null &&\n \"target\" in entry &&\n \"options\" in entry &&\n \"resolvedToolName\" in entry;\n const descriptor = isDescriptor ? (entry as HandoffDescriptor) : autoWrap(entry as SDKAgent);\n if (descriptor.target.agentId === parentAgentId) {\n throw new HandoffSelfReferenceError(parentAgentId);\n }\n const name = descriptor.resolvedToolName;\n if (seenNames.has(name)) {\n throw new HandoffNameCollisionError(name);\n }\n seenNames.add(name);\n out.push({ descriptor });\n }\n return out;\n}\n\nfunction autoWrap(agent: SDKAgent): HandoffDescriptor {\n const name = resolveTargetName(agent);\n return {\n target: agent,\n options: {},\n resolvedToolName: `transfer_to_${name}`,\n };\n}\n\nfunction resolveTargetName(agent: SDKAgent): string {\n // Prefer a `name` field if exposed; fall back to a short agentId slug.\n const candidate = (agent as unknown as { name?: string }).name ?? agent.agentId ?? \"anonymous\";\n return slugify(candidate);\n}\n\nfunction slugify(input: string): string {\n return (\n input\n .replace(/^agent-/i, \"\")\n .replace(/[^a-zA-Z0-9_-]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 64) || \"anonymous\"\n );\n}\n\n/**\n * Build a `CustomTool` for one handoff descriptor. The handler dispatches\n * the handoff using a fresh chain state per `send()`-level invocation.\n *\n * NOTE: this v1 builds a NEW chain state per tool invocation. Pure\n * cross-tool depth tracking within one send() requires per-Agent context\n * — deferred. The single-flight pair guard catches direct ping-pong even\n * without cross-invocation chain (since each call wraps the same depth\n * counter from 1).\n */\nexport function buildHandoffTool(\n parentAgentId: string,\n descriptor: HandoffDescriptor,\n maxHandoffDepth: number,\n): CustomTool {\n const description =\n descriptor.options.toolDescription ??\n `Transfer the conversation to the ${descriptor.target.agentId} agent. ` +\n `Use this when the user's request matches their specialty.`;\n\n const inputZod =\n descriptor.options.inputType ??\n z.object({\n reason: z.string().optional().describe(\"Brief reason for the transfer (one short sentence).\"),\n });\n // CustomTool.inputSchema expects a JSON schema (Record<string, unknown>),\n // not the raw Zod type. Convert lazily so we don't fail when Zod is missing.\n // Universal Zod 3+4 conversion (feature-detects native v4, falls back to lib on v3).\n const inputSchema = toJsonSchema(inputZod);\n\n return {\n name: descriptor.resolvedToolName,\n description,\n inputSchema,\n handler: async (input: unknown): Promise<string> => {\n const chainState = createChainState(parentAgentId, maxHandoffDepth);\n try {\n const { reply, result } = await dispatchHandoff({\n descriptor,\n senderAgentId: parentAgentId,\n chainState,\n rawInputJson: input,\n history: { messages: [] }, // v1: history replay deferred\n });\n return JSON.stringify({\n ok: true,\n transferred_to: result.to,\n depth: result.depth,\n reply,\n });\n } catch (err) {\n return JSON.stringify({\n ok: false,\n error: err instanceof Error ? err.name : \"HandoffError\",\n message: err instanceof Error ? err.message : String(err),\n });\n }\n },\n };\n}\n","/**\n * Public `Handoff` class — factory for handoff descriptors (Adoption\n * Roadmap #4; ADRs D214-D229).\n *\n * Usage:\n *\n * import { Agent, Handoff } from \"@theokit/sdk\";\n *\n * const billing = await Agent.create({\n * name: \"billing\",\n * systemPrompt: \"You handle billing questions.\",\n * model: { id: \"openai/gpt-4o-mini\" },\n * apiKey: process.env.OPENROUTER_API_KEY,\n * });\n *\n * const triage = await Agent.create({\n * name: \"triage\",\n * systemPrompt: \"Classify the user's intent and transfer to the right specialist.\",\n * model: { id: \"openai/gpt-4o-mini\" },\n * apiKey: process.env.OPENROUTER_API_KEY,\n * handoffs: [\n * billing, // auto-wrapped as Handoff.create(billing)\n * Handoff.create(supportAgent, { inputFilter: redactCreditCards }),\n * ],\n * });\n *\n * @public\n */\n\nimport { Plugin, type PluginContext, type SDKAgent } from \"@theokit/sdk\";\nimport type { ZodType } from \"zod\";\nimport type { HandoffDescriptor, HandoffOptions } from \"./types/handoff.js\";\n\n/** Recommended system-prompt prefix for senders (D215 / EC-13). */\nexport const RECOMMENDED_HANDOFF_PROMPT_PREFIX = `\nYou can transfer the conversation to other specialist agents when their\nexpertise matches the user's request. Invoke the appropriate\ntransfer_to_<agent> tool with a short reason. The receiving agent will\ntake over the conversation; do not duplicate their work.\n`.trim();\n\nexport class Handoff {\n private constructor() {}\n\n /**\n * Build a `HandoffDescriptor` for a target agent. Wrap with custom options\n * (filter / inputType / callback / whitelist / etc); pass to\n * `Agent.create({ handoffs: [...] })`.\n *\n * Raw `SDKAgent` instances in `handoffs[]` are auto-wrapped by the runtime\n * — call `Handoff.create()` explicitly only when you need to customize.\n */\n static create<TInput extends ZodType = ZodType>(\n target: SDKAgent,\n options: HandoffOptions<TInput> = {} as HandoffOptions<TInput>,\n ): HandoffDescriptor<TInput> {\n if (target === undefined || target === null) {\n throw new Error(\"Handoff.create: target agent is required\");\n }\n if (typeof target.send !== \"function\") {\n throw new Error(\"Handoff.create: target must be an SDKAgent instance\");\n }\n const resolvedToolName = options.toolName ?? `transfer_to_${slugifyName(target)}`;\n return {\n target,\n options,\n resolvedToolName,\n };\n }\n\n /**\n * Plugin-based wiring (SDK 2.x preferred). Wraps `targets` in synthetic\n * `transfer_to_<receiver>` tools and registers them via `ctx.registerTool`\n * at agent init time.\n *\n * Replaces the legacy `Agent.create({ handoffs: [...] })` option (which is\n * still supported as a transitional convenience while sdk-handoff is\n * installed — the framework lazy-imports the tool-injector at runtime).\n *\n * @example\n * const support = await Agent.create({\n * name: \"support\",\n * plugins: [Handoff.asPlugin({ parentAgentId: \"support\", targets: [billing] })],\n * });\n */\n static asPlugin(opts: AsPluginOptions): Plugin {\n const parent = opts.parentAgentId ?? \"anonymous\";\n const maxDepth = opts.maxHandoffDepth ?? 5;\n const targets = opts.targets;\n return Plugin.create({\n name: `handoff-${parent}`,\n version: \"1.0.0\",\n kind: \"general\" as const,\n register(ctx: PluginContext): void {\n if (maxDepth === 0 || targets.length === 0) return;\n // Lazy import — keeps cold path lean if asPlugin is constructed but\n // its register hook is never invoked (e.g., disabled by config).\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n void (async () => {\n const { normalizeHandoffs, buildHandoffTool } = await import(\n \"./internal/tool-injector.js\"\n );\n const normalized = normalizeHandoffs(parent, targets);\n for (const { descriptor } of normalized) {\n ctx.registerTool(buildHandoffTool(parent, descriptor, maxDepth));\n }\n })();\n },\n });\n }\n}\n\n/**\n * Options for `Handoff.asPlugin()`. `parentAgentId` defaults to `\"anonymous\"`;\n * pass the host agent's `name` for correct loop detection in chains.\n */\nexport interface AsPluginOptions {\n readonly targets: ReadonlyArray<SDKAgent | HandoffDescriptor>;\n readonly parentAgentId?: string;\n readonly maxHandoffDepth?: number;\n}\n\nfunction slugifyName(agent: SDKAgent): string {\n const candidate = (agent as unknown as { name?: string }).name ?? agent.agentId ?? \"anonymous\";\n return (\n candidate\n .replace(/^agent-/i, \"\")\n .replace(/[^a-zA-Z0-9_-]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 64) || \"anonymous\"\n );\n}\n\n/**\n * Imperative escape hatch (D225). Useful for tests / programmatic flows\n * that need deterministic handoff without LLM routing.\n *\n * NOTE: this is a STANDALONE helper rather than a method on `SDKAgent`\n * to avoid invasive refactor of the agent class. Behavior is identical\n * to invoking the corresponding synthetic tool would be.\n */\nexport async function handoffTo(\n sender: SDKAgent,\n target: SDKAgent,\n message: string,\n options: HandoffOptions = {},\n): Promise<string> {\n const descriptor = Handoff.create(target, options);\n // Lazy import to avoid loading internal module unless this is called.\n const { dispatchHandoff } = await import(\"./internal/dispatcher.js\");\n const { createChainState } = await import(\"./internal/registry.js\");\n const chainState = createChainState(sender.agentId, 5);\n const { reply } = await dispatchHandoff({\n descriptor,\n senderAgentId: sender.agentId,\n chainState,\n rawInputJson: undefined,\n history: { messages: [] },\n messageOverride: message,\n });\n return reply;\n}\n","/**\n * `@theokit/sdk-handoff` — inter-agent dispatch for `@theokit/sdk`.\n *\n * Extracted from `@theokit/sdk@1.7.0` as part of the SDK 2.0 package split\n * (Phase 4 / T4.1). Integrates with `Agent` via the Plugin protocol —\n * `Handoff.asPlugin({ targets })` returns a `Plugin` consumed by\n * `Agent.create({ plugins: [...] })`.\n *\n * @packageDocumentation\n */\n\nexport {\n type AsPluginOptions,\n Handoff,\n handoffTo,\n RECOMMENDED_HANDOFF_PROMPT_PREFIX,\n} from \"./handoff.js\";\nexport type { HandoffDescriptor, HandoffOptions } from \"./types/handoff.js\";\nexport {\n HandoffLoopError,\n HandoffNameCollisionError,\n HandoffPairLoopError,\n HandoffReceiverDisposedError,\n HandoffSelfReferenceError,\n} from \"./types/handoff.js\";\n"]}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { createRequire } from 'module';
2
2
  import { z, toJSONSchema } from 'zod';
3
- import { definePlugin } from '@theokit/sdk';
3
+ import { Plugin } from '@theokit/sdk';
4
4
 
5
5
  var __defProp = Object.defineProperty;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -441,7 +441,7 @@ var Handoff = class {
441
441
  const parent = opts.parentAgentId ?? "anonymous";
442
442
  const maxDepth = opts.maxHandoffDepth ?? 5;
443
443
  const targets = opts.targets;
444
- return definePlugin({
444
+ return Plugin.create({
445
445
  name: `handoff-${parent}`,
446
446
  version: "1.0.0",
447
447
  kind: "general",
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types/handoff.ts","../src/internal/registry.ts","../src/internal/telemetry.ts","../src/internal/dispatcher.ts","../src/internal/to-json-schema.ts","../src/internal/tool-injector.ts","../src/handoff.ts","../src/index.ts"],"names":["z","normalizeHandoffs","buildHandoffTool","dispatchHandoff","createChainState"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Public types for `Agent.create({ handoffs })` + `Handoff.create()` +\n * `Agent.handoffTo()` (Adoption Roadmap #4; ADRs D214-D229).\n *\n * Pattern: handoff-as-tool. Each handoff destination becomes a synthetic\n * `transfer_to_<receiver>` function tool exposed to the LLM. Runtime\n * intercepts the tool call and routes the next turn to the receiver.\n *\n * T4.1 follow-up (cycle #4 closed): `HandoffDescriptor` + its leaf-friendly\n * sibling types now live in `./handoff-descriptor.ts` (generic over\n * `TAgent`). This module re-exports the leaf types pinned to `SDKAgent`,\n * keeps the runtime error classes, and removes the back-edge to `agent.ts`.\n *\n * @public\n */\n\nimport type { SDKAgent } from \"@theokit/sdk\";\nimport type { ZodType } from \"zod\";\nimport type {\n HandoffContext,\n HandoffDescriptor as HandoffDescriptorGeneric,\n HandoffHistory,\n HandoffOptions,\n HandoffResult,\n} from \"./handoff-descriptor.js\";\n\nexport type { HandoffContext, HandoffHistory, HandoffOptions, HandoffResult };\n\n/**\n * `HandoffDescriptor` pinned to `SDKAgent` — back-compat shape for callers\n * that imported `import type { HandoffDescriptor } from \"@theokit/sdk\"`\n * before T4.1 follow-up.\n *\n * @public\n */\nexport type HandoffDescriptor<TInput extends ZodType = ZodType> = HandoffDescriptorGeneric<\n TInput,\n SDKAgent\n>;\n\n/** Throw when handoff depth exceeds `maxHandoffDepth` (default 5; D218). */\nexport class HandoffLoopError extends Error {\n override readonly name = \"HandoffLoopError\";\n readonly depth: number;\n readonly chain: ReadonlyArray<string>;\n constructor(depth: number, chain: ReadonlyArray<string>) {\n super(\n `Handoff loop exceeded max depth ${depth}. Chain: ${chain.join(\" -> \")}. ` +\n `Use Agent.create({ maxHandoffDepth: N }) to raise the cap.`,\n );\n this.depth = depth;\n this.chain = chain;\n }\n}\n\n/** Throw when the same (sender, receiver) pair invoked twice in one send() (D221). */\nexport class HandoffPairLoopError extends Error {\n override readonly name = \"HandoffPairLoopError\";\n readonly senderAgentId: string;\n readonly receiverAgentId: string;\n constructor(senderAgentId: string, receiverAgentId: string) {\n super(\n `Handoff loop: ${senderAgentId} -> ${receiverAgentId} already invoked in this send() call. ` +\n `Likely a ping-pong loop; revisit your handoff conditions.`,\n );\n this.senderAgentId = senderAgentId;\n this.receiverAgentId = receiverAgentId;\n }\n}\n\n/** Throw when an agent's `handoffs[]` includes a self-reference (EC-6). */\nexport class HandoffSelfReferenceError extends Error {\n override readonly name = \"HandoffSelfReferenceError\";\n readonly agentId: string;\n constructor(agentId: string) {\n super(\n `Agent \"${agentId}\" has a self-reference in its handoffs[]. ` +\n `Self-handoff causes infinite recursion; introduce a sibling agent for re-entry.`,\n );\n this.agentId = agentId;\n }\n}\n\n/** Throw when receiver is disposed at dispatch time (EC-5). */\nexport class HandoffReceiverDisposedError extends Error {\n override readonly name = \"HandoffReceiverDisposedError\";\n readonly receiverAgentId: string;\n constructor(receiverAgentId: string) {\n super(\n `Handoff target agent \"${receiverAgentId}\" is disposed. ` +\n `Don't dispose receivers while their parent is still active.`,\n );\n this.receiverAgentId = receiverAgentId;\n }\n}\n\n/** Throw when two handoffs in the same parent collide on tool name (D215). */\nexport class HandoffNameCollisionError extends Error {\n override readonly name = \"HandoffNameCollisionError\";\n readonly conflictingName: string;\n constructor(conflictingName: string) {\n super(\n `Two handoffs share the same tool name \"${conflictingName}\". ` +\n `Set { toolName } on at least one of them to disambiguate.`,\n );\n this.conflictingName = conflictingName;\n }\n}\n","/**\n * Handoff registry — pure state container per `Agent` instance.\n *\n * Holds the active dispatch chain (for depth + pair tracking) across the\n * lifetime of a single `agent.send()` call. Cleared between calls.\n *\n * @internal\n */\n\nimport { HandoffLoopError, HandoffPairLoopError } from \"../types/handoff.js\";\n\nexport interface HandoffChainState {\n /** Ordered chain of agentIds traversed so far (oldest first). */\n readonly chain: string[];\n /** Set of \"<sender>-><receiver>\" keys for pair-level loop detection (D221). */\n readonly seenPairs: Set<string>;\n /** Caller-supplied max depth (D218). */\n readonly maxDepth: number;\n}\n\nexport function createChainState(rootAgentId: string, maxDepth: number): HandoffChainState {\n return {\n chain: [rootAgentId],\n seenPairs: new Set(),\n maxDepth,\n };\n}\n\n/**\n * Record a handoff hop. Throws on depth-exceed (D218) or pair-loop (D221).\n * Mutates the state in place.\n */\nexport function recordHop(\n state: HandoffChainState,\n senderAgentId: string,\n receiverAgentId: string,\n): void {\n const pairKey = `${senderAgentId}->${receiverAgentId}`;\n if (state.seenPairs.has(pairKey)) {\n throw new HandoffPairLoopError(senderAgentId, receiverAgentId);\n }\n state.seenPairs.add(pairKey);\n state.chain.push(receiverAgentId);\n // chain.length = nodes; depth = hops = chain.length - 1.\n const depth = state.chain.length - 1;\n if (depth > state.maxDepth) {\n throw new HandoffLoopError(state.maxDepth, [...state.chain]);\n }\n}\n\nexport function currentDepth(state: HandoffChainState): number {\n return state.chain.length - 1;\n}\n","/**\n * D220 — Lazy-loaded OTel `handoff.transfer` span emitter.\n *\n * @internal\n */\n\n// Inline tracer-loader (same workaround as @theokit/sdk-cache/internal/telemetry.ts):\n// rollup-plugin-dts emits incomplete index.d.ts for newly-modified internal/ barrels\n// in @theokit/sdk. Runtime via the sub-path works; TypeScript users hit TS2305.\n// Inlining keeps sdk-handoff self-contained for the (small) observability hook.\nimport { createRequire } from \"node:module\";\n\ninterface SpanLike {\n setAttribute(key: string, value: string | number | boolean): SpanLike;\n end(): void;\n}\n\nconst _NOOP_SPAN: SpanLike = {\n setAttribute: () => _NOOP_SPAN,\n end: () => undefined,\n};\n\ninterface TracerLike {\n startSpan(\n name: string,\n options?: { attributes?: Record<string, string | number | boolean> },\n ): SpanLike;\n}\n\ninterface TracerCacheEntry {\n tracer: TracerLike | null;\n}\nconst tracerCache = new Map<string, TracerCacheEntry>();\n\nfunction getTracer(name: string, version = \"1.0.0\"): TracerLike | undefined {\n const cached = tracerCache.get(name);\n if (cached !== undefined) return cached.tracer ?? undefined;\n try {\n const r = createRequire(import.meta.url);\n const otel = r(\"@opentelemetry/api\") as {\n trace?: { getTracer: (n: string, v?: string) => TracerLike };\n };\n if (otel.trace?.getTracer === undefined) {\n tracerCache.set(name, { tracer: null });\n return undefined;\n }\n const tracer = otel.trace.getTracer(name, version);\n tracerCache.set(name, { tracer });\n return tracer;\n } catch {\n tracerCache.set(name, { tracer: null });\n return undefined;\n }\n}\n\nfunction resetTracerCacheForTests(): void {\n tracerCache.clear();\n}\n\nconst TRACER_NAME = \"theokit-sdk-handoff\";\n\ninterface HandoffSpanHandle {\n setAttribute(key: string, value: string | number | boolean): void;\n end(): void;\n}\n\nconst NOOP: HandoffSpanHandle = { setAttribute: () => undefined, end: () => undefined };\n\nfunction safe<T>(fn: () => T, fallback: T): T {\n try {\n return fn();\n } catch {\n return fallback;\n }\n}\n\nexport function startHandoffSpan(attrs: {\n from: string;\n to: string;\n reason: string;\n depth: number;\n toolName: string;\n}): HandoffSpanHandle {\n const tracer = getTracer(TRACER_NAME);\n if (tracer === undefined) return NOOP;\n const span: SpanLike | undefined = safe(\n () =>\n tracer.startSpan(\"handoff.transfer\", {\n attributes: {\n \"handoff.from\": attrs.from,\n \"handoff.to\": attrs.to,\n \"handoff.reason\": attrs.reason,\n \"handoff.depth\": attrs.depth,\n \"handoff.tool_name\": attrs.toolName,\n },\n }),\n undefined,\n );\n if (span === undefined) return NOOP;\n return {\n setAttribute: (k, v) => safe(() => span.setAttribute(k, v), undefined),\n end: () => safe(() => span.end(), undefined),\n };\n}\n\n/** Test-only — reset cached OTel handle. */\nfunction __resetHandoffOtelCacheForTests(): void {\n resetTracerCacheForTests();\n}\n","/**\n * Handoff dispatch orchestration.\n *\n * Pragmatic v1: when a handoff fires, the sender calls `receiver.send()`\n * with the (optionally filtered) history. The receiver's reply is returned\n * to the sender, which captures it as the answer to the user's question.\n *\n * NOTE: this is NOT pure peer-to-peer (the sender stays on the call stack\n * until the receiver returns). Pure intercept-and-swap requires deeper\n * agent-loop refactor; deferred to v2. v1 still validates the user-facing\n * value: \"agent A reasoned about routing, agent B answered.\"\n *\n * @internal\n */\n\nimport type { SDKAgent } from \"@theokit/sdk\";\nimport { z } from \"zod\";\nimport type {\n HandoffContext,\n HandoffDescriptor,\n HandoffHistory,\n HandoffResult,\n} from \"../types/handoff.js\";\nimport { HandoffReceiverDisposedError } from \"../types/handoff.js\";\nimport { type HandoffChainState, recordHop } from \"./registry.js\";\nimport { startHandoffSpan } from \"./telemetry.js\";\n\n/**\n * EC-2 / D228 — `safeFilter` wraps `inputFilter`. On exception, falls back\n * to the un-filtered history and warns to stderr once per process.\n */\nlet warnedFilterOnce = false;\nasync function safeFilter(\n filter: ((h: HandoffHistory) => HandoffHistory | Promise<HandoffHistory>) | undefined,\n history: HandoffHistory,\n): Promise<HandoffHistory> {\n if (filter === undefined) return history;\n try {\n const result = filter(history);\n return result instanceof Promise ? await result : result;\n } catch (err) {\n if (!warnedFilterOnce) {\n warnedFilterOnce = true;\n process.stderr.write(\n `[handoff] inputFilter threw, falling back to full history: ${err instanceof Error ? err.message : String(err)}\\n`,\n );\n }\n return history;\n }\n}\n\n/**\n * EC-4 / D229 — parse the LLM-provided JSON args. Returns undefined when\n * no `inputType` set; returns parsed value otherwise (default to `{}` on\n * empty/null input before Zod refinements).\n */\nfunction parseHandoffInput(descriptor: HandoffDescriptor, raw: unknown): unknown {\n const inputType = descriptor.options.inputType;\n if (inputType === undefined) return undefined;\n const candidate = raw === null || raw === undefined ? {} : raw;\n return inputType.parse(candidate);\n}\n\nfunction isAgentDisposed(agent: SDKAgent): boolean {\n // SDKAgent doesn't expose `disposed` publicly; check via duck-typing on\n // a known internal flag. Safe fallback: if we can't tell, assume alive.\n const maybe = agent as unknown as { disposed?: boolean };\n return maybe.disposed === true;\n}\n\n/**\n * Run a single handoff hop. Returns the receiver's reply text.\n *\n * Algorithm:\n * 1. EC-5: refuse if receiver disposed.\n * 2. Build HandoffContext.\n * 3. Check isEnabled() — if false, refuse with a clear error message.\n * 4. Parse inputType (D229).\n * 5. Run onHandoff(ctx, parsed) — throw aborts (D227).\n * 6. Apply inputFilter (safeFilter — D228).\n * 7. Record hop in chain state (depth + pair guards).\n * 8. Open OTel span (D220).\n * 9. Receiver: build the user-facing message and `await receiver.send(msg).then(wait)`.\n * 10. Close span + return reply.\n */\nasync function assertHandoffEnabled(\n descriptor: HandoffDescriptor,\n ctx: HandoffContext,\n receiverAgentId: string,\n): Promise<void> {\n const opt = descriptor.options.isEnabled;\n let enabled = true;\n if (typeof opt === \"boolean\") enabled = opt;\n else if (typeof opt === \"function\") {\n const r = opt(ctx);\n enabled = r instanceof Promise ? await r : r;\n }\n if (!enabled) {\n throw new Error(`Handoff to ${receiverAgentId} is disabled (isEnabled returned false)`);\n }\n}\n\nfunction parseAndValidate(descriptor: HandoffDescriptor, rawInputJson: unknown): unknown {\n try {\n return parseHandoffInput(descriptor, rawInputJson);\n } catch (err) {\n const detail =\n err instanceof z.ZodError\n ? (err.issues[0]?.message ?? \"schema_invalid\")\n : err instanceof Error\n ? err.message\n : String(err);\n throw new Error(`Handoff input validation failed: ${detail}`);\n }\n}\n\nasync function runOnHandoff(\n descriptor: HandoffDescriptor,\n ctx: HandoffContext,\n parsedInput: unknown,\n): Promise<void> {\n const onHandoff = descriptor.options.onHandoff;\n if (onHandoff === undefined) return;\n // biome-ignore lint/suspicious/noExplicitAny: parsedInput is typed unknown by design.\n const result = onHandoff(ctx, parsedInput as any);\n if (result instanceof Promise) await result;\n}\n\nfunction extractUserText(content: unknown): string | undefined {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return undefined;\n const text = content\n .filter((c): c is { type: \"text\"; text: string } => (c as { type?: string })?.type === \"text\")\n .map((c) => c.text)\n .join(\"\\n\");\n return text.length > 0 ? text : undefined;\n}\n\nfunction extractLastUserMessage(history: HandoffHistory, senderAgentId: string): string {\n for (let i = history.messages.length - 1; i >= 0; i -= 1) {\n const m = history.messages[i] as {\n type?: string;\n message?: { role?: string; content?: unknown };\n };\n if (m?.type !== \"user\" || m.message?.role !== \"user\") continue;\n const text = extractUserText(m.message.content);\n if (text !== undefined) return text;\n }\n return `(Handoff from ${senderAgentId} — no prior user message in history.)`;\n}\n\nexport async function dispatchHandoff(args: {\n descriptor: HandoffDescriptor;\n senderAgentId: string;\n chainState: HandoffChainState;\n rawInputJson: unknown;\n /** The conversation so far (history wrapper). v1: just the LAST user message. */\n history: HandoffHistory;\n /** Override the message text sent to the receiver. Used by `Agent.handoffTo` imperative. */\n messageOverride?: string;\n}): Promise<{ reply: string; result: HandoffResult }> {\n const { descriptor, senderAgentId, chainState, rawInputJson, history, messageOverride } = args;\n const receiver = descriptor.target;\n\n if (isAgentDisposed(receiver)) {\n throw new HandoffReceiverDisposedError(receiver.agentId);\n }\n\n const depthAfterThisHop = chainState.chain.length;\n const ctx: HandoffContext = {\n senderAgentId,\n receiverAgentId: receiver.agentId,\n currentDepth: depthAfterThisHop,\n chain: [...chainState.chain, receiver.agentId],\n };\n\n await assertHandoffEnabled(descriptor, ctx, receiver.agentId);\n const parsedInput = parseAndValidate(descriptor, rawInputJson);\n await runOnHandoff(descriptor, ctx, parsedInput);\n\n // Filter history (D228 — resilient)\n const filteredHistory = await safeFilter(descriptor.options.inputFilter, history);\n\n // Record hop — may throw HandoffLoopError or HandoffPairLoopError\n recordHop(chainState, senderAgentId, receiver.agentId);\n\n const lastUserMessage = messageOverride ?? extractLastUserMessage(filteredHistory, senderAgentId);\n const reason = extractReason(parsedInput);\n\n const span = startHandoffSpan({\n from: senderAgentId,\n to: receiver.agentId,\n reason,\n depth: depthAfterThisHop,\n toolName: descriptor.resolvedToolName,\n });\n\n try {\n const run = await receiver.send(lastUserMessage);\n const result = await run.wait();\n const reply = buildReply(result, receiver.agentId);\n return {\n reply,\n result: {\n from: senderAgentId,\n to: receiver.agentId,\n depth: depthAfterThisHop,\n toolName: descriptor.resolvedToolName,\n ...(reason !== \"\" ? { reasonFromLlm: reason } : {}),\n },\n };\n } finally {\n span.end();\n }\n}\n\nfunction extractReason(parsedInput: unknown): string {\n if (typeof parsedInput !== \"object\" || parsedInput === null) return \"\";\n if (!(\"reason\" in parsedInput)) return \"\";\n return String((parsedInput as { reason: unknown }).reason ?? \"\");\n}\n\nfunction buildReply(\n result: { status: string; result?: string; error?: { message: string } },\n receiverAgentId: string,\n): string {\n if (result.status === \"finished\" && result.result !== undefined) return result.result;\n const suffix = result.error !== undefined ? `: ${result.error.message}` : \"\";\n return `(Handoff target ${receiverAgentId} returned status=${result.status}${suffix})`;\n}\n","/**\n * Zod v4 → JSON Schema adapter for sdk-handoff.\n *\n * Uses Zod v4's native `z.toJSONSchema()` directly. v3 fallback removed\n * after zod-v4-migration plan (ADR D2).\n *\n * @internal\n */\n\nimport { toJSONSchema } from \"zod\";\n\ninterface ToJsonSchemaOptions {\n /** `\"any\"` keeps transforms/refinements as `{}` (loose). Default: `\"any\"`. */\n unrepresentable?: \"any\" | \"throw\";\n}\n\n/**\n * Convert a Zod schema to a JSON Schema object via Zod v4 native.\n *\n * @internal\n */\nexport function toJsonSchema(\n schema: unknown,\n options: ToJsonSchemaOptions = { unrepresentable: \"any\" },\n): Record<string, unknown> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- generic ZodType erasure\n return toJSONSchema(schema as any, options) as Record<string, unknown>;\n}\n","/**\n * Convert `handoffs[]` entries into synthetic `transfer_to_<receiver>` tools\n * for injection into the agent's tool registry at construction time.\n *\n * The synthesized tool's handler calls `dispatchHandoff` internally and\n * returns the receiver's reply as `tool_result`. v1 trade-off documented\n * in dispatcher.ts.\n *\n * @internal\n */\n\nimport type { CustomTool, SDKAgent } from \"@theokit/sdk\";\nimport { z } from \"zod\";\nimport {\n type HandoffDescriptor,\n HandoffNameCollisionError,\n HandoffSelfReferenceError,\n} from \"../types/handoff.js\";\nimport { dispatchHandoff } from \"./dispatcher.js\";\nimport { createChainState } from \"./registry.js\";\nimport { toJsonSchema } from \"./to-json-schema.js\";\n\ninterface NormalizedHandoff {\n descriptor: HandoffDescriptor;\n}\n\n/**\n * Normalize each `handoffs[]` entry to a `HandoffDescriptor`. Raw `SDKAgent`\n * instances are auto-wrapped with default options. Validates:\n * - EC-6: no self-reference (would cause infinite recursion).\n * - D215: resolved tool names must be unique.\n */\nexport function normalizeHandoffs(\n parentAgentId: string,\n entries: ReadonlyArray<SDKAgent | HandoffDescriptor>,\n): NormalizedHandoff[] {\n if (entries.length === 0) return [];\n const out: NormalizedHandoff[] = [];\n const seenNames = new Set<string>();\n for (const entry of entries) {\n // Detect raw Agent vs HandoffDescriptor by presence of `.target`.\n const isDescriptor =\n typeof entry === \"object\" &&\n entry !== null &&\n \"target\" in entry &&\n \"options\" in entry &&\n \"resolvedToolName\" in entry;\n const descriptor = isDescriptor ? (entry as HandoffDescriptor) : autoWrap(entry as SDKAgent);\n if (descriptor.target.agentId === parentAgentId) {\n throw new HandoffSelfReferenceError(parentAgentId);\n }\n const name = descriptor.resolvedToolName;\n if (seenNames.has(name)) {\n throw new HandoffNameCollisionError(name);\n }\n seenNames.add(name);\n out.push({ descriptor });\n }\n return out;\n}\n\nfunction autoWrap(agent: SDKAgent): HandoffDescriptor {\n const name = resolveTargetName(agent);\n return {\n target: agent,\n options: {},\n resolvedToolName: `transfer_to_${name}`,\n };\n}\n\nfunction resolveTargetName(agent: SDKAgent): string {\n // Prefer a `name` field if exposed; fall back to a short agentId slug.\n const candidate = (agent as unknown as { name?: string }).name ?? agent.agentId ?? \"anonymous\";\n return slugify(candidate);\n}\n\nfunction slugify(input: string): string {\n return (\n input\n .replace(/^agent-/i, \"\")\n .replace(/[^a-zA-Z0-9_-]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 64) || \"anonymous\"\n );\n}\n\n/**\n * Build a `CustomTool` for one handoff descriptor. The handler dispatches\n * the handoff using a fresh chain state per `send()`-level invocation.\n *\n * NOTE: this v1 builds a NEW chain state per tool invocation. Pure\n * cross-tool depth tracking within one send() requires per-Agent context\n * — deferred. The single-flight pair guard catches direct ping-pong even\n * without cross-invocation chain (since each call wraps the same depth\n * counter from 1).\n */\nexport function buildHandoffTool(\n parentAgentId: string,\n descriptor: HandoffDescriptor,\n maxHandoffDepth: number,\n): CustomTool {\n const description =\n descriptor.options.toolDescription ??\n `Transfer the conversation to the ${descriptor.target.agentId} agent. ` +\n `Use this when the user's request matches their specialty.`;\n\n const inputZod =\n descriptor.options.inputType ??\n z.object({\n reason: z.string().optional().describe(\"Brief reason for the transfer (one short sentence).\"),\n });\n // CustomTool.inputSchema expects a JSON schema (Record<string, unknown>),\n // not the raw Zod type. Convert lazily so we don't fail when Zod is missing.\n // Universal Zod 3+4 conversion (feature-detects native v4, falls back to lib on v3).\n const inputSchema = toJsonSchema(inputZod);\n\n return {\n name: descriptor.resolvedToolName,\n description,\n inputSchema,\n handler: async (input: unknown): Promise<string> => {\n const chainState = createChainState(parentAgentId, maxHandoffDepth);\n try {\n const { reply, result } = await dispatchHandoff({\n descriptor,\n senderAgentId: parentAgentId,\n chainState,\n rawInputJson: input,\n history: { messages: [] }, // v1: history replay deferred\n });\n return JSON.stringify({\n ok: true,\n transferred_to: result.to,\n depth: result.depth,\n reply,\n });\n } catch (err) {\n return JSON.stringify({\n ok: false,\n error: err instanceof Error ? err.name : \"HandoffError\",\n message: err instanceof Error ? err.message : String(err),\n });\n }\n },\n };\n}\n","/**\n * Public `Handoff` class — factory for handoff descriptors (Adoption\n * Roadmap #4; ADRs D214-D229).\n *\n * Usage:\n *\n * import { Agent, Handoff } from \"@theokit/sdk\";\n *\n * const billing = await Agent.create({\n * name: \"billing\",\n * systemPrompt: \"You handle billing questions.\",\n * model: { id: \"openai/gpt-4o-mini\" },\n * apiKey: process.env.OPENROUTER_API_KEY,\n * });\n *\n * const triage = await Agent.create({\n * name: \"triage\",\n * systemPrompt: \"Classify the user's intent and transfer to the right specialist.\",\n * model: { id: \"openai/gpt-4o-mini\" },\n * apiKey: process.env.OPENROUTER_API_KEY,\n * handoffs: [\n * billing, // auto-wrapped as Handoff.create(billing)\n * Handoff.create(supportAgent, { inputFilter: redactCreditCards }),\n * ],\n * });\n *\n * @public\n */\n\nimport { definePlugin, type Plugin, type PluginContext, type SDKAgent } from \"@theokit/sdk\";\nimport type { ZodType } from \"zod\";\nimport type { HandoffDescriptor, HandoffOptions } from \"./types/handoff.js\";\n\n/** Recommended system-prompt prefix for senders (D215 / EC-13). */\nexport const RECOMMENDED_HANDOFF_PROMPT_PREFIX = `\nYou can transfer the conversation to other specialist agents when their\nexpertise matches the user's request. Invoke the appropriate\ntransfer_to_<agent> tool with a short reason. The receiving agent will\ntake over the conversation; do not duplicate their work.\n`.trim();\n\nexport class Handoff {\n private constructor() {}\n\n /**\n * Build a `HandoffDescriptor` for a target agent. Wrap with custom options\n * (filter / inputType / callback / whitelist / etc); pass to\n * `Agent.create({ handoffs: [...] })`.\n *\n * Raw `SDKAgent` instances in `handoffs[]` are auto-wrapped by the runtime\n * — call `Handoff.create()` explicitly only when you need to customize.\n */\n static create<TInput extends ZodType = ZodType>(\n target: SDKAgent,\n options: HandoffOptions<TInput> = {} as HandoffOptions<TInput>,\n ): HandoffDescriptor<TInput> {\n if (target === undefined || target === null) {\n throw new Error(\"Handoff.create: target agent is required\");\n }\n if (typeof target.send !== \"function\") {\n throw new Error(\"Handoff.create: target must be an SDKAgent instance\");\n }\n const resolvedToolName = options.toolName ?? `transfer_to_${slugifyName(target)}`;\n return {\n target,\n options,\n resolvedToolName,\n };\n }\n\n /**\n * Plugin-based wiring (SDK 2.x preferred). Wraps `targets` in synthetic\n * `transfer_to_<receiver>` tools and registers them via `ctx.registerTool`\n * at agent init time.\n *\n * Replaces the legacy `Agent.create({ handoffs: [...] })` option (which is\n * still supported as a transitional convenience while sdk-handoff is\n * installed — the framework lazy-imports the tool-injector at runtime).\n *\n * @example\n * const support = await Agent.create({\n * name: \"support\",\n * plugins: [Handoff.asPlugin({ parentAgentId: \"support\", targets: [billing] })],\n * });\n */\n static asPlugin(opts: AsPluginOptions): Plugin {\n const parent = opts.parentAgentId ?? \"anonymous\";\n const maxDepth = opts.maxHandoffDepth ?? 5;\n const targets = opts.targets;\n return definePlugin({\n name: `handoff-${parent}`,\n version: \"1.0.0\",\n kind: \"general\" as const,\n register(ctx: PluginContext): void {\n if (maxDepth === 0 || targets.length === 0) return;\n // Lazy import — keeps cold path lean if asPlugin is constructed but\n // its register hook is never invoked (e.g., disabled by config).\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n void (async () => {\n const { normalizeHandoffs, buildHandoffTool } = await import(\n \"./internal/tool-injector.js\"\n );\n const normalized = normalizeHandoffs(parent, targets);\n for (const { descriptor } of normalized) {\n ctx.registerTool(buildHandoffTool(parent, descriptor, maxDepth));\n }\n })();\n },\n });\n }\n}\n\n/**\n * Options for `Handoff.asPlugin()`. `parentAgentId` defaults to `\"anonymous\"`;\n * pass the host agent's `name` for correct loop detection in chains.\n */\nexport interface AsPluginOptions {\n readonly targets: ReadonlyArray<SDKAgent | HandoffDescriptor>;\n readonly parentAgentId?: string;\n readonly maxHandoffDepth?: number;\n}\n\nfunction slugifyName(agent: SDKAgent): string {\n const candidate = (agent as unknown as { name?: string }).name ?? agent.agentId ?? \"anonymous\";\n return (\n candidate\n .replace(/^agent-/i, \"\")\n .replace(/[^a-zA-Z0-9_-]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 64) || \"anonymous\"\n );\n}\n\n/**\n * Imperative escape hatch (D225). Useful for tests / programmatic flows\n * that need deterministic handoff without LLM routing.\n *\n * NOTE: this is a STANDALONE helper rather than a method on `SDKAgent`\n * to avoid invasive refactor of the agent class. Behavior is identical\n * to invoking the corresponding synthetic tool would be.\n */\nexport async function handoffTo(\n sender: SDKAgent,\n target: SDKAgent,\n message: string,\n options: HandoffOptions = {},\n): Promise<string> {\n const descriptor = Handoff.create(target, options);\n // Lazy import to avoid loading internal module unless this is called.\n const { dispatchHandoff } = await import(\"./internal/dispatcher.js\");\n const { createChainState } = await import(\"./internal/registry.js\");\n const chainState = createChainState(sender.agentId, 5);\n const { reply } = await dispatchHandoff({\n descriptor,\n senderAgentId: sender.agentId,\n chainState,\n rawInputJson: undefined,\n history: { messages: [] },\n messageOverride: message,\n });\n return reply;\n}\n","/**\n * `@theokit/sdk-handoff` — inter-agent dispatch for `@theokit/sdk`.\n *\n * Extracted from `@theokit/sdk@1.7.0` as part of the SDK 2.0 package split\n * (Phase 4 / T4.1). Integrates with `Agent` via the Plugin protocol —\n * `Handoff.asPlugin({ targets })` returns a `Plugin` consumed by\n * `Agent.create({ plugins: [...] })`.\n *\n * @packageDocumentation\n */\n\nexport {\n type AsPluginOptions,\n Handoff,\n handoffTo,\n RECOMMENDED_HANDOFF_PROMPT_PREFIX,\n} from \"./handoff.js\";\nexport type { HandoffDescriptor, HandoffOptions } from \"./types/handoff.js\";\nexport {\n HandoffLoopError,\n HandoffNameCollisionError,\n HandoffPairLoopError,\n HandoffReceiverDisposedError,\n HandoffSelfReferenceError,\n} from \"./types/handoff.js\";\n"]}
1
+ {"version":3,"sources":["../src/types/handoff.ts","../src/internal/registry.ts","../src/internal/telemetry.ts","../src/internal/dispatcher.ts","../src/internal/to-json-schema.ts","../src/internal/tool-injector.ts","../src/handoff.ts","../src/index.ts"],"names":["z","normalizeHandoffs","buildHandoffTool","dispatchHandoff","createChainState"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Public types for `Agent.create({ handoffs })` + `Handoff.create()` +\n * `Agent.handoffTo()` (Adoption Roadmap #4; ADRs D214-D229).\n *\n * Pattern: handoff-as-tool. Each handoff destination becomes a synthetic\n * `transfer_to_<receiver>` function tool exposed to the LLM. Runtime\n * intercepts the tool call and routes the next turn to the receiver.\n *\n * T4.1 follow-up (cycle #4 closed): `HandoffDescriptor` + its leaf-friendly\n * sibling types now live in `./handoff-descriptor.ts` (generic over\n * `TAgent`). This module re-exports the leaf types pinned to `SDKAgent`,\n * keeps the runtime error classes, and removes the back-edge to `agent.ts`.\n *\n * @public\n */\n\nimport type { SDKAgent } from \"@theokit/sdk\";\nimport type { ZodType } from \"zod\";\nimport type {\n HandoffContext,\n HandoffDescriptor as HandoffDescriptorGeneric,\n HandoffHistory,\n HandoffOptions,\n HandoffResult,\n} from \"./handoff-descriptor.js\";\n\nexport type { HandoffContext, HandoffHistory, HandoffOptions, HandoffResult };\n\n/**\n * `HandoffDescriptor` pinned to `SDKAgent` — back-compat shape for callers\n * that imported `import type { HandoffDescriptor } from \"@theokit/sdk\"`\n * before T4.1 follow-up.\n *\n * @public\n */\nexport type HandoffDescriptor<TInput extends ZodType = ZodType> = HandoffDescriptorGeneric<\n TInput,\n SDKAgent\n>;\n\n/** Throw when handoff depth exceeds `maxHandoffDepth` (default 5; D218). */\nexport class HandoffLoopError extends Error {\n override readonly name = \"HandoffLoopError\";\n readonly depth: number;\n readonly chain: ReadonlyArray<string>;\n constructor(depth: number, chain: ReadonlyArray<string>) {\n super(\n `Handoff loop exceeded max depth ${depth}. Chain: ${chain.join(\" -> \")}. ` +\n `Use Agent.create({ maxHandoffDepth: N }) to raise the cap.`,\n );\n this.depth = depth;\n this.chain = chain;\n }\n}\n\n/** Throw when the same (sender, receiver) pair invoked twice in one send() (D221). */\nexport class HandoffPairLoopError extends Error {\n override readonly name = \"HandoffPairLoopError\";\n readonly senderAgentId: string;\n readonly receiverAgentId: string;\n constructor(senderAgentId: string, receiverAgentId: string) {\n super(\n `Handoff loop: ${senderAgentId} -> ${receiverAgentId} already invoked in this send() call. ` +\n `Likely a ping-pong loop; revisit your handoff conditions.`,\n );\n this.senderAgentId = senderAgentId;\n this.receiverAgentId = receiverAgentId;\n }\n}\n\n/** Throw when an agent's `handoffs[]` includes a self-reference (EC-6). */\nexport class HandoffSelfReferenceError extends Error {\n override readonly name = \"HandoffSelfReferenceError\";\n readonly agentId: string;\n constructor(agentId: string) {\n super(\n `Agent \"${agentId}\" has a self-reference in its handoffs[]. ` +\n `Self-handoff causes infinite recursion; introduce a sibling agent for re-entry.`,\n );\n this.agentId = agentId;\n }\n}\n\n/** Throw when receiver is disposed at dispatch time (EC-5). */\nexport class HandoffReceiverDisposedError extends Error {\n override readonly name = \"HandoffReceiverDisposedError\";\n readonly receiverAgentId: string;\n constructor(receiverAgentId: string) {\n super(\n `Handoff target agent \"${receiverAgentId}\" is disposed. ` +\n `Don't dispose receivers while their parent is still active.`,\n );\n this.receiverAgentId = receiverAgentId;\n }\n}\n\n/** Throw when two handoffs in the same parent collide on tool name (D215). */\nexport class HandoffNameCollisionError extends Error {\n override readonly name = \"HandoffNameCollisionError\";\n readonly conflictingName: string;\n constructor(conflictingName: string) {\n super(\n `Two handoffs share the same tool name \"${conflictingName}\". ` +\n `Set { toolName } on at least one of them to disambiguate.`,\n );\n this.conflictingName = conflictingName;\n }\n}\n","/**\n * Handoff registry — pure state container per `Agent` instance.\n *\n * Holds the active dispatch chain (for depth + pair tracking) across the\n * lifetime of a single `agent.send()` call. Cleared between calls.\n *\n * @internal\n */\n\nimport { HandoffLoopError, HandoffPairLoopError } from \"../types/handoff.js\";\n\nexport interface HandoffChainState {\n /** Ordered chain of agentIds traversed so far (oldest first). */\n readonly chain: string[];\n /** Set of \"<sender>-><receiver>\" keys for pair-level loop detection (D221). */\n readonly seenPairs: Set<string>;\n /** Caller-supplied max depth (D218). */\n readonly maxDepth: number;\n}\n\nexport function createChainState(rootAgentId: string, maxDepth: number): HandoffChainState {\n return {\n chain: [rootAgentId],\n seenPairs: new Set(),\n maxDepth,\n };\n}\n\n/**\n * Record a handoff hop. Throws on depth-exceed (D218) or pair-loop (D221).\n * Mutates the state in place.\n */\nexport function recordHop(\n state: HandoffChainState,\n senderAgentId: string,\n receiverAgentId: string,\n): void {\n const pairKey = `${senderAgentId}->${receiverAgentId}`;\n if (state.seenPairs.has(pairKey)) {\n throw new HandoffPairLoopError(senderAgentId, receiverAgentId);\n }\n state.seenPairs.add(pairKey);\n state.chain.push(receiverAgentId);\n // chain.length = nodes; depth = hops = chain.length - 1.\n const depth = state.chain.length - 1;\n if (depth > state.maxDepth) {\n throw new HandoffLoopError(state.maxDepth, [...state.chain]);\n }\n}\n\nexport function currentDepth(state: HandoffChainState): number {\n return state.chain.length - 1;\n}\n","/**\n * D220 — Lazy-loaded OTel `handoff.transfer` span emitter.\n *\n * @internal\n */\n\n// Inline tracer-loader (same workaround as @theokit/sdk-cache/internal/telemetry.ts):\n// rollup-plugin-dts emits incomplete index.d.ts for newly-modified internal/ barrels\n// in @theokit/sdk. Runtime via the sub-path works; TypeScript users hit TS2305.\n// Inlining keeps sdk-handoff self-contained for the (small) observability hook.\nimport { createRequire } from \"node:module\";\n\ninterface SpanLike {\n setAttribute(key: string, value: string | number | boolean): SpanLike;\n end(): void;\n}\n\nconst _NOOP_SPAN: SpanLike = {\n setAttribute: () => _NOOP_SPAN,\n end: () => undefined,\n};\n\ninterface TracerLike {\n startSpan(\n name: string,\n options?: { attributes?: Record<string, string | number | boolean> },\n ): SpanLike;\n}\n\ninterface TracerCacheEntry {\n tracer: TracerLike | null;\n}\nconst tracerCache = new Map<string, TracerCacheEntry>();\n\nfunction getTracer(name: string, version = \"1.0.0\"): TracerLike | undefined {\n const cached = tracerCache.get(name);\n if (cached !== undefined) return cached.tracer ?? undefined;\n try {\n const r = createRequire(import.meta.url);\n const otel = r(\"@opentelemetry/api\") as {\n trace?: { getTracer: (n: string, v?: string) => TracerLike };\n };\n if (otel.trace?.getTracer === undefined) {\n tracerCache.set(name, { tracer: null });\n return undefined;\n }\n const tracer = otel.trace.getTracer(name, version);\n tracerCache.set(name, { tracer });\n return tracer;\n } catch {\n tracerCache.set(name, { tracer: null });\n return undefined;\n }\n}\n\nfunction resetTracerCacheForTests(): void {\n tracerCache.clear();\n}\n\nconst TRACER_NAME = \"theokit-sdk-handoff\";\n\ninterface HandoffSpanHandle {\n setAttribute(key: string, value: string | number | boolean): void;\n end(): void;\n}\n\nconst NOOP: HandoffSpanHandle = { setAttribute: () => undefined, end: () => undefined };\n\nfunction safe<T>(fn: () => T, fallback: T): T {\n try {\n return fn();\n } catch {\n return fallback;\n }\n}\n\nexport function startHandoffSpan(attrs: {\n from: string;\n to: string;\n reason: string;\n depth: number;\n toolName: string;\n}): HandoffSpanHandle {\n const tracer = getTracer(TRACER_NAME);\n if (tracer === undefined) return NOOP;\n const span: SpanLike | undefined = safe(\n () =>\n tracer.startSpan(\"handoff.transfer\", {\n attributes: {\n \"handoff.from\": attrs.from,\n \"handoff.to\": attrs.to,\n \"handoff.reason\": attrs.reason,\n \"handoff.depth\": attrs.depth,\n \"handoff.tool_name\": attrs.toolName,\n },\n }),\n undefined,\n );\n if (span === undefined) return NOOP;\n return {\n setAttribute: (k, v) => safe(() => span.setAttribute(k, v), undefined),\n end: () => safe(() => span.end(), undefined),\n };\n}\n\n/** Test-only — reset cached OTel handle. */\nfunction __resetHandoffOtelCacheForTests(): void {\n resetTracerCacheForTests();\n}\n","/**\n * Handoff dispatch orchestration.\n *\n * Pragmatic v1: when a handoff fires, the sender calls `receiver.send()`\n * with the (optionally filtered) history. The receiver's reply is returned\n * to the sender, which captures it as the answer to the user's question.\n *\n * NOTE: this is NOT pure peer-to-peer (the sender stays on the call stack\n * until the receiver returns). Pure intercept-and-swap requires deeper\n * agent-loop refactor; deferred to v2. v1 still validates the user-facing\n * value: \"agent A reasoned about routing, agent B answered.\"\n *\n * @internal\n */\n\nimport type { SDKAgent } from \"@theokit/sdk\";\nimport { z } from \"zod\";\nimport type {\n HandoffContext,\n HandoffDescriptor,\n HandoffHistory,\n HandoffResult,\n} from \"../types/handoff.js\";\nimport { HandoffReceiverDisposedError } from \"../types/handoff.js\";\nimport { type HandoffChainState, recordHop } from \"./registry.js\";\nimport { startHandoffSpan } from \"./telemetry.js\";\n\n/**\n * EC-2 / D228 — `safeFilter` wraps `inputFilter`. On exception, falls back\n * to the un-filtered history and warns to stderr once per process.\n */\nlet warnedFilterOnce = false;\nasync function safeFilter(\n filter: ((h: HandoffHistory) => HandoffHistory | Promise<HandoffHistory>) | undefined,\n history: HandoffHistory,\n): Promise<HandoffHistory> {\n if (filter === undefined) return history;\n try {\n const result = filter(history);\n return result instanceof Promise ? await result : result;\n } catch (err) {\n if (!warnedFilterOnce) {\n warnedFilterOnce = true;\n process.stderr.write(\n `[handoff] inputFilter threw, falling back to full history: ${err instanceof Error ? err.message : String(err)}\\n`,\n );\n }\n return history;\n }\n}\n\n/**\n * EC-4 / D229 — parse the LLM-provided JSON args. Returns undefined when\n * no `inputType` set; returns parsed value otherwise (default to `{}` on\n * empty/null input before Zod refinements).\n */\nfunction parseHandoffInput(descriptor: HandoffDescriptor, raw: unknown): unknown {\n const inputType = descriptor.options.inputType;\n if (inputType === undefined) return undefined;\n const candidate = raw === null || raw === undefined ? {} : raw;\n return inputType.parse(candidate);\n}\n\nfunction isAgentDisposed(agent: SDKAgent): boolean {\n // SDKAgent doesn't expose `disposed` publicly; check via duck-typing on\n // a known internal flag. Safe fallback: if we can't tell, assume alive.\n const maybe = agent as unknown as { disposed?: boolean };\n return maybe.disposed === true;\n}\n\n/**\n * Run a single handoff hop. Returns the receiver's reply text.\n *\n * Algorithm:\n * 1. EC-5: refuse if receiver disposed.\n * 2. Build HandoffContext.\n * 3. Check isEnabled() — if false, refuse with a clear error message.\n * 4. Parse inputType (D229).\n * 5. Run onHandoff(ctx, parsed) — throw aborts (D227).\n * 6. Apply inputFilter (safeFilter — D228).\n * 7. Record hop in chain state (depth + pair guards).\n * 8. Open OTel span (D220).\n * 9. Receiver: build the user-facing message and `await receiver.send(msg).then(wait)`.\n * 10. Close span + return reply.\n */\nasync function assertHandoffEnabled(\n descriptor: HandoffDescriptor,\n ctx: HandoffContext,\n receiverAgentId: string,\n): Promise<void> {\n const opt = descriptor.options.isEnabled;\n let enabled = true;\n if (typeof opt === \"boolean\") enabled = opt;\n else if (typeof opt === \"function\") {\n const r = opt(ctx);\n enabled = r instanceof Promise ? await r : r;\n }\n if (!enabled) {\n throw new Error(`Handoff to ${receiverAgentId} is disabled (isEnabled returned false)`);\n }\n}\n\nfunction parseAndValidate(descriptor: HandoffDescriptor, rawInputJson: unknown): unknown {\n try {\n return parseHandoffInput(descriptor, rawInputJson);\n } catch (err) {\n const detail =\n err instanceof z.ZodError\n ? (err.issues[0]?.message ?? \"schema_invalid\")\n : err instanceof Error\n ? err.message\n : String(err);\n throw new Error(`Handoff input validation failed: ${detail}`);\n }\n}\n\nasync function runOnHandoff(\n descriptor: HandoffDescriptor,\n ctx: HandoffContext,\n parsedInput: unknown,\n): Promise<void> {\n const onHandoff = descriptor.options.onHandoff;\n if (onHandoff === undefined) return;\n // biome-ignore lint/suspicious/noExplicitAny: parsedInput is typed unknown by design.\n const result = onHandoff(ctx, parsedInput as any);\n if (result instanceof Promise) await result;\n}\n\nfunction extractUserText(content: unknown): string | undefined {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return undefined;\n const text = content\n .filter((c): c is { type: \"text\"; text: string } => (c as { type?: string })?.type === \"text\")\n .map((c) => c.text)\n .join(\"\\n\");\n return text.length > 0 ? text : undefined;\n}\n\nfunction extractLastUserMessage(history: HandoffHistory, senderAgentId: string): string {\n for (let i = history.messages.length - 1; i >= 0; i -= 1) {\n const m = history.messages[i] as {\n type?: string;\n message?: { role?: string; content?: unknown };\n };\n if (m?.type !== \"user\" || m.message?.role !== \"user\") continue;\n const text = extractUserText(m.message.content);\n if (text !== undefined) return text;\n }\n return `(Handoff from ${senderAgentId} — no prior user message in history.)`;\n}\n\nexport async function dispatchHandoff(args: {\n descriptor: HandoffDescriptor;\n senderAgentId: string;\n chainState: HandoffChainState;\n rawInputJson: unknown;\n /** The conversation so far (history wrapper). v1: just the LAST user message. */\n history: HandoffHistory;\n /** Override the message text sent to the receiver. Used by `Agent.handoffTo` imperative. */\n messageOverride?: string;\n}): Promise<{ reply: string; result: HandoffResult }> {\n const { descriptor, senderAgentId, chainState, rawInputJson, history, messageOverride } = args;\n const receiver = descriptor.target;\n\n if (isAgentDisposed(receiver)) {\n throw new HandoffReceiverDisposedError(receiver.agentId);\n }\n\n const depthAfterThisHop = chainState.chain.length;\n const ctx: HandoffContext = {\n senderAgentId,\n receiverAgentId: receiver.agentId,\n currentDepth: depthAfterThisHop,\n chain: [...chainState.chain, receiver.agentId],\n };\n\n await assertHandoffEnabled(descriptor, ctx, receiver.agentId);\n const parsedInput = parseAndValidate(descriptor, rawInputJson);\n await runOnHandoff(descriptor, ctx, parsedInput);\n\n // Filter history (D228 — resilient)\n const filteredHistory = await safeFilter(descriptor.options.inputFilter, history);\n\n // Record hop — may throw HandoffLoopError or HandoffPairLoopError\n recordHop(chainState, senderAgentId, receiver.agentId);\n\n const lastUserMessage = messageOverride ?? extractLastUserMessage(filteredHistory, senderAgentId);\n const reason = extractReason(parsedInput);\n\n const span = startHandoffSpan({\n from: senderAgentId,\n to: receiver.agentId,\n reason,\n depth: depthAfterThisHop,\n toolName: descriptor.resolvedToolName,\n });\n\n try {\n const run = await receiver.send(lastUserMessage);\n const result = await run.wait();\n const reply = buildReply(result, receiver.agentId);\n return {\n reply,\n result: {\n from: senderAgentId,\n to: receiver.agentId,\n depth: depthAfterThisHop,\n toolName: descriptor.resolvedToolName,\n ...(reason !== \"\" ? { reasonFromLlm: reason } : {}),\n },\n };\n } finally {\n span.end();\n }\n}\n\nfunction extractReason(parsedInput: unknown): string {\n if (typeof parsedInput !== \"object\" || parsedInput === null) return \"\";\n if (!(\"reason\" in parsedInput)) return \"\";\n return String((parsedInput as { reason: unknown }).reason ?? \"\");\n}\n\nfunction buildReply(\n result: { status: string; result?: string; error?: { message: string } },\n receiverAgentId: string,\n): string {\n if (result.status === \"finished\" && result.result !== undefined) return result.result;\n const suffix = result.error !== undefined ? `: ${result.error.message}` : \"\";\n return `(Handoff target ${receiverAgentId} returned status=${result.status}${suffix})`;\n}\n","/**\n * Zod v4 → JSON Schema adapter for sdk-handoff.\n *\n * Uses Zod v4's native `z.toJSONSchema()` directly. v3 fallback removed\n * after zod-v4-migration plan (ADR D2).\n *\n * @internal\n */\n\nimport { toJSONSchema } from \"zod\";\n\ninterface ToJsonSchemaOptions {\n /** `\"any\"` keeps transforms/refinements as `{}` (loose). Default: `\"any\"`. */\n unrepresentable?: \"any\" | \"throw\";\n}\n\n/**\n * Convert a Zod schema to a JSON Schema object via Zod v4 native.\n *\n * @internal\n */\nexport function toJsonSchema(\n schema: unknown,\n options: ToJsonSchemaOptions = { unrepresentable: \"any\" },\n): Record<string, unknown> {\n // The schema param is `unknown` (callers pass `T extends ZodType` generics that\n // don't structurally satisfy Zod v4's `$ZodType`); cast to the exact parameter\n // type `toJSONSchema` expects rather than `any` — any z.* schema IS valid at runtime.\n return toJSONSchema(schema as Parameters<typeof toJSONSchema>[0], options) as Record<\n string,\n unknown\n >;\n}\n","/**\n * Convert `handoffs[]` entries into synthetic `transfer_to_<receiver>` tools\n * for injection into the agent's tool registry at construction time.\n *\n * The synthesized tool's handler calls `dispatchHandoff` internally and\n * returns the receiver's reply as `tool_result`. v1 trade-off documented\n * in dispatcher.ts.\n *\n * @internal\n */\n\nimport type { CustomTool, SDKAgent } from \"@theokit/sdk\";\nimport { z } from \"zod\";\nimport {\n type HandoffDescriptor,\n HandoffNameCollisionError,\n HandoffSelfReferenceError,\n} from \"../types/handoff.js\";\nimport { dispatchHandoff } from \"./dispatcher.js\";\nimport { createChainState } from \"./registry.js\";\nimport { toJsonSchema } from \"./to-json-schema.js\";\n\ninterface NormalizedHandoff {\n descriptor: HandoffDescriptor;\n}\n\n/**\n * Normalize each `handoffs[]` entry to a `HandoffDescriptor`. Raw `SDKAgent`\n * instances are auto-wrapped with default options. Validates:\n * - EC-6: no self-reference (would cause infinite recursion).\n * - D215: resolved tool names must be unique.\n */\nexport function normalizeHandoffs(\n parentAgentId: string,\n entries: ReadonlyArray<SDKAgent | HandoffDescriptor>,\n): NormalizedHandoff[] {\n if (entries.length === 0) return [];\n const out: NormalizedHandoff[] = [];\n const seenNames = new Set<string>();\n for (const entry of entries) {\n // Detect raw Agent vs HandoffDescriptor by presence of `.target`.\n const isDescriptor =\n typeof entry === \"object\" &&\n entry !== null &&\n \"target\" in entry &&\n \"options\" in entry &&\n \"resolvedToolName\" in entry;\n const descriptor = isDescriptor ? (entry as HandoffDescriptor) : autoWrap(entry as SDKAgent);\n if (descriptor.target.agentId === parentAgentId) {\n throw new HandoffSelfReferenceError(parentAgentId);\n }\n const name = descriptor.resolvedToolName;\n if (seenNames.has(name)) {\n throw new HandoffNameCollisionError(name);\n }\n seenNames.add(name);\n out.push({ descriptor });\n }\n return out;\n}\n\nfunction autoWrap(agent: SDKAgent): HandoffDescriptor {\n const name = resolveTargetName(agent);\n return {\n target: agent,\n options: {},\n resolvedToolName: `transfer_to_${name}`,\n };\n}\n\nfunction resolveTargetName(agent: SDKAgent): string {\n // Prefer a `name` field if exposed; fall back to a short agentId slug.\n const candidate = (agent as unknown as { name?: string }).name ?? agent.agentId ?? \"anonymous\";\n return slugify(candidate);\n}\n\nfunction slugify(input: string): string {\n return (\n input\n .replace(/^agent-/i, \"\")\n .replace(/[^a-zA-Z0-9_-]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 64) || \"anonymous\"\n );\n}\n\n/**\n * Build a `CustomTool` for one handoff descriptor. The handler dispatches\n * the handoff using a fresh chain state per `send()`-level invocation.\n *\n * NOTE: this v1 builds a NEW chain state per tool invocation. Pure\n * cross-tool depth tracking within one send() requires per-Agent context\n * — deferred. The single-flight pair guard catches direct ping-pong even\n * without cross-invocation chain (since each call wraps the same depth\n * counter from 1).\n */\nexport function buildHandoffTool(\n parentAgentId: string,\n descriptor: HandoffDescriptor,\n maxHandoffDepth: number,\n): CustomTool {\n const description =\n descriptor.options.toolDescription ??\n `Transfer the conversation to the ${descriptor.target.agentId} agent. ` +\n `Use this when the user's request matches their specialty.`;\n\n const inputZod =\n descriptor.options.inputType ??\n z.object({\n reason: z.string().optional().describe(\"Brief reason for the transfer (one short sentence).\"),\n });\n // CustomTool.inputSchema expects a JSON schema (Record<string, unknown>),\n // not the raw Zod type. Convert lazily so we don't fail when Zod is missing.\n // Universal Zod 3+4 conversion (feature-detects native v4, falls back to lib on v3).\n const inputSchema = toJsonSchema(inputZod);\n\n return {\n name: descriptor.resolvedToolName,\n description,\n inputSchema,\n handler: async (input: unknown): Promise<string> => {\n const chainState = createChainState(parentAgentId, maxHandoffDepth);\n try {\n const { reply, result } = await dispatchHandoff({\n descriptor,\n senderAgentId: parentAgentId,\n chainState,\n rawInputJson: input,\n history: { messages: [] }, // v1: history replay deferred\n });\n return JSON.stringify({\n ok: true,\n transferred_to: result.to,\n depth: result.depth,\n reply,\n });\n } catch (err) {\n return JSON.stringify({\n ok: false,\n error: err instanceof Error ? err.name : \"HandoffError\",\n message: err instanceof Error ? err.message : String(err),\n });\n }\n },\n };\n}\n","/**\n * Public `Handoff` class — factory for handoff descriptors (Adoption\n * Roadmap #4; ADRs D214-D229).\n *\n * Usage:\n *\n * import { Agent, Handoff } from \"@theokit/sdk\";\n *\n * const billing = await Agent.create({\n * name: \"billing\",\n * systemPrompt: \"You handle billing questions.\",\n * model: { id: \"openai/gpt-4o-mini\" },\n * apiKey: process.env.OPENROUTER_API_KEY,\n * });\n *\n * const triage = await Agent.create({\n * name: \"triage\",\n * systemPrompt: \"Classify the user's intent and transfer to the right specialist.\",\n * model: { id: \"openai/gpt-4o-mini\" },\n * apiKey: process.env.OPENROUTER_API_KEY,\n * handoffs: [\n * billing, // auto-wrapped as Handoff.create(billing)\n * Handoff.create(supportAgent, { inputFilter: redactCreditCards }),\n * ],\n * });\n *\n * @public\n */\n\nimport { Plugin, type PluginContext, type SDKAgent } from \"@theokit/sdk\";\nimport type { ZodType } from \"zod\";\nimport type { HandoffDescriptor, HandoffOptions } from \"./types/handoff.js\";\n\n/** Recommended system-prompt prefix for senders (D215 / EC-13). */\nexport const RECOMMENDED_HANDOFF_PROMPT_PREFIX = `\nYou can transfer the conversation to other specialist agents when their\nexpertise matches the user's request. Invoke the appropriate\ntransfer_to_<agent> tool with a short reason. The receiving agent will\ntake over the conversation; do not duplicate their work.\n`.trim();\n\nexport class Handoff {\n private constructor() {}\n\n /**\n * Build a `HandoffDescriptor` for a target agent. Wrap with custom options\n * (filter / inputType / callback / whitelist / etc); pass to\n * `Agent.create({ handoffs: [...] })`.\n *\n * Raw `SDKAgent` instances in `handoffs[]` are auto-wrapped by the runtime\n * — call `Handoff.create()` explicitly only when you need to customize.\n */\n static create<TInput extends ZodType = ZodType>(\n target: SDKAgent,\n options: HandoffOptions<TInput> = {} as HandoffOptions<TInput>,\n ): HandoffDescriptor<TInput> {\n if (target === undefined || target === null) {\n throw new Error(\"Handoff.create: target agent is required\");\n }\n if (typeof target.send !== \"function\") {\n throw new Error(\"Handoff.create: target must be an SDKAgent instance\");\n }\n const resolvedToolName = options.toolName ?? `transfer_to_${slugifyName(target)}`;\n return {\n target,\n options,\n resolvedToolName,\n };\n }\n\n /**\n * Plugin-based wiring (SDK 2.x preferred). Wraps `targets` in synthetic\n * `transfer_to_<receiver>` tools and registers them via `ctx.registerTool`\n * at agent init time.\n *\n * Replaces the legacy `Agent.create({ handoffs: [...] })` option (which is\n * still supported as a transitional convenience while sdk-handoff is\n * installed — the framework lazy-imports the tool-injector at runtime).\n *\n * @example\n * const support = await Agent.create({\n * name: \"support\",\n * plugins: [Handoff.asPlugin({ parentAgentId: \"support\", targets: [billing] })],\n * });\n */\n static asPlugin(opts: AsPluginOptions): Plugin {\n const parent = opts.parentAgentId ?? \"anonymous\";\n const maxDepth = opts.maxHandoffDepth ?? 5;\n const targets = opts.targets;\n return Plugin.create({\n name: `handoff-${parent}`,\n version: \"1.0.0\",\n kind: \"general\" as const,\n register(ctx: PluginContext): void {\n if (maxDepth === 0 || targets.length === 0) return;\n // Lazy import — keeps cold path lean if asPlugin is constructed but\n // its register hook is never invoked (e.g., disabled by config).\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n void (async () => {\n const { normalizeHandoffs, buildHandoffTool } = await import(\n \"./internal/tool-injector.js\"\n );\n const normalized = normalizeHandoffs(parent, targets);\n for (const { descriptor } of normalized) {\n ctx.registerTool(buildHandoffTool(parent, descriptor, maxDepth));\n }\n })();\n },\n });\n }\n}\n\n/**\n * Options for `Handoff.asPlugin()`. `parentAgentId` defaults to `\"anonymous\"`;\n * pass the host agent's `name` for correct loop detection in chains.\n */\nexport interface AsPluginOptions {\n readonly targets: ReadonlyArray<SDKAgent | HandoffDescriptor>;\n readonly parentAgentId?: string;\n readonly maxHandoffDepth?: number;\n}\n\nfunction slugifyName(agent: SDKAgent): string {\n const candidate = (agent as unknown as { name?: string }).name ?? agent.agentId ?? \"anonymous\";\n return (\n candidate\n .replace(/^agent-/i, \"\")\n .replace(/[^a-zA-Z0-9_-]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 64) || \"anonymous\"\n );\n}\n\n/**\n * Imperative escape hatch (D225). Useful for tests / programmatic flows\n * that need deterministic handoff without LLM routing.\n *\n * NOTE: this is a STANDALONE helper rather than a method on `SDKAgent`\n * to avoid invasive refactor of the agent class. Behavior is identical\n * to invoking the corresponding synthetic tool would be.\n */\nexport async function handoffTo(\n sender: SDKAgent,\n target: SDKAgent,\n message: string,\n options: HandoffOptions = {},\n): Promise<string> {\n const descriptor = Handoff.create(target, options);\n // Lazy import to avoid loading internal module unless this is called.\n const { dispatchHandoff } = await import(\"./internal/dispatcher.js\");\n const { createChainState } = await import(\"./internal/registry.js\");\n const chainState = createChainState(sender.agentId, 5);\n const { reply } = await dispatchHandoff({\n descriptor,\n senderAgentId: sender.agentId,\n chainState,\n rawInputJson: undefined,\n history: { messages: [] },\n messageOverride: message,\n });\n return reply;\n}\n","/**\n * `@theokit/sdk-handoff` — inter-agent dispatch for `@theokit/sdk`.\n *\n * Extracted from `@theokit/sdk@1.7.0` as part of the SDK 2.0 package split\n * (Phase 4 / T4.1). Integrates with `Agent` via the Plugin protocol —\n * `Handoff.asPlugin({ targets })` returns a `Plugin` consumed by\n * `Agent.create({ plugins: [...] })`.\n *\n * @packageDocumentation\n */\n\nexport {\n type AsPluginOptions,\n Handoff,\n handoffTo,\n RECOMMENDED_HANDOFF_PROMPT_PREFIX,\n} from \"./handoff.js\";\nexport type { HandoffDescriptor, HandoffOptions } from \"./types/handoff.js\";\nexport {\n HandoffLoopError,\n HandoffNameCollisionError,\n HandoffPairLoopError,\n HandoffReceiverDisposedError,\n HandoffSelfReferenceError,\n} from \"./types/handoff.js\";\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/handoff.ts","../../src/internal/registry.ts","../../src/internal/telemetry.ts","../../src/internal/dispatcher.ts","../../src/internal/to-json-schema.ts","../../src/internal/tool-injector.ts"],"names":["createRequire","z","toJSONSchema"],"mappings":"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","file":"tool-injector.cjs","sourcesContent":["/**\n * Public types for `Agent.create({ handoffs })` + `Handoff.create()` +\n * `Agent.handoffTo()` (Adoption Roadmap #4; ADRs D214-D229).\n *\n * Pattern: handoff-as-tool. Each handoff destination becomes a synthetic\n * `transfer_to_<receiver>` function tool exposed to the LLM. Runtime\n * intercepts the tool call and routes the next turn to the receiver.\n *\n * T4.1 follow-up (cycle #4 closed): `HandoffDescriptor` + its leaf-friendly\n * sibling types now live in `./handoff-descriptor.ts` (generic over\n * `TAgent`). This module re-exports the leaf types pinned to `SDKAgent`,\n * keeps the runtime error classes, and removes the back-edge to `agent.ts`.\n *\n * @public\n */\n\nimport type { SDKAgent } from \"@theokit/sdk\";\nimport type { ZodType } from \"zod\";\nimport type {\n HandoffContext,\n HandoffDescriptor as HandoffDescriptorGeneric,\n HandoffHistory,\n HandoffOptions,\n HandoffResult,\n} from \"./handoff-descriptor.js\";\n\nexport type { HandoffContext, HandoffHistory, HandoffOptions, HandoffResult };\n\n/**\n * `HandoffDescriptor` pinned to `SDKAgent` — back-compat shape for callers\n * that imported `import type { HandoffDescriptor } from \"@theokit/sdk\"`\n * before T4.1 follow-up.\n *\n * @public\n */\nexport type HandoffDescriptor<TInput extends ZodType = ZodType> = HandoffDescriptorGeneric<\n TInput,\n SDKAgent\n>;\n\n/** Throw when handoff depth exceeds `maxHandoffDepth` (default 5; D218). */\nexport class HandoffLoopError extends Error {\n override readonly name = \"HandoffLoopError\";\n readonly depth: number;\n readonly chain: ReadonlyArray<string>;\n constructor(depth: number, chain: ReadonlyArray<string>) {\n super(\n `Handoff loop exceeded max depth ${depth}. Chain: ${chain.join(\" -> \")}. ` +\n `Use Agent.create({ maxHandoffDepth: N }) to raise the cap.`,\n );\n this.depth = depth;\n this.chain = chain;\n }\n}\n\n/** Throw when the same (sender, receiver) pair invoked twice in one send() (D221). */\nexport class HandoffPairLoopError extends Error {\n override readonly name = \"HandoffPairLoopError\";\n readonly senderAgentId: string;\n readonly receiverAgentId: string;\n constructor(senderAgentId: string, receiverAgentId: string) {\n super(\n `Handoff loop: ${senderAgentId} -> ${receiverAgentId} already invoked in this send() call. ` +\n `Likely a ping-pong loop; revisit your handoff conditions.`,\n );\n this.senderAgentId = senderAgentId;\n this.receiverAgentId = receiverAgentId;\n }\n}\n\n/** Throw when an agent's `handoffs[]` includes a self-reference (EC-6). */\nexport class HandoffSelfReferenceError extends Error {\n override readonly name = \"HandoffSelfReferenceError\";\n readonly agentId: string;\n constructor(agentId: string) {\n super(\n `Agent \"${agentId}\" has a self-reference in its handoffs[]. ` +\n `Self-handoff causes infinite recursion; introduce a sibling agent for re-entry.`,\n );\n this.agentId = agentId;\n }\n}\n\n/** Throw when receiver is disposed at dispatch time (EC-5). */\nexport class HandoffReceiverDisposedError extends Error {\n override readonly name = \"HandoffReceiverDisposedError\";\n readonly receiverAgentId: string;\n constructor(receiverAgentId: string) {\n super(\n `Handoff target agent \"${receiverAgentId}\" is disposed. ` +\n `Don't dispose receivers while their parent is still active.`,\n );\n this.receiverAgentId = receiverAgentId;\n }\n}\n\n/** Throw when two handoffs in the same parent collide on tool name (D215). */\nexport class HandoffNameCollisionError extends Error {\n override readonly name = \"HandoffNameCollisionError\";\n readonly conflictingName: string;\n constructor(conflictingName: string) {\n super(\n `Two handoffs share the same tool name \"${conflictingName}\". ` +\n `Set { toolName } on at least one of them to disambiguate.`,\n );\n this.conflictingName = conflictingName;\n }\n}\n","/**\n * Handoff registry — pure state container per `Agent` instance.\n *\n * Holds the active dispatch chain (for depth + pair tracking) across the\n * lifetime of a single `agent.send()` call. Cleared between calls.\n *\n * @internal\n */\n\nimport { HandoffLoopError, HandoffPairLoopError } from \"../types/handoff.js\";\n\nexport interface HandoffChainState {\n /** Ordered chain of agentIds traversed so far (oldest first). */\n readonly chain: string[];\n /** Set of \"<sender>-><receiver>\" keys for pair-level loop detection (D221). */\n readonly seenPairs: Set<string>;\n /** Caller-supplied max depth (D218). */\n readonly maxDepth: number;\n}\n\nexport function createChainState(rootAgentId: string, maxDepth: number): HandoffChainState {\n return {\n chain: [rootAgentId],\n seenPairs: new Set(),\n maxDepth,\n };\n}\n\n/**\n * Record a handoff hop. Throws on depth-exceed (D218) or pair-loop (D221).\n * Mutates the state in place.\n */\nexport function recordHop(\n state: HandoffChainState,\n senderAgentId: string,\n receiverAgentId: string,\n): void {\n const pairKey = `${senderAgentId}->${receiverAgentId}`;\n if (state.seenPairs.has(pairKey)) {\n throw new HandoffPairLoopError(senderAgentId, receiverAgentId);\n }\n state.seenPairs.add(pairKey);\n state.chain.push(receiverAgentId);\n // chain.length = nodes; depth = hops = chain.length - 1.\n const depth = state.chain.length - 1;\n if (depth > state.maxDepth) {\n throw new HandoffLoopError(state.maxDepth, [...state.chain]);\n }\n}\n\nexport function currentDepth(state: HandoffChainState): number {\n return state.chain.length - 1;\n}\n","/**\n * D220 — Lazy-loaded OTel `handoff.transfer` span emitter.\n *\n * @internal\n */\n\n// Inline tracer-loader (same workaround as @theokit/sdk-cache/internal/telemetry.ts):\n// rollup-plugin-dts emits incomplete index.d.ts for newly-modified internal/ barrels\n// in @theokit/sdk. Runtime via the sub-path works; TypeScript users hit TS2305.\n// Inlining keeps sdk-handoff self-contained for the (small) observability hook.\nimport { createRequire } from \"node:module\";\n\ninterface SpanLike {\n setAttribute(key: string, value: string | number | boolean): SpanLike;\n end(): void;\n}\n\nconst _NOOP_SPAN: SpanLike = {\n setAttribute: () => _NOOP_SPAN,\n end: () => undefined,\n};\n\ninterface TracerLike {\n startSpan(\n name: string,\n options?: { attributes?: Record<string, string | number | boolean> },\n ): SpanLike;\n}\n\ninterface TracerCacheEntry {\n tracer: TracerLike | null;\n}\nconst tracerCache = new Map<string, TracerCacheEntry>();\n\nfunction getTracer(name: string, version = \"1.0.0\"): TracerLike | undefined {\n const cached = tracerCache.get(name);\n if (cached !== undefined) return cached.tracer ?? undefined;\n try {\n const r = createRequire(import.meta.url);\n const otel = r(\"@opentelemetry/api\") as {\n trace?: { getTracer: (n: string, v?: string) => TracerLike };\n };\n if (otel.trace?.getTracer === undefined) {\n tracerCache.set(name, { tracer: null });\n return undefined;\n }\n const tracer = otel.trace.getTracer(name, version);\n tracerCache.set(name, { tracer });\n return tracer;\n } catch {\n tracerCache.set(name, { tracer: null });\n return undefined;\n }\n}\n\nfunction resetTracerCacheForTests(): void {\n tracerCache.clear();\n}\n\nconst TRACER_NAME = \"theokit-sdk-handoff\";\n\ninterface HandoffSpanHandle {\n setAttribute(key: string, value: string | number | boolean): void;\n end(): void;\n}\n\nconst NOOP: HandoffSpanHandle = { setAttribute: () => undefined, end: () => undefined };\n\nfunction safe<T>(fn: () => T, fallback: T): T {\n try {\n return fn();\n } catch {\n return fallback;\n }\n}\n\nexport function startHandoffSpan(attrs: {\n from: string;\n to: string;\n reason: string;\n depth: number;\n toolName: string;\n}): HandoffSpanHandle {\n const tracer = getTracer(TRACER_NAME);\n if (tracer === undefined) return NOOP;\n const span: SpanLike | undefined = safe(\n () =>\n tracer.startSpan(\"handoff.transfer\", {\n attributes: {\n \"handoff.from\": attrs.from,\n \"handoff.to\": attrs.to,\n \"handoff.reason\": attrs.reason,\n \"handoff.depth\": attrs.depth,\n \"handoff.tool_name\": attrs.toolName,\n },\n }),\n undefined,\n );\n if (span === undefined) return NOOP;\n return {\n setAttribute: (k, v) => safe(() => span.setAttribute(k, v), undefined),\n end: () => safe(() => span.end(), undefined),\n };\n}\n\n/** Test-only — reset cached OTel handle. */\nfunction __resetHandoffOtelCacheForTests(): void {\n resetTracerCacheForTests();\n}\n","/**\n * Handoff dispatch orchestration.\n *\n * Pragmatic v1: when a handoff fires, the sender calls `receiver.send()`\n * with the (optionally filtered) history. The receiver's reply is returned\n * to the sender, which captures it as the answer to the user's question.\n *\n * NOTE: this is NOT pure peer-to-peer (the sender stays on the call stack\n * until the receiver returns). Pure intercept-and-swap requires deeper\n * agent-loop refactor; deferred to v2. v1 still validates the user-facing\n * value: \"agent A reasoned about routing, agent B answered.\"\n *\n * @internal\n */\n\nimport type { SDKAgent } from \"@theokit/sdk\";\nimport { z } from \"zod\";\nimport type {\n HandoffContext,\n HandoffDescriptor,\n HandoffHistory,\n HandoffResult,\n} from \"../types/handoff.js\";\nimport { HandoffReceiverDisposedError } from \"../types/handoff.js\";\nimport { type HandoffChainState, recordHop } from \"./registry.js\";\nimport { startHandoffSpan } from \"./telemetry.js\";\n\n/**\n * EC-2 / D228 — `safeFilter` wraps `inputFilter`. On exception, falls back\n * to the un-filtered history and warns to stderr once per process.\n */\nlet warnedFilterOnce = false;\nasync function safeFilter(\n filter: ((h: HandoffHistory) => HandoffHistory | Promise<HandoffHistory>) | undefined,\n history: HandoffHistory,\n): Promise<HandoffHistory> {\n if (filter === undefined) return history;\n try {\n const result = filter(history);\n return result instanceof Promise ? await result : result;\n } catch (err) {\n if (!warnedFilterOnce) {\n warnedFilterOnce = true;\n process.stderr.write(\n `[handoff] inputFilter threw, falling back to full history: ${err instanceof Error ? err.message : String(err)}\\n`,\n );\n }\n return history;\n }\n}\n\n/**\n * EC-4 / D229 — parse the LLM-provided JSON args. Returns undefined when\n * no `inputType` set; returns parsed value otherwise (default to `{}` on\n * empty/null input before Zod refinements).\n */\nfunction parseHandoffInput(descriptor: HandoffDescriptor, raw: unknown): unknown {\n const inputType = descriptor.options.inputType;\n if (inputType === undefined) return undefined;\n const candidate = raw === null || raw === undefined ? {} : raw;\n return inputType.parse(candidate);\n}\n\nfunction isAgentDisposed(agent: SDKAgent): boolean {\n // SDKAgent doesn't expose `disposed` publicly; check via duck-typing on\n // a known internal flag. Safe fallback: if we can't tell, assume alive.\n const maybe = agent as unknown as { disposed?: boolean };\n return maybe.disposed === true;\n}\n\n/**\n * Run a single handoff hop. Returns the receiver's reply text.\n *\n * Algorithm:\n * 1. EC-5: refuse if receiver disposed.\n * 2. Build HandoffContext.\n * 3. Check isEnabled() — if false, refuse with a clear error message.\n * 4. Parse inputType (D229).\n * 5. Run onHandoff(ctx, parsed) — throw aborts (D227).\n * 6. Apply inputFilter (safeFilter — D228).\n * 7. Record hop in chain state (depth + pair guards).\n * 8. Open OTel span (D220).\n * 9. Receiver: build the user-facing message and `await receiver.send(msg).then(wait)`.\n * 10. Close span + return reply.\n */\nasync function assertHandoffEnabled(\n descriptor: HandoffDescriptor,\n ctx: HandoffContext,\n receiverAgentId: string,\n): Promise<void> {\n const opt = descriptor.options.isEnabled;\n let enabled = true;\n if (typeof opt === \"boolean\") enabled = opt;\n else if (typeof opt === \"function\") {\n const r = opt(ctx);\n enabled = r instanceof Promise ? await r : r;\n }\n if (!enabled) {\n throw new Error(`Handoff to ${receiverAgentId} is disabled (isEnabled returned false)`);\n }\n}\n\nfunction parseAndValidate(descriptor: HandoffDescriptor, rawInputJson: unknown): unknown {\n try {\n return parseHandoffInput(descriptor, rawInputJson);\n } catch (err) {\n const detail =\n err instanceof z.ZodError\n ? (err.issues[0]?.message ?? \"schema_invalid\")\n : err instanceof Error\n ? err.message\n : String(err);\n throw new Error(`Handoff input validation failed: ${detail}`);\n }\n}\n\nasync function runOnHandoff(\n descriptor: HandoffDescriptor,\n ctx: HandoffContext,\n parsedInput: unknown,\n): Promise<void> {\n const onHandoff = descriptor.options.onHandoff;\n if (onHandoff === undefined) return;\n // biome-ignore lint/suspicious/noExplicitAny: parsedInput is typed unknown by design.\n const result = onHandoff(ctx, parsedInput as any);\n if (result instanceof Promise) await result;\n}\n\nfunction extractUserText(content: unknown): string | undefined {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return undefined;\n const text = content\n .filter((c): c is { type: \"text\"; text: string } => (c as { type?: string })?.type === \"text\")\n .map((c) => c.text)\n .join(\"\\n\");\n return text.length > 0 ? text : undefined;\n}\n\nfunction extractLastUserMessage(history: HandoffHistory, senderAgentId: string): string {\n for (let i = history.messages.length - 1; i >= 0; i -= 1) {\n const m = history.messages[i] as {\n type?: string;\n message?: { role?: string; content?: unknown };\n };\n if (m?.type !== \"user\" || m.message?.role !== \"user\") continue;\n const text = extractUserText(m.message.content);\n if (text !== undefined) return text;\n }\n return `(Handoff from ${senderAgentId} — no prior user message in history.)`;\n}\n\nexport async function dispatchHandoff(args: {\n descriptor: HandoffDescriptor;\n senderAgentId: string;\n chainState: HandoffChainState;\n rawInputJson: unknown;\n /** The conversation so far (history wrapper). v1: just the LAST user message. */\n history: HandoffHistory;\n /** Override the message text sent to the receiver. Used by `Agent.handoffTo` imperative. */\n messageOverride?: string;\n}): Promise<{ reply: string; result: HandoffResult }> {\n const { descriptor, senderAgentId, chainState, rawInputJson, history, messageOverride } = args;\n const receiver = descriptor.target;\n\n if (isAgentDisposed(receiver)) {\n throw new HandoffReceiverDisposedError(receiver.agentId);\n }\n\n const depthAfterThisHop = chainState.chain.length;\n const ctx: HandoffContext = {\n senderAgentId,\n receiverAgentId: receiver.agentId,\n currentDepth: depthAfterThisHop,\n chain: [...chainState.chain, receiver.agentId],\n };\n\n await assertHandoffEnabled(descriptor, ctx, receiver.agentId);\n const parsedInput = parseAndValidate(descriptor, rawInputJson);\n await runOnHandoff(descriptor, ctx, parsedInput);\n\n // Filter history (D228 — resilient)\n const filteredHistory = await safeFilter(descriptor.options.inputFilter, history);\n\n // Record hop — may throw HandoffLoopError or HandoffPairLoopError\n recordHop(chainState, senderAgentId, receiver.agentId);\n\n const lastUserMessage = messageOverride ?? extractLastUserMessage(filteredHistory, senderAgentId);\n const reason = extractReason(parsedInput);\n\n const span = startHandoffSpan({\n from: senderAgentId,\n to: receiver.agentId,\n reason,\n depth: depthAfterThisHop,\n toolName: descriptor.resolvedToolName,\n });\n\n try {\n const run = await receiver.send(lastUserMessage);\n const result = await run.wait();\n const reply = buildReply(result, receiver.agentId);\n return {\n reply,\n result: {\n from: senderAgentId,\n to: receiver.agentId,\n depth: depthAfterThisHop,\n toolName: descriptor.resolvedToolName,\n ...(reason !== \"\" ? { reasonFromLlm: reason } : {}),\n },\n };\n } finally {\n span.end();\n }\n}\n\nfunction extractReason(parsedInput: unknown): string {\n if (typeof parsedInput !== \"object\" || parsedInput === null) return \"\";\n if (!(\"reason\" in parsedInput)) return \"\";\n return String((parsedInput as { reason: unknown }).reason ?? \"\");\n}\n\nfunction buildReply(\n result: { status: string; result?: string; error?: { message: string } },\n receiverAgentId: string,\n): string {\n if (result.status === \"finished\" && result.result !== undefined) return result.result;\n const suffix = result.error !== undefined ? `: ${result.error.message}` : \"\";\n return `(Handoff target ${receiverAgentId} returned status=${result.status}${suffix})`;\n}\n","/**\n * Zod v4 → JSON Schema adapter for sdk-handoff.\n *\n * Uses Zod v4's native `z.toJSONSchema()` directly. v3 fallback removed\n * after zod-v4-migration plan (ADR D2).\n *\n * @internal\n */\n\nimport { toJSONSchema } from \"zod\";\n\ninterface ToJsonSchemaOptions {\n /** `\"any\"` keeps transforms/refinements as `{}` (loose). Default: `\"any\"`. */\n unrepresentable?: \"any\" | \"throw\";\n}\n\n/**\n * Convert a Zod schema to a JSON Schema object via Zod v4 native.\n *\n * @internal\n */\nexport function toJsonSchema(\n schema: unknown,\n options: ToJsonSchemaOptions = { unrepresentable: \"any\" },\n): Record<string, unknown> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- generic ZodType erasure\n return toJSONSchema(schema as any, options) as Record<string, unknown>;\n}\n","/**\n * Convert `handoffs[]` entries into synthetic `transfer_to_<receiver>` tools\n * for injection into the agent's tool registry at construction time.\n *\n * The synthesized tool's handler calls `dispatchHandoff` internally and\n * returns the receiver's reply as `tool_result`. v1 trade-off documented\n * in dispatcher.ts.\n *\n * @internal\n */\n\nimport type { CustomTool, SDKAgent } from \"@theokit/sdk\";\nimport { z } from \"zod\";\nimport {\n type HandoffDescriptor,\n HandoffNameCollisionError,\n HandoffSelfReferenceError,\n} from \"../types/handoff.js\";\nimport { dispatchHandoff } from \"./dispatcher.js\";\nimport { createChainState } from \"./registry.js\";\nimport { toJsonSchema } from \"./to-json-schema.js\";\n\ninterface NormalizedHandoff {\n descriptor: HandoffDescriptor;\n}\n\n/**\n * Normalize each `handoffs[]` entry to a `HandoffDescriptor`. Raw `SDKAgent`\n * instances are auto-wrapped with default options. Validates:\n * - EC-6: no self-reference (would cause infinite recursion).\n * - D215: resolved tool names must be unique.\n */\nexport function normalizeHandoffs(\n parentAgentId: string,\n entries: ReadonlyArray<SDKAgent | HandoffDescriptor>,\n): NormalizedHandoff[] {\n if (entries.length === 0) return [];\n const out: NormalizedHandoff[] = [];\n const seenNames = new Set<string>();\n for (const entry of entries) {\n // Detect raw Agent vs HandoffDescriptor by presence of `.target`.\n const isDescriptor =\n typeof entry === \"object\" &&\n entry !== null &&\n \"target\" in entry &&\n \"options\" in entry &&\n \"resolvedToolName\" in entry;\n const descriptor = isDescriptor ? (entry as HandoffDescriptor) : autoWrap(entry as SDKAgent);\n if (descriptor.target.agentId === parentAgentId) {\n throw new HandoffSelfReferenceError(parentAgentId);\n }\n const name = descriptor.resolvedToolName;\n if (seenNames.has(name)) {\n throw new HandoffNameCollisionError(name);\n }\n seenNames.add(name);\n out.push({ descriptor });\n }\n return out;\n}\n\nfunction autoWrap(agent: SDKAgent): HandoffDescriptor {\n const name = resolveTargetName(agent);\n return {\n target: agent,\n options: {},\n resolvedToolName: `transfer_to_${name}`,\n };\n}\n\nfunction resolveTargetName(agent: SDKAgent): string {\n // Prefer a `name` field if exposed; fall back to a short agentId slug.\n const candidate = (agent as unknown as { name?: string }).name ?? agent.agentId ?? \"anonymous\";\n return slugify(candidate);\n}\n\nfunction slugify(input: string): string {\n return (\n input\n .replace(/^agent-/i, \"\")\n .replace(/[^a-zA-Z0-9_-]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 64) || \"anonymous\"\n );\n}\n\n/**\n * Build a `CustomTool` for one handoff descriptor. The handler dispatches\n * the handoff using a fresh chain state per `send()`-level invocation.\n *\n * NOTE: this v1 builds a NEW chain state per tool invocation. Pure\n * cross-tool depth tracking within one send() requires per-Agent context\n * — deferred. The single-flight pair guard catches direct ping-pong even\n * without cross-invocation chain (since each call wraps the same depth\n * counter from 1).\n */\nexport function buildHandoffTool(\n parentAgentId: string,\n descriptor: HandoffDescriptor,\n maxHandoffDepth: number,\n): CustomTool {\n const description =\n descriptor.options.toolDescription ??\n `Transfer the conversation to the ${descriptor.target.agentId} agent. ` +\n `Use this when the user's request matches their specialty.`;\n\n const inputZod =\n descriptor.options.inputType ??\n z.object({\n reason: z.string().optional().describe(\"Brief reason for the transfer (one short sentence).\"),\n });\n // CustomTool.inputSchema expects a JSON schema (Record<string, unknown>),\n // not the raw Zod type. Convert lazily so we don't fail when Zod is missing.\n // Universal Zod 3+4 conversion (feature-detects native v4, falls back to lib on v3).\n const inputSchema = toJsonSchema(inputZod);\n\n return {\n name: descriptor.resolvedToolName,\n description,\n inputSchema,\n handler: async (input: unknown): Promise<string> => {\n const chainState = createChainState(parentAgentId, maxHandoffDepth);\n try {\n const { reply, result } = await dispatchHandoff({\n descriptor,\n senderAgentId: parentAgentId,\n chainState,\n rawInputJson: input,\n history: { messages: [] }, // v1: history replay deferred\n });\n return JSON.stringify({\n ok: true,\n transferred_to: result.to,\n depth: result.depth,\n reply,\n });\n } catch (err) {\n return JSON.stringify({\n ok: false,\n error: err instanceof Error ? err.name : \"HandoffError\",\n message: err instanceof Error ? err.message : String(err),\n });\n }\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../../src/types/handoff.ts","../../src/internal/registry.ts","../../src/internal/telemetry.ts","../../src/internal/dispatcher.ts","../../src/internal/to-json-schema.ts","../../src/internal/tool-injector.ts"],"names":["createRequire","z","toJSONSchema"],"mappings":"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","file":"tool-injector.cjs","sourcesContent":["/**\n * Public types for `Agent.create({ handoffs })` + `Handoff.create()` +\n * `Agent.handoffTo()` (Adoption Roadmap #4; ADRs D214-D229).\n *\n * Pattern: handoff-as-tool. Each handoff destination becomes a synthetic\n * `transfer_to_<receiver>` function tool exposed to the LLM. Runtime\n * intercepts the tool call and routes the next turn to the receiver.\n *\n * T4.1 follow-up (cycle #4 closed): `HandoffDescriptor` + its leaf-friendly\n * sibling types now live in `./handoff-descriptor.ts` (generic over\n * `TAgent`). This module re-exports the leaf types pinned to `SDKAgent`,\n * keeps the runtime error classes, and removes the back-edge to `agent.ts`.\n *\n * @public\n */\n\nimport type { SDKAgent } from \"@theokit/sdk\";\nimport type { ZodType } from \"zod\";\nimport type {\n HandoffContext,\n HandoffDescriptor as HandoffDescriptorGeneric,\n HandoffHistory,\n HandoffOptions,\n HandoffResult,\n} from \"./handoff-descriptor.js\";\n\nexport type { HandoffContext, HandoffHistory, HandoffOptions, HandoffResult };\n\n/**\n * `HandoffDescriptor` pinned to `SDKAgent` — back-compat shape for callers\n * that imported `import type { HandoffDescriptor } from \"@theokit/sdk\"`\n * before T4.1 follow-up.\n *\n * @public\n */\nexport type HandoffDescriptor<TInput extends ZodType = ZodType> = HandoffDescriptorGeneric<\n TInput,\n SDKAgent\n>;\n\n/** Throw when handoff depth exceeds `maxHandoffDepth` (default 5; D218). */\nexport class HandoffLoopError extends Error {\n override readonly name = \"HandoffLoopError\";\n readonly depth: number;\n readonly chain: ReadonlyArray<string>;\n constructor(depth: number, chain: ReadonlyArray<string>) {\n super(\n `Handoff loop exceeded max depth ${depth}. Chain: ${chain.join(\" -> \")}. ` +\n `Use Agent.create({ maxHandoffDepth: N }) to raise the cap.`,\n );\n this.depth = depth;\n this.chain = chain;\n }\n}\n\n/** Throw when the same (sender, receiver) pair invoked twice in one send() (D221). */\nexport class HandoffPairLoopError extends Error {\n override readonly name = \"HandoffPairLoopError\";\n readonly senderAgentId: string;\n readonly receiverAgentId: string;\n constructor(senderAgentId: string, receiverAgentId: string) {\n super(\n `Handoff loop: ${senderAgentId} -> ${receiverAgentId} already invoked in this send() call. ` +\n `Likely a ping-pong loop; revisit your handoff conditions.`,\n );\n this.senderAgentId = senderAgentId;\n this.receiverAgentId = receiverAgentId;\n }\n}\n\n/** Throw when an agent's `handoffs[]` includes a self-reference (EC-6). */\nexport class HandoffSelfReferenceError extends Error {\n override readonly name = \"HandoffSelfReferenceError\";\n readonly agentId: string;\n constructor(agentId: string) {\n super(\n `Agent \"${agentId}\" has a self-reference in its handoffs[]. ` +\n `Self-handoff causes infinite recursion; introduce a sibling agent for re-entry.`,\n );\n this.agentId = agentId;\n }\n}\n\n/** Throw when receiver is disposed at dispatch time (EC-5). */\nexport class HandoffReceiverDisposedError extends Error {\n override readonly name = \"HandoffReceiverDisposedError\";\n readonly receiverAgentId: string;\n constructor(receiverAgentId: string) {\n super(\n `Handoff target agent \"${receiverAgentId}\" is disposed. ` +\n `Don't dispose receivers while their parent is still active.`,\n );\n this.receiverAgentId = receiverAgentId;\n }\n}\n\n/** Throw when two handoffs in the same parent collide on tool name (D215). */\nexport class HandoffNameCollisionError extends Error {\n override readonly name = \"HandoffNameCollisionError\";\n readonly conflictingName: string;\n constructor(conflictingName: string) {\n super(\n `Two handoffs share the same tool name \"${conflictingName}\". ` +\n `Set { toolName } on at least one of them to disambiguate.`,\n );\n this.conflictingName = conflictingName;\n }\n}\n","/**\n * Handoff registry — pure state container per `Agent` instance.\n *\n * Holds the active dispatch chain (for depth + pair tracking) across the\n * lifetime of a single `agent.send()` call. Cleared between calls.\n *\n * @internal\n */\n\nimport { HandoffLoopError, HandoffPairLoopError } from \"../types/handoff.js\";\n\nexport interface HandoffChainState {\n /** Ordered chain of agentIds traversed so far (oldest first). */\n readonly chain: string[];\n /** Set of \"<sender>-><receiver>\" keys for pair-level loop detection (D221). */\n readonly seenPairs: Set<string>;\n /** Caller-supplied max depth (D218). */\n readonly maxDepth: number;\n}\n\nexport function createChainState(rootAgentId: string, maxDepth: number): HandoffChainState {\n return {\n chain: [rootAgentId],\n seenPairs: new Set(),\n maxDepth,\n };\n}\n\n/**\n * Record a handoff hop. Throws on depth-exceed (D218) or pair-loop (D221).\n * Mutates the state in place.\n */\nexport function recordHop(\n state: HandoffChainState,\n senderAgentId: string,\n receiverAgentId: string,\n): void {\n const pairKey = `${senderAgentId}->${receiverAgentId}`;\n if (state.seenPairs.has(pairKey)) {\n throw new HandoffPairLoopError(senderAgentId, receiverAgentId);\n }\n state.seenPairs.add(pairKey);\n state.chain.push(receiverAgentId);\n // chain.length = nodes; depth = hops = chain.length - 1.\n const depth = state.chain.length - 1;\n if (depth > state.maxDepth) {\n throw new HandoffLoopError(state.maxDepth, [...state.chain]);\n }\n}\n\nexport function currentDepth(state: HandoffChainState): number {\n return state.chain.length - 1;\n}\n","/**\n * D220 — Lazy-loaded OTel `handoff.transfer` span emitter.\n *\n * @internal\n */\n\n// Inline tracer-loader (same workaround as @theokit/sdk-cache/internal/telemetry.ts):\n// rollup-plugin-dts emits incomplete index.d.ts for newly-modified internal/ barrels\n// in @theokit/sdk. Runtime via the sub-path works; TypeScript users hit TS2305.\n// Inlining keeps sdk-handoff self-contained for the (small) observability hook.\nimport { createRequire } from \"node:module\";\n\ninterface SpanLike {\n setAttribute(key: string, value: string | number | boolean): SpanLike;\n end(): void;\n}\n\nconst _NOOP_SPAN: SpanLike = {\n setAttribute: () => _NOOP_SPAN,\n end: () => undefined,\n};\n\ninterface TracerLike {\n startSpan(\n name: string,\n options?: { attributes?: Record<string, string | number | boolean> },\n ): SpanLike;\n}\n\ninterface TracerCacheEntry {\n tracer: TracerLike | null;\n}\nconst tracerCache = new Map<string, TracerCacheEntry>();\n\nfunction getTracer(name: string, version = \"1.0.0\"): TracerLike | undefined {\n const cached = tracerCache.get(name);\n if (cached !== undefined) return cached.tracer ?? undefined;\n try {\n const r = createRequire(import.meta.url);\n const otel = r(\"@opentelemetry/api\") as {\n trace?: { getTracer: (n: string, v?: string) => TracerLike };\n };\n if (otel.trace?.getTracer === undefined) {\n tracerCache.set(name, { tracer: null });\n return undefined;\n }\n const tracer = otel.trace.getTracer(name, version);\n tracerCache.set(name, { tracer });\n return tracer;\n } catch {\n tracerCache.set(name, { tracer: null });\n return undefined;\n }\n}\n\nfunction resetTracerCacheForTests(): void {\n tracerCache.clear();\n}\n\nconst TRACER_NAME = \"theokit-sdk-handoff\";\n\ninterface HandoffSpanHandle {\n setAttribute(key: string, value: string | number | boolean): void;\n end(): void;\n}\n\nconst NOOP: HandoffSpanHandle = { setAttribute: () => undefined, end: () => undefined };\n\nfunction safe<T>(fn: () => T, fallback: T): T {\n try {\n return fn();\n } catch {\n return fallback;\n }\n}\n\nexport function startHandoffSpan(attrs: {\n from: string;\n to: string;\n reason: string;\n depth: number;\n toolName: string;\n}): HandoffSpanHandle {\n const tracer = getTracer(TRACER_NAME);\n if (tracer === undefined) return NOOP;\n const span: SpanLike | undefined = safe(\n () =>\n tracer.startSpan(\"handoff.transfer\", {\n attributes: {\n \"handoff.from\": attrs.from,\n \"handoff.to\": attrs.to,\n \"handoff.reason\": attrs.reason,\n \"handoff.depth\": attrs.depth,\n \"handoff.tool_name\": attrs.toolName,\n },\n }),\n undefined,\n );\n if (span === undefined) return NOOP;\n return {\n setAttribute: (k, v) => safe(() => span.setAttribute(k, v), undefined),\n end: () => safe(() => span.end(), undefined),\n };\n}\n\n/** Test-only — reset cached OTel handle. */\nfunction __resetHandoffOtelCacheForTests(): void {\n resetTracerCacheForTests();\n}\n","/**\n * Handoff dispatch orchestration.\n *\n * Pragmatic v1: when a handoff fires, the sender calls `receiver.send()`\n * with the (optionally filtered) history. The receiver's reply is returned\n * to the sender, which captures it as the answer to the user's question.\n *\n * NOTE: this is NOT pure peer-to-peer (the sender stays on the call stack\n * until the receiver returns). Pure intercept-and-swap requires deeper\n * agent-loop refactor; deferred to v2. v1 still validates the user-facing\n * value: \"agent A reasoned about routing, agent B answered.\"\n *\n * @internal\n */\n\nimport type { SDKAgent } from \"@theokit/sdk\";\nimport { z } from \"zod\";\nimport type {\n HandoffContext,\n HandoffDescriptor,\n HandoffHistory,\n HandoffResult,\n} from \"../types/handoff.js\";\nimport { HandoffReceiverDisposedError } from \"../types/handoff.js\";\nimport { type HandoffChainState, recordHop } from \"./registry.js\";\nimport { startHandoffSpan } from \"./telemetry.js\";\n\n/**\n * EC-2 / D228 — `safeFilter` wraps `inputFilter`. On exception, falls back\n * to the un-filtered history and warns to stderr once per process.\n */\nlet warnedFilterOnce = false;\nasync function safeFilter(\n filter: ((h: HandoffHistory) => HandoffHistory | Promise<HandoffHistory>) | undefined,\n history: HandoffHistory,\n): Promise<HandoffHistory> {\n if (filter === undefined) return history;\n try {\n const result = filter(history);\n return result instanceof Promise ? await result : result;\n } catch (err) {\n if (!warnedFilterOnce) {\n warnedFilterOnce = true;\n process.stderr.write(\n `[handoff] inputFilter threw, falling back to full history: ${err instanceof Error ? err.message : String(err)}\\n`,\n );\n }\n return history;\n }\n}\n\n/**\n * EC-4 / D229 — parse the LLM-provided JSON args. Returns undefined when\n * no `inputType` set; returns parsed value otherwise (default to `{}` on\n * empty/null input before Zod refinements).\n */\nfunction parseHandoffInput(descriptor: HandoffDescriptor, raw: unknown): unknown {\n const inputType = descriptor.options.inputType;\n if (inputType === undefined) return undefined;\n const candidate = raw === null || raw === undefined ? {} : raw;\n return inputType.parse(candidate);\n}\n\nfunction isAgentDisposed(agent: SDKAgent): boolean {\n // SDKAgent doesn't expose `disposed` publicly; check via duck-typing on\n // a known internal flag. Safe fallback: if we can't tell, assume alive.\n const maybe = agent as unknown as { disposed?: boolean };\n return maybe.disposed === true;\n}\n\n/**\n * Run a single handoff hop. Returns the receiver's reply text.\n *\n * Algorithm:\n * 1. EC-5: refuse if receiver disposed.\n * 2. Build HandoffContext.\n * 3. Check isEnabled() — if false, refuse with a clear error message.\n * 4. Parse inputType (D229).\n * 5. Run onHandoff(ctx, parsed) — throw aborts (D227).\n * 6. Apply inputFilter (safeFilter — D228).\n * 7. Record hop in chain state (depth + pair guards).\n * 8. Open OTel span (D220).\n * 9. Receiver: build the user-facing message and `await receiver.send(msg).then(wait)`.\n * 10. Close span + return reply.\n */\nasync function assertHandoffEnabled(\n descriptor: HandoffDescriptor,\n ctx: HandoffContext,\n receiverAgentId: string,\n): Promise<void> {\n const opt = descriptor.options.isEnabled;\n let enabled = true;\n if (typeof opt === \"boolean\") enabled = opt;\n else if (typeof opt === \"function\") {\n const r = opt(ctx);\n enabled = r instanceof Promise ? await r : r;\n }\n if (!enabled) {\n throw new Error(`Handoff to ${receiverAgentId} is disabled (isEnabled returned false)`);\n }\n}\n\nfunction parseAndValidate(descriptor: HandoffDescriptor, rawInputJson: unknown): unknown {\n try {\n return parseHandoffInput(descriptor, rawInputJson);\n } catch (err) {\n const detail =\n err instanceof z.ZodError\n ? (err.issues[0]?.message ?? \"schema_invalid\")\n : err instanceof Error\n ? err.message\n : String(err);\n throw new Error(`Handoff input validation failed: ${detail}`);\n }\n}\n\nasync function runOnHandoff(\n descriptor: HandoffDescriptor,\n ctx: HandoffContext,\n parsedInput: unknown,\n): Promise<void> {\n const onHandoff = descriptor.options.onHandoff;\n if (onHandoff === undefined) return;\n // biome-ignore lint/suspicious/noExplicitAny: parsedInput is typed unknown by design.\n const result = onHandoff(ctx, parsedInput as any);\n if (result instanceof Promise) await result;\n}\n\nfunction extractUserText(content: unknown): string | undefined {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return undefined;\n const text = content\n .filter((c): c is { type: \"text\"; text: string } => (c as { type?: string })?.type === \"text\")\n .map((c) => c.text)\n .join(\"\\n\");\n return text.length > 0 ? text : undefined;\n}\n\nfunction extractLastUserMessage(history: HandoffHistory, senderAgentId: string): string {\n for (let i = history.messages.length - 1; i >= 0; i -= 1) {\n const m = history.messages[i] as {\n type?: string;\n message?: { role?: string; content?: unknown };\n };\n if (m?.type !== \"user\" || m.message?.role !== \"user\") continue;\n const text = extractUserText(m.message.content);\n if (text !== undefined) return text;\n }\n return `(Handoff from ${senderAgentId} — no prior user message in history.)`;\n}\n\nexport async function dispatchHandoff(args: {\n descriptor: HandoffDescriptor;\n senderAgentId: string;\n chainState: HandoffChainState;\n rawInputJson: unknown;\n /** The conversation so far (history wrapper). v1: just the LAST user message. */\n history: HandoffHistory;\n /** Override the message text sent to the receiver. Used by `Agent.handoffTo` imperative. */\n messageOverride?: string;\n}): Promise<{ reply: string; result: HandoffResult }> {\n const { descriptor, senderAgentId, chainState, rawInputJson, history, messageOverride } = args;\n const receiver = descriptor.target;\n\n if (isAgentDisposed(receiver)) {\n throw new HandoffReceiverDisposedError(receiver.agentId);\n }\n\n const depthAfterThisHop = chainState.chain.length;\n const ctx: HandoffContext = {\n senderAgentId,\n receiverAgentId: receiver.agentId,\n currentDepth: depthAfterThisHop,\n chain: [...chainState.chain, receiver.agentId],\n };\n\n await assertHandoffEnabled(descriptor, ctx, receiver.agentId);\n const parsedInput = parseAndValidate(descriptor, rawInputJson);\n await runOnHandoff(descriptor, ctx, parsedInput);\n\n // Filter history (D228 — resilient)\n const filteredHistory = await safeFilter(descriptor.options.inputFilter, history);\n\n // Record hop — may throw HandoffLoopError or HandoffPairLoopError\n recordHop(chainState, senderAgentId, receiver.agentId);\n\n const lastUserMessage = messageOverride ?? extractLastUserMessage(filteredHistory, senderAgentId);\n const reason = extractReason(parsedInput);\n\n const span = startHandoffSpan({\n from: senderAgentId,\n to: receiver.agentId,\n reason,\n depth: depthAfterThisHop,\n toolName: descriptor.resolvedToolName,\n });\n\n try {\n const run = await receiver.send(lastUserMessage);\n const result = await run.wait();\n const reply = buildReply(result, receiver.agentId);\n return {\n reply,\n result: {\n from: senderAgentId,\n to: receiver.agentId,\n depth: depthAfterThisHop,\n toolName: descriptor.resolvedToolName,\n ...(reason !== \"\" ? { reasonFromLlm: reason } : {}),\n },\n };\n } finally {\n span.end();\n }\n}\n\nfunction extractReason(parsedInput: unknown): string {\n if (typeof parsedInput !== \"object\" || parsedInput === null) return \"\";\n if (!(\"reason\" in parsedInput)) return \"\";\n return String((parsedInput as { reason: unknown }).reason ?? \"\");\n}\n\nfunction buildReply(\n result: { status: string; result?: string; error?: { message: string } },\n receiverAgentId: string,\n): string {\n if (result.status === \"finished\" && result.result !== undefined) return result.result;\n const suffix = result.error !== undefined ? `: ${result.error.message}` : \"\";\n return `(Handoff target ${receiverAgentId} returned status=${result.status}${suffix})`;\n}\n","/**\n * Zod v4 → JSON Schema adapter for sdk-handoff.\n *\n * Uses Zod v4's native `z.toJSONSchema()` directly. v3 fallback removed\n * after zod-v4-migration plan (ADR D2).\n *\n * @internal\n */\n\nimport { toJSONSchema } from \"zod\";\n\ninterface ToJsonSchemaOptions {\n /** `\"any\"` keeps transforms/refinements as `{}` (loose). Default: `\"any\"`. */\n unrepresentable?: \"any\" | \"throw\";\n}\n\n/**\n * Convert a Zod schema to a JSON Schema object via Zod v4 native.\n *\n * @internal\n */\nexport function toJsonSchema(\n schema: unknown,\n options: ToJsonSchemaOptions = { unrepresentable: \"any\" },\n): Record<string, unknown> {\n // The schema param is `unknown` (callers pass `T extends ZodType` generics that\n // don't structurally satisfy Zod v4's `$ZodType`); cast to the exact parameter\n // type `toJSONSchema` expects rather than `any` — any z.* schema IS valid at runtime.\n return toJSONSchema(schema as Parameters<typeof toJSONSchema>[0], options) as Record<\n string,\n unknown\n >;\n}\n","/**\n * Convert `handoffs[]` entries into synthetic `transfer_to_<receiver>` tools\n * for injection into the agent's tool registry at construction time.\n *\n * The synthesized tool's handler calls `dispatchHandoff` internally and\n * returns the receiver's reply as `tool_result`. v1 trade-off documented\n * in dispatcher.ts.\n *\n * @internal\n */\n\nimport type { CustomTool, SDKAgent } from \"@theokit/sdk\";\nimport { z } from \"zod\";\nimport {\n type HandoffDescriptor,\n HandoffNameCollisionError,\n HandoffSelfReferenceError,\n} from \"../types/handoff.js\";\nimport { dispatchHandoff } from \"./dispatcher.js\";\nimport { createChainState } from \"./registry.js\";\nimport { toJsonSchema } from \"./to-json-schema.js\";\n\ninterface NormalizedHandoff {\n descriptor: HandoffDescriptor;\n}\n\n/**\n * Normalize each `handoffs[]` entry to a `HandoffDescriptor`. Raw `SDKAgent`\n * instances are auto-wrapped with default options. Validates:\n * - EC-6: no self-reference (would cause infinite recursion).\n * - D215: resolved tool names must be unique.\n */\nexport function normalizeHandoffs(\n parentAgentId: string,\n entries: ReadonlyArray<SDKAgent | HandoffDescriptor>,\n): NormalizedHandoff[] {\n if (entries.length === 0) return [];\n const out: NormalizedHandoff[] = [];\n const seenNames = new Set<string>();\n for (const entry of entries) {\n // Detect raw Agent vs HandoffDescriptor by presence of `.target`.\n const isDescriptor =\n typeof entry === \"object\" &&\n entry !== null &&\n \"target\" in entry &&\n \"options\" in entry &&\n \"resolvedToolName\" in entry;\n const descriptor = isDescriptor ? (entry as HandoffDescriptor) : autoWrap(entry as SDKAgent);\n if (descriptor.target.agentId === parentAgentId) {\n throw new HandoffSelfReferenceError(parentAgentId);\n }\n const name = descriptor.resolvedToolName;\n if (seenNames.has(name)) {\n throw new HandoffNameCollisionError(name);\n }\n seenNames.add(name);\n out.push({ descriptor });\n }\n return out;\n}\n\nfunction autoWrap(agent: SDKAgent): HandoffDescriptor {\n const name = resolveTargetName(agent);\n return {\n target: agent,\n options: {},\n resolvedToolName: `transfer_to_${name}`,\n };\n}\n\nfunction resolveTargetName(agent: SDKAgent): string {\n // Prefer a `name` field if exposed; fall back to a short agentId slug.\n const candidate = (agent as unknown as { name?: string }).name ?? agent.agentId ?? \"anonymous\";\n return slugify(candidate);\n}\n\nfunction slugify(input: string): string {\n return (\n input\n .replace(/^agent-/i, \"\")\n .replace(/[^a-zA-Z0-9_-]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 64) || \"anonymous\"\n );\n}\n\n/**\n * Build a `CustomTool` for one handoff descriptor. The handler dispatches\n * the handoff using a fresh chain state per `send()`-level invocation.\n *\n * NOTE: this v1 builds a NEW chain state per tool invocation. Pure\n * cross-tool depth tracking within one send() requires per-Agent context\n * — deferred. The single-flight pair guard catches direct ping-pong even\n * without cross-invocation chain (since each call wraps the same depth\n * counter from 1).\n */\nexport function buildHandoffTool(\n parentAgentId: string,\n descriptor: HandoffDescriptor,\n maxHandoffDepth: number,\n): CustomTool {\n const description =\n descriptor.options.toolDescription ??\n `Transfer the conversation to the ${descriptor.target.agentId} agent. ` +\n `Use this when the user's request matches their specialty.`;\n\n const inputZod =\n descriptor.options.inputType ??\n z.object({\n reason: z.string().optional().describe(\"Brief reason for the transfer (one short sentence).\"),\n });\n // CustomTool.inputSchema expects a JSON schema (Record<string, unknown>),\n // not the raw Zod type. Convert lazily so we don't fail when Zod is missing.\n // Universal Zod 3+4 conversion (feature-detects native v4, falls back to lib on v3).\n const inputSchema = toJsonSchema(inputZod);\n\n return {\n name: descriptor.resolvedToolName,\n description,\n inputSchema,\n handler: async (input: unknown): Promise<string> => {\n const chainState = createChainState(parentAgentId, maxHandoffDepth);\n try {\n const { reply, result } = await dispatchHandoff({\n descriptor,\n senderAgentId: parentAgentId,\n chainState,\n rawInputJson: input,\n history: { messages: [] }, // v1: history replay deferred\n });\n return JSON.stringify({\n ok: true,\n transferred_to: result.to,\n depth: result.depth,\n reply,\n });\n } catch (err) {\n return JSON.stringify({\n ok: false,\n error: err instanceof Error ? err.name : \"HandoffError\",\n message: err instanceof Error ? err.message : String(err),\n });\n }\n },\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/handoff.ts","../../src/internal/registry.ts","../../src/internal/telemetry.ts","../../src/internal/dispatcher.ts","../../src/internal/to-json-schema.ts","../../src/internal/tool-injector.ts"],"names":["z"],"mappings":"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","file":"tool-injector.js","sourcesContent":["/**\n * Public types for `Agent.create({ handoffs })` + `Handoff.create()` +\n * `Agent.handoffTo()` (Adoption Roadmap #4; ADRs D214-D229).\n *\n * Pattern: handoff-as-tool. Each handoff destination becomes a synthetic\n * `transfer_to_<receiver>` function tool exposed to the LLM. Runtime\n * intercepts the tool call and routes the next turn to the receiver.\n *\n * T4.1 follow-up (cycle #4 closed): `HandoffDescriptor` + its leaf-friendly\n * sibling types now live in `./handoff-descriptor.ts` (generic over\n * `TAgent`). This module re-exports the leaf types pinned to `SDKAgent`,\n * keeps the runtime error classes, and removes the back-edge to `agent.ts`.\n *\n * @public\n */\n\nimport type { SDKAgent } from \"@theokit/sdk\";\nimport type { ZodType } from \"zod\";\nimport type {\n HandoffContext,\n HandoffDescriptor as HandoffDescriptorGeneric,\n HandoffHistory,\n HandoffOptions,\n HandoffResult,\n} from \"./handoff-descriptor.js\";\n\nexport type { HandoffContext, HandoffHistory, HandoffOptions, HandoffResult };\n\n/**\n * `HandoffDescriptor` pinned to `SDKAgent` — back-compat shape for callers\n * that imported `import type { HandoffDescriptor } from \"@theokit/sdk\"`\n * before T4.1 follow-up.\n *\n * @public\n */\nexport type HandoffDescriptor<TInput extends ZodType = ZodType> = HandoffDescriptorGeneric<\n TInput,\n SDKAgent\n>;\n\n/** Throw when handoff depth exceeds `maxHandoffDepth` (default 5; D218). */\nexport class HandoffLoopError extends Error {\n override readonly name = \"HandoffLoopError\";\n readonly depth: number;\n readonly chain: ReadonlyArray<string>;\n constructor(depth: number, chain: ReadonlyArray<string>) {\n super(\n `Handoff loop exceeded max depth ${depth}. Chain: ${chain.join(\" -> \")}. ` +\n `Use Agent.create({ maxHandoffDepth: N }) to raise the cap.`,\n );\n this.depth = depth;\n this.chain = chain;\n }\n}\n\n/** Throw when the same (sender, receiver) pair invoked twice in one send() (D221). */\nexport class HandoffPairLoopError extends Error {\n override readonly name = \"HandoffPairLoopError\";\n readonly senderAgentId: string;\n readonly receiverAgentId: string;\n constructor(senderAgentId: string, receiverAgentId: string) {\n super(\n `Handoff loop: ${senderAgentId} -> ${receiverAgentId} already invoked in this send() call. ` +\n `Likely a ping-pong loop; revisit your handoff conditions.`,\n );\n this.senderAgentId = senderAgentId;\n this.receiverAgentId = receiverAgentId;\n }\n}\n\n/** Throw when an agent's `handoffs[]` includes a self-reference (EC-6). */\nexport class HandoffSelfReferenceError extends Error {\n override readonly name = \"HandoffSelfReferenceError\";\n readonly agentId: string;\n constructor(agentId: string) {\n super(\n `Agent \"${agentId}\" has a self-reference in its handoffs[]. ` +\n `Self-handoff causes infinite recursion; introduce a sibling agent for re-entry.`,\n );\n this.agentId = agentId;\n }\n}\n\n/** Throw when receiver is disposed at dispatch time (EC-5). */\nexport class HandoffReceiverDisposedError extends Error {\n override readonly name = \"HandoffReceiverDisposedError\";\n readonly receiverAgentId: string;\n constructor(receiverAgentId: string) {\n super(\n `Handoff target agent \"${receiverAgentId}\" is disposed. ` +\n `Don't dispose receivers while their parent is still active.`,\n );\n this.receiverAgentId = receiverAgentId;\n }\n}\n\n/** Throw when two handoffs in the same parent collide on tool name (D215). */\nexport class HandoffNameCollisionError extends Error {\n override readonly name = \"HandoffNameCollisionError\";\n readonly conflictingName: string;\n constructor(conflictingName: string) {\n super(\n `Two handoffs share the same tool name \"${conflictingName}\". ` +\n `Set { toolName } on at least one of them to disambiguate.`,\n );\n this.conflictingName = conflictingName;\n }\n}\n","/**\n * Handoff registry — pure state container per `Agent` instance.\n *\n * Holds the active dispatch chain (for depth + pair tracking) across the\n * lifetime of a single `agent.send()` call. Cleared between calls.\n *\n * @internal\n */\n\nimport { HandoffLoopError, HandoffPairLoopError } from \"../types/handoff.js\";\n\nexport interface HandoffChainState {\n /** Ordered chain of agentIds traversed so far (oldest first). */\n readonly chain: string[];\n /** Set of \"<sender>-><receiver>\" keys for pair-level loop detection (D221). */\n readonly seenPairs: Set<string>;\n /** Caller-supplied max depth (D218). */\n readonly maxDepth: number;\n}\n\nexport function createChainState(rootAgentId: string, maxDepth: number): HandoffChainState {\n return {\n chain: [rootAgentId],\n seenPairs: new Set(),\n maxDepth,\n };\n}\n\n/**\n * Record a handoff hop. Throws on depth-exceed (D218) or pair-loop (D221).\n * Mutates the state in place.\n */\nexport function recordHop(\n state: HandoffChainState,\n senderAgentId: string,\n receiverAgentId: string,\n): void {\n const pairKey = `${senderAgentId}->${receiverAgentId}`;\n if (state.seenPairs.has(pairKey)) {\n throw new HandoffPairLoopError(senderAgentId, receiverAgentId);\n }\n state.seenPairs.add(pairKey);\n state.chain.push(receiverAgentId);\n // chain.length = nodes; depth = hops = chain.length - 1.\n const depth = state.chain.length - 1;\n if (depth > state.maxDepth) {\n throw new HandoffLoopError(state.maxDepth, [...state.chain]);\n }\n}\n\nexport function currentDepth(state: HandoffChainState): number {\n return state.chain.length - 1;\n}\n","/**\n * D220 — Lazy-loaded OTel `handoff.transfer` span emitter.\n *\n * @internal\n */\n\n// Inline tracer-loader (same workaround as @theokit/sdk-cache/internal/telemetry.ts):\n// rollup-plugin-dts emits incomplete index.d.ts for newly-modified internal/ barrels\n// in @theokit/sdk. Runtime via the sub-path works; TypeScript users hit TS2305.\n// Inlining keeps sdk-handoff self-contained for the (small) observability hook.\nimport { createRequire } from \"node:module\";\n\ninterface SpanLike {\n setAttribute(key: string, value: string | number | boolean): SpanLike;\n end(): void;\n}\n\nconst _NOOP_SPAN: SpanLike = {\n setAttribute: () => _NOOP_SPAN,\n end: () => undefined,\n};\n\ninterface TracerLike {\n startSpan(\n name: string,\n options?: { attributes?: Record<string, string | number | boolean> },\n ): SpanLike;\n}\n\ninterface TracerCacheEntry {\n tracer: TracerLike | null;\n}\nconst tracerCache = new Map<string, TracerCacheEntry>();\n\nfunction getTracer(name: string, version = \"1.0.0\"): TracerLike | undefined {\n const cached = tracerCache.get(name);\n if (cached !== undefined) return cached.tracer ?? undefined;\n try {\n const r = createRequire(import.meta.url);\n const otel = r(\"@opentelemetry/api\") as {\n trace?: { getTracer: (n: string, v?: string) => TracerLike };\n };\n if (otel.trace?.getTracer === undefined) {\n tracerCache.set(name, { tracer: null });\n return undefined;\n }\n const tracer = otel.trace.getTracer(name, version);\n tracerCache.set(name, { tracer });\n return tracer;\n } catch {\n tracerCache.set(name, { tracer: null });\n return undefined;\n }\n}\n\nfunction resetTracerCacheForTests(): void {\n tracerCache.clear();\n}\n\nconst TRACER_NAME = \"theokit-sdk-handoff\";\n\ninterface HandoffSpanHandle {\n setAttribute(key: string, value: string | number | boolean): void;\n end(): void;\n}\n\nconst NOOP: HandoffSpanHandle = { setAttribute: () => undefined, end: () => undefined };\n\nfunction safe<T>(fn: () => T, fallback: T): T {\n try {\n return fn();\n } catch {\n return fallback;\n }\n}\n\nexport function startHandoffSpan(attrs: {\n from: string;\n to: string;\n reason: string;\n depth: number;\n toolName: string;\n}): HandoffSpanHandle {\n const tracer = getTracer(TRACER_NAME);\n if (tracer === undefined) return NOOP;\n const span: SpanLike | undefined = safe(\n () =>\n tracer.startSpan(\"handoff.transfer\", {\n attributes: {\n \"handoff.from\": attrs.from,\n \"handoff.to\": attrs.to,\n \"handoff.reason\": attrs.reason,\n \"handoff.depth\": attrs.depth,\n \"handoff.tool_name\": attrs.toolName,\n },\n }),\n undefined,\n );\n if (span === undefined) return NOOP;\n return {\n setAttribute: (k, v) => safe(() => span.setAttribute(k, v), undefined),\n end: () => safe(() => span.end(), undefined),\n };\n}\n\n/** Test-only — reset cached OTel handle. */\nfunction __resetHandoffOtelCacheForTests(): void {\n resetTracerCacheForTests();\n}\n","/**\n * Handoff dispatch orchestration.\n *\n * Pragmatic v1: when a handoff fires, the sender calls `receiver.send()`\n * with the (optionally filtered) history. The receiver's reply is returned\n * to the sender, which captures it as the answer to the user's question.\n *\n * NOTE: this is NOT pure peer-to-peer (the sender stays on the call stack\n * until the receiver returns). Pure intercept-and-swap requires deeper\n * agent-loop refactor; deferred to v2. v1 still validates the user-facing\n * value: \"agent A reasoned about routing, agent B answered.\"\n *\n * @internal\n */\n\nimport type { SDKAgent } from \"@theokit/sdk\";\nimport { z } from \"zod\";\nimport type {\n HandoffContext,\n HandoffDescriptor,\n HandoffHistory,\n HandoffResult,\n} from \"../types/handoff.js\";\nimport { HandoffReceiverDisposedError } from \"../types/handoff.js\";\nimport { type HandoffChainState, recordHop } from \"./registry.js\";\nimport { startHandoffSpan } from \"./telemetry.js\";\n\n/**\n * EC-2 / D228 — `safeFilter` wraps `inputFilter`. On exception, falls back\n * to the un-filtered history and warns to stderr once per process.\n */\nlet warnedFilterOnce = false;\nasync function safeFilter(\n filter: ((h: HandoffHistory) => HandoffHistory | Promise<HandoffHistory>) | undefined,\n history: HandoffHistory,\n): Promise<HandoffHistory> {\n if (filter === undefined) return history;\n try {\n const result = filter(history);\n return result instanceof Promise ? await result : result;\n } catch (err) {\n if (!warnedFilterOnce) {\n warnedFilterOnce = true;\n process.stderr.write(\n `[handoff] inputFilter threw, falling back to full history: ${err instanceof Error ? err.message : String(err)}\\n`,\n );\n }\n return history;\n }\n}\n\n/**\n * EC-4 / D229 — parse the LLM-provided JSON args. Returns undefined when\n * no `inputType` set; returns parsed value otherwise (default to `{}` on\n * empty/null input before Zod refinements).\n */\nfunction parseHandoffInput(descriptor: HandoffDescriptor, raw: unknown): unknown {\n const inputType = descriptor.options.inputType;\n if (inputType === undefined) return undefined;\n const candidate = raw === null || raw === undefined ? {} : raw;\n return inputType.parse(candidate);\n}\n\nfunction isAgentDisposed(agent: SDKAgent): boolean {\n // SDKAgent doesn't expose `disposed` publicly; check via duck-typing on\n // a known internal flag. Safe fallback: if we can't tell, assume alive.\n const maybe = agent as unknown as { disposed?: boolean };\n return maybe.disposed === true;\n}\n\n/**\n * Run a single handoff hop. Returns the receiver's reply text.\n *\n * Algorithm:\n * 1. EC-5: refuse if receiver disposed.\n * 2. Build HandoffContext.\n * 3. Check isEnabled() — if false, refuse with a clear error message.\n * 4. Parse inputType (D229).\n * 5. Run onHandoff(ctx, parsed) — throw aborts (D227).\n * 6. Apply inputFilter (safeFilter — D228).\n * 7. Record hop in chain state (depth + pair guards).\n * 8. Open OTel span (D220).\n * 9. Receiver: build the user-facing message and `await receiver.send(msg).then(wait)`.\n * 10. Close span + return reply.\n */\nasync function assertHandoffEnabled(\n descriptor: HandoffDescriptor,\n ctx: HandoffContext,\n receiverAgentId: string,\n): Promise<void> {\n const opt = descriptor.options.isEnabled;\n let enabled = true;\n if (typeof opt === \"boolean\") enabled = opt;\n else if (typeof opt === \"function\") {\n const r = opt(ctx);\n enabled = r instanceof Promise ? await r : r;\n }\n if (!enabled) {\n throw new Error(`Handoff to ${receiverAgentId} is disabled (isEnabled returned false)`);\n }\n}\n\nfunction parseAndValidate(descriptor: HandoffDescriptor, rawInputJson: unknown): unknown {\n try {\n return parseHandoffInput(descriptor, rawInputJson);\n } catch (err) {\n const detail =\n err instanceof z.ZodError\n ? (err.issues[0]?.message ?? \"schema_invalid\")\n : err instanceof Error\n ? err.message\n : String(err);\n throw new Error(`Handoff input validation failed: ${detail}`);\n }\n}\n\nasync function runOnHandoff(\n descriptor: HandoffDescriptor,\n ctx: HandoffContext,\n parsedInput: unknown,\n): Promise<void> {\n const onHandoff = descriptor.options.onHandoff;\n if (onHandoff === undefined) return;\n // biome-ignore lint/suspicious/noExplicitAny: parsedInput is typed unknown by design.\n const result = onHandoff(ctx, parsedInput as any);\n if (result instanceof Promise) await result;\n}\n\nfunction extractUserText(content: unknown): string | undefined {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return undefined;\n const text = content\n .filter((c): c is { type: \"text\"; text: string } => (c as { type?: string })?.type === \"text\")\n .map((c) => c.text)\n .join(\"\\n\");\n return text.length > 0 ? text : undefined;\n}\n\nfunction extractLastUserMessage(history: HandoffHistory, senderAgentId: string): string {\n for (let i = history.messages.length - 1; i >= 0; i -= 1) {\n const m = history.messages[i] as {\n type?: string;\n message?: { role?: string; content?: unknown };\n };\n if (m?.type !== \"user\" || m.message?.role !== \"user\") continue;\n const text = extractUserText(m.message.content);\n if (text !== undefined) return text;\n }\n return `(Handoff from ${senderAgentId} — no prior user message in history.)`;\n}\n\nexport async function dispatchHandoff(args: {\n descriptor: HandoffDescriptor;\n senderAgentId: string;\n chainState: HandoffChainState;\n rawInputJson: unknown;\n /** The conversation so far (history wrapper). v1: just the LAST user message. */\n history: HandoffHistory;\n /** Override the message text sent to the receiver. Used by `Agent.handoffTo` imperative. */\n messageOverride?: string;\n}): Promise<{ reply: string; result: HandoffResult }> {\n const { descriptor, senderAgentId, chainState, rawInputJson, history, messageOverride } = args;\n const receiver = descriptor.target;\n\n if (isAgentDisposed(receiver)) {\n throw new HandoffReceiverDisposedError(receiver.agentId);\n }\n\n const depthAfterThisHop = chainState.chain.length;\n const ctx: HandoffContext = {\n senderAgentId,\n receiverAgentId: receiver.agentId,\n currentDepth: depthAfterThisHop,\n chain: [...chainState.chain, receiver.agentId],\n };\n\n await assertHandoffEnabled(descriptor, ctx, receiver.agentId);\n const parsedInput = parseAndValidate(descriptor, rawInputJson);\n await runOnHandoff(descriptor, ctx, parsedInput);\n\n // Filter history (D228 — resilient)\n const filteredHistory = await safeFilter(descriptor.options.inputFilter, history);\n\n // Record hop — may throw HandoffLoopError or HandoffPairLoopError\n recordHop(chainState, senderAgentId, receiver.agentId);\n\n const lastUserMessage = messageOverride ?? extractLastUserMessage(filteredHistory, senderAgentId);\n const reason = extractReason(parsedInput);\n\n const span = startHandoffSpan({\n from: senderAgentId,\n to: receiver.agentId,\n reason,\n depth: depthAfterThisHop,\n toolName: descriptor.resolvedToolName,\n });\n\n try {\n const run = await receiver.send(lastUserMessage);\n const result = await run.wait();\n const reply = buildReply(result, receiver.agentId);\n return {\n reply,\n result: {\n from: senderAgentId,\n to: receiver.agentId,\n depth: depthAfterThisHop,\n toolName: descriptor.resolvedToolName,\n ...(reason !== \"\" ? { reasonFromLlm: reason } : {}),\n },\n };\n } finally {\n span.end();\n }\n}\n\nfunction extractReason(parsedInput: unknown): string {\n if (typeof parsedInput !== \"object\" || parsedInput === null) return \"\";\n if (!(\"reason\" in parsedInput)) return \"\";\n return String((parsedInput as { reason: unknown }).reason ?? \"\");\n}\n\nfunction buildReply(\n result: { status: string; result?: string; error?: { message: string } },\n receiverAgentId: string,\n): string {\n if (result.status === \"finished\" && result.result !== undefined) return result.result;\n const suffix = result.error !== undefined ? `: ${result.error.message}` : \"\";\n return `(Handoff target ${receiverAgentId} returned status=${result.status}${suffix})`;\n}\n","/**\n * Zod v4 → JSON Schema adapter for sdk-handoff.\n *\n * Uses Zod v4's native `z.toJSONSchema()` directly. v3 fallback removed\n * after zod-v4-migration plan (ADR D2).\n *\n * @internal\n */\n\nimport { toJSONSchema } from \"zod\";\n\ninterface ToJsonSchemaOptions {\n /** `\"any\"` keeps transforms/refinements as `{}` (loose). Default: `\"any\"`. */\n unrepresentable?: \"any\" | \"throw\";\n}\n\n/**\n * Convert a Zod schema to a JSON Schema object via Zod v4 native.\n *\n * @internal\n */\nexport function toJsonSchema(\n schema: unknown,\n options: ToJsonSchemaOptions = { unrepresentable: \"any\" },\n): Record<string, unknown> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- generic ZodType erasure\n return toJSONSchema(schema as any, options) as Record<string, unknown>;\n}\n","/**\n * Convert `handoffs[]` entries into synthetic `transfer_to_<receiver>` tools\n * for injection into the agent's tool registry at construction time.\n *\n * The synthesized tool's handler calls `dispatchHandoff` internally and\n * returns the receiver's reply as `tool_result`. v1 trade-off documented\n * in dispatcher.ts.\n *\n * @internal\n */\n\nimport type { CustomTool, SDKAgent } from \"@theokit/sdk\";\nimport { z } from \"zod\";\nimport {\n type HandoffDescriptor,\n HandoffNameCollisionError,\n HandoffSelfReferenceError,\n} from \"../types/handoff.js\";\nimport { dispatchHandoff } from \"./dispatcher.js\";\nimport { createChainState } from \"./registry.js\";\nimport { toJsonSchema } from \"./to-json-schema.js\";\n\ninterface NormalizedHandoff {\n descriptor: HandoffDescriptor;\n}\n\n/**\n * Normalize each `handoffs[]` entry to a `HandoffDescriptor`. Raw `SDKAgent`\n * instances are auto-wrapped with default options. Validates:\n * - EC-6: no self-reference (would cause infinite recursion).\n * - D215: resolved tool names must be unique.\n */\nexport function normalizeHandoffs(\n parentAgentId: string,\n entries: ReadonlyArray<SDKAgent | HandoffDescriptor>,\n): NormalizedHandoff[] {\n if (entries.length === 0) return [];\n const out: NormalizedHandoff[] = [];\n const seenNames = new Set<string>();\n for (const entry of entries) {\n // Detect raw Agent vs HandoffDescriptor by presence of `.target`.\n const isDescriptor =\n typeof entry === \"object\" &&\n entry !== null &&\n \"target\" in entry &&\n \"options\" in entry &&\n \"resolvedToolName\" in entry;\n const descriptor = isDescriptor ? (entry as HandoffDescriptor) : autoWrap(entry as SDKAgent);\n if (descriptor.target.agentId === parentAgentId) {\n throw new HandoffSelfReferenceError(parentAgentId);\n }\n const name = descriptor.resolvedToolName;\n if (seenNames.has(name)) {\n throw new HandoffNameCollisionError(name);\n }\n seenNames.add(name);\n out.push({ descriptor });\n }\n return out;\n}\n\nfunction autoWrap(agent: SDKAgent): HandoffDescriptor {\n const name = resolveTargetName(agent);\n return {\n target: agent,\n options: {},\n resolvedToolName: `transfer_to_${name}`,\n };\n}\n\nfunction resolveTargetName(agent: SDKAgent): string {\n // Prefer a `name` field if exposed; fall back to a short agentId slug.\n const candidate = (agent as unknown as { name?: string }).name ?? agent.agentId ?? \"anonymous\";\n return slugify(candidate);\n}\n\nfunction slugify(input: string): string {\n return (\n input\n .replace(/^agent-/i, \"\")\n .replace(/[^a-zA-Z0-9_-]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 64) || \"anonymous\"\n );\n}\n\n/**\n * Build a `CustomTool` for one handoff descriptor. The handler dispatches\n * the handoff using a fresh chain state per `send()`-level invocation.\n *\n * NOTE: this v1 builds a NEW chain state per tool invocation. Pure\n * cross-tool depth tracking within one send() requires per-Agent context\n * — deferred. The single-flight pair guard catches direct ping-pong even\n * without cross-invocation chain (since each call wraps the same depth\n * counter from 1).\n */\nexport function buildHandoffTool(\n parentAgentId: string,\n descriptor: HandoffDescriptor,\n maxHandoffDepth: number,\n): CustomTool {\n const description =\n descriptor.options.toolDescription ??\n `Transfer the conversation to the ${descriptor.target.agentId} agent. ` +\n `Use this when the user's request matches their specialty.`;\n\n const inputZod =\n descriptor.options.inputType ??\n z.object({\n reason: z.string().optional().describe(\"Brief reason for the transfer (one short sentence).\"),\n });\n // CustomTool.inputSchema expects a JSON schema (Record<string, unknown>),\n // not the raw Zod type. Convert lazily so we don't fail when Zod is missing.\n // Universal Zod 3+4 conversion (feature-detects native v4, falls back to lib on v3).\n const inputSchema = toJsonSchema(inputZod);\n\n return {\n name: descriptor.resolvedToolName,\n description,\n inputSchema,\n handler: async (input: unknown): Promise<string> => {\n const chainState = createChainState(parentAgentId, maxHandoffDepth);\n try {\n const { reply, result } = await dispatchHandoff({\n descriptor,\n senderAgentId: parentAgentId,\n chainState,\n rawInputJson: input,\n history: { messages: [] }, // v1: history replay deferred\n });\n return JSON.stringify({\n ok: true,\n transferred_to: result.to,\n depth: result.depth,\n reply,\n });\n } catch (err) {\n return JSON.stringify({\n ok: false,\n error: err instanceof Error ? err.name : \"HandoffError\",\n message: err instanceof Error ? err.message : String(err),\n });\n }\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../../src/types/handoff.ts","../../src/internal/registry.ts","../../src/internal/telemetry.ts","../../src/internal/dispatcher.ts","../../src/internal/to-json-schema.ts","../../src/internal/tool-injector.ts"],"names":["z"],"mappings":"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","file":"tool-injector.js","sourcesContent":["/**\n * Public types for `Agent.create({ handoffs })` + `Handoff.create()` +\n * `Agent.handoffTo()` (Adoption Roadmap #4; ADRs D214-D229).\n *\n * Pattern: handoff-as-tool. Each handoff destination becomes a synthetic\n * `transfer_to_<receiver>` function tool exposed to the LLM. Runtime\n * intercepts the tool call and routes the next turn to the receiver.\n *\n * T4.1 follow-up (cycle #4 closed): `HandoffDescriptor` + its leaf-friendly\n * sibling types now live in `./handoff-descriptor.ts` (generic over\n * `TAgent`). This module re-exports the leaf types pinned to `SDKAgent`,\n * keeps the runtime error classes, and removes the back-edge to `agent.ts`.\n *\n * @public\n */\n\nimport type { SDKAgent } from \"@theokit/sdk\";\nimport type { ZodType } from \"zod\";\nimport type {\n HandoffContext,\n HandoffDescriptor as HandoffDescriptorGeneric,\n HandoffHistory,\n HandoffOptions,\n HandoffResult,\n} from \"./handoff-descriptor.js\";\n\nexport type { HandoffContext, HandoffHistory, HandoffOptions, HandoffResult };\n\n/**\n * `HandoffDescriptor` pinned to `SDKAgent` — back-compat shape for callers\n * that imported `import type { HandoffDescriptor } from \"@theokit/sdk\"`\n * before T4.1 follow-up.\n *\n * @public\n */\nexport type HandoffDescriptor<TInput extends ZodType = ZodType> = HandoffDescriptorGeneric<\n TInput,\n SDKAgent\n>;\n\n/** Throw when handoff depth exceeds `maxHandoffDepth` (default 5; D218). */\nexport class HandoffLoopError extends Error {\n override readonly name = \"HandoffLoopError\";\n readonly depth: number;\n readonly chain: ReadonlyArray<string>;\n constructor(depth: number, chain: ReadonlyArray<string>) {\n super(\n `Handoff loop exceeded max depth ${depth}. Chain: ${chain.join(\" -> \")}. ` +\n `Use Agent.create({ maxHandoffDepth: N }) to raise the cap.`,\n );\n this.depth = depth;\n this.chain = chain;\n }\n}\n\n/** Throw when the same (sender, receiver) pair invoked twice in one send() (D221). */\nexport class HandoffPairLoopError extends Error {\n override readonly name = \"HandoffPairLoopError\";\n readonly senderAgentId: string;\n readonly receiverAgentId: string;\n constructor(senderAgentId: string, receiverAgentId: string) {\n super(\n `Handoff loop: ${senderAgentId} -> ${receiverAgentId} already invoked in this send() call. ` +\n `Likely a ping-pong loop; revisit your handoff conditions.`,\n );\n this.senderAgentId = senderAgentId;\n this.receiverAgentId = receiverAgentId;\n }\n}\n\n/** Throw when an agent's `handoffs[]` includes a self-reference (EC-6). */\nexport class HandoffSelfReferenceError extends Error {\n override readonly name = \"HandoffSelfReferenceError\";\n readonly agentId: string;\n constructor(agentId: string) {\n super(\n `Agent \"${agentId}\" has a self-reference in its handoffs[]. ` +\n `Self-handoff causes infinite recursion; introduce a sibling agent for re-entry.`,\n );\n this.agentId = agentId;\n }\n}\n\n/** Throw when receiver is disposed at dispatch time (EC-5). */\nexport class HandoffReceiverDisposedError extends Error {\n override readonly name = \"HandoffReceiverDisposedError\";\n readonly receiverAgentId: string;\n constructor(receiverAgentId: string) {\n super(\n `Handoff target agent \"${receiverAgentId}\" is disposed. ` +\n `Don't dispose receivers while their parent is still active.`,\n );\n this.receiverAgentId = receiverAgentId;\n }\n}\n\n/** Throw when two handoffs in the same parent collide on tool name (D215). */\nexport class HandoffNameCollisionError extends Error {\n override readonly name = \"HandoffNameCollisionError\";\n readonly conflictingName: string;\n constructor(conflictingName: string) {\n super(\n `Two handoffs share the same tool name \"${conflictingName}\". ` +\n `Set { toolName } on at least one of them to disambiguate.`,\n );\n this.conflictingName = conflictingName;\n }\n}\n","/**\n * Handoff registry — pure state container per `Agent` instance.\n *\n * Holds the active dispatch chain (for depth + pair tracking) across the\n * lifetime of a single `agent.send()` call. Cleared between calls.\n *\n * @internal\n */\n\nimport { HandoffLoopError, HandoffPairLoopError } from \"../types/handoff.js\";\n\nexport interface HandoffChainState {\n /** Ordered chain of agentIds traversed so far (oldest first). */\n readonly chain: string[];\n /** Set of \"<sender>-><receiver>\" keys for pair-level loop detection (D221). */\n readonly seenPairs: Set<string>;\n /** Caller-supplied max depth (D218). */\n readonly maxDepth: number;\n}\n\nexport function createChainState(rootAgentId: string, maxDepth: number): HandoffChainState {\n return {\n chain: [rootAgentId],\n seenPairs: new Set(),\n maxDepth,\n };\n}\n\n/**\n * Record a handoff hop. Throws on depth-exceed (D218) or pair-loop (D221).\n * Mutates the state in place.\n */\nexport function recordHop(\n state: HandoffChainState,\n senderAgentId: string,\n receiverAgentId: string,\n): void {\n const pairKey = `${senderAgentId}->${receiverAgentId}`;\n if (state.seenPairs.has(pairKey)) {\n throw new HandoffPairLoopError(senderAgentId, receiverAgentId);\n }\n state.seenPairs.add(pairKey);\n state.chain.push(receiverAgentId);\n // chain.length = nodes; depth = hops = chain.length - 1.\n const depth = state.chain.length - 1;\n if (depth > state.maxDepth) {\n throw new HandoffLoopError(state.maxDepth, [...state.chain]);\n }\n}\n\nexport function currentDepth(state: HandoffChainState): number {\n return state.chain.length - 1;\n}\n","/**\n * D220 — Lazy-loaded OTel `handoff.transfer` span emitter.\n *\n * @internal\n */\n\n// Inline tracer-loader (same workaround as @theokit/sdk-cache/internal/telemetry.ts):\n// rollup-plugin-dts emits incomplete index.d.ts for newly-modified internal/ barrels\n// in @theokit/sdk. Runtime via the sub-path works; TypeScript users hit TS2305.\n// Inlining keeps sdk-handoff self-contained for the (small) observability hook.\nimport { createRequire } from \"node:module\";\n\ninterface SpanLike {\n setAttribute(key: string, value: string | number | boolean): SpanLike;\n end(): void;\n}\n\nconst _NOOP_SPAN: SpanLike = {\n setAttribute: () => _NOOP_SPAN,\n end: () => undefined,\n};\n\ninterface TracerLike {\n startSpan(\n name: string,\n options?: { attributes?: Record<string, string | number | boolean> },\n ): SpanLike;\n}\n\ninterface TracerCacheEntry {\n tracer: TracerLike | null;\n}\nconst tracerCache = new Map<string, TracerCacheEntry>();\n\nfunction getTracer(name: string, version = \"1.0.0\"): TracerLike | undefined {\n const cached = tracerCache.get(name);\n if (cached !== undefined) return cached.tracer ?? undefined;\n try {\n const r = createRequire(import.meta.url);\n const otel = r(\"@opentelemetry/api\") as {\n trace?: { getTracer: (n: string, v?: string) => TracerLike };\n };\n if (otel.trace?.getTracer === undefined) {\n tracerCache.set(name, { tracer: null });\n return undefined;\n }\n const tracer = otel.trace.getTracer(name, version);\n tracerCache.set(name, { tracer });\n return tracer;\n } catch {\n tracerCache.set(name, { tracer: null });\n return undefined;\n }\n}\n\nfunction resetTracerCacheForTests(): void {\n tracerCache.clear();\n}\n\nconst TRACER_NAME = \"theokit-sdk-handoff\";\n\ninterface HandoffSpanHandle {\n setAttribute(key: string, value: string | number | boolean): void;\n end(): void;\n}\n\nconst NOOP: HandoffSpanHandle = { setAttribute: () => undefined, end: () => undefined };\n\nfunction safe<T>(fn: () => T, fallback: T): T {\n try {\n return fn();\n } catch {\n return fallback;\n }\n}\n\nexport function startHandoffSpan(attrs: {\n from: string;\n to: string;\n reason: string;\n depth: number;\n toolName: string;\n}): HandoffSpanHandle {\n const tracer = getTracer(TRACER_NAME);\n if (tracer === undefined) return NOOP;\n const span: SpanLike | undefined = safe(\n () =>\n tracer.startSpan(\"handoff.transfer\", {\n attributes: {\n \"handoff.from\": attrs.from,\n \"handoff.to\": attrs.to,\n \"handoff.reason\": attrs.reason,\n \"handoff.depth\": attrs.depth,\n \"handoff.tool_name\": attrs.toolName,\n },\n }),\n undefined,\n );\n if (span === undefined) return NOOP;\n return {\n setAttribute: (k, v) => safe(() => span.setAttribute(k, v), undefined),\n end: () => safe(() => span.end(), undefined),\n };\n}\n\n/** Test-only — reset cached OTel handle. */\nfunction __resetHandoffOtelCacheForTests(): void {\n resetTracerCacheForTests();\n}\n","/**\n * Handoff dispatch orchestration.\n *\n * Pragmatic v1: when a handoff fires, the sender calls `receiver.send()`\n * with the (optionally filtered) history. The receiver's reply is returned\n * to the sender, which captures it as the answer to the user's question.\n *\n * NOTE: this is NOT pure peer-to-peer (the sender stays on the call stack\n * until the receiver returns). Pure intercept-and-swap requires deeper\n * agent-loop refactor; deferred to v2. v1 still validates the user-facing\n * value: \"agent A reasoned about routing, agent B answered.\"\n *\n * @internal\n */\n\nimport type { SDKAgent } from \"@theokit/sdk\";\nimport { z } from \"zod\";\nimport type {\n HandoffContext,\n HandoffDescriptor,\n HandoffHistory,\n HandoffResult,\n} from \"../types/handoff.js\";\nimport { HandoffReceiverDisposedError } from \"../types/handoff.js\";\nimport { type HandoffChainState, recordHop } from \"./registry.js\";\nimport { startHandoffSpan } from \"./telemetry.js\";\n\n/**\n * EC-2 / D228 — `safeFilter` wraps `inputFilter`. On exception, falls back\n * to the un-filtered history and warns to stderr once per process.\n */\nlet warnedFilterOnce = false;\nasync function safeFilter(\n filter: ((h: HandoffHistory) => HandoffHistory | Promise<HandoffHistory>) | undefined,\n history: HandoffHistory,\n): Promise<HandoffHistory> {\n if (filter === undefined) return history;\n try {\n const result = filter(history);\n return result instanceof Promise ? await result : result;\n } catch (err) {\n if (!warnedFilterOnce) {\n warnedFilterOnce = true;\n process.stderr.write(\n `[handoff] inputFilter threw, falling back to full history: ${err instanceof Error ? err.message : String(err)}\\n`,\n );\n }\n return history;\n }\n}\n\n/**\n * EC-4 / D229 — parse the LLM-provided JSON args. Returns undefined when\n * no `inputType` set; returns parsed value otherwise (default to `{}` on\n * empty/null input before Zod refinements).\n */\nfunction parseHandoffInput(descriptor: HandoffDescriptor, raw: unknown): unknown {\n const inputType = descriptor.options.inputType;\n if (inputType === undefined) return undefined;\n const candidate = raw === null || raw === undefined ? {} : raw;\n return inputType.parse(candidate);\n}\n\nfunction isAgentDisposed(agent: SDKAgent): boolean {\n // SDKAgent doesn't expose `disposed` publicly; check via duck-typing on\n // a known internal flag. Safe fallback: if we can't tell, assume alive.\n const maybe = agent as unknown as { disposed?: boolean };\n return maybe.disposed === true;\n}\n\n/**\n * Run a single handoff hop. Returns the receiver's reply text.\n *\n * Algorithm:\n * 1. EC-5: refuse if receiver disposed.\n * 2. Build HandoffContext.\n * 3. Check isEnabled() — if false, refuse with a clear error message.\n * 4. Parse inputType (D229).\n * 5. Run onHandoff(ctx, parsed) — throw aborts (D227).\n * 6. Apply inputFilter (safeFilter — D228).\n * 7. Record hop in chain state (depth + pair guards).\n * 8. Open OTel span (D220).\n * 9. Receiver: build the user-facing message and `await receiver.send(msg).then(wait)`.\n * 10. Close span + return reply.\n */\nasync function assertHandoffEnabled(\n descriptor: HandoffDescriptor,\n ctx: HandoffContext,\n receiverAgentId: string,\n): Promise<void> {\n const opt = descriptor.options.isEnabled;\n let enabled = true;\n if (typeof opt === \"boolean\") enabled = opt;\n else if (typeof opt === \"function\") {\n const r = opt(ctx);\n enabled = r instanceof Promise ? await r : r;\n }\n if (!enabled) {\n throw new Error(`Handoff to ${receiverAgentId} is disabled (isEnabled returned false)`);\n }\n}\n\nfunction parseAndValidate(descriptor: HandoffDescriptor, rawInputJson: unknown): unknown {\n try {\n return parseHandoffInput(descriptor, rawInputJson);\n } catch (err) {\n const detail =\n err instanceof z.ZodError\n ? (err.issues[0]?.message ?? \"schema_invalid\")\n : err instanceof Error\n ? err.message\n : String(err);\n throw new Error(`Handoff input validation failed: ${detail}`);\n }\n}\n\nasync function runOnHandoff(\n descriptor: HandoffDescriptor,\n ctx: HandoffContext,\n parsedInput: unknown,\n): Promise<void> {\n const onHandoff = descriptor.options.onHandoff;\n if (onHandoff === undefined) return;\n // biome-ignore lint/suspicious/noExplicitAny: parsedInput is typed unknown by design.\n const result = onHandoff(ctx, parsedInput as any);\n if (result instanceof Promise) await result;\n}\n\nfunction extractUserText(content: unknown): string | undefined {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return undefined;\n const text = content\n .filter((c): c is { type: \"text\"; text: string } => (c as { type?: string })?.type === \"text\")\n .map((c) => c.text)\n .join(\"\\n\");\n return text.length > 0 ? text : undefined;\n}\n\nfunction extractLastUserMessage(history: HandoffHistory, senderAgentId: string): string {\n for (let i = history.messages.length - 1; i >= 0; i -= 1) {\n const m = history.messages[i] as {\n type?: string;\n message?: { role?: string; content?: unknown };\n };\n if (m?.type !== \"user\" || m.message?.role !== \"user\") continue;\n const text = extractUserText(m.message.content);\n if (text !== undefined) return text;\n }\n return `(Handoff from ${senderAgentId} — no prior user message in history.)`;\n}\n\nexport async function dispatchHandoff(args: {\n descriptor: HandoffDescriptor;\n senderAgentId: string;\n chainState: HandoffChainState;\n rawInputJson: unknown;\n /** The conversation so far (history wrapper). v1: just the LAST user message. */\n history: HandoffHistory;\n /** Override the message text sent to the receiver. Used by `Agent.handoffTo` imperative. */\n messageOverride?: string;\n}): Promise<{ reply: string; result: HandoffResult }> {\n const { descriptor, senderAgentId, chainState, rawInputJson, history, messageOverride } = args;\n const receiver = descriptor.target;\n\n if (isAgentDisposed(receiver)) {\n throw new HandoffReceiverDisposedError(receiver.agentId);\n }\n\n const depthAfterThisHop = chainState.chain.length;\n const ctx: HandoffContext = {\n senderAgentId,\n receiverAgentId: receiver.agentId,\n currentDepth: depthAfterThisHop,\n chain: [...chainState.chain, receiver.agentId],\n };\n\n await assertHandoffEnabled(descriptor, ctx, receiver.agentId);\n const parsedInput = parseAndValidate(descriptor, rawInputJson);\n await runOnHandoff(descriptor, ctx, parsedInput);\n\n // Filter history (D228 — resilient)\n const filteredHistory = await safeFilter(descriptor.options.inputFilter, history);\n\n // Record hop — may throw HandoffLoopError or HandoffPairLoopError\n recordHop(chainState, senderAgentId, receiver.agentId);\n\n const lastUserMessage = messageOverride ?? extractLastUserMessage(filteredHistory, senderAgentId);\n const reason = extractReason(parsedInput);\n\n const span = startHandoffSpan({\n from: senderAgentId,\n to: receiver.agentId,\n reason,\n depth: depthAfterThisHop,\n toolName: descriptor.resolvedToolName,\n });\n\n try {\n const run = await receiver.send(lastUserMessage);\n const result = await run.wait();\n const reply = buildReply(result, receiver.agentId);\n return {\n reply,\n result: {\n from: senderAgentId,\n to: receiver.agentId,\n depth: depthAfterThisHop,\n toolName: descriptor.resolvedToolName,\n ...(reason !== \"\" ? { reasonFromLlm: reason } : {}),\n },\n };\n } finally {\n span.end();\n }\n}\n\nfunction extractReason(parsedInput: unknown): string {\n if (typeof parsedInput !== \"object\" || parsedInput === null) return \"\";\n if (!(\"reason\" in parsedInput)) return \"\";\n return String((parsedInput as { reason: unknown }).reason ?? \"\");\n}\n\nfunction buildReply(\n result: { status: string; result?: string; error?: { message: string } },\n receiverAgentId: string,\n): string {\n if (result.status === \"finished\" && result.result !== undefined) return result.result;\n const suffix = result.error !== undefined ? `: ${result.error.message}` : \"\";\n return `(Handoff target ${receiverAgentId} returned status=${result.status}${suffix})`;\n}\n","/**\n * Zod v4 → JSON Schema adapter for sdk-handoff.\n *\n * Uses Zod v4's native `z.toJSONSchema()` directly. v3 fallback removed\n * after zod-v4-migration plan (ADR D2).\n *\n * @internal\n */\n\nimport { toJSONSchema } from \"zod\";\n\ninterface ToJsonSchemaOptions {\n /** `\"any\"` keeps transforms/refinements as `{}` (loose). Default: `\"any\"`. */\n unrepresentable?: \"any\" | \"throw\";\n}\n\n/**\n * Convert a Zod schema to a JSON Schema object via Zod v4 native.\n *\n * @internal\n */\nexport function toJsonSchema(\n schema: unknown,\n options: ToJsonSchemaOptions = { unrepresentable: \"any\" },\n): Record<string, unknown> {\n // The schema param is `unknown` (callers pass `T extends ZodType` generics that\n // don't structurally satisfy Zod v4's `$ZodType`); cast to the exact parameter\n // type `toJSONSchema` expects rather than `any` — any z.* schema IS valid at runtime.\n return toJSONSchema(schema as Parameters<typeof toJSONSchema>[0], options) as Record<\n string,\n unknown\n >;\n}\n","/**\n * Convert `handoffs[]` entries into synthetic `transfer_to_<receiver>` tools\n * for injection into the agent's tool registry at construction time.\n *\n * The synthesized tool's handler calls `dispatchHandoff` internally and\n * returns the receiver's reply as `tool_result`. v1 trade-off documented\n * in dispatcher.ts.\n *\n * @internal\n */\n\nimport type { CustomTool, SDKAgent } from \"@theokit/sdk\";\nimport { z } from \"zod\";\nimport {\n type HandoffDescriptor,\n HandoffNameCollisionError,\n HandoffSelfReferenceError,\n} from \"../types/handoff.js\";\nimport { dispatchHandoff } from \"./dispatcher.js\";\nimport { createChainState } from \"./registry.js\";\nimport { toJsonSchema } from \"./to-json-schema.js\";\n\ninterface NormalizedHandoff {\n descriptor: HandoffDescriptor;\n}\n\n/**\n * Normalize each `handoffs[]` entry to a `HandoffDescriptor`. Raw `SDKAgent`\n * instances are auto-wrapped with default options. Validates:\n * - EC-6: no self-reference (would cause infinite recursion).\n * - D215: resolved tool names must be unique.\n */\nexport function normalizeHandoffs(\n parentAgentId: string,\n entries: ReadonlyArray<SDKAgent | HandoffDescriptor>,\n): NormalizedHandoff[] {\n if (entries.length === 0) return [];\n const out: NormalizedHandoff[] = [];\n const seenNames = new Set<string>();\n for (const entry of entries) {\n // Detect raw Agent vs HandoffDescriptor by presence of `.target`.\n const isDescriptor =\n typeof entry === \"object\" &&\n entry !== null &&\n \"target\" in entry &&\n \"options\" in entry &&\n \"resolvedToolName\" in entry;\n const descriptor = isDescriptor ? (entry as HandoffDescriptor) : autoWrap(entry as SDKAgent);\n if (descriptor.target.agentId === parentAgentId) {\n throw new HandoffSelfReferenceError(parentAgentId);\n }\n const name = descriptor.resolvedToolName;\n if (seenNames.has(name)) {\n throw new HandoffNameCollisionError(name);\n }\n seenNames.add(name);\n out.push({ descriptor });\n }\n return out;\n}\n\nfunction autoWrap(agent: SDKAgent): HandoffDescriptor {\n const name = resolveTargetName(agent);\n return {\n target: agent,\n options: {},\n resolvedToolName: `transfer_to_${name}`,\n };\n}\n\nfunction resolveTargetName(agent: SDKAgent): string {\n // Prefer a `name` field if exposed; fall back to a short agentId slug.\n const candidate = (agent as unknown as { name?: string }).name ?? agent.agentId ?? \"anonymous\";\n return slugify(candidate);\n}\n\nfunction slugify(input: string): string {\n return (\n input\n .replace(/^agent-/i, \"\")\n .replace(/[^a-zA-Z0-9_-]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 64) || \"anonymous\"\n );\n}\n\n/**\n * Build a `CustomTool` for one handoff descriptor. The handler dispatches\n * the handoff using a fresh chain state per `send()`-level invocation.\n *\n * NOTE: this v1 builds a NEW chain state per tool invocation. Pure\n * cross-tool depth tracking within one send() requires per-Agent context\n * — deferred. The single-flight pair guard catches direct ping-pong even\n * without cross-invocation chain (since each call wraps the same depth\n * counter from 1).\n */\nexport function buildHandoffTool(\n parentAgentId: string,\n descriptor: HandoffDescriptor,\n maxHandoffDepth: number,\n): CustomTool {\n const description =\n descriptor.options.toolDescription ??\n `Transfer the conversation to the ${descriptor.target.agentId} agent. ` +\n `Use this when the user's request matches their specialty.`;\n\n const inputZod =\n descriptor.options.inputType ??\n z.object({\n reason: z.string().optional().describe(\"Brief reason for the transfer (one short sentence).\"),\n });\n // CustomTool.inputSchema expects a JSON schema (Record<string, unknown>),\n // not the raw Zod type. Convert lazily so we don't fail when Zod is missing.\n // Universal Zod 3+4 conversion (feature-detects native v4, falls back to lib on v3).\n const inputSchema = toJsonSchema(inputZod);\n\n return {\n name: descriptor.resolvedToolName,\n description,\n inputSchema,\n handler: async (input: unknown): Promise<string> => {\n const chainState = createChainState(parentAgentId, maxHandoffDepth);\n try {\n const { reply, result } = await dispatchHandoff({\n descriptor,\n senderAgentId: parentAgentId,\n chainState,\n rawInputJson: input,\n history: { messages: [] }, // v1: history replay deferred\n });\n return JSON.stringify({\n ok: true,\n transferred_to: result.to,\n depth: result.depth,\n reply,\n });\n } catch (err) {\n return JSON.stringify({\n ok: false,\n error: err instanceof Error ? err.name : \"HandoffError\",\n message: err instanceof Error ? err.message : String(err),\n });\n }\n },\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theokit/sdk-handoff",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Inter-agent dispatch for @theokit/sdk — typed Handoff descriptors, loop protection, plugin-based wiring.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/usetheo/theokit-sdk#readme",
@@ -54,23 +54,23 @@
54
54
  "CHANGELOG.md",
55
55
  "LICENSE"
56
56
  ],
57
- "scripts": {
58
- "build": "tsup",
59
- "test": "vitest run",
60
- "typecheck": "tsc --noEmit"
61
- },
62
57
  "peerDependencies": {
63
- "@theokit/sdk": ">=1.7.0",
58
+ "@theokit/sdk": ">=4.0.0",
64
59
  "zod": "^4.0.0"
65
60
  },
66
61
  "devDependencies": {
67
62
  "tsup": "^8.3.5",
68
63
  "typescript": "^5.7.2",
69
64
  "vitest": "^4.1.8",
70
- "@theokit/sdk": "workspace:*",
71
- "zod": "^4.0.0"
65
+ "zod": "^4.0.0",
66
+ "@theokit/sdk": "4.2.0"
72
67
  },
73
68
  "publishConfig": {
74
69
  "access": "public"
70
+ },
71
+ "scripts": {
72
+ "build": "tsup",
73
+ "test": "vitest run",
74
+ "typecheck": "tsc --noEmit"
75
75
  }
76
- }
76
+ }