@polpo-ai/dashboard 0.1.3 → 0.15.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +3 -1
- package/README.md +13 -40
- package/dist/components.d.ts +53 -0
- package/dist/components.d.ts.map +1 -0
- package/dist/components.js +81 -0
- package/dist/components.js.map +1 -0
- package/dist/host.d.ts +24 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +18 -0
- package/dist/host.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/test/setup.d.ts +2 -0
- package/dist/test/setup.d.ts.map +1 -0
- package/dist/test/setup.js +2 -0
- package/dist/test/setup.js.map +1 -0
- package/dist/views/agent-detail.d.ts +4 -0
- package/dist/views/agent-detail.d.ts.map +1 -0
- package/dist/views/agent-detail.js +31 -0
- package/dist/views/agent-detail.js.map +1 -0
- package/dist/views/agents.d.ts +2 -0
- package/dist/views/agents.d.ts.map +1 -0
- package/dist/views/agents.js +81 -0
- package/dist/views/agents.js.map +1 -0
- package/dist/views/files.d.ts +2 -0
- package/dist/views/files.d.ts.map +1 -0
- package/dist/views/files.js +30 -0
- package/dist/views/files.js.map +1 -0
- package/dist/views/memory.d.ts +2 -0
- package/dist/views/memory.d.ts.map +1 -0
- package/dist/views/memory.js +19 -0
- package/dist/views/memory.js.map +1 -0
- package/dist/views/playground.d.ts +4 -0
- package/dist/views/playground.d.ts.map +1 -0
- package/dist/views/playground.js +43 -0
- package/dist/views/playground.js.map +1 -0
- package/dist/views/session-detail.d.ts +4 -0
- package/dist/views/session-detail.d.ts.map +1 -0
- package/dist/views/session-detail.js +23 -0
- package/dist/views/session-detail.js.map +1 -0
- package/dist/views/sessions.d.ts +2 -0
- package/dist/views/sessions.d.ts.map +1 -0
- package/dist/views/sessions.js +17 -0
- package/dist/views/sessions.js.map +1 -0
- package/dist/views/skills.d.ts +2 -0
- package/dist/views/skills.d.ts.map +1 -0
- package/dist/views/skills.js +16 -0
- package/dist/views/skills.js.map +1 -0
- package/package.json +47 -83
- package/src/styles.css +169 -0
- package/app/(dashboard)/error.tsx +0 -47
- package/app/(dashboard)/layout.tsx +0 -41
- package/app/(dashboard)/loading.tsx +0 -30
- package/app/(dashboard)/projects/[id]/agents/[name]/memory/view.tsx +0 -36
- package/app/(dashboard)/projects/[id]/agents/[name]/models-view.tsx +0 -30
- package/app/(dashboard)/projects/[id]/agents/[name]/page.tsx +0 -51
- package/app/(dashboard)/projects/[id]/agents/[name]/prompt/view.tsx +0 -211
- package/app/(dashboard)/projects/[id]/agents/[name]/skills/view.tsx +0 -84
- package/app/(dashboard)/projects/[id]/agents/[name]/tools/view.tsx +0 -525
- package/app/(dashboard)/projects/[id]/agents/[name]/vault/view.tsx +0 -61
- package/app/(dashboard)/projects/[id]/agents/page.tsx +0 -39
- package/app/(dashboard)/projects/[id]/agents/view.tsx +0 -283
- package/app/(dashboard)/projects/[id]/layout.tsx +0 -11
- package/app/(dashboard)/projects/[id]/logs/page.tsx +0 -27
- package/app/(dashboard)/projects/[id]/logs/view.tsx +0 -184
- package/app/(dashboard)/projects/[id]/memory/page.tsx +0 -40
- package/app/(dashboard)/projects/[id]/memory/view.tsx +0 -17
- package/app/(dashboard)/projects/[id]/missions/[missionId]/page.tsx +0 -88
- package/app/(dashboard)/projects/[id]/missions/[missionId]/view.tsx +0 -569
- package/app/(dashboard)/projects/[id]/missions/page.tsx +0 -32
- package/app/(dashboard)/projects/[id]/missions/view.tsx +0 -282
- package/app/(dashboard)/projects/[id]/onboarding-checklist.tsx +0 -359
- package/app/(dashboard)/projects/[id]/page.tsx +0 -68
- package/app/(dashboard)/projects/[id]/playbooks/[name]/page.tsx +0 -5
- package/app/(dashboard)/projects/[id]/playbooks/[name]/view.tsx +0 -433
- package/app/(dashboard)/projects/[id]/playbooks/page.tsx +0 -5
- package/app/(dashboard)/projects/[id]/playbooks/view.tsx +0 -222
- package/app/(dashboard)/projects/[id]/schedules/page.tsx +0 -44
- package/app/(dashboard)/projects/[id]/schedules/view.tsx +0 -385
- package/app/(dashboard)/projects/[id]/sessions/[sessionId]/page.tsx +0 -55
- package/app/(dashboard)/projects/[id]/sessions/[sessionId]/raw-view.tsx +0 -373
- package/app/(dashboard)/projects/[id]/sessions/[sessionId]/view.tsx +0 -124
- package/app/(dashboard)/projects/[id]/sessions/page.tsx +0 -31
- package/app/(dashboard)/projects/[id]/sessions/view.tsx +0 -242
- package/app/(dashboard)/projects/[id]/settings/page.tsx +0 -52
- package/app/(dashboard)/projects/[id]/skills/[name]/page.tsx +0 -65
- package/app/(dashboard)/projects/[id]/skills/[name]/view.tsx +0 -227
- package/app/(dashboard)/projects/[id]/skills/page.tsx +0 -31
- package/app/(dashboard)/projects/[id]/skills/view.tsx +0 -243
- package/app/(dashboard)/projects/[id]/storage/page.tsx +0 -5
- package/app/(dashboard)/projects/[id]/storage/view.tsx +0 -385
- package/app/(dashboard)/projects/[id]/tasks/[taskId]/activity/view.tsx +0 -336
- package/app/(dashboard)/projects/[id]/tasks/[taskId]/assessment/view.tsx +0 -113
- package/app/(dashboard)/projects/[id]/tasks/[taskId]/blueprint.ts +0 -72
- package/app/(dashboard)/projects/[id]/tasks/[taskId]/output/view.tsx +0 -90
- package/app/(dashboard)/projects/[id]/tasks/[taskId]/page.tsx +0 -63
- package/app/(dashboard)/projects/[id]/tasks/[taskId]/view.tsx +0 -137
- package/app/(dashboard)/projects/[id]/tasks/page.tsx +0 -40
- package/app/(dashboard)/projects/[id]/tasks/view.tsx +0 -421
- package/app/(dashboard)/projects/[id]/view.tsx +0 -421
- package/app/(dashboard)/projects/[id]/welcome-banner.tsx +0 -156
- package/app/(dashboard)/projects/projects-list.tsx +0 -126
- package/app/(playground)/error.tsx +0 -42
- package/app/(playground)/layout.tsx +0 -27
- package/app/(playground)/projects/[id]/playground/page.tsx +0 -57
- package/app/(playground)/projects/[id]/playground/view.tsx +0 -167
- package/app/(playground)/projects/[id]/playground-legacy/page.tsx +0 -47
- package/app/(playground)/projects/[id]/playground-legacy/skeleton.tsx +0 -63
- package/app/(playground)/projects/[id]/playground-legacy/view.tsx +0 -237
- package/app/favicon.ico +0 -0
- package/app/globals.css +0 -385
- package/app/icon.svg +0 -6
- package/app/layout.tsx +0 -39
- package/app/page.tsx +0 -11
- package/components/ai-elements/code-block.tsx +0 -562
- package/components/dashboard/agent-capabilities.tsx +0 -326
- package/components/dashboard/agent-identity-header.tsx +0 -50
- package/components/dashboard/agent-model-picker.tsx +0 -195
- package/components/dashboard/agent-model-selector.tsx +0 -121
- package/components/dashboard/agent-picker-card.tsx +0 -46
- package/components/dashboard/agent-studio.tsx +0 -242
- package/components/dashboard/agents-table.tsx +0 -48
- package/components/dashboard/breadcrumb.tsx +0 -70
- package/components/dashboard/builder-chat.tsx +0 -418
- package/components/dashboard/chat-shell.tsx +0 -40
- package/components/dashboard/client-picker.tsx +0 -63
- package/components/dashboard/command-snippet.tsx +0 -77
- package/components/dashboard/connect-dialog.tsx +0 -680
- package/components/dashboard/copy-button.tsx +0 -45
- package/components/dashboard/copy-card.tsx +0 -48
- package/components/dashboard/file-browser.tsx +0 -161
- package/components/dashboard/hint.tsx +0 -22
- package/components/dashboard/inference-mode.tsx +0 -15
- package/components/dashboard/manual-refresh-button.tsx +0 -52
- package/components/dashboard/markdown.tsx +0 -31
- package/components/dashboard/mcp-install-panel.tsx +0 -196
- package/components/dashboard/mission-graph.tsx +0 -262
- package/components/dashboard/nav-tabs.tsx +0 -86
- package/components/dashboard/polpo-chat.tsx +0 -468
- package/components/dashboard/project-copilot.tsx +0 -253
- package/components/dashboard/sdk-snippet-panel.tsx +0 -194
- package/components/dashboard/section-header.tsx +0 -37
- package/components/dashboard/settings-form.tsx +0 -2477
- package/components/dashboard/sidebar.tsx +0 -385
- package/components/dashboard/skeletons.tsx +0 -1054
- package/components/dashboard/skills-install-wizard.tsx +0 -294
- package/components/dashboard/swarm-runs.tsx +0 -316
- package/components/dashboard/tab-toggle.tsx +0 -35
- package/components/dashboard/task-studio.tsx +0 -224
- package/components/dashboard/top-header.tsx +0 -203
- package/components/dashboard/webhook-deliveries.tsx +0 -234
- package/components/icons/coding-agents.tsx +0 -151
- package/components/json-ld.tsx +0 -8
- package/components/providers.tsx +0 -25
- package/components/ui/badge.tsx +0 -52
- package/components/ui/button.tsx +0 -60
- package/components/ui/card.tsx +0 -103
- package/components/ui/chart.tsx +0 -356
- package/components/ui/command.tsx +0 -196
- package/components/ui/dialog.tsx +0 -157
- package/components/ui/input-group.tsx +0 -158
- package/components/ui/input.tsx +0 -20
- package/components/ui/multi-select.tsx +0 -161
- package/components/ui/popover.tsx +0 -90
- package/components/ui/select.tsx +0 -201
- package/components/ui/separator.tsx +0 -25
- package/components/ui/sheet.tsx +0 -135
- package/components/ui/skeleton.tsx +0 -13
- package/components/ui/tabs.tsx +0 -56
- package/components/ui/textarea.tsx +0 -18
- package/components/ui/tooltip.tsx +0 -66
- package/hooks/use-desktop-sidebar.tsx +0 -50
- package/hooks/use-mobile-sidebar.tsx +0 -37
- package/index.ts +0 -17
- package/lib/api.ts +0 -194
- package/lib/builder-context.ts +0 -60
- package/lib/data-client.ts +0 -68
- package/lib/get-query-client.ts +0 -25
- package/lib/polpo-client.tsx +0 -49
- package/lib/tool-catalog.ts +0 -234
- package/lib/use-event-catalog.ts +0 -28
- package/lib/utils.ts +0 -6
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import Link from "next/link";
|
|
2
|
-
import { Markdown } from "../../../../../../../components/dashboard/markdown";
|
|
3
|
-
import { CopyButton } from "../../../../../../../components/dashboard/copy-button";
|
|
4
|
-
import { Hint } from "../../../../../../../components/dashboard/hint";
|
|
5
|
-
|
|
6
|
-
export default function AgentMemoryView({ id, content }: { id: string; content: string }) {
|
|
7
|
-
return (
|
|
8
|
-
<div>
|
|
9
|
-
<div className="mb-4">
|
|
10
|
-
<Hint action={content ? <CopyButton value={content} label="Copy" className="shrink-0" /> : undefined}>
|
|
11
|
-
Private memory this agent accumulates across sessions. It also inherits the
|
|
12
|
-
shared project memory.
|
|
13
|
-
</Hint>
|
|
14
|
-
</div>
|
|
15
|
-
|
|
16
|
-
{content ? (
|
|
17
|
-
<div data-testid="agent-memory-content" className="border border-border bg-card p-6">
|
|
18
|
-
<Markdown content={content} />
|
|
19
|
-
</div>
|
|
20
|
-
) : (
|
|
21
|
-
<div className="border border-border p-8 text-center text-sm text-muted-foreground">
|
|
22
|
-
No memory yet. Memory is created automatically when the agent works.
|
|
23
|
-
</div>
|
|
24
|
-
)}
|
|
25
|
-
|
|
26
|
-
<div className="mt-4">
|
|
27
|
-
<Link
|
|
28
|
-
href={`/projects/${id}/memory`}
|
|
29
|
-
className="text-xs text-muted-foreground hover:text-foreground transition-colors"
|
|
30
|
-
>
|
|
31
|
-
View shared project memory →
|
|
32
|
-
</Link>
|
|
33
|
-
</div>
|
|
34
|
-
</div>
|
|
35
|
-
);
|
|
36
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import type { AgentConfig } from "@polpo-ai/core";
|
|
2
|
-
import { AgentCapabilities } from "../../../../../../components/dashboard/agent-capabilities";
|
|
3
|
-
|
|
4
|
-
/** Models tab — the per-capability model grid (one row per modality). */
|
|
5
|
-
export default function AgentModelsView({
|
|
6
|
-
agent,
|
|
7
|
-
projectId,
|
|
8
|
-
agentName,
|
|
9
|
-
}: {
|
|
10
|
-
agent: AgentConfig | null;
|
|
11
|
-
projectId: string;
|
|
12
|
-
agentName: string;
|
|
13
|
-
}) {
|
|
14
|
-
if (!agent) {
|
|
15
|
-
return (
|
|
16
|
-
<div
|
|
17
|
-
data-testid="agent-not-found"
|
|
18
|
-
className="mt-4 border border-border p-8 text-center text-sm text-muted-foreground"
|
|
19
|
-
>
|
|
20
|
-
Agent not found.
|
|
21
|
-
</div>
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return (
|
|
26
|
-
<section className="pt-2">
|
|
27
|
-
<AgentCapabilities agent={agent} projectId={projectId} agentName={agentName} />
|
|
28
|
-
</section>
|
|
29
|
-
);
|
|
30
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { Suspense } from "react";
|
|
2
|
-
import { dataApi, getAgent } from "../../../../../../lib/api";
|
|
3
|
-
import { AgentProfileSkeleton } from "../../../../../../components/dashboard/skeletons";
|
|
4
|
-
import { AgentStudio, type VaultEntry } from "../../../../../../components/dashboard/agent-studio";
|
|
5
|
-
|
|
6
|
-
const API_URL = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:4000";
|
|
7
|
-
|
|
8
|
-
async function AgentData({ id, name }: { id: string; name: string }) {
|
|
9
|
-
// The agent detail IS the Studio (chat canvas). Fetch everything its
|
|
10
|
-
// tabs need (agent + memory + vault) up front, server-side.
|
|
11
|
-
const [agent, memoryContent, vaultEntries] = await Promise.all([
|
|
12
|
-
getAgent(id, name),
|
|
13
|
-
dataApi<{ ok: boolean; data: { content: string } }>(
|
|
14
|
-
id,
|
|
15
|
-
`/v1/memory/agent/${encodeURIComponent(name)}`,
|
|
16
|
-
)
|
|
17
|
-
.then((r) => r.data?.content ?? "")
|
|
18
|
-
.catch(() => ""),
|
|
19
|
-
dataApi<{ ok: boolean; data: VaultEntry[] }>(
|
|
20
|
-
id,
|
|
21
|
-
`/v1/vault/entries/${encodeURIComponent(name)}`,
|
|
22
|
-
)
|
|
23
|
-
.then((r) => r.data ?? [])
|
|
24
|
-
.catch(() => [] as VaultEntry[]),
|
|
25
|
-
]);
|
|
26
|
-
|
|
27
|
-
return (
|
|
28
|
-
<AgentStudio
|
|
29
|
-
projectId={id}
|
|
30
|
-
apiUrl={API_URL}
|
|
31
|
-
agent={agent}
|
|
32
|
-
memoryContent={memoryContent}
|
|
33
|
-
vaultEntries={vaultEntries}
|
|
34
|
-
/>
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export default async function AgentDetailPage({
|
|
39
|
-
params,
|
|
40
|
-
}: {
|
|
41
|
-
params: Promise<{ id: string; name: string }>;
|
|
42
|
-
}) {
|
|
43
|
-
const { id, name } = await params;
|
|
44
|
-
const decodedName = decodeURIComponent(name);
|
|
45
|
-
|
|
46
|
-
return (
|
|
47
|
-
<Suspense fallback={<AgentProfileSkeleton />}>
|
|
48
|
-
<AgentData id={id} name={decodedName} />
|
|
49
|
-
</Suspense>
|
|
50
|
-
);
|
|
51
|
-
}
|
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { useState } from "react";
|
|
4
|
-
import { Eye } from "lucide-react";
|
|
5
|
-
import type { AgentConfig } from "@polpo-ai/core";
|
|
6
|
-
import { Markdown } from "../../../../../../../components/dashboard/markdown";
|
|
7
|
-
import { CopyButton } from "../../../../../../../components/dashboard/copy-button";
|
|
8
|
-
import { Hint } from "../../../../../../../components/dashboard/hint";
|
|
9
|
-
import {
|
|
10
|
-
Dialog,
|
|
11
|
-
DialogContent,
|
|
12
|
-
DialogDescription,
|
|
13
|
-
DialogHeader,
|
|
14
|
-
DialogTitle,
|
|
15
|
-
} from "../../../../../../../components/ui/dialog";
|
|
16
|
-
|
|
17
|
-
const API_URL = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:4000";
|
|
18
|
-
|
|
19
|
-
/** Rough token estimate — ~4 chars/token, good enough for a budget hint. */
|
|
20
|
-
const approxTokens = (s: string) => Math.round(s.length / 4);
|
|
21
|
-
|
|
22
|
-
export default function AgentPromptView({
|
|
23
|
-
agent,
|
|
24
|
-
projectId,
|
|
25
|
-
agentName,
|
|
26
|
-
}: {
|
|
27
|
-
agent: AgentConfig | null;
|
|
28
|
-
projectId: string;
|
|
29
|
-
agentName: string;
|
|
30
|
-
}) {
|
|
31
|
-
if (!agent) {
|
|
32
|
-
return (
|
|
33
|
-
<div className="mt-4 border border-border p-8 text-center text-sm text-muted-foreground">
|
|
34
|
-
Agent not found.
|
|
35
|
-
</div>
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const instructions = agent.systemPrompt ?? "";
|
|
40
|
-
const chars = instructions.length;
|
|
41
|
-
|
|
42
|
-
return (
|
|
43
|
-
<div>
|
|
44
|
-
<Hint action={<PreviewButton projectId={projectId} agentName={agentName} />}>
|
|
45
|
-
Extra instructions added on top of the agent's base prompt — they shape
|
|
46
|
-
tone and rules without replacing Polpo's defaults. Hit Preview for the
|
|
47
|
-
full composed prompt.
|
|
48
|
-
</Hint>
|
|
49
|
-
|
|
50
|
-
{instructions ? (
|
|
51
|
-
<>
|
|
52
|
-
<div className="mt-2 flex items-center gap-2">
|
|
53
|
-
<span className="inline-flex items-center gap-1 border border-border bg-secondary/40 px-2 py-0.5 font-mono text-[11px] font-medium text-foreground">
|
|
54
|
-
{chars.toLocaleString()}
|
|
55
|
-
<span className="text-muted-foreground">chars</span>
|
|
56
|
-
</span>
|
|
57
|
-
<span className="inline-flex items-center gap-1 border border-border bg-secondary/40 px-2 py-0.5 font-mono text-[11px] font-medium text-foreground">
|
|
58
|
-
~{approxTokens(instructions).toLocaleString()}
|
|
59
|
-
<span className="text-muted-foreground">tokens</span>
|
|
60
|
-
</span>
|
|
61
|
-
</div>
|
|
62
|
-
<div className="mt-3 border border-border bg-card p-6">
|
|
63
|
-
<Markdown content={instructions} />
|
|
64
|
-
</div>
|
|
65
|
-
</>
|
|
66
|
-
) : (
|
|
67
|
-
<div className="mt-3 border border-border p-8 text-center">
|
|
68
|
-
<p className="text-sm text-muted-foreground">No extra instructions configured.</p>
|
|
69
|
-
<p className="mt-1 text-xs text-muted-foreground">
|
|
70
|
-
This agent runs on the default base prompt. Preview it to see what that includes.
|
|
71
|
-
</p>
|
|
72
|
-
</div>
|
|
73
|
-
)}
|
|
74
|
-
</div>
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Loading state for the prompt preview — a sharp skeleton that mimics the
|
|
80
|
-
* composed prompt materialising (metadata bar + paragraph blocks of
|
|
81
|
-
* varying width), in keeping with the rest of the surface.
|
|
82
|
-
*/
|
|
83
|
-
function PromptSkeleton() {
|
|
84
|
-
// Width pattern per "paragraph" — last line of each block is shorter,
|
|
85
|
-
// so it reads as real prose rather than a uniform block.
|
|
86
|
-
const blocks = [
|
|
87
|
-
["w-1/3"],
|
|
88
|
-
["w-full", "w-full", "w-11/12", "w-2/3"],
|
|
89
|
-
["w-full", "w-5/6", "w-full", "w-1/2"],
|
|
90
|
-
["w-3/4", "w-full", "w-4/5"],
|
|
91
|
-
];
|
|
92
|
-
let line = 0;
|
|
93
|
-
return (
|
|
94
|
-
<div className="flex min-h-0 flex-1 flex-col">
|
|
95
|
-
<div className="flex items-center justify-between gap-4 border-y border-border py-2">
|
|
96
|
-
<span className="h-3 w-40 animate-pulse bg-muted" />
|
|
97
|
-
<span className="h-6 w-16 animate-pulse bg-muted" />
|
|
98
|
-
</div>
|
|
99
|
-
<div className="min-h-0 flex-1 space-y-5 overflow-hidden bg-card p-4">
|
|
100
|
-
{blocks.map((widths, b) => (
|
|
101
|
-
<div key={b} className="space-y-2">
|
|
102
|
-
{widths.map((w) => {
|
|
103
|
-
const delay = (line++ % 6) * 90;
|
|
104
|
-
return (
|
|
105
|
-
<div
|
|
106
|
-
key={w + line}
|
|
107
|
-
className={`h-3 ${w} animate-pulse bg-muted`}
|
|
108
|
-
style={{ animationDelay: `${delay}ms` }}
|
|
109
|
-
/>
|
|
110
|
-
);
|
|
111
|
-
})}
|
|
112
|
-
</div>
|
|
113
|
-
))}
|
|
114
|
-
</div>
|
|
115
|
-
<p className="border-t border-border pt-2 font-mono text-[11px] text-muted-foreground/60">
|
|
116
|
-
Composing the full prompt…
|
|
117
|
-
</p>
|
|
118
|
-
</div>
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Preview — fetches the FULLY composed system prompt from the data plane
|
|
124
|
-
* (`GET /v1/agents/:name/prompt`), which runs the same `buildAgentSystemPrompt`
|
|
125
|
-
* + skill-loading the runtime uses. Shows the exact text sent to the model.
|
|
126
|
-
*/
|
|
127
|
-
function PreviewButton({
|
|
128
|
-
projectId,
|
|
129
|
-
agentName,
|
|
130
|
-
}: {
|
|
131
|
-
projectId: string;
|
|
132
|
-
agentName: string;
|
|
133
|
-
}) {
|
|
134
|
-
const [open, setOpen] = useState(false);
|
|
135
|
-
const [loading, setLoading] = useState(false);
|
|
136
|
-
const [prompt, setPrompt] = useState<string | null>(null);
|
|
137
|
-
const [error, setError] = useState<string | null>(null);
|
|
138
|
-
|
|
139
|
-
async function load() {
|
|
140
|
-
setOpen(true);
|
|
141
|
-
setLoading(true);
|
|
142
|
-
setError(null);
|
|
143
|
-
setPrompt(null);
|
|
144
|
-
try {
|
|
145
|
-
const res = await fetch(
|
|
146
|
-
`${API_URL}/v1/projects/${projectId}/data/v1/agents/${encodeURIComponent(agentName)}/prompt`,
|
|
147
|
-
{ credentials: "include" },
|
|
148
|
-
);
|
|
149
|
-
const body = await res.json().catch(() => ({}));
|
|
150
|
-
if (!res.ok || !body.ok) {
|
|
151
|
-
setError(body.error ?? `Failed to compose prompt (${res.status})`);
|
|
152
|
-
} else {
|
|
153
|
-
setPrompt(body.data?.prompt ?? "");
|
|
154
|
-
}
|
|
155
|
-
} catch (err) {
|
|
156
|
-
setError((err as Error).message ?? "Failed to compose prompt");
|
|
157
|
-
}
|
|
158
|
-
setLoading(false);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
return (
|
|
162
|
-
<>
|
|
163
|
-
<button
|
|
164
|
-
type="button"
|
|
165
|
-
onClick={() => void load()}
|
|
166
|
-
className="inline-flex shrink-0 items-center gap-1.5 border border-border bg-card px-2.5 py-1.5 text-xs font-medium text-muted-foreground transition-colors hover:border-foreground/30 hover:text-foreground"
|
|
167
|
-
>
|
|
168
|
-
<Eye className="h-3.5 w-3.5" strokeWidth={1.5} />
|
|
169
|
-
Preview
|
|
170
|
-
</button>
|
|
171
|
-
|
|
172
|
-
<Dialog open={open} onOpenChange={setOpen}>
|
|
173
|
-
<DialogContent className="flex max-h-[85vh] flex-col overflow-hidden sm:max-w-3xl">
|
|
174
|
-
<DialogHeader>
|
|
175
|
-
<DialogTitle>Composed system prompt</DialogTitle>
|
|
176
|
-
<DialogDescription>
|
|
177
|
-
The complete prompt the platform sends to the model — base prompt,
|
|
178
|
-
identity, your instructions and loaded skills, exactly as the
|
|
179
|
-
runtime composes it.
|
|
180
|
-
</DialogDescription>
|
|
181
|
-
</DialogHeader>
|
|
182
|
-
|
|
183
|
-
{loading ? (
|
|
184
|
-
<PromptSkeleton />
|
|
185
|
-
) : error ? (
|
|
186
|
-
<p className="py-6 text-sm text-destructive">{error}</p>
|
|
187
|
-
) : prompt !== null ? (
|
|
188
|
-
<>
|
|
189
|
-
<div className="flex items-center justify-between gap-4 border-y border-border py-2">
|
|
190
|
-
<div className="flex items-center gap-2">
|
|
191
|
-
<span className="inline-flex items-center gap-1 border border-border bg-secondary/40 px-2 py-0.5 font-mono text-[11px] font-medium text-foreground">
|
|
192
|
-
{prompt.length.toLocaleString()}
|
|
193
|
-
<span className="text-muted-foreground">chars</span>
|
|
194
|
-
</span>
|
|
195
|
-
<span className="inline-flex items-center gap-1 border border-border bg-secondary/40 px-2 py-0.5 font-mono text-[11px] font-medium text-foreground">
|
|
196
|
-
~{approxTokens(prompt).toLocaleString()}
|
|
197
|
-
<span className="text-muted-foreground">tokens</span>
|
|
198
|
-
</span>
|
|
199
|
-
</div>
|
|
200
|
-
<CopyButton value={prompt} label="Copy" className="shrink-0" />
|
|
201
|
-
</div>
|
|
202
|
-
<div className="min-h-0 flex-1 overflow-auto bg-card p-4">
|
|
203
|
-
<Markdown content={prompt} />
|
|
204
|
-
</div>
|
|
205
|
-
</>
|
|
206
|
-
) : null}
|
|
207
|
-
</DialogContent>
|
|
208
|
-
</Dialog>
|
|
209
|
-
</>
|
|
210
|
-
);
|
|
211
|
-
}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import Link from "next/link";
|
|
2
|
-
import type { AgentConfig } from "@polpo-ai/core";
|
|
3
|
-
import { BookMarked, ExternalLink } from "lucide-react";
|
|
4
|
-
import { SectionHeader } from "../../../../../../../components/dashboard/section-header";
|
|
5
|
-
|
|
6
|
-
export default function AgentSkillsView({
|
|
7
|
-
agent,
|
|
8
|
-
projectId,
|
|
9
|
-
}: {
|
|
10
|
-
agent: AgentConfig | null;
|
|
11
|
-
projectId: string;
|
|
12
|
-
}) {
|
|
13
|
-
if (!agent) {
|
|
14
|
-
return (
|
|
15
|
-
<div
|
|
16
|
-
data-testid="agent-not-found"
|
|
17
|
-
className="border border-border p-8 text-center text-sm text-muted-foreground"
|
|
18
|
-
>
|
|
19
|
-
Agent not found.
|
|
20
|
-
</div>
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const skills = agent.skills ?? [];
|
|
25
|
-
|
|
26
|
-
return (
|
|
27
|
-
<div>
|
|
28
|
-
<SectionHeader
|
|
29
|
-
description={
|
|
30
|
-
<>
|
|
31
|
-
Installed skills extend this agent with reusable procedures. Manage
|
|
32
|
-
them with <span className="font-mono">polpo install</span> or in the
|
|
33
|
-
agent config <span className="font-mono">skills</span> field.
|
|
34
|
-
</>
|
|
35
|
-
}
|
|
36
|
-
/>
|
|
37
|
-
|
|
38
|
-
{skills.length === 0 ? (
|
|
39
|
-
<div className="mt-4 border border-dashed border-border p-8 text-center">
|
|
40
|
-
<BookMarked
|
|
41
|
-
className="mx-auto h-5 w-5 text-muted-foreground/40"
|
|
42
|
-
strokeWidth={1.5}
|
|
43
|
-
/>
|
|
44
|
-
<p className="mt-2 text-sm text-muted-foreground">No skills installed.</p>
|
|
45
|
-
<p className="mt-1 text-xs text-muted-foreground/60">
|
|
46
|
-
Browse the catalog at{" "}
|
|
47
|
-
<a
|
|
48
|
-
href="https://docs.polpo.sh/docs/agents/skills"
|
|
49
|
-
target="_blank"
|
|
50
|
-
rel="noopener noreferrer"
|
|
51
|
-
className="underline decoration-dotted underline-offset-2 transition-colors hover:text-foreground"
|
|
52
|
-
>
|
|
53
|
-
docs.polpo.sh
|
|
54
|
-
</a>
|
|
55
|
-
.
|
|
56
|
-
</p>
|
|
57
|
-
</div>
|
|
58
|
-
) : (
|
|
59
|
-
<div className="mt-4 grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3">
|
|
60
|
-
{skills.map((skill) => (
|
|
61
|
-
<Link
|
|
62
|
-
key={skill}
|
|
63
|
-
href={`/projects/${projectId}/skills/${encodeURIComponent(skill)}`}
|
|
64
|
-
target="_blank"
|
|
65
|
-
rel="noopener noreferrer"
|
|
66
|
-
className="group flex items-center gap-2.5 border border-border bg-card p-3 transition-colors hover:border-foreground/30"
|
|
67
|
-
>
|
|
68
|
-
<span className="grid size-7 shrink-0 place-items-center bg-secondary text-muted-foreground">
|
|
69
|
-
<BookMarked className="h-3.5 w-3.5" strokeWidth={1.5} />
|
|
70
|
-
</span>
|
|
71
|
-
<span className="min-w-0 flex-1 truncate font-mono text-sm text-foreground">
|
|
72
|
-
{skill}
|
|
73
|
-
</span>
|
|
74
|
-
<ExternalLink
|
|
75
|
-
className="h-3.5 w-3.5 shrink-0 text-muted-foreground/40 transition-colors group-hover:text-foreground"
|
|
76
|
-
strokeWidth={1.5}
|
|
77
|
-
/>
|
|
78
|
-
</Link>
|
|
79
|
-
))}
|
|
80
|
-
</div>
|
|
81
|
-
)}
|
|
82
|
-
</div>
|
|
83
|
-
);
|
|
84
|
-
}
|