Add ultracode toggle that runs a request as a native dynamic workflow
A new transient per-request toggle state (off→plan→ultracode→fusion→moa) that whitelists the CLI's Workflow + Task tools so Anthropic's native dynamic-workflow orchestration runs in gott's headless -p mode without a permission gate (the engine silently denies Workflow otherwise). Effort is raised to xhigh (the real ultracode equivalent; "ultracode" itself is not a valid effort value) without downgrading an explicit max. Only enabled for Claude models (z.ai/GLM has no workflow runtime) and not in plan mode. The frontend injects a "use a workflow" hint, like plan mode injects its own. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
5418dc9225
commit
d5854a3f4b
7 files changed
+59
-12
No files matched your search
@@ -452,6 +452,11 @@
|
||||
background: color-mix(in srgb, var(--primary) 28%, transparent);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
#planModeBtn.ultracode-active {
|
||||
color: var(--info);
|
||||
background: color-mix(in srgb, var(--info) 18%, transparent);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
/* Emoji Picker */
|
||||
|
||||
|
||||
+2
-1
@@ -60,9 +60,10 @@ function apiMe() { return _get('/api/auth/me', null); }
|
||||
|
||||
// ── Chat API ──
|
||||
|
||||
function apiChat(content, sessionId, signal, planMode) {
|
||||
function apiChat(content, sessionId, signal, planMode, ultracode) {
|
||||
var payload = { content: content, sessionId: sessionId };
|
||||
if (planMode) payload.planMode = true;
|
||||
if (ultracode) payload.ultracode = true;
|
||||
return fetch('/api/chat', { method: 'POST', headers: _jsonHeaders, body: JSON.stringify(payload), signal: signal });
|
||||
}
|
||||
|
||||
|
||||
+23
-9
@@ -228,13 +228,14 @@ function handleStreamEvent(eventType, data) {
|
||||
//
|
||||
// _planModeActive bleibt als Compat-Variable (sendMessage + modals.js lesen sie direkt).
|
||||
|
||||
let _compositeMode = 'off'; // 'off' | 'plan' | 'fusion' | 'moa'
|
||||
let _compositeMode = 'off'; // 'off' | 'plan' | 'ultracode' | 'fusion' | 'moa'
|
||||
let _compositeHasAgents = false;
|
||||
|
||||
// Compat-Variablen – werden durch cycleCompositeMode / initCompositeMode synchron gehalten
|
||||
let _planModeActive = false; // true genau wenn _compositeMode === 'plan'
|
||||
let _ultracodeActive = false; // true genau wenn _compositeMode === 'ultracode' (transient, pro Request)
|
||||
|
||||
const _COMPOSITE_ORDER = ['off', 'plan', 'fusion', 'moa'];
|
||||
const _COMPOSITE_ORDER = ['off', 'plan', 'ultracode', 'fusion', 'moa'];
|
||||
|
||||
// Serialisierte Modus-Persistenz. Schnelles Durchklicken (off→plan→fusion→moa) feuert sonst
|
||||
// ÜBERLAPPENDE PATCHes, deren Commit-Reihenfolge nicht garantiert ist → der zuletzt committete
|
||||
@@ -247,14 +248,19 @@ let _modePersist = Promise.resolve();
|
||||
function _renderCompositeBtn() {
|
||||
var btn = $('#planModeBtn');
|
||||
if (!btn) return;
|
||||
btn.classList.remove('plan-mode-active', 'panel-mode-fusion', 'panel-mode-moa');
|
||||
btn.classList.remove('plan-mode-active', 'ultracode-active', 'panel-mode-fusion', 'panel-mode-moa');
|
||||
var icon = btn.querySelector('i');
|
||||
var input = $('#input');
|
||||
if (_compositeMode === 'plan') {
|
||||
btn.classList.add('plan-mode-active');
|
||||
if (icon) icon.className = 'fa fa-map';
|
||||
btn.title = 'Plan-Modus aktiv · klicken → Fusion';
|
||||
btn.title = 'Plan-Modus aktiv · klicken → Ultracode';
|
||||
if (input) input.placeholder = 'Planen...';
|
||||
} else if (_compositeMode === 'ultracode') {
|
||||
btn.classList.add('ultracode-active');
|
||||
if (icon) icon.className = 'fa fa-sitemap';
|
||||
btn.title = 'Ultracode aktiv (dynamischer Workflow) · klicken → Fusion';
|
||||
if (input) input.placeholder = 'Ultracode – als Workflow...';
|
||||
} else if (_compositeMode === 'fusion') {
|
||||
btn.classList.add('panel-mode-fusion');
|
||||
if (icon) icon.className = 'fa fa-users';
|
||||
@@ -278,6 +284,7 @@ function initCompositeMode(panelMode, hasAgents) {
|
||||
_compositeHasAgents = !!hasAgents;
|
||||
_compositeMode = (panelMode === 'fusion' || panelMode === 'moa') ? panelMode : 'off';
|
||||
_planModeActive = false;
|
||||
_ultracodeActive = false;
|
||||
_renderCompositeBtn();
|
||||
}
|
||||
|
||||
@@ -287,12 +294,13 @@ async function cycleCompositeMode() {
|
||||
var idx = _COMPOSITE_ORDER.indexOf(_compositeMode);
|
||||
_compositeMode = _COMPOSITE_ORDER[(idx + 1) % _COMPOSITE_ORDER.length];
|
||||
_planModeActive = (_compositeMode === 'plan');
|
||||
_ultracodeActive = (_compositeMode === 'ultracode');
|
||||
_renderCompositeBtn();
|
||||
|
||||
// Nur Fusion/MoA/Off brauchen einen Server-Call (Plan ist transient). Auf die serialisierte
|
||||
// Kette legen, damit aufeinanderfolgende Klicks in Reihenfolge committen (letzter Klick gewinnt)
|
||||
// und sendMessage das offene PATCH abwarten kann.
|
||||
if (_compositeMode !== 'plan') {
|
||||
// Nur Fusion/MoA/Off brauchen einen Server-Call (Plan + Ultracode sind transient pro Request).
|
||||
// Auf die serialisierte Kette legen, damit aufeinanderfolgende Klicks in Reihenfolge committen
|
||||
// (letzter Klick gewinnt) und sendMessage das offene PATCH abwarten kann.
|
||||
if (_compositeMode !== 'plan' && _compositeMode !== 'ultracode') {
|
||||
var sid = getCurrentSessionId();
|
||||
if (sid) {
|
||||
var targetMode = _compositeMode;
|
||||
@@ -310,6 +318,8 @@ async function cycleCompositeMode() {
|
||||
showToast('Modus: Aus', 'info');
|
||||
} else if (_compositeMode === 'plan') {
|
||||
showToast('Plan-Modus aktiv', 'info');
|
||||
} else if (_compositeMode === 'ultracode') {
|
||||
showToast('Ultracode aktiv – diese Anfrage läuft als dynamischer Workflow (mehr Tokens/Zeit)', 'info');
|
||||
} else if (!_compositeHasAgents) {
|
||||
showToast('Panel: ' + (_compositeMode === 'moa' ? 'MoA' : 'Fusion') + ' aktiv – aber keine Panel-Agenten konfiguriert (im Session-Bearbeiten festlegen)', 'info');
|
||||
} else {
|
||||
@@ -560,6 +570,10 @@ async function sendMessage() {
|
||||
msgText += `\n<hint>Plan-Modus ist aktiv. KEINE Dateien ändern, KEINE Shell-Befehle (außer read-only), KEINE Commits. Nur analysieren, Rückfragen stellen und Plan erstellen.</hint>`;
|
||||
}
|
||||
|
||||
if (_ultracodeActive) {
|
||||
msgText += `\n<hint>Ultracode ist aktiv: Bearbeite diese Anfrage als dynamischen Workflow – use a workflow. Fächere die Arbeit über mehrere Subagenten parallel auf, lass Befunde adversarial gegenprüfen und synthetisiere am Ende. Nutze dafür das Workflow-Tool.</hint>`;
|
||||
}
|
||||
|
||||
let inlineImages = []; // Bilder für Inline-Anzeige
|
||||
if (pendingFiles.length > 0) {
|
||||
content = [];
|
||||
@@ -595,7 +609,7 @@ async function sendMessage() {
|
||||
// (z.B. MoA → nur 1 Runde, weil das Backend noch 'fusion' liest).
|
||||
await _modePersist;
|
||||
|
||||
await _runStream((signal) => apiChat(content, getCurrentSessionId(), signal, _planModeActive));
|
||||
await _runStream((signal) => apiChat(content, getCurrentSessionId(), signal, _planModeActive, _ultracodeActive));
|
||||
}
|
||||
|
||||
// ── Steering (Einwurf in die laufende Chain) ──
|
||||
|
||||
Reference in new issue
Block a user