@assistant-ui/react 0.14.11 → 0.14.12

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.
Files changed (36) hide show
  1. package/dist/augmentations.d.ts.map +1 -1
  2. package/dist/context/react/utils/createContextHook.d.ts.map +1 -1
  3. package/dist/context/react/utils/createContextStoreHook.d.ts.map +1 -1
  4. package/dist/context/react/utils/createStateHookForRuntime.d.ts.map +1 -1
  5. package/dist/context/react/utils/createStateHookForRuntime.js.map +1 -1
  6. package/dist/context/react/utils/useRuntimeState.d.ts.map +1 -1
  7. package/dist/devtools/DevToolsHooks.d.ts.map +1 -1
  8. package/dist/devtools/DevToolsHooks.js.map +1 -1
  9. package/dist/index.d.ts +3 -3
  10. package/dist/index.js +3 -3
  11. package/dist/legacy-runtime/cloud/useCloudThreadListRuntime.d.ts.map +1 -1
  12. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.d.ts.map +1 -1
  13. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js.map +1 -1
  14. package/dist/legacy-runtime/runtime-cores/assistant-transport/useConvertedState.d.ts.map +1 -1
  15. package/dist/legacy-runtime/runtime-cores/assistant-transport/useLatestRef.d.ts.map +1 -1
  16. package/dist/mcp-apps/app-frame.d.ts.map +1 -1
  17. package/dist/primitives/composer/trigger/triggerKeyboardResource.js.map +1 -1
  18. package/dist/primitives/messagePart/MessagePartImage.js.map +1 -1
  19. package/dist/primitives/thread/useThreadViewportAutoScroll.d.ts.map +1 -1
  20. package/dist/primitives/thread/useThreadViewportAutoScroll.js +12 -2
  21. package/dist/primitives/thread/useThreadViewportAutoScroll.js.map +1 -1
  22. package/dist/unstable/useMentionAdapter.js.map +1 -1
  23. package/dist/unstable/useSlashCommandAdapter.js.map +1 -1
  24. package/dist/utils/Primitive.d.ts.map +1 -1
  25. package/package.json +8 -8
  26. package/src/augmentations.ts +0 -2
  27. package/src/context/react/utils/createStateHookForRuntime.ts +0 -1
  28. package/src/devtools/DevToolsHooks.ts +0 -4
  29. package/src/index.ts +6 -1
  30. package/src/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.ts +0 -12
  31. package/src/primitives/composer/trigger/triggerKeyboardResource.ts +0 -2
  32. package/src/primitives/messagePart/MessagePartImage.tsx +0 -1
  33. package/src/primitives/thread/useThreadViewportAutoScroll.ts +26 -2
  34. package/src/tests/ExternalStoreThreadRuntimeCore.test.ts +62 -0
  35. package/src/unstable/useMentionAdapter.ts +0 -3
  36. package/src/unstable/useSlashCommandAdapter.ts +0 -2
