assistant-ui 0.0.123 → 0.0.124

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 (33) hide show
  1. package/dist/codemods/v0-11/content-part-to-message-part.d.ts.map +1 -1
  2. package/dist/codemods/v0-11/content-part-to-message-part.js +126 -40
  3. package/dist/codemods/v0-11/content-part-to-message-part.js.map +1 -1
  4. package/dist/codemods/v0-12/event-names-to-camelcase.d.ts.map +1 -1
  5. package/dist/codemods/v0-12/event-names-to-camelcase.js +2 -2
  6. package/dist/codemods/v0-12/event-names-to-camelcase.js.map +1 -1
  7. package/dist/codemods/v0-12/primitive-if-to-aui-if.d.ts.map +1 -1
  8. package/dist/codemods/v0-12/primitive-if-to-aui-if.js +53 -37
  9. package/dist/codemods/v0-12/primitive-if-to-aui-if.js.map +1 -1
  10. package/dist/codemods/v0-8/ui-package-split.d.ts.map +1 -1
  11. package/dist/codemods/v0-8/ui-package-split.js +11 -35
  12. package/dist/codemods/v0-8/ui-package-split.js.map +1 -1
  13. package/dist/codemods/v0-9/edge-package-split.d.ts.map +1 -1
  14. package/dist/codemods/v0-9/edge-package-split.js +15 -69
  15. package/dist/codemods/v0-9/edge-package-split.js.map +1 -1
  16. package/dist/lib/utils/package-installer.d.ts.map +1 -1
  17. package/dist/lib/utils/package-installer.js +3 -2
  18. package/dist/lib/utils/package-installer.js.map +1 -1
  19. package/package.json +1 -1
  20. package/src/codemods/v0-11/__tests__/content-part-to-message-part.test.ts +268 -2
  21. package/src/codemods/v0-11/content-part-to-message-part.ts +211 -80
  22. package/src/codemods/v0-12/__tests__/event-names-to-camelcase.test.ts +23 -0
  23. package/src/codemods/v0-12/__tests__/primitive-if-to-aui-if.test.ts +115 -0
  24. package/src/codemods/v0-12/event-names-to-camelcase.ts +2 -8
  25. package/src/codemods/v0-12/primitive-if-to-aui-if.ts +87 -57
  26. package/src/codemods/v0-8/__tests__/ui-package-split.test.ts +83 -0
  27. package/src/codemods/v0-8/ui-package-split.ts +21 -59
  28. package/src/codemods/v0-9/edge-package-split.test.ts +100 -0
  29. package/src/codemods/v0-9/edge-package-split.ts +30 -139
  30. package/src/lib/utils/package-installer.test.ts +39 -0
  31. package/src/lib/utils/package-installer.ts +3 -1
  32. package/templates/cloud-harness/components/assistant-ui/elements/tool-fallback.aui.tsx +17 -8
  33. package/templates/cloud-harness/package.json +2 -2
@@ -1,11 +1,8 @@
1
1
  import { createTransformer } from "../utils/createTransformer";
2
2
 
