Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions apps/presentation/dashboard/src/data/decision-context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import {requestJson} from "./chat";

/** Native activation/recall packets. Profile and raw hits are never cached. */
export type DecisionContextActivation = Readonly<{
ok: boolean;
status: string;
reason_code?: string | null;
available: boolean;
enabled: boolean;
context_provider_configured: boolean;
}>;

export type DecisionContextRecall = Readonly<{
ok: boolean;
status: string;
reason_code?: string | null;
provider?: string;
provider_version?: string | null;
observed_at?: string;
results: ReadonlyArray<Readonly<{
provider_ref: string;
summary: string;
content: string;
score: number | null;
}>>;
}>;

type ContextTarget = Readonly<{
goal_id: string;
agent_id: string;
profile: Record<string, unknown> | null;
}>;

export function inspectDecisionContext(target: ContextTarget, signal: AbortSignal) {
return requestJson<DecisionContextActivation>("/api/chat/decision-context", {
method: "POST", body: JSON.stringify({...target, action: "inspect"}), signal,
});
}

export function recallDecisionContext(
request: ContextTarget & Readonly<{query: string; context_scope_ref: string; max_results: number}>,
signal: AbortSignal,
) {
return requestJson<DecisionContextRecall>("/api/chat/decision-context", {
method: "POST", body: JSON.stringify({...request, action: "recall"}), signal,
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type FieldCopy = Record<string, Readonly<{ description?: string; label: string;

const capabilityCopy: Record<WorkspaceLocale, Record<string, LocalizedCopy>> = {
en: {
decision_context: {displayName: "Find evidence", description: "Find advisory evidence with a temporary private profile. OpenViking and BM25 are retrieval implementations; this page does not save a binding or enable automatic memory."},
content_ops: {displayName: "Reference styles", description: "Retrieve source styles from an existing private catalog and prepare attributed outlines. No source or material-store writes."},
goal_storage: { displayName: "New Goal authority", description: "New Goals default to canonical SQLite with hard leases. Choose storage and execution policy for future Goals. Existing Goals require a separate backed-up migration." },
manager_runtime: {
Expand Down Expand Up @@ -74,11 +75,12 @@ const capabilityCopy: Record<WorkspaceLocale, Record<string, LocalizedCopy>> = {
description: "Sets forward/reverse PR review directions with machine, Goal and Agent settings; it never grants GitHub, Todo, push, or merge authority.",
},
reward_memory: {
displayName: "Reward Memory experiment",
displayName: "Experience learning (experimental)",
description: "Configures a reviewed local-private provider binding for Goal-scoped Agent recall and evidence-backed outcome learning.",
},
},
"zh-CN": {
decision_context: {displayName: "资料召回", description: "通过临时私有配置查找参考证据。OpenViking、BM25 是检索实现;本页不保存绑定,也不启用自动记忆。"},
content_ops: {displayName: "素材与风格", description: "从原有私有目录检索表达结构,准备带来源署名的提纲;不执行来源或素材库写入。"},
goal_storage: { displayName: "新 Goal 的权威存储", description: "新 Goal 默认使用 canonical SQLite 与 hard lease;可选择之后新 Goal 的存储与执行策略。已有 Goal 仍需单独备份、迁移。" },
manager_runtime: {
Expand Down Expand Up @@ -141,7 +143,7 @@ const capabilityCopy: Record<WorkspaceLocale, Record<string, LocalizedCopy>> = {
description: "配置公开 GitHub PR 审阅队列的本机默认排序;不会授予 GitHub、Todo、push 或 merge 权限。",
},
reward_memory: {
displayName: "Reward Memory 实验",
displayName: "经验学习(实验)",
description: "为 Goal 内 Agent 的召回与证据化结果学习配置经过审阅的本机私有 Provider 绑定。",
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { AlertTriangle, ShieldCheck, SlidersHorizontal } from "lucide-react";
import type { CapabilityConfigurationCatalog } from "../../data/chat";
import { useWorkspaceI18n, type WorkspaceLocale, type WorkspaceTranslate } from "./i18n";
import { localizeCapability, localizedCapabilityFieldCopy } from "./capability-localization";
import {isMemoryCapability, memoryCapabilities, memorySettingsTitle} from "./memory-settings";

type CapabilityDescriptor = CapabilityConfigurationCatalog["capabilities"][number];

Expand Down Expand Up @@ -90,9 +91,20 @@ export function CapabilityCatalogNavigation({
showScope?: boolean;
t: WorkspaceTranslate;
}>) {
const memory = scope === "goal" ? memoryCapabilities(capabilities) : [];
const memorySelected = memory.some(item => item.capability_id === selectedCapabilityId);
let memoryRendered = false;
return (
<nav aria-label={t(scope === "goal" ? "capabilities.catalog" : "machine.capabilityCatalog")} className="personal-capability-list" tabIndex={0}>
{orderCapabilitiesForPresentation(capabilities, locale).map((rawCapability) => {
if (memory.length && isMemoryCapability(rawCapability.capability_id)) {
if (memoryRendered) return null;
memoryRendered = true;
return <button aria-current={memorySelected ? "page" : undefined} key="memory-sources"
onClick={() => onSelect(memorySelected ? selectedCapabilityId : memory[0].capability_id)} type="button">
<span><strong>{memorySettingsTitle(locale)}</strong></span>
</button>;
}
const capability = localizeCapability(rawCapability, locale);
return (
<button
Expand All @@ -114,6 +126,22 @@ export function CapabilityCatalogNavigation({
);
}

export function CapabilityConfigurationHelp({capability, locale}: Readonly<{
capability: CapabilityDescriptor;
locale: WorkspaceLocale;
}>) {
const localized = localizeCapability(capability, locale);
return <details className="personal-capability-help" key={capability.capability_id}>
<summary>{locale === "zh-CN" ? "配置说明" : "Configuration help"}</summary>
<p>{localized.description}</p>
<dl>{capability.configuration_editor.fields.map(field => {
const copy = localizedCapabilityFieldCopy(locale, capability.capability_id)[field.key];
const description = copy?.description ?? field.description;
return description ? <div key={field.key}><dt>{copy?.label ?? field.label}</dt><dd>{description}</dd></div> : null;
})}</dl>
</details>;
}

export function CapabilityDetailHeader({ capability, locale, source }: Readonly<{
capability: CapabilityDescriptor;
locale: WorkspaceLocale;
Expand Down Expand Up @@ -152,15 +180,7 @@ export function CapabilityDetailHeader({ capability, locale, source }: Readonly<
: "LoopX Turn includes context in requests and results. For native tools, the LoopX skill reads the same interface. Execution and adoption require run evidence."}</p>
</details>
)}
<details className="personal-capability-help" key={capability.capability_id}>
<summary>{locale === "zh-CN" ? "配置说明" : "Configuration help"}</summary>
<p>{localized.description}</p>
<dl>{capability.configuration_editor.fields.map((field) => {
const copy = localizedCapabilityFieldCopy(locale, capability.capability_id)[field.key];
const description = copy?.description ?? field.description;
return description ? <div key={field.key}><dt>{copy?.label ?? field.label}</dt><dd>{description}</dd></div> : null;
})}</dl>
</details>
<CapabilityConfigurationHelp capability={capability} locale={locale} />
</div>
</header>
);
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading