Q114: goal audits use the org's own auditor model and see pointers, not the executor's account
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0ae014af05
commit
abfcbf4824
19 files changed
+252
-41
No files matched your search
@@ -390,6 +390,10 @@ export const zh: Record<string, string> = {
|
||||
"Replaced by an edit": "已因编辑被替换",
|
||||
"Changed since approval": "批准后已改动",
|
||||
"Removed since approval": "批准后已删除",
|
||||
"Goal audit": "目标审查",
|
||||
"An independent model checks every goal before it closes. Pick one your agents do not use, ideally from another provider.": "每个目标关闭前都由一个独立模型检查。请选择 Agent 不使用的模型,最好来自另一家服务商。",
|
||||
"No auditor is set, so goals cannot be closed yet.": "尚未设置审查模型,目标暂时无法关闭。",
|
||||
"Choose a provider": "选择服务商",
|
||||
"Could not check approved content: {message}": "无法核对已批准内容:{message}",
|
||||
"Revoke {name}": "撤销 {name}",
|
||||
"Grant {name} to": "把 {name} 授予",
|
||||
|
||||
@@ -63,6 +63,7 @@ export function SettingsPage({ snapshot, actions }: PageProps) {
|
||||
{tab === "advanced" && (
|
||||
<AdvancedPanel
|
||||
orgId={orgId}
|
||||
organization={organization}
|
||||
agents={agents}
|
||||
providers={providers}
|
||||
catalog={snapshot.providerCatalog}
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { ProviderRateLimitStateRecord } from "../../../../shared/provider-r
|
||||
import type {
|
||||
AgentRecord,
|
||||
HiringPolicyRecord,
|
||||
OrganizationRecord,
|
||||
ProviderCatalogEntry,
|
||||
ProviderRecord,
|
||||
ProviderRequestRecord,
|
||||
@@ -10,12 +11,14 @@ import type {
|
||||
} from "../../../../shared/domain";
|
||||
import type { SnapshotActions } from "../../app/useSnapshot";
|
||||
import { BillingPanel } from "./BillingPanel";
|
||||
import { GoalAuditPanel } from "./GoalAuditPanel";
|
||||
import { ProviderRequestPanel } from "./ProviderRequestPanel";
|
||||
import { t } from "../../i18n/i18n";
|
||||
|
||||
/** The low-frequency operator surfaces, one section each. */
|
||||
export function AdvancedPanel({
|
||||
orgId,
|
||||
organization,
|
||||
agents,
|
||||
providers,
|
||||
catalog,
|
||||
@@ -27,6 +30,7 @@ export function AdvancedPanel({
|
||||
actions,
|
||||
}: {
|
||||
orgId: string;
|
||||
organization: OrganizationRecord;
|
||||
agents: AgentRecord[];
|
||||
providers: ProviderRecord[];
|
||||
catalog: ProviderCatalogEntry[];
|
||||
@@ -55,6 +59,10 @@ export function AdvancedPanel({
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div style={{ marginTop: 28 }}>
|
||||
<GoalAuditPanel organization={organization} providers={connected} actions={actions} />
|
||||
</div>
|
||||
|
||||
<div style={{ marginTop: 28 }}>
|
||||
<BillingPanel agents={agents} providers={providers} usage={usage} providerRateLimits={providerRateLimits} hiringPolicies={hiringPolicies} />
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import { useState, type FormEvent } from "react";
|
||||
import type { OrganizationRecord, ProviderRecord } from "../../../../shared/domain";
|
||||
import type { SnapshotActions } from "../../app/useSnapshot";
|
||||
import { Button, Field } from "../../shared/ui";
|
||||
import { t } from "../../i18n/i18n";
|
||||
|
||||
/** The model that audits goal completion; it must differ from the executor's so the two do not share one model's blind spots. */
|
||||
export function GoalAuditPanel({ organization, providers, actions }: { organization: OrganizationRecord; providers: ProviderRecord[]; actions: SnapshotActions }) {
|
||||
const [providerId, setProviderId] = useState(organization.auditProviderId ?? "");
|
||||
const [modelId, setModelId] = useState(organization.auditModelId ?? "");
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const save = (event: FormEvent) => {
|
||||
event.preventDefault();
|
||||
setError(null);
|
||||
void actions.run(() => window.agentCompany.setGoalAuditor({ orgId: organization.id, providerId, modelId }))
|
||||
.catch((reason: unknown) => setError(reason instanceof Error ? reason.message : String(reason)));
|
||||
};
|
||||
return (
|
||||
<section>
|
||||
<div className="section-label" style={{ marginBottom: 6 }}>{t("Goal audit")}</div>
|
||||
<p style={{ color: "var(--text-2)", fontSize: 13, margin: "0 0 12px" }}>
|
||||
{t("An independent model checks every goal before it closes. Pick one your agents do not use, ideally from another provider.")}
|
||||
</p>
|
||||
{!organization.auditModelId && (
|
||||
<p style={{ color: "var(--red)", fontSize: 13, margin: "0 0 12px" }}>{t("No auditor is set, so goals cannot be closed yet.")}</p>
|
||||
)}
|
||||
<form className="row" style={{ gap: 10, alignItems: "flex-end" }} onSubmit={save}>
|
||||
<Field label={t("Provider")}>
|
||||
<select className="input" value={providerId} onChange={(event) => setProviderId(event.target.value)} required>
|
||||
<option value="" disabled>{t("Choose a provider")}</option>
|
||||
{providers.map((provider) => <option key={provider.id} value={provider.id}>{provider.label}</option>)}
|
||||
</select>
|
||||
</Field>
|
||||
<Field label={t("Model")}>
|
||||
<input className="input" value={modelId} onChange={(event) => setModelId(event.target.value)} placeholder="claude-opus-5-5" required />
|
||||
</Field>
|
||||
<Button type="submit">{t("Save")}</Button>
|
||||
</form>
|
||||
{error && <p style={{ color: "var(--red)", fontSize: 13, margin: "8px 0 0" }}>{error}</p>}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user