@osdk/react 0.17.0-main-5dc557e9e321d23e8e150e8015c41ebe3b6f387c → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. package/AGENTS.md +19 -35
  2. package/CHANGELOG.md +8 -7
  3. package/build/browser/aip/chatStore.js +67 -0
  4. package/build/browser/aip/chatStore.js.map +1 -0
  5. package/build/browser/aip/chatStream.js +155 -0
  6. package/build/browser/aip/chatStream.js.map +1 -0
  7. package/build/browser/aip/useChat.js +243 -0
  8. package/build/browser/aip/useChat.js.map +1 -0
  9. package/build/browser/index.js +14 -1
  10. package/build/browser/index.js.map +1 -1
  11. package/build/browser/new/{OsdkContext2.js → OsdkContext.js} +4 -4
  12. package/build/browser/new/OsdkContext.js.map +1 -0
  13. package/build/browser/new/{OsdkProvider2.js → OsdkProvider.js} +7 -13
  14. package/build/browser/new/OsdkProvider.js.map +1 -0
  15. package/build/browser/new/core/useStableObjectSet.js +1 -1
  16. package/build/browser/new/core/useStableObjectSet.js.map +1 -1
  17. package/build/browser/new/createCompositeExternalStore.js.map +1 -1
  18. package/build/browser/new/makeExternalStore.js.map +1 -1
  19. package/build/browser/new/platform-apis/admin/useCbacBanner.js +2 -2
  20. package/build/browser/new/platform-apis/admin/useCbacBanner.js.map +1 -1
  21. package/build/browser/new/platform-apis/admin/useCbacMarkingRestrictions.js +2 -2
  22. package/build/browser/new/platform-apis/admin/useCbacMarkingRestrictions.js.map +1 -1
  23. package/build/browser/new/platform-apis/admin/useCurrentFoundryUser.js +2 -2
  24. package/build/browser/new/platform-apis/admin/useCurrentFoundryUser.js.map +1 -1
  25. package/build/browser/new/platform-apis/admin/useFoundryUser.js +2 -2
  26. package/build/browser/new/platform-apis/admin/useFoundryUser.js.map +1 -1
  27. package/build/browser/new/platform-apis/admin/useFoundryUsersList.js +2 -2
  28. package/build/browser/new/platform-apis/admin/useFoundryUsersList.js.map +1 -1
  29. package/build/browser/new/platform-apis/admin/useMarkingCategories.js +2 -2
  30. package/build/browser/new/platform-apis/admin/useMarkingCategories.js.map +1 -1
  31. package/build/browser/new/platform-apis/admin/useMarkings.js +2 -2
  32. package/build/browser/new/platform-apis/admin/useMarkings.js.map +1 -1
  33. package/build/browser/new/platform-apis/admin/useUserMarkings.js +2 -2
  34. package/build/browser/new/platform-apis/admin/useUserMarkings.js.map +1 -1
  35. package/build/browser/new/shapes/derivedLinksStore.js.map +1 -1
  36. package/build/browser/new/shapes/types.js.map +1 -1
  37. package/build/browser/new/useDevToolsClient.js.map +1 -1
  38. package/build/browser/new/useLinks.js +5 -3
  39. package/build/browser/new/useLinks.js.map +1 -1
  40. package/build/browser/new/useObjectSet.js +3 -3
  41. package/build/browser/new/useObjectSet.js.map +1 -1
  42. package/build/browser/new/useOsdkAction.js +2 -2
  43. package/build/browser/new/useOsdkAction.js.map +1 -1
  44. package/build/browser/new/useOsdkAggregation.js +3 -3
  45. package/build/browser/new/useOsdkAggregation.js.map +1 -1
  46. package/build/browser/new/useOsdkFunction.js +3 -3
  47. package/build/browser/new/useOsdkFunction.js.map +1 -1
  48. package/build/browser/new/useOsdkFunctions.js +2 -2
  49. package/build/browser/new/useOsdkFunctions.js.map +1 -1
  50. package/build/browser/new/useOsdkObject.js +2 -2
  51. package/build/browser/new/useOsdkObject.js.map +1 -1
  52. package/build/browser/new/useOsdkObjects.js +2 -2
  53. package/build/browser/new/useOsdkObjects.js.map +1 -1
  54. package/build/browser/public/devtools-registry.js.map +1 -1
  55. package/build/browser/public/experimental/admin.js +27 -0
  56. package/build/browser/public/experimental/admin.js.map +1 -1
  57. package/build/browser/{OsdkProvider.js → public/experimental/aip.js} +3 -14
  58. package/build/browser/public/experimental/aip.js.map +1 -0
  59. package/build/browser/public/experimental.js +58 -2
  60. package/build/browser/public/experimental.js.map +1 -1
  61. package/build/browser/public/platform-apis.js +25 -0
  62. package/build/browser/public/platform-apis.js.map +1 -0
  63. package/build/browser/public/testing.js +61 -0
  64. package/build/browser/public/testing.js.map +1 -0
  65. package/build/browser/useObservableClient.js +41 -0
  66. package/build/browser/useObservableClient.js.map +1 -0
  67. package/build/browser/useOsdkClient.js +1 -5
  68. package/build/browser/useOsdkClient.js.map +1 -1
  69. package/build/browser/util/UserAgent.js +1 -1
  70. package/build/browser/util/UserAgent.js.map +1 -1
  71. package/build/browser/utils/usePlatformQuery.js.map +1 -1
  72. package/build/cjs/chunk-6XVB5CWK.cjs +875 -0
  73. package/build/cjs/chunk-6XVB5CWK.cjs.map +1 -0
  74. package/build/cjs/{chunk-2Y5CIQPC.cjs → chunk-DO3NFBKN.cjs} +6 -6
  75. package/build/cjs/chunk-DO3NFBKN.cjs.map +1 -0
  76. package/build/cjs/chunk-HJHKH4B6.cjs +300 -0
  77. package/build/cjs/chunk-HJHKH4B6.cjs.map +1 -0
  78. package/build/cjs/index.cjs +65 -14
  79. package/build/cjs/index.cjs.map +1 -1
  80. package/build/cjs/index.d.cts +25 -8
  81. package/build/cjs/public/devtools-registry.d.cts +1 -1
  82. package/build/cjs/public/experimental/admin.cjs +35 -293
  83. package/build/cjs/public/experimental/admin.cjs.map +1 -1
  84. package/build/cjs/public/experimental/admin.d.cts +3 -275
  85. package/build/cjs/public/experimental/aip.cjs +389 -0
  86. package/build/cjs/public/experimental/aip.cjs.map +1 -0
  87. package/build/cjs/public/experimental/aip.d.cts +83 -0
  88. package/build/cjs/public/experimental.cjs +53 -847
  89. package/build/cjs/public/experimental.cjs.map +1 -1
  90. package/build/cjs/public/experimental.d.cts +41 -16
  91. package/build/cjs/public/platform-apis.cjs +42 -0
  92. package/build/cjs/public/platform-apis.cjs.map +1 -0
  93. package/build/cjs/public/platform-apis.d.cts +275 -0
  94. package/build/cjs/public/testing.cjs +55 -0
  95. package/build/cjs/public/testing.cjs.map +1 -0
  96. package/build/cjs/public/testing.d.cts +27 -0
  97. package/build/esm/aip/chatStore.js +67 -0
  98. package/build/esm/aip/chatStore.js.map +1 -0
  99. package/build/esm/aip/chatStream.js +155 -0
  100. package/build/esm/aip/chatStream.js.map +1 -0
  101. package/build/esm/aip/useChat.js +243 -0
  102. package/build/esm/aip/useChat.js.map +1 -0
  103. package/build/esm/index.js +14 -1
  104. package/build/esm/index.js.map +1 -1
  105. package/build/esm/new/{OsdkContext2.js → OsdkContext.js} +4 -4
  106. package/build/esm/new/OsdkContext.js.map +1 -0
  107. package/build/esm/new/{OsdkProvider2.js → OsdkProvider.js} +7 -13
  108. package/build/esm/new/OsdkProvider.js.map +1 -0
  109. package/build/esm/new/core/useStableObjectSet.js +1 -1
  110. package/build/esm/new/core/useStableObjectSet.js.map +1 -1
  111. package/build/esm/new/createCompositeExternalStore.js.map +1 -1
  112. package/build/esm/new/makeExternalStore.js.map +1 -1
  113. package/build/esm/new/platform-apis/admin/useCbacBanner.js +2 -2
  114. package/build/esm/new/platform-apis/admin/useCbacBanner.js.map +1 -1
  115. package/build/esm/new/platform-apis/admin/useCbacMarkingRestrictions.js +2 -2
  116. package/build/esm/new/platform-apis/admin/useCbacMarkingRestrictions.js.map +1 -1
  117. package/build/esm/new/platform-apis/admin/useCurrentFoundryUser.js +2 -2
  118. package/build/esm/new/platform-apis/admin/useCurrentFoundryUser.js.map +1 -1
  119. package/build/esm/new/platform-apis/admin/useFoundryUser.js +2 -2
  120. package/build/esm/new/platform-apis/admin/useFoundryUser.js.map +1 -1
  121. package/build/esm/new/platform-apis/admin/useFoundryUsersList.js +2 -2
  122. package/build/esm/new/platform-apis/admin/useFoundryUsersList.js.map +1 -1
  123. package/build/esm/new/platform-apis/admin/useMarkingCategories.js +2 -2
  124. package/build/esm/new/platform-apis/admin/useMarkingCategories.js.map +1 -1
  125. package/build/esm/new/platform-apis/admin/useMarkings.js +2 -2
  126. package/build/esm/new/platform-apis/admin/useMarkings.js.map +1 -1
  127. package/build/esm/new/platform-apis/admin/useUserMarkings.js +2 -2
  128. package/build/esm/new/platform-apis/admin/useUserMarkings.js.map +1 -1
  129. package/build/esm/new/shapes/derivedLinksStore.js.map +1 -1
  130. package/build/esm/new/shapes/types.js.map +1 -1
  131. package/build/esm/new/useDevToolsClient.js.map +1 -1
  132. package/build/esm/new/useLinks.js +5 -3
  133. package/build/esm/new/useLinks.js.map +1 -1
  134. package/build/esm/new/useObjectSet.js +3 -3
  135. package/build/esm/new/useObjectSet.js.map +1 -1
  136. package/build/esm/new/useOsdkAction.js +2 -2
  137. package/build/esm/new/useOsdkAction.js.map +1 -1
  138. package/build/esm/new/useOsdkAggregation.js +3 -3
  139. package/build/esm/new/useOsdkAggregation.js.map +1 -1
  140. package/build/esm/new/useOsdkFunction.js +3 -3
  141. package/build/esm/new/useOsdkFunction.js.map +1 -1
  142. package/build/esm/new/useOsdkFunctions.js +2 -2
  143. package/build/esm/new/useOsdkFunctions.js.map +1 -1
  144. package/build/esm/new/useOsdkObject.js +2 -2
  145. package/build/esm/new/useOsdkObject.js.map +1 -1
  146. package/build/esm/new/useOsdkObjects.js +2 -2
  147. package/build/esm/new/useOsdkObjects.js.map +1 -1
  148. package/build/esm/public/devtools-registry.js.map +1 -1
  149. package/build/esm/public/experimental/admin.js +27 -0
  150. package/build/esm/public/experimental/admin.js.map +1 -1
  151. package/build/esm/{OsdkProvider.js → public/experimental/aip.js} +3 -14
  152. package/build/esm/public/experimental/aip.js.map +1 -0
  153. package/build/esm/public/experimental.js +58 -2
  154. package/build/esm/public/experimental.js.map +1 -1
  155. package/build/esm/public/platform-apis.js +25 -0
  156. package/build/esm/public/platform-apis.js.map +1 -0
  157. package/build/esm/public/testing.js +61 -0
  158. package/build/esm/public/testing.js.map +1 -0
  159. package/build/esm/useObservableClient.js +41 -0
  160. package/build/esm/useObservableClient.js.map +1 -0
  161. package/build/esm/useOsdkClient.js +1 -5
  162. package/build/esm/useOsdkClient.js.map +1 -1
  163. package/build/esm/util/UserAgent.js +1 -1
  164. package/build/esm/util/UserAgent.js.map +1 -1
  165. package/build/esm/utils/usePlatformQuery.js.map +1 -1
  166. package/build/types/aip/chatStore.d.ts +31 -0
  167. package/build/types/aip/chatStore.d.ts.map +1 -0
  168. package/build/types/aip/chatStream.d.ts +20 -0
  169. package/build/types/aip/chatStream.d.ts.map +1 -0
  170. package/build/types/aip/useChat.d.ts +79 -0
  171. package/build/types/aip/useChat.d.ts.map +1 -0
  172. package/build/types/index.d.ts +20 -1
  173. package/build/types/index.d.ts.map +1 -1
  174. package/build/types/new/{OsdkContext2.d.ts → OsdkContext.d.ts} +3 -3
  175. package/build/types/new/OsdkContext.d.ts.map +1 -0
  176. package/build/types/new/OsdkProvider.d.ts +9 -0
  177. package/build/types/new/OsdkProvider.d.ts.map +1 -0
  178. package/build/types/new/createCompositeExternalStore.d.ts +1 -1
  179. package/build/types/new/createCompositeExternalStore.d.ts.map +1 -1
  180. package/build/types/new/makeExternalStore.d.ts +1 -1
  181. package/build/types/new/makeExternalStore.d.ts.map +1 -1
  182. package/build/types/new/shapes/derivedLinksStore.d.ts +1 -1
  183. package/build/types/new/shapes/derivedLinksStore.d.ts.map +1 -1
  184. package/build/types/new/shapes/types.d.ts +1 -1
  185. package/build/types/new/shapes/types.d.ts.map +1 -1
  186. package/build/types/new/useDevToolsClient.d.ts +1 -1
  187. package/build/types/new/useDevToolsClient.d.ts.map +1 -1
  188. package/build/types/new/useLinks.d.ts +11 -3
  189. package/build/types/new/useLinks.d.ts.map +1 -1
  190. package/build/types/new/useObjectSet.d.ts +3 -1
  191. package/build/types/new/useObjectSet.d.ts.map +1 -1
  192. package/build/types/new/useOsdkAction.d.ts +1 -1
  193. package/build/types/new/useOsdkAction.d.ts.map +1 -1
  194. package/build/types/new/useOsdkAggregation.d.ts +1 -1
  195. package/build/types/new/useOsdkAggregation.d.ts.map +1 -1
  196. package/build/types/new/useOsdkFunction.d.ts +1 -1
  197. package/build/types/new/useOsdkFunction.d.ts.map +1 -1
  198. package/build/types/new/useOsdkObjects.d.ts +10 -4
  199. package/build/types/new/useOsdkObjects.d.ts.map +1 -1
  200. package/build/types/public/devtools-registry.d.ts +1 -1
  201. package/build/types/public/devtools-registry.d.ts.map +1 -1
  202. package/build/types/public/experimental/admin.d.ts +16 -0
  203. package/build/types/public/experimental/admin.d.ts.map +1 -1
  204. package/build/types/public/experimental/aip.d.ts +4 -0
  205. package/build/types/public/experimental/aip.d.ts.map +1 -0
  206. package/build/types/public/experimental.d.ts +36 -2
  207. package/build/types/public/experimental.d.ts.map +1 -1
  208. package/build/types/public/platform-apis.d.ts +11 -0
  209. package/build/types/public/platform-apis.d.ts.map +1 -0
  210. package/build/types/public/testing.d.ts +24 -0
  211. package/build/types/public/testing.d.ts.map +1 -0
  212. package/build/types/useObservableClient.d.ts +20 -0
  213. package/build/types/useObservableClient.d.ts.map +1 -0
  214. package/build/types/useOsdkClient.d.ts +0 -1
  215. package/build/types/useOsdkClient.d.ts.map +1 -1
  216. package/docs/actions.md +8 -12
  217. package/docs/advanced-queries.md +17 -23
  218. package/docs/cache-management.md +13 -13
  219. package/docs/getting-started.md +34 -109
  220. package/docs/platform-apis.md +4 -4
  221. package/docs/prerequisites.md +5 -5
  222. package/docs/querying-data.md +14 -23
  223. package/{build/browser/OsdkContext.js → experimental/aip.d.ts} +2 -12
  224. package/experimental.d.ts +1 -1
  225. package/package.json +39 -7
  226. package/{build/esm/OsdkContext.js → platform-apis.d.ts} +2 -12
  227. package/testing.d.ts +17 -0
  228. package/build/browser/OsdkContext.js.map +0 -1
  229. package/build/browser/OsdkProvider.js.map +0 -1
  230. package/build/browser/new/OsdkContext2.js.map +0 -1
  231. package/build/browser/new/OsdkProvider2.js.map +0 -1
  232. package/build/cjs/chunk-2Y5CIQPC.cjs.map +0 -1
  233. package/build/cjs/chunk-MERQDEQC.cjs +0 -54
  234. package/build/cjs/chunk-MERQDEQC.cjs.map +0 -1
  235. package/build/cjs/useOsdkMetadata-CRTcdg-a.d.cts +0 -16
  236. package/build/esm/OsdkContext.js.map +0 -1
  237. package/build/esm/OsdkProvider.js.map +0 -1
  238. package/build/esm/new/OsdkContext2.js.map +0 -1
  239. package/build/esm/new/OsdkProvider2.js.map +0 -1
  240. package/build/types/OsdkContext.d.ts +0 -5
  241. package/build/types/OsdkContext.d.ts.map +0 -1
  242. package/build/types/OsdkProvider.d.ts +0 -6
  243. package/build/types/OsdkProvider.d.ts.map +0 -1
  244. package/build/types/new/OsdkContext2.d.ts.map +0 -1
  245. package/build/types/new/OsdkProvider2.d.ts +0 -11
  246. package/build/types/new/OsdkProvider2.d.ts.map +0 -1