@@ -1 +1 @@
1
- {"version":3,"file":"augmentations.d.ts","names":[],"sources":["../src/augmentations.ts"],"mappings":";;AAuBA;;;;AAKgC;AAGhC;;;;;;;;;AAAsE;AACtE;;;;;;;kBATiB,SAAA;EAAA,UAEE,QAAA;EAAA,UAGA,aAAa;AAAA;AAAA,KAGpB,YAAA,GAAe,SAAA,CAAU,QAAA,OAAe,SAAA,CAAU,QAAQ;AAAA,KAC1D,iBAAA,SAA0B,SAAA,CAAU,aAAA,iBAC5C,MAAA,oBACA,SAAA,CAAU,aAAA,OAAoB,SAAA,CAAU,aAAA"}
1
+ {"version":3,"file":"augmentations.d.ts","names":[],"sources":["../src/augmentations.ts"],"mappings":";;AAuBA;;;;AAGgC;AAGhC;;;;;;;;;AAAsE;AACtE;;;;;;;kBAPiB,SAAA;EAAA,UACE,QAAA;EAAA,UAEA,aAAa;AAAA;AAAA,KAGpB,YAAA,GAAe,SAAA,CAAU,QAAA,OAAe,SAAA,CAAU,QAAQ;AAAA,KAC1D,iBAAA,SAA0B,SAAA,CAAU,aAAA,iBAC5C,MAAA,oBACA,SAAA,CAAU,aAAA,OAAoB,SAAA,CAAU,aAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"createContextHook.d.ts","names":[],"sources":["../../../../src/context/react/utils/createContextHook.ts"],"mappings":";;;;;AAUA;;;;iBAAgB,iBAAA,GAAA,CACd,OAAA,EAAS,OAAA,CAAQ,CAAA,UACjB,YAAA,YAAoB,OAAA;EAGlB,QAAA;AAAA,MACE,CAAA"}
1
+ {"version":3,"file":"createContextHook.d.ts","names":[],"sources":["../../../../src/context/react/utils/createContextHook.ts"],"mappings":";;;;;AAUA;;;;iBAAgB,iBAAA,IACd,OAAA,EAAS,OAAA,CAAQ,CAAA,UACjB,YAAA,YAAoB,OAAA;EAGlB,QAAA;AAAA,MACE,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"createContextStoreHook.d.ts","names":[],"sources":["../../../../src/context/react/utils/createContextStoreHook.ts"],"mappings":";;;;;AASA;;;;iBAAgB,sBAAA,oBAA0C,CAAA,UAAA,CACxD,WAAA,GAAc,OAAA;EAAY,QAAA;AAAA,MAAyB,CAAA,SACnD,UAAA,EAAY,CAAA,WA0DJ,CAAA;EAAA,0CAvDgD,CAAA;EAAA,YAiBzB,QAAA,GAClB,KAAA,EAAK,CAAA,CAAA,CAAA,UAAA,aAAA,YAlBsC,CAAA,aAkBtB,SAAA,GAC/B,SAAA;EAAA;IAC8B,QAAA;EAAA,KAAmB,CAAA,CAAA,CAAA,UAAA,aAAA,YApBI,CAAA;EAAA,YAqBzB,OAAA;IAC7B,QAAA;IACA,QAAA,IAAY,KAAA,EAAK,CAAA,CAAA,CAAA,UAAA,aAAA,YAvBqC,CAAA,aAuBrB,SAAA;EAAA,IAC/B,SAAA;AAAA,iBAiCO,CAAA;EAAA,IAtDmB,aAAA,CAAa,CAAA,CAAA,CAAA,UAAA,aAAA,YAHa,CAAA;EAAA;IAKtD,QAAA;EAAA,IACE,aAAA,CAAa,CAAA,CAAA,CAAA,UAAA,aAAA,YANuC,CAAA;AAAA"}
1
+ {"version":3,"file":"createContextStoreHook.d.ts","names":[],"sources":["../../../../src/context/react/utils/createContextStoreHook.ts"],"mappings":";;;;;AASA;;;;iBAAgB,sBAAA,oBAA0C,CAAA,WACxD,WAAA,GAAc,OAAA;EAAY,QAAA;AAAA,MAAyB,CAAA,SACnD,UAAA,EAAY,CAAA,WA0DJ,CAAA;EAAA,0CAvDgD,CAAA;EAAA,YAiBzB,QAAA,GAClB,KAAA,EAAK,CAAA,CAAA,CAAA,UAAA,aAAA,YAlBsC,CAAA,aAkBtB,SAAA,GAC/B,SAAA;EAAA;IAC8B,QAAA;EAAA,KAAmB,CAAA,CAAA,CAAA,UAAA,aAAA,YApBI,CAAA;EAAA,YAqBzB,OAAA;IAC7B,QAAA;IACA,QAAA,IAAY,KAAA,EAAK,CAAA,CAAA,CAAA,UAAA,aAAA,YAvBqC,CAAA,aAuBrB,SAAA;EAAA,IAC/B,SAAA;AAAA,iBAiCO,CAAA;EAAA,IAtDmB,aAAA,CAAa,CAAA,CAAA,CAAA,UAAA,aAAA,YAHa,CAAA;EAAA;IAKtD,QAAA;EAAA,IACE,aAAA,CAAa,CAAA,CAAA,CAAA,UAAA,aAAA,YANuC,CAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"createStateHookForRuntime.d.ts","names":[],"sources":["../../../../src/context/react/utils/createStateHookForRuntime.ts"],"mappings":";;;iBAKgB,yBAAA,QAAA,CACd,UAAA,GAAa,OAAA;EACX,QAAA;AAAA,MACI,mBAAA,CAAoB,MAAA;EAAA,IAGD,MAAA;EAAA,YAGM,QAAA,GAClB,KAAA,EAAO,MAAA,KAAW,SAAA,GAC5B,SAAA;EAAA,YAG4B,QAAA,IACjB,KAAA,EAAO,MAAA,KAAW,SAAA,gBAC7B,SAAA,GAAY,MAAA;EAAA;IAGkB,QAAA;EAAA,IAAiC,MAAA;EAAA;IAIhE,QAAA;EAAA,IACE,MAAA;EAAA,YAG2B,OAAA;IAC7B,QAAA;IACA,QAAA,GAAW,KAAA,EAAO,MAAA,KAAW,SAAA;EAAA,IAC3B,SAAA;EAAA,YAG2B,OAAA;IAC7B,QAAA;IACA,QAAA,IAAY,KAAA,EAAO,MAAA,KAAW,SAAA;EAAA,IAC5B,SAAA,GAAY,MAAA;EAAA,YAGe,OAAA;IAC7B,QAAA;IACA,QAAA,GAAW,KAAA,EAAO,MAAA,KAAW,SAAA;EAAA,IAC3B,SAAA;EAAA,YAG2B,OAAA;IAC7B,QAAA;IACA,QAAA,IAAY,KAAA,EAAO,MAAA,KAAW,SAAA;EAAA,IAC5B,SAAA,GAAY,MAAA;AAAA"}
1
+ {"version":3,"file":"createStateHookForRuntime.d.ts","names":[],"sources":["../../../../src/context/react/utils/createStateHookForRuntime.ts"],"mappings":";;;iBAKgB,yBAAA,SACd,UAAA,GAAa,OAAA;EACX,QAAA;AAAA,MACI,mBAAA,CAAoB,MAAA;EAAA,IAGD,MAAA;EAAA,YAGM,QAAA,GAClB,KAAA,EAAO,MAAA,KAAW,SAAA,GAC5B,SAAA;EAAA,YAG4B,QAAA,IACjB,KAAA,EAAO,MAAA,KAAW,SAAA,gBAC7B,SAAA,GAAY,MAAA;EAAA;IAGkB,QAAA;EAAA,IAAiC,MAAA;EAAA;IAIhE,QAAA;EAAA,IACE,MAAA;EAAA,YAG2B,OAAA;IAC7B,QAAA;IACA,QAAA,GAAW,KAAA,EAAO,MAAA,KAAW,SAAA;EAAA,IAC3B,SAAA;EAAA,YAG2B,OAAA;IAC7B,QAAA;IACA,QAAA,IAAY,KAAA,EAAO,MAAA,KAAW,SAAA;EAAA,IAC5B,SAAA,GAAY,MAAA;EAAA,YAGe,OAAA;IAC7B,QAAA;IACA,QAAA,GAAW,KAAA,EAAO,MAAA,KAAW,SAAA;EAAA,IAC3B,SAAA;EAAA,YAG2B,OAAA;IAC7B,QAAA;IACA,QAAA,IAAY,KAAA,EAAO,MAAA,KAAW,SAAA;EAAA,IAC5B,SAAA,GAAY,MAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"createStateHookForRuntime.js","names":[],"sources":["../../../../src/context/react/utils/createStateHookForRuntime.ts"],"sourcesContent":["import {\n type SubscribableRuntime,\n useRuntimeStateInternal,\n} from \"./useRuntimeState\";\n\nexport function createStateHookForRuntime<TState>(\n useRuntime: (options: {\n optional: boolean | undefined;\n }) => SubscribableRuntime<TState> | null,\n) {\n // empty\n function useStoreHook(): TState;\n\n // selector\n function useStoreHook<TSelected>(\n selector: (state: TState) => TSelected,\n ): TSelected;\n\n // selector?\n function useStoreHook<TSelected>(\n selector: ((state: TState) => TSelected) | undefined,\n ): TSelected | TState;\n\n // optional=false\n function useStoreHook(options: { optional?: false | undefined }): TState;\n\n // optional?\n function useStoreHook(options: {\n optional?: boolean | undefined;\n }): TState | null;\n\n // optional=false, selector\n function useStoreHook<TSelected>(options: {\n optional?: false | undefined;\n selector: (state: TState) => TSelected;\n }): TSelected;\n\n // optional=false, selector?\n function useStoreHook<TSelected>(options: {\n optional?: false | undefined;\n selector: ((state: TState) => TSelected) | undefined;\n }): TSelected | TState;\n\n // optional?, selector\n function useStoreHook<TSelected>(options: {\n optional?: boolean | undefined;\n selector: (state: TState) => TSelected;\n }): TSelected | null;\n\n // optional?, selector?\n function useStoreHook<TSelected>(options: {\n optional?: boolean | undefined;\n selector: ((state: TState) => TSelected) | undefined;\n }): TSelected | TState | null;\n\n function useStoreHook<TSelected>(\n param?:\n | ((state: TState) => TSelected)\n | {\n optional?: boolean | undefined;\n selector?: ((state: TState) => TSelected) | undefined;\n },\n ): TSelected | TState | null {\n let optional = false;\n let selector: ((state: TState) => TSelected) | undefined;\n\n if (typeof param === \"function\") {\n selector = param;\n } else if (param) {\n optional = !!param.optional;\n selector = param.selector;\n }\n\n const store = useRuntime({ optional });\n if (!store) return null;\n\n // it is ok to call useRuntimeStateInternal conditionally because it will never become null if its available\n // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage\n return useRuntimeStateInternal(store, selector);\n }\n\n return useStoreHook;\n}\n"],"mappings":";;AAKA,SAAgB,0BACd,YAGA;CA8CA,SAAS,aACP,OAM2B;EAC3B,IAAI,WAAW;EACf,IAAI;EAEJ,IAAI,OAAO,UAAU,YACnB,WAAW;OACN,IAAI,OAAO;GAChB,WAAW,CAAC,CAAC,MAAM;GACnB,WAAW,MAAM;EACnB;EAEA,MAAM,QAAQ,WAAW,EAAE,SAAS,CAAC;EACrC,IAAI,CAAC,OAAO,OAAO;EAInB,OAAO,wBAAwB,OAAO,QAAQ;CAChD;CAEA,OAAO;AACT"}
1
+ {"version":3,"file":"createStateHookForRuntime.js","names":[],"sources":["../../../../src/context/react/utils/createStateHookForRuntime.ts"],"sourcesContent":["import {\n type SubscribableRuntime,\n useRuntimeStateInternal,\n} from \"./useRuntimeState\";\n\nexport function createStateHookForRuntime<TState>(\n useRuntime: (options: {\n optional: boolean | undefined;\n }) => SubscribableRuntime<TState> | null,\n) {\n // empty\n function useStoreHook(): TState;\n\n // selector\n function useStoreHook<TSelected>(\n selector: (state: TState) => TSelected,\n ): TSelected;\n\n // selector?\n function useStoreHook<TSelected>(\n selector: ((state: TState) => TSelected) | undefined,\n ): TSelected | TState;\n\n // optional=false\n function useStoreHook(options: { optional?: false | undefined }): TState;\n\n // optional?\n function useStoreHook(options: {\n optional?: boolean | undefined;\n }): TState | null;\n\n // optional=false, selector\n function useStoreHook<TSelected>(options: {\n optional?: false | undefined;\n selector: (state: TState) => TSelected;\n }): TSelected;\n\n // optional=false, selector?\n function useStoreHook<TSelected>(options: {\n optional?: false | undefined;\n selector: ((state: TState) => TSelected) | undefined;\n }): TSelected | TState;\n\n // optional?, selector\n function useStoreHook<TSelected>(options: {\n optional?: boolean | undefined;\n selector: (state: TState) => TSelected;\n }): TSelected | null;\n\n // optional?, selector?\n function useStoreHook<TSelected>(options: {\n optional?: boolean | undefined;\n selector: ((state: TState) => TSelected) | undefined;\n }): TSelected | TState | null;\n\n function useStoreHook<TSelected>(\n param?:\n | ((state: TState) => TSelected)\n | {\n optional?: boolean | undefined;\n selector?: ((state: TState) => TSelected) | undefined;\n },\n ): TSelected | TState | null {\n let optional = false;\n let selector: ((state: TState) => TSelected) | undefined;\n\n if (typeof param === \"function\") {\n selector = param;\n } else if (param) {\n optional = !!param.optional;\n selector = param.selector;\n }\n\n const store = useRuntime({ optional });\n if (!store) return null;\n\n // it is ok to call useRuntimeStateInternal conditionally because it will never become null if its available\n return useRuntimeStateInternal(store, selector);\n }\n\n return useStoreHook;\n}\n"],"mappings":";;AAKA,SAAgB,0BACd,YAGA;CA8CA,SAAS,aACP,OAM2B;EAC3B,IAAI,WAAW;EACf,IAAI;EAEJ,IAAI,OAAO,UAAU,YACnB,WAAW;OACN,IAAI,OAAO;GAChB,WAAW,CAAC,CAAC,MAAM;GACnB,WAAW,MAAM;EACnB;EAEA,MAAM,QAAQ,WAAW,EAAE,SAAS,CAAC;EACrC,IAAI,CAAC,OAAO,OAAO;EAGnB,OAAO,wBAAwB,OAAO,QAAQ;CAChD;CAEA,OAAO;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"useRuntimeState.d.ts","names":[],"sources":["../../../../src/context/react/utils/useRuntimeState.ts"],"mappings":";;;KAIY,mBAAA;EACV,QAAA,QAAgB,MAAA;EAChB,SAAA,GAAY,QAAA,iBAAyB,WAAW;AAAA;AAAA,iBAGlC,uBAAA,mBAAA,CACd,OAAA,EAAS,mBAAA,CAAoB,MAAA,GAC7B,QAAA,KAAY,KAAA,EAAO,MAAA,KAAW,SAAA,GAAY,MAAA,gBACzC,SAAA,GAAY,MAAA;AAAA,iBAcC,eAAA,QAAA,CACd,OAAA,EAAS,mBAAA,CAAoB,MAAA,IAC5B,MAAA;AAAA,iBACa,eAAA,mBAAA,CACd,OAAA,EAAS,mBAAA,CAAoB,MAAA,GAC7B,QAAA,GAAW,KAAA,EAAO,MAAA,KAAW,SAAA,GAC5B,SAAA;AAAA,iBACa,eAAA,mBAAA,CACd,OAAA,EAAS,mBAAA,CAAoB,MAAA,GAC7B,QAAA,IAAY,KAAA,EAAO,MAAA,KAAW,SAAA,gBAC7B,SAAA,GAAY,MAAA"}
1
+ {"version":3,"file":"useRuntimeState.d.ts","names":[],"sources":["../../../../src/context/react/utils/useRuntimeState.ts"],"mappings":";;;KAIY,mBAAA;EACV,QAAA,QAAgB,MAAA;EAChB,SAAA,GAAY,QAAA,iBAAyB,WAAW;AAAA;AAAA,iBAGlC,uBAAA,oBACd,OAAA,EAAS,mBAAA,CAAoB,MAAA,GAC7B,QAAA,KAAY,KAAA,EAAO,MAAA,KAAW,SAAA,GAAY,MAAA,gBACzC,SAAA,GAAY,MAAA;AAAA,iBAcC,eAAA,SACd,OAAA,EAAS,mBAAA,CAAoB,MAAA,IAC5B,MAAA;AAAA,iBACa,eAAA,oBACd,OAAA,EAAS,mBAAA,CAAoB,MAAA,GAC7B,QAAA,GAAW,KAAA,EAAO,MAAA,KAAW,SAAA,GAC5B,SAAA;AAAA,iBACa,eAAA,oBACd,OAAA,EAAS,mBAAA,CAAoB,MAAA,GAC7B,QAAA,IAAY,KAAA,EAAO,MAAA,KAAW,SAAA,gBAC7B,SAAA,GAAY,MAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"DevToolsHooks.d.ts","names":[],"sources":["../../src/devtools/DevToolsHooks.ts"],"mappings":";;;;UAGiB,QAAA;EACf,IAAA,EAAM,IAAI;EACV,KAAA;EACA,IAAA;AAAA;AAAA,UAGQ,gBAAA;EACR,GAAA,EAAK,OAAA,CAAQ,eAAA;EACb,IAAA,EAAM,QAAA;AAAA;AAAA,UAGE,YAAA;EACR,IAAA,EAAM,GAAA,SAAY,gBAAA;EAClB,MAAA;EACA,SAAA,EAAW,GAAA,EAAK,KAAA;AAAA;AAAA,QAGV,MAAA;EAAA,UACI,MAAA;IACR,8BAAA,GAAiC,YAAY;EAAA;AAAA;AAAA,cAmCpC,aAAA;EAAA,OACJ,SAAA,CAAU,QAAA,eAAuB,WAAA;EAAA,OAQjC,cAAA,CAAe,KAAA;EAAA,OASf,OAAA,CAAA,GAAW,GAAA,SAAY,gBAAA;EAAA,eAIf,eAAA;AAAA;AAAA,cAQJ,mBAAA;EAAA,wBACa,sBAAA;EAAA,OAEjB,QAAA,CAAS,GAAA,EAAK,OAAA,CAAQ,eAAA,IAAmB,WAAA;EAAA,eAuDjC,eAAA;AAAA"}
1
+ {"version":3,"file":"DevToolsHooks.d.ts","names":[],"sources":["../../src/devtools/DevToolsHooks.ts"],"mappings":";;;;UAGiB,QAAA;EACf,IAAA,EAAM,IAAI;EACV,KAAA;EACA,IAAA;AAAA;AAAA,UAGQ,gBAAA;EACR,GAAA,EAAK,OAAA,CAAQ,eAAA;EACb,IAAA,EAAM,QAAA;AAAA;AAAA,UAGE,YAAA;EACR,IAAA,EAAM,GAAA,SAAY,gBAAA;EAClB,MAAA;EACA,SAAA,EAAW,GAAA,EAAK,KAAA;AAAA;AAAA,QAGV,MAAA;EAAA,UACI,MAAA;IACR,8BAAA,GAAiC,YAAY;EAAA;AAAA;AAAA,cAkCpC,aAAA;EAAA,OACJ,SAAA,CAAU,QAAA,eAAuB,WAAA;EAAA,OAQjC,cAAA,CAAe,KAAA;EAAA,OASf,OAAA,IAAW,GAAA,SAAY,gBAAA;EAAA,eAIf,eAAA;AAAA;AAAA,cAMJ,mBAAA;EAAA,wBACa,sBAAA;EAAA,OAEjB,QAAA,CAAS,GAAA,EAAK,OAAA,CAAQ,eAAA,IAAmB,WAAA;EAAA,eAuDjC,eAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"DevToolsHooks.js","names":[],"sources":["../../src/devtools/DevToolsHooks.ts"],"sourcesContent":["import type { Unsubscribe } from \"@assistant-ui/core\";\nimport type { AssistantClient } from \"@assistant-ui/store\";\n\nexport interface EventLog {\n time: Date;\n event: string;\n data: unknown;\n}\n\ninterface DevToolsApiEntry {\n api: Partial<AssistantClient>;\n logs: EventLog[];\n}\n\ninterface DevToolsHook {\n apis: Map<number, DevToolsApiEntry>;\n nextId: number;\n listeners: Set<(apiId: number) => void>;\n}\n\ndeclare global {\n interface Window {\n __ASSISTANT_UI_DEVTOOLS_HOOK__?: DevToolsHook;\n }\n}\n\nlet cachedHook: DevToolsHook | undefined;\n\nconst getHook = (): DevToolsHook => {\n if (cachedHook) {\n return cachedHook;\n }\n\n const createHook = (): DevToolsHook => ({\n apis: new Map(),\n nextId: 0,\n listeners: new Set(),\n });\n\n if (typeof window === \"undefined\") {\n cachedHook = createHook();\n return cachedHook;\n }\n\n const existingHook = window.__ASSISTANT_UI_DEVTOOLS_HOOK__;\n if (existingHook) {\n cachedHook = existingHook;\n return existingHook;\n }\n\n const newHook = createHook();\n window.__ASSISTANT_UI_DEVTOOLS_HOOK__ = newHook;\n cachedHook = newHook;\n return newHook;\n};\n\n// biome-ignore lint/complexity/noStaticOnlyClass: intentional namespace for DevTools API\nexport class DevToolsHooks {\n static subscribe(listener: () => void): Unsubscribe {\n const hook = getHook();\n hook.listeners.add(listener);\n return () => {\n hook.listeners.delete(listener);\n };\n }\n\n static clearEventLogs(apiId: number): void {\n const hook = getHook();\n const entry = hook.apis.get(apiId);\n if (!entry) return;\n\n entry.logs = [];\n DevToolsHooks.notifyListeners(apiId);\n }\n\n static getApis(): Map<number, DevToolsApiEntry> {\n return getHook().apis;\n }\n\n private static notifyListeners(apiId: number): void {\n const hook = getHook();\n // biome-ignore lint/suspicious/useIterableCallbackReturn: forEach callback intentionally has no return\n hook.listeners.forEach((listener) => listener(apiId));\n }\n}\n\n// biome-ignore lint/complexity/noStaticOnlyClass: intentional namespace for DevTools API\nexport class DevToolsProviderApi {\n private static readonly MAX_EVENT_LOGS_PER_API = 200;\n\n static register(aui: Partial<AssistantClient>): Unsubscribe {\n const hook = getHook();\n\n for (const entry of hook.apis.values()) {\n if (entry.api === aui) {\n return () => {};\n }\n }\n\n const apiId = hook.nextId++;\n const entry: DevToolsApiEntry = {\n api: aui,\n logs: [],\n };\n\n const eventUnsubscribe = aui.on?.(\"*\", (e) => {\n const entry = hook.apis.get(apiId);\n if (!entry) return;\n\n entry.logs.push({\n time: new Date(),\n event: e.event,\n data: e.payload,\n });\n\n if (entry.logs.length > DevToolsProviderApi.MAX_EVENT_LOGS_PER_API) {\n entry.logs = entry.logs.slice(\n -DevToolsProviderApi.MAX_EVENT_LOGS_PER_API,\n );\n }\n\n DevToolsProviderApi.notifyListeners(apiId);\n });\n\n const stateUnsubscribe = aui.subscribe?.(() => {\n DevToolsProviderApi.notifyListeners(apiId);\n });\n\n hook.apis.set(apiId, entry);\n DevToolsProviderApi.notifyListeners(apiId);\n\n return () => {\n const hook = getHook();\n const entry = hook.apis.get(apiId);\n if (!entry) return;\n\n eventUnsubscribe?.();\n stateUnsubscribe?.();\n\n hook.apis.delete(apiId);\n\n DevToolsProviderApi.notifyListeners(apiId);\n };\n }\n\n private static notifyListeners(apiId: number): void {\n const hook = getHook();\n // biome-ignore lint/suspicious/useIterableCallbackReturn: forEach callback intentionally has no return\n hook.listeners.forEach((listener) => listener(apiId));\n }\n}\n"],"mappings":";AA0BA,IAAI;AAEJ,MAAM,gBAA8B;CAClC,IAAI,YACF,OAAO;CAGT,MAAM,oBAAkC;EACtC,sBAAM,IAAI,IAAI;EACd,QAAQ;EACR,2BAAW,IAAI,IAAI;CACrB;CAEA,IAAI,OAAO,WAAW,aAAa;EACjC,aAAa,WAAW;EACxB,OAAO;CACT;CAEA,MAAM,eAAe,OAAO;CAC5B,IAAI,cAAc;EAChB,aAAa;EACb,OAAO;CACT;CAEA,MAAM,UAAU,WAAW;CAC3B,OAAO,iCAAiC;CACxC,aAAa;CACb,OAAO;AACT;AAGA,IAAa,gBAAb,MAAa,cAAc;CACzB,OAAO,UAAU,UAAmC;EAClD,MAAM,OAAO,QAAQ;EACrB,KAAK,UAAU,IAAI,QAAQ;EAC3B,aAAa;GACX,KAAK,UAAU,OAAO,QAAQ;EAChC;CACF;CAEA,OAAO,eAAe,OAAqB;EAEzC,MAAM,QADO,QACI,EAAE,KAAK,IAAI,KAAK;EACjC,IAAI,CAAC,OAAO;EAEZ,MAAM,OAAO,CAAC;EACd,cAAc,gBAAgB,KAAK;CACrC;CAEA,OAAO,UAAyC;EAC9C,OAAO,QAAQ,EAAE;CACnB;CAEA,OAAe,gBAAgB,OAAqB;EAGlD,QAAG,EAAE,UAAU,SAAS,aAAa,SAAS,KAAK,CAAC;CACtD;AACF;AAGA,IAAa,sBAAb,MAAa,oBAAoB;CAC/B,OAAwB,yBAAyB;CAEjD,OAAO,SAAS,KAA4C;EAC1D,MAAM,OAAO,QAAQ;EAErB,KAAK,MAAM,SAAS,KAAK,KAAK,OAAO,GACnC,IAAI,MAAM,QAAQ,KAChB,aAAa,CAAC;EAIlB,MAAM,QAAQ,KAAK;EACnB,MAAM,QAA0B;GAC9B,KAAK;GACL,MAAM,CAAC;EACT;EAEA,MAAM,mBAAmB,IAAI,KAAK,MAAM,MAAM;GAC5C,MAAM,QAAQ,KAAK,KAAK,IAAI,KAAK;GACjC,IAAI,CAAC,OAAO;GAEZ,MAAM,KAAK,KAAK;IACd,sBAAM,IAAI,KAAK;IACf,OAAO,EAAE;IACT,MAAM,EAAE;GACV,CAAC;GAED,IAAI,MAAM,KAAK,SAAS,oBAAoB,wBAC1C,MAAM,OAAO,MAAM,KAAK,MACtB,CAAC,oBAAoB,sBACvB;GAGF,oBAAoB,gBAAgB,KAAK;EAC3C,CAAC;EAED,MAAM,mBAAmB,IAAI,kBAAkB;GAC7C,oBAAoB,gBAAgB,KAAK;EAC3C,CAAC;EAED,KAAK,KAAK,IAAI,OAAO,KAAK;EAC1B,oBAAoB,gBAAgB,KAAK;EAEzC,aAAa;GACX,MAAM,OAAO,QAAQ;GAErB,IAAI,CADU,KAAK,KAAK,IAAI,KACnB,GAAG;GAEZ,mBAAmB;GACnB,mBAAmB;GAEnB,KAAK,KAAK,OAAO,KAAK;GAEtB,oBAAoB,gBAAgB,KAAK;EAC3C;CACF;CAEA,OAAe,gBAAgB,OAAqB;EAGlD,QAAG,EAAE,UAAU,SAAS,aAAa,SAAS,KAAK,CAAC;CACtD;AACF"}
1
+ {"version":3,"file":"DevToolsHooks.js","names":[],"sources":["../../src/devtools/DevToolsHooks.ts"],"sourcesContent":["import type { Unsubscribe } from \"@assistant-ui/core\";\nimport type { AssistantClient } from \"@assistant-ui/store\";\n\nexport interface EventLog {\n time: Date;\n event: string;\n data: unknown;\n}\n\ninterface DevToolsApiEntry {\n api: Partial<AssistantClient>;\n logs: EventLog[];\n}\n\ninterface DevToolsHook {\n apis: Map<number, DevToolsApiEntry>;\n nextId: number;\n listeners: Set<(apiId: number) => void>;\n}\n\ndeclare global {\n interface Window {\n __ASSISTANT_UI_DEVTOOLS_HOOK__?: DevToolsHook;\n }\n}\n\nlet cachedHook: DevToolsHook | undefined;\n\nconst getHook = (): DevToolsHook => {\n if (cachedHook) {\n return cachedHook;\n }\n\n const createHook = (): DevToolsHook => ({\n apis: new Map(),\n nextId: 0,\n listeners: new Set(),\n });\n\n if (typeof window === \"undefined\") {\n cachedHook = createHook();\n return cachedHook;\n }\n\n const existingHook = window.__ASSISTANT_UI_DEVTOOLS_HOOK__;\n if (existingHook) {\n cachedHook = existingHook;\n return existingHook;\n }\n\n const newHook = createHook();\n window.__ASSISTANT_UI_DEVTOOLS_HOOK__ = newHook;\n cachedHook = newHook;\n return newHook;\n};\n\nexport class DevToolsHooks {\n static subscribe(listener: () => void): Unsubscribe {\n const hook = getHook();\n hook.listeners.add(listener);\n return () => {\n hook.listeners.delete(listener);\n };\n }\n\n static clearEventLogs(apiId: number): void {\n const hook = getHook();\n const entry = hook.apis.get(apiId);\n if (!entry) return;\n\n entry.logs = [];\n DevToolsHooks.notifyListeners(apiId);\n }\n\n static getApis(): Map<number, DevToolsApiEntry> {\n return getHook().apis;\n }\n\n private static notifyListeners(apiId: number): void {\n const hook = getHook();\n hook.listeners.forEach((listener) => listener(apiId));\n }\n}\n\nexport class DevToolsProviderApi {\n private static readonly MAX_EVENT_LOGS_PER_API = 200;\n\n static register(aui: Partial<AssistantClient>): Unsubscribe {\n const hook = getHook();\n\n for (const entry of hook.apis.values()) {\n if (entry.api === aui) {\n return () => {};\n }\n }\n\n const apiId = hook.nextId++;\n const entry: DevToolsApiEntry = {\n api: aui,\n logs: [],\n };\n\n const eventUnsubscribe = aui.on?.(\"*\", (e) => {\n const entry = hook.apis.get(apiId);\n if (!entry) return;\n\n entry.logs.push({\n time: new Date(),\n event: e.event,\n data: e.payload,\n });\n\n if (entry.logs.length > DevToolsProviderApi.MAX_EVENT_LOGS_PER_API) {\n entry.logs = entry.logs.slice(\n -DevToolsProviderApi.MAX_EVENT_LOGS_PER_API,\n );\n }\n\n DevToolsProviderApi.notifyListeners(apiId);\n });\n\n const stateUnsubscribe = aui.subscribe?.(() => {\n DevToolsProviderApi.notifyListeners(apiId);\n });\n\n hook.apis.set(apiId, entry);\n DevToolsProviderApi.notifyListeners(apiId);\n\n return () => {\n const hook = getHook();\n const entry = hook.apis.get(apiId);\n if (!entry) return;\n\n eventUnsubscribe?.();\n stateUnsubscribe?.();\n\n hook.apis.delete(apiId);\n\n DevToolsProviderApi.notifyListeners(apiId);\n };\n }\n\n private static notifyListeners(apiId: number): void {\n const hook = getHook();\n hook.listeners.forEach((listener) => listener(apiId));\n }\n}\n"],"mappings":";AA0BA,IAAI;AAEJ,MAAM,gBAA8B;CAClC,IAAI,YACF,OAAO;CAGT,MAAM,oBAAkC;EACtC,sBAAM,IAAI,IAAI;EACd,QAAQ;EACR,2BAAW,IAAI,IAAI;CACrB;CAEA,IAAI,OAAO,WAAW,aAAa;EACjC,aAAa,WAAW;EACxB,OAAO;CACT;CAEA,MAAM,eAAe,OAAO;CAC5B,IAAI,cAAc;EAChB,aAAa;EACb,OAAO;CACT;CAEA,MAAM,UAAU,WAAW;CAC3B,OAAO,iCAAiC;CACxC,aAAa;CACb,OAAO;AACT;AAEA,IAAa,gBAAb,MAAa,cAAc;CACzB,OAAO,UAAU,UAAmC;EAClD,MAAM,OAAO,QAAQ;EACrB,KAAK,UAAU,IAAI,QAAQ;EAC3B,aAAa;GACX,KAAK,UAAU,OAAO,QAAQ;EAChC;CACF;CAEA,OAAO,eAAe,OAAqB;EAEzC,MAAM,QADO,QACI,EAAE,KAAK,IAAI,KAAK;EACjC,IAAI,CAAC,OAAO;EAEZ,MAAM,OAAO,CAAC;EACd,cAAc,gBAAgB,KAAK;CACrC;CAEA,OAAO,UAAyC;EAC9C,OAAO,QAAQ,EAAE;CACnB;CAEA,OAAe,gBAAgB,OAAqB;EAElD,QAAG,EAAE,UAAU,SAAS,aAAa,SAAS,KAAK,CAAC;CACtD;AACF;AAEA,IAAa,sBAAb,MAAa,oBAAoB;CAC/B,OAAwB,yBAAyB;CAEjD,OAAO,SAAS,KAA4C;EAC1D,MAAM,OAAO,QAAQ;EAErB,KAAK,MAAM,SAAS,KAAK,KAAK,OAAO,GACnC,IAAI,MAAM,QAAQ,KAChB,aAAa,CAAC;EAIlB,MAAM,QAAQ,KAAK;EACnB,MAAM,QAA0B;GAC9B,KAAK;GACL,MAAM,CAAC;EACT;EAEA,MAAM,mBAAmB,IAAI,KAAK,MAAM,MAAM;GAC5C,MAAM,QAAQ,KAAK,KAAK,IAAI,KAAK;GACjC,IAAI,CAAC,OAAO;GAEZ,MAAM,KAAK,KAAK;IACd,sBAAM,IAAI,KAAK;IACf,OAAO,EAAE;IACT,MAAM,EAAE;GACV,CAAC;GAED,IAAI,MAAM,KAAK,SAAS,oBAAoB,wBAC1C,MAAM,OAAO,MAAM,KAAK,MACtB,CAAC,oBAAoB,sBACvB;GAGF,oBAAoB,gBAAgB,KAAK;EAC3C,CAAC;EAED,MAAM,mBAAmB,IAAI,kBAAkB;GAC7C,oBAAoB,gBAAgB,KAAK;EAC3C,CAAC;EAED,KAAK,KAAK,IAAI,OAAO,KAAK;EAC1B,oBAAoB,gBAAgB,KAAK;EAEzC,aAAa;GACX,MAAM,OAAO,QAAQ;GAErB,IAAI,CADU,KAAK,KAAK,IAAI,KACnB,GAAG;GAEZ,mBAAmB;GACnB,mBAAmB;GAEnB,KAAK,KAAK,OAAO,KAAK;GAEtB,oBAAoB,gBAAgB,KAAK;EAC3C;CACF;CAEA,OAAe,gBAAgB,OAAqB;EAElD,QAAG,EAAE,UAAU,SAAS,aAAa,SAAS,KAAK,CAAC;CACtD;AACF"}
package/dist/index.d.ts CHANGED
@@ -74,9 +74,9 @@ import { McpAppRenderer, McpAppRendererOptions } from "./mcp-apps/McpAppRenderer
74
74
  import { McpAppsRemoteHost } from "./mcp-apps/McpAppsRemoteHost.js";
75
75
  import { getMcpAppFromToolPart } from "./mcp-apps/utils.js";
76
76
  import { AssistantClient, AssistantEventCallback, AssistantEventName, AssistantEventPayload, AssistantEventScope, AssistantEventSelector, AssistantState, AuiIf, AuiProvider, useAui, useAuiEvent, useAuiState } from "@assistant-ui/store";
77
- import { AssistantContextConfig, AssistantDataUI, AssistantDataUIProps, AssistantInteractableProps, AssistantTool, AssistantToolProps, AssistantToolUI, AssistantToolUIProps, DataMessagePartComponent, DataMessagePartProps, DataRenderers, EmptyMessagePartComponent, EmptyMessagePartProps, EnrichedPartState, FileMessagePartComponent, FileMessagePartProps, GenerativeUIComponentRegistry, GenerativeUIMessagePartComponent, GenerativeUIMessagePartProps, GenerativeUIRender, GenerativeUIRenderError, GenerativeUIRenderProps, ImageMessagePartComponent, ImageMessagePartProps, Interactables, McpAppResourceOutput, PartState, QuoteMessagePartComponent, QuoteMessagePartProps, ReasoningGroupComponent, ReasoningGroupProps, ReasoningMessagePartComponent, ReasoningMessagePartProps, RuntimeAdapterProvider, RuntimeAdapters, SourceMessagePartComponent, SourceMessagePartProps, TextMessagePartComponent, TextMessagePartProps, ToolArgsStatus, ToolCallMessagePartComponent, ToolCallMessagePartProps, ToolDefinition, Toolkit, Tools, Unstable_AudioMessagePartComponent, Unstable_AudioMessagePartProps, groupPartByType, makeAssistantDataUI, makeAssistantTool, makeAssistantToolUI, useAssistantContext, useAssistantDataUI, useAssistantInstructions, useAssistantInteractable, useAssistantTool, useAssistantToolUI, useInlineRender, useInteractableState, useRuntimeAdapters, useToolArgsStatus, useVoiceControls, useVoiceState, useVoiceVolume } from "@assistant-ui/core/react";
77
+ import { AssistantContextConfig, AssistantDataUI, AssistantDataUIProps, AssistantInteractableProps, AssistantTool, AssistantToolProps, AssistantToolUI, AssistantToolUIProps, DataMessagePartComponent, DataMessagePartProps, DataRenderers, EmptyMessagePartComponent, EmptyMessagePartProps, EnrichedPartState, FileMessagePartComponent, FileMessagePartProps, GenerativeUIComponentRegistry, GenerativeUIMessagePartComponent, GenerativeUIMessagePartProps, GenerativeUIRender, GenerativeUIRenderError, GenerativeUIRenderProps, GroupByContext, ImageMessagePartComponent, ImageMessagePartProps, Interactables, McpAppResourceOutput, PartState, QuoteMessagePartComponent, QuoteMessagePartProps, ReasoningGroupComponent, ReasoningGroupProps, ReasoningMessagePartComponent, ReasoningMessagePartProps, RuntimeAdapterProvider, RuntimeAdapters, SourceMessagePartComponent, SourceMessagePartProps, TextMessagePartComponent, TextMessagePartProps, ToolArgsStatus, ToolCallMessagePartComponent, ToolCallMessagePartProps, ToolDefinition, Toolkit, ToolkitDeclaration, ToolkitDeclarationDefinition, Tools, Unstable_AudioMessagePartComponent, Unstable_AudioMessagePartProps, groupPartByType, makeAssistantDataUI, makeAssistantTool, makeAssistantToolUI, useAssistantContext, useAssistantDataUI, useAssistantInstructions, useAssistantInteractable, useAssistantTool, useAssistantToolUI, useExternalStoreSharedOptions, useInlineRender, useInteractableState, useRuntimeAdapters, useToolArgsStatus, useVoiceControls, useVoiceState, useVoiceVolume } from "@assistant-ui/core/react";
78
78
  import { AssistantCloud } from "assistant-cloud";
79
- import { AddToolResultOptions, AppendMessage, AssistantFrameHost, AssistantFrameProvider, AssistantRuntime, Attachment, AttachmentAdapter, AttachmentRuntime, AttachmentState, AttachmentStatus, ChatModelAdapter, ChatModelRunOptions, ChatModelRunResult, ChatModelRunUpdate, CompleteAttachment, ComposerRuntime, ComposerState, CompositeAttachmentAdapter, CreateAppendMessage, CreateAttachment, CreateResumeRunConfig, CreateStartRunConfig, DataMessagePart, DictationAdapter, DictationState, EditComposerRuntime, EditComposerState, ExportedMessageRepository, ExportedMessageRepositoryItem, ExternalStoreAdapter, ExternalStoreMessageConverter, ExternalStoreThreadData, ExternalStoreThreadListAdapter, FRAME_MESSAGE_CHANNEL, FeedbackAdapter, FileMessagePart, FrameMessage, FrameMessageType, GenerativeUIMessagePart, GenerativeUINode, GenerativeUISpec, GenericThreadHistoryAdapter, ImageMessagePart, InMemoryThreadListAdapter, LanguageModelConfig, LanguageModelV1CallSettings, LocalRuntimeOptionsBase, MessageFormatAdapter, MessageFormatItem, MessageFormatRepository, MessagePartRuntime, MessagePartState, MessagePartStatus, MessageRuntime, MessageState, MessageStatus, MessageStorageEntry, MessageTiming, ModelContext, ModelContextProvider, ModelContextRegistry, ModelContextRegistryInstructionHandle, ModelContextRegistryProviderHandle, ModelContextRegistryToolHandle, PendingAttachment, QuoteInfo, RealtimeVoiceAdapter, ReasoningMessagePart, RemoteThreadListAdapter, SerializedModelContext, SerializedTool, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, SourceMessagePart, SourceProviderMetadata, SpeechSynthesisAdapter, SubmitFeedbackOptions, SuggestionAdapter, TextMessagePart, ThreadAssistantMessage, ThreadAssistantMessagePart, ThreadComposerRuntime, ThreadComposerState, ThreadHistoryAdapter, ThreadListItemRuntime, ThreadListItemState, ThreadListItemStatus, ThreadListRuntime, ThreadListState, ThreadMessage, ThreadMessageLike, ThreadRuntime, ThreadState, ThreadSuggestion, ThreadSystemMessage, ThreadUserMessage, ThreadUserMessagePart, ToolCallMessagePart, ToolCallMessagePartStatus, ToolModelContentPart, Unstable_AudioMessagePart, Unstable_DirectiveFormatter, Unstable_DirectiveSegment, Unstable_TriggerItem, Unsubscribe, VoiceSessionControls, VoiceSessionHelpers, VoiceSessionState, WebSpeechDictationAdapter, WebSpeechSynthesisAdapter, bindExternalStoreMessage, createVoiceSession, getExternalStoreMessages, mergeModelContexts, tool, unstable_defaultDirectiveFormatter } from "@assistant-ui/core";
79
+ import { AddToolResultOptions, AppendMessage, AssistantFrameHost, AssistantFrameProvider, AssistantRuntime, Attachment, AttachmentAdapter, AttachmentRuntime, AttachmentState, AttachmentStatus, ChatModelAdapter, ChatModelRunOptions, ChatModelRunResult, ChatModelRunUpdate, CompleteAttachment, ComposerRuntime, ComposerState, CompositeAttachmentAdapter, CreateAppendMessage, CreateAttachment, CreateResumeRunConfig, CreateStartRunConfig, DataMessagePart, DictationAdapter, DictationState, EditComposerRuntime, EditComposerState, ExportedMessageRepository, ExportedMessageRepositoryItem, ExternalStoreAdapter, ExternalStoreMessageConverter, ExternalStoreSharedOptions, ExternalStoreThreadData, ExternalStoreThreadListAdapter, FRAME_MESSAGE_CHANNEL, FeedbackAdapter, FileMessagePart, FrameMessage, FrameMessageType, GenerativeUIMessagePart, GenerativeUINode, GenerativeUISpec, GenericThreadHistoryAdapter, ImageMessagePart, InMemoryThreadListAdapter, LanguageModelConfig, LanguageModelV1CallSettings, LocalRuntimeOptionsBase, MessageFormatAdapter, MessageFormatItem, MessageFormatRepository, MessagePartRuntime, MessagePartState, MessagePartStatus, MessageRuntime, MessageState, MessageStatus, MessageStorageEntry, MessageTiming, ModelContext, ModelContextProvider, ModelContextRegistry, ModelContextRegistryInstructionHandle, ModelContextRegistryProviderHandle, ModelContextRegistryToolHandle, PendingAttachment, QuoteInfo, RealtimeVoiceAdapter, ReasoningMessagePart, RemoteThreadListAdapter, SerializedModelContext, SerializedTool, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, SourceMessagePart, SourceProviderMetadata, SpeechSynthesisAdapter, SubmitFeedbackOptions, SuggestionAdapter, TextMessagePart, ThreadAssistantMessage, ThreadAssistantMessagePart, ThreadComposerRuntime, ThreadComposerState, ThreadHistoryAdapter, ThreadListItemRuntime, ThreadListItemState, ThreadListItemStatus, ThreadListRuntime, ThreadListState, ThreadMessage, ThreadMessageLike, ThreadRuntime, ThreadState, ThreadSuggestion, ThreadSystemMessage, ThreadUserMessage, ThreadUserMessagePart, ToolCallMessagePart, ToolCallMessagePartStatus, ToolModelContentPart, Unstable_AudioMessagePart, Unstable_DirectiveFormatter, Unstable_DirectiveSegment, Unstable_TriggerItem, Unsubscribe, VoiceSessionControls, VoiceSessionHelpers, VoiceSessionState, WebSpeechDictationAdapter, WebSpeechSynthesisAdapter, bindExternalStoreMessage, createVoiceSession, getExternalStoreMessages, mergeModelContexts, pickExternalStoreSharedOptions, tool, unstable_defaultDirectiveFormatter } from "@assistant-ui/core";
80
80
  import { Tool } from "assistant-stream";
81
81
  import { ChainOfThoughtClient, ComposerSendOptions, ModelContext as ModelContextClient, QueueItemMethods, QueueItemState, SuggestionConfig, Suggestions } from "@assistant-ui/core/store";
82
- export { actionBarMore_d_exports as ActionBarMorePrimitive, actionBar_d_exports as ActionBarPrimitive, type AddToolResultOptions, type AppendMessage, type Assistant, type AssistantClient, AssistantCloud, type AssistantContextConfig, type AssistantDataUI, type AssistantDataUIProps, type AssistantEventCallback, type AssistantEventName, type AssistantEventPayload, type AssistantEventScope, type AssistantEventSelector, AssistantFrameHost, AssistantFrameProvider, type AssistantInteractableProps, assistantModal_d_exports as AssistantModalPrimitive, type AssistantRuntime, AssistantRuntimeProvider, type AssistantState, type AssistantTool, type AssistantToolProps, type AssistantToolUI, type AssistantToolUIProps, type AssistantTransportCommand, type AssistantTransportConnectionMetadata, type AssistantTransportProtocol, type Attachment, type AttachmentAdapter, attachment_d_exports as AttachmentPrimitive, type AttachmentRuntime, type AttachmentState, type AttachmentStatus, AuiIf, AuiProvider, branchPicker_d_exports as BranchPickerPrimitive, ChainOfThoughtByIndicesProvider, ChainOfThoughtClient, chainOfThought_d_exports as ChainOfThoughtPrimitive, type ChatModelAdapter, type ChatModelRunOptions, type ChatModelRunResult, type ChatModelRunUpdate, CloudFileAttachmentAdapter, type CompleteAttachment, ComposerAttachmentByIndexProvider, composer_d_exports as ComposerPrimitive, type ComposerRuntime, type ComposerSendOptions, type ComposerState, CompositeAttachmentAdapter, type CreateAppendMessage, type CreateAttachment, type CreateResumeRunConfig, type CreateStartRunConfig, type DataMessagePart, type DataMessagePartComponent, type DataMessagePartProps, DataRenderers, DevToolsHooks, DevToolsProviderApi, type DictationAdapter, type DictationState, type EditComposerRuntime, type EditComposerState, type EmptyMessagePartComponent, type EmptyMessagePartProps, type EnrichedPartState, error_d_exports as ErrorPrimitive, ExportedMessageRepository, type ExportedMessageRepositoryItem, type ExternalStoreAdapter, type ExternalStoreMessageConverter, type ExternalStoreThreadData, type ExternalStoreThreadListAdapter, ExternalThread, type ExternalThreadMessage, type ExternalThreadProps, type ExternalThreadQueueAdapter, FRAME_MESSAGE_CHANNEL, type FeedbackAdapter, type FileMessagePart, type FileMessagePartComponent, type FileMessagePartProps, type FrameMessage, type FrameMessageType, type GenerativeUIComponentRegistry, type GenerativeUIMessagePart, type GenerativeUIMessagePartComponent, type GenerativeUIMessagePartProps, type GenerativeUINode, GenerativeUIRender, GenerativeUIRenderError, type GenerativeUIRenderProps, type GenerativeUISpec, type GenericThreadHistoryAdapter, internal_d_exports as INTERNAL, type ImageMessagePart, type ImageMessagePartComponent, type ImageMessagePartProps, InMemoryThreadList, InMemoryThreadListAdapter, type InMemoryThreadListProps, Interactables, type LanguageModelConfig, type LanguageModelV1CallSettings, type LocalRuntimeOptions, type LocalRuntimeOptionsBase, type McpAppDisplayMode, type McpAppHostContext, type McpAppHostInfo, type McpAppMetadata, McpAppRenderer, type McpAppRendererOptions, type McpAppResource, type McpAppResourceCSP, type McpAppResourceMeta, type McpAppResourceOutput, type McpAppSandboxConfig, type McpAppToolCallParams, type McpAppsHost, McpAppsRemoteHost, type McpAppsRemoteHostOptions, MessageAttachmentByIndexProvider, MessageByIndexProvider, type MessageFormatAdapter, type MessageFormatItem, type MessageFormatRepository, messagePart_d_exports as MessagePartPrimitive, type MessagePartRuntime, type MessagePartState, type MessagePartStatus, message_d_exports as MessagePrimitive, MessageProvider, type MessageRuntime, type MessageState, type MessageStatus, type MessageStorageEntry, type MessageTiming, type ModelContext, ModelContextClient, type ModelContextProvider, ModelContextRegistry, type ModelContextRegistryInstructionHandle, type ModelContextRegistryProviderHandle, type ModelContextRegistryToolHandle, PartByIndexProvider, type PartState, type PendingAttachment, type QueueItemMethods, queueItem_d_exports as QueueItemPrimitive, type QueueItemState, type QuoteInfo, type QuoteMessagePartComponent, type QuoteMessagePartProps, ReadonlyThreadProvider, type RealtimeVoiceAdapter, type ReasoningGroupComponent, type ReasoningGroupProps, type ReasoningMessagePart, type ReasoningMessagePartComponent, type ReasoningMessagePartProps, type RemoteThreadListAdapter, RuntimeAdapterProvider, type RuntimeAdapters, selectionToolbar_d_exports as SelectionToolbarPrimitive, type SendCommandsRequestBody, type SerializedModelContext, type SerializedTool, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, SingleThreadList, type SourceMessagePart, type SourceMessagePartComponent, type SourceMessagePartProps, type SourceProviderMetadata, type SpeechSynthesisAdapter, type SubmitFeedbackOptions, type SuggestionAdapter, SuggestionByIndexProvider, type SuggestionConfig, suggestion_d_exports as SuggestionPrimitive, Suggestions, type TextMessagePart, type TextMessagePartComponent, type TextMessagePartProps, TextMessagePartProvider, type ThreadAssistantMessage, type ThreadAssistantMessagePart, type ThreadComposerRuntime, type ThreadComposerState, type ThreadHistoryAdapter, ThreadListItemByIndexProvider, threadListItemMore_d_exports as ThreadListItemMorePrimitive, threadListItem_d_exports as ThreadListItemPrimitive, type ThreadListItemRuntime, ThreadListItemRuntimeProvider, type ThreadListItemState, type ThreadListItemStatus, threadList_d_exports as ThreadListPrimitive, type ThreadListRuntime, type ThreadListState, type ThreadMessage, type ThreadMessageLike, thread_d_exports as ThreadPrimitive, type ThreadRuntime, type ThreadState, type ThreadSuggestion, type ThreadSystemMessage, type ThreadUserMessage, type ThreadUserMessagePart, type ThreadViewportState, type Tool, type ToolArgsStatus, type ToolCallMessagePart, type ToolCallMessagePartComponent, type ToolCallMessagePartMcpMetadata, type ToolCallMessagePartProps, type ToolCallMessagePartStatus, type ToolDefinition, type ToolExecutionStatus, type ToolModelContentPart, type Toolkit, Tools, type Unstable_AudioMessagePart, type Unstable_AudioMessagePartComponent, type Unstable_AudioMessagePartProps, type Unstable_DirectiveFormatter, type Unstable_DirectiveSegment, type Unstable_IconComponent, type Unstable_Mention, type Unstable_MentionCategory, type Unstable_MentionDirective, type Unstable_ModelContextToolsOptions, type RegisteredTrigger as Unstable_RegisteredTrigger, type Unstable_SlashCommand, type Unstable_SlashCommandAction, type TriggerBehavior as Unstable_TriggerBehavior, type Unstable_TriggerItem, type Unstable_UseMentionAdapterOptions, type Unstable_UseSlashCommandAdapterOptions, type Unsubscribe, type VoiceSessionControls, type VoiceSessionHelpers, type VoiceSessionState, WebSpeechDictationAdapter, WebSpeechSynthesisAdapter, bindExternalStoreMessage, createVoiceSession, getExternalStoreMessages, getMcpAppFromToolPart, groupPartByType, makeAssistantDataUI, makeAssistantTool, makeAssistantToolUI, makeAssistantVisible, mergeModelContexts, tool, convertExternalMessages as unstable_convertExternalMessages, createMessageConverter as unstable_createMessageConverter, unstable_defaultDirectiveFormatter, unstable_useMentionAdapter, unstable_useSlashCommandAdapter, useTriggerPopoverRootContext as unstable_useTriggerPopoverRootContext, useTriggerPopoverRootContextOptional as unstable_useTriggerPopoverRootContextOptional, useTriggerPopoverScopeContext as unstable_useTriggerPopoverScopeContext, useTriggerPopoverScopeContextOptional as unstable_useTriggerPopoverScopeContextOptional, useTriggerPopoverTriggers as unstable_useTriggerPopoverTriggers, useTriggerPopoverTriggersOptional as unstable_useTriggerPopoverTriggersOptional, useAssistantContext, useAssistantDataUI, useAssistantFrameHost, useAssistantInstructions, useAssistantInteractable, useAssistantRuntime, useAssistantTool, useAssistantToolUI, useAssistantTransportRuntime, useAssistantTransportSendCommand, useAssistantTransportState, useAttachment, useAttachmentRuntime, useAui, useAuiEvent, useAuiState, useCloudThreadListAdapter, useCloudThreadListRuntime, useComposer, useComposerRuntime, useEditComposer, useEditComposerAttachment, useEditComposerAttachmentRuntime, useExternalMessageConverter, useExternalStoreRuntime, useInlineRender, useInteractableState, useLocalRuntime, useMessage, useMessageAttachment, useMessageAttachmentRuntime, useMessagePart, useMessagePartData, useMessagePartFile, useMessagePartImage, useMessagePartReasoning, useMessagePartRuntime, useMessagePartSource, useMessagePartText, useMessageQuote, useMessageRuntime, useMessageTiming, useRemoteThreadListRuntime, useRuntimeAdapters, useScrollLock, useThread, useThreadComposer, useThreadComposerAttachment, useThreadComposerAttachmentRuntime, useThreadList, useThreadListItem, useThreadListItemRuntime, useThreadModelContext, useThreadRuntime, useThreadViewport, useThreadViewportAutoScroll, useThreadViewportStore, useToolArgsStatus, useVoiceControls, useVoiceState, useVoiceVolume };
82
+ export { actionBarMore_d_exports as ActionBarMorePrimitive, actionBar_d_exports as ActionBarPrimitive, type AddToolResultOptions, type AppendMessage, type Assistant, type AssistantClient, AssistantCloud, type AssistantContextConfig, type AssistantDataUI, type AssistantDataUIProps, type AssistantEventCallback, type AssistantEventName, type AssistantEventPayload, type AssistantEventScope, type AssistantEventSelector, AssistantFrameHost, AssistantFrameProvider, type AssistantInteractableProps, assistantModal_d_exports as AssistantModalPrimitive, type AssistantRuntime, AssistantRuntimeProvider, type AssistantState, type AssistantTool, type AssistantToolProps, type AssistantToolUI, type AssistantToolUIProps, type AssistantTransportCommand, type AssistantTransportConnectionMetadata, type AssistantTransportProtocol, type Attachment, type AttachmentAdapter, attachment_d_exports as AttachmentPrimitive, type AttachmentRuntime, type AttachmentState, type AttachmentStatus, AuiIf, AuiProvider, branchPicker_d_exports as BranchPickerPrimitive, ChainOfThoughtByIndicesProvider, ChainOfThoughtClient, chainOfThought_d_exports as ChainOfThoughtPrimitive, type ChatModelAdapter, type ChatModelRunOptions, type ChatModelRunResult, type ChatModelRunUpdate, CloudFileAttachmentAdapter, type CompleteAttachment, ComposerAttachmentByIndexProvider, composer_d_exports as ComposerPrimitive, type ComposerRuntime, type ComposerSendOptions, type ComposerState, CompositeAttachmentAdapter, type CreateAppendMessage, type CreateAttachment, type CreateResumeRunConfig, type CreateStartRunConfig, type DataMessagePart, type DataMessagePartComponent, type DataMessagePartProps, DataRenderers, DevToolsHooks, DevToolsProviderApi, type DictationAdapter, type DictationState, type EditComposerRuntime, type EditComposerState, type EmptyMessagePartComponent, type EmptyMessagePartProps, type EnrichedPartState, error_d_exports as ErrorPrimitive, ExportedMessageRepository, type ExportedMessageRepositoryItem, type ExternalStoreAdapter, type ExternalStoreMessageConverter, type ExternalStoreSharedOptions, type ExternalStoreThreadData, type ExternalStoreThreadListAdapter, ExternalThread, type ExternalThreadMessage, type ExternalThreadProps, type ExternalThreadQueueAdapter, FRAME_MESSAGE_CHANNEL, type FeedbackAdapter, type FileMessagePart, type FileMessagePartComponent, type FileMessagePartProps, type FrameMessage, type FrameMessageType, type GenerativeUIComponentRegistry, type GenerativeUIMessagePart, type GenerativeUIMessagePartComponent, type GenerativeUIMessagePartProps, type GenerativeUINode, GenerativeUIRender, GenerativeUIRenderError, type GenerativeUIRenderProps, type GenerativeUISpec, type GenericThreadHistoryAdapter, type GroupByContext, internal_d_exports as INTERNAL, type ImageMessagePart, type ImageMessagePartComponent, type ImageMessagePartProps, InMemoryThreadList, InMemoryThreadListAdapter, type InMemoryThreadListProps, Interactables, type LanguageModelConfig, type LanguageModelV1CallSettings, type LocalRuntimeOptions, type LocalRuntimeOptionsBase, type McpAppDisplayMode, type McpAppHostContext, type McpAppHostInfo, type McpAppMetadata, McpAppRenderer, type McpAppRendererOptions, type McpAppResource, type McpAppResourceCSP, type McpAppResourceMeta, type McpAppResourceOutput, type McpAppSandboxConfig, type McpAppToolCallParams, type McpAppsHost, McpAppsRemoteHost, type McpAppsRemoteHostOptions, MessageAttachmentByIndexProvider, MessageByIndexProvider, type MessageFormatAdapter, type MessageFormatItem, type MessageFormatRepository, messagePart_d_exports as MessagePartPrimitive, type MessagePartRuntime, type MessagePartState, type MessagePartStatus, message_d_exports as MessagePrimitive, MessageProvider, type MessageRuntime, type MessageState, type MessageStatus, type MessageStorageEntry, type MessageTiming, type ModelContext, ModelContextClient, type ModelContextProvider, ModelContextRegistry, type ModelContextRegistryInstructionHandle, type ModelContextRegistryProviderHandle, type ModelContextRegistryToolHandle, PartByIndexProvider, type PartState, type PendingAttachment, type QueueItemMethods, queueItem_d_exports as QueueItemPrimitive, type QueueItemState, type QuoteInfo, type QuoteMessagePartComponent, type QuoteMessagePartProps, ReadonlyThreadProvider, type RealtimeVoiceAdapter, type ReasoningGroupComponent, type ReasoningGroupProps, type ReasoningMessagePart, type ReasoningMessagePartComponent, type ReasoningMessagePartProps, type RemoteThreadListAdapter, RuntimeAdapterProvider, type RuntimeAdapters, selectionToolbar_d_exports as SelectionToolbarPrimitive, type SendCommandsRequestBody, type SerializedModelContext, type SerializedTool, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, SingleThreadList, type SourceMessagePart, type SourceMessagePartComponent, type SourceMessagePartProps, type SourceProviderMetadata, type SpeechSynthesisAdapter, type SubmitFeedbackOptions, type SuggestionAdapter, SuggestionByIndexProvider, type SuggestionConfig, suggestion_d_exports as SuggestionPrimitive, Suggestions, type TextMessagePart, type TextMessagePartComponent, type TextMessagePartProps, TextMessagePartProvider, type ThreadAssistantMessage, type ThreadAssistantMessagePart, type ThreadComposerRuntime, type ThreadComposerState, type ThreadHistoryAdapter, ThreadListItemByIndexProvider, threadListItemMore_d_exports as ThreadListItemMorePrimitive, threadListItem_d_exports as ThreadListItemPrimitive, type ThreadListItemRuntime, ThreadListItemRuntimeProvider, type ThreadListItemState, type ThreadListItemStatus, threadList_d_exports as ThreadListPrimitive, type ThreadListRuntime, type ThreadListState, type ThreadMessage, type ThreadMessageLike, thread_d_exports as ThreadPrimitive, type ThreadRuntime, type ThreadState, type ThreadSuggestion, type ThreadSystemMessage, type ThreadUserMessage, type ThreadUserMessagePart, type ThreadViewportState, type Tool, type ToolArgsStatus, type ToolCallMessagePart, type ToolCallMessagePartComponent, type ToolCallMessagePartMcpMetadata, type ToolCallMessagePartProps, type ToolCallMessagePartStatus, type ToolDefinition, type ToolExecutionStatus, type ToolModelContentPart, type Toolkit, type ToolkitDeclaration, type ToolkitDeclarationDefinition, Tools, type Unstable_AudioMessagePart, type Unstable_AudioMessagePartComponent, type Unstable_AudioMessagePartProps, type Unstable_DirectiveFormatter, type Unstable_DirectiveSegment, type Unstable_IconComponent, type Unstable_Mention, type Unstable_MentionCategory, type Unstable_MentionDirective, type Unstable_ModelContextToolsOptions, type RegisteredTrigger as Unstable_RegisteredTrigger, type Unstable_SlashCommand, type Unstable_SlashCommandAction, type TriggerBehavior as Unstable_TriggerBehavior, type Unstable_TriggerItem, type Unstable_UseMentionAdapterOptions, type Unstable_UseSlashCommandAdapterOptions, type Unsubscribe, type VoiceSessionControls, type VoiceSessionHelpers, type VoiceSessionState, WebSpeechDictationAdapter, WebSpeechSynthesisAdapter, bindExternalStoreMessage, createVoiceSession, getExternalStoreMessages, getMcpAppFromToolPart, groupPartByType, makeAssistantDataUI, makeAssistantTool, makeAssistantToolUI, makeAssistantVisible, mergeModelContexts, pickExternalStoreSharedOptions, tool, convertExternalMessages as unstable_convertExternalMessages, createMessageConverter as unstable_createMessageConverter, unstable_defaultDirectiveFormatter, unstable_useMentionAdapter, unstable_useSlashCommandAdapter, useTriggerPopoverRootContext as unstable_useTriggerPopoverRootContext, useTriggerPopoverRootContextOptional as unstable_useTriggerPopoverRootContextOptional, useTriggerPopoverScopeContext as unstable_useTriggerPopoverScopeContext, useTriggerPopoverScopeContextOptional as unstable_useTriggerPopoverScopeContextOptional, useTriggerPopoverTriggers as unstable_useTriggerPopoverTriggers, useTriggerPopoverTriggersOptional as unstable_useTriggerPopoverTriggersOptional, useAssistantContext, useAssistantDataUI, useAssistantFrameHost, useAssistantInstructions, useAssistantInteractable, useAssistantRuntime, useAssistantTool, useAssistantToolUI, useAssistantTransportRuntime, useAssistantTransportSendCommand, useAssistantTransportState, useAttachment, useAttachmentRuntime, useAui, useAuiEvent, useAuiState, useCloudThreadListAdapter, useCloudThreadListRuntime, useComposer, useComposerRuntime, useEditComposer, useEditComposerAttachment, useEditComposerAttachmentRuntime, useExternalMessageConverter, useExternalStoreRuntime, useExternalStoreSharedOptions, useInlineRender, useInteractableState, useLocalRuntime, useMessage, useMessageAttachment, useMessageAttachmentRuntime, useMessagePart, useMessagePartData, useMessagePartFile, useMessagePartImage, useMessagePartReasoning, useMessagePartRuntime, useMessagePartSource, useMessagePartText, useMessageQuote, useMessageRuntime, useMessageTiming, useRemoteThreadListRuntime, useRuntimeAdapters, useScrollLock, useThread, useThreadComposer, useThreadComposerAttachment, useThreadComposerAttachmentRuntime, useThreadList, useThreadListItem, useThreadListItemRuntime, useThreadModelContext, useThreadRuntime, useThreadViewport, useThreadViewportAutoScroll, useThreadViewportStore, useToolArgsStatus, useVoiceControls, useVoiceState, useVoiceVolume };
package/dist/index.js CHANGED
@@ -67,8 +67,8 @@ import { getMcpAppFromToolPart } from "./mcp-apps/utils.js";
67
67
  import { McpAppRenderer } from "./mcp-apps/McpAppRenderer.js";
68
68
  import { McpAppsRemoteHost } from "./mcp-apps/McpAppsRemoteHost.js";
69
69
  import { AuiIf, AuiProvider, useAui, useAuiEvent, useAuiState } from "@assistant-ui/store";
70
- import { DataRenderers, GenerativeUIRender, GenerativeUIRenderError, Interactables, RuntimeAdapterProvider, Tools, groupPartByType, makeAssistantDataUI, makeAssistantTool, makeAssistantToolUI, useAssistantContext, useAssistantDataUI, useAssistantInstructions, useAssistantInteractable, useAssistantTool, useAssistantToolUI, useInlineRender, useInteractableState, useRuntimeAdapters, useToolArgsStatus, useVoiceControls, useVoiceState, useVoiceVolume } from "@assistant-ui/core/react";
70
+ import { DataRenderers, GenerativeUIRender, GenerativeUIRenderError, Interactables, RuntimeAdapterProvider, Tools, groupPartByType, makeAssistantDataUI, makeAssistantTool, makeAssistantToolUI, useAssistantContext, useAssistantDataUI, useAssistantInstructions, useAssistantInteractable, useAssistantTool, useAssistantToolUI, useExternalStoreSharedOptions, useInlineRender, useInteractableState, useRuntimeAdapters, useToolArgsStatus, useVoiceControls, useVoiceState, useVoiceVolume } from "@assistant-ui/core/react";
71
71
  import { AssistantCloud } from "assistant-cloud";
72
- import { AssistantFrameHost, AssistantFrameProvider, CompositeAttachmentAdapter, ExportedMessageRepository, FRAME_MESSAGE_CHANNEL, InMemoryThreadListAdapter, ModelContextRegistry, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, WebSpeechDictationAdapter, WebSpeechSynthesisAdapter, bindExternalStoreMessage, createVoiceSession, getExternalStoreMessages, mergeModelContexts, tool, unstable_defaultDirectiveFormatter } from "@assistant-ui/core";
72
+ import { AssistantFrameHost, AssistantFrameProvider, CompositeAttachmentAdapter, ExportedMessageRepository, FRAME_MESSAGE_CHANNEL, InMemoryThreadListAdapter, ModelContextRegistry, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, WebSpeechDictationAdapter, WebSpeechSynthesisAdapter, bindExternalStoreMessage, createVoiceSession, getExternalStoreMessages, mergeModelContexts, pickExternalStoreSharedOptions, tool, unstable_defaultDirectiveFormatter } from "@assistant-ui/core";
73
73
  import { ChainOfThoughtClient, ModelContext as ModelContextClient, Suggestions } from "@assistant-ui/core/store";
74
- export { actionBarMore_exports as ActionBarMorePrimitive, actionBar_exports as ActionBarPrimitive, AssistantCloud, AssistantFrameHost, AssistantFrameProvider, assistantModal_exports as AssistantModalPrimitive, AssistantRuntimeProvider, attachment_exports as AttachmentPrimitive, AuiIf, AuiProvider, branchPicker_exports as BranchPickerPrimitive, ChainOfThoughtByIndicesProvider, ChainOfThoughtClient, chainOfThought_exports as ChainOfThoughtPrimitive, CloudFileAttachmentAdapter, ComposerAttachmentByIndexProvider, composer_exports as ComposerPrimitive, CompositeAttachmentAdapter, DataRenderers, DevToolsHooks, DevToolsProviderApi, error_exports as ErrorPrimitive, ExportedMessageRepository, ExternalThread, FRAME_MESSAGE_CHANNEL, GenerativeUIRender, GenerativeUIRenderError, internal_exports as INTERNAL, InMemoryThreadList, InMemoryThreadListAdapter, Interactables, McpAppRenderer, McpAppsRemoteHost, MessageAttachmentByIndexProvider, MessageByIndexProvider, messagePart_exports as MessagePartPrimitive, message_exports as MessagePrimitive, MessageProvider, ModelContextClient, ModelContextRegistry, PartByIndexProvider, queueItem_exports as QueueItemPrimitive, ReadonlyThreadProvider, RuntimeAdapterProvider, selectionToolbar_exports as SelectionToolbarPrimitive, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, SingleThreadList, SuggestionByIndexProvider, suggestion_exports as SuggestionPrimitive, Suggestions, TextMessagePartProvider, ThreadListItemByIndexProvider, threadListItemMore_exports as ThreadListItemMorePrimitive, threadListItem_exports as ThreadListItemPrimitive, ThreadListItemRuntimeProvider, threadList_exports as ThreadListPrimitive, thread_exports as ThreadPrimitive, Tools, WebSpeechDictationAdapter, WebSpeechSynthesisAdapter, bindExternalStoreMessage, createVoiceSession, getExternalStoreMessages, getMcpAppFromToolPart, groupPartByType, makeAssistantDataUI, makeAssistantTool, makeAssistantToolUI, makeAssistantVisible, mergeModelContexts, tool, convertExternalMessages as unstable_convertExternalMessages, createMessageConverter as unstable_createMessageConverter, unstable_defaultDirectiveFormatter, unstable_useMentionAdapter, unstable_useSlashCommandAdapter, useTriggerPopoverRootContext as unstable_useTriggerPopoverRootContext, useTriggerPopoverRootContextOptional as unstable_useTriggerPopoverRootContextOptional, useTriggerPopoverScopeContext as unstable_useTriggerPopoverScopeContext, useTriggerPopoverScopeContextOptional as unstable_useTriggerPopoverScopeContextOptional, useTriggerPopoverTriggers as unstable_useTriggerPopoverTriggers, useTriggerPopoverTriggersOptional as unstable_useTriggerPopoverTriggersOptional, useAssistantContext, useAssistantDataUI, useAssistantFrameHost, useAssistantInstructions, useAssistantInteractable, useAssistantRuntime, useAssistantTool, useAssistantToolUI, useAssistantTransportRuntime, useAssistantTransportSendCommand, useAssistantTransportState, useAttachment, useAttachmentRuntime, useAui, useAuiEvent, useAuiState, useCloudThreadListAdapter, useCloudThreadListRuntime, useComposer, useComposerRuntime, useEditComposer, useEditComposerAttachment, useEditComposerAttachmentRuntime, useExternalMessageConverter, useExternalStoreRuntime, useInlineRender, useInteractableState, useLocalRuntime, useMessage, useMessageAttachment, useMessageAttachmentRuntime, useMessagePart, useMessagePartData, useMessagePartFile, useMessagePartImage, useMessagePartReasoning, useMessagePartRuntime, useMessagePartSource, useMessagePartText, useMessageQuote, useMessageRuntime, useMessageTiming, useRemoteThreadListRuntime, useRuntimeAdapters, useScrollLock, useThread, useThreadComposer, useThreadComposerAttachment, useThreadComposerAttachmentRuntime, useThreadList, useThreadListItem, useThreadListItemRuntime, useThreadModelContext, useThreadRuntime, useThreadViewport, useThreadViewportAutoScroll, useThreadViewportStore, useToolArgsStatus, useVoiceControls, useVoiceState, useVoiceVolume };
74
+ export { actionBarMore_exports as ActionBarMorePrimitive, actionBar_exports as ActionBarPrimitive, AssistantCloud, AssistantFrameHost, AssistantFrameProvider, assistantModal_exports as AssistantModalPrimitive, AssistantRuntimeProvider, attachment_exports as AttachmentPrimitive, AuiIf, AuiProvider, branchPicker_exports as BranchPickerPrimitive, ChainOfThoughtByIndicesProvider, ChainOfThoughtClient, chainOfThought_exports as ChainOfThoughtPrimitive, CloudFileAttachmentAdapter, ComposerAttachmentByIndexProvider, composer_exports as ComposerPrimitive, CompositeAttachmentAdapter, DataRenderers, DevToolsHooks, DevToolsProviderApi, error_exports as ErrorPrimitive, ExportedMessageRepository, ExternalThread, FRAME_MESSAGE_CHANNEL, GenerativeUIRender, GenerativeUIRenderError, internal_exports as INTERNAL, InMemoryThreadList, InMemoryThreadListAdapter, Interactables, McpAppRenderer, McpAppsRemoteHost, MessageAttachmentByIndexProvider, MessageByIndexProvider, messagePart_exports as MessagePartPrimitive, message_exports as MessagePrimitive, MessageProvider, ModelContextClient, ModelContextRegistry, PartByIndexProvider, queueItem_exports as QueueItemPrimitive, ReadonlyThreadProvider, RuntimeAdapterProvider, selectionToolbar_exports as SelectionToolbarPrimitive, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, SingleThreadList, SuggestionByIndexProvider, suggestion_exports as SuggestionPrimitive, Suggestions, TextMessagePartProvider, ThreadListItemByIndexProvider, threadListItemMore_exports as ThreadListItemMorePrimitive, threadListItem_exports as ThreadListItemPrimitive, ThreadListItemRuntimeProvider, threadList_exports as ThreadListPrimitive, thread_exports as ThreadPrimitive, Tools, WebSpeechDictationAdapter, WebSpeechSynthesisAdapter, bindExternalStoreMessage, createVoiceSession, getExternalStoreMessages, getMcpAppFromToolPart, groupPartByType, makeAssistantDataUI, makeAssistantTool, makeAssistantToolUI, makeAssistantVisible, mergeModelContexts, pickExternalStoreSharedOptions, tool, convertExternalMessages as unstable_convertExternalMessages, createMessageConverter as unstable_createMessageConverter, unstable_defaultDirectiveFormatter, unstable_useMentionAdapter, unstable_useSlashCommandAdapter, useTriggerPopoverRootContext as unstable_useTriggerPopoverRootContext, useTriggerPopoverRootContextOptional as unstable_useTriggerPopoverRootContextOptional, useTriggerPopoverScopeContext as unstable_useTriggerPopoverScopeContext, useTriggerPopoverScopeContextOptional as unstable_useTriggerPopoverScopeContextOptional, useTriggerPopoverTriggers as unstable_useTriggerPopoverTriggers, useTriggerPopoverTriggersOptional as unstable_useTriggerPopoverTriggersOptional, useAssistantContext, useAssistantDataUI, useAssistantFrameHost, useAssistantInstructions, useAssistantInteractable, useAssistantRuntime, useAssistantTool, useAssistantToolUI, useAssistantTransportRuntime, useAssistantTransportSendCommand, useAssistantTransportState, useAttachment, useAttachmentRuntime, useAui, useAuiEvent, useAuiState, useCloudThreadListAdapter, useCloudThreadListRuntime, useComposer, useComposerRuntime, useEditComposer, useEditComposerAttachment, useEditComposerAttachmentRuntime, useExternalMessageConverter, useExternalStoreRuntime, useExternalStoreSharedOptions, useInlineRender, useInteractableState, useLocalRuntime, useMessage, useMessageAttachment, useMessageAttachmentRuntime, useMessagePart, useMessagePartData, useMessagePartFile, useMessagePartImage, useMessagePartReasoning, useMessagePartRuntime, useMessagePartSource, useMessagePartText, useMessageQuote, useMessageRuntime, useMessageTiming, useRemoteThreadListRuntime, useRuntimeAdapters, useScrollLock, useThread, useThreadComposer, useThreadComposerAttachment, useThreadComposerAttachmentRuntime, useThreadList, useThreadListItem, useThreadListItemRuntime, useThreadModelContext, useThreadRuntime, useThreadViewport, useThreadViewportAutoScroll, useThreadViewportStore, useToolArgsStatus, useVoiceControls, useVoiceState, useVoiceVolume };
@@ -1 +1 @@
1
- {"version":3,"file":"useCloudThreadListRuntime.d.ts","names":[],"sources":["../../../src/legacy-runtime/cloud/useCloudThreadListRuntime.ts"],"mappings":";;;;KAOK,UAAA;EACH,UAAU;AAAA;AAAA,KAGP,sBAAA;EACH,KAAA,EAAO,cAAA;EAEP,WAAA,QAAmB,gBAAA;EAEnB,MAAA,KAAW,OAAA,CAAQ,UAAA;EACnB,MAAA,EAAQ,QAAA,WAAmB,OAAA;AAAA;AAAA,iBAGb,yBAAA,CAAA;EACd,WAAA;EAAA,GACG;AAAA,GACF,sBAAA,GAAsB,gBAAA"}
1
+ {"version":3,"file":"useCloudThreadListRuntime.d.ts","names":[],"sources":["../../../src/legacy-runtime/cloud/useCloudThreadListRuntime.ts"],"mappings":";;;;KAOK,UAAA;EACH,UAAU;AAAA;AAAA,KAGP,sBAAA;EACH,KAAA,EAAO,cAAA;EAEP,WAAA,QAAmB,gBAAA;EAEnB,MAAA,KAAW,OAAA,CAAQ,UAAA;EACnB,MAAA,EAAQ,QAAA,WAAmB,OAAA;AAAA;AAAA,iBAGb,yBAAA;EACd,WAAA;EAAA,GACG;AAAA,GACF,sBAAA,GAAsB,gBAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"useAssistantTransportRuntime.d.ts","names":[],"sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.ts"],"mappings":";;;;;cA0Fa,gCAAA,SAGH,OAAkC,EAAzB,yBAAyB;AAAA,iBAO5B,0BAAA,CAAA,GAA8B,iBAAiB;AAAA,iBAC/C,0BAAA,GAAA,CACd,QAAA,GAAW,KAAA,EAAO,iBAAA,KAAsB,CAAA,GACvC,CAAA;;;;cAmQU,4BAAA,MACX,OAAA,EAAS,yBAAA,CAA0B,CAAA,MAClC,gBAAA"}
1
+ {"version":3,"file":"useAssistantTransportRuntime.d.ts","names":[],"sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.ts"],"mappings":";;;;;cA0Fa,gCAAA,SAGH,OAAkC,EAAzB,yBAAyB;AAAA,iBAO5B,0BAAA,IAA8B,iBAAiB;AAAA,iBAC/C,0BAAA,IACd,QAAA,GAAW,KAAA,EAAO,iBAAA,KAAsB,CAAA,GACvC,CAAA;;;;cAwPU,4BAAA,MACX,OAAA,EAAS,yBAAA,CAA0B,CAAA,MAClC,gBAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"useAssistantTransportRuntime.js","names":["createInitialMessage"],"sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.ts"],"sourcesContent":["\"use client\";\n\nimport type { AppendMessage } from \"@assistant-ui/core\";\nimport {\n type ReadonlyJSONObject,\n type ReadonlyJSONValue,\n asAsyncIterableStream,\n} from \"assistant-stream/utils\";\nimport { useExternalStoreRuntime } from \"../external-store/useExternalStoreRuntime\";\nimport type { AssistantRuntime } from \"../../runtime/AssistantRuntime\";\nimport type { AddToolResultOptions } from \"@assistant-ui/core\";\nimport { useMemo, useRef, useState } from \"react\";\nimport {\n AssistantMessageAccumulator,\n DataStreamDecoder,\n AssistantTransportDecoder,\n unstable_createInitialMessage as createInitialMessage,\n toToolsJSONSchema,\n} from \"assistant-stream\";\nimport type {\n AssistantTransportOptions,\n AddMessageCommand,\n AddToolResultCommand,\n UserMessagePart,\n QueuedCommand,\n AssistantTransportCommand,\n SendCommandsRequestBody,\n} from \"./types\";\nimport { useCommandQueue } from \"./commandQueue\";\nimport { useRunManager } from \"./runManager\";\nimport { useConvertedState } from \"./useConvertedState\";\nimport type { ToolExecutionStatus } from \"@assistant-ui/core\";\nimport { createRequestHeaders } from \"@assistant-ui/core\";\nimport { useRemoteThreadListRuntime } from \"../remote-thread-list/useRemoteThreadListRuntime\";\nimport { InMemoryThreadListAdapter } from \"@assistant-ui/core\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\nimport type { UserExternalState } from \"../../../augmentations\";\n\nconst convertAppendMessageToCommand = (\n message: AppendMessage,\n): AddMessageCommand => {\n if (message.role !== \"user\")\n throw new Error(\"Only user messages are supported\");\n\n const parts: UserMessagePart[] = [];\n const content = [\n ...message.content,\n ...(message.attachments?.flatMap((a) => a.content) ?? []),\n ];\n for (const contentPart of content) {\n if (contentPart.type === \"text\") {\n parts.push({ type: \"text\", text: contentPart.text });\n } else if (contentPart.type === \"image\") {\n parts.push({ type: \"image\", image: contentPart.image });\n }\n }\n\n return {\n type: \"add-message\",\n message: {\n role: \"user\",\n parts,\n },\n parentId: message.parentId,\n sourceId: message.sourceId,\n };\n};\n\nconst symbolAssistantTransportExtras = Symbol(\"assistant-transport-extras\");\ntype AssistantTransportExtras = {\n [symbolAssistantTransportExtras]: true;\n sendCommand: (command: AssistantTransportCommand) => void;\n state: UserExternalState;\n};\n\nconst asAssistantTransportExtras = (\n extras: unknown,\n): AssistantTransportExtras => {\n if (\n typeof extras !== \"object\" ||\n extras == null ||\n !(symbolAssistantTransportExtras in extras)\n )\n throw new Error(\n \"This method can only be called when you are using useAssistantTransportRuntime\",\n );\n\n return extras as AssistantTransportExtras;\n};\n\nexport const useAssistantTransportSendCommand = () => {\n const aui = useAui();\n\n return (command: AssistantTransportCommand) => {\n const extras = aui.thread().getState().extras;\n const transportExtras = asAssistantTransportExtras(extras);\n transportExtras.sendCommand(command);\n };\n};\n\nexport function useAssistantTransportState(): UserExternalState;\nexport function useAssistantTransportState<T>(\n selector: (state: UserExternalState) => T,\n): T;\nexport function useAssistantTransportState<T>(\n selector: (state: UserExternalState) => T = (t) => t as T,\n): T | UserExternalState {\n return useAuiState((s) =>\n selector(asAssistantTransportExtras(s.thread.extras).state),\n );\n}\n\nconst useAssistantTransportThreadRuntime = <T>(\n options: AssistantTransportOptions<T>,\n): AssistantRuntime => {\n // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage\n const agentStateRef = useRef(options.initialState);\n // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage\n const [, rerender] = useState(0);\n // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage\n const resumeFlagRef = useRef(false);\n // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage\n const parentIdRef = useRef<string | null | undefined>(undefined);\n // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage\n const commandQueue = useCommandQueue({\n onQueue: () => runManager.schedule(),\n });\n\n // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage\n const threadId = useAuiState((s) => s.threadListItem.remoteId);\n\n // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage\n const runManager = useRunManager({\n onRun: async (signal: AbortSignal) => {\n const isResume = resumeFlagRef.current;\n resumeFlagRef.current = false;\n const commands: QueuedCommand[] = isResume ? [] : commandQueue.flush();\n if (commands.length === 0 && !isResume)\n throw new Error(\"No commands to send\");\n\n const headers = await createRequestHeaders(options.headers);\n const bodyValue =\n typeof options.body === \"function\"\n ? await options.body()\n : options.body;\n const context = runtime.thread.getModelContext();\n\n let requestBody: Record<string, unknown> = {\n commands,\n state: agentStateRef.current,\n system: context.system,\n tools: context.tools ? toToolsJSONSchema(context.tools) : undefined,\n threadId,\n ...(parentIdRef.current !== undefined && {\n parentId: parentIdRef.current,\n }),\n // nested (new format, aligned with AssistantChatTransport)\n callSettings: context.callSettings,\n config: context.config,\n // @deprecated spread at top level — use nested `callSettings`/`config` instead. Will be removed in a future version.\n ...context.callSettings,\n ...context.config,\n ...(bodyValue ?? {}),\n };\n\n if (options.prepareSendCommandsRequest) {\n requestBody = await options.prepareSendCommandsRequest(\n requestBody as SendCommandsRequestBody,\n );\n }\n\n const response = await fetch(\n isResume ? options.resumeApi! : options.api,\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(requestBody),\n signal,\n },\n );\n\n options.onResponse?.(response);\n\n if (!response.ok) {\n throw new Error(`Status ${response.status}: ${await response.text()}`);\n }\n\n if (!response.body) {\n throw new Error(\"Response body is null\");\n }\n\n // Select decoder based on protocol option\n const protocol = options.protocol ?? \"data-stream\";\n const decoder =\n protocol === \"assistant-transport\"\n ? new AssistantTransportDecoder()\n : new DataStreamDecoder();\n\n let err: string | undefined;\n const stream = response.body.pipeThrough(decoder).pipeThrough(\n new AssistantMessageAccumulator({\n initialMessage: createInitialMessage({\n unstable_state:\n (agentStateRef.current as ReadonlyJSONValue) ?? null,\n }),\n throttle: isResume,\n onError: (error) => {\n err = error;\n },\n }),\n );\n\n let markedDelivered = false;\n\n for await (const chunk of asAsyncIterableStream(stream)) {\n if (chunk.metadata.unstable_state === agentStateRef.current) continue;\n\n if (!markedDelivered) {\n commandQueue.markDelivered();\n markedDelivered = true;\n }\n\n agentStateRef.current = chunk.metadata.unstable_state as T;\n rerender((prev) => prev + 1);\n }\n\n if (err) {\n throw new Error(err);\n }\n },\n onFinish: options.onFinish,\n onCancel: () => {\n const cmds = [\n ...commandQueue.state.inTransit,\n ...commandQueue.state.queued,\n ];\n\n commandQueue.reset();\n\n options.onCancel?.({\n commands: cmds,\n updateState: (updater) => {\n agentStateRef.current = updater(agentStateRef.current);\n rerender((prev) => prev + 1);\n },\n });\n },\n onError: async (error) => {\n const inTransitCmds = [...commandQueue.state.inTransit];\n const queuedCmds = [...commandQueue.state.queued];\n\n commandQueue.reset();\n\n try {\n await options.onError?.(error as Error, {\n commands: inTransitCmds,\n updateState: (updater) => {\n agentStateRef.current = updater(agentStateRef.current);\n rerender((prev) => prev + 1);\n },\n });\n } finally {\n options.onCancel?.({\n commands: queuedCmds,\n updateState: (updater) => {\n agentStateRef.current = updater(agentStateRef.current);\n rerender((prev) => prev + 1);\n },\n error: error as Error,\n });\n }\n },\n });\n\n // Tool execution status state\n // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage\n const [toolStatuses, setToolStatuses] = useState<\n Record<string, ToolExecutionStatus>\n >({});\n\n // Reactive conversion of agent state + connection metadata → UI state\n // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage\n const pendingCommands = useMemo(\n () => [...commandQueue.state.inTransit, ...commandQueue.state.queued],\n [commandQueue.state],\n );\n // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage\n const converted = useConvertedState(\n options.converter,\n agentStateRef.current,\n pendingCommands,\n runManager.isRunning,\n toolStatuses,\n );\n\n // Create runtime\n // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage\n const runtime = useExternalStoreRuntime({\n messages: converted.messages,\n state: converted.state,\n isRunning: converted.isRunning,\n adapters: options.adapters,\n unstable_enableToolInvocations: true,\n setToolStatuses,\n extras: {\n [symbolAssistantTransportExtras]: true,\n sendCommand: (command: AssistantTransportCommand) => {\n commandQueue.enqueue(command);\n },\n state: agentStateRef.current as UserExternalState,\n } satisfies AssistantTransportExtras,\n onNew: async (message: AppendMessage): Promise<void> => {\n parentIdRef.current = message.parentId;\n const command = convertAppendMessageToCommand(message);\n commandQueue.enqueue(command);\n },\n ...(options.capabilities?.edit && {\n onEdit: async (message: AppendMessage): Promise<void> => {\n parentIdRef.current = message.parentId;\n const command = convertAppendMessageToCommand(message);\n commandQueue.enqueue(command);\n },\n }),\n onCancel: async () => {\n runManager.cancel();\n },\n onResume: async () => {\n if (!options.resumeApi)\n throw new Error(\"Must pass resumeApi to options to resume runs\");\n\n resumeFlagRef.current = true;\n runManager.schedule();\n },\n onAddToolResult: async (\n toolOptions: AddToolResultOptions,\n ): Promise<void> => {\n const command: AddToolResultCommand = {\n type: \"add-tool-result\",\n toolCallId: toolOptions.toolCallId,\n result: toolOptions.result as ReadonlyJSONObject,\n toolName: toolOptions.toolName,\n isError: toolOptions.isError,\n ...(toolOptions.artifact && { artifact: toolOptions.artifact }),\n ...(toolOptions.modelContent !== undefined && {\n modelContent: toolOptions.modelContent,\n }),\n };\n\n commandQueue.enqueue(command);\n },\n onLoadExternalState: async (state) => {\n agentStateRef.current = state as T;\n rerender((prev) => prev + 1);\n },\n });\n\n return runtime;\n};\n\n/**\n * @alpha This is an experimental API that is subject to change.\n */\nexport const useAssistantTransportRuntime = <T>(\n options: AssistantTransportOptions<T>,\n): AssistantRuntime => {\n const runtime = useRemoteThreadListRuntime({\n runtimeHook: function RuntimeHook() {\n // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage\n return useAssistantTransportThreadRuntime(options);\n },\n adapter: new InMemoryThreadListAdapter(),\n allowNesting: true,\n });\n return runtime;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"useAssistantTransportRuntime.js","names":["createInitialMessage"],"sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.ts"],"sourcesContent":["\"use client\";\n\nimport type { AppendMessage } from \"@assistant-ui/core\";\nimport {\n type ReadonlyJSONObject,\n type ReadonlyJSONValue,\n asAsyncIterableStream,\n} from \"assistant-stream/utils\";\nimport { useExternalStoreRuntime } from \"../external-store/useExternalStoreRuntime\";\nimport type { AssistantRuntime } from \"../../runtime/AssistantRuntime\";\nimport type { AddToolResultOptions } from \"@assistant-ui/core\";\nimport { useMemo, useRef, useState } from \"react\";\nimport {\n AssistantMessageAccumulator,\n DataStreamDecoder,\n AssistantTransportDecoder,\n unstable_createInitialMessage as createInitialMessage,\n toToolsJSONSchema,\n} from \"assistant-stream\";\nimport type {\n AssistantTransportOptions,\n AddMessageCommand,\n AddToolResultCommand,\n UserMessagePart,\n QueuedCommand,\n AssistantTransportCommand,\n SendCommandsRequestBody,\n} from \"./types\";\nimport { useCommandQueue } from \"./commandQueue\";\nimport { useRunManager } from \"./runManager\";\nimport { useConvertedState } from \"./useConvertedState\";\nimport type { ToolExecutionStatus } from \"@assistant-ui/core\";\nimport { createRequestHeaders } from \"@assistant-ui/core\";\nimport { useRemoteThreadListRuntime } from \"../remote-thread-list/useRemoteThreadListRuntime\";\nimport { InMemoryThreadListAdapter } from \"@assistant-ui/core\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\nimport type { UserExternalState } from \"../../../augmentations\";\n\nconst convertAppendMessageToCommand = (\n message: AppendMessage,\n): AddMessageCommand => {\n if (message.role !== \"user\")\n throw new Error(\"Only user messages are supported\");\n\n const parts: UserMessagePart[] = [];\n const content = [\n ...message.content,\n ...(message.attachments?.flatMap((a) => a.content) ?? []),\n ];\n for (const contentPart of content) {\n if (contentPart.type === \"text\") {\n parts.push({ type: \"text\", text: contentPart.text });\n } else if (contentPart.type === \"image\") {\n parts.push({ type: \"image\", image: contentPart.image });\n }\n }\n\n return {\n type: \"add-message\",\n message: {\n role: \"user\",\n parts,\n },\n parentId: message.parentId,\n sourceId: message.sourceId,\n };\n};\n\nconst symbolAssistantTransportExtras = Symbol(\"assistant-transport-extras\");\ntype AssistantTransportExtras = {\n [symbolAssistantTransportExtras]: true;\n sendCommand: (command: AssistantTransportCommand) => void;\n state: UserExternalState;\n};\n\nconst asAssistantTransportExtras = (\n extras: unknown,\n): AssistantTransportExtras => {\n if (\n typeof extras !== \"object\" ||\n extras == null ||\n !(symbolAssistantTransportExtras in extras)\n )\n throw new Error(\n \"This method can only be called when you are using useAssistantTransportRuntime\",\n );\n\n return extras as AssistantTransportExtras;\n};\n\nexport const useAssistantTransportSendCommand = () => {\n const aui = useAui();\n\n return (command: AssistantTransportCommand) => {\n const extras = aui.thread().getState().extras;\n const transportExtras = asAssistantTransportExtras(extras);\n transportExtras.sendCommand(command);\n };\n};\n\nexport function useAssistantTransportState(): UserExternalState;\nexport function useAssistantTransportState<T>(\n selector: (state: UserExternalState) => T,\n): T;\nexport function useAssistantTransportState<T>(\n selector: (state: UserExternalState) => T = (t) => t as T,\n): T | UserExternalState {\n return useAuiState((s) =>\n selector(asAssistantTransportExtras(s.thread.extras).state),\n );\n}\n\nconst useAssistantTransportThreadRuntime = <T>(\n options: AssistantTransportOptions<T>,\n): AssistantRuntime => {\n const agentStateRef = useRef(options.initialState);\n const [, rerender] = useState(0);\n const resumeFlagRef = useRef(false);\n const parentIdRef = useRef<string | null | undefined>(undefined);\n const commandQueue = useCommandQueue({\n onQueue: () => runManager.schedule(),\n });\n\n const threadId = useAuiState((s) => s.threadListItem.remoteId);\n\n const runManager = useRunManager({\n onRun: async (signal: AbortSignal) => {\n const isResume = resumeFlagRef.current;\n resumeFlagRef.current = false;\n const commands: QueuedCommand[] = isResume ? [] : commandQueue.flush();\n if (commands.length === 0 && !isResume)\n throw new Error(\"No commands to send\");\n\n const headers = await createRequestHeaders(options.headers);\n const bodyValue =\n typeof options.body === \"function\"\n ? await options.body()\n : options.body;\n const context = runtime.thread.getModelContext();\n\n let requestBody: Record<string, unknown> = {\n commands,\n state: agentStateRef.current,\n system: context.system,\n tools: context.tools ? toToolsJSONSchema(context.tools) : undefined,\n threadId,\n ...(parentIdRef.current !== undefined && {\n parentId: parentIdRef.current,\n }),\n // nested (new format, aligned with AssistantChatTransport)\n callSettings: context.callSettings,\n config: context.config,\n // @deprecated spread at top level — use nested `callSettings`/`config` instead. Will be removed in a future version.\n ...context.callSettings,\n ...context.config,\n ...(bodyValue ?? {}),\n };\n\n if (options.prepareSendCommandsRequest) {\n requestBody = await options.prepareSendCommandsRequest(\n requestBody as SendCommandsRequestBody,\n );\n }\n\n const response = await fetch(\n isResume ? options.resumeApi! : options.api,\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(requestBody),\n signal,\n },\n );\n\n options.onResponse?.(response);\n\n if (!response.ok) {\n throw new Error(`Status ${response.status}: ${await response.text()}`);\n }\n\n if (!response.body) {\n throw new Error(\"Response body is null\");\n }\n\n // Select decoder based on protocol option\n const protocol = options.protocol ?? \"data-stream\";\n const decoder =\n protocol === \"assistant-transport\"\n ? new AssistantTransportDecoder()\n : new DataStreamDecoder();\n\n let err: string | undefined;\n const stream = response.body.pipeThrough(decoder).pipeThrough(\n new AssistantMessageAccumulator({\n initialMessage: createInitialMessage({\n unstable_state:\n (agentStateRef.current as ReadonlyJSONValue) ?? null,\n }),\n throttle: isResume,\n onError: (error) => {\n err = error;\n },\n }),\n );\n\n let markedDelivered = false;\n\n for await (const chunk of asAsyncIterableStream(stream)) {\n if (chunk.metadata.unstable_state === agentStateRef.current) continue;\n\n if (!markedDelivered) {\n commandQueue.markDelivered();\n markedDelivered = true;\n }\n\n agentStateRef.current = chunk.metadata.unstable_state as T;\n rerender((prev) => prev + 1);\n }\n\n if (err) {\n throw new Error(err);\n }\n },\n onFinish: options.onFinish,\n onCancel: () => {\n const cmds = [\n ...commandQueue.state.inTransit,\n ...commandQueue.state.queued,\n ];\n\n commandQueue.reset();\n\n options.onCancel?.({\n commands: cmds,\n updateState: (updater) => {\n agentStateRef.current = updater(agentStateRef.current);\n rerender((prev) => prev + 1);\n },\n });\n },\n onError: async (error) => {\n const inTransitCmds = [...commandQueue.state.inTransit];\n const queuedCmds = [...commandQueue.state.queued];\n\n commandQueue.reset();\n\n try {\n await options.onError?.(error as Error, {\n commands: inTransitCmds,\n updateState: (updater) => {\n agentStateRef.current = updater(agentStateRef.current);\n rerender((prev) => prev + 1);\n },\n });\n } finally {\n options.onCancel?.({\n commands: queuedCmds,\n updateState: (updater) => {\n agentStateRef.current = updater(agentStateRef.current);\n rerender((prev) => prev + 1);\n },\n error: error as Error,\n });\n }\n },\n });\n\n // Tool execution status state\n const [toolStatuses, setToolStatuses] = useState<\n Record<string, ToolExecutionStatus>\n >({});\n\n // Reactive conversion of agent state + connection metadata → UI state\n const pendingCommands = useMemo(\n () => [...commandQueue.state.inTransit, ...commandQueue.state.queued],\n [commandQueue.state],\n );\n const converted = useConvertedState(\n options.converter,\n agentStateRef.current,\n pendingCommands,\n runManager.isRunning,\n toolStatuses,\n );\n\n // Create runtime\n const runtime = useExternalStoreRuntime({\n messages: converted.messages,\n state: converted.state,\n isRunning: converted.isRunning,\n adapters: options.adapters,\n unstable_enableToolInvocations: true,\n setToolStatuses,\n extras: {\n [symbolAssistantTransportExtras]: true,\n sendCommand: (command: AssistantTransportCommand) => {\n commandQueue.enqueue(command);\n },\n state: agentStateRef.current as UserExternalState,\n } satisfies AssistantTransportExtras,\n onNew: async (message: AppendMessage): Promise<void> => {\n parentIdRef.current = message.parentId;\n const command = convertAppendMessageToCommand(message);\n commandQueue.enqueue(command);\n },\n ...(options.capabilities?.edit && {\n onEdit: async (message: AppendMessage): Promise<void> => {\n parentIdRef.current = message.parentId;\n const command = convertAppendMessageToCommand(message);\n commandQueue.enqueue(command);\n },\n }),\n onCancel: async () => {\n runManager.cancel();\n },\n onResume: async () => {\n if (!options.resumeApi)\n throw new Error(\"Must pass resumeApi to options to resume runs\");\n\n resumeFlagRef.current = true;\n runManager.schedule();\n },\n onAddToolResult: async (\n toolOptions: AddToolResultOptions,\n ): Promise<void> => {\n const command: AddToolResultCommand = {\n type: \"add-tool-result\",\n toolCallId: toolOptions.toolCallId,\n result: toolOptions.result as ReadonlyJSONObject,\n toolName: toolOptions.toolName,\n isError: toolOptions.isError,\n ...(toolOptions.artifact && { artifact: toolOptions.artifact }),\n ...(toolOptions.modelContent !== undefined && {\n modelContent: toolOptions.modelContent,\n }),\n };\n\n commandQueue.enqueue(command);\n },\n onLoadExternalState: async (state) => {\n agentStateRef.current = state as T;\n rerender((prev) => prev + 1);\n },\n });\n\n return runtime;\n};\n\n/**\n * @alpha This is an experimental API that is subject to change.\n */\nexport const useAssistantTransportRuntime = <T>(\n options: AssistantTransportOptions<T>,\n): AssistantRuntime => {\n const runtime = useRemoteThreadListRuntime({\n runtimeHook: function RuntimeHook() {\n return useAssistantTransportThreadRuntime(options);\n },\n adapter: new InMemoryThreadListAdapter(),\n allowNesting: true,\n });\n return runtime;\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"useConvertedState.d.ts","names":[],"sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/useConvertedState.ts"],"mappings":";;;;iBAQgB,iBAAA,GAAA,CACd,SAAA,EAAW,gCAAA,CAAiC,CAAA,GAC5C,UAAA,EAAY,CAAA,EACZ,eAAA,EAAiB,yBAAA,IACjB,SAAA,WACA,YAAA,EAAc,MAAA,SAAe,mBAAA,IAC5B,uBAAA"}
1
+ {"version":3,"file":"useConvertedState.d.ts","names":[],"sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/useConvertedState.ts"],"mappings":";;;;iBAQgB,iBAAA,IACd,SAAA,EAAW,gCAAA,CAAiC,CAAA,GAC5C,UAAA,EAAY,CAAA,EACZ,eAAA,EAAiB,yBAAA,IACjB,SAAA,WACA,YAAA,EAAc,MAAA,SAAe,mBAAA,IAC5B,uBAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"useLatestRef.d.ts","names":[],"sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/useLatestRef.ts"],"mappings":";iBAEgB,YAAA,GAAA,CAAgB,KAAA,EAAO,CAAA;EAKrB,OAAA,EAAS,CAAC;AAAA"}
1
+ {"version":3,"file":"useLatestRef.d.ts","names":[],"sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/useLatestRef.ts"],"mappings":";iBAEgB,YAAA,IAAgB,KAAA,EAAO,CAAA;EAKrB,OAAA,EAAS,CAAC;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"app-frame.d.ts","names":[],"sources":["../../src/mcp-apps/app-frame.tsx"],"mappings":";;;iBA2FgB,WAAA,CAAA;EACd,GAAA;EACA,QAAA;EACA,KAAA;EACA,MAAA;EACA,OAAA;EACA,QAAA;EACA,QAAA;EACA,WAAA;EACA;AAAA,GACC,gBAAA,+BAAgB,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"app-frame.d.ts","names":[],"sources":["../../src/mcp-apps/app-frame.tsx"],"mappings":";;;iBA2FgB,WAAA;EACd,GAAA;EACA,QAAA;EACA,KAAA;EACA,MAAA;EACA,OAAA;EACA,QAAA;EACA,QAAA;EACA,WAAA;EACA;AAAA,GACC,gBAAA,+BAAgB,GAAA,CAAA,OAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"triggerKeyboardResource.js","names":[],"sources":["../../../../src/primitives/composer/trigger/triggerKeyboardResource.ts"],"sourcesContent":["import {\n resource,\n tapEffect,\n tapEffectEvent,\n tapState,\n} from \"@assistant-ui/tap\";\nimport type {\n Unstable_TriggerCategory,\n Unstable_TriggerItem,\n} from \"@assistant-ui/core\";\n\n/** Relies on `Unstable_TriggerCategory` never carrying a `type` field. */\nfunction isTriggerItem(\n x: Unstable_TriggerItem | Unstable_TriggerCategory,\n): x is Unstable_TriggerItem {\n return \"type\" in x;\n}\n\n/** Key event shape accepted by the keyboard handler. */\nexport type TriggerPopoverKeyEvent = {\n readonly key: string;\n readonly shiftKey: boolean;\n preventDefault(): void;\n};\n\nexport type TriggerKeyboardResourceOutput = {\n /** Index of the currently highlighted entry within the navigable list. */\n readonly highlightedIndex: number;\n /** ID of the currently highlighted item (for `aria-activedescendant`). */\n readonly highlightedItemId: string | undefined;\n /** Move the highlight to an entry index (e.g. from pointer hover). Out-of-range values are ignored. */\n highlightIndex(index: number): void;\n /** Handle a key event; returns `true` if it was consumed. */\n handleKeyDown(e: TriggerPopoverKeyEvent): boolean;\n};\n\n/**\n * Owns keyboard-driven highlight state for the popover. Delegates selection,\n * category drill-in, back, and close to the callbacks supplied by the parent.\n */\nexport const TriggerKeyboardResource = resource(\n ({\n navigableList,\n isSearchMode,\n activeCategoryId,\n query,\n popoverId,\n open,\n selectItem,\n selectCategory,\n goBack,\n close,\n }: {\n navigableList: readonly (Unstable_TriggerCategory | Unstable_TriggerItem)[];\n isSearchMode: boolean;\n activeCategoryId: string | null;\n query: string;\n popoverId: string;\n open: boolean;\n selectItem: (item: Unstable_TriggerItem) => void;\n selectCategory: (categoryId: string) => void;\n goBack: () => void;\n close: () => void;\n }): TriggerKeyboardResourceOutput => {\n const [highlightedIndex, setHighlightedIndex] = tapState(0);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: intentional reset on list change\n tapEffect(() => {\n setHighlightedIndex(0);\n }, [navigableList]);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: intentional reset\n tapEffect(() => {\n setHighlightedIndex(0);\n }, [isSearchMode, activeCategoryId]);\n\n const highlightIndex = tapEffectEvent((index: number) => {\n if (index < 0 || index >= navigableList.length) return;\n if (index === highlightedIndex) return;\n setHighlightedIndex(index);\n });\n\n const handleKeyDown = tapEffectEvent(\n (e: TriggerPopoverKeyEvent): boolean => {\n if (!open) return false;\n\n switch (e.key) {\n case \"ArrowDown\": {\n e.preventDefault();\n setHighlightedIndex((prev) => {\n const len = navigableList.length;\n if (len === 0) return 0;\n return prev < len - 1 ? prev + 1 : 0;\n });\n return true;\n }\n case \"ArrowUp\": {\n e.preventDefault();\n setHighlightedIndex((prev) => {\n const len = navigableList.length;\n if (len === 0) return 0;\n return prev > 0 ? prev - 1 : len - 1;\n });\n return true;\n }\n case \"Enter\":\n case \"Tab\": {\n if (e.shiftKey) return false;\n e.preventDefault();\n const item = navigableList[highlightedIndex];\n if (!item) return true;\n\n if (isTriggerItem(item)) {\n selectItem(item);\n } else {\n selectCategory(item.id);\n }\n return true;\n }\n case \"Escape\": {\n e.preventDefault();\n close();\n return true;\n }\n case \"Backspace\": {\n if (activeCategoryId && query === \"\") {\n e.preventDefault();\n goBack();\n return true;\n }\n return false;\n }\n default:\n return false;\n }\n },\n );\n\n const highlightedEntry = navigableList[highlightedIndex];\n const highlightedItemId =\n open && highlightedEntry\n ? `${popoverId}-option-${highlightedEntry.id}`\n : undefined;\n\n return {\n highlightedIndex,\n highlightedItemId,\n highlightIndex,\n handleKeyDown,\n };\n },\n);\n"],"mappings":";;;AAYA,SAAS,cACP,GAC2B;CAC3B,OAAO,UAAU;AACnB;;;;;AAwBA,MAAa,0BAA0B,UACpC,EACC,eACA,cACA,kBACA,OACA,WACA,MACA,YACA,gBACA,QACA,YAYmC;CACnC,MAAM,CAAC,kBAAkB,uBAAuB,SAAS,CAAC;CAG1D,gBAAgB;EACd,oBAAoB,CAAC;CACvB,GAAG,CAAC,aAAa,CAAC;CAGlB,gBAAgB;EACd,oBAAoB,CAAC;CACvB,GAAG,CAAC,cAAc,gBAAgB,CAAC;CAEnC,MAAM,iBAAiB,gBAAgB,UAAkB;EACvD,IAAI,QAAQ,KAAK,SAAS,cAAc,QAAQ;EAChD,IAAI,UAAU,kBAAkB;EAChC,oBAAoB,KAAK;CAC3B,CAAC;CAED,MAAM,gBAAgB,gBACnB,MAAuC;EACtC,IAAI,CAAC,MAAM,OAAO;EAElB,QAAQ,EAAE,KAAV;GACE,KAAK;IACH,EAAE,eAAe;IACjB,qBAAqB,SAAS;KAC5B,MAAM,MAAM,cAAc;KAC1B,IAAI,QAAQ,GAAG,OAAO;KACtB,OAAO,OAAO,MAAM,IAAI,OAAO,IAAI;IACrC,CAAC;IACD,OAAO;GAET,KAAK;IACH,EAAE,eAAe;IACjB,qBAAqB,SAAS;KAC5B,MAAM,MAAM,cAAc;KAC1B,IAAI,QAAQ,GAAG,OAAO;KACtB,OAAO,OAAO,IAAI,OAAO,IAAI,MAAM;IACrC,CAAC;IACD,OAAO;GAET,KAAK;GACL,KAAK,OAAO;IACV,IAAI,EAAE,UAAU,OAAO;IACvB,EAAE,eAAe;IACjB,MAAM,OAAO,cAAc;IAC3B,IAAI,CAAC,MAAM,OAAO;IAElB,IAAI,cAAc,IAAI,GACpB,WAAW,IAAI;SAEf,eAAe,KAAK,EAAE;IAExB,OAAO;GACT;GACA,KAAK;IACH,EAAE,eAAe;IACjB,MAAM;IACN,OAAO;GAET,KAAK;IACH,IAAI,oBAAoB,UAAU,IAAI;KACpC,EAAE,eAAe;KACjB,OAAO;KACP,OAAO;IACT;IACA,OAAO;GAET,SACE,OAAO;EACX;CACF,CACF;CAEA,MAAM,mBAAmB,cAAc;CAMvC,OAAO;EACL;EACA,mBANA,QAAQ,mBACJ,GAAG,UAAU,UAAU,iBAAiB,OACxC,KAAA;EAKJ;EACA;CACF;AACF,CACF"}
1
+ {"version":3,"file":"triggerKeyboardResource.js","names":[],"sources":["../../../../src/primitives/composer/trigger/triggerKeyboardResource.ts"],"sourcesContent":["import {\n resource,\n tapEffect,\n tapEffectEvent,\n tapState,\n} from \"@assistant-ui/tap\";\nimport type {\n Unstable_TriggerCategory,\n Unstable_TriggerItem,\n} from \"@assistant-ui/core\";\n\n/** Relies on `Unstable_TriggerCategory` never carrying a `type` field. */\nfunction isTriggerItem(\n x: Unstable_TriggerItem | Unstable_TriggerCategory,\n): x is Unstable_TriggerItem {\n return \"type\" in x;\n}\n\n/** Key event shape accepted by the keyboard handler. */\nexport type TriggerPopoverKeyEvent = {\n readonly key: string;\n readonly shiftKey: boolean;\n preventDefault(): void;\n};\n\nexport type TriggerKeyboardResourceOutput = {\n /** Index of the currently highlighted entry within the navigable list. */\n readonly highlightedIndex: number;\n /** ID of the currently highlighted item (for `aria-activedescendant`). */\n readonly highlightedItemId: string | undefined;\n /** Move the highlight to an entry index (e.g. from pointer hover). Out-of-range values are ignored. */\n highlightIndex(index: number): void;\n /** Handle a key event; returns `true` if it was consumed. */\n handleKeyDown(e: TriggerPopoverKeyEvent): boolean;\n};\n\n/**\n * Owns keyboard-driven highlight state for the popover. Delegates selection,\n * category drill-in, back, and close to the callbacks supplied by the parent.\n */\nexport const TriggerKeyboardResource = resource(\n ({\n navigableList,\n isSearchMode,\n activeCategoryId,\n query,\n popoverId,\n open,\n selectItem,\n selectCategory,\n goBack,\n close,\n }: {\n navigableList: readonly (Unstable_TriggerCategory | Unstable_TriggerItem)[];\n isSearchMode: boolean;\n activeCategoryId: string | null;\n query: string;\n popoverId: string;\n open: boolean;\n selectItem: (item: Unstable_TriggerItem) => void;\n selectCategory: (categoryId: string) => void;\n goBack: () => void;\n close: () => void;\n }): TriggerKeyboardResourceOutput => {\n const [highlightedIndex, setHighlightedIndex] = tapState(0);\n\n tapEffect(() => {\n setHighlightedIndex(0);\n }, [navigableList]);\n\n tapEffect(() => {\n setHighlightedIndex(0);\n }, [isSearchMode, activeCategoryId]);\n\n const highlightIndex = tapEffectEvent((index: number) => {\n if (index < 0 || index >= navigableList.length) return;\n if (index === highlightedIndex) return;\n setHighlightedIndex(index);\n });\n\n const handleKeyDown = tapEffectEvent(\n (e: TriggerPopoverKeyEvent): boolean => {\n if (!open) return false;\n\n switch (e.key) {\n case \"ArrowDown\": {\n e.preventDefault();\n setHighlightedIndex((prev) => {\n const len = navigableList.length;\n if (len === 0) return 0;\n return prev < len - 1 ? prev + 1 : 0;\n });\n return true;\n }\n case \"ArrowUp\": {\n e.preventDefault();\n setHighlightedIndex((prev) => {\n const len = navigableList.length;\n if (len === 0) return 0;\n return prev > 0 ? prev - 1 : len - 1;\n });\n return true;\n }\n case \"Enter\":\n case \"Tab\": {\n if (e.shiftKey) return false;\n e.preventDefault();\n const item = navigableList[highlightedIndex];\n if (!item) return true;\n\n if (isTriggerItem(item)) {\n selectItem(item);\n } else {\n selectCategory(item.id);\n }\n return true;\n }\n case \"Escape\": {\n e.preventDefault();\n close();\n return true;\n }\n case \"Backspace\": {\n if (activeCategoryId && query === \"\") {\n e.preventDefault();\n goBack();\n return true;\n }\n return false;\n }\n default:\n return false;\n }\n },\n );\n\n const highlightedEntry = navigableList[highlightedIndex];\n const highlightedItemId =\n open && highlightedEntry\n ? `${popoverId}-option-${highlightedEntry.id}`\n : undefined;\n\n return {\n highlightedIndex,\n highlightedItemId,\n highlightIndex,\n handleKeyDown,\n };\n },\n);\n"],"mappings":";;;AAYA,SAAS,cACP,GAC2B;CAC3B,OAAO,UAAU;AACnB;;;;;AAwBA,MAAa,0BAA0B,UACpC,EACC,eACA,cACA,kBACA,OACA,WACA,MACA,YACA,gBACA,QACA,YAYmC;CACnC,MAAM,CAAC,kBAAkB,uBAAuB,SAAS,CAAC;CAE1D,gBAAgB;EACd,oBAAoB,CAAC;CACvB,GAAG,CAAC,aAAa,CAAC;CAElB,gBAAgB;EACd,oBAAoB,CAAC;CACvB,GAAG,CAAC,cAAc,gBAAgB,CAAC;CAEnC,MAAM,iBAAiB,gBAAgB,UAAkB;EACvD,IAAI,QAAQ,KAAK,SAAS,cAAc,QAAQ;EAChD,IAAI,UAAU,kBAAkB;EAChC,oBAAoB,KAAK;CAC3B,CAAC;CAED,MAAM,gBAAgB,gBACnB,MAAuC;EACtC,IAAI,CAAC,MAAM,OAAO;EAElB,QAAQ,EAAE,KAAV;GACE,KAAK;IACH,EAAE,eAAe;IACjB,qBAAqB,SAAS;KAC5B,MAAM,MAAM,cAAc;KAC1B,IAAI,QAAQ,GAAG,OAAO;KACtB,OAAO,OAAO,MAAM,IAAI,OAAO,IAAI;IACrC,CAAC;IACD,OAAO;GAET,KAAK;IACH,EAAE,eAAe;IACjB,qBAAqB,SAAS;KAC5B,MAAM,MAAM,cAAc;KAC1B,IAAI,QAAQ,GAAG,OAAO;KACtB,OAAO,OAAO,IAAI,OAAO,IAAI,MAAM;IACrC,CAAC;IACD,OAAO;GAET,KAAK;GACL,KAAK,OAAO;IACV,IAAI,EAAE,UAAU,OAAO;IACvB,EAAE,eAAe;IACjB,MAAM,OAAO,cAAc;IAC3B,IAAI,CAAC,MAAM,OAAO;IAElB,IAAI,cAAc,IAAI,GACpB,WAAW,IAAI;SAEf,eAAe,KAAK,EAAE;IAExB,OAAO;GACT;GACA,KAAK;IACH,EAAE,eAAe;IACjB,MAAM;IACN,OAAO;GAET,KAAK;IACH,IAAI,oBAAoB,UAAU,IAAI;KACpC,EAAE,eAAe;KACjB,OAAO;KACP,OAAO;IACT;IACA,OAAO;GAET,SACE,OAAO;EACX;CACF,CACF;CAEA,MAAM,mBAAmB,cAAc;CAMvC,OAAO;EACL;EACA,mBANA,QAAQ,mBACJ,GAAG,UAAU,UAAU,iBAAiB,OACxC,KAAA;EAKJ;EACA;CACF;AACF,CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"MessagePartImage.js","names":[],"sources":["../../../src/primitives/messagePart/MessagePartImage.tsx"],"sourcesContent":["\"use client\";\n\nimport { Primitive } from \"../../utils/Primitive\";\nimport {\n type ComponentRef,\n forwardRef,\n type ComponentPropsWithoutRef,\n} from \"react\";\nimport { useMessagePartImage } from \"./useMessagePartImage\";\n\nexport namespace MessagePartPrimitiveImage {\n export type Element = ComponentRef<typeof Primitive.img>;\n /**\n * Props for the MessagePartPrimitive.Image component.\n * Accepts all standard img element props.\n */\n export type Props = ComponentPropsWithoutRef<typeof Primitive.img>;\n}\n\n/**\n * Renders an image from the current message part context.\n *\n * This component displays image content from the current message part,\n * automatically setting the src attribute from the message part's image data.\n *\n * @example\n * ```tsx\n * <MessagePartPrimitive.Image\n * alt=\"Generated image\"\n * className=\"message-image\"\n * style={{ maxWidth: '100%' }}\n * />\n * ```\n */\nexport const MessagePartPrimitiveImage = forwardRef<\n MessagePartPrimitiveImage.Element,\n MessagePartPrimitiveImage.Props\n>((props, forwardedRef) => {\n const { image } = useMessagePartImage();\n // biome-ignore lint/performance/noImgElement: next/image not applicable here\n return <Primitive.img src={image} {...props} ref={forwardedRef} />;\n});\n\nMessagePartPrimitiveImage.displayName = \"MessagePartPrimitive.Image\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAkCA,MAAa,4BAA4B,YAGtC,OAAO,iBAAiB;CACzB,MAAM,EAAE,UAAU,oBAAoB;CAEtC,OAAO,oBAAC,UAAU,KAAX;EAAe,KAAK;EAAO,GAAI;EAAO,KAAK;CAAe,CAAA;AACnE,CAAC;AAED,0BAA0B,cAAc"}
1
+ {"version":3,"file":"MessagePartImage.js","names":[],"sources":["../../../src/primitives/messagePart/MessagePartImage.tsx"],"sourcesContent":["\"use client\";\n\nimport { Primitive } from \"../../utils/Primitive\";\nimport {\n type ComponentRef,\n forwardRef,\n type ComponentPropsWithoutRef,\n} from \"react\";\nimport { useMessagePartImage } from \"./useMessagePartImage\";\n\nexport namespace MessagePartPrimitiveImage {\n export type Element = ComponentRef<typeof Primitive.img>;\n /**\n * Props for the MessagePartPrimitive.Image component.\n * Accepts all standard img element props.\n */\n export type Props = ComponentPropsWithoutRef<typeof Primitive.img>;\n}\n\n/**\n * Renders an image from the current message part context.\n *\n * This component displays image content from the current message part,\n * automatically setting the src attribute from the message part's image data.\n *\n * @example\n * ```tsx\n * <MessagePartPrimitive.Image\n * alt=\"Generated image\"\n * className=\"message-image\"\n * style={{ maxWidth: '100%' }}\n * />\n * ```\n */\nexport const MessagePartPrimitiveImage = forwardRef<\n MessagePartPrimitiveImage.Element,\n MessagePartPrimitiveImage.Props\n>((props, forwardedRef) => {\n const { image } = useMessagePartImage();\n return <Primitive.img src={image} {...props} ref={forwardedRef} />;\n});\n\nMessagePartPrimitiveImage.displayName = \"MessagePartPrimitive.Image\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAkCA,MAAa,4BAA4B,YAGtC,OAAO,iBAAiB;CACzB,MAAM,EAAE,UAAU,oBAAoB;CACtC,OAAO,oBAAC,UAAU,KAAX;EAAe,KAAK;EAAO,GAAI;EAAO,KAAK;CAAe,CAAA;AACnE,CAAC;AAED,0BAA0B,cAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"useThreadViewportAutoScroll.d.ts","names":[],"sources":["../../../src/primitives/thread/useThreadViewportAutoScroll.ts"],"mappings":";;;kBAWiB,2BAAA;EAAA,KACH,OAAA;IADG;;;;;;IAQb,UAAA;IAcA;;;AAO4B;AAIhC;IAlBI,wBAAA;IA0KH;;;;;IAnKG,0BAAA;IAgBD;;;;;IATC,4BAAA;EAAA;AAAA;AAAA,cAIS,2BAAA,oBAAgD,WAAA;EAAa,UAAA;EAAA,wBAAA;EAAA,0BAAA;EAAA;AAAA,GAKvE,2BAAA,CAA4B,OAAA,KAAU,WAAA,CAAY,QAAA"}
1
+ {"version":3,"file":"useThreadViewportAutoScroll.d.ts","names":[],"sources":["../../../src/primitives/thread/useThreadViewportAutoScroll.ts"],"mappings":";;;kBAWiB,2BAAA;EAAA,KACH,OAAA;IADG;;;;;;IAQb,UAAA;IAcA;;;AAO4B;AAIhC;IAlBI,wBAAA;IAkMH;;;;;IA3LG,0BAAA;IAgBD;;;;;IATC,4BAAA;EAAA;AAAA;AAAA,cAIS,2BAAA,oBAAgD,WAAA;EAAa,UAAA;EAAA,wBAAA;EAAA,0BAAA;EAAA;AAAA,GAKvE,2BAAA,CAA4B,OAAA,KAAU,WAAA,CAAY,QAAA"}
@@ -16,6 +16,9 @@ const useThreadViewportAutoScroll = ({ autoScroll, scrollToBottomOnRunStart = tr
16
16
  const threadViewportStore = useThreadViewportStore();
17
17
  if (autoScroll === void 0) autoScroll = threadViewportStore.getState().turnAnchor !== "top";
18
18
  const lastScrollTop = useRef(0);
19
+ const lastScrollHeight = useRef(0);
20
+ const lastObservedScrollHeight = useRef(0);
21
+ const lastObservedClientHeight = useRef(0);
19
22
  const scrollingToBottomBehaviorRef = useRef(null);
20
23
  const scrollToBottom = useCallback((behavior) => {
21
24
  const div = divRef.current;
@@ -45,16 +48,23 @@ const useThreadViewportAutoScroll = ({ autoScroll, scrollToBottomOnRunStart = tr
45
48
  const div = divRef.current;
46
49
  if (!div) return;
47
50
  const isAtBottom = threadViewportStore.getState().isAtBottom;
48
- const newIsAtBottom = Math.abs(div.scrollHeight - div.scrollTop - div.clientHeight) < 1 || div.scrollHeight <= div.clientHeight;
51
+ const newIsAtBottom = Math.abs(div.scrollHeight - div.scrollTop - div.clientHeight) <= 1 || div.scrollHeight <= div.clientHeight;
49
52
  if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {} else {
50
53
  if (newIsAtBottom) {
51
54
  if (div.scrollHeight > div.clientHeight + 1) scrollingToBottomBehaviorRef.current = null;
52
- }
55
+ } else if (lastScrollTop.current > div.scrollTop && lastScrollHeight.current === div.scrollHeight) scrollingToBottomBehaviorRef.current = null;
53
56
  if ((newIsAtBottom || scrollingToBottomBehaviorRef.current === null) && newIsAtBottom !== isAtBottom) writableStore(threadViewportStore).setState({ isAtBottom: newIsAtBottom });
54
57
  }
55
58
  lastScrollTop.current = div.scrollTop;
59
+ lastScrollHeight.current = div.scrollHeight;
56
60
  };
57
61
  const resizeRef = useOnResizeContent(() => {
62
+ const div = divRef.current;
63
+ if (!div) return;
64
+ const { scrollHeight, clientHeight } = div;
65
+ if (scrollHeight === lastObservedScrollHeight.current && clientHeight === lastObservedClientHeight.current) return;
66
+ lastObservedScrollHeight.current = scrollHeight;
67
+ lastObservedClientHeight.current = clientHeight;
58
68
  const scrollBehavior = scrollingToBottomBehaviorRef.current;
59
69
  if (scrollBehavior && hasActiveTopAnchor()) scrollingToBottomBehaviorRef.current = null;
60
70
  else if (scrollBehavior) scrollToBottom(scrollBehavior);
@@ -1 +1 @@
1
- {"version":3,"file":"useThreadViewportAutoScroll.js","names":[],"sources":["../../../src/primitives/thread/useThreadViewportAutoScroll.ts"],"sourcesContent":["\"use client\";\n\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { useCallback, useLayoutEffect, useRef, type RefCallback } from \"react\";\nimport { useAuiEvent, useAuiState } from \"@assistant-ui/store\";\nimport { useOnResizeContent } from \"../../utils/hooks/useOnResizeContent\";\nimport { useOnScrollToBottom } from \"../../utils/hooks/useOnScrollToBottom\";\nimport { useManagedRef } from \"../../utils/hooks/useManagedRef\";\nimport { writableStore } from \"../../context/ReadonlyStore\";\nimport { useThreadViewportStore } from \"../../context/react/ThreadViewportContext\";\n\nexport namespace useThreadViewportAutoScroll {\n export type Options = {\n /**\n * Whether to automatically scroll to the bottom when new messages are added.\n * When enabled, the viewport will automatically scroll to show the latest content.\n *\n * Default false if `turnAnchor` is \"top\", otherwise defaults to true.\n */\n autoScroll?: boolean | undefined;\n\n /**\n * Whether to scroll to bottom when a new run starts.\n *\n * Defaults to true.\n */\n scrollToBottomOnRunStart?: boolean | undefined;\n\n /**\n * Whether to scroll to bottom when messages first appear in the thread.\n *\n * Defaults to true.\n */\n scrollToBottomOnInitialize?: boolean | undefined;\n\n /**\n * Whether to scroll to bottom when switching to a different thread.\n *\n * Defaults to true.\n */\n scrollToBottomOnThreadSwitch?: boolean | undefined;\n };\n}\n\nexport const useThreadViewportAutoScroll = <TElement extends HTMLElement>({\n autoScroll,\n scrollToBottomOnRunStart = true,\n scrollToBottomOnInitialize = true,\n scrollToBottomOnThreadSwitch = true,\n}: useThreadViewportAutoScroll.Options): RefCallback<TElement> => {\n const divRef = useRef<TElement>(null);\n const hasMessages = useAuiState((s) => s.thread.messages.length > 0);\n const initializeScrollRequestedRef = useRef(false);\n const scheduledFrameRef = useRef<number | null>(null);\n\n const threadViewportStore = useThreadViewportStore();\n if (autoScroll === undefined) {\n autoScroll = threadViewportStore.getState().turnAnchor !== \"top\";\n }\n\n const lastScrollTop = useRef<number>(0);\n\n // Pending bottom-scroll intent. Planted by initialize/run-start/switch/button\n // triggers, cleared only when handleScroll confirms we reached bottom.\n const scrollingToBottomBehaviorRef = useRef<ScrollBehavior | null>(null);\n\n const scrollToBottom = useCallback((behavior: ScrollBehavior) => {\n const div = divRef.current;\n if (!div) return;\n\n scrollingToBottomBehaviorRef.current = behavior;\n div.scrollTo({ top: div.scrollHeight, behavior });\n }, []);\n\n const scheduleScrollToBottom = useCallback(\n (behavior: ScrollBehavior) => {\n scrollingToBottomBehaviorRef.current = behavior;\n if (scheduledFrameRef.current !== null) {\n cancelAnimationFrame(scheduledFrameRef.current);\n }\n scheduledFrameRef.current = requestAnimationFrame(() => {\n scheduledFrameRef.current = null;\n scrollToBottom(behavior);\n });\n },\n [scrollToBottom],\n );\n\n useLayoutEffect(\n () => () => {\n if (scheduledFrameRef.current !== null) {\n cancelAnimationFrame(scheduledFrameRef.current);\n }\n },\n [],\n );\n\n const hasActiveTopAnchor = useCallback(() => {\n const state = threadViewportStore.getState();\n return (\n state.turnAnchor === \"top\" &&\n state.element.viewport === divRef.current &&\n state.element.anchor !== null\n );\n }, [threadViewportStore]);\n\n const handleScroll = () => {\n const div = divRef.current;\n if (!div) return;\n\n const isAtBottom = threadViewportStore.getState().isAtBottom;\n const newIsAtBottom =\n Math.abs(div.scrollHeight - div.scrollTop - div.clientHeight) < 1 ||\n div.scrollHeight <= div.clientHeight;\n\n const isInFlightDownwardScroll =\n !newIsAtBottom && lastScrollTop.current < div.scrollTop;\n if (isInFlightDownwardScroll) {\n // no-op: a smooth scroll-to-bottom fires many midpoint scroll events\n // before landing, don't flicker isAtBottom or clear intent mid-animation\n } else {\n if (newIsAtBottom) {\n // newIsAtBottom is ambiguous when the viewport doesn't overflow —\n // keep intent alive until content can actually scroll\n const viewportOverflows = div.scrollHeight > div.clientHeight + 1;\n if (viewportOverflows) {\n scrollingToBottomBehaviorRef.current = null;\n }\n }\n\n const shouldUpdate =\n newIsAtBottom || scrollingToBottomBehaviorRef.current === null;\n\n if (shouldUpdate && newIsAtBottom !== isAtBottom) {\n writableStore(threadViewportStore).setState({\n isAtBottom: newIsAtBottom,\n });\n }\n }\n\n lastScrollTop.current = div.scrollTop;\n };\n\n const resizeRef = useOnResizeContent(() => {\n const scrollBehavior = scrollingToBottomBehaviorRef.current;\n if (scrollBehavior && hasActiveTopAnchor()) {\n // Let the top-anchor reserve own scrolling while a run starts to avoid a bottom-scroll race.\n scrollingToBottomBehaviorRef.current = null;\n } else if (scrollBehavior) {\n scrollToBottom(scrollBehavior);\n } else if (autoScroll && threadViewportStore.getState().isAtBottom) {\n scrollToBottom(\"instant\");\n }\n\n handleScroll();\n });\n\n const scrollRef = useManagedRef<HTMLElement>((el) => {\n el.addEventListener(\"scroll\", handleScroll);\n return () => {\n el.removeEventListener(\"scroll\", handleScroll);\n };\n });\n\n useLayoutEffect(() => {\n if (!scrollToBottomOnInitialize) return;\n if (!hasMessages) {\n initializeScrollRequestedRef.current = false;\n return;\n }\n if (initializeScrollRequestedRef.current) return;\n\n initializeScrollRequestedRef.current = true;\n // defer to an in-flight run (e.g. first message on a new thread) that\n // already planted intent — otherwise we'd downgrade its \"auto\" to \"instant\"\n if (scrollingToBottomBehaviorRef.current !== null) return;\n scheduleScrollToBottom(\"instant\");\n }, [hasMessages, scheduleScrollToBottom, scrollToBottomOnInitialize]);\n\n useOnScrollToBottom(({ behavior }) => {\n scrollToBottom(behavior);\n });\n\n useAuiEvent(\"thread.runStart\", () => {\n if (!scrollToBottomOnRunStart) return;\n if (threadViewportStore.getState().turnAnchor === \"top\") return;\n scheduleScrollToBottom(\"auto\");\n });\n\n useAuiEvent(\"threadListItem.switchedTo\", () => {\n if (!scrollToBottomOnThreadSwitch) return;\n scheduleScrollToBottom(\"instant\");\n });\n\n const autoScrollRef = useComposedRefs<TElement>(resizeRef, scrollRef, divRef);\n return autoScrollRef as RefCallback<TElement>;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"useThreadViewportAutoScroll.js","names":[],"sources":["../../../src/primitives/thread/useThreadViewportAutoScroll.ts"],"sourcesContent":["\"use client\";\n\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { useCallback, useLayoutEffect, useRef, type RefCallback } from \"react\";\nimport { useAuiEvent, useAuiState } from \"@assistant-ui/store\";\nimport { useOnResizeContent } from \"../../utils/hooks/useOnResizeContent\";\nimport { useOnScrollToBottom } from \"../../utils/hooks/useOnScrollToBottom\";\nimport { useManagedRef } from \"../../utils/hooks/useManagedRef\";\nimport { writableStore } from \"../../context/ReadonlyStore\";\nimport { useThreadViewportStore } from \"../../context/react/ThreadViewportContext\";\n\nexport namespace useThreadViewportAutoScroll {\n export type Options = {\n /**\n * Whether to automatically scroll to the bottom when new messages are added.\n * When enabled, the viewport will automatically scroll to show the latest content.\n *\n * Default false if `turnAnchor` is \"top\", otherwise defaults to true.\n */\n autoScroll?: boolean | undefined;\n\n /**\n * Whether to scroll to bottom when a new run starts.\n *\n * Defaults to true.\n */\n scrollToBottomOnRunStart?: boolean | undefined;\n\n /**\n * Whether to scroll to bottom when messages first appear in the thread.\n *\n * Defaults to true.\n */\n scrollToBottomOnInitialize?: boolean | undefined;\n\n /**\n * Whether to scroll to bottom when switching to a different thread.\n *\n * Defaults to true.\n */\n scrollToBottomOnThreadSwitch?: boolean | undefined;\n };\n}\n\nexport const useThreadViewportAutoScroll = <TElement extends HTMLElement>({\n autoScroll,\n scrollToBottomOnRunStart = true,\n scrollToBottomOnInitialize = true,\n scrollToBottomOnThreadSwitch = true,\n}: useThreadViewportAutoScroll.Options): RefCallback<TElement> => {\n const divRef = useRef<TElement>(null);\n const hasMessages = useAuiState((s) => s.thread.messages.length > 0);\n const initializeScrollRequestedRef = useRef(false);\n const scheduledFrameRef = useRef<number | null>(null);\n\n const threadViewportStore = useThreadViewportStore();\n if (autoScroll === undefined) {\n autoScroll = threadViewportStore.getState().turnAnchor !== \"top\";\n }\n\n const lastScrollTop = useRef<number>(0);\n const lastScrollHeight = useRef<number>(0);\n const lastObservedScrollHeight = useRef<number>(0);\n const lastObservedClientHeight = useRef<number>(0);\n\n // Pending bottom-scroll intent. Planted by initialize/run-start/switch/button\n // triggers, cleared when handleScroll confirms we reached bottom, or when the\n // user actively scrolls up while content size is stable.\n const scrollingToBottomBehaviorRef = useRef<ScrollBehavior | null>(null);\n\n const scrollToBottom = useCallback((behavior: ScrollBehavior) => {\n const div = divRef.current;\n if (!div) return;\n\n scrollingToBottomBehaviorRef.current = behavior;\n div.scrollTo({ top: div.scrollHeight, behavior });\n }, []);\n\n const scheduleScrollToBottom = useCallback(\n (behavior: ScrollBehavior) => {\n scrollingToBottomBehaviorRef.current = behavior;\n if (scheduledFrameRef.current !== null) {\n cancelAnimationFrame(scheduledFrameRef.current);\n }\n scheduledFrameRef.current = requestAnimationFrame(() => {\n scheduledFrameRef.current = null;\n scrollToBottom(behavior);\n });\n },\n [scrollToBottom],\n );\n\n useLayoutEffect(\n () => () => {\n if (scheduledFrameRef.current !== null) {\n cancelAnimationFrame(scheduledFrameRef.current);\n }\n },\n [],\n );\n\n const hasActiveTopAnchor = useCallback(() => {\n const state = threadViewportStore.getState();\n return (\n state.turnAnchor === \"top\" &&\n state.element.viewport === divRef.current &&\n state.element.anchor !== null\n );\n }, [threadViewportStore]);\n\n const handleScroll = () => {\n const div = divRef.current;\n if (!div) return;\n\n const isAtBottom = threadViewportStore.getState().isAtBottom;\n const newIsAtBottom =\n Math.abs(div.scrollHeight - div.scrollTop - div.clientHeight) <= 1 ||\n div.scrollHeight <= div.clientHeight;\n\n const isInFlightDownwardScroll =\n !newIsAtBottom && lastScrollTop.current < div.scrollTop;\n if (isInFlightDownwardScroll) {\n // no-op: a smooth scroll-to-bottom fires many midpoint scroll events\n // before landing, don't flicker isAtBottom or clear intent mid-animation\n } else {\n if (newIsAtBottom) {\n // newIsAtBottom is ambiguous when the viewport doesn't overflow —\n // keep intent alive until content can actually scroll\n const viewportOverflows = div.scrollHeight > div.clientHeight + 1;\n if (viewportOverflows) {\n scrollingToBottomBehaviorRef.current = null;\n }\n } else if (\n lastScrollTop.current > div.scrollTop &&\n lastScrollHeight.current === div.scrollHeight\n ) {\n // scrollHeight equality rules out content-driven shifts being misread as user scroll-up\n scrollingToBottomBehaviorRef.current = null;\n }\n\n const shouldUpdate =\n newIsAtBottom || scrollingToBottomBehaviorRef.current === null;\n\n if (shouldUpdate && newIsAtBottom !== isAtBottom) {\n writableStore(threadViewportStore).setState({\n isAtBottom: newIsAtBottom,\n });\n }\n }\n\n lastScrollTop.current = div.scrollTop;\n lastScrollHeight.current = div.scrollHeight;\n };\n\n const resizeRef = useOnResizeContent(() => {\n const div = divRef.current;\n if (!div) return;\n\n const { scrollHeight, clientHeight } = div;\n if (\n scrollHeight === lastObservedScrollHeight.current &&\n clientHeight === lastObservedClientHeight.current\n ) {\n return;\n }\n lastObservedScrollHeight.current = scrollHeight;\n lastObservedClientHeight.current = clientHeight;\n\n const scrollBehavior = scrollingToBottomBehaviorRef.current;\n if (scrollBehavior && hasActiveTopAnchor()) {\n // Let the top-anchor reserve own scrolling while a run starts to avoid a bottom-scroll race.\n scrollingToBottomBehaviorRef.current = null;\n } else if (scrollBehavior) {\n scrollToBottom(scrollBehavior);\n } else if (autoScroll && threadViewportStore.getState().isAtBottom) {\n scrollToBottom(\"instant\");\n }\n\n handleScroll();\n });\n\n const scrollRef = useManagedRef<HTMLElement>((el) => {\n el.addEventListener(\"scroll\", handleScroll);\n return () => {\n el.removeEventListener(\"scroll\", handleScroll);\n };\n });\n\n useLayoutEffect(() => {\n if (!scrollToBottomOnInitialize) return;\n if (!hasMessages) {\n initializeScrollRequestedRef.current = false;\n return;\n }\n if (initializeScrollRequestedRef.current) return;\n\n initializeScrollRequestedRef.current = true;\n // defer to an in-flight run (e.g. first message on a new thread) that\n // already planted intent — otherwise we'd downgrade its \"auto\" to \"instant\"\n if (scrollingToBottomBehaviorRef.current !== null) return;\n scheduleScrollToBottom(\"instant\");\n }, [hasMessages, scheduleScrollToBottom, scrollToBottomOnInitialize]);\n\n useOnScrollToBottom(({ behavior }) => {\n scrollToBottom(behavior);\n });\n\n useAuiEvent(\"thread.runStart\", () => {\n if (!scrollToBottomOnRunStart) return;\n if (threadViewportStore.getState().turnAnchor === \"top\") return;\n scheduleScrollToBottom(\"auto\");\n });\n\n useAuiEvent(\"threadListItem.switchedTo\", () => {\n if (!scrollToBottomOnThreadSwitch) return;\n scheduleScrollToBottom(\"instant\");\n });\n\n const autoScrollRef = useComposedRefs<TElement>(resizeRef, scrollRef, divRef);\n return autoScrollRef as RefCallback<TElement>;\n};\n"],"mappings":";;;;;;;;;;AA4CA,MAAa,+BAA6D,EACxE,YACA,2BAA2B,MAC3B,6BAA6B,MAC7B,+BAA+B,WACiC;CAChE,MAAM,SAAS,OAAiB,IAAI;CACpC,MAAM,cAAc,aAAa,MAAM,EAAE,OAAO,SAAS,SAAS,CAAC;CACnE,MAAM,+BAA+B,OAAO,KAAK;CACjD,MAAM,oBAAoB,OAAsB,IAAI;CAEpD,MAAM,sBAAsB,uBAAuB;CACnD,IAAI,eAAe,KAAA,GACjB,aAAa,oBAAoB,SAAS,EAAE,eAAe;CAG7D,MAAM,gBAAgB,OAAe,CAAC;CACtC,MAAM,mBAAmB,OAAe,CAAC;CACzC,MAAM,2BAA2B,OAAe,CAAC;CACjD,MAAM,2BAA2B,OAAe,CAAC;CAKjD,MAAM,+BAA+B,OAA8B,IAAI;CAEvE,MAAM,iBAAiB,aAAa,aAA6B;EAC/D,MAAM,MAAM,OAAO;EACnB,IAAI,CAAC,KAAK;EAEV,6BAA6B,UAAU;EACvC,IAAI,SAAS;GAAE,KAAK,IAAI;GAAc;EAAS,CAAC;CAClD,GAAG,CAAC,CAAC;CAEL,MAAM,yBAAyB,aAC5B,aAA6B;EAC5B,6BAA6B,UAAU;EACvC,IAAI,kBAAkB,YAAY,MAChC,qBAAqB,kBAAkB,OAAO;EAEhD,kBAAkB,UAAU,4BAA4B;GACtD,kBAAkB,UAAU;GAC5B,eAAe,QAAQ;EACzB,CAAC;CACH,GACA,CAAC,cAAc,CACjB;CAEA,4BACc;EACV,IAAI,kBAAkB,YAAY,MAChC,qBAAqB,kBAAkB,OAAO;CAElD,GACA,CAAC,CACH;CAEA,MAAM,qBAAqB,kBAAkB;EAC3C,MAAM,QAAQ,oBAAoB,SAAS;EAC3C,OACE,MAAM,eAAe,SACrB,MAAM,QAAQ,aAAa,OAAO,WAClC,MAAM,QAAQ,WAAW;CAE7B,GAAG,CAAC,mBAAmB,CAAC;CAExB,MAAM,qBAAqB;EACzB,MAAM,MAAM,OAAO;EACnB,IAAI,CAAC,KAAK;EAEV,MAAM,aAAa,oBAAoB,SAAS,EAAE;EAClD,MAAM,gBACJ,KAAK,IAAI,IAAI,eAAe,IAAI,YAAY,IAAI,YAAY,KAAK,KACjE,IAAI,gBAAgB,IAAI;EAI1B,IADE,CAAC,iBAAiB,cAAc,UAAU,IAAI,WAClB,CAG9B,OAAO;GACL,IAAI;QAGwB,IAAI,eAAe,IAAI,eAAe,GAE9D,6BAA6B,UAAU;GAAA,OAEpC,IACL,cAAc,UAAU,IAAI,aAC5B,iBAAiB,YAAY,IAAI,cAGjC,6BAA6B,UAAU;GAMzC,KAFE,iBAAiB,6BAA6B,YAAY,SAExC,kBAAkB,YACpC,cAAc,mBAAmB,EAAE,SAAS,EAC1C,YAAY,cACd,CAAC;EAEL;EAEA,cAAc,UAAU,IAAI;EAC5B,iBAAiB,UAAU,IAAI;CACjC;CAEA,MAAM,YAAY,yBAAyB;EACzC,MAAM,MAAM,OAAO;EACnB,IAAI,CAAC,KAAK;EAEV,MAAM,EAAE,cAAc,iBAAiB;EACvC,IACE,iBAAiB,yBAAyB,WAC1C,iBAAiB,yBAAyB,SAE1C;EAEF,yBAAyB,UAAU;EACnC,yBAAyB,UAAU;EAEnC,MAAM,iBAAiB,6BAA6B;EACpD,IAAI,kBAAkB,mBAAmB,GAEvC,6BAA6B,UAAU;OAClC,IAAI,gBACT,eAAe,cAAc;OACxB,IAAI,cAAc,oBAAoB,SAAS,EAAE,YACtD,eAAe,SAAS;EAG1B,aAAa;CACf,CAAC;CAED,MAAM,YAAY,eAA4B,OAAO;EACnD,GAAG,iBAAiB,UAAU,YAAY;EAC1C,aAAa;GACX,GAAG,oBAAoB,UAAU,YAAY;EAC/C;CACF,CAAC;CAED,sBAAsB;EACpB,IAAI,CAAC,4BAA4B;EACjC,IAAI,CAAC,aAAa;GAChB,6BAA6B,UAAU;GACvC;EACF;EACA,IAAI,6BAA6B,SAAS;EAE1C,6BAA6B,UAAU;EAGvC,IAAI,6BAA6B,YAAY,MAAM;EACnD,uBAAuB,SAAS;CAClC,GAAG;EAAC;EAAa;EAAwB;CAA0B,CAAC;CAEpE,qBAAqB,EAAE,eAAe;EACpC,eAAe,QAAQ;CACzB,CAAC;CAED,YAAY,yBAAyB;EACnC,IAAI,CAAC,0BAA0B;EAC/B,IAAI,oBAAoB,SAAS,EAAE,eAAe,OAAO;EACzD,uBAAuB,MAAM;CAC/B,CAAC;CAED,YAAY,mCAAmC;EAC7C,IAAI,CAAC,8BAA8B;EACnC,uBAAuB,SAAS;CAClC,CAAC;CAGD,OADsB,gBAA0B,WAAW,WAAW,MACnD;AACrB"}
@@ -1 +1 @@
1
- {"version":3,"file":"useMentionAdapter.js","names":[],"sources":["../../src/unstable/useMentionAdapter.ts"],"sourcesContent":["\"use client\";\n\nimport { useMemo, type FC } from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport type {\n Unstable_DirectiveFormatter,\n Unstable_TriggerAdapter,\n Unstable_TriggerCategory,\n Unstable_TriggerItem,\n} from \"@assistant-ui/core\";\nimport { unstable_defaultDirectiveFormatter } from \"@assistant-ui/core\";\nimport type { ReadonlyJSONObject } from \"assistant-stream/utils\";\n\n/** Icon component shape consumed by `ComposerTriggerPopover`'s `iconMap`. */\nexport type Unstable_IconComponent = FC<{ className?: string }>;\n\nexport type Unstable_Mention = {\n readonly id: string;\n readonly type: string;\n readonly label: string;\n readonly description?: string | undefined;\n /** Shortcut for `metadata.icon`; merged with `metadata` if both are given. */\n readonly icon?: string | undefined;\n readonly metadata?: ReadonlyJSONObject | undefined;\n};\n\nexport type Unstable_MentionCategory = {\n readonly id: string;\n readonly label: string;\n readonly items: readonly Unstable_Mention[];\n};\n\nexport type Unstable_ModelContextToolsOptions = {\n /** Wrap tools in a dedicated category (drill-down mode). */\n readonly category?: { readonly id: string; readonly label: string };\n /** Format tool name for display. */\n readonly formatLabel?: (toolName: string) => string;\n /** Default icon key for each tool. */\n readonly icon?: string;\n};\n\nexport type Unstable_UseMentionAdapterOptions = {\n /** Flat mention list. Ignored when `categories` is set. */\n readonly items?: readonly Unstable_Mention[];\n /** Categorized mentions for drill-down navigation. */\n readonly categories?: readonly Unstable_MentionCategory[];\n /**\n * How tools registered via `useAssistantTool` integrate.\n * - `false`: exclude.\n * - `true`: include (default when no `items`/`categories`; as a category\n * if `categories` is set, flat otherwise).\n * - object: explicit config.\n *\n * Omitted → defaults to `true` iff neither `items` nor `categories`.\n */\n readonly includeModelContextTools?:\n | boolean\n | Unstable_ModelContextToolsOptions;\n /** Directive formatter. @default unstable_defaultDirectiveFormatter */\n readonly formatter?: Unstable_DirectiveFormatter;\n /** Fires after an item is inserted into the composer. */\n readonly onInserted?: (item: Unstable_TriggerItem) => void;\n /** Maps `metadata.icon` / `category.id` string keys to React components. */\n readonly iconMap?: Record<string, Unstable_IconComponent>;\n /** Fallback icon when no entry in `iconMap` matches. */\n readonly fallbackIcon?: Unstable_IconComponent;\n};\n\nexport type Unstable_MentionDirective = {\n readonly formatter: Unstable_DirectiveFormatter;\n readonly onInserted?: ((item: Unstable_TriggerItem) => void) | undefined;\n};\n\n/**\n * @deprecated Under active development and might change without notice.\n *\n * Creates a spreadable `{ adapter, directive }` bundle for `@` mentions.\n * Supports tools registered via `useAssistantTool`, explicit items, or both —\n * flat or categorized.\n *\n * @example\n * ```tsx\n * const mention = unstable_useMentionAdapter();\n * <ComposerTriggerPopover char=\"@\" {...mention} />\n * ```\n */\nexport function unstable_useMentionAdapter(\n options?: Unstable_UseMentionAdapterOptions,\n): {\n adapter: Unstable_TriggerAdapter;\n directive: Unstable_MentionDirective;\n iconMap?: Record<string, Unstable_IconComponent>;\n fallbackIcon?: Unstable_IconComponent;\n} {\n // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage\n const aui = useAui();\n\n const items = options?.items;\n const categories = options?.categories;\n const includeTools =\n options?.includeModelContextTools ?? (!items && !categories);\n const toolsConfig =\n typeof includeTools === \"object\" ? includeTools : undefined;\n const wantsTools = includeTools !== false;\n const formatter = options?.formatter;\n const onInserted = options?.onInserted;\n\n // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage\n const adapter = useMemo<Unstable_TriggerAdapter>(() => {\n const getModelContextTools = (): Unstable_TriggerItem[] => {\n if (!wantsTools) return [];\n const ctx = aui.thread().getModelContext();\n const tools = ctx.tools;\n if (!tools) return [];\n const formatLabel = toolsConfig?.formatLabel;\n const defaultIcon = toolsConfig?.icon;\n return Object.entries(tools).map(([name, tool]) =>\n toTriggerItem({\n id: name,\n type: \"tool\",\n label: formatLabel ? formatLabel(name) : name,\n description: tool.description ?? undefined,\n icon: defaultIcon,\n }),\n );\n };\n\n // Categorized: drill-down mode\n if (categories && categories.length > 0) {\n const groups = categories.map((cat) => ({\n id: cat.id,\n label: cat.label,\n items: cat.items.map(toTriggerItem),\n }));\n\n let toolCategory: {\n id: string;\n label: string;\n items: Unstable_TriggerItem[];\n } | null = null;\n if (wantsTools) {\n const toolItems = getModelContextTools();\n if (toolItems.length > 0) {\n toolCategory = {\n id: toolsConfig?.category?.id ?? \"tools\",\n label: toolsConfig?.category?.label ?? \"Tools\",\n items: toolItems,\n };\n }\n }\n const allGroups = toolCategory ? [...groups, toolCategory] : groups;\n\n return {\n categories: () => allGroups.map(({ id, label }) => ({ id, label })),\n categoryItems: (id) => allGroups.find((g) => g.id === id)?.items ?? [],\n search: (query) => {\n const lower = query.toLowerCase();\n return allGroups\n .flatMap((g) => g.items)\n .filter((item) => matchesQuery(item, lower));\n },\n };\n }\n\n // Flat: items + (optionally) tools, all in one search pool\n const flatItems = (items ?? []).map(toTriggerItem);\n const getFlatPool = (): Unstable_TriggerItem[] => {\n if (!wantsTools) return flatItems;\n const toolItems = getModelContextTools();\n // Dedupe by id — explicit items win.\n const seen = new Set(flatItems.map((i) => i.id));\n return [...flatItems, ...toolItems.filter((t) => !seen.has(t.id))];\n };\n\n return {\n categories: (): readonly Unstable_TriggerCategory[] => [],\n categoryItems: () => [],\n search: (query) => {\n const lower = query.toLowerCase();\n return getFlatPool().filter((item) => matchesQuery(item, lower));\n },\n };\n }, [aui, items, categories, wantsTools, toolsConfig]);\n\n // biome-ignore lint/correctness/useHookAtTopLevel: `unstable_` prefix not recognized as hook\n const directive = useMemo<Unstable_MentionDirective>(\n () => ({\n formatter: formatter ?? unstable_defaultDirectiveFormatter,\n ...(onInserted ? { onInserted } : {}),\n }),\n [formatter, onInserted],\n );\n\n return {\n adapter,\n directive,\n ...(options?.iconMap ? { iconMap: options.iconMap } : {}),\n ...(options?.fallbackIcon ? { fallbackIcon: options.fallbackIcon } : {}),\n };\n}\n\nfunction toTriggerItem(m: Unstable_Mention): Unstable_TriggerItem {\n const metadata =\n m.icon !== undefined ? { ...(m.metadata ?? {}), icon: m.icon } : m.metadata;\n return {\n id: m.id,\n type: m.type,\n label: m.label,\n ...(m.description !== undefined ? { description: m.description } : {}),\n ...(metadata !== undefined ? { metadata } : {}),\n };\n}\n\nfunction matchesQuery(item: Unstable_TriggerItem, lower: string): boolean {\n if (!lower) return true;\n if (item.id.toLowerCase().includes(lower)) return true;\n if (item.label.toLowerCase().includes(lower)) return true;\n if (item.description?.toLowerCase().includes(lower)) return true;\n return false;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useMentionAdapter.js","names":[],"sources":["../../src/unstable/useMentionAdapter.ts"],"sourcesContent":["\"use client\";\n\nimport { useMemo, type FC } from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport type {\n Unstable_DirectiveFormatter,\n Unstable_TriggerAdapter,\n Unstable_TriggerCategory,\n Unstable_TriggerItem,\n} from \"@assistant-ui/core\";\nimport { unstable_defaultDirectiveFormatter } from \"@assistant-ui/core\";\nimport type { ReadonlyJSONObject } from \"assistant-stream/utils\";\n\n/** Icon component shape consumed by `ComposerTriggerPopover`'s `iconMap`. */\nexport type Unstable_IconComponent = FC<{ className?: string }>;\n\nexport type Unstable_Mention = {\n readonly id: string;\n readonly type: string;\n readonly label: string;\n readonly description?: string | undefined;\n /** Shortcut for `metadata.icon`; merged with `metadata` if both are given. */\n readonly icon?: string | undefined;\n readonly metadata?: ReadonlyJSONObject | undefined;\n};\n\nexport type Unstable_MentionCategory = {\n readonly id: string;\n readonly label: string;\n readonly items: readonly Unstable_Mention[];\n};\n\nexport type Unstable_ModelContextToolsOptions = {\n /** Wrap tools in a dedicated category (drill-down mode). */\n readonly category?: { readonly id: string; readonly label: string };\n /** Format tool name for display. */\n readonly formatLabel?: (toolName: string) => string;\n /** Default icon key for each tool. */\n readonly icon?: string;\n};\n\nexport type Unstable_UseMentionAdapterOptions = {\n /** Flat mention list. Ignored when `categories` is set. */\n readonly items?: readonly Unstable_Mention[];\n /** Categorized mentions for drill-down navigation. */\n readonly categories?: readonly Unstable_MentionCategory[];\n /**\n * How tools registered via `useAssistantTool` integrate.\n * - `false`: exclude.\n * - `true`: include (default when no `items`/`categories`; as a category\n * if `categories` is set, flat otherwise).\n * - object: explicit config.\n *\n * Omitted → defaults to `true` iff neither `items` nor `categories`.\n */\n readonly includeModelContextTools?:\n | boolean\n | Unstable_ModelContextToolsOptions;\n /** Directive formatter. @default unstable_defaultDirectiveFormatter */\n readonly formatter?: Unstable_DirectiveFormatter;\n /** Fires after an item is inserted into the composer. */\n readonly onInserted?: (item: Unstable_TriggerItem) => void;\n /** Maps `metadata.icon` / `category.id` string keys to React components. */\n readonly iconMap?: Record<string, Unstable_IconComponent>;\n /** Fallback icon when no entry in `iconMap` matches. */\n readonly fallbackIcon?: Unstable_IconComponent;\n};\n\nexport type Unstable_MentionDirective = {\n readonly formatter: Unstable_DirectiveFormatter;\n readonly onInserted?: ((item: Unstable_TriggerItem) => void) | undefined;\n};\n\n/**\n * @deprecated Under active development and might change without notice.\n *\n * Creates a spreadable `{ adapter, directive }` bundle for `@` mentions.\n * Supports tools registered via `useAssistantTool`, explicit items, or both —\n * flat or categorized.\n *\n * @example\n * ```tsx\n * const mention = unstable_useMentionAdapter();\n * <ComposerTriggerPopover char=\"@\" {...mention} />\n * ```\n */\nexport function unstable_useMentionAdapter(\n options?: Unstable_UseMentionAdapterOptions,\n): {\n adapter: Unstable_TriggerAdapter;\n directive: Unstable_MentionDirective;\n iconMap?: Record<string, Unstable_IconComponent>;\n fallbackIcon?: Unstable_IconComponent;\n} {\n const aui = useAui();\n\n const items = options?.items;\n const categories = options?.categories;\n const includeTools =\n options?.includeModelContextTools ?? (!items && !categories);\n const toolsConfig =\n typeof includeTools === \"object\" ? includeTools : undefined;\n const wantsTools = includeTools !== false;\n const formatter = options?.formatter;\n const onInserted = options?.onInserted;\n\n const adapter = useMemo<Unstable_TriggerAdapter>(() => {\n const getModelContextTools = (): Unstable_TriggerItem[] => {\n if (!wantsTools) return [];\n const ctx = aui.thread().getModelContext();\n const tools = ctx.tools;\n if (!tools) return [];\n const formatLabel = toolsConfig?.formatLabel;\n const defaultIcon = toolsConfig?.icon;\n return Object.entries(tools).map(([name, tool]) =>\n toTriggerItem({\n id: name,\n type: \"tool\",\n label: formatLabel ? formatLabel(name) : name,\n description: tool.description ?? undefined,\n icon: defaultIcon,\n }),\n );\n };\n\n // Categorized: drill-down mode\n if (categories && categories.length > 0) {\n const groups = categories.map((cat) => ({\n id: cat.id,\n label: cat.label,\n items: cat.items.map(toTriggerItem),\n }));\n\n let toolCategory: {\n id: string;\n label: string;\n items: Unstable_TriggerItem[];\n } | null = null;\n if (wantsTools) {\n const toolItems = getModelContextTools();\n if (toolItems.length > 0) {\n toolCategory = {\n id: toolsConfig?.category?.id ?? \"tools\",\n label: toolsConfig?.category?.label ?? \"Tools\",\n items: toolItems,\n };\n }\n }\n const allGroups = toolCategory ? [...groups, toolCategory] : groups;\n\n return {\n categories: () => allGroups.map(({ id, label }) => ({ id, label })),\n categoryItems: (id) => allGroups.find((g) => g.id === id)?.items ?? [],\n search: (query) => {\n const lower = query.toLowerCase();\n return allGroups\n .flatMap((g) => g.items)\n .filter((item) => matchesQuery(item, lower));\n },\n };\n }\n\n // Flat: items + (optionally) tools, all in one search pool\n const flatItems = (items ?? []).map(toTriggerItem);\n const getFlatPool = (): Unstable_TriggerItem[] => {\n if (!wantsTools) return flatItems;\n const toolItems = getModelContextTools();\n // Dedupe by id — explicit items win.\n const seen = new Set(flatItems.map((i) => i.id));\n return [...flatItems, ...toolItems.filter((t) => !seen.has(t.id))];\n };\n\n return {\n categories: (): readonly Unstable_TriggerCategory[] => [],\n categoryItems: () => [],\n search: (query) => {\n const lower = query.toLowerCase();\n return getFlatPool().filter((item) => matchesQuery(item, lower));\n },\n };\n }, [aui, items, categories, wantsTools, toolsConfig]);\n\n const directive = useMemo<Unstable_MentionDirective>(\n () => ({\n formatter: formatter ?? unstable_defaultDirectiveFormatter,\n ...(onInserted ? { onInserted } : {}),\n }),\n [formatter, onInserted],\n );\n\n return {\n adapter,\n directive,\n ...(options?.iconMap ? { iconMap: options.iconMap } : {}),\n ...(options?.fallbackIcon ? { fallbackIcon: options.fallbackIcon } : {}),\n };\n}\n\nfunction toTriggerItem(m: Unstable_Mention): Unstable_TriggerItem {\n const metadata =\n m.icon !== undefined ? { ...(m.metadata ?? {}), icon: m.icon } : m.metadata;\n return {\n id: m.id,\n type: m.type,\n label: m.label,\n ...(m.description !== undefined ? { description: m.description } : {}),\n ...(metadata !== undefined ? { metadata } : {}),\n };\n}\n\nfunction matchesQuery(item: Unstable_TriggerItem, lower: string): boolean {\n if (!lower) return true;\n if (item.id.toLowerCase().includes(lower)) return true;\n if (item.label.toLowerCase().includes(lower)) return true;\n if (item.description?.toLowerCase().includes(lower)) return true;\n return false;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"useSlashCommandAdapter.js","names":[],"sources":["../../src/unstable/useSlashCommandAdapter.ts"],"sourcesContent":["\"use client\";\n\nimport { useMemo, useRef } from \"react\";\nimport type {\n Unstable_TriggerAdapter,\n Unstable_TriggerItem,\n} from \"@assistant-ui/core\";\nimport type { Unstable_IconComponent } from \"./useMentionAdapter\";\n\nexport type Unstable_SlashCommand = {\n readonly id: string;\n readonly label?: string | undefined;\n readonly description?: string | undefined;\n readonly icon?: string | undefined;\n readonly execute: () => void;\n};\n\nexport type Unstable_UseSlashCommandAdapterOptions = {\n readonly commands: readonly Unstable_SlashCommand[];\n /** Strip the trigger text from the composer after executing. @default false */\n readonly removeOnExecute?: boolean | undefined;\n /** Maps `metadata.icon` / `category.id` string keys to React components. */\n readonly iconMap?: Record<string, Unstable_IconComponent>;\n /** Fallback icon when no entry in `iconMap` matches. */\n readonly fallbackIcon?: Unstable_IconComponent;\n};\n\nexport type Unstable_SlashCommandAction = {\n readonly onExecute: (item: Unstable_TriggerItem) => void;\n readonly removeOnExecute?: boolean | undefined;\n};\n\n/**\n * @deprecated Under active development and may change without notice.\n *\n * Bundles slash command definitions (with inline `execute` callbacks) into\n * `{adapter, action}` that plug directly into `ComposerTriggerPopover`.\n * `execute` stays in the hook closure and is never attached to the returned\n * `TriggerItem`, keeping items serializable.\n *\n * @example\n * ```tsx\n * const slash = unstable_useSlashCommandAdapter({\n * commands: [\n * { id: \"summarize\", execute: () => runSummarize(), icon: \"FileText\" },\n * { id: \"translate\", execute: () => runTranslate(), icon: \"Languages\" },\n * ],\n * });\n *\n * <ComposerTriggerPopover char=\"/\" {...slash} />\n * ```\n */\nexport function unstable_useSlashCommandAdapter(\n options: Unstable_UseSlashCommandAdapterOptions,\n): {\n adapter: Unstable_TriggerAdapter;\n action: Unstable_SlashCommandAction;\n iconMap?: Record<string, Unstable_IconComponent>;\n fallbackIcon?: Unstable_IconComponent;\n} {\n const { commands, removeOnExecute } = options;\n\n // biome-ignore lint/correctness/useHookAtTopLevel: `unstable_` prefix not recognized as hook\n const commandsRef = useRef(commands);\n commandsRef.current = commands;\n\n // biome-ignore lint/correctness/useHookAtTopLevel: `unstable_` prefix not recognized as hook\n return useMemo(() => {\n const adapter: Unstable_TriggerAdapter = {\n categories: () => [],\n categoryItems: () => [],\n search: (query: string) => {\n const lower = query.toLowerCase();\n return commandsRef.current\n .filter((c) => matchesQuery(c, lower))\n .map(toItem);\n },\n };\n\n const action: Unstable_SlashCommandAction = {\n onExecute: (item) => {\n commandsRef.current.find((c) => c.id === item.id)?.execute();\n },\n ...(removeOnExecute !== undefined ? { removeOnExecute } : {}),\n };\n\n return {\n adapter,\n action,\n ...(options.iconMap ? { iconMap: options.iconMap } : {}),\n ...(options.fallbackIcon ? { fallbackIcon: options.fallbackIcon } : {}),\n };\n }, [removeOnExecute, options.iconMap, options.fallbackIcon]);\n}\n\nfunction toItem(cmd: Unstable_SlashCommand): Unstable_TriggerItem {\n return {\n id: cmd.id,\n type: \"command\",\n label: cmd.label ?? `/${cmd.id}`,\n ...(cmd.description !== undefined ? { description: cmd.description } : {}),\n ...(cmd.icon !== undefined ? { metadata: { icon: cmd.icon } } : {}),\n };\n}\n\nfunction matchesQuery(cmd: Unstable_SlashCommand, lower: string): boolean {\n if (!lower) return true;\n if (cmd.id.toLowerCase().includes(lower)) return true;\n if (cmd.label?.toLowerCase().includes(lower)) return true;\n if (cmd.description?.toLowerCase().includes(lower)) return true;\n return false;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAoDA,SAAgB,gCACd,SAMA;CACA,MAAM,EAAE,UAAU,oBAAoB;CAGtC,MAAM,cAAc,OAAO,QAAQ;CACnC,YAAY,UAAU;CAGtB,OAAO,cAAc;EAmBnB,OAAO;GACL,SAAA;IAlBA,kBAAkB,CAAC;IACnB,qBAAqB,CAAC;IACtB,SAAS,UAAkB;KACzB,MAAM,QAAQ,MAAM,YAAY;KAChC,OAAO,YAAY,QAChB,QAAQ,MAAM,aAAa,GAAG,KAAK,CAAC,EACpC,IAAI,MAAM;IACf;GAWM;GACN,QAAA;IARA,YAAY,SAAS;KACnB,YAAY,QAAQ,MAAM,MAAM,EAAE,OAAO,KAAK,EAAE,GAAG,QAAQ;IAC7D;IACA,GAAI,oBAAoB,KAAA,IAAY,EAAE,gBAAgB,IAAI,CAAC;GAKtD;GACL,GAAI,QAAQ,UAAU,EAAE,SAAS,QAAQ,QAAQ,IAAI,CAAC;GACtD,GAAI,QAAQ,eAAe,EAAE,cAAc,QAAQ,aAAa,IAAI,CAAC;EACvE;CACF,GAAG;EAAC;EAAiB,QAAQ;EAAS,QAAQ;CAAY,CAAC;AAC7D;AAEA,SAAS,OAAO,KAAkD;CAChE,OAAO;EACL,IAAI,IAAI;EACR,MAAM;EACN,OAAO,IAAI,SAAS,IAAI,IAAI;EAC5B,GAAI,IAAI,gBAAgB,KAAA,IAAY,EAAE,aAAa,IAAI,YAAY,IAAI,CAAC;EACxE,GAAI,IAAI,SAAS,KAAA,IAAY,EAAE,UAAU,EAAE,MAAM,IAAI,KAAK,EAAE,IAAI,CAAC;CACnE;AACF;AAEA,SAAS,aAAa,KAA4B,OAAwB;CACxE,IAAI,CAAC,OAAO,OAAO;CACnB,IAAI,IAAI,GAAG,YAAY,EAAE,SAAS,KAAK,GAAG,OAAO;CACjD,IAAI,IAAI,OAAO,YAAY,EAAE,SAAS,KAAK,GAAG,OAAO;CACrD,IAAI,IAAI,aAAa,YAAY,EAAE,SAAS,KAAK,GAAG,OAAO;CAC3D,OAAO;AACT"}
1
+ {"version":3,"file":"useSlashCommandAdapter.js","names":[],"sources":["../../src/unstable/useSlashCommandAdapter.ts"],"sourcesContent":["\"use client\";\n\nimport { useMemo, useRef } from \"react\";\nimport type {\n Unstable_TriggerAdapter,\n Unstable_TriggerItem,\n} from \"@assistant-ui/core\";\nimport type { Unstable_IconComponent } from \"./useMentionAdapter\";\n\nexport type Unstable_SlashCommand = {\n readonly id: string;\n readonly label?: string | undefined;\n readonly description?: string | undefined;\n readonly icon?: string | undefined;\n readonly execute: () => void;\n};\n\nexport type Unstable_UseSlashCommandAdapterOptions = {\n readonly commands: readonly Unstable_SlashCommand[];\n /** Strip the trigger text from the composer after executing. @default false */\n readonly removeOnExecute?: boolean | undefined;\n /** Maps `metadata.icon` / `category.id` string keys to React components. */\n readonly iconMap?: Record<string, Unstable_IconComponent>;\n /** Fallback icon when no entry in `iconMap` matches. */\n readonly fallbackIcon?: Unstable_IconComponent;\n};\n\nexport type Unstable_SlashCommandAction = {\n readonly onExecute: (item: Unstable_TriggerItem) => void;\n readonly removeOnExecute?: boolean | undefined;\n};\n\n/**\n * @deprecated Under active development and may change without notice.\n *\n * Bundles slash command definitions (with inline `execute` callbacks) into\n * `{adapter, action}` that plug directly into `ComposerTriggerPopover`.\n * `execute` stays in the hook closure and is never attached to the returned\n * `TriggerItem`, keeping items serializable.\n *\n * @example\n * ```tsx\n * const slash = unstable_useSlashCommandAdapter({\n * commands: [\n * { id: \"summarize\", execute: () => runSummarize(), icon: \"FileText\" },\n * { id: \"translate\", execute: () => runTranslate(), icon: \"Languages\" },\n * ],\n * });\n *\n * <ComposerTriggerPopover char=\"/\" {...slash} />\n * ```\n */\nexport function unstable_useSlashCommandAdapter(\n options: Unstable_UseSlashCommandAdapterOptions,\n): {\n adapter: Unstable_TriggerAdapter;\n action: Unstable_SlashCommandAction;\n iconMap?: Record<string, Unstable_IconComponent>;\n fallbackIcon?: Unstable_IconComponent;\n} {\n const { commands, removeOnExecute } = options;\n\n const commandsRef = useRef(commands);\n commandsRef.current = commands;\n\n return useMemo(() => {\n const adapter: Unstable_TriggerAdapter = {\n categories: () => [],\n categoryItems: () => [],\n search: (query: string) => {\n const lower = query.toLowerCase();\n return commandsRef.current\n .filter((c) => matchesQuery(c, lower))\n .map(toItem);\n },\n };\n\n const action: Unstable_SlashCommandAction = {\n onExecute: (item) => {\n commandsRef.current.find((c) => c.id === item.id)?.execute();\n },\n ...(removeOnExecute !== undefined ? { removeOnExecute } : {}),\n };\n\n return {\n adapter,\n action,\n ...(options.iconMap ? { iconMap: options.iconMap } : {}),\n ...(options.fallbackIcon ? { fallbackIcon: options.fallbackIcon } : {}),\n };\n }, [removeOnExecute, options.iconMap, options.fallbackIcon]);\n}\n\nfunction toItem(cmd: Unstable_SlashCommand): Unstable_TriggerItem {\n return {\n id: cmd.id,\n type: \"command\",\n label: cmd.label ?? `/${cmd.id}`,\n ...(cmd.description !== undefined ? { description: cmd.description } : {}),\n ...(cmd.icon !== undefined ? { metadata: { icon: cmd.icon } } : {}),\n };\n}\n\nfunction matchesQuery(cmd: Unstable_SlashCommand, lower: string): boolean {\n if (!lower) return true;\n if (cmd.id.toLowerCase().includes(lower)) return true;\n if (cmd.label?.toLowerCase().includes(lower)) return true;\n if (cmd.description?.toLowerCase().includes(lower)) return true;\n return false;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAoDA,SAAgB,gCACd,SAMA;CACA,MAAM,EAAE,UAAU,oBAAoB;CAEtC,MAAM,cAAc,OAAO,QAAQ;CACnC,YAAY,UAAU;CAEtB,OAAO,cAAc;EAmBnB,OAAO;GACL,SAAA;IAlBA,kBAAkB,CAAC;IACnB,qBAAqB,CAAC;IACtB,SAAS,UAAkB;KACzB,MAAM,QAAQ,MAAM,YAAY;KAChC,OAAO,YAAY,QAChB,QAAQ,MAAM,aAAa,GAAG,KAAK,CAAC,EACpC,IAAI,MAAM;IACf;GAWM;GACN,QAAA;IARA,YAAY,SAAS;KACnB,YAAY,QAAQ,MAAM,MAAM,EAAE,OAAO,KAAK,EAAE,GAAG,QAAQ;IAC7D;IACA,GAAI,oBAAoB,KAAA,IAAY,EAAE,gBAAgB,IAAI,CAAC;GAKtD;GACL,GAAI,QAAQ,UAAU,EAAE,SAAS,QAAQ,QAAQ,IAAI,CAAC;GACtD,GAAI,QAAQ,eAAe,EAAE,cAAc,QAAQ,aAAa,IAAI,CAAC;EACvE;CACF,GAAG;EAAC;EAAiB,QAAQ;EAAS,QAAQ;CAAY,CAAC;AAC7D;AAEA,SAAS,OAAO,KAAkD;CAChE,OAAO;EACL,IAAI,IAAI;EACR,MAAM;EACN,OAAO,IAAI,SAAS,IAAI,IAAI;EAC5B,GAAI,IAAI,gBAAgB,KAAA,IAAY,EAAE,aAAa,IAAI,YAAY,IAAI,CAAC;EACxE,GAAI,IAAI,SAAS,KAAA,IAAY,EAAE,UAAU,EAAE,MAAM,IAAI,KAAK,EAAE,IAAI,CAAC;CACnE;AACF;AAEA,SAAS,aAAa,KAA4B,OAAwB;CACxE,IAAI,CAAC,OAAO,OAAO;CACnB,IAAI,IAAI,GAAG,YAAY,EAAE,SAAS,KAAK,GAAG,OAAO;CACjD,IAAI,IAAI,OAAO,YAAY,EAAE,SAAS,KAAK,GAAG,OAAO;CACrD,IAAI,IAAI,aAAa,YAAY,EAAE,SAAS,KAAK,GAAG,OAAO;CAC3D,OAAO;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"Primitive.d.ts","names":[],"sources":["../../src/utils/Primitive.tsx"],"mappings":";;;;;;AAawE;;;;AA+B9D;AAAA;;cAlBJ,KAAA;AAAA,KAmBD,aAAA,WAAwB,KAAK;AAAA,KAE7B,mBAAA,WAA8B,WAAA,IACjC,wBAAA,CAAyB,CAAA;EACvB,MAAA,GAAS,YAAA;AAAA;AAAA,KAGR,cAAA,WAAyB,aAAA,IAAiB,mBAAA,SACrC,WAAA,EAAgB,CAAA;AAAA,iBAajB,cAAA,WAAyB,WAAA,CAAA,CAAa,SAAA,EAAW,CAAA,GAwCtC,yBAAA,CAChB,mBAAA,CAAoB,CAAA,IAAK,aAAA,CAAc,YAAA,CAAa,CAAA;AAAA,cAclD,SAAA;;;;aAxEO,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA"}
1
+ {"version":3,"file":"Primitive.d.ts","names":[],"sources":["../../src/utils/Primitive.tsx"],"mappings":";;;;;;AAawE;;;;AA+B9D;AAAA;;cAlBJ,KAAA;AAAA,KAmBD,aAAA,WAAwB,KAAK;AAAA,KAE7B,mBAAA,WAA8B,WAAA,IACjC,wBAAA,CAAyB,CAAA;EACvB,MAAA,GAAS,YAAA;AAAA;AAAA,KAGR,cAAA,WAAyB,aAAA,IAAiB,mBAAA,SACrC,WAAA,EAAgB,CAAA;AAAA,iBAajB,cAAA,WAAyB,WAAA,EAAa,SAAA,EAAW,CAAA,GAwCtC,yBAAA,CAChB,mBAAA,CAAoB,CAAA,IAAK,aAAA,CAAc,YAAA,CAAa,CAAA;AAAA,cAclD,SAAA;;;;aAxEO,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA;;;;aAAA,YAAA;EAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/react",
3
- "version": "0.14.11",
3
+ "version": "0.14.12",
4
4
  "description": "Open-source TypeScript/React library for building production-grade AI chat experiences",
5
5
  "keywords": [
6
6
  "radix-ui",
@@ -48,23 +48,23 @@
48
48
  ],
49
49
  "sideEffects": false,
50
50
  "dependencies": {
51
- "@assistant-ui/core": "^0.2.7",
52
- "@assistant-ui/store": "^0.2.12",
53
- "@assistant-ui/tap": "^0.5.13",
51
+ "@assistant-ui/core": "^0.2.8",
52
+ "@assistant-ui/store": "^0.2.13",
53
+ "@assistant-ui/tap": "^0.5.14",
54
54
  "@radix-ui/primitive": "^1.1.3",
55
55
  "@radix-ui/react-compose-refs": "^1.1.2",
56
56
  "@radix-ui/react-context": "^1.1.3",
57
57
  "@radix-ui/react-primitive": "^2.1.4",
58
58
  "@radix-ui/react-use-callback-ref": "^1.1.1",
59
59
  "@radix-ui/react-use-escape-keydown": "^1.1.1",
60
- "assistant-cloud": "^0.1.29",
61
- "assistant-stream": "^0.3.17",
60
+ "assistant-cloud": "^0.1.30",
61
+ "assistant-stream": "^0.3.18",
62
62
  "nanoid": "^5.1.11",
63
63
  "radix-ui": "^1.4.3",
64
64
  "react-textarea-autosize": "^8.5.9",
65
65
  "safe-content-frame": "^0.0.20",
66
66
  "zod": "^4.4.3",
67
- "zustand": "^5.0.13"
67
+ "zustand": "^5.0.14"
68
68
  },
69
69
  "peerDependencies": {
70
70
  "@types/react": "*",
@@ -90,7 +90,7 @@
90
90
  "react": "^19.2.6",
91
91
  "react-dom": "^19.2.6",
92
92
  "vitest": "^4.1.7",
93
- "@assistant-ui/x-buildutils": "0.0.9"
93
+ "@assistant-ui/x-buildutils": "0.0.10"
94
94
  },
95
95
  "publishConfig": {
96
96
  "access": "public",
@@ -22,10 +22,8 @@
22
22
  * ```
23
23
  */
24
24
  export namespace Assistant {
25
- // biome-ignore lint/suspicious/noEmptyInterface: declaration merging
26
25
  export interface Commands {}
27
26
 
28
- // biome-ignore lint/suspicious/noEmptyInterface: declaration merging
29
27
  export interface ExternalState {}
30
28
  }
31
29
 
@@ -75,7 +75,6 @@ export function createStateHookForRuntime<TState>(
75
75
  if (!store) return null;
76
76
 
77
77
  // it is ok to call useRuntimeStateInternal conditionally because it will never become null if its available
78
- // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
79
78
  return useRuntimeStateInternal(store, selector);
80
79
  }
81
80
 
@@ -54,7 +54,6 @@ const getHook = (): DevToolsHook => {
54
54
  return newHook;
55
55
  };
56
56
 
57
- // biome-ignore lint/complexity/noStaticOnlyClass: intentional namespace for DevTools API
58
57
  export class DevToolsHooks {
59
58
  static subscribe(listener: () => void): Unsubscribe {
60
59
  const hook = getHook();
@@ -79,12 +78,10 @@ export class DevToolsHooks {
79
78
 
80
79
  private static notifyListeners(apiId: number): void {
81
80
  const hook = getHook();
82
- // biome-ignore lint/suspicious/useIterableCallbackReturn: forEach callback intentionally has no return
83
81
  hook.listeners.forEach((listener) => listener(apiId));
84
82
  }
85
83
  }
86
84
 
87
- // biome-ignore lint/complexity/noStaticOnlyClass: intentional namespace for DevTools API
88
85
  export class DevToolsProviderApi {
89
86
  private static readonly MAX_EVENT_LOGS_PER_API = 200;
90
87
 
@@ -145,7 +142,6 @@ export class DevToolsProviderApi {
145
142
 
146
143
  private static notifyListeners(apiId: number): void {
147
144
  const hook = getHook();
148
- // biome-ignore lint/suspicious/useIterableCallbackReturn: forEach callback intentionally has no return
149
145
  hook.listeners.forEach((listener) => listener(apiId));
150
146
  }
151
147
  }
package/src/index.ts CHANGED
@@ -127,14 +127,17 @@ export type { ThreadMessageLike } from "@assistant-ui/core";
127
127
  export {
128
128
  getExternalStoreMessages,
129
129
  bindExternalStoreMessage,
130
+ pickExternalStoreSharedOptions,
130
131
  } from "@assistant-ui/core";
131
132
  export type {
132
133
  ExternalStoreAdapter,
133
134
  ExternalStoreMessageConverter,
135
+ ExternalStoreSharedOptions,
134
136
  ExternalStoreThreadListAdapter,
135
137
  ExternalStoreThreadData,
136
138
  } from "@assistant-ui/core";
137
139
  export { useExternalStoreRuntime } from "./legacy-runtime/runtime-cores/external-store/useExternalStoreRuntime";
140
+ export { useExternalStoreSharedOptions } from "@assistant-ui/core/react";
138
141
  export {
139
142
  useExternalMessageConverter,
140
143
  convertExternalMessages as unstable_convertExternalMessages,
@@ -184,6 +187,8 @@ export {
184
187
  useInlineRender,
185
188
  type Toolkit,
186
189
  type ToolDefinition,
190
+ type ToolkitDeclaration,
191
+ type ToolkitDeclarationDefinition,
187
192
  Tools,
188
193
  DataRenderers,
189
194
  Interactables,
@@ -254,7 +259,7 @@ export * as ThreadListItemPrimitive from "./primitives/threadListItem";
254
259
  export * as ThreadListItemMorePrimitive from "./primitives/threadListItemMore";
255
260
  export * as SelectionToolbarPrimitive from "./primitives/selectionToolbar";
256
261
 
257
- export { groupPartByType } from "@assistant-ui/core/react";
262
+ export { groupPartByType, type GroupByContext } from "@assistant-ui/core/react";
258
263
  export { useMessagePartText } from "./primitives/messagePart/useMessagePartText";
259
264
  export { useMessagePartReasoning } from "./primitives/messagePart/useMessagePartReasoning";
260
265
  export { useMessagePartSource } from "./primitives/messagePart/useMessagePartSource";
@@ -113,23 +113,16 @@ export function useAssistantTransportState<T>(
113
113
  const useAssistantTransportThreadRuntime = <T>(
114
114
  options: AssistantTransportOptions<T>,
115
115
  ): AssistantRuntime => {
116
- // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
117
116
  const agentStateRef = useRef(options.initialState);
118
- // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
119
117
  const [, rerender] = useState(0);
120
- // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
121
118
  const resumeFlagRef = useRef(false);
122
- // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
123
119
  const parentIdRef = useRef<string | null | undefined>(undefined);
124
- // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
125
120
  const commandQueue = useCommandQueue({
126
121
  onQueue: () => runManager.schedule(),
127
122
  });
128
123
 
129
- // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
130
124
  const threadId = useAuiState((s) => s.threadListItem.remoteId);
131
125
 
132
- // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
133
126
  const runManager = useRunManager({
134
127
  onRun: async (signal: AbortSignal) => {
135
128
  const isResume = resumeFlagRef.current;
@@ -273,18 +266,15 @@ const useAssistantTransportThreadRuntime = <T>(
273
266
  });
274
267
 
275
268
  // Tool execution status state
276
- // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
277
269
  const [toolStatuses, setToolStatuses] = useState<
278
270
  Record<string, ToolExecutionStatus>
279
271
  >({});
280
272
 
281
273
  // Reactive conversion of agent state + connection metadata → UI state
282
- // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
283
274
  const pendingCommands = useMemo(
284
275
  () => [...commandQueue.state.inTransit, ...commandQueue.state.queued],
285
276
  [commandQueue.state],
286
277
  );
287
- // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
288
278
  const converted = useConvertedState(
289
279
  options.converter,
290
280
  agentStateRef.current,
@@ -294,7 +284,6 @@ const useAssistantTransportThreadRuntime = <T>(
294
284
  );
295
285
 
296
286
  // Create runtime
297
- // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
298
287
  const runtime = useExternalStoreRuntime({
299
288
  messages: converted.messages,
300
289
  state: converted.state,
@@ -365,7 +354,6 @@ export const useAssistantTransportRuntime = <T>(
365
354
  ): AssistantRuntime => {
366
355
  const runtime = useRemoteThreadListRuntime({
367
356
  runtimeHook: function RuntimeHook() {
368
- // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
369
357
  return useAssistantTransportThreadRuntime(options);
370
358
  },
371
359
  adapter: new InMemoryThreadListAdapter(),
@@ -64,12 +64,10 @@ export const TriggerKeyboardResource = resource(
64
64
  }): TriggerKeyboardResourceOutput => {
65
65
  const [highlightedIndex, setHighlightedIndex] = tapState(0);
66
66
 
67
- // biome-ignore lint/correctness/useExhaustiveDependencies: intentional reset on list change
68
67
  tapEffect(() => {
69
68
  setHighlightedIndex(0);
70
69
  }, [navigableList]);
71
70
 
72
- // biome-ignore lint/correctness/useExhaustiveDependencies: intentional reset
73
71
  tapEffect(() => {
74
72
  setHighlightedIndex(0);
75
73
  }, [isSearchMode, activeCategoryId]);
@@ -37,7 +37,6 @@ export const MessagePartPrimitiveImage = forwardRef<
37
37
  MessagePartPrimitiveImage.Props
38
38
  >((props, forwardedRef) => {
39
39
  const { image } = useMessagePartImage();
40
- // biome-ignore lint/performance/noImgElement: next/image not applicable here
41
40
  return <Primitive.img src={image} {...props} ref={forwardedRef} />;
42
41
  });
43
42
 
@@ -59,9 +59,13 @@ export const useThreadViewportAutoScroll = <TElement extends HTMLElement>({
59
59
  }
60
60
 
61
61
  const lastScrollTop = useRef<number>(0);
62
+ const lastScrollHeight = useRef<number>(0);
63
+ const lastObservedScrollHeight = useRef<number>(0);
64
+ const lastObservedClientHeight = useRef<number>(0);
62
65
 
63
66
  // Pending bottom-scroll intent. Planted by initialize/run-start/switch/button
64
- // triggers, cleared only when handleScroll confirms we reached bottom.
67
+ // triggers, cleared when handleScroll confirms we reached bottom, or when the
68
+ // user actively scrolls up while content size is stable.
65
69
  const scrollingToBottomBehaviorRef = useRef<ScrollBehavior | null>(null);
66
70
 
67
71
  const scrollToBottom = useCallback((behavior: ScrollBehavior) => {
@@ -110,7 +114,7 @@ export const useThreadViewportAutoScroll = <TElement extends HTMLElement>({
110
114
 
111
115
  const isAtBottom = threadViewportStore.getState().isAtBottom;
112
116
  const newIsAtBottom =
113
- Math.abs(div.scrollHeight - div.scrollTop - div.clientHeight) < 1 ||
117
+ Math.abs(div.scrollHeight - div.scrollTop - div.clientHeight) <= 1 ||
114
118
  div.scrollHeight <= div.clientHeight;
115
119
 
116
120
  const isInFlightDownwardScroll =
@@ -126,6 +130,12 @@ export const useThreadViewportAutoScroll = <TElement extends HTMLElement>({
126
130
  if (viewportOverflows) {
127
131
  scrollingToBottomBehaviorRef.current = null;
128
132
  }
133
+ } else if (
134
+ lastScrollTop.current > div.scrollTop &&
135
+ lastScrollHeight.current === div.scrollHeight
136
+ ) {
137
+ // scrollHeight equality rules out content-driven shifts being misread as user scroll-up
138
+ scrollingToBottomBehaviorRef.current = null;
129
139
  }
130
140
 
131
141
  const shouldUpdate =
@@ -139,9 +149,23 @@ export const useThreadViewportAutoScroll = <TElement extends HTMLElement>({
139
149
  }
140
150
 
141
151
  lastScrollTop.current = div.scrollTop;
152
+ lastScrollHeight.current = div.scrollHeight;
142
153
  };
143
154
 
144
155
  const resizeRef = useOnResizeContent(() => {
156
+ const div = divRef.current;
157
+ if (!div) return;
158
+
159
+ const { scrollHeight, clientHeight } = div;
160
+ if (
161
+ scrollHeight === lastObservedScrollHeight.current &&
162
+ clientHeight === lastObservedClientHeight.current
163
+ ) {
164
+ return;
165
+ }
166
+ lastObservedScrollHeight.current = scrollHeight;
167
+ lastObservedClientHeight.current = clientHeight;
168
+
145
169
  const scrollBehavior = scrollingToBottomBehaviorRef.current;
146
170
  if (scrollBehavior && hasActiveTopAnchor()) {
147
171
  // Let the top-anchor reserve own scrolling while a run starts to avoid a bottom-scroll race.
@@ -255,6 +255,68 @@ describe("ExternalStoreThreadRuntimeCore", () => {
255
255
  "Runtime does not support cancelling runs.",
256
256
  );
257
257
  });
258
+
259
+ it("keeps a partially-streamed optimistic message on cancel", async () => {
260
+ // Only empty optimistic heads are evicted; one with content survives.
261
+ const optimisticAssistant = {
262
+ ...createAssistantMessage("server-msg", "partial answer"),
263
+ status: { type: "running" as const },
264
+ metadata: {
265
+ unstable_state: null,
266
+ unstable_annotations: [],
267
+ unstable_data: [],
268
+ steps: [],
269
+ custom: {},
270
+ isOptimistic: true,
271
+ },
272
+ } as ThreadMessage;
273
+ const setMessages = vi.fn();
274
+ const adapter = createBaseAdapter({
275
+ messages: [createUserMessage("u1"), optimisticAssistant],
276
+ isRunning: true,
277
+ onCancel: vi.fn(),
278
+ setMessages,
279
+ });
280
+ const core = new ExternalStoreThreadRuntimeCore(contextProvider, adapter);
281
+
282
+ core.cancelRun();
283
+
284
+ // cancelRun resyncs to the store via setTimeout(0); inspect the push.
285
+ await new Promise((resolve) => setTimeout(resolve, 0));
286
+ const lastCall = setMessages.mock.lastCall?.[0] as ThreadMessage[];
287
+ expect(lastCall.map((m) => m.id)).toContain("server-msg");
288
+ });
289
+
290
+ it("evicts an empty optimistic head on cancel", async () => {
291
+ // An empty optimistic head is dropped on cancel, falling back to its prev.
292
+ const optimisticAssistant = {
293
+ ...createAssistantMessage("server-msg", ""),
294
+ content: [],
295
+ status: { type: "running" as const },
296
+ metadata: {
297
+ unstable_state: null,
298
+ unstable_annotations: [],
299
+ unstable_data: [],
300
+ steps: [],
301
+ custom: {},
302
+ isOptimistic: true,
303
+ },
304
+ } as ThreadMessage;
305
+ const setMessages = vi.fn();
306
+ const adapter = createBaseAdapter({
307
+ messages: [createUserMessage("u1"), optimisticAssistant],
308
+ isRunning: true,
309
+ onCancel: vi.fn(),
310
+ setMessages,
311
+ });
312
+ const core = new ExternalStoreThreadRuntimeCore(contextProvider, adapter);
313
+
314
+ core.cancelRun();
315
+
316
+ await new Promise((resolve) => setTimeout(resolve, 0));
317
+ const lastCall = setMessages.mock.lastCall?.[0] as ThreadMessage[];
318
+ expect(lastCall.map((m) => m.id)).not.toContain("server-msg");
319
+ });
258
320
  });
259
321
 
260
322
  describe("optimistic assistant message", () => {
@@ -92,7 +92,6 @@ export function unstable_useMentionAdapter(
92
92
  iconMap?: Record<string, Unstable_IconComponent>;
93
93
  fallbackIcon?: Unstable_IconComponent;
94
94
  } {
95
- // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
96
95
  const aui = useAui();
97
96
 
98
97
  const items = options?.items;
@@ -105,7 +104,6 @@ export function unstable_useMentionAdapter(
105
104
  const formatter = options?.formatter;
106
105
  const onInserted = options?.onInserted;
107
106
 
108
- // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
109
107
  const adapter = useMemo<Unstable_TriggerAdapter>(() => {
110
108
  const getModelContextTools = (): Unstable_TriggerItem[] => {
111
109
  if (!wantsTools) return [];
@@ -182,7 +180,6 @@ export function unstable_useMentionAdapter(
182
180
  };
183
181
  }, [aui, items, categories, wantsTools, toolsConfig]);
184
182
 
185
- // biome-ignore lint/correctness/useHookAtTopLevel: `unstable_` prefix not recognized as hook
186
183
  const directive = useMemo<Unstable_MentionDirective>(
187
184
  () => ({
188
185
  formatter: formatter ?? unstable_defaultDirectiveFormatter,
@@ -60,11 +60,9 @@ export function unstable_useSlashCommandAdapter(
60
60
  } {
61
61
  const { commands, removeOnExecute } = options;
62
62
 
63
- // biome-ignore lint/correctness/useHookAtTopLevel: `unstable_` prefix not recognized as hook
64
63
  const commandsRef = useRef(commands);
65
64
  commandsRef.current = commands;
66
65
 
67
- // biome-ignore lint/correctness/useHookAtTopLevel: `unstable_` prefix not recognized as hook
68
66
  return useMemo(() => {
69
67
  const adapter: Unstable_TriggerAdapter = {
70
68
  categories: () => [],