bazilion 0.10.0 → 0.12.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.
Files changed (80) hide show
  1. package/dist/cli.js +1666 -266
  2. package/dist/cli.js.map +1 -1
  3. package/dist/daemon.js +4303 -522
  4. package/dist/daemon.js.map +1 -1
  5. package/dist/migrations/0001_init.sql +101 -0
  6. package/dist/web/client/assets/AgentTabs-R6gSjIj3.js +1 -0
  7. package/dist/web/client/assets/{ProductionTeamPolicyEditor-CiQ-VVDo.js → ProductionTeamPolicyEditor-CSL3W7XM.js} +2 -2
  8. package/dist/web/client/assets/{ProfileCommunicationEditor-D84F5yfr.js → ProfileCommunicationEditor-CwU0QkmE.js} +1 -1
  9. package/dist/web/client/assets/{TeamTabs-Btoe_FAE.js → TeamTabs-C1Hakkff.js} +1 -1
  10. package/dist/web/client/assets/{TemplatesTabs-CAYY03F5.js → TemplatesTabs-klEydJ8-.js} +1 -1
  11. package/dist/web/client/assets/{_id-BqU2BodK.js → _id-BOC7ioJu.js} +1 -1
  12. package/dist/web/client/assets/{_id-CKtoio3t.js → _id-CnVq-rED.js} +1 -1
  13. package/dist/web/client/assets/{_id-BeauECmk.js → _id-e4u7dmBb.js} +1 -1
  14. package/dist/web/client/assets/{_id-Q98Of6k9.js → _id-wkjjWLz0.js} +1 -1
  15. package/dist/web/client/assets/{activity-DXN_N85w.js → activity-uqhwzmiy.js} +1 -1
  16. package/dist/web/client/assets/{agents-C5Xsdge1.js → agents-B2usE-L_.js} +1 -1
  17. package/dist/web/client/assets/{agents-Cgxo4H5G.js → agents-FaQtkAWs.js} +1 -1
  18. package/dist/web/client/assets/{approvals-BnG7fbw-.js → approvals-DqLE6ttw.js} +1 -1
  19. package/dist/web/client/assets/attention-CkGozYnJ.js +1 -0
  20. package/dist/web/client/assets/attention-Gavt2yEp.js +1 -0
  21. package/dist/web/client/assets/chevron-down-CJk0zGNT.js +1 -0
  22. package/dist/web/client/assets/{config-xw4NyrXF.js → config-xrXoDEWM.js} +1 -1
  23. package/dist/web/client/assets/{context-D2V1Oi4z.js → context-ZWqx3uiC.js} +1 -1
  24. package/dist/web/client/assets/inbox-BoIvl9ZF.js +1 -0
  25. package/dist/web/client/assets/{index-VdURSoM4.js → index-nb2MV8X1.js} +3 -3
  26. package/dist/web/client/assets/learning-6_oYn1l7.js +1 -0
  27. package/dist/web/client/assets/{login-CvptUoMR.js → login-DM1ytxQL.js} +1 -1
  28. package/dist/web/client/assets/{mcp-BDFM_sW-.js → mcp-CetZbyUh.js} +1 -1
  29. package/dist/web/client/assets/{members-BJvph_TR.js → members-DdqWtwZd.js} +1 -1
  30. package/dist/web/client/assets/{memory-DRytqZCD.js → memory-FNrxFHmC.js} +1 -1
  31. package/dist/web/client/assets/plus-C3GroITC.js +1 -0
  32. package/dist/web/client/assets/{policy-CGP50OtQ.js → policy-BKPejYRI.js} +1 -1
  33. package/dist/web/client/assets/{routes-DJnWYvC9.js → routes-CH1ZTTo-.js} +1 -1
  34. package/dist/web/client/assets/{services-DHheiv7L.js → services-zk9SqN06.js} +1 -1
  35. package/dist/web/client/assets/{skills-DmsitluU.js → skills-tXDpomHW.js} +1 -1
  36. package/dist/web/client/assets/styles-DMltY3su.css +2 -0
  37. package/dist/web/client/assets/{teams-BdC4gthq.js → teams-BZYjekBN.js} +1 -1
  38. package/dist/web/client/assets/{teams-CbxSaorm.js → teams-D1c8zlxs.js} +1 -1
  39. package/dist/web/client/assets/telegram-DCe1CWMt.js +1 -0
  40. package/dist/web/client/assets/{tokens-CjRplDrJ.js → tokens-DAPjRS0N.js} +1 -1
  41. package/dist/web/client/assets/triggers-D8R-5guA.js +1 -0
  42. package/dist/web/client/assets/{welcome-wBfX9dAd.js → welcome-CuK0shDJ.js} +1 -1
  43. package/dist/web/client/assets/wire-constants-BhVKOCQa.js +74 -0
  44. package/dist/web/server/assets/{AgentTabs-DoMDJBXH.js → AgentTabs-aXdsiiMp.js} +5 -0
  45. package/dist/web/server/assets/{ChatPane-eUY_dga3.js → ChatPane-Ba5wTsVk.js} +325 -36
  46. package/dist/web/server/assets/{_id-ClN9hY2x.js → _id-BHYLL8M-.js} +3 -3
  47. package/dist/web/server/assets/{_id-DkYodSkG.js → _id-FcHdSocl.js} +1 -1
  48. package/dist/web/server/assets/{_tanstack-start-manifest_v-D09Xu_6u.js → _tanstack-start-manifest_v-fLsYERQ-.js} +77 -54
  49. package/dist/web/server/assets/attention-BW_6ddkj.js +11 -0
  50. package/dist/web/server/assets/attention-BxkTf337.js +14 -0
  51. package/dist/web/server/assets/attention-CM-Ks1N9.js +19 -0
  52. package/dist/web/server/assets/attention-w21GQIGH.js +264 -0
  53. package/dist/web/server/assets/{inbox-CUIyf9MT.js → inbox-BLUzA5sQ.js} +40 -3
  54. package/dist/web/server/assets/{inbox-B3-TRsNI.js → inbox-CzlKT9Wg.js} +5 -3
  55. package/dist/web/server/assets/{inbox-BardsGyy.js → inbox-ZvDNAjaM.js} +1 -1
  56. package/dist/web/server/assets/learning-8zav4pIT.js +33 -0
  57. package/dist/web/server/assets/learning-B7PBkvER.js +16 -0
  58. package/dist/web/server/assets/learning-Cq7K2heb.js +312 -0
  59. package/dist/web/server/assets/{router-DIdp8ZNt.js → router-CQuj7553.js} +81 -48
  60. package/dist/web/server/assets/{routes-Jb0zjKav.js → routes-B6cMLIPk.js} +3 -3
  61. package/dist/web/server/assets/{routes-CXz4hTAr.js → routes-BrA-U_Hm.js} +1 -1
  62. package/dist/web/server/assets/{routes-lIclH9Br.js → routes-C19CMLZt.js} +1 -1
  63. package/dist/web/server/assets/{telegram-7ub--6xz.js → telegram-CBF8SJzB.js} +1 -24
  64. package/dist/web/server/assets/{telegram-Bazhmpr4.js → telegram-XwyKSEtj.js} +1 -1
  65. package/dist/web/server/assets/{triggers-Ca57_qym.js → triggers-BZPl5CHs.js} +1 -1
  66. package/dist/web/server/assets/{triggers-BMpHsGIr.js → triggers-CSNNzRIi.js} +28 -4
  67. package/dist/web/server/assets/{triggers-C_0y6QV9.js → triggers-D79NoSXk.js} +3 -2
  68. package/dist/web/server/server.js +13 -5
  69. package/dist/worker.js +1752 -148
  70. package/dist/worker.js.map +1 -1
  71. package/package.json +4 -3
  72. package/dist/web/client/assets/AgentTabs-B3hq5a3e.js +0 -1
  73. package/dist/web/client/assets/chevron-down-BhcBspw3.js +0 -1
  74. package/dist/web/client/assets/inbox-DK6hWCMp.js +0 -1
  75. package/dist/web/client/assets/plus-C9ee3SIO.js +0 -1
  76. package/dist/web/client/assets/styles-B5eQAwLP.css +0 -2
  77. package/dist/web/client/assets/telegram-D61G_alO.js +0 -1
  78. package/dist/web/client/assets/triggers-MLzTm_DM.js +0 -1
  79. package/dist/web/client/assets/wire-constants-BxfyUMXB.js +0 -74
  80. package/dist/web/server/assets/{Sidebar-O_CH1-JD.js → Sidebar-DsRVCszF.js} +1 -1