package/AGENTS.md CHANGED
@@ -2,12 +2,10 @@
2
2
 
3
3
  ## Installing
4
4
 
5
- **Default: `pnpm add @osdk/react@latest`** use a prerelease only if you specifically need an unreleased feature. Everything below is for when you are NOT on the latest stable.
5
+ `pnpm add @osdk/react@latest`. Must install `@osdk/react` AND `@osdk/client` AND `@osdk/api` together, and the versions must line up tighter than the declared peer ranges. `@osdk/react` imports its observable runtime from `@osdk/client/observable`, which is version-locked across the three packages.
6
6
 
7
- Must install `@osdk/react` AND `@osdk/client` AND `@osdk/api` together, and versions must line up tighter than the declared peer ranges. `@osdk/react` imports unstable APIs from `@osdk/client/unstable-do-not-use` that move between releases without deprecation.
8
-
9
- - **Stable `@osdk/react`** (e.g. `0.14.x`) → latest stable `@osdk/client` and `@osdk/api` (`2.x`).
10
- - **Prerelease `@osdk/react`** (e.g. `0.10.0-beta.15`) → MUST use prerelease `@osdk/client` and `@osdk/api` from the same line. Stable releases will break.
7
+ - **Stable `@osdk/react`** (e.g. `1.x`) latest stable `@osdk/client` and `@osdk/api` (`2.x`).
8
+ - **Prerelease `@osdk/react`** → MUST use prerelease `@osdk/client` and `@osdk/api` from the same line. Stable releases will break.
11
9
 