3
- // Chat runtime and converter exports moved to react-ai-sdk
4
3
  const reactAiSdkExports: string[] = [
5
- // Chat Runtime (replaces edge runtime)
6
4
  "useChatRuntime",
7
5
 
8
- // Core Types
9
6
  "CoreMessage",
10
7
  "CoreUserMessage",
11
8
  "CoreAssistantMessage",
@@ -14,13 +11,11 @@ const reactAiSdkExports: string[] = [
14
11
  "CoreAssistantMessagePart",
15
12
  "CoreToolCallMessagePart",
16
13
 
17
- // Core message converters
18
14
  "fromCoreMessages",
19
15
  "fromCoreMessage",
20
16
  "toCoreMessages",
21
17
  "toCoreMessage",
22
18
 
23
- // Language model converters
24
19
  "toLanguageModelMessages",
25
20
  "toLanguageModelTools",
26
21
  "fromLanguageModelMessages",
@@ -29,150 +24,46 @@ const reactAiSdkExports: string[] = [
29
24
  ];
30
25
 
31
26
  const migrateToEdgePackage = createTransformer(({ j, root, markAsChanged }) => {
32
- const sourcesToMigrate: string[] = ["@assistant-ui/react"];
33
- const movedAiSdkSpecifiers: any[] = [];
34
- let lastMigratedImportPath: any = null;
35
-
36
- root
37
- .find(j.ImportDeclaration)
38
- .filter((path: any) => sourcesToMigrate.includes(path.value.source.value))
39
- .forEach((path: any) => {
40
- let hadMigratedSpecifiers = false;
41
- const remainingSpecifiers: any[] = [];
42
- path.value.specifiers.forEach((specifier: any) => {
43
- if (
44
- j.ImportSpecifier.check(specifier) &&
45
- reactAiSdkExports.includes(specifier.imported.name as string)
46
- ) {
47
- movedAiSdkSpecifiers.push(specifier);
48
- hadMigratedSpecifiers = true;
49
- } else {
50
- remainingSpecifiers.push(specifier);
51
- }
52
- });
53
- if (hadMigratedSpecifiers) {
54
- lastMigratedImportPath = path;
55
- }
56
- if (remainingSpecifiers.length === 0) {
57
- j(path).remove();
58
- markAsChanged();
59
- } else if (remainingSpecifiers.length !== path.value.specifiers.length) {
60
- path.value.specifiers = remainingSpecifiers;
61
- markAsChanged();
62
- }
63
- });
64
-
65
- // Add imports for react-ai-sdk (all edge-related imports now go here)
66
- if (movedAiSdkSpecifiers.length > 0) {
67
- const existingAiSdkImport = root.find(j.ImportDeclaration, {
68
- source: { value: "@assistant-ui/react-ai-sdk" },
69
- });
70
- if (existingAiSdkImport.size() > 0) {
71
- existingAiSdkImport.forEach((path: any) => {
72
- movedAiSdkSpecifiers.forEach((specifier: any) => {
73
- if (
74
- !path.value.specifiers.some(
75
- (s: any) => s.imported.name === specifier.imported.name,
76
- )
77
- ) {
78
- path.value.specifiers.push(specifier);
79
- }
80
- });
81
- });
82
- } else {
83
- const newImport = j.importDeclaration(
84
- movedAiSdkSpecifiers,
85
- j.literal("@assistant-ui/react-ai-sdk"),
86
- );
87
- if (lastMigratedImportPath) {
88
- j(lastMigratedImportPath).insertAfter(newImport);
89
- } else {
90
- const firstImport = root.find(j.ImportDeclaration).at(0);
91
- if (firstImport.size() > 0) {
92
- firstImport.insertBefore(newImport);
93
- } else {
94
- root.get().node.program.body.unshift(newImport);
95
- }
96
- }
97
- }
98
- markAsChanged();
99
- }
100
-
101
- // Migrate imports from edge/converters
102
- root.find(j.ImportDeclaration).forEach((path: any) => {
103
- const sourceValue: string = path.value.source.value;
27
+ root.find(j.ImportDeclaration).forEach((path) => {
28
+ const source = path.node.source.value;
104
29
  if (
105
- sourceValue.startsWith("@assistant-ui/react/") &&
106
- (sourceValue.includes("edge/") ||
107
- sourceValue.includes("dangerous-in-browser/"))
30
+ typeof source === "string" &&
31
+ source.startsWith("@assistant-ui/react/") &&
32
+ (source.includes("edge/") || source.includes("dangerous-in-browser/"))
108
33
  ) {
109
- path.value.source = j.literal(
110
- sourceValue.replace(
111
- "@assistant-ui/react/",
112
- "@assistant-ui/react-ai-sdk/",
113
- ),
34
+ path.node.source = j.literal(
35
+ source.replace("@assistant-ui/react/", "@assistant-ui/react-ai-sdk/"),
114
36
  );
115
37
  markAsChanged();
38
+ return;
116
39
  }
117
- });
118
40
 
119
- // Migrate language model converter imports from react-edge to react-ai-sdk
120
- root.find(j.ImportDeclaration).forEach((path: any) => {
121
- const sourceValue: string = path.value.source.value;
122
41
  if (
123
- sourceValue === "@assistant-ui/react-edge" ||
124
- sourceValue === "@assistant-ui/react"
125
- ) {
126
- let hasLanguageModelConverters = false;
127
- const remainingSpecifiers: any[] = [];
128
- const aiSdkSpecifiers: any[] = [];
129
-
130
- path.value.specifiers.forEach((specifier: any) => {
131
- if (
132
- j.ImportSpecifier.check(specifier) &&
133
- reactAiSdkExports.includes(specifier.imported.name as string)
134
- ) {
135
- aiSdkSpecifiers.push(specifier);
136
- hasLanguageModelConverters = true;
137
- } else {
138
- remainingSpecifiers.push(specifier);
139
- }
140
- });
141
-
142
- if (hasLanguageModelConverters) {
143
- if (remainingSpecifiers.length === 0) {
144
- j(path).remove();
145
- } else {
146
- path.value.specifiers = remainingSpecifiers;
147
- }
148
-
149
- const existingAiSdkImport = root.find(j.ImportDeclaration, {
150
- source: { value: "@assistant-ui/react-ai-sdk" },
151
- });
42
+ source !== "@assistant-ui/react" &&
43
+ source !== "@assistant-ui/react-edge"
44
+ )
45
+ return;
152
46
 
153
- if (existingAiSdkImport.size() > 0) {
154
- existingAiSdkImport.forEach((importPath: any) => {
155
- aiSdkSpecifiers.forEach((specifier: any) => {
156
- if (
157
- !importPath.value.specifiers.some(
158
- (s: any) => s.imported.name === specifier.imported.name,
159
- )
160
- ) {
161
- importPath.value.specifiers.push(specifier);
162
- }
163
- });
164
- });
165
- } else {
166
- const newImport = j.importDeclaration(
167
- aiSdkSpecifiers,
168
- j.literal("@assistant-ui/react-ai-sdk"),
169
- );
170
- j(path).insertAfter(newImport);
171
- }
47
+ const specifiers = path.node.specifiers ?? [];
48
+ const moved = specifiers.filter(
49
+ (specifier) =>
50
+ j.ImportSpecifier.check(specifier) &&
51
+ reactAiSdkExports.includes(specifier.imported.name as string),
52
+ );
53
+ if (moved.length === 0) return;
172
54
 
173
- markAsChanged();
174
- }
55
+ const destination = j.literal("@assistant-ui/react-ai-sdk");
56
+ if (moved.length === specifiers.length) {
57
+ path.node.source = destination;
58
+ } else {
59
+ path.node.specifiers = specifiers.filter(
60
+ (specifier) => !moved.includes(specifier),
61
+ );
62
+ const declaration = j.importDeclaration(moved, destination);
63
+ declaration.importKind = path.node.importKind ?? "value";
64
+ j(path).insertAfter(declaration);
175
65
  }
66
+ markAsChanged();
176
67
  });
177
68
  });
178
69
 
@@ -0,0 +1,39 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { installPackageIfNeeded } from "./package-installer";
3
+
4
+ const mocks = vi.hoisted(() => ({
5
+ askQuestion: vi.fn(),
6
+ installPackage: vi.fn(),
7
+ }));
8
+
9
+ vi.mock("./file-scanner", async (importOriginal) => ({
10
+ ...(await importOriginal<typeof import("./file-scanner")>()),
11
+ scanForImport: () => true,
12
+ }));
13
+
14
+ vi.mock("./package-manager", async (importOriginal) => ({
15
+ ...(await importOriginal<typeof import("./package-manager")>()),
16
+ isPackageInstalled: () => false,
17
+ askQuestion: mocks.askQuestion,
18
+ installPackage: mocks.installPackage,
19
+ }));
20
+
21
+ describe("installPackageIfNeeded", () => {
22
+ it.each(["y", ""])(
23
+ "rejects a failed required install after accepting with %j",
24
+ async (answer) => {
25
+ mocks.askQuestion.mockResolvedValue(answer);
26
+ mocks.installPackage.mockResolvedValue(false);
27
+
28
+ await expect(
29
+ installPackageIfNeeded({
30
+ packageName: "@assistant-ui/ai-sdk",
31
+ importPatterns: ["@assistant-ui/ai-sdk"],
32
+ promptMessage: "Install?",
33
+ skipMessage: "Already installed",
34
+ notFoundMessage: "Not found",
35
+ }),
36
+ ).rejects.toThrow("Failed to install @assistant-ui/ai-sdk");
37
+ },
38
+ );
39
+ });
@@ -31,7 +31,9 @@ export async function installPackageIfNeeded(
31
31
 
32
32
  const answer = await askQuestion(config.promptMessage);
33
33
  if (answer === "" || answer.toLowerCase().startsWith("y")) {
34
- await installPackage(config.packageName);
34
+ if (!(await installPackage(config.packageName))) {
35
+ throw new Error(`Failed to install ${config.packageName}`);
36
+ }
35
37
  } else {
36
38
  logger.info("Skipping installation.");
37
39
  }
@@ -141,11 +141,13 @@ function ToolFallbackDuration({
141
141
  function ToolFallbackTrigger({
142
142
  toolName,
143
143
  status,
144
+ responseDeliveryStatus,
144
145
  className,
145
146
  ...props
146
147
  }: React.ComponentProps<typeof CollapsibleTrigger> & {
147
148
  toolName: string;
148
149
  status?: ToolCallMessagePartStatus;
150
+ responseDeliveryStatus?: ToolCallMessagePart["responseDeliveryStatus"];
149
151
  }) {
150
152
  const statusType = status?.type ?? "complete";
151
153
  const isRunning = statusType === "running";
@@ -154,13 +156,15 @@ function ToolFallbackTrigger({
154
156
 
155
157
  const Icon = statusIconMap[statusType];
156
158
  const label =
157
- statusType === "running"
158
- ? "Running tool"
159
- : statusType === "requires-action"
160
- ? "Waiting on tool"
161
- : statusType === "incomplete"
162
- ? `${isCancelled ? "Cancelled" : "Failed"} tool`
163
- : "Used tool";
159
+ responseDeliveryStatus === "queued"
160
+ ? "Reply queued, not sent yet"
161
+ : statusType === "running"
162
+ ? "Running tool"
163
+ : statusType === "requires-action"
164
+ ? "Waiting on tool"
165
+ : statusType === "incomplete"
166
+ ? `${isCancelled ? "Cancelled" : "Failed"} tool`
167
+ : "Used tool";
164
168
 
165
169
  return (
166
170
  <CollapsibleTrigger
@@ -1195,6 +1199,7 @@ const ToolFallbackImpl: ToolCallMessagePartComponent = ({
1195
1199
  argsText,
1196
1200
  result,
1197
1201
  status,
1202
+ responseDeliveryStatus,
1198
1203
  addResult,
1199
1204
  resume,
1200
1205
  interrupt,
@@ -1243,7 +1248,11 @@ const ToolFallbackImpl: ToolCallMessagePartComponent = ({
1243
1248
 
1244
1249
  return (
1245
1250
  <ToolFallbackRoot open={open} onOpenChange={setOpen}>
1246
- <ToolFallbackTrigger toolName={toolName} status={status} />
1251
+ <ToolFallbackTrigger
1252
+ toolName={toolName}
1253
+ status={status}
1254
+ responseDeliveryStatus={responseDeliveryStatus}
1255
+ />
1247
1256
  <ToolFallbackContent>
1248
1257
  <ToolFallbackError status={status} />
1249
1258
  <ToolFallbackArgs
@@ -28,13 +28,13 @@
28
28
  "cn": "^0.4.0",
29
29
  "harness-sdk": "file:vendor/harness-sdk-0.3.1.tgz",
30
30
  "lucide-react": "^1.52.0",
31
- "next": "^16.4.0",
31
+ "next": "^16.4.1",
32
32
  "react": "^19.3.0",
33
33
  "react-dom": "^19.3.0",
34
34
  "remark-gfm": "^4.0.1",
35
35
  "statewire": "file:vendor/statewire-0.19.3.tgz",
36
36
  "tw-animate-css": "^1.4.0",
37
- "tw-shimmer": "^0.4.13",
37
+ "tw-shimmer": "^0.4.14",
38
38
  "zustand": "^5.0.15"
39
39
  },
40
40
  "devDependencies": {