@@ -1,6 +1,6 @@
1
- import { t as Route } from "./inbox-BardsGyy.js";
1
+ import { t as Route } from "./inbox-ZvDNAjaM.js";
2
2
  import { r as PageShell } from "./Page-LENulSXY.js";
3
- import { t as AgentTabs } from "./AgentTabs-DoMDJBXH.js";
3
+ import { t as AgentTabs } from "./AgentTabs-aXdsiiMp.js";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
  //#region src/routes/agents/$id/inbox.tsx?tsr-split=component
6
6
  function decodeText(payload) {
@@ -11,7 +11,7 @@ function decodeText(payload) {
11
11
  return payload;
12
12
  }
13
13
  function InboxPage() {
14
- const { resolved, messages, unreadCount, selected, agentNames } = Route.useLoaderData();
14
+ const { resolved, messages, unreadCount, selected, agentNames, loopBreaks } = Route.useLoaderData();
15
15
  const unreadOnly = Route.useSearch().unread === "1";
16
16
  const misaddressed = Boolean(selected && selected.toAgentId !== resolved.agent.id);
17
17
  function agentLabel(aid) {
@@ -122,6 +122,43 @@ function InboxPage() {
122
122
  }),
123
123
  " tool. An idle recipient's scheduler tick drains unread mail."
124
124
  ]
125
+ }),
126
+ /* @__PURE__ */ jsxs("div", {
127
+ className: "mt-6 rounded-lg border bg-card p-4",
128
+ children: [/* @__PURE__ */ jsx("h2", {
129
+ className: "mb-2 font-serif text-lg text-foreground",
130
+ children: "Loop circuit breaker"
131
+ }), loopBreaks.length === 0 ? /* @__PURE__ */ jsx("p", {
132
+ className: "text-xs text-muted-foreground",
133
+ children: "No agent-message chains stopped."
134
+ }) : /* @__PURE__ */ jsx("div", {
135
+ className: "space-y-3",
136
+ children: loopBreaks.map((event) => /* @__PURE__ */ jsxs("div", {
137
+ className: "border-t first:border-0 first:pt-0 pt-3 text-xs",
138
+ children: [/* @__PURE__ */ jsxs("div", {
139
+ className: "font-mono text-foreground",
140
+ children: [
141
+ agentLabel(event.fromAgentId),
142
+ " → ",
143
+ agentLabel(event.toAgentId)
144
+ ]
145
+ }), /* @__PURE__ */ jsxs("div", {
146
+ className: "mt-1 text-muted-foreground",
147
+ children: [
148
+ "stopped hop ",
149
+ event.attemptedHop,
150
+ " at limit ",
151
+ event.maxHops,
152
+ " · chain",
153
+ " ",
154
+ /* @__PURE__ */ jsx("code", { children: event.causalChainId.slice(0, 8) }),
155
+ " ·",
156
+ " ",
157
+ new Date(event.createdAt).toLocaleString()
158
+ ]
159
+ })]
160
+ }, event.id))
161
+ })]
125
162
  })