12
10
  To find the exact compatible `@osdk/client` and `@osdk/api` for any installed `@osdk/react`:
13
11
 
@@ -16,52 +14,43 @@ To find the exact compatible `@osdk/client` and `@osdk/api` for any installed `@
16
14
  3. If that entry has an `Updated dependencies` section, install the exact `@osdk/client@X.Y.Z` AND `@osdk/api@X.Y.Z` it lists
17
15
  4. If it does NOT, walk backwards to the most recent prior entry that does, and use those versions
18
16
 
19
- **Worked example** — installed `@osdk/react@0.10.0-beta.15`:
20
-
21
- - `0.10.0-beta.15` has no `Updated dependencies` section → walk back
22
- - `0.10.0-beta.14` lists `@osdk/client@2.8.0-beta.29` and `@osdk/api@2.8.0-beta.29`
23
- - Run: `pnpm add @osdk/client@2.8.0-beta.29 @osdk/api@2.8.0-beta.29`
24
-
25
17
  **Optional peers** (install only if you import from the matching surface):
26
18
 
27
- - `@osdk/foundry.admin` + `@osdk/foundry.core`: required ONLY for any hook from `@osdk/react/experimental/admin`. Otherwise omit.
19
+ - `@osdk/foundry.admin` + `@osdk/foundry.core`: required ONLY for any hook from `@osdk/react/platform-apis`. Otherwise omit.
28
20
 
29
21
  ## Install-time errors
30
22
 
31
- | Error | Cause | Fix |
32
- | ------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
33
- | `"<name>" is not exported by @osdk/client/.../unstable-do-not-use.js` (or `@osdk/api/...`) | `@osdk/client` or `@osdk/api` is on a different release line than the one `@osdk/react` was built against — usually a beta `@osdk/react` paired with stable peers (or vice versa) | Do NOT delete the import or downgrade `@osdk/react` silently. Follow the CHANGELOG recipe in `## Installing` to find the exact `@osdk/client` and `@osdk/api` versions, then `pnpm add @osdk/client@<version> @osdk/api@<version>`. |
34
- | `Rollup failed to resolve import "@osdk/foundry.admin"` (or `@osdk/foundry.core`) | Imported from `@osdk/react/experimental/admin` without installing the optional peers | Install `@osdk/foundry.admin` + `@osdk/foundry.core`, OR stop importing from `/experimental/admin`. |
35
- | pnpm/npm peer warning about `@osdk/client` or `@osdk/api` range | Declared peer ranges are deliberately broad; prerelease coupling is tighter than the ranges express | Follow the CHANGELOG recipe; pin to the exact `@osdk/client` and `@osdk/api` versions. |
23
+ | Error | Cause | Fix |
24
+ | ------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
25
+ | `"<name>" is not exported by @osdk/client/.../observable.js` (or `@osdk/client/.../unstable-do-not-use.js`, or `@osdk/api/...`) | `@osdk/client` or `@osdk/api` is on a different release line than the one `@osdk/react` was built against — usually a prerelease `@osdk/react` paired with stable peers (or vice versa) | Do NOT delete the import or downgrade `@osdk/react` silently. Follow the CHANGELOG recipe in `## Installing` to find the exact `@osdk/client` and `@osdk/api` versions, then `pnpm add @osdk/client@<version> @osdk/api@<version>`. |
26
+ | `Rollup failed to resolve import "@osdk/foundry.admin"` (or `@osdk/foundry.core`) | Imported from `@osdk/react/platform-apis` without installing the optional peers | Install `@osdk/foundry.admin` + `@osdk/foundry.core`, OR stop importing from `/platform-apis`. |
27
+ | pnpm/npm peer warning about `@osdk/client` or `@osdk/api` range | Declared peer ranges are deliberately broad; prerelease coupling is tighter than the ranges express | Follow the CHANGELOG recipe; pin to the exact `@osdk/client` and `@osdk/api` versions. |
36
28
 
37
29
  ## Rules
38
30
 
39
- 1. **Use `OsdkProvider2`**, not `OsdkProvider`. All modern hooks require it.
40
- 2. **Import from `@osdk/react/experimental`**, not `@osdk/react`. Main entry only has legacy hooks.
41
- 3. **Never conditionally call hooks.** Use the `enabled` option instead.
42
- 4. **Keep rendering during loading.** No early returns like `if (isLoading) return <Spinner />`. Show loading indicators alongside existing data to prevent UI flashing. Exception: `if (!data && isLoading)` is acceptable for initial load.
43
- 5. **`useOsdkObject` `enabled` is positional**, not in an options object: `useOsdkObject(Type, id, false)`.
31
+ 1. **Wrap your app in `OsdkProvider`** at the root. All hooks require it.
32
+ 2. **Never conditionally call hooks.** Use the `enabled` option instead.
33
+ 3. **Keep rendering during loading.** No early returns like `if (isLoading) return <Spinner />`. Show loading indicators alongside existing data to prevent UI flashing. Exception: `if (!data && isLoading)` is acceptable for initial load.
34
+ 4. **`useOsdkObject` `enabled` is positional**, not in an options object: `useOsdkObject(Type, id, false)`.
44
35
 
45
36
  ## Exports
46
37
 
47
- **Stable** (`@osdk/react`): `OsdkProvider` (legacy), `useOsdkClient`, `useOsdkMetadata`
38
+ **Main entry** (`@osdk/react`): `OsdkProvider`, `useOsdkObjects`, `useOsdkObject`, `useOsdkAction`, `useLinks`, `useObjectSet`, `useOsdkAggregation`, `useOsdkFunction`, `useOsdkFunctions`, `useStableObjectSet`, `useRegisterUserAgent`, `useDebouncedCallback`, `useOsdkClient`, `useOsdkMetadata`, plus the devtools registry re-exports (`registerDevTools`, `getRegisteredDevTools`).
39
+
40
+ **Platform APIs** (`@osdk/react/platform-apis`): `useCurrentFoundryUser`, `useFoundryUser`, `useFoundryUsersList`, `useMarkings`, `useMarkingCategories`, `useUserViewMarkings`, `useCbacBanner`, `useCbacMarkingRestrictions` — requires `@osdk/foundry.admin` + `@osdk/foundry.core` to be installed.
48
41
 
49
- **Experimental** (`@osdk/react/experimental`): `OsdkProvider2`, `useOsdkObjects`, `useOsdkObject`, `useOsdkAction`, `useLinks`, `useObjectSet`, `useOsdkAggregation`, `useOsdkFunction`, `useDebouncedCallback`, `useCurrentFoundryUser`, `useFoundryUser`, `useFoundryUsersList`
42
+ **DevTools** (`@osdk/react/devtools-registry`): `registerDevTools`, `getRegisteredDevTools`, `DevToolsRegistry` (also re-exported from main).
50
43
 
51
44
  ## Hook Options
52
45
 
53
- - `OsdkProvider2` - Modern provider (use this)
46
+ - `OsdkProvider` - Wrap your app at the root
54
47
  - `useOsdkObjects` - Query lists of objects
55
48
  - `useOsdkObject` - Query single object by type+key or instance
56
49
  - `useOsdkAction` - Execute and validate actions
57
50
  - `useLinks` - Navigate object relationships
58
51
  - `useObjectSet` - Advanced set operations (union, intersect, subtract, pivot)
59
52
  - `useOsdkAggregation` - Server-side aggregations with groupBy/select
60
- - `useOsdkClient`, `useOsdkMetadata` - Also available from experimental
61
-
62
- **Experimental Admin** (`@osdk/react/experimental/admin`):
63
-
64
- - `useCurrentFoundryUser`, `useFoundryUser`, `useFoundryUsersList` - Platform APIs (requires `@osdk/foundry.admin`)
53
+ - `useOsdkFunction` / `useOsdkFunctions` - Call ontology functions
65
54
 
66
55
  ## Correct Patterns
67
56
 
@@ -100,11 +89,6 @@ if (isLoading) return <Spinner />;
100
89
  // CORRECT: render together
101
90
  <div>{isLoading && <Spinner />}{data?.map(...)}</div>
102
91
 
103
- // WRONG: import from main entry
104
- import { useOsdkObjects } from "@osdk/react";
105
- // CORRECT
106
- import { useOsdkObjects } from "@osdk/react/experimental";
107
-
108
92
  // WRONG: useOsdkObject enabled in options
109
93
  useOsdkObject(Employee, id, { enabled: false });
110
94
  // CORRECT: positional
package/CHANGELOG.md CHANGED
@@ -1,20 +1,21 @@
1
1
  # @osdkkit/react
2
2
 
3
- ## 0.17.0-main-5dc557e9e321d23e8e150e8015c41ebe3b6f387c
3
+ ## 0.17.0
4
4
 
5
5
  ### Minor Changes
6
6
 
