@aws/nx-plugin 0.104.1 → 0.105.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.
- package/LICENSE-THIRD-PARTY +406 -436
- package/package.json +12 -12
- package/src/infra/app/__snapshots__/generator.spec.ts.snap +21 -21
- package/src/open-api/ts-client/__snapshots__/generator.composite-types.spec.ts.snap +438 -0
- package/src/open-api/ts-client/files/client.gen.ts.template +20 -0
- package/src/open-api/utils/codegen-data/languages.js +7 -3
- package/src/open-api/utils/codegen-data/languages.js.map +1 -1
- package/src/open-api/utils/normalise.js +17 -0
- package/src/open-api/utils/normalise.js.map +1 -1
- package/src/preset/__snapshots__/generator.spec.ts.snap +4 -4
- package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +4 -4
- package/src/py/strands-agent/__snapshots__/generator.spec.ts.snap +9 -9
- package/src/py/strands-agent/react-connection/__snapshots__/generator.spec.ts.snap +129 -4
- package/src/py/strands-agent/react-connection/serve-local.js +1 -1
- package/src/py/strands-agent/react-connection/serve-local.js.map +1 -1
- package/src/trpc/react/__snapshots__/generator.spec.ts.snap +4 -1
- package/src/ts/lib/__snapshots__/generator.spec.ts.snap +3 -1
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +3 -3
- package/src/ts/mcp-server/generator.js +1 -0
- package/src/ts/mcp-server/generator.js.map +1 -1
- package/src/ts/react-website/agui/files/cloudscape/src/components/copilot/CloudscapeAssistantMessage.tsx.template +71 -0
- package/src/ts/react-website/agui/files/cloudscape/src/components/copilot/CloudscapeChatInput.tsx.template +65 -0
- package/src/ts/react-website/agui/files/cloudscape/src/components/copilot/CloudscapeCursor.tsx.template +10 -0
- package/src/ts/react-website/agui/files/cloudscape/src/components/copilot/CloudscapeUserMessage.tsx.template +42 -0
- package/src/ts/react-website/agui/files/cloudscape/src/components/copilot/copilot.css.template +128 -0
- package/src/ts/react-website/agui/files/cloudscape/src/components/copilot/index.tsx.template +46 -0
- package/src/ts/react-website/agui/files/{src → common/src}/components/AguiProvider.tsx.template +10 -2
- package/src/ts/react-website/agui/files/default/src/components/copilot/index.tsx.template +5 -0
- package/src/ts/react-website/agui/files/shadcn/src/components/copilot/ShadcnAssistantMessage.tsx.template +71 -0
- package/src/ts/react-website/agui/files/shadcn/src/components/copilot/ShadcnChatInput.tsx.template +117 -0
- package/src/ts/react-website/agui/files/shadcn/src/components/copilot/ShadcnCursor.tsx.template +23 -0
- package/src/ts/react-website/agui/files/shadcn/src/components/copilot/ShadcnUserMessage.tsx.template +49 -0
- package/src/ts/react-website/agui/files/shadcn/src/components/copilot/copilot.css.template +116 -0
- package/src/ts/react-website/agui/files/shadcn/src/components/copilot/index.tsx.template +46 -0
- package/src/ts/react-website/agui/generator.d.ts +3 -0
- package/src/ts/react-website/agui/generator.js +28 -1
- package/src/ts/react-website/agui/generator.js.map +1 -1
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +42 -38
- package/src/ts/strands-agent/__snapshots__/generator.spec.ts.snap +1 -1
- package/src/ts/strands-agent/generator.js +1 -0
- package/src/ts/strands-agent/generator.js.map +1 -1
- package/src/utils/agent-core-constructs/files/terraform/core/agent-core/runtime.tf.template +1 -1
- package/src/utils/files/common/shadcn/src/components/ui/avatar.tsx.template +53 -0
- package/src/utils/files/common/shadcn/src/components/ui/textarea.tsx.template +18 -0
- package/src/utils/files/website/hooks/sigv4/useSigV4.tsx.template +4 -1
- package/src/utils/versions.d.ts +59 -58
- package/src/utils/versions.js +58 -57
- package/src/utils/versions.js.map +1 -1
- /package/src/ts/react-website/agui/files/{src → common/src}/hooks/useAgui__agentNameClassName__.tsx.template +0 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { CopilotChatUserMessage } from '@copilotkit/react-core/v2';
|
|
2
|
+
import type { CopilotChatUserMessageProps } from '@copilotkit/react-core/v2';
|
|
3
|
+
import ChatBubble from '@cloudscape-design/chat-components/chat-bubble';
|
|
4
|
+
import Avatar from '@cloudscape-design/chat-components/avatar';
|
|
5
|
+
|
|
6
|
+
const flattenContent = (
|
|
7
|
+
content: CopilotChatUserMessageProps['message']['content'],
|
|
8
|
+
): string => {
|
|
9
|
+
if (!content) return '';
|
|
10
|
+
if (typeof content === 'string') return content;
|
|
11
|
+
return content
|
|
12
|
+
.filter(
|
|
13
|
+
(part): part is { type: 'text'; text: string } =>
|
|
14
|
+
!!part &&
|
|
15
|
+
typeof part === 'object' &&
|
|
16
|
+
'type' in part &&
|
|
17
|
+
(part as { type?: unknown }).type === 'text' &&
|
|
18
|
+
'text' in part &&
|
|
19
|
+
typeof (part as { text?: unknown }).text === 'string',
|
|
20
|
+
)
|
|
21
|
+
.map((part) => part.text)
|
|
22
|
+
.join('\n');
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const CloudscapeUserMessageImpl = ({ message }: CopilotChatUserMessageProps) => (
|
|
26
|
+
<ChatBubble
|
|
27
|
+
ariaLabel="Your message"
|
|
28
|
+
type="outgoing"
|
|
29
|
+
avatar={<Avatar ariaLabel="You" tooltipText="You" initials="Me" />}
|
|
30
|
+
>
|
|
31
|
+
<div style={{ whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>
|
|
32
|
+
{flattenContent(message.content)}
|
|
33
|
+
</div>
|
|
34
|
+
</ChatBubble>
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
export const CloudscapeUserMessage = Object.assign(
|
|
38
|
+
CloudscapeUserMessageImpl,
|
|
39
|
+
CopilotChatUserMessage,
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
export default CloudscapeUserMessage;
|
package/src/ts/react-website/agui/files/cloudscape/src/components/copilot/copilot.css.template
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/* Explicit styles for the Streamdown markdown output (CopilotKit emits
|
|
2
|
+
* unprefixed Tailwind utilities that the website's Tailwind build can't see). */
|
|
3
|
+
|
|
4
|
+
.copilotkit-cloudscape-messages {
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
gap: 12px;
|
|
8
|
+
padding: 16px;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.copilotkit-cloudscape-input {
|
|
12
|
+
padding: 12px 16px 16px;
|
|
13
|
+
background: var(--awsui-color-background-container-content, #ffffff);
|
|
14
|
+
border-top: 1px solid var(--awsui-color-border-divider-default, #dfe3e6);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.copilotkit-cloudscape-messages [data-streamdown='strong'] {
|
|
18
|
+
font-weight: 600;
|
|
19
|
+
}
|
|
20
|
+
.copilotkit-cloudscape-messages [data-streamdown='emphasis'] {
|
|
21
|
+
font-style: italic;
|
|
22
|
+
}
|
|
23
|
+
.copilotkit-cloudscape-messages [data-streamdown='paragraph'],
|
|
24
|
+
.copilotkit-cloudscape-messages > p {
|
|
25
|
+
margin: 0.5em 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.copilotkit-cloudscape-messages [data-streamdown='heading-1'],
|
|
29
|
+
.copilotkit-cloudscape-messages [data-streamdown='heading-2'],
|
|
30
|
+
.copilotkit-cloudscape-messages [data-streamdown='heading-3'],
|
|
31
|
+
.copilotkit-cloudscape-messages [data-streamdown='heading-4'],
|
|
32
|
+
.copilotkit-cloudscape-messages [data-streamdown='heading-5'],
|
|
33
|
+
.copilotkit-cloudscape-messages [data-streamdown='heading-6'] {
|
|
34
|
+
font-weight: 600;
|
|
35
|
+
line-height: 1.3;
|
|
36
|
+
margin: 0.8em 0 0.4em;
|
|
37
|
+
}
|
|
38
|
+
.copilotkit-cloudscape-messages [data-streamdown='heading-1'] {
|
|
39
|
+
font-size: 1.5em;
|
|
40
|
+
}
|
|
41
|
+
.copilotkit-cloudscape-messages [data-streamdown='heading-2'] {
|
|
42
|
+
font-size: 1.3em;
|
|
43
|
+
}
|
|
44
|
+
.copilotkit-cloudscape-messages [data-streamdown='heading-3'] {
|
|
45
|
+
font-size: 1.15em;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.copilotkit-cloudscape-messages [data-streamdown='unordered-list'] {
|
|
49
|
+
list-style: disc;
|
|
50
|
+
padding-inline-start: 1.5em;
|
|
51
|
+
margin: 0.5em 0;
|
|
52
|
+
}
|
|
53
|
+
.copilotkit-cloudscape-messages [data-streamdown='ordered-list'] {
|
|
54
|
+
list-style: decimal;
|
|
55
|
+
padding-inline-start: 1.5em;
|
|
56
|
+
margin: 0.5em 0;
|
|
57
|
+
}
|
|
58
|
+
.copilotkit-cloudscape-messages [data-streamdown='list-item'] {
|
|
59
|
+
margin: 0.25em 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.copilotkit-cloudscape-messages [data-streamdown='inline-code'],
|
|
63
|
+
.copilotkit-cloudscape-messages code {
|
|
64
|
+
background: rgba(0, 0, 0, 0.06);
|
|
65
|
+
border-radius: 4px;
|
|
66
|
+
padding: 0.1em 0.35em;
|
|
67
|
+
font-family: var(--font-family-monospace, ui-monospace, monospace);
|
|
68
|
+
font-size: 0.9em;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.copilotkit-cloudscape-messages [data-streamdown='code-block'] {
|
|
72
|
+
background: rgba(0, 0, 0, 0.04);
|
|
73
|
+
border: 1px solid rgba(0, 0, 0, 0.08);
|
|
74
|
+
border-radius: 8px;
|
|
75
|
+
margin: 0.75em 0;
|
|
76
|
+
max-width: 100%;
|
|
77
|
+
overflow: hidden;
|
|
78
|
+
}
|
|
79
|
+
.copilotkit-cloudscape-messages [data-streamdown='code-block'] pre {
|
|
80
|
+
margin: 0;
|
|
81
|
+
padding: 12px 16px;
|
|
82
|
+
overflow-x: auto;
|
|
83
|
+
white-space: pre;
|
|
84
|
+
font-family: var(--font-family-monospace, ui-monospace, monospace);
|
|
85
|
+
font-size: 0.85em;
|
|
86
|
+
line-height: 1.5;
|
|
87
|
+
}
|
|
88
|
+
.copilotkit-cloudscape-messages [data-streamdown='code-block'] code {
|
|
89
|
+
background: transparent;
|
|
90
|
+
padding: 0;
|
|
91
|
+
white-space: pre;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.copilotkit-cloudscape-messages [data-streamdown='blockquote'] {
|
|
95
|
+
border-inline-start: 3px solid rgba(0, 0, 0, 0.15);
|
|
96
|
+
margin: 0.5em 0;
|
|
97
|
+
padding-inline-start: 1em;
|
|
98
|
+
color: rgba(0, 0, 0, 0.65);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.copilotkit-cloudscape-messages table[data-streamdown='table-wrapper'] {
|
|
102
|
+
border-collapse: collapse;
|
|
103
|
+
margin: 0.75em 0;
|
|
104
|
+
max-width: 100%;
|
|
105
|
+
overflow-x: auto;
|
|
106
|
+
width: auto;
|
|
107
|
+
}
|
|
108
|
+
.copilotkit-cloudscape-messages table[data-streamdown='table-wrapper'] th,
|
|
109
|
+
.copilotkit-cloudscape-messages table[data-streamdown='table-wrapper'] td {
|
|
110
|
+
border: 1px solid rgba(0, 0, 0, 0.12);
|
|
111
|
+
padding: 6px 10px;
|
|
112
|
+
text-align: start;
|
|
113
|
+
}
|
|
114
|
+
.copilotkit-cloudscape-messages table[data-streamdown='table-wrapper'] th {
|
|
115
|
+
background: rgba(0, 0, 0, 0.04);
|
|
116
|
+
font-weight: 600;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.copilotkit-cloudscape-messages [data-streamdown='link'] {
|
|
120
|
+
color: var(--awsui-color-text-link-default, #0972d3);
|
|
121
|
+
text-decoration: underline;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.copilotkit-cloudscape-messages [data-streamdown='horizontal-rule'] {
|
|
125
|
+
border: 0;
|
|
126
|
+
border-top: 1px solid rgba(0, 0, 0, 0.12);
|
|
127
|
+
margin: 1em 0;
|
|
128
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CopilotChat as CopilotChatBase,
|
|
3
|
+
CopilotSidebar as CopilotSidebarBase,
|
|
4
|
+
CopilotPopup as CopilotPopupBase,
|
|
5
|
+
CopilotChatView,
|
|
6
|
+
type CopilotChatProps,
|
|
7
|
+
type CopilotSidebarProps,
|
|
8
|
+
type CopilotPopupProps,
|
|
9
|
+
} from '@copilotkit/react-core/v2';
|
|
10
|
+
import { CloudscapeAssistantMessage } from './CloudscapeAssistantMessage';
|
|
11
|
+
import { CloudscapeUserMessage } from './CloudscapeUserMessage';
|
|
12
|
+
import { CloudscapeChatInput } from './CloudscapeChatInput';
|
|
13
|
+
import { CloudscapeCursor } from './CloudscapeCursor';
|
|
14
|
+
import './copilot.css';
|
|
15
|
+
|
|
16
|
+
const NoopFeather: typeof CopilotChatView.Feather = () => null;
|
|
17
|
+
|
|
18
|
+
export const cloudscapeCopilotTheme = {
|
|
19
|
+
messageView: {
|
|
20
|
+
assistantMessage: CloudscapeAssistantMessage,
|
|
21
|
+
userMessage: CloudscapeUserMessage,
|
|
22
|
+
cursor: CloudscapeCursor,
|
|
23
|
+
className: 'copilotkit-cloudscape-messages',
|
|
24
|
+
},
|
|
25
|
+
input: CloudscapeChatInput,
|
|
26
|
+
scrollView: { feather: NoopFeather },
|
|
27
|
+
} as const;
|
|
28
|
+
|
|
29
|
+
export const CopilotChat = (props: CopilotChatProps) => (
|
|
30
|
+
<CopilotChatBase {...cloudscapeCopilotTheme} {...props} />
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
export const CopilotSidebar = (props: CopilotSidebarProps) => (
|
|
34
|
+
<CopilotSidebarBase {...cloudscapeCopilotTheme} {...props} />
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
export const CopilotPopup = (props: CopilotPopupProps) => (
|
|
38
|
+
<CopilotPopupBase {...cloudscapeCopilotTheme} {...props} />
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
export {
|
|
42
|
+
CloudscapeAssistantMessage,
|
|
43
|
+
CloudscapeUserMessage,
|
|
44
|
+
CloudscapeChatInput,
|
|
45
|
+
CloudscapeCursor,
|
|
46
|
+
};
|
package/src/ts/react-website/agui/files/{src → common/src}/components/AguiProvider.tsx.template
RENAMED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
CopilotKitProvider,
|
|
3
|
+
WildcardToolCallRender,
|
|
4
|
+
} from '@copilotkit/react-core/v2';
|
|
2
5
|
import '@copilotkit/react-core/v2/styles.css';
|
|
3
6
|
import { type FC, type PropsWithChildren, useMemo } from 'react';
|
|
4
7
|
import type { AbstractAgent } from '@ag-ui/client';
|
|
5
8
|
|
|
9
|
+
const renderToolCalls = [WildcardToolCallRender];
|
|
10
|
+
|
|
6
11
|
export const AguiProvider: FC<PropsWithChildren> = ({ children }) => {
|
|
7
12
|
const selfManagedAgents = useMemo<Record<string, AbstractAgent>>(
|
|
8
13
|
() => ({}),
|
|
@@ -10,7 +15,10 @@ export const AguiProvider: FC<PropsWithChildren> = ({ children }) => {
|
|
|
10
15
|
);
|
|
11
16
|
|
|
12
17
|
return (
|
|
13
|
-
<CopilotKitProvider
|
|
18
|
+
<CopilotKitProvider
|
|
19
|
+
selfManagedAgents={selfManagedAgents}
|
|
20
|
+
renderToolCalls={renderToolCalls}
|
|
21
|
+
>
|
|
14
22
|
{children}
|
|
15
23
|
</CopilotKitProvider>
|
|
16
24
|
);
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CopilotChatAssistantMessage,
|
|
3
|
+
CopilotChatToolCallsView,
|
|
4
|
+
} from '@copilotkit/react-core/v2';
|
|
5
|
+
import type { CopilotChatAssistantMessageProps } from '@copilotkit/react-core/v2';
|
|
6
|
+
import { Copy, Sparkles } from 'lucide-react';
|
|
7
|
+
import {
|
|
8
|
+
Avatar,
|
|
9
|
+
AvatarFallback,
|
|
10
|
+
} from '<%= scopeAlias %>common-shadcn/components/ui/avatar';
|
|
11
|
+
import { Button } from '<%= scopeAlias %>common-shadcn/components/ui/button';
|
|
12
|
+
import { cn } from '<%= scopeAlias %>common-shadcn/lib/utils';
|
|
13
|
+
|
|
14
|
+
const ShadcnAssistantMessageImpl = ({
|
|
15
|
+
message,
|
|
16
|
+
messages,
|
|
17
|
+
}: CopilotChatAssistantMessageProps) => {
|
|
18
|
+
const hasContent = !!(message.content && message.content.trim().length > 0);
|
|
19
|
+
|
|
20
|
+
const handleCopy = () => {
|
|
21
|
+
if (typeof message.content === 'string') {
|
|
22
|
+
void navigator.clipboard?.writeText(message.content);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<div className="group flex items-start gap-3 py-2">
|
|
28
|
+
<Avatar className="bg-primary/10 border-primary/20 mt-0.5 border">
|
|
29
|
+
<AvatarFallback className="bg-transparent">
|
|
30
|
+
<Sparkles className="text-primary size-4" />
|
|
31
|
+
</AvatarFallback>
|
|
32
|
+
</Avatar>
|
|
33
|
+
<div className="flex min-w-0 flex-1 flex-col gap-1.5">
|
|
34
|
+
<div
|
|
35
|
+
className={cn(
|
|
36
|
+
'bg-muted/60 text-foreground rounded-2xl rounded-tl-sm px-4 py-3',
|
|
37
|
+
'copilotkit-shadcn-markdown',
|
|
38
|
+
)}
|
|
39
|
+
>
|
|
40
|
+
<CopilotChatAssistantMessage.MarkdownRenderer
|
|
41
|
+
content={message.content ?? ''}
|
|
42
|
+
/>
|
|
43
|
+
</div>
|
|
44
|
+
{message.toolCalls && message.toolCalls.length > 0 && (
|
|
45
|
+
<CopilotChatToolCallsView message={message} messages={messages} />
|
|
46
|
+
)}
|
|
47
|
+
{hasContent && (
|
|
48
|
+
<div className="text-muted-foreground flex items-center gap-0.5 opacity-0 transition-opacity group-hover:opacity-100">
|
|
49
|
+
<Button
|
|
50
|
+
type="button"
|
|
51
|
+
variant="ghost"
|
|
52
|
+
size="icon"
|
|
53
|
+
className="size-7"
|
|
54
|
+
aria-label="Copy message"
|
|
55
|
+
onClick={handleCopy}
|
|
56
|
+
>
|
|
57
|
+
<Copy className="size-3.5" />
|
|
58
|
+
</Button>
|
|
59
|
+
</div>
|
|
60
|
+
)}
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const ShadcnAssistantMessage = Object.assign(
|
|
67
|
+
ShadcnAssistantMessageImpl,
|
|
68
|
+
CopilotChatAssistantMessage,
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
export default ShadcnAssistantMessage;
|
package/src/ts/react-website/agui/files/shadcn/src/components/copilot/ShadcnChatInput.tsx.template
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useRef,
|
|
3
|
+
useState,
|
|
4
|
+
useEffect,
|
|
5
|
+
type KeyboardEvent,
|
|
6
|
+
} from 'react';
|
|
7
|
+
import {
|
|
8
|
+
CopilotChatInput,
|
|
9
|
+
type CopilotChatInputProps,
|
|
10
|
+
} from '@copilotkit/react-core/v2';
|
|
11
|
+
import { ArrowUp, Square } from 'lucide-react';
|
|
12
|
+
import { Button } from '<%= scopeAlias %>common-shadcn/components/ui/button';
|
|
13
|
+
import { Textarea } from '<%= scopeAlias %>common-shadcn/components/ui/textarea';
|
|
14
|
+
import { cn } from '<%= scopeAlias %>common-shadcn/lib/utils';
|
|
15
|
+
|
|
16
|
+
const MAX_ROWS = 8;
|
|
17
|
+
|
|
18
|
+
const ShadcnChatInputImpl = ({
|
|
19
|
+
value,
|
|
20
|
+
onChange,
|
|
21
|
+
onSubmitMessage,
|
|
22
|
+
onStop,
|
|
23
|
+
isRunning,
|
|
24
|
+
autoFocus,
|
|
25
|
+
mode,
|
|
26
|
+
}: CopilotChatInputProps) => {
|
|
27
|
+
const [internalValue, setInternalValue] = useState('');
|
|
28
|
+
const textareaRef = useRef<HTMLTextAreaElement | null>(null);
|
|
29
|
+
const currentValue = value ?? internalValue;
|
|
30
|
+
const disabled = mode === 'processing';
|
|
31
|
+
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
const el = textareaRef.current;
|
|
34
|
+
if (!el) return;
|
|
35
|
+
el.style.height = 'auto';
|
|
36
|
+
const lineHeight = parseFloat(getComputedStyle(el).lineHeight || '20');
|
|
37
|
+
el.style.height = `${Math.min(el.scrollHeight, lineHeight * MAX_ROWS)}px`;
|
|
38
|
+
}, [currentValue]);
|
|
39
|
+
|
|
40
|
+
const setValue = (next: string) => {
|
|
41
|
+
onChange?.(next);
|
|
42
|
+
if (value === undefined) setInternalValue(next);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const submit = () => {
|
|
46
|
+
const trimmed = currentValue.trim();
|
|
47
|
+
if (!trimmed) return;
|
|
48
|
+
onSubmitMessage?.(trimmed);
|
|
49
|
+
if (value === undefined) setInternalValue('');
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const handleKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {
|
|
53
|
+
if (event.key === 'Enter' && !event.shiftKey) {
|
|
54
|
+
event.preventDefault();
|
|
55
|
+
submit();
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<div className="px-4 pb-4 pt-2">
|
|
61
|
+
<div
|
|
62
|
+
className={cn(
|
|
63
|
+
'bg-background border-input focus-within:border-ring focus-within:ring-ring/30',
|
|
64
|
+
'flex items-end gap-2 rounded-3xl border px-3 py-2',
|
|
65
|
+
'shadow-[0_2px_10px_rgba(0,0,0,0.06)]',
|
|
66
|
+
'focus-within:ring-4 transition-[border,box-shadow]',
|
|
67
|
+
)}
|
|
68
|
+
>
|
|
69
|
+
<Textarea
|
|
70
|
+
ref={textareaRef}
|
|
71
|
+
value={currentValue}
|
|
72
|
+
onChange={(event) => setValue(event.target.value)}
|
|
73
|
+
onKeyDown={handleKeyDown}
|
|
74
|
+
disabled={disabled}
|
|
75
|
+
autoFocus={autoFocus}
|
|
76
|
+
placeholder="Ask me anything..."
|
|
77
|
+
rows={1}
|
|
78
|
+
className={cn(
|
|
79
|
+
'flex-1 resize-none border-0 bg-transparent p-2 shadow-none',
|
|
80
|
+
'focus-visible:ring-0 focus-visible:ring-offset-0',
|
|
81
|
+
'min-h-0 max-h-48 leading-6',
|
|
82
|
+
)}
|
|
83
|
+
/>
|
|
84
|
+
{isRunning ? (
|
|
85
|
+
<Button
|
|
86
|
+
type="button"
|
|
87
|
+
variant="secondary"
|
|
88
|
+
size="icon"
|
|
89
|
+
onClick={onStop}
|
|
90
|
+
aria-label="Stop"
|
|
91
|
+
className="size-9 rounded-full"
|
|
92
|
+
>
|
|
93
|
+
<Square className="size-4" fill="currentColor" />
|
|
94
|
+
</Button>
|
|
95
|
+
) : (
|
|
96
|
+
<Button
|
|
97
|
+
type="button"
|
|
98
|
+
size="icon"
|
|
99
|
+
onClick={submit}
|
|
100
|
+
disabled={disabled || !currentValue.trim()}
|
|
101
|
+
aria-label="Send message"
|
|
102
|
+
className="size-9 rounded-full"
|
|
103
|
+
>
|
|
104
|
+
<ArrowUp className="size-4" />
|
|
105
|
+
</Button>
|
|
106
|
+
)}
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
export const ShadcnChatInput = Object.assign(
|
|
113
|
+
ShadcnChatInputImpl,
|
|
114
|
+
CopilotChatInput,
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
export default ShadcnChatInput;
|
package/src/ts/react-website/agui/files/shadcn/src/components/copilot/ShadcnCursor.tsx.template
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { CopilotChatMessageView } from '@copilotkit/react-core/v2';
|
|
2
|
+
import { cn } from '<%= scopeAlias %>common-shadcn/lib/utils';
|
|
3
|
+
|
|
4
|
+
export const ShadcnCursor: typeof CopilotChatMessageView.Cursor = () => (
|
|
5
|
+
<div
|
|
6
|
+
role="status"
|
|
7
|
+
aria-label="Generating response"
|
|
8
|
+
className="flex items-center gap-1 px-4 py-2"
|
|
9
|
+
>
|
|
10
|
+
{[0, 1, 2].map((i) => (
|
|
11
|
+
<span
|
|
12
|
+
key={i}
|
|
13
|
+
className={cn(
|
|
14
|
+
'bg-muted-foreground/60 size-1.5 rounded-full',
|
|
15
|
+
'animate-bounce',
|
|
16
|
+
)}
|
|
17
|
+
style={{ animationDelay: `${i * 120}ms` }}
|
|
18
|
+
/>
|
|
19
|
+
))}
|
|
20
|
+
</div>
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
export default ShadcnCursor;
|
package/src/ts/react-website/agui/files/shadcn/src/components/copilot/ShadcnUserMessage.tsx.template
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { CopilotChatUserMessage } from '@copilotkit/react-core/v2';
|
|
2
|
+
import type {
|
|
3
|
+
CopilotChatUserMessageProps,
|
|
4
|
+
UserMessage,
|
|
5
|
+
} from '@copilotkit/react-core/v2';
|
|
6
|
+
import { User } from 'lucide-react';
|
|
7
|
+
import {
|
|
8
|
+
Avatar,
|
|
9
|
+
AvatarFallback,
|
|
10
|
+
} from '<%= scopeAlias %>common-shadcn/components/ui/avatar';
|
|
11
|
+
|
|
12
|
+
const flattenContent = (content: UserMessage['content']): string => {
|
|
13
|
+
if (!content) return '';
|
|
14
|
+
if (typeof content === 'string') return content;
|
|
15
|
+
return content
|
|
16
|
+
.filter(
|
|
17
|
+
(part): part is { type: 'text'; text: string } =>
|
|
18
|
+
!!part &&
|
|
19
|
+
typeof part === 'object' &&
|
|
20
|
+
'type' in part &&
|
|
21
|
+
(part as { type?: unknown }).type === 'text' &&
|
|
22
|
+
'text' in part &&
|
|
23
|
+
typeof (part as { text?: unknown }).text === 'string',
|
|
24
|
+
)
|
|
25
|
+
.map((part) => part.text)
|
|
26
|
+
.join('\n');
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const ShadcnUserMessageImpl = ({ message }: CopilotChatUserMessageProps) => (
|
|
30
|
+
<div className="flex items-start justify-end gap-3 py-2">
|
|
31
|
+
<div className="flex min-w-0 max-w-[85%] flex-col items-end gap-1.5">
|
|
32
|
+
<div className="bg-primary text-primary-foreground rounded-2xl rounded-tr-sm px-4 py-2.5 whitespace-pre-wrap break-words">
|
|
33
|
+
{flattenContent(message.content)}
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
<Avatar className="bg-secondary mt-0.5">
|
|
37
|
+
<AvatarFallback className="bg-transparent">
|
|
38
|
+
<User className="text-secondary-foreground size-4" />
|
|
39
|
+
</AvatarFallback>
|
|
40
|
+
</Avatar>
|
|
41
|
+
</div>
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
export const ShadcnUserMessage = Object.assign(
|
|
45
|
+
ShadcnUserMessageImpl,
|
|
46
|
+
CopilotChatUserMessage,
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
export default ShadcnUserMessage;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/* Explicit styles for the Streamdown markdown output (CopilotKit emits
|
|
2
|
+
* unprefixed Tailwind utilities that the website's Tailwind build can't see). */
|
|
3
|
+
|
|
4
|
+
.copilotkit-shadcn-markdown {
|
|
5
|
+
font-size: 0.95rem;
|
|
6
|
+
line-height: 1.55;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.copilotkit-shadcn-markdown [data-streamdown='strong'] {
|
|
10
|
+
font-weight: 600;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.copilotkit-shadcn-markdown [data-streamdown='emphasis'] {
|
|
14
|
+
font-style: italic;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.copilotkit-shadcn-markdown [data-streamdown='paragraph'] {
|
|
18
|
+
margin: 0.35em 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.copilotkit-shadcn-markdown [data-streamdown='heading-1'],
|
|
22
|
+
.copilotkit-shadcn-markdown [data-streamdown='heading-2'],
|
|
23
|
+
.copilotkit-shadcn-markdown [data-streamdown='heading-3'],
|
|
24
|
+
.copilotkit-shadcn-markdown [data-streamdown='heading-4'] {
|
|
25
|
+
font-weight: 600;
|
|
26
|
+
line-height: 1.3;
|
|
27
|
+
margin: 0.7em 0 0.35em;
|
|
28
|
+
}
|
|
29
|
+
.copilotkit-shadcn-markdown [data-streamdown='heading-1'] {
|
|
30
|
+
font-size: 1.35em;
|
|
31
|
+
}
|
|
32
|
+
.copilotkit-shadcn-markdown [data-streamdown='heading-2'] {
|
|
33
|
+
font-size: 1.2em;
|
|
34
|
+
}
|
|
35
|
+
.copilotkit-shadcn-markdown [data-streamdown='heading-3'] {
|
|
36
|
+
font-size: 1.05em;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.copilotkit-shadcn-markdown [data-streamdown='unordered-list'] {
|
|
40
|
+
list-style: disc;
|
|
41
|
+
padding-inline-start: 1.5em;
|
|
42
|
+
margin: 0.4em 0;
|
|
43
|
+
}
|
|
44
|
+
.copilotkit-shadcn-markdown [data-streamdown='ordered-list'] {
|
|
45
|
+
list-style: decimal;
|
|
46
|
+
padding-inline-start: 1.5em;
|
|
47
|
+
margin: 0.4em 0;
|
|
48
|
+
}
|
|
49
|
+
.copilotkit-shadcn-markdown [data-streamdown='list-item'] {
|
|
50
|
+
margin: 0.2em 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.copilotkit-shadcn-markdown [data-streamdown='inline-code'],
|
|
54
|
+
.copilotkit-shadcn-markdown code {
|
|
55
|
+
background: var(--background);
|
|
56
|
+
border-radius: 4px;
|
|
57
|
+
padding: 0.1em 0.35em;
|
|
58
|
+
font-family: var(--font-mono, ui-monospace, monospace);
|
|
59
|
+
font-size: 0.88em;
|
|
60
|
+
color: inherit;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.copilotkit-shadcn-markdown [data-streamdown='code-block'] {
|
|
64
|
+
background: var(--background);
|
|
65
|
+
border: 1px solid var(--border);
|
|
66
|
+
border-radius: 10px;
|
|
67
|
+
margin: 0.6em 0;
|
|
68
|
+
overflow: hidden;
|
|
69
|
+
max-width: 100%;
|
|
70
|
+
}
|
|
71
|
+
.copilotkit-shadcn-markdown [data-streamdown='code-block'] pre {
|
|
72
|
+
margin: 0;
|
|
73
|
+
padding: 10px 14px;
|
|
74
|
+
overflow-x: auto;
|
|
75
|
+
font-family: var(--font-mono, ui-monospace, monospace);
|
|
76
|
+
font-size: 0.85em;
|
|
77
|
+
line-height: 1.5;
|
|
78
|
+
}
|
|
79
|
+
.copilotkit-shadcn-markdown [data-streamdown='code-block'] code {
|
|
80
|
+
background: transparent;
|
|
81
|
+
padding: 0;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.copilotkit-shadcn-markdown [data-streamdown='blockquote'] {
|
|
85
|
+
border-inline-start: 3px solid var(--border);
|
|
86
|
+
margin: 0.5em 0;
|
|
87
|
+
padding-inline-start: 1em;
|
|
88
|
+
color: var(--muted-foreground);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.copilotkit-shadcn-markdown table[data-streamdown='table-wrapper'] {
|
|
92
|
+
border-collapse: collapse;
|
|
93
|
+
margin: 0.6em 0;
|
|
94
|
+
max-width: 100%;
|
|
95
|
+
}
|
|
96
|
+
.copilotkit-shadcn-markdown table[data-streamdown='table-wrapper'] th,
|
|
97
|
+
.copilotkit-shadcn-markdown table[data-streamdown='table-wrapper'] td {
|
|
98
|
+
border: 1px solid var(--border);
|
|
99
|
+
padding: 6px 10px;
|
|
100
|
+
text-align: start;
|
|
101
|
+
}
|
|
102
|
+
.copilotkit-shadcn-markdown table[data-streamdown='table-wrapper'] th {
|
|
103
|
+
background: var(--muted);
|
|
104
|
+
font-weight: 600;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.copilotkit-shadcn-markdown [data-streamdown='link'] {
|
|
108
|
+
color: var(--primary);
|
|
109
|
+
text-decoration: underline;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.copilotkit-shadcn-markdown [data-streamdown='horizontal-rule'] {
|
|
113
|
+
border: 0;
|
|
114
|
+
border-top: 1px solid var(--border);
|
|
115
|
+
margin: 1em 0;
|
|
116
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CopilotChat as CopilotChatBase,
|
|
3
|
+
CopilotSidebar as CopilotSidebarBase,
|
|
4
|
+
CopilotPopup as CopilotPopupBase,
|
|
5
|
+
CopilotChatView,
|
|
6
|
+
type CopilotChatProps,
|
|
7
|
+
type CopilotSidebarProps,
|
|
8
|
+
type CopilotPopupProps,
|
|
9
|
+
} from '@copilotkit/react-core/v2';
|
|
10
|
+
import { ShadcnAssistantMessage } from './ShadcnAssistantMessage';
|
|
11
|
+
import { ShadcnUserMessage } from './ShadcnUserMessage';
|
|
12
|
+
import { ShadcnChatInput } from './ShadcnChatInput';
|
|
13
|
+
import { ShadcnCursor } from './ShadcnCursor';
|
|
14
|
+
import './copilot.css';
|
|
15
|
+
|
|
16
|
+
const NoopFeather: typeof CopilotChatView.Feather = () => null;
|
|
17
|
+
|
|
18
|
+
export const shadcnCopilotTheme = {
|
|
19
|
+
messageView: {
|
|
20
|
+
assistantMessage: ShadcnAssistantMessage,
|
|
21
|
+
userMessage: ShadcnUserMessage,
|
|
22
|
+
cursor: ShadcnCursor,
|
|
23
|
+
className: 'flex flex-col gap-3 px-4 py-6',
|
|
24
|
+
},
|
|
25
|
+
input: ShadcnChatInput,
|
|
26
|
+
scrollView: { feather: NoopFeather },
|
|
27
|
+
} as const;
|
|
28
|
+
|
|
29
|
+
export const CopilotChat = (props: CopilotChatProps) => (
|
|
30
|
+
<CopilotChatBase {...shadcnCopilotTheme} {...props} />
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
export const CopilotSidebar = (props: CopilotSidebarProps) => (
|
|
34
|
+
<CopilotSidebarBase {...shadcnCopilotTheme} {...props} />
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
export const CopilotPopup = (props: CopilotPopupProps) => (
|
|
38
|
+
<CopilotPopupBase {...shadcnCopilotTheme} {...props} />
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
export {
|
|
42
|
+
ShadcnAssistantMessage,
|
|
43
|
+
ShadcnUserMessage,
|
|
44
|
+
ShadcnChatInput,
|
|
45
|
+
ShadcnCursor,
|
|
46
|
+
};
|
|
@@ -22,5 +22,8 @@ export interface AgUiReactConnectionOptions {
|
|
|
22
22
|
* `selfManagedAgents` registry) and wraps `<App />` in it. Each invocation
|
|
23
23
|
* AST-patches `AguiProvider` to register one more agent hook — running the
|
|
24
24
|
* generator multiple times is idempotent and additive.
|
|
25
|
+
*
|
|
26
|
+
* Also vends a `src/components/copilot` theme module picked from the
|
|
27
|
+
* website's `metadata.uxProvider` (cloudscape / shadcn / default).
|
|
25
28
|
*/
|
|
26
29
|
export declare const addAgUiReactConnection: (tree: Tree, options: AgUiReactConnectionOptions) => Promise<void>;
|