126
163
  ] })]
127
164
  })
@@ -17,10 +17,11 @@ var fetchInbox = createServerFn({ method: "POST" }).inputValidator((d) => d).han
17
17
  throw err;
18
18
  }
19
19
  const inboxQs = data.unreadOnly ? "?unread=1" : "";
20
- const [list, unread, allAgents] = await Promise.all([
20
+ const [list, unread, allAgents, loopBreaks] = await Promise.all([
21
21
  c.get(`/api/agents/${encodeURIComponent(resolved.agent.id)}/messages${inboxQs}`),
22
22
  c.get(`/api/agents/${encodeURIComponent(resolved.agent.id)}/messages?unread=1`),
23
- c.get("/api/agents?includeArchived=true")
23
+ c.get("/api/agents?includeArchived=true"),
24
+ c.get(`/api/agents/${encodeURIComponent(resolved.agent.id)}/loop-breaks?limit=10`)
24
25
  ]);
25
26
  let selected = null;
26
27
  if (data.selectedId) try {
@@ -35,7 +36,8 @@ var fetchInbox = createServerFn({ method: "POST" }).inputValidator((d) => d).han
35
36
  messages: [...list.messages].reverse(),
36
37
  unreadCount: unread.messages.length,
37
38
  selected,
38
- agentNames
39
+ agentNames,
40
+ loopBreaks: loopBreaks.events
39
41
  };
40
42
  });