7
+ - f747fa3: Add `@osdk/aip-core` — the AIP SDK's chat completion primitives, backed by the Foundry Language Model Service's OpenAI-compatible proxy. Construct a model via `foundryModel({ client, model })` and call `generateText` for non-streaming completions or `streamText` for streaming. `LmsChatTransport` plugs into UI hooks; `useChat` is exposed from `@osdk/react/experimental/aip` and returns `messages`, `status`, `sendMessage`, `regenerate`, `stop`, `clearError`, and accepts a `transport` override. v0 is text-only and single-step — tool round-trips, multi-step loops, image/file content, Zod tool schemas, and stream resume are deferred.
8
+ - d892397: expose `$includeAllBaseObjectProperties` on `useLinks` and on the underlying `ObservableClient.observeLinks`. When set against a link whose target is an interface, the server returns the underlying concrete object's full property set so `obj.$as(ConcreteType)` yields a fully-populated concrete object. The flag is dropped at fetch time when the link target is an object type and does not narrow the returned `Osdk.Instance` type.
7
9
  - c5a6047: expose `$includeAllBaseObjectProperties` on `useOsdkObject` and on the underlying `ObservableClient.observeObject`. When set against an interface query, the server returns the underlying concrete object's full property set so `obj.$as(ConcreteType)` yields a fully-populated concrete object. The flag is dropped for non-interface queries and does not narrow the returned `Osdk.Instance` type.
8
10
  - 45be476: expose `$includeAllBaseObjectProperties` on `useOsdkObjects` and on the underlying `ObservableClient.observeList`. When set against an interface query, the server returns the underlying concrete object's full property set so `obj.$as(ConcreteType)` yields a fully-populated concrete object. The flag is dropped for non-interface queries and does not narrow the returned `Osdk.Instance` type.
11
+ - b355bc3: Add CONTRIBUTING.md for @osdk/react and @osdk/react-components
12
+ - 20e9678: Wrap `@example` JSDoc blocks in fenced ts/tsx code blocks so VS Code's Markdown renderer preserves whitespace and applies syntax highlighting.
9
13
 
10
14
  ### Patch Changes
11
15
 
12
- - b355bc3: Add CONTRIBUTING.md for @osdk/react and @osdk/react-components
13
- - Updated dependencies [eb36e21]
14
- - Updated dependencies [c5a6047]
15
- - Updated dependencies [45be476]
16
- - @osdk/client@2.14.0-main-5dc557e9e321d23e8e150e8015c41ebe3b6f387c
17
- - @osdk/api@2.14.0-main-5dc557e9e321d23e8e150e8015c41ebe3b6f387c
16
+ - Updated dependencies [86cc68c]
17
+ - Updated dependencies [f747fa3]
18
+ - @osdk/aip-core@0.2.0
18
19
 
19
20
  ## 0.16.0
20
21
 
