@surf-kit/agent 0.1.1 → 0.2.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/README.md +19 -1
- package/dist/agent-BNSmiexZ.d.cts +44 -0
- package/dist/agent-BNSmiexZ.d.ts +44 -0
- package/dist/agent-identity/index.cjs +157 -0
- package/dist/agent-identity/index.cjs.map +1 -0
- package/dist/agent-identity/index.d.cts +35 -0
- package/dist/agent-identity/index.d.ts +35 -0
- package/dist/agent-identity/index.js +127 -0
- package/dist/agent-identity/index.js.map +1 -0
- package/dist/chat/index.cjs +1281 -0
- package/dist/chat/index.cjs.map +1 -0
- package/dist/chat/index.d.cts +72 -0
- package/dist/chat/index.d.ts +72 -0
- package/dist/chat/index.js +1239 -0
- package/dist/chat/index.js.map +1 -0
- package/dist/chat--OifhIRe.d.ts +24 -0
- package/dist/chat-ChYl2XjV.d.cts +24 -0
- package/dist/confidence/index.cjs +253 -0
- package/dist/confidence/index.cjs.map +1 -0
- package/dist/confidence/index.d.cts +40 -0
- package/dist/confidence/index.d.ts +40 -0
- package/dist/confidence/index.js +222 -0
- package/dist/confidence/index.js.map +1 -0
- package/dist/feedback/index.cjs +186 -0
- package/dist/feedback/index.cjs.map +1 -0
- package/dist/feedback/index.d.cts +27 -0
- package/dist/feedback/index.d.ts +27 -0
- package/dist/feedback/index.js +157 -0
- package/dist/feedback/index.js.map +1 -0
- package/dist/{hooks-B8CSeOsn.d.cts → hooks-BGs8-4GK.d.ts} +4 -99
- package/dist/{hooks-B8CSeOsn.d.ts → hooks-DLfF18IU.d.cts} +4 -99
- package/dist/hooks.d.cts +4 -1
- package/dist/hooks.d.ts +4 -1
- package/dist/index-BazLnae1.d.cts +67 -0
- package/dist/index-BazLnae1.d.ts +67 -0
- package/dist/index.cjs +889 -144
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -321
- package/dist/index.d.ts +15 -321
- package/dist/index.js +879 -142
- package/dist/index.js.map +1 -1
- package/dist/layouts/index.cjs +1588 -0
- package/dist/layouts/index.cjs.map +1 -0
- package/dist/layouts/index.d.cts +46 -0
- package/dist/layouts/index.d.ts +46 -0
- package/dist/layouts/index.js +1548 -0
- package/dist/layouts/index.js.map +1 -0
- package/dist/mcp/index.cjs +522 -0
- package/dist/mcp/index.cjs.map +1 -0
- package/dist/mcp/index.d.cts +2 -0
- package/dist/mcp/index.d.ts +2 -0
- package/dist/mcp/index.js +492 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/response/index.cjs +519 -0
- package/dist/response/index.cjs.map +1 -0
- package/dist/response/index.d.cts +44 -0
- package/dist/response/index.d.ts +44 -0
- package/dist/response/index.js +478 -0
- package/dist/response/index.js.map +1 -0
- package/dist/sources/index.cjs +243 -0
- package/dist/sources/index.cjs.map +1 -0
- package/dist/sources/index.d.cts +44 -0
- package/dist/sources/index.d.ts +44 -0
- package/dist/sources/index.js +212 -0
- package/dist/sources/index.js.map +1 -0
- package/dist/streaming/index.cjs +531 -0
- package/dist/streaming/index.cjs.map +1 -0
- package/dist/streaming/index.d.cts +81 -0
- package/dist/streaming/index.d.ts +81 -0
- package/dist/streaming/index.js +495 -0
- package/dist/streaming/index.js.map +1 -0
- package/dist/streaming-DbQxScpi.d.ts +39 -0
- package/dist/streaming-DfT22A0z.d.cts +39 -0
- package/package.json +62 -17
package/README.md
CHANGED
|
@@ -34,7 +34,7 @@ function App() {
|
|
|
34
34
|
|
|
35
35
|
**Chat** — AgentChat, MessageThread, MessageBubble, MessageComposer, WelcomeScreen, ConversationList
|
|
36
36
|
|
|
37
|
-
**Streaming** — StreamingMessage, ThinkingIndicator, ToolExecution, RetrievalProgress, VerificationProgress, TypewriterText
|
|
37
|
+
**Streaming** — StreamingMessage, ThinkingIndicator, ToolExecution, RetrievalProgress, VerificationProgress, TypewriterText, TypingIndicator, TextGlimmer, StreamingList, StreamingStructure
|
|
38
38
|
|
|
39
39
|
**Trust & Confidence** — ConfidenceBadge, ConfidenceMeter, ConfidenceBreakdown, VerificationBadge, VerificationDetail
|
|
40
40
|
|
|
@@ -48,8 +48,26 @@ function App() {
|
|
|
48
48
|
|
|
49
49
|
**Layouts** — AgentFullPage, AgentPanel, AgentWidget, AgentEmbed
|
|
50
50
|
|
|
51
|
+
**MCP** — MCPToolCall, MCPResourceView, MCPServerStatus, MCPApprovalDialog
|
|
52
|
+
|
|
51
53
|
**Hooks** (via `@surf-kit/agent/hooks`) — useAgentChat, useStreaming, useConversation, useFeedback, useAgentTheme, useCharacterDrain
|
|
52
54
|
|
|
55
|
+
## Subpath Exports
|
|
56
|
+
|
|
57
|
+
Import only what you need for smaller bundles:
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
import { MessageThread } from '@surf-kit/agent/chat'
|
|
61
|
+
import { StreamingMessage } from '@surf-kit/agent/streaming'
|
|
62
|
+
import { MCPToolCall } from '@surf-kit/agent/mcp'
|
|
63
|
+
import { ConfidenceBadge } from '@surf-kit/agent/confidence'
|
|
64
|
+
import { SourceCard } from '@surf-kit/agent/sources'
|
|
65
|
+
import { AgentAvatar } from '@surf-kit/agent/agent-identity'
|
|
66
|
+
import { FollowUpChips } from '@surf-kit/agent/response'
|
|
67
|
+
import { AgentFullPage } from '@surf-kit/agent/layouts'
|
|
68
|
+
import { ThumbsFeedback } from '@surf-kit/agent/feedback'
|
|
69
|
+
```
|
|
70
|
+
|
|
53
71
|
## Docs
|
|
54
72
|
|
|
55
73
|
- [Storybook](https://barney-w.github.io/surf-kit/storybook)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
interface Source {
|
|
4
|
+
title: string;
|
|
5
|
+
section?: string;
|
|
6
|
+
document_id: string;
|
|
7
|
+
url: string;
|
|
8
|
+
confidence: number;
|
|
9
|
+
snippet: string;
|
|
10
|
+
}
|
|
11
|
+
interface ConfidenceBreakdown {
|
|
12
|
+
overall: 'high' | 'medium' | 'low';
|
|
13
|
+
retrieval_quality: number;
|
|
14
|
+
source_authority: number;
|
|
15
|
+
answer_groundedness: number;
|
|
16
|
+
recency: number;
|
|
17
|
+
reasoning: string;
|
|
18
|
+
}
|
|
19
|
+
interface VerificationResult {
|
|
20
|
+
status: 'passed' | 'flagged' | 'failed';
|
|
21
|
+
flags: string[];
|
|
22
|
+
claims_checked: number;
|
|
23
|
+
claims_verified: number;
|
|
24
|
+
}
|
|
25
|
+
interface AgentResponse {
|
|
26
|
+
message: string;
|
|
27
|
+
sources: Source[];
|
|
28
|
+
confidence: ConfidenceBreakdown;
|
|
29
|
+
verification: VerificationResult;
|
|
30
|
+
ui_hint: 'text' | 'table' | 'card' | 'list' | 'steps' | 'warning';
|
|
31
|
+
structured_data: Record<string, unknown> | null;
|
|
32
|
+
follow_up_suggestions: string[];
|
|
33
|
+
}
|
|
34
|
+
interface AgentInfo {
|
|
35
|
+
id: string;
|
|
36
|
+
label: string;
|
|
37
|
+
accent?: string;
|
|
38
|
+
icon?: React.ComponentType<{
|
|
39
|
+
size?: number;
|
|
40
|
+
className?: string;
|
|
41
|
+
}>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type { AgentInfo as A, ConfidenceBreakdown as C, Source as S, VerificationResult as V, AgentResponse as a };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
interface Source {
|
|
4
|
+
title: string;
|
|
5
|
+
section?: string;
|
|
6
|
+
document_id: string;
|
|
7
|
+
url: string;
|
|
8
|
+
confidence: number;
|
|
9
|
+
snippet: string;
|
|
10
|
+
}
|
|
11
|
+
interface ConfidenceBreakdown {
|
|
12
|
+
overall: 'high' | 'medium' | 'low';
|
|
13
|
+
retrieval_quality: number;
|
|
14
|
+
source_authority: number;
|
|
15
|
+
answer_groundedness: number;
|
|
16
|
+
recency: number;
|
|
17
|
+
reasoning: string;
|
|
18
|
+
}
|
|
19
|
+
interface VerificationResult {
|
|
20
|
+
status: 'passed' | 'flagged' | 'failed';
|
|
21
|
+
flags: string[];
|
|
22
|
+
claims_checked: number;
|
|
23
|
+
claims_verified: number;
|
|
24
|
+
}
|
|
25
|
+
interface AgentResponse {
|
|
26
|
+
message: string;
|
|
27
|
+
sources: Source[];
|
|
28
|
+
confidence: ConfidenceBreakdown;
|
|
29
|
+
verification: VerificationResult;
|
|
30
|
+
ui_hint: 'text' | 'table' | 'card' | 'list' | 'steps' | 'warning';
|
|
31
|
+
structured_data: Record<string, unknown> | null;
|
|
32
|
+
follow_up_suggestions: string[];
|
|
33
|
+
}
|
|
34
|
+
interface AgentInfo {
|
|
35
|
+
id: string;
|
|
36
|
+
label: string;
|
|
37
|
+
accent?: string;
|
|
38
|
+
icon?: React.ComponentType<{
|
|
39
|
+
size?: number;
|
|
40
|
+
className?: string;
|
|
41
|
+
}>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type { AgentInfo as A, ConfidenceBreakdown as C, Source as S, VerificationResult as V, AgentResponse as a };
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/agent-identity/index.ts
|
|
21
|
+
var agent_identity_exports = {};
|
|
22
|
+
__export(agent_identity_exports, {
|
|
23
|
+
AgentAvatar: () => AgentAvatar,
|
|
24
|
+
AgentHandoff: () => AgentHandoff,
|
|
25
|
+
AgentLabel: () => AgentLabel,
|
|
26
|
+
RoutingIndicator: () => RoutingIndicator
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(agent_identity_exports);
|
|
29
|
+
|
|
30
|
+
// src/hooks/useAgentTheme.ts
|
|
31
|
+
var import_react = require("react");
|
|
32
|
+
var DEFAULT_ACCENT = "#6366f1";
|
|
33
|
+
var DEFAULT_LABEL = "Agent";
|
|
34
|
+
function useAgentTheme(agentId, agentThemes) {
|
|
35
|
+
return (0, import_react.useMemo)(() => {
|
|
36
|
+
if (!agentId) {
|
|
37
|
+
return { accent: DEFAULT_ACCENT, icon: null, label: DEFAULT_LABEL };
|
|
38
|
+
}
|
|
39
|
+
const theme = agentThemes?.[agentId];
|
|
40
|
+
if (!theme) {
|
|
41
|
+
return { accent: DEFAULT_ACCENT, icon: null, label: agentId };
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
accent: theme.accent ?? DEFAULT_ACCENT,
|
|
45
|
+
icon: theme.icon ?? null,
|
|
46
|
+
label: theme.label
|
|
47
|
+
};
|
|
48
|
+
}, [agentId, agentThemes]);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// src/agent-identity/AgentAvatar/AgentAvatar.tsx
|
|
52
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
53
|
+
var sizeMap = {
|
|
54
|
+
sm: "h-6 w-6 text-xs",
|
|
55
|
+
md: "h-8 w-8 text-sm",
|
|
56
|
+
lg: "h-10 w-10 text-base"
|
|
57
|
+
};
|
|
58
|
+
var iconSizeMap = {
|
|
59
|
+
sm: 14,
|
|
60
|
+
md: 18,
|
|
61
|
+
lg: 22
|
|
62
|
+
};
|
|
63
|
+
function AgentAvatar({ agentId, agent, size = "md", agentThemes, className }) {
|
|
64
|
+
const resolvedId = agent?.id ?? agentId ?? null;
|
|
65
|
+
const themes = agent ? { ...agentThemes, [agent.id]: agent } : agentThemes;
|
|
66
|
+
const { accent, icon: Icon, label } = useAgentTheme(resolvedId, themes);
|
|
67
|
+
const initial = label.charAt(0).toUpperCase();
|
|
68
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
69
|
+
"div",
|
|
70
|
+
{
|
|
71
|
+
className: `inline-flex items-center justify-center rounded-full shrink-0 font-medium text-white ${sizeMap[size]} ${className ?? ""}`,
|
|
72
|
+
style: { backgroundColor: accent },
|
|
73
|
+
role: "img",
|
|
74
|
+
"aria-label": `${label} avatar`,
|
|
75
|
+
"data-testid": "agent-avatar",
|
|
76
|
+
children: Icon ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { size: iconSizeMap[size], className: "text-white" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": "true", children: initial })
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// src/agent-identity/AgentLabel/AgentLabel.tsx
|
|
82
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
83
|
+
function AgentLabel({ agent, className }) {
|
|
84
|
+
const accent = agent.accent ?? "#6366f1";
|
|
85
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
86
|
+
"span",
|
|
87
|
+
{
|
|
88
|
+
className: `text-xs font-medium ${className ?? ""}`,
|
|
89
|
+
"data-testid": "agent-label",
|
|
90
|
+
children: [
|
|
91
|
+
"Answered by",
|
|
92
|
+
" ",
|
|
93
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: accent }, children: agent.label })
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// src/agent-identity/AgentHandoff/AgentHandoff.tsx
|
|
100
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
101
|
+
function AgentHandoff({ from, to, className }) {
|
|
102
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
103
|
+
"div",
|
|
104
|
+
{
|
|
105
|
+
className: `flex items-center gap-3 px-4 py-3 rounded-xl border border-border bg-surface ${className ?? ""}`,
|
|
106
|
+
"data-testid": "agent-handoff",
|
|
107
|
+
children: [
|
|
108
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-2 animate-in fade-in slide-in-from-left-2 duration-300", children: [
|
|
109
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AgentAvatar, { agent: from, size: "sm" }),
|
|
110
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-xs text-text-secondary", children: from.label })
|
|
111
|
+
] }),
|
|
112
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-text-secondary text-xs", "aria-hidden": "true", children: "\u2192" }),
|
|
113
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-2 animate-in fade-in slide-in-from-right-2 duration-300", children: [
|
|
114
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AgentAvatar, { agent: to, size: "sm" }),
|
|
115
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-xs text-text-secondary", children: to.label })
|
|
116
|
+
] }),
|
|
117
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "sr-only", role: "status", "aria-live": "polite", children: [
|
|
118
|
+
"Handing off from ",
|
|
119
|
+
from.label,
|
|
120
|
+
" to ",
|
|
121
|
+
to.label
|
|
122
|
+
] })
|
|
123
|
+
]
|
|
124
|
+
}
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// src/agent-identity/RoutingIndicator/RoutingIndicator.tsx
|
|
129
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
130
|
+
function RoutingIndicator({ from, to, reason, className }) {
|
|
131
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
132
|
+
"div",
|
|
133
|
+
{
|
|
134
|
+
className: `inline-flex items-center gap-1.5 rounded-md border border-border/50 bg-surface-secondary/50 px-2.5 py-1 font-mono text-[11px] text-text-secondary ${className ?? ""}`,
|
|
135
|
+
"data-testid": "routing-indicator",
|
|
136
|
+
children: [
|
|
137
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "opacity-60", children: "Routed:" }),
|
|
138
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: from }),
|
|
139
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "opacity-40", "aria-hidden": "true", children: "\u2192" }),
|
|
140
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: to }),
|
|
141
|
+
reason && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "opacity-50 ml-1", title: reason, children: [
|
|
142
|
+
"(",
|
|
143
|
+
reason,
|
|
144
|
+
")"
|
|
145
|
+
] })
|
|
146
|
+
]
|
|
147
|
+
}
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
151
|
+
0 && (module.exports = {
|
|
152
|
+
AgentAvatar,
|
|
153
|
+
AgentHandoff,
|
|
154
|
+
AgentLabel,
|
|
155
|
+
RoutingIndicator
|
|
156
|
+
});
|
|
157
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/agent-identity/index.ts","../../src/hooks/useAgentTheme.ts","../../src/agent-identity/AgentAvatar/AgentAvatar.tsx","../../src/agent-identity/AgentLabel/AgentLabel.tsx","../../src/agent-identity/AgentHandoff/AgentHandoff.tsx","../../src/agent-identity/RoutingIndicator/RoutingIndicator.tsx"],"sourcesContent":["export { AgentAvatar } from './AgentAvatar'\nexport type { AgentAvatarProps } from './AgentAvatar'\n\nexport { AgentLabel } from './AgentLabel'\nexport type { AgentLabelProps } from './AgentLabel'\n\nexport { AgentHandoff } from './AgentHandoff'\nexport type { AgentHandoffProps } from './AgentHandoff'\n\nexport { RoutingIndicator } from './RoutingIndicator'\nexport type { RoutingIndicatorProps } from './RoutingIndicator'\n","import { useMemo } from 'react'\nimport type { AgentInfo } from '../types/agent'\n\nexport interface AgentThemeResult {\n accent: string\n icon: AgentInfo['icon'] | null\n label: string\n}\n\nconst DEFAULT_ACCENT = '#6366f1'\nconst DEFAULT_LABEL = 'Agent'\n\nexport function useAgentTheme(\n agentId: string | null | undefined,\n agentThemes?: Record<string, AgentInfo>,\n): AgentThemeResult {\n return useMemo(() => {\n if (!agentId) {\n return { accent: DEFAULT_ACCENT, icon: null, label: DEFAULT_LABEL }\n }\n\n const theme = agentThemes?.[agentId]\n if (!theme) {\n return { accent: DEFAULT_ACCENT, icon: null, label: agentId }\n }\n\n return {\n accent: theme.accent ?? DEFAULT_ACCENT,\n icon: theme.icon ?? null,\n label: theme.label,\n }\n }, [agentId, agentThemes])\n}\n","import React from 'react'\nimport type { AgentInfo } from '../../types/agent'\nimport { useAgentTheme } from '../../hooks/useAgentTheme'\n\nexport type AgentAvatarProps = {\n agentId?: string\n agent?: AgentInfo\n size?: 'sm' | 'md' | 'lg'\n agentThemes?: Record<string, AgentInfo>\n className?: string\n}\n\nconst sizeMap = {\n sm: 'h-6 w-6 text-xs',\n md: 'h-8 w-8 text-sm',\n lg: 'h-10 w-10 text-base',\n} as const\n\nconst iconSizeMap = {\n sm: 14,\n md: 18,\n lg: 22,\n} as const\n\nfunction AgentAvatar({ agentId, agent, size = 'md', agentThemes, className }: AgentAvatarProps) {\n const resolvedId = agent?.id ?? agentId ?? null\n const themes = agent ? { ...agentThemes, [agent.id]: agent } : agentThemes\n const { accent, icon: Icon, label } = useAgentTheme(resolvedId, themes)\n\n const initial = label.charAt(0).toUpperCase()\n\n return (\n <div\n className={`inline-flex items-center justify-center rounded-full shrink-0 font-medium text-white ${sizeMap[size]} ${className ?? ''}`}\n style={{ backgroundColor: accent }}\n role=\"img\"\n aria-label={`${label} avatar`}\n data-testid=\"agent-avatar\"\n >\n {Icon ? (\n <Icon size={iconSizeMap[size]} className=\"text-white\" />\n ) : (\n <span aria-hidden=\"true\">{initial}</span>\n )}\n </div>\n )\n}\n\nexport { AgentAvatar }\n","import React from 'react'\nimport type { AgentInfo } from '../../types/agent'\n\nexport type AgentLabelProps = {\n agent: AgentInfo\n className?: string\n}\n\nfunction AgentLabel({ agent, className }: AgentLabelProps) {\n const accent = agent.accent ?? '#6366f1'\n\n return (\n <span\n className={`text-xs font-medium ${className ?? ''}`}\n data-testid=\"agent-label\"\n >\n Answered by{' '}\n <span style={{ color: accent }}>{agent.label}</span>\n </span>\n )\n}\n\nexport { AgentLabel }\n","import React from 'react'\nimport type { AgentInfo } from '../../types/agent'\nimport { AgentAvatar } from '../AgentAvatar'\n\nexport type AgentHandoffProps = {\n from: AgentInfo\n to: AgentInfo\n className?: string\n}\n\nfunction AgentHandoff({ from, to, className }: AgentHandoffProps) {\n return (\n <div\n className={`flex items-center gap-3 px-4 py-3 rounded-xl border border-border bg-surface ${className ?? ''}`}\n data-testid=\"agent-handoff\"\n >\n <div className=\"flex items-center gap-2 animate-in fade-in slide-in-from-left-2 duration-300\">\n <AgentAvatar agent={from} size=\"sm\" />\n <span className=\"text-xs text-text-secondary\">{from.label}</span>\n </div>\n\n <span className=\"text-text-secondary text-xs\" aria-hidden=\"true\">{'\\u2192'}</span>\n\n <div className=\"flex items-center gap-2 animate-in fade-in slide-in-from-right-2 duration-300\">\n <AgentAvatar agent={to} size=\"sm\" />\n <span className=\"text-xs text-text-secondary\">{to.label}</span>\n </div>\n\n <div className=\"sr-only\" role=\"status\" aria-live=\"polite\">\n Handing off from {from.label} to {to.label}\n </div>\n </div>\n )\n}\n\nexport { AgentHandoff }\n","import React from 'react'\n\nexport type RoutingIndicatorProps = {\n from: string\n to: string\n reason?: string\n className?: string\n}\n\nfunction RoutingIndicator({ from, to, reason, className }: RoutingIndicatorProps) {\n return (\n <div\n className={`inline-flex items-center gap-1.5 rounded-md border border-border/50 bg-surface-secondary/50 px-2.5 py-1 font-mono text-[11px] text-text-secondary ${className ?? ''}`}\n data-testid=\"routing-indicator\"\n >\n <span className=\"opacity-60\">Routed:</span>\n <span>{from}</span>\n <span className=\"opacity-40\" aria-hidden=\"true\">{'\\u2192'}</span>\n <span>{to}</span>\n {reason && (\n <span className=\"opacity-50 ml-1\" title={reason}>\n ({reason})\n </span>\n )}\n </div>\n )\n}\n\nexport { RoutingIndicator }\n"],"mappings":"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","names":["import_jsx_runtime","import_jsx_runtime","import_jsx_runtime"]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { A as AgentInfo } from '../agent-BNSmiexZ.cjs';
|
|
3
|
+
import 'react';
|
|
4
|
+
|
|
5
|
+
type AgentAvatarProps = {
|
|
6
|
+
agentId?: string;
|
|
7
|
+
agent?: AgentInfo;
|
|
8
|
+
size?: 'sm' | 'md' | 'lg';
|
|
9
|
+
agentThemes?: Record<string, AgentInfo>;
|
|
10
|
+
className?: string;
|
|
11
|
+
};
|
|
12
|
+
declare function AgentAvatar({ agentId, agent, size, agentThemes, className }: AgentAvatarProps): react_jsx_runtime.JSX.Element;
|
|
13
|
+
|
|
14
|
+
type AgentLabelProps = {
|
|
15
|
+
agent: AgentInfo;
|
|
16
|
+
className?: string;
|
|
17
|
+
};
|
|
18
|
+
declare function AgentLabel({ agent, className }: AgentLabelProps): react_jsx_runtime.JSX.Element;
|
|
19
|
+
|
|
20
|
+
type AgentHandoffProps = {
|
|
21
|
+
from: AgentInfo;
|
|
22
|
+
to: AgentInfo;
|
|
23
|
+
className?: string;
|
|
24
|
+
};
|
|
25
|
+
declare function AgentHandoff({ from, to, className }: AgentHandoffProps): react_jsx_runtime.JSX.Element;
|
|
26
|
+
|
|
27
|
+
type RoutingIndicatorProps = {
|
|
28
|
+
from: string;
|
|
29
|
+
to: string;
|
|
30
|
+
reason?: string;
|
|
31
|
+
className?: string;
|
|
32
|
+
};
|
|
33
|
+
declare function RoutingIndicator({ from, to, reason, className }: RoutingIndicatorProps): react_jsx_runtime.JSX.Element;
|
|
34
|
+
|
|
35
|
+
export { AgentAvatar, type AgentAvatarProps, AgentHandoff, type AgentHandoffProps, AgentLabel, type AgentLabelProps, RoutingIndicator, type RoutingIndicatorProps };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { A as AgentInfo } from '../agent-BNSmiexZ.js';
|
|
3
|
+
import 'react';
|
|
4
|
+
|
|
5
|
+
type AgentAvatarProps = {
|
|
6
|
+
agentId?: string;
|
|
7
|
+
agent?: AgentInfo;
|
|
8
|
+
size?: 'sm' | 'md' | 'lg';
|
|
9
|
+
agentThemes?: Record<string, AgentInfo>;
|
|
10
|
+
className?: string;
|
|
11
|
+
};
|
|
12
|
+
declare function AgentAvatar({ agentId, agent, size, agentThemes, className }: AgentAvatarProps): react_jsx_runtime.JSX.Element;
|
|
13
|
+
|
|
14
|
+
type AgentLabelProps = {
|
|
15
|
+
agent: AgentInfo;
|
|
16
|
+
className?: string;
|
|
17
|
+
};
|
|
18
|
+
declare function AgentLabel({ agent, className }: AgentLabelProps): react_jsx_runtime.JSX.Element;
|
|
19
|
+
|
|
20
|
+
type AgentHandoffProps = {
|
|
21
|
+
from: AgentInfo;
|
|
22
|
+
to: AgentInfo;
|
|
23
|
+
className?: string;
|
|
24
|
+
};
|
|
25
|
+
declare function AgentHandoff({ from, to, className }: AgentHandoffProps): react_jsx_runtime.JSX.Element;
|
|
26
|
+
|
|
27
|
+
type RoutingIndicatorProps = {
|
|
28
|
+
from: string;
|
|
29
|
+
to: string;
|
|
30
|
+
reason?: string;
|
|
31
|
+
className?: string;
|
|
32
|
+
};
|
|
33
|
+
declare function RoutingIndicator({ from, to, reason, className }: RoutingIndicatorProps): react_jsx_runtime.JSX.Element;
|
|
34
|
+
|
|
35
|
+
export { AgentAvatar, type AgentAvatarProps, AgentHandoff, type AgentHandoffProps, AgentLabel, type AgentLabelProps, RoutingIndicator, type RoutingIndicatorProps };
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// src/hooks/useAgentTheme.ts
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
var DEFAULT_ACCENT = "#6366f1";
|
|
4
|
+
var DEFAULT_LABEL = "Agent";
|
|
5
|
+
function useAgentTheme(agentId, agentThemes) {
|
|
6
|
+
return useMemo(() => {
|
|
7
|
+
if (!agentId) {
|
|
8
|
+
return { accent: DEFAULT_ACCENT, icon: null, label: DEFAULT_LABEL };
|
|
9
|
+
}
|
|
10
|
+
const theme = agentThemes?.[agentId];
|
|
11
|
+
if (!theme) {
|
|
12
|
+
return { accent: DEFAULT_ACCENT, icon: null, label: agentId };
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
accent: theme.accent ?? DEFAULT_ACCENT,
|
|
16
|
+
icon: theme.icon ?? null,
|
|
17
|
+
label: theme.label
|
|
18
|
+
};
|
|
19
|
+
}, [agentId, agentThemes]);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// src/agent-identity/AgentAvatar/AgentAvatar.tsx
|
|
23
|
+
import { jsx } from "react/jsx-runtime";
|
|
24
|
+
var sizeMap = {
|
|
25
|
+
sm: "h-6 w-6 text-xs",
|
|
26
|
+
md: "h-8 w-8 text-sm",
|
|
27
|
+
lg: "h-10 w-10 text-base"
|
|
28
|
+
};
|
|
29
|
+
var iconSizeMap = {
|
|
30
|
+
sm: 14,
|
|
31
|
+
md: 18,
|
|
32
|
+
lg: 22
|
|
33
|
+
};
|
|
34
|
+
function AgentAvatar({ agentId, agent, size = "md", agentThemes, className }) {
|
|
35
|
+
const resolvedId = agent?.id ?? agentId ?? null;
|
|
36
|
+
const themes = agent ? { ...agentThemes, [agent.id]: agent } : agentThemes;
|
|
37
|
+
const { accent, icon: Icon, label } = useAgentTheme(resolvedId, themes);
|
|
38
|
+
const initial = label.charAt(0).toUpperCase();
|
|
39
|
+
return /* @__PURE__ */ jsx(
|
|
40
|
+
"div",
|
|
41
|
+
{
|
|
42
|
+
className: `inline-flex items-center justify-center rounded-full shrink-0 font-medium text-white ${sizeMap[size]} ${className ?? ""}`,
|
|
43
|
+
style: { backgroundColor: accent },
|
|
44
|
+
role: "img",
|
|
45
|
+
"aria-label": `${label} avatar`,
|
|
46
|
+
"data-testid": "agent-avatar",
|
|
47
|
+
children: Icon ? /* @__PURE__ */ jsx(Icon, { size: iconSizeMap[size], className: "text-white" }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: initial })
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// src/agent-identity/AgentLabel/AgentLabel.tsx
|
|
53
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
54
|
+
function AgentLabel({ agent, className }) {
|
|
55
|
+
const accent = agent.accent ?? "#6366f1";
|
|
56
|
+
return /* @__PURE__ */ jsxs(
|
|
57
|
+
"span",
|
|
58
|
+
{
|
|
59
|
+
className: `text-xs font-medium ${className ?? ""}`,
|
|
60
|
+
"data-testid": "agent-label",
|
|
61
|
+
children: [
|
|
62
|
+
"Answered by",
|
|
63
|
+
" ",
|
|
64
|
+
/* @__PURE__ */ jsx2("span", { style: { color: accent }, children: agent.label })
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// src/agent-identity/AgentHandoff/AgentHandoff.tsx
|
|
71
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
72
|
+
function AgentHandoff({ from, to, className }) {
|
|
73
|
+
return /* @__PURE__ */ jsxs2(
|
|
74
|
+
"div",
|
|
75
|
+
{
|
|
76
|
+
className: `flex items-center gap-3 px-4 py-3 rounded-xl border border-border bg-surface ${className ?? ""}`,
|
|
77
|
+
"data-testid": "agent-handoff",
|
|
78
|
+
children: [
|
|
79
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 animate-in fade-in slide-in-from-left-2 duration-300", children: [
|
|
80
|
+
/* @__PURE__ */ jsx3(AgentAvatar, { agent: from, size: "sm" }),
|
|
81
|
+
/* @__PURE__ */ jsx3("span", { className: "text-xs text-text-secondary", children: from.label })
|
|
82
|
+
] }),
|
|
83
|
+
/* @__PURE__ */ jsx3("span", { className: "text-text-secondary text-xs", "aria-hidden": "true", children: "\u2192" }),
|
|
84
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 animate-in fade-in slide-in-from-right-2 duration-300", children: [
|
|
85
|
+
/* @__PURE__ */ jsx3(AgentAvatar, { agent: to, size: "sm" }),
|
|
86
|
+
/* @__PURE__ */ jsx3("span", { className: "text-xs text-text-secondary", children: to.label })
|
|
87
|
+
] }),
|
|
88
|
+
/* @__PURE__ */ jsxs2("div", { className: "sr-only", role: "status", "aria-live": "polite", children: [
|
|
89
|
+
"Handing off from ",
|
|
90
|
+
from.label,
|
|
91
|
+
" to ",
|
|
92
|
+
to.label
|
|
93
|
+
] })
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// src/agent-identity/RoutingIndicator/RoutingIndicator.tsx
|
|
100
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
101
|
+
function RoutingIndicator({ from, to, reason, className }) {
|
|
102
|
+
return /* @__PURE__ */ jsxs3(
|
|
103
|
+
"div",
|
|
104
|
+
{
|
|
105
|
+
className: `inline-flex items-center gap-1.5 rounded-md border border-border/50 bg-surface-secondary/50 px-2.5 py-1 font-mono text-[11px] text-text-secondary ${className ?? ""}`,
|
|
106
|
+
"data-testid": "routing-indicator",
|
|
107
|
+
children: [
|
|
108
|
+
/* @__PURE__ */ jsx4("span", { className: "opacity-60", children: "Routed:" }),
|
|
109
|
+
/* @__PURE__ */ jsx4("span", { children: from }),
|
|
110
|
+
/* @__PURE__ */ jsx4("span", { className: "opacity-40", "aria-hidden": "true", children: "\u2192" }),
|
|
111
|
+
/* @__PURE__ */ jsx4("span", { children: to }),
|
|
112
|
+
reason && /* @__PURE__ */ jsxs3("span", { className: "opacity-50 ml-1", title: reason, children: [
|
|
113
|
+
"(",
|
|
114
|
+
reason,
|
|
115
|
+
")"
|
|
116
|
+
] })
|
|
117
|
+
]
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
export {
|
|
122
|
+
AgentAvatar,
|
|
123
|
+
AgentHandoff,
|
|
124
|
+
AgentLabel,
|
|
125
|
+
RoutingIndicator
|
|
126
|
+
};
|
|
127
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/useAgentTheme.ts","../../src/agent-identity/AgentAvatar/AgentAvatar.tsx","../../src/agent-identity/AgentLabel/AgentLabel.tsx","../../src/agent-identity/AgentHandoff/AgentHandoff.tsx","../../src/agent-identity/RoutingIndicator/RoutingIndicator.tsx"],"sourcesContent":["import { useMemo } from 'react'\nimport type { AgentInfo } from '../types/agent'\n\nexport interface AgentThemeResult {\n accent: string\n icon: AgentInfo['icon'] | null\n label: string\n}\n\nconst DEFAULT_ACCENT = '#6366f1'\nconst DEFAULT_LABEL = 'Agent'\n\nexport function useAgentTheme(\n agentId: string | null | undefined,\n agentThemes?: Record<string, AgentInfo>,\n): AgentThemeResult {\n return useMemo(() => {\n if (!agentId) {\n return { accent: DEFAULT_ACCENT, icon: null, label: DEFAULT_LABEL }\n }\n\n const theme = agentThemes?.[agentId]\n if (!theme) {\n return { accent: DEFAULT_ACCENT, icon: null, label: agentId }\n }\n\n return {\n accent: theme.accent ?? DEFAULT_ACCENT,\n icon: theme.icon ?? null,\n label: theme.label,\n }\n }, [agentId, agentThemes])\n}\n","import React from 'react'\nimport type { AgentInfo } from '../../types/agent'\nimport { useAgentTheme } from '../../hooks/useAgentTheme'\n\nexport type AgentAvatarProps = {\n agentId?: string\n agent?: AgentInfo\n size?: 'sm' | 'md' | 'lg'\n agentThemes?: Record<string, AgentInfo>\n className?: string\n}\n\nconst sizeMap = {\n sm: 'h-6 w-6 text-xs',\n md: 'h-8 w-8 text-sm',\n lg: 'h-10 w-10 text-base',\n} as const\n\nconst iconSizeMap = {\n sm: 14,\n md: 18,\n lg: 22,\n} as const\n\nfunction AgentAvatar({ agentId, agent, size = 'md', agentThemes, className }: AgentAvatarProps) {\n const resolvedId = agent?.id ?? agentId ?? null\n const themes = agent ? { ...agentThemes, [agent.id]: agent } : agentThemes\n const { accent, icon: Icon, label } = useAgentTheme(resolvedId, themes)\n\n const initial = label.charAt(0).toUpperCase()\n\n return (\n <div\n className={`inline-flex items-center justify-center rounded-full shrink-0 font-medium text-white ${sizeMap[size]} ${className ?? ''}`}\n style={{ backgroundColor: accent }}\n role=\"img\"\n aria-label={`${label} avatar`}\n data-testid=\"agent-avatar\"\n >\n {Icon ? (\n <Icon size={iconSizeMap[size]} className=\"text-white\" />\n ) : (\n <span aria-hidden=\"true\">{initial}</span>\n )}\n </div>\n )\n}\n\nexport { AgentAvatar }\n","import React from 'react'\nimport type { AgentInfo } from '../../types/agent'\n\nexport type AgentLabelProps = {\n agent: AgentInfo\n className?: string\n}\n\nfunction AgentLabel({ agent, className }: AgentLabelProps) {\n const accent = agent.accent ?? '#6366f1'\n\n return (\n <span\n className={`text-xs font-medium ${className ?? ''}`}\n data-testid=\"agent-label\"\n >\n Answered by{' '}\n <span style={{ color: accent }}>{agent.label}</span>\n </span>\n )\n}\n\nexport { AgentLabel }\n","import React from 'react'\nimport type { AgentInfo } from '../../types/agent'\nimport { AgentAvatar } from '../AgentAvatar'\n\nexport type AgentHandoffProps = {\n from: AgentInfo\n to: AgentInfo\n className?: string\n}\n\nfunction AgentHandoff({ from, to, className }: AgentHandoffProps) {\n return (\n <div\n className={`flex items-center gap-3 px-4 py-3 rounded-xl border border-border bg-surface ${className ?? ''}`}\n data-testid=\"agent-handoff\"\n >\n <div className=\"flex items-center gap-2 animate-in fade-in slide-in-from-left-2 duration-300\">\n <AgentAvatar agent={from} size=\"sm\" />\n <span className=\"text-xs text-text-secondary\">{from.label}</span>\n </div>\n\n <span className=\"text-text-secondary text-xs\" aria-hidden=\"true\">{'\\u2192'}</span>\n\n <div className=\"flex items-center gap-2 animate-in fade-in slide-in-from-right-2 duration-300\">\n <AgentAvatar agent={to} size=\"sm\" />\n <span className=\"text-xs text-text-secondary\">{to.label}</span>\n </div>\n\n <div className=\"sr-only\" role=\"status\" aria-live=\"polite\">\n Handing off from {from.label} to {to.label}\n </div>\n </div>\n )\n}\n\nexport { AgentHandoff }\n","import React from 'react'\n\nexport type RoutingIndicatorProps = {\n from: string\n to: string\n reason?: string\n className?: string\n}\n\nfunction RoutingIndicator({ from, to, reason, className }: RoutingIndicatorProps) {\n return (\n <div\n className={`inline-flex items-center gap-1.5 rounded-md border border-border/50 bg-surface-secondary/50 px-2.5 py-1 font-mono text-[11px] text-text-secondary ${className ?? ''}`}\n data-testid=\"routing-indicator\"\n >\n <span className=\"opacity-60\">Routed:</span>\n <span>{from}</span>\n <span className=\"opacity-40\" aria-hidden=\"true\">{'\\u2192'}</span>\n <span>{to}</span>\n {reason && (\n <span className=\"opacity-50 ml-1\" title={reason}>\n ({reason})\n </span>\n )}\n </div>\n )\n}\n\nexport { RoutingIndicator }\n"],"mappings":"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","names":["jsx","jsx","jsxs","jsx","jsxs"]}
|