feat: initial public release (MAESTRO)

This commit is contained in:
oss-sync
2026-06-03 05:08:00 +00:00
commit f5c7666f6b
823 changed files with 184150 additions and 0 deletions
@@ -0,0 +1,209 @@
import { HelpText } from './HelpText';
import { FieldLabel, FieldInput } from './formUtils';
import type { SectionFormProps } from './types';
/**
* Reflection (Hermes mode) settings.
*
* Toggle + caps for the per-job reflection loop that auto-updates a user's
* persistent memory. See `src/engine/reflection/` and the design doc at
* docs/superpowers/specs/2026-05-11-self-improving-memory-design.md.
*
* For Reflection to actually run, a worker with `roles: [reflection]` must
* exist in the LLM Workers tab. Otherwise (with the default `worker_required`)
* jobs are silently skipped.
*/
export function ReflectionForm({ config, onChange }: SectionFormProps) {
const reflection = config.reflection ?? {};
// Step 7 (design 2026-05-21): read v2 `llm.workers`. The v2 API contract
// already strips the legacy `provider` block from GET /api/config, so
// falling back to it would always be empty. Kept as a defensive `?? []`
// for the brief window where draft state may still be undefined.
const workers = config.llm?.workers ?? [];
const hasReflectionWorker = workers.some(
(w: { roles?: string[] }) => Array.isArray(w.roles) && w.roles.includes('reflection'),
);
const enabled = reflection.enabled === true;
return (
<div className="space-y-5">
<h2 className="text-base font-semibold text-slate-800">Reflection (Hermes mode)</h2>
<p className="text-xs text-slate-600 leading-relaxed">
LLM memory
(<code className="font-mono text-2xs">data/users/{'{userId}'}/memory/</code>)
custom piece snapshot
Memory &amp; Learning revert
</p>
<div>
<label className="flex items-center gap-2 text-sm text-slate-700">
<input
type="checkbox"
checked={enabled}
onChange={e => onChange('reflection.enabled', e.target.checked)}
className="rounded"
/>
<span className="font-semibold">Reflection </span>
</label>
<HelpText>
ON reflection memory
デフォルト: 無効
</HelpText>
</div>
{enabled && !hasReflectionWorker && (
<div className="rounded-md border border-amber-300 bg-amber-50 px-3 py-2 text-xs text-amber-900">
<div className="font-semibold mb-1"> Reflection worker </div>
<div>
Reflection <code className="font-mono">roles</code>
<code className="font-mono">reflection</code> worker
enqueue <strong>LLM Workers</strong> worker
:
</div>
<pre className="mt-2 text-2xs font-mono bg-white border border-amber-200 rounded p-2 overflow-auto">{`id: reflection-1
connection_type: direct
endpoint: http://localhost:11434/v1
model: qwen2.5:3b # cheap モデル推奨
roles: [reflection]
max_concurrency: 1`}</pre>
</div>
)}
<div>
<label className="flex items-center gap-2 text-sm text-slate-700">
<input
type="checkbox"
checked={reflection.workerRequired !== false}
onChange={e => onChange('reflection.workerRequired', e.target.checked)}
className="rounded"
/>
reflection worker
</label>
<HelpText>
ON: <code className="font-mono">roles: [reflection]</code> worker
reflection enqueue ()OFF enabled
worker
</HelpText>
</div>
<h3 className="text-sm font-medium text-slate-600 mt-4 pt-3 border-t border-slate-200">Caps</h3>
<div>
<FieldLabel>Max memory changes per job</FieldLabel>
<FieldInput
type="number"
value={reflection.maxMemoryChangesPerJob ?? 3}
onChange={v => onChange('reflection.maxMemoryChangesPerJob', Number(v))}
/>
<HelpText>1 reflection memory entry デフォルト: 3</HelpText>
</div>
<div>
<FieldLabel>Max entry body bytes</FieldLabel>
<FieldInput
type="number"
value={reflection.maxEntryBodyBytes ?? 8192}
onChange={v => onChange('reflection.maxEntryBodyBytes', Number(v))}
/>
<HelpText>memory entry body semantic validator rejectデフォルト: 8192</HelpText>
</div>
<div>
<FieldLabel>Piece edit cooldown (hours)</FieldLabel>
<FieldInput
type="number"
value={reflection.pieceEditCooldownHours ?? 24}
onChange={v => onChange('reflection.pieceEditCooldownHours', Number(v))}
/>
<HelpText> piece cooldownデフォルト: 24 (24h 2 3 )</HelpText>
</div>
<div>
<FieldLabel>Activity log max bytes</FieldLabel>
<FieldInput
type="number"
value={reflection.activityLogMaxBytes ?? 4096}
onChange={v => onChange('reflection.activityLogMaxBytes', Number(v))}
/>
<HelpText>reflection LLM activity log デフォルト: 4096</HelpText>
</div>
<h3 className="text-sm font-medium text-slate-600 mt-4 pt-3 border-t border-slate-200">Budget</h3>
<div>
<FieldLabel>Per-user daily budget (tokens)</FieldLabel>
<FieldInput
type="number"
value={reflection.perUserDailyBudgetTokens ?? 200000}
onChange={v => onChange('reflection.perUserDailyBudgetTokens', Number(v))}
/>
<HelpText>1 1 reflection token reflection enqueue デフォルト: 200000</HelpText>
</div>
<h3 className="text-sm font-medium text-slate-600 mt-4 pt-3 border-t border-slate-200">Snapshot &amp; Retention</h3>
<div>
<FieldLabel>Snapshot retention (days)</FieldLabel>
<FieldInput
type="number"
value={reflection.snapshotRetentionDays ?? 90}
onChange={v => onChange('reflection.snapshotRetentionDays', Number(v))}
/>
<HelpText>reflection-history snapshot デフォルト: 90</HelpText>
</div>
<div>
<FieldLabel>Snapshot max bytes per user</FieldLabel>
<FieldInput
type="number"
value={reflection.snapshotMaxBytesPerUser ?? 100 * 1024 * 1024}
onChange={v => onChange('reflection.snapshotMaxBytesPerUser', Number(v))}
/>
<HelpText>1 snapshot (bytes)デフォルト: 100 MiB</HelpText>
</div>
<div>
<FieldLabel>Snapshot max bytes per entry</FieldLabel>
<FieldInput
type="number"
value={reflection.snapshotMaxBytesPerEntry ?? 1 * 1024 * 1024}
onChange={v => onChange('reflection.snapshotMaxBytesPerEntry', Number(v))}
/>
<HelpText>1 snapshot (bytes)デフォルト: 1 MiB</HelpText>
</div>
<div>
<label className="flex items-center gap-2 text-sm text-slate-700">
<input
type="checkbox"
checked={reflection.storeLlmRaw === true}
onChange={e => onChange('reflection.storeLlmRaw', e.target.checked)}
className="rounded"
/>
LLM
</label>
<HelpText>
ON <code className="font-mono">llm-raw.json</code> snapshot
OFF ()
</HelpText>
</div>
<h3 className="text-sm font-medium text-slate-600 mt-4 pt-3 border-t border-slate-200">Monitoring</h3>
<div>
<FieldLabel>Abstain rate floor</FieldLabel>
<FieldInput
type="number"
value={reflection.abstainRateFloor ?? 0.3}
onChange={v => onChange('reflection.abstainRateFloor', v ? Number(v) : undefined)}
/>
<HelpText>
abstain () ()
デフォルト: 0.3 warn
max_memory_changes_per_job
</HelpText>
</div>
</div>
);
}