@agent-native/core 0.207.0-nightly-20261011124220 → 0.207.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/dist/agent/production-agent.js +23 -6
- package/dist/agent/thread-data-builder.js +7 -4
- package/dist/cli/eval.js +20 -4
- package/dist/client/analytics/index.d.ts +1 -1
- package/dist/client/analytics.d.ts +12 -3
- package/dist/client/analytics.js +51 -17
- package/dist/client/onboarding/use-onboarding.d.ts +1 -0
- package/dist/client/onboarding/use-onboarding.js +19 -6
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/eval/agent-runner.js +18 -8
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/mcp/connect-route.js +9 -4
- package/dist/observability/routes.d.ts +7 -7
- package/dist/onboarding/plugin.js +15 -45
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/store.js +25 -30
- package/dist/server/agent-discovery.js +47 -53
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-engine-ollama-models-route.d.ts +2 -2
- package/dist/server/builtin-agents.d.ts +2 -0
- package/dist/server/builtin-agents.js +50 -3
- package/dist/server/credential-provider.d.ts +6 -9
- package/dist/server/credential-provider.js +33 -21
- package/dist/templates/builder-code-starter/.agents/skills/adding-a-feature/SKILL.md.patch +1 -1
- package/dist/templates/builder-code-starter/AGENTS.md.patch +3 -3
- package/dist/templates/builder-code-starter/app/components/layout/Layout.tsx.patch +6 -7
- package/dist/templates/builder-code-starter/app/hooks/use-navigation-state.ts.patch +21 -28
- package/dist/templates/builder-code-starter/app/root.tsx.patch +16 -5
- package/dist/templates/builder-code-starter/template-layer.json +4 -0
- package/dist/templates/chat/.agents/skills/secrets/SKILL.md +6 -2
- package/dist/templates/chat/AGENTS.md +3 -3
- package/dist/templates/chat/CHANGELOG.md +6 -0
- package/dist/templates/chat/app/components/chat/ChatHomeRedirect.tsx +25 -0
- package/dist/templates/chat/app/components/chat/ChatRouteContent.tsx +828 -15
- package/dist/templates/chat/app/components/home/HomePage.tsx +332 -0
- package/dist/templates/chat/app/components/layout/AgentInspector.tsx +2 -4
- package/dist/templates/chat/app/components/layout/Header.tsx +1 -1
- package/dist/templates/chat/app/components/layout/Layout.tsx +5 -6
- package/dist/templates/chat/app/components/layout/Sidebar.tsx +35 -11
- package/dist/templates/chat/app/components/ui/item.tsx +1 -0
- package/dist/templates/chat/app/components/ui/separator.tsx +1 -0
- package/dist/templates/chat/app/components/ui/skeleton.tsx +1 -0
- package/dist/templates/chat/app/hooks/use-navigation-state.ts +16 -22
- package/dist/templates/chat/app/i18n/ar-SA.ts +25 -0
- package/dist/templates/chat/app/i18n/de-DE.ts +26 -0
- package/dist/templates/chat/app/i18n/en-US.ts +25 -0
- package/dist/templates/chat/app/i18n/es-ES.ts +26 -0
- package/dist/templates/chat/app/i18n/fr-FR.ts +26 -0
- package/dist/templates/chat/app/i18n/hi-IN.ts +26 -0
- package/dist/templates/chat/app/i18n/ja-JP.ts +26 -0
- package/dist/templates/chat/app/i18n/ko-KR.ts +26 -0
- package/dist/templates/chat/app/i18n/pt-BR.ts +26 -0
- package/dist/templates/chat/app/i18n/zh-CN.ts +25 -0
- package/dist/templates/chat/app/i18n/zh-TW.ts +25 -0
- package/dist/templates/chat/app/lib/chat-paths.ts +479 -0
- package/dist/templates/chat/app/root.tsx +14 -3
- package/dist/templates/chat/app/routes/chat._index.tsx +5 -0
- package/dist/templates/chat/app/routes/home.tsx +3 -22
- package/dist/templates/chat/changelog/2026-10-10-home-handoff-recovery-capacity.md +6 -0
- package/dist/templates/default/.agents/skills/secrets/SKILL.md +6 -2
- package/dist/templates/headless/.agents/skills/secrets/SKILL.md +6 -2
- package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +6 -2
- package/dist/triggers/actions/manage-automation.d.ts +2 -2
- package/docs/content/deployment-environment-variables.mdx +10 -10
- package/docs/content/environment-variables.mdx +38 -6
- package/docs/content/getting-started.mdx +7 -7
- package/docs/content/multi-app-workspace.mdx +7 -3
- package/docs/content/template-chat-first-edits.mdx +46 -33
- package/package.json +4 -4
- package/src/templates/builder-code-starter/.agents/skills/adding-a-feature/SKILL.md.patch +1 -1
- package/src/templates/builder-code-starter/AGENTS.md.patch +3 -3
- package/src/templates/builder-code-starter/app/components/layout/Layout.tsx.patch +6 -7
- package/src/templates/builder-code-starter/app/hooks/use-navigation-state.ts.patch +21 -28
- package/src/templates/builder-code-starter/app/root.tsx.patch +16 -5
- package/src/templates/builder-code-starter/template-layer.json +4 -0
- package/src/templates/chat/.agents/skills/secrets/SKILL.md +6 -2
- package/src/templates/chat/AGENTS.md +3 -3
- package/src/templates/chat/CHANGELOG.md +6 -0
- package/src/templates/chat/app/components/chat/ChatHomeRedirect.tsx +25 -0
- package/src/templates/chat/app/components/chat/ChatRouteContent.tsx +828 -15
- package/src/templates/chat/app/components/home/HomePage.tsx +332 -0
- package/src/templates/chat/app/components/layout/AgentInspector.tsx +2 -4
- package/src/templates/chat/app/components/layout/Header.tsx +1 -1
- package/src/templates/chat/app/components/layout/Layout.tsx +5 -6
- package/src/templates/chat/app/components/layout/Sidebar.tsx +35 -11
- package/src/templates/chat/app/components/ui/item.tsx +1 -0
- package/src/templates/chat/app/components/ui/separator.tsx +1 -0
- package/src/templates/chat/app/components/ui/skeleton.tsx +1 -0
- package/src/templates/chat/app/hooks/use-navigation-state.ts +16 -22
- package/src/templates/chat/app/i18n/ar-SA.ts +25 -0
- package/src/templates/chat/app/i18n/de-DE.ts +26 -0
- package/src/templates/chat/app/i18n/en-US.ts +25 -0
- package/src/templates/chat/app/i18n/es-ES.ts +26 -0
- package/src/templates/chat/app/i18n/fr-FR.ts +26 -0
- package/src/templates/chat/app/i18n/hi-IN.ts +26 -0
- package/src/templates/chat/app/i18n/ja-JP.ts +26 -0
- package/src/templates/chat/app/i18n/ko-KR.ts +26 -0
- package/src/templates/chat/app/i18n/pt-BR.ts +26 -0
- package/src/templates/chat/app/i18n/zh-CN.ts +25 -0
- package/src/templates/chat/app/i18n/zh-TW.ts +25 -0
- package/src/templates/chat/app/lib/chat-paths.ts +479 -0
- package/src/templates/chat/app/root.tsx +14 -3
- package/src/templates/chat/app/routes/chat._index.tsx +5 -0
- package/src/templates/chat/app/routes/home.tsx +3 -22
- package/src/templates/chat/changelog/2026-10-10-home-handoff-recovery-capacity.md +6 -0
- package/src/templates/default/.agents/skills/secrets/SKILL.md +6 -2
- package/src/templates/headless/.agents/skills/secrets/SKILL.md +6 -2
- package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +6 -2
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
import {
|
|
2
|
+
markAgentChatHomeHandoff,
|
|
3
|
+
navigateWithAgentChatViewTransition,
|
|
4
|
+
} from "@agent-native/core/client/agent-chat";
|
|
5
|
+
import { createAgentNativeAgentKitTransport } from "@agent-native/core/client/agentkit-chat/transport";
|
|
6
|
+
import { useT } from "@agent-native/core/client/i18n";
|
|
7
|
+
import { AgentKitComposer } from "@agent-native/toolkit/app/agentkit/react/components";
|
|
8
|
+
import { useAgentKitControl } from "@agent-native/toolkit/app/agentkit/react/context";
|
|
9
|
+
import { CoreComposerRuntimeProvider } from "@agent-native/toolkit/app/chat/agentkit-chat/composer";
|
|
10
|
+
import { CoreAgentKitRoot } from "@agent-native/toolkit/app/chat/agentkit-chat/index";
|
|
11
|
+
import { WaveBackground } from "@agent-native/toolkit/app/shared";
|
|
12
|
+
import { AgentNativeIcon } from "@agent-native/toolkit/app/shared/AgentNativeIcon";
|
|
13
|
+
import {
|
|
14
|
+
IconBook,
|
|
15
|
+
IconBrandDiscord,
|
|
16
|
+
IconBrandGithub,
|
|
17
|
+
IconUsers,
|
|
18
|
+
} from "@tabler/icons-react";
|
|
19
|
+
import { Fragment, useState, type ReactNode } from "react";
|
|
20
|
+
import { useNavigate } from "react-router";
|
|
21
|
+
|
|
22
|
+
import { Button } from "@/components/ui/button";
|
|
23
|
+
import {
|
|
24
|
+
Item,
|
|
25
|
+
ItemContent,
|
|
26
|
+
ItemDescription,
|
|
27
|
+
ItemFooter,
|
|
28
|
+
ItemMedia,
|
|
29
|
+
ItemTitle,
|
|
30
|
+
} from "@/components/ui/item";
|
|
31
|
+
import { Separator } from "@/components/ui/separator";
|
|
32
|
+
import { getChatHomeThreadId } from "@/lib/chat-home-thread";
|
|
33
|
+
import {
|
|
34
|
+
chatThreadPath,
|
|
35
|
+
type ChatInitialComposerOptions,
|
|
36
|
+
type ChatRouteState,
|
|
37
|
+
} from "@/lib/chat-paths";
|
|
38
|
+
import { TAB_ID } from "@/lib/tab-id";
|
|
39
|
+
|
|
40
|
+
const DOCS_URL = "https://www.agent-native.com/docs";
|
|
41
|
+
const GITHUB_URL = "https://github.com/BuilderIO/agent-native";
|
|
42
|
+
const DISCORD_URL = "https://discord.gg/qm82StQ2NC";
|
|
43
|
+
|
|
44
|
+
const INLINE_COMPOSER_STYLE = {
|
|
45
|
+
display: "block",
|
|
46
|
+
blockSize: "auto",
|
|
47
|
+
overflow: "visible",
|
|
48
|
+
background: "transparent",
|
|
49
|
+
} as const;
|
|
50
|
+
|
|
51
|
+
const EDIT_HINT_CODE = { file: "actions/hello.ts" };
|
|
52
|
+
|
|
53
|
+
/** Placeholder values that `WithCode` swaps back out for code chips. */
|
|
54
|
+
function codeSlots(code: Record<string, string>): Record<string, string> {
|
|
55
|
+
return Object.fromEntries(
|
|
56
|
+
Object.keys(code).map((name) => [name, `\u0000${name}\u0000`]),
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function WithCode({
|
|
61
|
+
text,
|
|
62
|
+
code,
|
|
63
|
+
}: {
|
|
64
|
+
text: string;
|
|
65
|
+
code: Record<string, string>;
|
|
66
|
+
}) {
|
|
67
|
+
return (
|
|
68
|
+
<>
|
|
69
|
+
{text
|
|
70
|
+
.split(/\u0000(\w+)\u0000/)
|
|
71
|
+
.map((part, index) =>
|
|
72
|
+
index % 2 === 1 ? (
|
|
73
|
+
<CodeChip key={index}>{code[part]}</CodeChip>
|
|
74
|
+
) : (
|
|
75
|
+
<Fragment key={index}>{part}</Fragment>
|
|
76
|
+
),
|
|
77
|
+
)}
|
|
78
|
+
</>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function CodeChip({ children }: { children: ReactNode }) {
|
|
83
|
+
return (
|
|
84
|
+
<code className="whitespace-nowrap rounded-md bg-muted px-1.5 py-0.5 font-mono text-[0.9em] text-foreground">
|
|
85
|
+
{children}
|
|
86
|
+
</code>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The same AgentKit composer the chat page uses, so Connect AI and the model
|
|
92
|
+
* picker look the way they will in chat. Submitting hands the prompt to the
|
|
93
|
+
* full chat page instead of running it here.
|
|
94
|
+
*/
|
|
95
|
+
function HomeAgentComposer() {
|
|
96
|
+
const navigate = useNavigate();
|
|
97
|
+
const [threadId] = useState(getChatHomeThreadId);
|
|
98
|
+
const [mode, setMode] = useState<"act" | "plan">("act");
|
|
99
|
+
const [transport] = useState(() =>
|
|
100
|
+
createAgentNativeAgentKitTransport({
|
|
101
|
+
browserTabId: TAB_ID,
|
|
102
|
+
surface: "app",
|
|
103
|
+
adapter: { textFormat: "markdown" },
|
|
104
|
+
}),
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
function openChat(
|
|
108
|
+
message: string,
|
|
109
|
+
options: ChatInitialComposerOptions,
|
|
110
|
+
onLocalSubmit?: () => void,
|
|
111
|
+
) {
|
|
112
|
+
const state: ChatRouteState = {
|
|
113
|
+
initialMessage: message,
|
|
114
|
+
initialComposerOptions: options,
|
|
115
|
+
};
|
|
116
|
+
markAgentChatHomeHandoff("chat");
|
|
117
|
+
navigateWithAgentChatViewTransition(navigate, chatThreadPath(threadId), {
|
|
118
|
+
state,
|
|
119
|
+
});
|
|
120
|
+
onLocalSubmit?.();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return (
|
|
124
|
+
// `agentkit-chat` carries the page composer's sizing tokens. Its stylesheet
|
|
125
|
+
// is unlayered, so Tailwind utilities can't undo the transcript canvas
|
|
126
|
+
// (background, full-height grid); only inline styles win here.
|
|
127
|
+
<div
|
|
128
|
+
className="agentkit-chat w-full max-w-2xl text-start"
|
|
129
|
+
style={INLINE_COMPOSER_STYLE}
|
|
130
|
+
>
|
|
131
|
+
<div className="agentkit-composer-stack">
|
|
132
|
+
<CoreComposerRuntimeProvider>
|
|
133
|
+
<CoreAgentKitRoot
|
|
134
|
+
transport={transport}
|
|
135
|
+
clientOptions={{ transportOwnership: "owned" }}
|
|
136
|
+
threadId={threadId}
|
|
137
|
+
>
|
|
138
|
+
<HomeAgentComposerInput
|
|
139
|
+
threadId={threadId}
|
|
140
|
+
mode={mode}
|
|
141
|
+
onModeChange={setMode}
|
|
142
|
+
onSubmit={openChat}
|
|
143
|
+
/>
|
|
144
|
+
</CoreAgentKitRoot>
|
|
145
|
+
</CoreComposerRuntimeProvider>
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function HomeAgentComposerInput({
|
|
152
|
+
threadId,
|
|
153
|
+
mode,
|
|
154
|
+
onModeChange,
|
|
155
|
+
onSubmit,
|
|
156
|
+
}: {
|
|
157
|
+
threadId: string;
|
|
158
|
+
mode: "act" | "plan";
|
|
159
|
+
onModeChange: (mode: "act" | "plan") => void;
|
|
160
|
+
onSubmit: (
|
|
161
|
+
text: string,
|
|
162
|
+
options: ChatInitialComposerOptions,
|
|
163
|
+
onLocalSubmit?: () => void,
|
|
164
|
+
) => void;
|
|
165
|
+
}) {
|
|
166
|
+
const t = useT();
|
|
167
|
+
const control = useAgentKitControl(threadId);
|
|
168
|
+
|
|
169
|
+
return (
|
|
170
|
+
<AgentKitComposer
|
|
171
|
+
threadId={threadId}
|
|
172
|
+
requireAgentEngine
|
|
173
|
+
placeholder={t("home.composerPlaceholder")}
|
|
174
|
+
plusMenuMode="hidden"
|
|
175
|
+
attachmentsEnabled={false}
|
|
176
|
+
mode={mode}
|
|
177
|
+
onModeChange={onModeChange}
|
|
178
|
+
voiceEnabled
|
|
179
|
+
onSubmit={async (text, files, references, options) => {
|
|
180
|
+
const uploadedAttachments = files.length
|
|
181
|
+
? await control.uploadFiles(
|
|
182
|
+
files.map((file) => ({
|
|
183
|
+
name: file.name,
|
|
184
|
+
mediaType: file.type || "application/octet-stream",
|
|
185
|
+
size: file.size,
|
|
186
|
+
body: file,
|
|
187
|
+
})),
|
|
188
|
+
)
|
|
189
|
+
: [];
|
|
190
|
+
const {
|
|
191
|
+
onLocalSubmit: clearLocalDraft,
|
|
192
|
+
attachments: _rawAttachments,
|
|
193
|
+
...submitOptions
|
|
194
|
+
} = options;
|
|
195
|
+
onSubmit(
|
|
196
|
+
text,
|
|
197
|
+
{
|
|
198
|
+
...submitOptions,
|
|
199
|
+
mode,
|
|
200
|
+
references,
|
|
201
|
+
...(uploadedAttachments.length ? { uploadedAttachments } : {}),
|
|
202
|
+
},
|
|
203
|
+
clearLocalDraft,
|
|
204
|
+
);
|
|
205
|
+
}}
|
|
206
|
+
/>
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function ResourceLink({
|
|
211
|
+
href,
|
|
212
|
+
icon,
|
|
213
|
+
children,
|
|
214
|
+
}: {
|
|
215
|
+
href: string;
|
|
216
|
+
icon?: ReactNode;
|
|
217
|
+
children: ReactNode;
|
|
218
|
+
}) {
|
|
219
|
+
return (
|
|
220
|
+
<Button asChild variant="outline" size="sm">
|
|
221
|
+
<a href={href} target="_blank" rel="noreferrer">
|
|
222
|
+
{icon}
|
|
223
|
+
{children}
|
|
224
|
+
</a>
|
|
225
|
+
</Button>
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function ResourceColumn({
|
|
230
|
+
icon,
|
|
231
|
+
title,
|
|
232
|
+
description,
|
|
233
|
+
children,
|
|
234
|
+
}: {
|
|
235
|
+
icon: ReactNode;
|
|
236
|
+
title: string;
|
|
237
|
+
description?: string;
|
|
238
|
+
children: ReactNode;
|
|
239
|
+
}) {
|
|
240
|
+
return (
|
|
241
|
+
<Item asChild className="px-6 py-8 sm:px-10">
|
|
242
|
+
<section>
|
|
243
|
+
<ItemMedia variant="icon">{icon}</ItemMedia>
|
|
244
|
+
<ItemContent>
|
|
245
|
+
<ItemTitle role="heading" aria-level={2}>
|
|
246
|
+
{title}
|
|
247
|
+
</ItemTitle>
|
|
248
|
+
{description ? (
|
|
249
|
+
<ItemDescription>{description}</ItemDescription>
|
|
250
|
+
) : null}
|
|
251
|
+
</ItemContent>
|
|
252
|
+
<ItemFooter className="flex-wrap justify-start">{children}</ItemFooter>
|
|
253
|
+
</section>
|
|
254
|
+
</Item>
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export default function HomePage() {
|
|
259
|
+
const t = useT();
|
|
260
|
+
|
|
261
|
+
return (
|
|
262
|
+
<div className="flex min-h-full flex-col">
|
|
263
|
+
<section className="relative isolate flex flex-1 flex-col items-center justify-center gap-6 overflow-hidden px-4 py-16 text-center">
|
|
264
|
+
<WaveBackground className="pointer-events-none absolute inset-0 -z-10" />
|
|
265
|
+
<AgentNativeIcon
|
|
266
|
+
aria-hidden="true"
|
|
267
|
+
className="h-8 w-14 text-foreground"
|
|
268
|
+
/>
|
|
269
|
+
<div className="flex flex-col items-center gap-3">
|
|
270
|
+
<h1 className="text-4xl font-semibold tracking-tight sm:text-5xl">
|
|
271
|
+
{t("home.title")}
|
|
272
|
+
</h1>
|
|
273
|
+
<p className="max-w-xl text-base text-muted-foreground">
|
|
274
|
+
<span className="block">{t("home.lead")}</span>
|
|
275
|
+
<span className="block">{t("home.leadTry")}</span>
|
|
276
|
+
</p>
|
|
277
|
+
</div>
|
|
278
|
+
<HomeAgentComposer />
|
|
279
|
+
<p className="max-w-lg text-sm text-muted-foreground">
|
|
280
|
+
<WithCode
|
|
281
|
+
text={t("home.editHint", codeSlots(EDIT_HINT_CODE))}
|
|
282
|
+
code={EDIT_HINT_CODE}
|
|
283
|
+
/>
|
|
284
|
+
</p>
|
|
285
|
+
<Button asChild variant="link" size="sm" className="h-auto px-0">
|
|
286
|
+
<a
|
|
287
|
+
href={`${DOCS_URL}/environment-variables#llm-provider-keys`}
|
|
288
|
+
target="_blank"
|
|
289
|
+
rel="noreferrer"
|
|
290
|
+
>
|
|
291
|
+
{t("home.llmSetupLink")}
|
|
292
|
+
</a>
|
|
293
|
+
</Button>
|
|
294
|
+
</section>
|
|
295
|
+
|
|
296
|
+
<Separator />
|
|
297
|
+
<div className="grid md:grid-cols-[1fr_auto_1fr]">
|
|
298
|
+
<ResourceColumn
|
|
299
|
+
icon={<IconBook />}
|
|
300
|
+
title={t("home.docsTitle")}
|
|
301
|
+
description={t("home.docsDescription")}
|
|
302
|
+
>
|
|
303
|
+
<ResourceLink href={`${DOCS_URL}/getting-started`}>
|
|
304
|
+
{t("home.docsGettingStarted")}
|
|
305
|
+
</ResourceLink>
|
|
306
|
+
<ResourceLink href={`${DOCS_URL}/getting-started-actions`}>
|
|
307
|
+
{t("home.docsAddAction")}
|
|
308
|
+
</ResourceLink>
|
|
309
|
+
<ResourceLink href={`${DOCS_URL}/getting-started-pages`}>
|
|
310
|
+
{t("home.docsAddPage")}
|
|
311
|
+
</ResourceLink>
|
|
312
|
+
<ResourceLink href={`${DOCS_URL}/key-concepts`}>
|
|
313
|
+
{t("home.docsKeyConcepts")}
|
|
314
|
+
</ResourceLink>
|
|
315
|
+
</ResourceColumn>
|
|
316
|
+
<Separator orientation="vertical" className="hidden md:block" />
|
|
317
|
+
<ResourceColumn
|
|
318
|
+
icon={<IconUsers />}
|
|
319
|
+
title={t("home.communityTitle")}
|
|
320
|
+
description={t("home.communityDescription")}
|
|
321
|
+
>
|
|
322
|
+
<ResourceLink href={GITHUB_URL} icon={<IconBrandGithub />}>
|
|
323
|
+
GitHub
|
|
324
|
+
</ResourceLink>
|
|
325
|
+
<ResourceLink href={DISCORD_URL} icon={<IconBrandDiscord />}>
|
|
326
|
+
Discord
|
|
327
|
+
</ResourceLink>
|
|
328
|
+
</ResourceColumn>
|
|
329
|
+
</div>
|
|
330
|
+
</div>
|
|
331
|
+
);
|
|
332
|
+
}
|
|
@@ -5,6 +5,7 @@ import { AgentSidebar } from "@agent-native/toolkit/app/chat";
|
|
|
5
5
|
import { type ReactNode } from "react";
|
|
6
6
|
import { useNavigate } from "react-router";
|
|
7
7
|
|
|
8
|
+
import { chatThreadPath } from "@/lib/chat-paths";
|
|
8
9
|
import { TAB_ID } from "@/lib/tab-id";
|
|
9
10
|
|
|
10
11
|
interface AgentInspectorProps {
|
|
@@ -24,10 +25,7 @@ export function AgentInspector({
|
|
|
24
25
|
|
|
25
26
|
function openAskAgentFullscreen(threadId?: string) {
|
|
26
27
|
focusAgentChat();
|
|
27
|
-
navigateWithAgentChatViewTransition(
|
|
28
|
-
navigate,
|
|
29
|
-
threadId ? `/chat/${encodeURIComponent(threadId)}` : "/home",
|
|
30
|
-
);
|
|
28
|
+
navigateWithAgentChatViewTransition(navigate, chatThreadPath(threadId));
|
|
31
29
|
}
|
|
32
30
|
|
|
33
31
|
return (
|
|
@@ -10,7 +10,7 @@ import { useLocation } from "react-router";
|
|
|
10
10
|
import { APP_TITLE } from "@/lib/app-config";
|
|
11
11
|
|
|
12
12
|
const pageTitleKeys: Record<string, string> = {
|
|
13
|
-
"/home": "navigation.
|
|
13
|
+
"/home": "navigation.home",
|
|
14
14
|
"/observability": "navigation.observability",
|
|
15
15
|
"/agent": "settings.agentTitle",
|
|
16
16
|
"/settings": "navigation.settings",
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
SheetTitle,
|
|
19
19
|
} from "@/components/ui/sheet";
|
|
20
20
|
import { APP_TITLE } from "@/lib/app-config";
|
|
21
|
+
import { HOME_PATH, isChatPathname } from "@/lib/chat-paths";
|
|
21
22
|
|
|
22
23
|
import { Sidebar } from "./Sidebar";
|
|
23
24
|
|
|
@@ -38,8 +39,8 @@ const SIDEBAR_COLLAPSE_KEY = "chat.sidebar.collapsed";
|
|
|
38
39
|
|
|
39
40
|
function routeOwnsToolbar(pathname: string): boolean {
|
|
40
41
|
return (
|
|
41
|
-
pathname ===
|
|
42
|
-
pathname
|
|
42
|
+
pathname === HOME_PATH ||
|
|
43
|
+
isChatPathname(pathname) ||
|
|
43
44
|
pathname === "/database" ||
|
|
44
45
|
pathname.startsWith("/extensions")
|
|
45
46
|
);
|
|
@@ -50,8 +51,7 @@ export function Layout({ children }: LayoutProps) {
|
|
|
50
51
|
const t = useT();
|
|
51
52
|
const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false);
|
|
52
53
|
const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
|
|
53
|
-
const isChatRoute =
|
|
54
|
-
location.pathname === "/home" || location.pathname.startsWith("/chat/");
|
|
54
|
+
const isChatRoute = isChatPathname(location.pathname);
|
|
55
55
|
// Settings brings its own navigation, header, and agent toggle, so it
|
|
56
56
|
// renders full width.
|
|
57
57
|
const settingsOwnsChrome = isSettingsPathname(location.pathname);
|
|
@@ -63,8 +63,7 @@ export function Layout({ children }: LayoutProps) {
|
|
|
63
63
|
const chatHomeHandoffPending = isAgentChatHomeHandoffActive("chat");
|
|
64
64
|
useAgentChatHomeHandoffLinks({
|
|
65
65
|
storageKey: "chat",
|
|
66
|
-
isChatPath:
|
|
67
|
-
pathname === "/home" || pathname.startsWith("/chat/"),
|
|
66
|
+
isChatPath: isChatPathname,
|
|
68
67
|
requireActiveHandoff: true,
|
|
69
68
|
});
|
|
70
69
|
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
IconApps,
|
|
18
18
|
IconClock,
|
|
19
19
|
IconEdit,
|
|
20
|
+
IconHome,
|
|
20
21
|
IconLayoutSidebarLeftCollapse,
|
|
21
22
|
IconLayoutSidebarLeftExpand,
|
|
22
23
|
IconLoader2,
|
|
@@ -39,6 +40,7 @@ import {
|
|
|
39
40
|
TooltipTrigger,
|
|
40
41
|
} from "@/components/ui/tooltip";
|
|
41
42
|
import { APP_TITLE } from "@/lib/app-config";
|
|
43
|
+
import { chatThreadPath, HOME_PATH, threadIdFromPath } from "@/lib/chat-paths";
|
|
42
44
|
import { visibleChatThreads } from "@/lib/sidebar-thread-state";
|
|
43
45
|
import { cn } from "@/lib/utils";
|
|
44
46
|
|
|
@@ -237,19 +239,40 @@ function persistActiveThreadId(threadId: string) {
|
|
|
237
239
|
} catch {}
|
|
238
240
|
}
|
|
239
241
|
|
|
240
|
-
function
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
242
|
+
function HomeNavLink({ collapsed }: { collapsed: boolean }) {
|
|
243
|
+
const t = useT();
|
|
244
|
+
const location = useLocation();
|
|
245
|
+
const active = location.pathname === HOME_PATH;
|
|
246
|
+
const link = (
|
|
247
|
+
<Link
|
|
248
|
+
to={HOME_PATH}
|
|
249
|
+
aria-current={active ? "page" : undefined}
|
|
250
|
+
aria-label={collapsed ? t("navigation.home") : undefined}
|
|
251
|
+
className={cn(
|
|
252
|
+
"flex items-center text-sidebar-accent-foreground transition-colors hover:bg-sidebar-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sidebar-ring",
|
|
253
|
+
active && "bg-sidebar-accent",
|
|
254
|
+
collapsed
|
|
255
|
+
? "size-10 justify-center rounded-md"
|
|
256
|
+
: "h-10 w-full gap-3 rounded-lg px-3 text-sm font-medium",
|
|
257
|
+
)}
|
|
258
|
+
>
|
|
259
|
+
<IconHome className="size-4 shrink-0" strokeWidth={1.8} />
|
|
260
|
+
<span className={collapsed ? "sr-only" : "truncate"}>
|
|
261
|
+
{t("navigation.home")}
|
|
262
|
+
</span>
|
|
263
|
+
</Link>
|
|
264
|
+
);
|
|
265
|
+
|
|
266
|
+
if (collapsed) {
|
|
267
|
+
return (
|
|
268
|
+
<Tooltip>
|
|
269
|
+
<TooltipTrigger asChild>{link}</TooltipTrigger>
|
|
270
|
+
<TooltipContent side="right">{t("navigation.home")}</TooltipContent>
|
|
271
|
+
</Tooltip>
|
|
272
|
+
);
|
|
248
273
|
}
|
|
249
|
-
}
|
|
250
274
|
|
|
251
|
-
|
|
252
|
-
return `/chat/${encodeURIComponent(threadId)}`;
|
|
275
|
+
return <div className="px-2">{link}</div>;
|
|
253
276
|
}
|
|
254
277
|
|
|
255
278
|
function ChatThreadsSection({ collapsed }: { collapsed: boolean }) {
|
|
@@ -540,6 +563,7 @@ export function Sidebar({
|
|
|
540
563
|
collapsed ? "items-center gap-1 px-1 py-2" : "pt-1",
|
|
541
564
|
)}
|
|
542
565
|
>
|
|
566
|
+
<HomeNavLink collapsed={collapsed} />
|
|
543
567
|
<ChatThreadsSection collapsed={collapsed} />
|
|
544
568
|
</nav>
|
|
545
569
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@agent-native/toolkit/ui/item";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@agent-native/toolkit/ui/separator";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@agent-native/toolkit/ui/skeleton";
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { appBasePath, appPath } from "@agent-native/core/client/api-path";
|
|
2
2
|
import { useAgentRouteState } from "@agent-native/core/client/navigation";
|
|
3
3
|
|
|
4
|
+
import {
|
|
5
|
+
chatThreadPath,
|
|
6
|
+
HOME_PATH,
|
|
7
|
+
isChatPathname,
|
|
8
|
+
NEW_CHAT_PATH,
|
|
9
|
+
threadIdFromPath,
|
|
10
|
+
} from "@/lib/chat-paths";
|
|
4
11
|
import { TAB_ID } from "@/lib/tab-id";
|
|
5
12
|
|
|
6
13
|
export interface NavigationState {
|
|
@@ -26,19 +33,9 @@ export function useNavigationState() {
|
|
|
26
33
|
});
|
|
27
34
|
}
|
|
28
35
|
|
|
29
|
-
function threadIdFromPath(pathname: string): string | null {
|
|
30
|
-
const match = pathname.match(/^\/chat\/([^/]+)/);
|
|
31
|
-
if (!match) return null;
|
|
32
|
-
try {
|
|
33
|
-
const value = decodeURIComponent(match[1]).trim();
|
|
34
|
-
return value || null;
|
|
35
|
-
} catch {
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
36
|
function viewForPath(pathname: string): string {
|
|
41
|
-
if (
|
|
37
|
+
if (isChatPathname(pathname)) return "chat";
|
|
38
|
+
if (pathname === HOME_PATH) return "home";
|
|
42
39
|
if (pathname.startsWith("/database")) return "database";
|
|
43
40
|
if (pathname.startsWith("/extensions")) return "extensions";
|
|
44
41
|
if (pathname.startsWith("/observability")) return "observability";
|
|
@@ -53,9 +50,10 @@ function viewForPath(pathname: string): string {
|
|
|
53
50
|
function pathForView(view?: string): string {
|
|
54
51
|
switch (view) {
|
|
55
52
|
case "chat":
|
|
56
|
-
case "home":
|
|
57
53
|
case "ask":
|
|
58
|
-
return
|
|
54
|
+
return NEW_CHAT_PATH;
|
|
55
|
+
case "home":
|
|
56
|
+
return HOME_PATH;
|
|
59
57
|
case "database":
|
|
60
58
|
return "/database";
|
|
61
59
|
case "extensions":
|
|
@@ -69,16 +67,16 @@ function pathForView(view?: string): string {
|
|
|
69
67
|
case "team":
|
|
70
68
|
return "/settings/organization";
|
|
71
69
|
default:
|
|
72
|
-
return
|
|
70
|
+
return HOME_PATH;
|
|
73
71
|
}
|
|
74
72
|
}
|
|
75
73
|
|
|
76
|
-
function pathForCommand(command: any): string {
|
|
74
|
+
export function pathForCommand(command: any): string {
|
|
77
75
|
const path = pathForView(command?.view);
|
|
78
|
-
if (
|
|
76
|
+
if (command?.view !== "chat" && command?.view !== "ask") return path;
|
|
79
77
|
const threadId =
|
|
80
78
|
typeof command?.threadId === "string" ? command.threadId.trim() : "";
|
|
81
|
-
return threadId ?
|
|
79
|
+
return threadId ? chatThreadPath(threadId) : path;
|
|
82
80
|
}
|
|
83
81
|
|
|
84
82
|
function routerPath(path: string): string {
|
|
@@ -90,7 +88,3 @@ function routerPath(path: string): string {
|
|
|
90
88
|
}
|
|
91
89
|
return path;
|
|
92
90
|
}
|
|
93
|
-
|
|
94
|
-
function isChatPath(pathname: string): boolean {
|
|
95
|
-
return pathname === "/home" || pathname.startsWith("/chat/");
|
|
96
|
-
}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
const messages = {
|
|
2
|
+
composer: {
|
|
3
|
+
removeAttachment: "إزالة {{name}}",
|
|
4
|
+
removeReference: "إزالة مرجع {{name}}",
|
|
5
|
+
},
|
|
2
6
|
settings: {
|
|
3
7
|
title: "الإعدادات",
|
|
4
8
|
workspaceTitle: "مساحة العمل",
|
|
@@ -29,6 +33,10 @@ const messages = {
|
|
|
29
33
|
pinned: "المثبتة",
|
|
30
34
|
recents: "الأخيرة",
|
|
31
35
|
retryPreviousRequest: "أعِد محاولة طلبي السابق الآن بعد توصيل مزود النموذج.",
|
|
36
|
+
invalidHandoffOptions:
|
|
37
|
+
"تم حفظ المطالبة كمسودة، لكن تعذرت استعادة إعدادات الدردشة. راجع المطالبة والسياق والنموذج قبل إرسالها مرة أخرى.",
|
|
38
|
+
recoveryDraftUnsaved:
|
|
39
|
+
"لم تُحفظ هذه التغييرات على المسودة. قد تفقدها إذا أعدت تحميل هذه المحادثة.",
|
|
32
40
|
retryAttachmentUnavailable:
|
|
33
41
|
"لا يمكن للدردشة إعادة فتح هذا المرفق لإعادة المحاولة. أضف عنوان URL يمكن الوصول إليه للملف، ثم أعد المحاولة.",
|
|
34
42
|
renameChat: "إعادة تسمية المحادثة",
|
|
@@ -40,12 +48,29 @@ const messages = {
|
|
|
40
48
|
unpinChat: "إلغاء تثبيت المحادثة",
|
|
41
49
|
untitledChat: "محادثة بلا عنوان",
|
|
42
50
|
},
|
|
51
|
+
home: {
|
|
52
|
+
communityDescription: "انضم إلى مجتمع Agent-Native",
|
|
53
|
+
composerPlaceholder: "استدعِ الإجراء hello من أجل Alex",
|
|
54
|
+
communityTitle: "تواصل معنا",
|
|
55
|
+
docsAddAction: "إضافة إجراء",
|
|
56
|
+
docsAddPage: "إضافة صفحة",
|
|
57
|
+
docsDescription: "أدلة حول الإجراءات والصفحات والوكلاء",
|
|
58
|
+
docsGettingStarted: "البدء",
|
|
59
|
+
docsKeyConcepts: "المفاهيم الأساسية",
|
|
60
|
+
docsTitle: "المستندات",
|
|
61
|
+
editHint: "عدّل {{file}} واحفظه، ثم اسأل مجددًا لترى التحية الجديدة.",
|
|
62
|
+
lead: "تتشارك واجهة تطبيقك ووكيله الإجراءات نفسها.",
|
|
63
|
+
leadTry: "اطلب من الوكيل استدعاء الإجراء hello.",
|
|
64
|
+
llmSetupLink: "إعداد موفّر LLM",
|
|
65
|
+
title: "ابدأ الآن",
|
|
66
|
+
},
|
|
43
67
|
navigation: {
|
|
44
68
|
chat: "المحادثة",
|
|
45
69
|
collapseSidebar: "طي الشريط الجانبي",
|
|
46
70
|
database: "قاعدة البيانات",
|
|
47
71
|
expandSidebar: "توسيع الشريط الجانبي",
|
|
48
72
|
extensions: "الإضافات",
|
|
73
|
+
home: "الرئيسية",
|
|
49
74
|
navigation: "التنقل",
|
|
50
75
|
navigationDescription: "التنقل الرئيسي",
|
|
51
76
|
observability: "قابلية المراقبة",
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
const messages = {
|
|
2
|
+
composer: {
|
|
3
|
+
removeAttachment: "{{name}} entfernen",
|
|
4
|
+
removeReference: "Referenz {{name}} entfernen",
|
|
5
|
+
},
|
|
2
6
|
settings: {
|
|
3
7
|
title: "Einstellungen",
|
|
4
8
|
workspaceTitle: "Arbeitsbereich",
|
|
@@ -31,6 +35,10 @@ const messages = {
|
|
|
31
35
|
recents: "Kürzlich",
|
|
32
36
|
retryPreviousRequest:
|
|
33
37
|
"Wiederhole meine vorherige Anfrage, jetzt wo der KI-Anbieter verbunden ist.",
|
|
38
|
+
invalidHandoffOptions:
|
|
39
|
+
"Die Eingabe wurde als Entwurf gespeichert, aber ihre Chateinstellungen konnten nicht wiederhergestellt werden. Prüfe Eingabe, Kontext und Modell, bevor du sie erneut sendest.",
|
|
40
|
+
recoveryDraftUnsaved:
|
|
41
|
+
"Diese Änderungen am Entwurf sind nicht gespeichert. Beim Neuladen dieses Chats können sie verloren gehen.",
|
|
34
42
|
retryAttachmentUnavailable:
|
|
35
43
|
"Chat kann diesen Anhang für einen erneuten Versuch nicht öffnen. Füge eine zugängliche Datei-URL hinzu und versuche es erneut.",
|
|
36
44
|
renameChat: "Chat umbenennen",
|
|
@@ -42,12 +50,30 @@ const messages = {
|
|
|
42
50
|
unpinChat: "Chat lösen",
|
|
43
51
|
untitledChat: "Unbenannter Chat",
|
|
44
52
|
},
|
|
53
|
+
home: {
|
|
54
|
+
communityDescription: "Tritt der Agent-Native-Community bei",
|
|
55
|
+
composerPlaceholder: "Ruf die Aktion hello für Alex auf",
|
|
56
|
+
communityTitle: "Mach mit",
|
|
57
|
+
docsAddAction: "Aktion hinzufügen",
|
|
58
|
+
docsAddPage: "Seite hinzufügen",
|
|
59
|
+
docsDescription: "Anleitungen zu Aktionen, Seiten und Agenten",
|
|
60
|
+
docsGettingStarted: "Erste Schritte",
|
|
61
|
+
docsKeyConcepts: "Grundkonzepte",
|
|
62
|
+
docsTitle: "Dokumentation",
|
|
63
|
+
editHint:
|
|
64
|
+
"Bearbeite {{file}}, speichere und frag erneut, um die neue Begrüßung zu sehen.",
|
|
65
|
+
lead: "Die Oberfläche deiner App und ihr Agent nutzen dieselben Aktionen.",
|
|
66
|
+
leadTry: "Bitte den Agenten, die Aktion hello aufzurufen.",
|
|
67
|
+
llmSetupLink: "LLM-Anbieter einrichten",
|
|
68
|
+
title: "Loslegen",
|
|
69
|
+
},
|
|
45
70
|
navigation: {
|
|
46
71
|
chat: "Chat",
|
|
47
72
|
collapseSidebar: "Seitenleiste einklappen",
|
|
48
73
|
database: "Datenbank",
|
|
49
74
|
expandSidebar: "Seitenleiste ausklappen",
|
|
50
75
|
extensions: "Erweiterungen",
|
|
76
|
+
home: "Start",
|
|
51
77
|
navigation: "Navigation",
|
|
52
78
|
navigationDescription: "Hauptnavigation",
|
|
53
79
|
observability: "Beobachtbarkeit",
|