@agent-platform/ui 0.0.3 → 0.0.4

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.
@@ -4,6 +4,7 @@ import { Paperclip, PaperPlaneTilt } from '@phosphor-icons/react/dist/ssr';
4
4
  import { useCallback, useRef, useState } from 'react';
5
5
  import { cn } from '../../lib/utils';
6
6
  import { Button } from '../ui/button';
7
+ import { Textarea } from '../ui/textarea';
7
8
  function AgentInput({ value: controlledValue, onChange, onSend, onAttach, placeholder = 'AIに相談してみましょう', disabled = false, isLoading = false, className, }) {
8
9
  const [uncontrolledValue, setUncontrolledValue] = useState('');
9
10
  const textareaRef = useRef(null);
@@ -45,6 +46,6 @@ function AgentInput({ value: controlledValue, onChange, onSend, onAttach, placeh
45
46
  }
46
47
  }, [handleSend]);
47
48
  const canSend = value.trim().length > 0 && !disabled && !isLoading;
48
- return (_jsx("div", { "data-slot": "agent-input", className: cn('w-full border-t border-border bg-muted px-3 pb-3 pt-2', className), children: _jsxs("div", { className: "flex items-end gap-2 rounded-lg border border-border bg-background px-2.5 py-1.5 transition-colors focus-within:border-primary/40", children: [_jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", onClick: onAttach, disabled: disabled, "aria-label": "\u30D5\u30A1\u30A4\u30EB\u3092\u6DFB\u4ED8", className: "mb-0.5 text-muted-foreground hover:text-foreground", children: _jsx(Paperclip, { className: "size-5" }) }), _jsx("textarea", { ref: textareaRef, value: value, onChange: handleChange, onKeyDown: handleKeyDown, placeholder: placeholder, disabled: disabled, rows: 1, className: "flex-1 resize-none bg-transparent text-sm leading-5 text-foreground placeholder:text-placeholder focus:outline-none disabled:cursor-not-allowed disabled:opacity-50", style: { maxHeight: '160px' } }), _jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", onClick: handleSend, disabled: !canSend, "aria-label": "\u9001\u4FE1 (\u2318+Enter)", className: "mb-0.5 text-muted-foreground hover:text-foreground disabled:opacity-30", children: _jsx(PaperPlaneTilt, { className: "size-5", weight: "fill" }) })] }) }));
49
+ return (_jsx("div", { "data-slot": "agent-input", className: cn('w-full border-t border-border bg-muted px-3 pb-3 pt-2', className), children: _jsxs("div", { className: "flex items-end gap-1 p-2 rounded-lg border border-border bg-background transition-colors", children: [_jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", onClick: onAttach, disabled: disabled, "aria-label": "\u30D5\u30A1\u30A4\u30EB\u3092\u6DFB\u4ED8", className: "mb-0.5 text-muted-foreground hover:text-foreground", children: _jsx(Paperclip, { className: "size-4", weight: "bold" }) }), _jsx(Textarea, { ref: textareaRef, value: value, onChange: handleChange, onKeyDown: handleKeyDown, placeholder: placeholder, disabled: disabled, rows: 1, className: "border-none p-1 resize-none min-h-8 focus-visible:ring-0 focus-visible:border-0 bg-transparent" }), _jsx(Button, { type: "button", size: "icon-sm", onClick: handleSend, disabled: !canSend, "aria-label": "\u9001\u4FE1 (\u2318+Enter)", children: _jsx(PaperPlaneTilt, { className: "size-5", weight: "fill" }) })] }) }));
49
50
  }
50
51
  export { AgentInput };
@@ -1,8 +1,8 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useEffect, useMemo, useState } from 'react';
4
- import { Button } from '../ui/button';
5
4
  import { cn } from '../../lib/utils';
5
+ import { Button } from '../ui/button';
6
6
  import { AgentContainer } from './agent-container';
7
7
  import { AgentProvider } from './provider';
8
8
  const DEFAULT_OFFSET = '1.5rem';
@@ -1,5 +1,5 @@
1
- export { AgentScreen } from './agent-screen';
2
- export type { AgentScreenProps } from './agent-screen';
3
- export { AgentPopupWidget } from './agent-popup-widget';
4
1
  export type { AgentPopupWidgetProps } from './agent-popup-widget';
2
+ export { AgentPopupWidget } from './agent-popup-widget';
3
+ export type { AgentScreenProps } from './agent-screen';
4
+ export { AgentScreen } from './agent-screen';
5
5
  export type { AgentHomeCardProps } from './types';
@@ -1,2 +1,2 @@
1
- export { AgentScreen } from './agent-screen';
2
1
  export { AgentPopupWidget } from './agent-popup-widget';
2
+ export { AgentScreen } from './agent-screen';
@@ -43,21 +43,21 @@ const components = {
43
43
  if (className) {
44
44
  return _jsx("code", { className: cn('text-xs', className), children: children });
45
45
  }
46
- return (_jsx("code", { className: "bg-background/50 px-1 py-0.5 rounded text-xs", children: children }));
46
+ return _jsx("code", { className: "bg-background/50 px-1 py-0.5 rounded text-xs", children: children });
47
47
  },
48
48
  a: ({ href, children }) => (_jsx("a", { href: href, target: "_blank", rel: "noopener noreferrer", className: "text-primary underline hover:text-primary/80", children: children })),
49
- ul: ({ children }) => (_jsx("ul", { className: "list-disc list-inside pl-1 my-1.5 space-y-0.5", children: children })),
50
- ol: ({ children }) => (_jsx("ol", { className: "list-decimal list-inside pl-1 my-1.5 space-y-0.5", children: children })),
49
+ ul: ({ children }) => _jsx("ul", { className: "list-disc list-inside pl-3 my-1", children: children }),
50
+ ol: ({ children }) => _jsx("ol", { className: "list-decimal list-inside pl-3 my-1", children: children }),
51
51
  li: ({ children }) => _jsx("li", { className: "leading-relaxed", children: children }),
52
- p: ({ children }) => _jsx("p", { className: "my-1.5 first:mt-0 last:mb-0", children: children }),
53
- h1: ({ children }) => (_jsx("h1", { className: "text-base font-bold mt-3 mb-1.5 first:mt-0", children: children })),
54
- h2: ({ children }) => (_jsx("h2", { className: "text-sm font-bold mt-2.5 mb-1 first:mt-0", children: children })),
55
- h3: ({ children }) => (_jsx("h3", { className: "text-sm font-semibold mt-2 mb-1 first:mt-0", children: children })),
52
+ p: ({ children }) => _jsx("p", { className: "first:mt-0 last:mb-0", children: children }),
53
+ h1: ({ children }) => _jsx("h1", { className: "text-base font-bold mt-3 mb-1 first:mt-0", children: children }),
54
+ h2: ({ children }) => _jsx("h2", { className: "text-sm font-bold mt-2.5 mb-1 first:mt-0", children: children }),
55
+ h3: ({ children }) => _jsx("h3", { className: "text-sm font-semibold mt-2 mb-1 first:mt-0", children: children }),
56
56
  blockquote: ({ children }) => (_jsx("blockquote", { className: "border-l-2 border-border pl-3 my-1.5 text-muted-foreground italic", children: children })),
57
57
  table: ({ children }) => (_jsx("div", { className: "overflow-x-auto my-1.5", children: _jsx("table", { className: "min-w-full border-collapse border border-border text-xs", children: children }) })),
58
- thead: ({ children }) => (_jsx("thead", { className: "bg-muted/50", children: children })),
58
+ thead: ({ children }) => _jsx("thead", { className: "bg-muted/50", children: children }),
59
59
  th: ({ children }) => (_jsx("th", { className: "border border-border px-2 py-1.5 text-left font-semibold", children: children })),
60
- td: ({ children }) => (_jsx("td", { className: "border border-border px-2 py-1.5", children: children })),
60
+ td: ({ children }) => _jsx("td", { className: "border border-border px-2 py-1.5", children: children }),
61
61
  hr: () => _jsx("hr", { className: "my-3 border-border" }),
62
62
  };
63
63
  export function Markdown({ content, className }) {
@@ -4,4 +4,4 @@ export interface MessageItemProps {
4
4
  pendingToolCalls: ToolCallState[];
5
5
  toolNameLabels?: Record<string, string>;
6
6
  }
7
- export declare function MessageItem({ message, pendingToolCalls, toolNameLabels, }: MessageItemProps): import("react/jsx-runtime").JSX.Element | null;
7
+ export declare function MessageItem({ message, pendingToolCalls, toolNameLabels }: MessageItemProps): import("react/jsx-runtime").JSX.Element | null;
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { cn } from '../../../lib/utils';
4
4
  import { Markdown } from './markdown';
5
5
  import { ToolCallCard } from './tool-call-card';
6
- export function MessageItem({ message, pendingToolCalls, toolNameLabels, }) {
6
+ export function MessageItem({ message, pendingToolCalls, toolNameLabels }) {
7
7
  const isUser = message.role === 'user';
8
8
  // メッセージからテキストを抽出
9
9
  const textContent = message.content
@@ -8,7 +8,7 @@ export function MessageList({ messages, pendingToolCalls, toolNameLabels, isLoad
8
8
  // 新しいメッセージが追加されたら自動スクロール
9
9
  useEffect(() => {
10
10
  bottomRef.current?.scrollIntoView({ behavior: 'smooth' });
11
- }, [messages, isLoading]);
11
+ }, []);
12
12
  if (messages.length === 0 && !isLoading) {
13
13
  return null;
14
14
  }
@@ -19,6 +19,7 @@ export function MessageList({ messages, pendingToolCalls, toolNameLabels, isLoad
19
19
  // Show loading indicator when:
20
20
  // 1. isLoading is true AND
21
21
  // 2. No messages yet OR last message is from user OR last assistant has no content
22
- const showLoadingIndicator = isLoading && (messages.length === 0 || lastMessage?.role === 'user' || !lastAssistantHasContent);
22
+ const showLoadingIndicator = isLoading &&
23
+ (messages.length === 0 || lastMessage?.role === 'user' || !lastAssistantHasContent);
23
24
  return (_jsxs("div", { className: "flex flex-col gap-3 p-3", children: [messages.map((message) => (_jsx(MessageItem, { message: message, pendingToolCalls: pendingToolCalls, toolNameLabels: toolNameLabels }, message.id))), showLoadingIndicator && _jsx(MessageLoading, {}), _jsx("div", { ref: bottomRef })] }));
24
25
  }
@@ -6,7 +6,7 @@ function BouncingDots() {
6
6
  return (_jsxs("span", { className: "flex gap-1", "aria-hidden": "true", children: [_jsx("span", { className: "h-1.5 w-1.5 animate-bounce rounded-full bg-muted-foreground [animation-delay:0ms]" }), _jsx("span", { className: "h-1.5 w-1.5 animate-bounce rounded-full bg-muted-foreground [animation-delay:150ms]" }), _jsx("span", { className: "h-1.5 w-1.5 animate-bounce rounded-full bg-muted-foreground [animation-delay:300ms]" })] }));
7
7
  }
8
8
  export function MessageLoading({ className }) {
9
- return (_jsx("div", { className: cn('flex justify-start', className), role: "status", "aria-label": "AI\u5FDC\u7B54\u3092\u5F85\u6A5F\u4E2D", children: _jsx("div", { className: "max-w-xl", children: _jsxs("div", { className: "rounded-lg border border-border bg-card px-3 py-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("div", { className: "relative flex items-center justify-center", children: [_jsx("div", { className: "absolute h-4 w-4 animate-ping rounded-full bg-primary/20" }), _jsx("div", { className: "relative h-2 w-2 animate-pulse rounded-full bg-primary" })] }), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: "text-xs text-muted-foreground", children: "\u8003\u3048\u4E2D" }), _jsx(BouncingDots, {})] })] }), _jsxs("div", { className: "mt-2 space-y-1.5", "aria-hidden": "true", children: [_jsx("div", { className: "h-2.5 w-full animate-shimmer rounded bg-gradient-to-r from-muted via-muted-foreground/10 to-muted bg-[length:200%_100%]" }), _jsx("div", { className: "h-2.5 w-3/4 animate-shimmer rounded bg-gradient-to-r from-muted via-muted-foreground/10 to-muted bg-[length:200%_100%] [animation-delay:100ms]" }), _jsx("div", { className: "h-2.5 w-1/2 animate-shimmer rounded bg-gradient-to-r from-muted via-muted-foreground/10 to-muted bg-[length:200%_100%] [animation-delay:200ms]" })] })] }) }) }));
9
+ return (_jsx("div", { className: cn('flex justify-start', className), role: "status", "aria-label": "AI\u5FDC\u7B54\u3092\u5F85\u6A5F\u4E2D", children: _jsx("div", { className: "max-w-xl", children: _jsxs("div", { className: "rounded-lg border border-border bg-card px-3 py-2", children: [_jsxs("div", { className: "flex it ems-center gap-2", children: [_jsxs("div", { className: "relative flex items-center justify-center", children: [_jsx("div", { className: "absolute h-4 w-4 animate-ping rounded-full bg-primary/20" }), _jsx("div", { className: "relative h-2 w-2 animate-pulse rounded-full bg-primary" })] }), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: "text-xs text-muted-foreground", children: "\u8003\u3048\u4E2D" }), _jsx(BouncingDots, {})] })] }), _jsxs("div", { className: "mt-2 space-y-1.5", "aria-hidden": "true", children: [_jsx("div", { className: "h-2.5 w-full animate-shimmer rounded bg-linear-to-r from-muted via-muted-foreground/10 to-muted bg-size-[200%_100%]" }), _jsx("div", { className: "h-2.5 w-3/4 animate-shimmer rounded bg-linear-to-r from-muted via-muted-foreground/10 to-muted bg-size-[200%_100%] [animation-delay:100ms]" }), _jsx("div", { className: "h-2.5 w-1/2 animate-shimmer rounded bg-linear-to-r from-muted via-muted-foreground/10 to-muted bg-size-[200%_100%] [animation-delay:200ms]" })] })] }) }) }));
10
10
  }
11
11
  /**
12
12
  * Compact loading indicator for inline use (e.g., inside MessageItem during streaming)
@@ -1,8 +1,15 @@
1
- const FIXED_AGENT_ENDPOINT = 'https://agent-server-prod--agent-platform-dev-8e3ae.asia-east1.hosted.app/api/agent';
2
- const FIXED_API_BASE_URL = 'https://demo-scout-api-prod--agent-platform-dev-8e3ae.asia-east1.hosted.app/api';
1
+ const isDevelopment = process.env.NODE_ENV === 'development';
2
+ const PRODUCTION_AGENT_ENDPOINT = 'https://agent-server-prod--agent-platform-dev-8e3ae.asia-east1.hosted.app/api/agent';
3
+ const DEVELOPMENT_AGENT_ENDPOINT = 'http://localhost:3002/api/agent';
4
+ const FIXED_API_BASE_URL = isDevelopment
5
+ ? 'http://localhost:3001/api'
6
+ : 'https://demo-scout-api-prod--agent-platform-dev-8e3ae.asia-east1.hosted.app/api';
7
+ function normalizeUrl(url) {
8
+ return url.replace(/\/$/, '');
9
+ }
3
10
  export function resolveAgentRuntimeConfig() {
4
11
  return {
5
- endpoint: FIXED_AGENT_ENDPOINT,
6
- apiBaseUrl: FIXED_API_BASE_URL,
12
+ endpoint: normalizeUrl(isDevelopment ? DEVELOPMENT_AGENT_ENDPOINT : PRODUCTION_AGENT_ENDPOINT),
13
+ apiBaseUrl: normalizeUrl(FIXED_API_BASE_URL),
7
14
  };
8
15
  }
@@ -25,6 +25,7 @@ export type AgentHeadersProvider = () => Record<string, string> | Promise<Record
25
25
  */
26
26
  export interface AgentProviderConfig {
27
27
  agentId?: string;
28
+ /** 通信先URLは packages/ui 内部のruntime-configで解決される */
28
29
  /**
29
30
  * @deprecated 旧実装との後方互換用。
30
31
  * executeOn: 'client' のツールをブラウザ側で実行するコールバック
@@ -1,7 +1,7 @@
1
1
  import * as React from "react";
2
2
  import { type VariantProps } from "class-variance-authority";
3
3
  declare const badgeVariants: (props?: ({
4
- variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
4
+ variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | null | undefined;
5
5
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
6
6
  declare function Badge({ className, variant, asChild, ...props }: React.ComponentProps<"span"> & VariantProps<typeof badgeVariants> & {
7
7
  asChild?: boolean;
@@ -1,10 +1,10 @@
1
- import * as React from "react";
2
- import { type VariantProps } from "class-variance-authority";
1
+ import { type VariantProps } from 'class-variance-authority';
2
+ import type * as React from 'react';
3
3
  declare const buttonVariants: (props?: ({
4
- variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
4
+ variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | null | undefined;
5
5
  size?: "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
6
6
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
- declare function Button({ className, variant, size, asChild, ...props }: React.ComponentProps<"button"> & VariantProps<typeof buttonVariants> & {
7
+ declare function Button({ className, variant, size, asChild, ...props }: React.ComponentProps<'button'> & VariantProps<typeof buttonVariants> & {
8
8
  asChild?: boolean;
9
9
  }): import("react/jsx-runtime").JSX.Element;
10
10
  export { Button, buttonVariants };
@@ -1,35 +1,35 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { cva } from "class-variance-authority";
3
- import { Slot } from "radix-ui";
4
- import { cn } from "../../lib/utils";
2
+ import { cva } from 'class-variance-authority';
3
+ import { Slot } from 'radix-ui';
4
+ import { cn } from '../../lib/utils';
5
5
  const buttonVariants = cva("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", {
6
6
  variants: {
7
7
  variant: {
8
- default: "bg-primary text-primary-foreground hover:bg-primary/90",
9
- destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
10
- outline: "border bg-background hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
11
- secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
12
- ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
13
- link: "text-primary underline-offset-4 hover:underline",
8
+ default: 'bg-primary text-primary-foreground hover:bg-primary/90',
9
+ destructive: 'bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
10
+ outline: 'border bg-background hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50',
11
+ secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
12
+ ghost: 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',
13
+ link: 'text-primary underline-offset-4 hover:underline',
14
14
  },
15
15
  size: {
16
- default: "h-10 px-4 py-2 has-[>svg]:px-3",
16
+ default: 'h-10 px-4 py-2 has-[>svg]:px-3',
17
17
  xs: "h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
18
- sm: "h-9 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
19
- lg: "h-11 rounded-md px-6 has-[>svg]:px-4",
20
- icon: "size-10",
21
- "icon-xs": "size-6 rounded-md [&_svg:not([class*='size-'])]:size-3",
22
- "icon-sm": "size-8 min-h-12 min-w-12",
23
- "icon-lg": "size-10",
18
+ sm: 'h-9 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5',
19
+ lg: 'h-11 rounded-md px-6 has-[>svg]:px-4',
20
+ icon: 'size-10',
21
+ 'icon-xs': "size-6 rounded-md [&_svg:not([class*='size-'])]:size-3",
22
+ 'icon-sm': "size-8 rounded-md [&_svg:not([class*='size-'])]:size-4",
23
+ 'icon-lg': "size-10 rounded-md [&_svg:not([class*='size-'])]:size-5",
24
24
  },
25
25
  },
26
26
  defaultVariants: {
27
- variant: "default",
28
- size: "default",
27
+ variant: 'default',
28
+ size: 'default',
29
29
  },
30
30
  });
31
- function Button({ className, variant = "default", size = "default", asChild = false, ...props }) {
32
- const Comp = asChild ? Slot.Root : "button";
31
+ function Button({ className, variant = 'default', size = 'default', asChild = false, ...props }) {
32
+ const Comp = asChild ? Slot.Root : 'button';
33
33
  return (_jsx(Comp, { "data-slot": "button", "data-variant": variant, "data-size": size, className: cn(buttonVariants({ variant, size, className })), ...props }));
34
34
  }
35
35
  export { Button, buttonVariants };
@@ -0,0 +1,3 @@
1
+ import type * as React from 'react';
2
+ declare function Textarea({ className, ...props }: React.ComponentProps<'textarea'>): import("react/jsx-runtime").JSX.Element;
3
+ export { Textarea };
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cn } from '@/lib/utils';
3
+ function Textarea({ className, ...props }) {
4
+ return (_jsx("textarea", { "data-slot": "textarea", className: cn('border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm', className), ...props }));
5
+ }
6
+ export { Textarea };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-platform/ui",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "sideEffects": false,