@@ -0,0 +1,67 @@
1
+ /*
2
+ * Copyright 2026 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Tiny pub-sub store backing `useChat`. Throttles subscriber notifications so
19
+ * fast token-delta streams don't trigger one render per token.
20
+ */
21
+ export function createChatStore(options) {
22
+ let state = {
23
+ messages: options.initialMessages ?? [],
24
+ status: "ready",
25
+ error: undefined
26
+ };
27
+ const subscribers = new Set();
28
+ const throttleMs = options.throttleMs ?? 0;
29
+ let pendingNotify;
30
+ const notifyNow = () => {
31
+ if (pendingNotify != null) {
32
+ clearTimeout(pendingNotify);
33
+ pendingNotify = undefined;
34
+ }
35
+ for (const s of subscribers) {
36
+ s();
37
+ }
38
+ };
39
+ const notifyThrottled = () => {
40
+ if (throttleMs <= 0) {
41
+ notifyNow();
42
+ return;
43
+ }
44
+ if (pendingNotify != null) {
45
+ return;
46
+ }
47
+ pendingNotify = setTimeout(notifyNow, throttleMs);
48
+ };
49
+ return {
50
+ getSnapshot: () => state,
51
+ subscribe: notify => {
52
+ subscribers.add(notify);
53
+ return () => {
54
+ subscribers.delete(notify);
55
+ };
56
+ },
57
+ setState: next => {
58
+ state = typeof next === "function" ? next(state) : next;
59
+ notifyNow();
60
+ },
61
+ setStateThrottled: next => {
62
+ state = typeof next === "function" ? next(state) : next;
63
+ notifyThrottled();
64
+ }
65
+ };
66
+ }
67
+ //# sourceMappingURL=chatStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chatStore.js","names":["createChatStore","options","state","messages","initialMessages","status","error","undefined","subscribers","Set","throttleMs","pendingNotify","notifyNow","clearTimeout","s","notifyThrottled","setTimeout","getSnapshot","subscribe","notify","add","delete","setState","next","setStateThrottled"],"sources":["chatStore.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { UIMessage } from \"@osdk/aip-core\";\n\nexport type ChatStatus = \"ready\" | \"submitted\" | \"streaming\" | \"error\";\n\nexport interface ChatState {\n messages: ReadonlyArray<UIMessage>;\n status: ChatStatus;\n error: Error | undefined;\n}\n\nexport interface ChatStore {\n getSnapshot: () => ChatState;\n /** Subscribe to state changes. Returns the unsubscribe function. */\n subscribe: (notify: () => void) => () => void;\n /** Replace state and notify subscribers synchronously. */\n setState: (\n next: ChatState | ((prev: ChatState) => ChatState),\n ) => void;\n /**\n * Replace state and coalesce subscriber notifications across rapid calls.\n * Notifications fire `throttleMs` after the first change in a quiet window.\n * Use for high-frequency updates (e.g. token streaming) where one render per\n * change is wasteful.\n */\n setStateThrottled: (\n next: ChatState | ((prev: ChatState) => ChatState),\n ) => void;\n}\n\nexport interface CreateChatStoreOptions {\n initialMessages?: ReadonlyArray<UIMessage>;\n /** Min ms between subscriber notifications. 0 = synchronous. Defaults to 0. */\n throttleMs?: number;\n}\n\n/**\n * Tiny pub-sub store backing `useChat`. Throttles subscriber notifications so\n * fast token-delta streams don't trigger one render per token.\n */\nexport function createChatStore(options: CreateChatStoreOptions): ChatStore {\n let state: ChatState = {\n messages: options.initialMessages ?? [],\n status: \"ready\",\n error: undefined,\n };\n\n const subscribers = new Set<() => void>();\n const throttleMs = options.throttleMs ?? 0;\n let pendingNotify: ReturnType<typeof setTimeout> | undefined;\n\n const notifyNow = (): void => {\n if (pendingNotify != null) {\n clearTimeout(pendingNotify);\n pendingNotify = undefined;\n }\n for (const s of subscribers) {\n s();\n }\n };\n\n const notifyThrottled = (): void => {\n if (throttleMs <= 0) {\n notifyNow();\n return;\n }\n if (pendingNotify != null) {\n return;\n }\n pendingNotify = setTimeout(notifyNow, throttleMs);\n };\n\n return {\n getSnapshot: () => state,\n subscribe: (notify) => {\n subscribers.add(notify);\n return () => {\n subscribers.delete(notify);\n };\n },\n setState: (next) => {\n state = typeof next === \"function\" ? next(state) : next;\n notifyNow();\n },\n setStateThrottled: (next) => {\n state = typeof next === \"function\" ? next(state) : next;\n notifyThrottled();\n },\n };\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAqCA;AACA;AACA;AACA;AACA,OAAO,SAASA,eAAeA,CAACC,OAA+B,EAAa;EAC1E,IAAIC,KAAgB,GAAG;IACrBC,QAAQ,EAAEF,OAAO,CAACG,eAAe,IAAI,EAAE;IACvCC,MAAM,EAAE,OAAO;IACfC,KAAK,EAAEC;EACT,CAAC;EAED,MAAMC,WAAW,GAAG,IAAIC,GAAG,CAAa,CAAC;EACzC,MAAMC,UAAU,GAAGT,OAAO,CAACS,UAAU,IAAI,CAAC;EAC1C,IAAIC,aAAwD;EAE5D,MAAMC,SAAS,GAAGA,CAAA,KAAY;IAC5B,IAAID,aAAa,IAAI,IAAI,EAAE;MACzBE,YAAY,CAACF,aAAa,CAAC;MAC3BA,aAAa,GAAGJ,SAAS;IAC3B;IACA,KAAK,MAAMO,CAAC,IAAIN,WAAW,EAAE;MAC3BM,CAAC,CAAC,CAAC;IACL;EACF,CAAC;EAED,MAAMC,eAAe,GAAGA,CAAA,KAAY;IAClC,IAAIL,UAAU,IAAI,CAAC,EAAE;MACnBE,SAAS,CAAC,CAAC;MACX;IACF;IACA,IAAID,aAAa,IAAI,IAAI,EAAE;MACzB;IACF;IACAA,aAAa,GAAGK,UAAU,CAACJ,SAAS,EAAEF,UAAU,CAAC;EACnD,CAAC;EAED,OAAO;IACLO,WAAW,EAAEA,CAAA,KAAMf,KAAK;IACxBgB,SAAS,EAAGC,MAAM,IAAK;MACrBX,WAAW,CAACY,GAAG,CAACD,MAAM,CAAC;MACvB,OAAO,MAAM;QACXX,WAAW,CAACa,MAAM,CAACF,MAAM,CAAC;MAC5B,CAAC;IACH,CAAC;IACDG,QAAQ,EAAGC,IAAI,IAAK;MAClBrB,KAAK,GAAG,OAAOqB,IAAI,KAAK,UAAU,GAAGA,IAAI,CAACrB,KAAK,CAAC,GAAGqB,IAAI;MACvDX,SAAS,CAAC,CAAC;IACb,CAAC;IACDY,iBAAiB,EAAGD,IAAI,IAAK;MAC3BrB,KAAK,GAAG,OAAOqB,IAAI,KAAK,UAAU,GAAGA,IAAI,CAACrB,KAAK,CAAC,GAAGqB,IAAI;MACvDR,eAAe,CAAC,CAAC;IACnB;EACF,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1,155 @@
1
+ /*
2
+ * Copyright 2026 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { generateMessageId } from "@osdk/aip-core";
18
+
19
+ /**
20
+ * Mutable orchestration handle threaded through the streaming functions.
21
+ * Holds everything they need to read snapshots, mutate state, and check
22
+ * whether their stream is still the active one.
23
+ */
24
+
25
+ export async function runChatStream(ctx, transport, chatId, seed, trigger) {
26
+ ctx.abortRef.current?.abort();
27
+ const ctrl = new AbortController();
28
+ ctx.abortRef.current = ctrl;
29
+ ctx.stoppedRef.current = false;
30
+ const assistantId = generateMessageId();
31
+ try {
32
+ const stream = await transport.sendMessages({
33
+ trigger,
34
+ chatId,
35
+ messageId: assistantId,
36
+ messages: seed.slice(),
37
+ abortSignal: ctrl.signal
38
+ });
39
+ await drainStream(ctx, stream, assistantId, ctrl);
40
+ } catch (err) {
41
+ handleStreamError(ctx, err, ctrl);
42
+ }
43
+ }
44
+ export async function drainStream(ctx, stream, assistantMessageId, capturedCtrl) {
45
+ const {
46
+ store
47
+ } = ctx;
48
+ const reader = stream.getReader();
49
+ let textBuf = "";
50
+ const isStale = () => ctx.abortRef.current != null && ctx.abortRef.current !== capturedCtrl;
51
+
52
+ // Caller dropped our assistant message via `setMessages` mid-stream.
53
+ // Treat as "the consumer no longer wants this stream" — quietly stop.
54
+ const isOrphaned = () => {
55
+ const messages = store.getSnapshot().messages;
56
+ return textBuf.length > 0 && !messages.some(m => m.id === assistantMessageId);
57
+ };
58
+ try {
59
+ while (true) {
60
+ const {
61
+ done,
62
+ value
63
+ } = await reader.read();
64
+ if (done) {
65
+ break;
66
+ }
67
+ if (isStale()) {
68
+ await reader.cancel();
69
+ return;
70
+ }
71
+ if (isOrphaned()) {
72
+ await reader.cancel();
73
+ store.setState(prev => ({
74
+ ...prev,
75
+ status: "ready"
76
+ }));
77
+ return;
78
+ }
79
+ if (value.type === "text-delta") {
80
+ textBuf += value.delta;
81
+ upsertAssistantText(store, assistantMessageId, textBuf);
82
+ } else if (value.type === "error") {
83
+ if (ctx.stoppedRef.current || capturedCtrl.signal.aborted) {
84
+ return;
85
+ }
86
+ await reader.cancel();
87
+ throw new Error(value.errorText);
88
+ }
89
+ }
90
+ if (isStale()) {
91
+ return;
92
+ }
93
+ store.setState(prev => ({
94
+ ...prev,
95
+ status: "ready"
96
+ }));
97
+ const finalSnap = store.getSnapshot();
98
+ const finalMessage = finalSnap.messages.find(m => m.id === assistantMessageId);
99
+ if (finalMessage != null && ctx.onFinish != null) {
100
+ ctx.onFinish({
101
+ message: finalMessage,
102
+ messages: finalSnap.messages
103
+ });
104
+ }
105
+ } catch (err) {
106
+ handleStreamError(ctx, err, capturedCtrl);
107
+ } finally {
108
+ reader.releaseLock();
109
+ }
110
+ }
111
+ function upsertAssistantText(store, assistantMessageId, text) {
112
+ store.setStateThrottled(prev => {
113
+ const exists = prev.messages.some(m => m.id === assistantMessageId);
114
+ const messages = exists ? prev.messages.map(m => m.id === assistantMessageId ? {
115
+ ...m,
116
+ parts: [{
117
+ type: "text",
118
+ text
119
+ }]
120
+ } : m) : [...prev.messages, {
121
+ id: assistantMessageId,
122
+ role: "assistant",
123
+ parts: [{
124
+ type: "text",
125
+ text
126
+ }]
127
+ }];
128
+ return {
129
+ ...prev,
130
+ status: "streaming",
131
+ messages
132
+ };
133
+ });
134
+ }
135
+ function handleStreamError(ctx, err, capturedCtrl) {
136
+ if (ctx.abortRef.current != null && ctx.abortRef.current !== capturedCtrl) {
137
+ return;
138
+ }
139
+ const error = err instanceof Error ? err : new Error(String(err));
140
+ if (ctx.stoppedRef.current || error.name === "AbortError" || capturedCtrl.signal.aborted) {
141
+ ctx.store.setState(prev => ({
142
+ ...prev,
143
+ status: "ready",
144
+ error: undefined
145
+ }));
146
+ return;
147
+ }
148
+ ctx.store.setState(prev => ({
149
+ ...prev,
150
+ status: "error",
151
+ error
152
+ }));
153
+ ctx.onError?.(error);
154
+ }
155
+ //# sourceMappingURL=chatStream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chatStream.js","names":["generateMessageId","runChatStream","ctx","transport","chatId","seed","trigger","abortRef","current","abort","ctrl","AbortController","stoppedRef","assistantId","stream","sendMessages","messageId","messages","slice","abortSignal","signal","drainStream","err","handleStreamError","assistantMessageId","capturedCtrl","store","reader","getReader","textBuf","isStale","isOrphaned","getSnapshot","length","some","m","id","done","value","read","cancel","setState","prev","status","type","delta","upsertAssistantText","aborted","Error","errorText","finalSnap","finalMessage","find","onFinish","message","releaseLock","text","setStateThrottled","exists","map","parts","role","error","String","name","undefined","onError"],"sources":["chatStream.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n type ChatTransport,\n generateMessageId,\n type UIMessage,\n type UIMessageChunk,\n} from \"@osdk/aip-core\";\nimport type React from \"react\";\nimport type { ChatStore } from \"./chatStore.js\";\n\n/**\n * Mutable orchestration handle threaded through the streaming functions.\n * Holds everything they need to read snapshots, mutate state, and check\n * whether their stream is still the active one.\n */\nexport interface StreamContext {\n store: ChatStore;\n abortRef: React.MutableRefObject<AbortController | undefined>;\n stoppedRef: React.MutableRefObject<boolean>;\n onFinish:\n | ((event: {\n message: UIMessage;\n messages: ReadonlyArray<UIMessage>;\n }) => void)\n | undefined;\n onError: ((error: Error) => void) | undefined;\n}\n\nexport async function runChatStream(\n ctx: StreamContext,\n transport: ChatTransport<UIMessage>,\n chatId: string,\n seed: ReadonlyArray<UIMessage>,\n trigger: \"submit-message\" | \"regenerate-message\",\n): Promise<void> {\n ctx.abortRef.current?.abort();\n const ctrl = new AbortController();\n ctx.abortRef.current = ctrl;\n ctx.stoppedRef.current = false;\n\n const assistantId = generateMessageId();\n try {\n const stream = await transport.sendMessages({\n trigger,\n chatId,\n messageId: assistantId,\n messages: seed.slice(),\n abortSignal: ctrl.signal,\n });\n await drainStream(ctx, stream, assistantId, ctrl);\n } catch (err) {\n handleStreamError(ctx, err, ctrl);\n }\n}\n\nexport async function drainStream(\n ctx: StreamContext,\n stream: ReadableStream<UIMessageChunk>,\n assistantMessageId: string,\n capturedCtrl: AbortController,\n): Promise<void> {\n const { store } = ctx;\n const reader = stream.getReader();\n let textBuf = \"\";\n\n const isStale = (): boolean =>\n ctx.abortRef.current != null && ctx.abortRef.current !== capturedCtrl;\n\n // Caller dropped our assistant message via `setMessages` mid-stream.\n // Treat as \"the consumer no longer wants this stream\" — quietly stop.\n const isOrphaned = (): boolean => {\n const messages = store.getSnapshot().messages;\n return textBuf.length > 0\n && !messages.some((m) => m.id === assistantMessageId);\n };\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n if (isStale()) {\n await reader.cancel();\n return;\n }\n if (isOrphaned()) {\n await reader.cancel();\n store.setState((prev) => ({ ...prev, status: \"ready\" }));\n return;\n }\n if (value.type === \"text-delta\") {\n textBuf += value.delta;\n upsertAssistantText(store, assistantMessageId, textBuf);\n } else if (value.type === \"error\") {\n if (ctx.stoppedRef.current || capturedCtrl.signal.aborted) {\n return;\n }\n await reader.cancel();\n throw new Error(value.errorText);\n }\n }\n if (isStale()) {\n return;\n }\n store.setState((prev) => ({ ...prev, status: \"ready\" }));\n const finalSnap = store.getSnapshot();\n const finalMessage = finalSnap.messages.find(\n (m) => m.id === assistantMessageId,\n );\n if (finalMessage != null && ctx.onFinish != null) {\n ctx.onFinish({ message: finalMessage, messages: finalSnap.messages });\n }\n } catch (err) {\n handleStreamError(ctx, err, capturedCtrl);\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction upsertAssistantText(\n store: ChatStore,\n assistantMessageId: string,\n text: string,\n): void {\n store.setStateThrottled((prev) => {\n const exists = prev.messages.some((m) => m.id === assistantMessageId);\n const messages = exists\n ? prev.messages.map((m) =>\n m.id === assistantMessageId\n ? { ...m, parts: [{ type: \"text\" as const, text }] }\n : m\n )\n : [\n ...prev.messages,\n {\n id: assistantMessageId,\n role: \"assistant\" as const,\n parts: [{ type: \"text\" as const, text }],\n },\n ];\n return { ...prev, status: \"streaming\", messages };\n });\n}\n\nfunction handleStreamError(\n ctx: StreamContext,\n err: unknown,\n capturedCtrl: AbortController,\n): void {\n if (ctx.abortRef.current != null && ctx.abortRef.current !== capturedCtrl) {\n return;\n }\n const error = err instanceof Error ? err : new Error(String(err));\n if (\n ctx.stoppedRef.current\n || error.name === \"AbortError\"\n || capturedCtrl.signal.aborted\n ) {\n ctx.store.setState((prev) => ({\n ...prev,\n status: \"ready\",\n error: undefined,\n }));\n return;\n }\n ctx.store.setState((prev) => ({ ...prev, status: \"error\", error }));\n ctx.onError?.(error);\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,243 @@
1
+ /*
2
+ * Copyright 2026 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { generateMessageId, LmsChatTransport } from "@osdk/aip-core";
18
+ import React from "react";
19
+ import { createChatStore } from "./chatStore.js";
20
+ import { drainStream, runChatStream } from "./chatStream.js";
21
+
22
+ /**
23
+ * Options for {@link useChat}.
24
+ *
25
+ * v0 covers text-only chat. Tools, multi-step agent loops, and stream
26
+ * resume are not supported.
27
+ */
28
+
29
+ /** Return value of {@link useChat}. */
30
+
31
+ /** Input shape accepted by `sendMessage`. */
32
+
33
+ /**
34
+ * React hook for streaming chat completions through `@osdk/aip-core`'s
35
+ * `streamText`.
36
+ *
37
+ * @example
38
+ * ```tsx
39
+ * const { messages, status, sendMessage, stop, error } = useChat({
40
+ * model: foundryModel({ client, model: "gpt-4o" }),
41
+ * system: "You are a concise assistant.",
42
+ * });
43
+ * ```
44
+ */
45
+ export function useChat(options) {
46
+ const {
47
+ onFinish,
48
+ onError
49
+ } = options;
50
+ const id = React.useMemo(() => options.id ?? generateMessageId(), [options.id]);
51
+
52
+ // JSON-stringify keys keep the memo stable when callers pass inline objects.
53
+ const headersKey = JSON.stringify(options.headers ?? null);
54
+ const stopSequencesKey = JSON.stringify(options.stopSequences ?? null);
55
+ const transport = React.useMemo(() => {
56
+ if (options.transport != null) {
57
+ return options.transport;
58
+ }
59
+ if (options.model == null) {
60
+ throw new Error("useChat: `model` is required when no `transport` is provided.");
61
+ }
62
+ const built = {
63
+ model: options.model,
64
+ system: options.system,
65
+ temperature: options.temperature,
66
+ maxOutputTokens: options.maxOutputTokens,
67
+ topP: options.topP,
68
+ presencePenalty: options.presencePenalty,
69
+ frequencyPenalty: options.frequencyPenalty,
70
+ stopSequences: options.stopSequences,
71
+ seed: options.seed,
72
+ headers: options.headers
73
+ };
74
+ return new LmsChatTransport(built);
75
+ },
76
+ // eslint-disable-next-line react-hooks/exhaustive-deps
77
+ [options.transport, options.model, options.system, options.temperature, options.maxOutputTokens, options.topP, options.presencePenalty, options.frequencyPenalty, options.seed, headersKey, stopSequencesKey]);
78
+ const store = React.useMemo(() => createChatStore({
79
+ initialMessages: options.messages,
80
+ throttleMs: options.experimentalThrottle ?? 50
81
+ }),
82
+ // Recreating the store mid-session would drop chat state, so it's keyed
83
+ // only by `id`. Use `setMessages` to mutate messages at runtime.
84
+ // eslint-disable-next-line react-hooks/exhaustive-deps
85
+ [id]);
86
+ const state = React.useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);
87
+ const abortRef = React.useRef(undefined);
88
+ const stoppedRef = React.useRef(false);
89
+ const ctxRef = React.useRef({
90
+ store,
91
+ abortRef,
92
+ stoppedRef,
93
+ onFinish,
94
+ onError
95
+ });
96
+ ctxRef.current = {
97
+ store,
98
+ abortRef,
99
+ stoppedRef,
100
+ onFinish,
101
+ onError
102
+ };
103
+ const runStream = React.useCallback((seed, trigger) => runChatStream(ctxRef.current, transport, id, seed, trigger), [transport, id]);
104
+ const sendMessage = React.useCallback(async input => {
105
+ const userMsg = normalizeUserMessage(input);
106
+ const seeded = [...store.getSnapshot().messages, userMsg];
107
+ store.setState({
108
+ messages: seeded,
109
+ status: "submitted",
110
+ error: undefined
111
+ });
112
+ await runStream(seeded, "submit-message");
113
+ }, [store, runStream]);
114
+ const regenerate = React.useCallback(async regenerateOpts => {
115
+ const messages = store.getSnapshot().messages;
116
+ const cutoff = resolveRegenerateCutoff(messages, regenerateOpts?.messageId);
117
+ if (cutoff.kind === "noop") {
118
+ return;
119
+ }
120
+ if (cutoff.kind === "error") {
121
+ store.setState(prev => ({
122
+ ...prev,
123
+ status: "error",
124
+ error: cutoff.error
125
+ }));
126
+ return;
127
+ }
128
+ const truncated = messages.slice(0, cutoff.index);
129
+ store.setState({
130
+ messages: truncated,
131
+ status: "submitted",
132
+ error: undefined
133
+ });
134
+ await runStream(truncated, "regenerate-message");
135
+ }, [store, runStream]);
136
+ const stop = React.useCallback(() => {
137
+ stoppedRef.current = true;
138
+ abortRef.current?.abort();
139
+ abortRef.current = undefined;
140
+ }, []);
141
+ const resumeStream = React.useCallback(async () => {
142
+ const stream = await transport.reconnectToStream({
143
+ chatId: id
144
+ });
145
+ if (stream == null) {
146
+ return;
147
+ }
148
+ abortRef.current?.abort();
149
+ const ctrl = new AbortController();
150
+ abortRef.current = ctrl;
151
+ const assistantId = generateMessageId();
152
+ await drainStream(ctxRef.current, stream, assistantId, ctrl);
153
+ }, [transport, id]);
154
+ const clearError = React.useCallback(() => {
155
+ // Resetting from streaming/submitted would race the in-flight stream, so
156
+ // only reset when status === "error".
157
+ store.setState(prev => prev.status === "error" ? {
158
+ ...prev,
159
+ status: "ready",
160
+ error: undefined
161
+ } : prev);
162
+ }, [store]);
163
+ const setMessages = React.useCallback(next => {
164
+ store.setState(prev => {
165
+ if (prev.status === "streaming" || prev.status === "submitted") {
166
+ return prev;
167
+ }
168
+ return {
169
+ ...prev,
170
+ messages: typeof next === "function" ? next(prev.messages) : next
171
+ };
172
+ });
173
+ }, [store]);
174
+ return React.useMemo(() => ({
175
+ id,
176
+ messages: state.messages,
177
+ setMessages,
178
+ status: state.status,
179
+ error: state.error,
180
+ sendMessage,
181
+ regenerate,
182
+ stop,
183
+ resumeStream,
184
+ clearError
185
+ }), [id, state.messages, state.status, state.error, setMessages, sendMessage, regenerate, stop, resumeStream, clearError]);
186
+ }
187
+ function resolveRegenerateCutoff(messages, messageId) {
188
+ if (messageId != null) {
189
+ const index = messages.findIndex(m => m.id === messageId);
190
+ if (index < 0) {
191
+ return {
192
+ kind: "noop"
193
+ };
194
+ }
195
+ const target = messages[index];
196
+ if (target == null || target.role !== "assistant") {
197
+ return {
198
+ kind: "error",
199
+ error: new Error(`useChat.regenerate: messageId "${messageId}" is ` + `not an assistant message; only assistant messages can be regenerated.`)
200
+ };
201
+ }
202
+ return {
203
+ kind: "ok",
204
+ index
205
+ };
206
+ }
207
+ const lastAssistant = findLastAssistantIndex(messages);
208
+ if (lastAssistant < 0) {
209
+ return {
210
+ kind: "noop"
211
+ };
212
+ }
213
+ return {
214
+ kind: "ok",
215
+ index: lastAssistant
216
+ };
217
+ }
218
+ function normalizeUserMessage(input) {
219
+ if ("text" in input) {
220
+ return {
221
+ id: generateMessageId(),
222
+ role: "user",
223
+ parts: [{
224
+ type: "text",
225
+ text: input.text
226
+ }]
227
+ };
228
+ }
229
+ return {
230
+ id: generateMessageId(),
231
+ role: input.role,
232
+ parts: input.parts
233
+ };
234
+ }
235
+ function findLastAssistantIndex(arr) {
236
+ for (let i = arr.length - 1; i >= 0; i--) {
237
+ if (arr[i]?.role === "assistant") {
238
+ return i;
239
+ }
240
+ }
241
+ return -1;
242
+ }
243
+ //# sourceMappingURL=useChat.js.map