ai-agent-book 精选快照(<2MB 代码与文档,来自 github.com/bojieli/ai-agent-book)
Build latest book artifacts / build (push) Canceled after 0s
dependency resolution / resolve (3.11) (push) Canceled after 0s
dependency resolution / resolve (3.13) (push) Canceled after 0s
deploy-pages / build (push) Canceled after 0s
deploy-pages / deploy (push) Canceled after 0s
i18n consistency check / check (push) Canceled after 0s
provider adoption tests / test (chapter2/context-compression) (push) Canceled after 0s
provider adoption tests / test (chapter2/prompt-injection) (push) Canceled after 0s
provider adoption tests / test (chapter2/system-hint) (push) Canceled after 0s
provider adoption tests / test (chapter3/log-sanitization) (push) Canceled after 0s
web-search-agent tests / test (push) Canceled after 0s
web-search-agent tests / agentbook (push) Canceled after 0s
Build latest book artifacts / build (push) Canceled after 0s
dependency resolution / resolve (3.11) (push) Canceled after 0s
dependency resolution / resolve (3.13) (push) Canceled after 0s
deploy-pages / build (push) Canceled after 0s
deploy-pages / deploy (push) Canceled after 0s
i18n consistency check / check (push) Canceled after 0s
provider adoption tests / test (chapter2/context-compression) (push) Canceled after 0s
provider adoption tests / test (chapter2/prompt-injection) (push) Canceled after 0s
provider adoption tests / test (chapter2/system-hint) (push) Canceled after 0s
provider adoption tests / test (chapter3/log-sanitization) (push) Canceled after 0s
web-search-agent tests / test (push) Canceled after 0s
web-search-agent tests / agentbook (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
import { useState } from "react";
|
||||
|
||||
// ===========================================================================
|
||||
// 基础 chatbot 界面。
|
||||
// 这是一个"可被自然语言定制"的最小 React 应用:
|
||||
// - 标题文案、按钮文字等 UI 文本都写在这里(Agent 可按需求改文案);
|
||||
// - 颜色、字体、布局等样式集中在 theme.css(Agent 可按需求改样式)。
|
||||
// 用户在对话中说"把发送按钮改成蓝色 / 换成等宽字体 / 标题改成 XXX",
|
||||
// Agent 会定位并修改这些源码文件,Vite HMR 让改动即时生效。
|
||||
// ===========================================================================
|
||||
|
||||
// UI 文案(Agent 定制"文案"需求时修改这里)
|
||||
const HEADER_TITLE = "智能助手";
|
||||
const HEADER_SUBTITLE = "有什么可以帮你的吗?";
|
||||
const SEND_BUTTON_LABEL = "发送";
|
||||
|
||||
export default function App() {
|
||||
const [messages, setMessages] = useState([
|
||||
{ role: "assistant", text: "你好!我是你的智能助手,随时为你服务。" },
|
||||
]);
|
||||
const [input, setInput] = useState("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
async function handleSend() {
|
||||
const text = input.trim();
|
||||
if (!text || loading) return;
|
||||
setMessages((m) => [...m, { role: "user", text }]);
|
||||
setInput("");
|
||||
setLoading(true);
|
||||
try {
|
||||
const resp = await fetch("/api/chat", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ message: text }),
|
||||
});
|
||||
const data = await resp.json();
|
||||
setMessages((m) => [...m, { role: "assistant", text: data.reply }]);
|
||||
} catch (e) {
|
||||
setMessages((m) => [
|
||||
...m,
|
||||
{ role: "assistant", text: "(后端未连接,这是本地占位回复)" },
|
||||
]);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="app">
|
||||
<header className="header">
|
||||
<h1 className="header-title">{HEADER_TITLE}</h1>
|
||||
<p className="header-subtitle">{HEADER_SUBTITLE}</p>
|
||||
</header>
|
||||
|
||||
<main className="chat-window">
|
||||
{messages.map((m, i) => (
|
||||
<div key={i} className={`bubble bubble-${m.role}`}>
|
||||
{m.text}
|
||||
</div>
|
||||
))}
|
||||
{loading && <div className="bubble bubble-assistant">思考中…</div>}
|
||||
</main>
|
||||
|
||||
<footer className="composer">
|
||||
<input
|
||||
className="composer-input"
|
||||
value={input}
|
||||
placeholder="输入消息…"
|
||||
onChange={(e) => setInput(e.target.value)}
|
||||
onKeyDown={(e) => e.key === "Enter" && handleSend()}
|
||||
/>
|
||||
<button className="send-button" onClick={handleSend}>
|
||||
{SEND_BUTTON_LABEL}
|
||||
</button>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import App from "./App.jsx";
|
||||
import "./theme.css";
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")).render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>
|
||||
);
|
||||
@@ -0,0 +1,108 @@
|
||||
/* ==========================================================================
|
||||
主题样式表(Agent 定制"颜色 / 字体 / 布局"需求时修改这里)
|
||||
为方便自然语言定制,关键视觉变量集中在 :root 里。
|
||||
========================================================================== */
|
||||
:root {
|
||||
--color-primary: #16a34a; /* 主色(发送按钮、用户气泡)——初始为绿色 */
|
||||
--color-primary-text: #ffffff; /* 主色上的文字颜色 */
|
||||
--color-bg: #f5f5f5; /* 页面背景 */
|
||||
--color-panel: #ffffff; /* 面板/卡片背景 */
|
||||
--color-text: #1f2937; /* 正文文字 */
|
||||
--font-family: system-ui, "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
--radius: 12px;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background: var(--color-bg);
|
||||
color: var(--color-text);
|
||||
font-family: var(--font-family);
|
||||
}
|
||||
|
||||
.app {
|
||||
max-width: 640px;
|
||||
margin: 0 auto;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: var(--color-panel);
|
||||
}
|
||||
|
||||
.header {
|
||||
padding: 20px 24px;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
margin: 0;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.header-subtitle {
|
||||
margin: 4px 0 0;
|
||||
font-size: 13px;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.chat-window {
|
||||
flex: 1;
|
||||
padding: 20px 24px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.bubble {
|
||||
max-width: 75%;
|
||||
padding: 10px 14px;
|
||||
border-radius: var(--radius);
|
||||
line-height: 1.5;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.bubble-assistant {
|
||||
align-self: flex-start;
|
||||
background: #eef2f5;
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.bubble-user {
|
||||
align-self: flex-end;
|
||||
background: var(--color-primary);
|
||||
color: var(--color-primary-text);
|
||||
}
|
||||
|
||||
.composer {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
padding: 16px 24px;
|
||||
border-top: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.composer-input {
|
||||
flex: 1;
|
||||
padding: 10px 12px;
|
||||
border: 1px solid #d1d5db;
|
||||
border-radius: var(--radius);
|
||||
font-size: 14px;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.send-button {
|
||||
padding: 10px 20px;
|
||||
border: none;
|
||||
border-radius: var(--radius);
|
||||
background: var(--color-primary);
|
||||
color: var(--color-primary-text);
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.send-button:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
Reference in New Issue
Block a user