41
43
  //#endregion
@@ -2,7 +2,7 @@ import { t as createServerFn } from "../server.js";
2
2
  import { t as createSsrRpc } from "./createSsrRpc-DFsIAfFd.js";
3
3
  import { createFileRoute, lazyRouteComponent, redirect } from "@tanstack/react-router";
4
4
  //#region src/routes/agents/$id/inbox.tsx
5
- var $$splitComponentImporter = () => import("./inbox-CUIyf9MT.js");
5
+ var $$splitComponentImporter = () => import("./inbox-BLUzA5sQ.js");
6
6
  var fetchInbox = createServerFn({ method: "POST" }).inputValidator((d) => d).handler(createSsrRpc("2cd8c6ec40e2e2d9518b5f127a518ecd83a2222d85665cc61d5144bcf59ed4fb"));
7
7
  var Route = createFileRoute("/agents/$id/inbox")({
8
8
  validateSearch: (s) => ({
@@ -0,0 +1,33 @@
1
+ import { t as createServerFn } from "../server.js";
2
+ import { t as createServerRpc } from "./createServerRpc-pU-IQV2Y.js";
3
+ import { n as daemonClient, r as ApiClientError } from "./daemon-client-2NRMzlTr.js";
4
+ //#region src/routes/agents/$id/learning.tsx?tss-serverfn-split
5
+ var fetchLearning_createServerFn_handler = createServerRpc({
6
+ id: "fcdd0f08b635c7c501caa840d01d1376ace6683e26cc5ac7dead28d7870f98b9",
7
+ name: "fetchLearning",
8
+ filename: "src/routes/agents/$id/learning.tsx"
9
+ }, (opts) => fetchLearning.__executeServer(opts));
10
+ var fetchLearning = createServerFn({ method: "POST" }).inputValidator((data) => data).handler(fetchLearning_createServerFn_handler, async ({ data }) => {
11
+ const client = daemonClient();
12
+ let resolved;
13
+ try {
14
+ resolved = await client.get(`/api/agents/${encodeURIComponent(data.id)}`);
15
+ } catch (error) {
16
+ if (error instanceof ApiClientError && error.status === 404) return null;
17
+ throw error;
18
+ }
19
+ const id = encodeURIComponent(resolved.agent.id);
20
+ const [config, reviews, proposals] = await Promise.all([
21
+ client.get(`/api/agents/${id}/review-config`),
22
+ client.get(`/api/agents/${id}/reviews`),
23
+ client.get(`/api/agents/${id}/lesson-proposals`)
24
+ ]);
25
+ return {
26
+ resolved,
27
+ config,
28
+ reviews: reviews.reviews,
29
+ proposals: proposals.proposals
30
+ };
31
+ });
32
+ //#endregion
33
+ export { fetchLearning_createServerFn_handler };
@@ -0,0 +1,16 @@
1
+ import { t as createServerFn } from "../server.js";
2
+ import { t as createSsrRpc } from "./createSsrRpc-DFsIAfFd.js";
3
+ import { createFileRoute, lazyRouteComponent, redirect } from "@tanstack/react-router";
4
+ //#region src/routes/agents/$id/learning.tsx
5
+ var $$splitComponentImporter = () => import("./learning-Cq7K2heb.js");
6
+ var fetchLearning = createServerFn({ method: "POST" }).inputValidator((data) => data).handler(createSsrRpc("fcdd0f08b635c7c501caa840d01d1376ace6683e26cc5ac7dead28d7870f98b9"));
7
+ var Route = createFileRoute("/agents/$id/learning")({
8
+ loader: async ({ params }) => {
9
+ const data = await fetchLearning({ data: { id: params.id } });
10
+ if (!data) throw redirect({ to: "/agents" });
11
+ return data;
12
+ },
13
+ component: lazyRouteComponent($$splitComponentImporter, "component")
14
+ });
15
+ //#endregion
16
+ export { Route as t };
@@ -0,0 +1,312 @@
1
+ import { t as Route } from "./learning-B7PBkvER.js";
2
+ import { r as PageShell } from "./Page-LENulSXY.js";
3
+ import { t as AgentTabs } from "./AgentTabs-aXdsiiMp.js";
4
+ import { t as Button } from "./Button-Dsnw22OF.js";
5
+ import { useState } from "react";
6
+ import { useRouter } from "@tanstack/react-router";
7
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
+ //#region src/routes/agents/$id/learning.tsx?tsr-split=component
9
+ function LearningPage() {
10
+ const { resolved, config, reviews, proposals } = Route.useLoaderData();
11
+ const router = useRouter();
12
+ const [error, setError] = useState(null);
13
+ const [busy, setBusy] = useState(false);
14
+ async function request(path, method, body) {
15
+ setError(null);
16
+ setBusy(true);
17
+ try {
18
+ const response = await fetch(path, {
19
+ method,
20
+ headers: body === void 0 ? void 0 : { "content-type": "application/json" },
21
+ body: body === void 0 ? void 0 : JSON.stringify(body)
22
+ });
23
+ if (!response.ok) {
24
+ const detail = await response.json().catch(() => null);
25
+ throw new Error(detail?.error ?? `request failed (${response.status})`);
26
+ }
27
+ await router.invalidate();
28
+ } catch (cause) {
29
+ setError(cause instanceof Error ? cause.message : String(cause));
30
+ } finally {
31
+ setBusy(false);
32
+ }
33
+ }
34
+ const id = encodeURIComponent(resolved.agent.id);
35
+ return /* @__PURE__ */ jsxs(PageShell, { children: [
36
+ /* @__PURE__ */ jsx("header", {
37
+ className: "mb-6",
38
+ children: /* @__PURE__ */ jsx("h1", { children: resolved.agent.name })
39
+ }),
40
+ /* @__PURE__ */ jsx(AgentTabs, {
41
+ agentId: resolved.agent.id,
42
+ active: "learning",
43
+ archived: resolved.agent.status === "archived"
44
+ }),
45
+ error && /* @__PURE__ */ jsxs("p", {
46
+ className: "mb-4 rounded border border-red-300 bg-red-50 p-3 text-sm text-red-800",
47
+ children: [error, ". Refresh before retrying if another operator changed this proposal."]
48
+ }),
49
+ /* @__PURE__ */ jsxs("section", {
50
+ className: "mb-8 rounded-lg border bg-card p-5",
51
+ children: [
52
+ /* @__PURE__ */ jsx("h2", {
53
+ className: "mb-2 text-xl",
54
+ children: "Reviewed learning"
55
+ }),
56
+ /* @__PURE__ */ jsxs("p", {
57
+ className: "mb-4 text-sm text-muted-foreground",
58
+ children: [
59
+ "Reviews inspect at most 8 successful user turns and 40,000 characters. They use ",
60
+ config.model ?? "the Agent model",
61
+ " at ",
62
+ config.reasoningLevel,
63
+ " reasoning, propose at most five lessons, and never apply anything without your approval."
64
+ ]
65
+ }),
66
+ /* @__PURE__ */ jsx(ReviewConfigForm, {
67
+ agentId: resolved.agent.id,
68
+ config,
69
+ disabled: busy,
70
+ onError: setError,
71
+ onSaved: () => router.invalidate()
72
+ }),
73
+ /* @__PURE__ */ jsxs("div", {
74
+ className: "mt-4 flex items-center gap-3",
75
+ children: [/* @__PURE__ */ jsx(Button, {
76
+ variant: "primary",
77
+ disabled: busy || resolved.agent.status === "archived",
78
+ onClick: () => request(`/api/agents/${id}/reviews`, "POST"),
79
+ children: "Review now"
80
+ }), !config.enabled && /* @__PURE__ */ jsx("span", {
81
+ className: "text-sm text-muted-foreground",
82
+ children: "Periodic review is disabled; manual review remains available."
83
+ })]
84
+ })
85
+ ]
86
+ }),
87
+ /* @__PURE__ */ jsx("h2", {
88
+ className: "mb-3 text-xl",
89
+ children: "Lesson proposals"
90
+ }),
91
+ proposals.length === 0 ? /* @__PURE__ */ jsx("p", {
92
+ className: "mb-8 text-muted-foreground",
93
+ children: "No proposals yet. A successful review may also produce zero proposals."
94
+ }) : /* @__PURE__ */ jsx("div", {
95
+ className: "mb-8 grid gap-3",
96
+ children: proposals.map((proposal) => /* @__PURE__ */ jsx(ProposalCard, {
97
+ proposal,
98
+ agentId: resolved.agent.id,
99
+ busy,
100
+ act: request
101
+ }, proposal.id))
102
+ }),
103
+ /* @__PURE__ */ jsx("h2", {
104
+ className: "mb-3 text-xl",
105
+ children: "Review history"
106
+ }),
107
+ reviews.length === 0 ? /* @__PURE__ */ jsx("p", {
108
+ className: "text-muted-foreground",
109
+ children: "No reviews have been queued."
110
+ }) : /* @__PURE__ */ jsx("div", {
111
+ className: "overflow-x-auto",
112
+ children: /* @__PURE__ */ jsxs("table", { children: [/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
113
+ /* @__PURE__ */ jsx("th", { children: "created" }),
114
+ /* @__PURE__ */ jsx("th", { children: "trigger" }),
115
+ /* @__PURE__ */ jsx("th", { children: "status" }),
116
+ /* @__PURE__ */ jsx("th", { children: "turns" }),
117
+ /* @__PURE__ */ jsx("th", { children: "proposals" }),
118
+ /* @__PURE__ */ jsx("th", { children: "diagnostic" })
119
+ ] }) }), /* @__PURE__ */ jsx("tbody", { children: reviews.map((review) => /* @__PURE__ */ jsxs("tr", { children: [
120
+ /* @__PURE__ */ jsx("td", { children: new Date(review.createdAt).toLocaleString() }),
121
+ /* @__PURE__ */ jsx("td", { children: review.trigger }),
122
+ /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx("code", { children: review.status }) }),
123
+ /* @__PURE__ */ jsx("td", { children: review.turnsReviewed }),
124
+ /* @__PURE__ */ jsx("td", { children: review.proposalCount }),
125
+ /* @__PURE__ */ jsx("td", { children: review.lastError ?? "—" })
126
+ ] }, review.id)) })] })
127
+ })
128
+ ] });
129
+ }
130
+ function ReviewConfigForm({ agentId, config, disabled, onError, onSaved }) {
131
+ const [enabled, setEnabled] = useState(config.enabled);
132
+ const [every, setEvery] = useState(config.everyNTurns);
133
+ const [model, setModel] = useState(config.model ?? "");
134
+ const [reasoning, setReasoning] = useState(config.reasoningLevel);
135
+ async function submit(event) {
136
+ event.preventDefault();
137
+ onError(null);
138
+ const response = await fetch(`/api/agents/${encodeURIComponent(agentId)}/review-config`, {
139
+ method: "PATCH",
140
+ headers: { "content-type": "application/json" },
141
+ body: JSON.stringify({
142
+ enabled,
143
+ everyNTurns: every,
144
+ model: model.trim() || null,
145
+ reasoningLevel: reasoning
146
+ })
147
+ });
148
+ if (!response.ok) {
149
+ onError((await response.json().catch(() => null))?.error ?? `request failed (${response.status})`);
150
+ return;
151
+ }
152
+ onSaved();
153
+ }
154
+ return /* @__PURE__ */ jsxs("form", {
155
+ onSubmit: submit,
156
+ className: "grid gap-3 md:grid-cols-4",
157
+ children: [
158
+ /* @__PURE__ */ jsxs("label", {
159
+ className: "text-sm",
160
+ children: [
161
+ /* @__PURE__ */ jsx("span", {
162
+ className: "block mb-1",
163
+ children: "Periodic review"
164
+ }),
165
+ /* @__PURE__ */ jsx("input", {
166
+ type: "checkbox",
167
+ checked: enabled,
168
+ onChange: (event) => setEnabled(event.target.checked)
169
+ }),
170
+ " enabled"
171
+ ]
172
+ }),
173
+ /* @__PURE__ */ jsxs("label", {
174
+ className: "text-sm",
175
+ children: [/* @__PURE__ */ jsx("span", {
176
+ className: "block mb-1",
177
+ children: "Every turns"
178
+ }), /* @__PURE__ */ jsx("input", {
179
+ type: "number",
180
+ min: 1,
181
+ max: 100,
182
+ value: every,
183
+ onChange: (event) => setEvery(Number(event.target.value))
184
+ })]
185
+ }),
186
+ /* @__PURE__ */ jsxs("label", {
187
+ className: "text-sm",
188
+ children: [/* @__PURE__ */ jsx("span", {
189
+ className: "block mb-1",
190
+ children: "Model override"
191
+ }), /* @__PURE__ */ jsx("input", {
192
+ value: model,
193
+ placeholder: "agent model",
194
+ onChange: (event) => setModel(event.target.value)
195
+ })]
196
+ }),
197
+ /* @__PURE__ */ jsxs("label", {
198
+ className: "text-sm",
199
+ children: [/* @__PURE__ */ jsx("span", {
200
+ className: "block mb-1",
201
+ children: "Reasoning"
202
+ }), /* @__PURE__ */ jsxs("select", {
203
+ value: reasoning,
204
+ onChange: (event) => setReasoning(event.target.value),
205
+ children: [
206
+ /* @__PURE__ */ jsx("option", { children: "off" }),
207
+ /* @__PURE__ */ jsx("option", { children: "minimal" }),
208
+ /* @__PURE__ */ jsx("option", { children: "low" }),
209
+ /* @__PURE__ */ jsx("option", { children: "medium" }),
210
+ /* @__PURE__ */ jsx("option", { children: "high" }),
211
+ /* @__PURE__ */ jsx("option", { children: "xhigh" })
212
+ ]
213
+ })]
214
+ }),
215
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, {
216
+ variant: "primary",
217
+ type: "submit",
218
+ disabled,
219
+ children: "Save learning settings"
220
+ }) })
221
+ ]
222
+ });
223
+ }
224
+ function ProposalCard({ proposal, agentId, busy, act }) {
225
+ const [text, setText] = useState(proposal.text);
226
+ const [scope, setScope] = useState(proposal.scope);
227
+ const base = `/api/agents/${encodeURIComponent(agentId)}/lesson-proposals/${encodeURIComponent(proposal.id)}`;
228
+ return /* @__PURE__ */ jsxs("article", {
229
+ className: "rounded-lg border bg-card p-4",
230
+ children: [
231
+ /* @__PURE__ */ jsxs("div", {
232
+ className: "mb-2 flex justify-between gap-2",
233
+ children: [/* @__PURE__ */ jsx("code", { children: proposal.status }), /* @__PURE__ */ jsxs("span", {
234
+ className: "text-xs text-muted-foreground",
235
+ children: ["v", proposal.version]
236
+ })]
237
+ }),
238
+ proposal.status === "pending" ? /* @__PURE__ */ jsxs(Fragment, { children: [
239
+ /* @__PURE__ */ jsx("textarea", {
240
+ className: "w-full",
241
+ rows: 3,
242
+ value: text,
243
+ onChange: (event) => setText(event.target.value)
244
+ }),
245
+ /* @__PURE__ */ jsxs("select", {
246
+ className: "mt-2",
247
+ value: scope,
248
+ onChange: (event) => setScope(event.target.value),
249
+ children: [/* @__PURE__ */ jsx("option", {
250
+ value: "private",
251
+ children: "private Agent behavior"
252
+ }), /* @__PURE__ */ jsx("option", {
253
+ value: "shared",
254
+ children: "shared Team knowledge"
255
+ })]
256
+ }),
257
+ /* @__PURE__ */ jsxs("div", {
258
+ className: "mt-3 flex flex-wrap gap-2",
259
+ children: [
260
+ /* @__PURE__ */ jsx(Button, {
261
+ variant: "ghost",
262
+ disabled: busy,
263
+ onClick: () => act(base, "PATCH", {
264
+ version: proposal.version,
265
+ text,
266
+ scope
267
+ }),
268
+ children: "Save edit"
269
+ }),
270
+ /* @__PURE__ */ jsx(Button, {
271
+ variant: "primary",
272
+ disabled: busy,
273
+ onClick: () => act(`${base}/approve`, "POST", { version: proposal.version }),
274
+ children: "Approve"
275
+ }),
276
+ /* @__PURE__ */ jsx(Button, {
277
+ variant: "danger",
278
+ disabled: busy,
279
+ onClick: () => act(`${base}/reject`, "POST", { version: proposal.version }),
280
+ children: "Reject"
281
+ })
282
+ ]
283
+ })
284
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("p", { children: proposal.text }), proposal.status === "approved" && /* @__PURE__ */ jsx("div", {
285
+ className: "mt-3",
286
+ children: /* @__PURE__ */ jsx(Button, {
287
+ variant: "danger",
288
+ disabled: busy,
289
+ onClick: () => act(`${base}/revoke`, "POST", { version: proposal.version }),
290
+ children: "Revoke"
291
+ })
292
+ })] }),
293
+ /* @__PURE__ */ jsxs("div", {
294
+ className: "mt-3 text-xs text-muted-foreground",
295
+ children: ["Evidence: ", proposal.evidence.length === 0 ? "none" : /* @__PURE__ */ jsx("ul", {
296
+ className: "mt-1 list-disc pl-5",
297
+ children: proposal.evidence.map((item) => /* @__PURE__ */ jsxs("li", { children: [/* @__PURE__ */ jsxs("code", { children: [
298
+ item.sessionId,
299
+ ":",
300
+ item.entryOrdinal
301
+ ] }), item.excerpt ? ` — ${item.excerpt}` : " — excerpt unavailable"] }, `${item.sessionId}:${item.entryOrdinal}`))
302
+ })]
303
+ }),
304
+ scope === "shared" && /* @__PURE__ */ jsx("p", {
305
+ className: "mt-1 text-xs text-muted-foreground",
306
+ children: "Shared lessons become searchable Team memory. Stable facts about the human belong in Team USER.md instead."
307
+ })
308
+ ]
309
+ });
310
+ }
311
+ //#endregion
312
+ export { LearningPage as component };