mirror of
https://github.com/agent0ai/agent-zero.git
synced 2026-07-10 01:18:29 +00:00
Promote the terminal agent work into the built-in plugins tree as _orchestrator with Orchestrator branding and the orchestrator skill. Include adapter status APIs, settings UI, per-agent skill references, thumbnail asset, tests, and DOX coverage for the bundled plugin.
504 lines
19 KiB
HTML
504 lines
19 KiB
HTML
<html>
|
|
<head>
|
|
<title>Orchestrator</title>
|
|
<script type="module" src="/plugins/_orchestrator/webui/orchestrator-store.js"></script>
|
|
<style>
|
|
.ta-settings {
|
|
display: grid;
|
|
gap: 16px;
|
|
}
|
|
.ta-header {
|
|
align-items: flex-start;
|
|
display: flex;
|
|
gap: 12px;
|
|
justify-content: space-between;
|
|
}
|
|
.ta-refresh.btn-icon-action {
|
|
border-radius: 8px;
|
|
color: var(--color-text);
|
|
height: 34px;
|
|
width: 34px;
|
|
}
|
|
.ta-usage {
|
|
color: var(--color-text);
|
|
font-size: 0.82rem;
|
|
line-height: 1.45;
|
|
margin-top: 10px;
|
|
max-width: 760px;
|
|
opacity: 0.82;
|
|
}
|
|
.ta-agent {
|
|
border: 1px solid var(--color-border, #333);
|
|
border-radius: 8px;
|
|
background: color-mix(in srgb, var(--color-background) 28%, transparent);
|
|
}
|
|
.ta-agent {
|
|
display: grid;
|
|
overflow: hidden;
|
|
padding: 0;
|
|
}
|
|
.ta-panel {
|
|
border-top: 1px solid color-mix(in srgb, var(--color-border) 50%, transparent);
|
|
display: grid;
|
|
gap: 16px;
|
|
padding: 16px;
|
|
}
|
|
summary.ta-agent-head {
|
|
cursor: pointer;
|
|
list-style: none;
|
|
}
|
|
summary.ta-agent-head::-webkit-details-marker {
|
|
display: none;
|
|
}
|
|
.ta-agent-head {
|
|
align-items: center;
|
|
display: grid;
|
|
gap: 12px;
|
|
grid-template-columns: minmax(0, 1fr) auto;
|
|
padding: 14px;
|
|
}
|
|
.ta-agent-copy {
|
|
display: grid;
|
|
gap: 4px;
|
|
min-width: 0;
|
|
}
|
|
.ta-agent-title {
|
|
align-items: baseline;
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 8px;
|
|
min-width: 0;
|
|
}
|
|
.ta-agent-title strong {
|
|
font-size: 0.94rem;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
.ta-agent-title code {
|
|
color: var(--color-text-secondary, #aaa);
|
|
}
|
|
.ta-actions {
|
|
align-items: center;
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 8px;
|
|
justify-content: flex-end;
|
|
}
|
|
.ta-action {
|
|
align-items: center;
|
|
background: #f5f7fa;
|
|
border: 0;
|
|
border-radius: 8px;
|
|
color: #111418;
|
|
cursor: pointer;
|
|
display: inline-flex;
|
|
font: inherit;
|
|
font-size: 0.76rem;
|
|
font-weight: 750;
|
|
gap: 6px;
|
|
justify-content: center;
|
|
min-height: 34px;
|
|
padding: 0 10px;
|
|
white-space: nowrap;
|
|
}
|
|
.ta-action.secondary {
|
|
background: color-mix(in srgb, var(--color-border) 44%, transparent);
|
|
border: 1px solid color-mix(in srgb, var(--color-border) 76%, transparent);
|
|
color: var(--color-text);
|
|
}
|
|
.ta-action.danger {
|
|
background: color-mix(in srgb, #f06464 16%, var(--color-panel, transparent));
|
|
border: 1px solid color-mix(in srgb, #f06464 40%, var(--color-border));
|
|
color: var(--color-text);
|
|
}
|
|
.ta-action:disabled {
|
|
cursor: default;
|
|
opacity: 0.65;
|
|
}
|
|
.ta-action .material-symbols-outlined {
|
|
font-size: 1rem;
|
|
}
|
|
.ta-form {
|
|
display: grid;
|
|
align-items: start;
|
|
gap: 16px 18px;
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
}
|
|
.ta-field {
|
|
display: grid;
|
|
gap: 7px;
|
|
min-width: 0;
|
|
}
|
|
.ta-field-toggle {
|
|
align-items: center;
|
|
grid-template-columns: minmax(0, 1fr) auto;
|
|
}
|
|
.ta-field-toggle .field-control {
|
|
justify-content: flex-end;
|
|
width: auto;
|
|
}
|
|
.ta-field .field-label {
|
|
display: grid;
|
|
gap: 3px;
|
|
padding-right: 0;
|
|
}
|
|
.ta-field .field-title {
|
|
color: color-mix(in srgb, var(--color-text) 78%, var(--color-primary));
|
|
font-size: 0.84rem;
|
|
font-weight: 800;
|
|
}
|
|
.ta-field .field-description {
|
|
color: var(--color-text);
|
|
font-size: 0.8rem;
|
|
line-height: 1.35;
|
|
margin: 0;
|
|
opacity: 0.78;
|
|
}
|
|
.ta-field .field-control {
|
|
min-width: 0;
|
|
width: 100%;
|
|
}
|
|
.ta-readonly-value {
|
|
align-items: center;
|
|
color: var(--color-text);
|
|
display: flex;
|
|
font-size: 0.82rem;
|
|
font-weight: 800;
|
|
min-height: 36px;
|
|
overflow-wrap: anywhere;
|
|
}
|
|
.ta-field input:not([type="checkbox"]),
|
|
.ta-field select {
|
|
background: color-mix(in srgb, var(--color-background) 72%, transparent);
|
|
border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
|
|
border-radius: 7px;
|
|
color: var(--color-text);
|
|
min-height: 36px;
|
|
width: 100%;
|
|
}
|
|
.ta-wide {
|
|
grid-column: 1 / -1;
|
|
}
|
|
.ta-expand {
|
|
color: var(--color-text-secondary, #aaa);
|
|
transition: transform 140ms ease;
|
|
}
|
|
.ta-agent[open] .ta-expand {
|
|
transform: rotate(180deg);
|
|
}
|
|
.ta-login {
|
|
background: color-mix(in srgb, var(--color-border) 18%, transparent);
|
|
border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
|
|
border-radius: 8px;
|
|
display: grid;
|
|
gap: 8px;
|
|
padding: 12px;
|
|
}
|
|
.ta-login code {
|
|
font-size: 1.2rem;
|
|
letter-spacing: 2px;
|
|
}
|
|
@media (max-width: 720px) {
|
|
.ta-form {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
.ta-header,
|
|
.ta-agent-head {
|
|
align-items: stretch;
|
|
grid-template-columns: 1fr;
|
|
}
|
|
.ta-actions {
|
|
justify-content: flex-start;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div x-data>
|
|
<template x-if="config && $store.orchestratorStore">
|
|
<div
|
|
class="ta-settings"
|
|
x-init="$store.orchestratorStore.onOpen()"
|
|
x-destroy="$store.orchestratorStore.cleanup()"
|
|
>
|
|
<div class="ta-header">
|
|
<div>
|
|
<div class="section-title">Orchestrator</div>
|
|
<div class="section-description">
|
|
Command defaults and advanced settings for the <code>orchestrator</code> skill.
|
|
</div>
|
|
<div class="ta-usage">
|
|
Ask Agent Zero for a coding agent, or describe the session you want to start.
|
|
For example: “Consult with Codex CLI on this heavy refactor before writing code.”
|
|
Or: “Create a council with Claude Code and Codex using the models and effort levels I specify.”
|
|
</div>
|
|
</div>
|
|
<button
|
|
class="btn-icon-action ta-refresh"
|
|
type="button"
|
|
title="Refresh status"
|
|
aria-label="Refresh status"
|
|
:disabled="$store.orchestratorStore.loading"
|
|
@click="$store.orchestratorStore.refresh()"
|
|
>
|
|
<span class="material-symbols-outlined" aria-hidden="true" x-text="$store.orchestratorStore.loading ? 'progress_activity' : 'refresh'"></span>
|
|
</button>
|
|
</div>
|
|
|
|
<template x-for="agent in $store.orchestratorStore.agents" :key="agent.id">
|
|
<details class="ta-agent" x-init="$store.orchestratorStore.ensureConfig(config, agent)">
|
|
<summary class="ta-agent-head">
|
|
<div class="ta-agent-copy">
|
|
<div class="ta-agent-title">
|
|
<strong x-text="agent.title"></strong>
|
|
<code x-text="agent.id"></code>
|
|
</div>
|
|
<div class="section-description" x-text="agent.description"></div>
|
|
</div>
|
|
<div class="ta-actions">
|
|
<button
|
|
class="ta-action"
|
|
type="button"
|
|
x-show="agent.installed && !agent.auth?.connected && agent.supports_device_login && (!$store.orchestratorStore.login || $store.orchestratorStore.login.agentId !== agent.id)"
|
|
@click.stop="$store.orchestratorStore.startLogin(agent.id)"
|
|
>
|
|
<span class="material-symbols-outlined" aria-hidden="true">login</span>
|
|
<span>Connect</span>
|
|
</button>
|
|
<button
|
|
class="ta-action danger"
|
|
type="button"
|
|
x-show="agent.auth?.connected && agent.can_disconnect"
|
|
:disabled="$store.orchestratorStore.disconnectingAgent === agent.id"
|
|
@click.stop="$store.orchestratorStore.disconnect(agent.id)"
|
|
>
|
|
<span class="material-symbols-outlined" aria-hidden="true" x-text="$store.orchestratorStore.disconnectingAgent === agent.id ? 'progress_activity' : 'link_off'"></span>
|
|
<span x-text="$store.orchestratorStore.disconnectingAgent === agent.id ? 'Disconnecting' : 'Disconnect'"></span>
|
|
</button>
|
|
<span class="material-symbols-outlined ta-expand" aria-hidden="true">expand_more</span>
|
|
</div>
|
|
</summary>
|
|
|
|
<div class="ta-panel">
|
|
<div class="ta-form">
|
|
<div class="ta-field">
|
|
<div class="field-label">
|
|
<div class="field-title">Binary</div>
|
|
<div class="field-description">Command name or absolute path.</div>
|
|
</div>
|
|
<div class="field-control">
|
|
<input type="text" x-model.trim="config[agent.id].binary" :placeholder="agent.id" spellcheck="false" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="ta-field">
|
|
<div class="field-label">
|
|
<div class="field-title">Auth</div>
|
|
<div class="field-description">Detected connection source.</div>
|
|
</div>
|
|
<div class="field-control">
|
|
<div class="ta-readonly-value" x-text="$store.orchestratorStore.authText(agent)"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="ta-field" x-show="agent.id === 'codex' || agent.id === 'claude' || agent.id === 'grok' || agent.id === 'hermes' || agent.id === 'opencode'">
|
|
<div class="field-label">
|
|
<div class="field-title">Model</div>
|
|
<div class="field-description">Optional CLI model override.</div>
|
|
</div>
|
|
<div class="field-control">
|
|
<input type="text" x-model.trim="config[agent.id].model" placeholder="default" spellcheck="false" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="ta-field" x-show="agent.id === 'hermes'">
|
|
<div class="field-label">
|
|
<div class="field-title">Provider</div>
|
|
<div class="field-description">Optional Hermes provider override.</div>
|
|
</div>
|
|
<div class="field-control">
|
|
<input type="text" x-model.trim="config[agent.id].provider" placeholder="openrouter" spellcheck="false" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="ta-field" x-show="agent.id === 'opencode'">
|
|
<div class="field-label">
|
|
<div class="field-title">Agent</div>
|
|
<div class="field-description">Optional OpenCode agent name.</div>
|
|
</div>
|
|
<div class="field-control">
|
|
<input type="text" x-model.trim="config[agent.id].agent" placeholder="build" spellcheck="false" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="ta-field ta-field-toggle" x-show="agent.id === 'codex'">
|
|
<div class="field-label">
|
|
<div class="field-title">Bypass sandbox</div>
|
|
<div class="field-description">Needed in this Docker runtime.</div>
|
|
</div>
|
|
<div class="field-control">
|
|
<label class="toggle">
|
|
<input type="checkbox" x-model="config[agent.id].bypass_sandbox" />
|
|
<span class="toggler"></span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="ta-field ta-field-toggle" x-show="agent.id === 'hermes'">
|
|
<div class="field-label">
|
|
<div class="field-title">Skip approvals</div>
|
|
<div class="field-description">Pass <code>--yolo</code> for non-interactive runs.</div>
|
|
</div>
|
|
<div class="field-control">
|
|
<label class="toggle">
|
|
<input type="checkbox" x-model="config[agent.id].yolo" />
|
|
<span class="toggler"></span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="ta-field ta-field-toggle" x-show="agent.id === 'cursor'">
|
|
<div class="field-label">
|
|
<div class="field-title">Force changes</div>
|
|
<div class="field-description">Pass <code>--force</code> so scripts can modify files.</div>
|
|
</div>
|
|
<div class="field-control">
|
|
<label class="toggle">
|
|
<input type="checkbox" x-model="config[agent.id].force" />
|
|
<span class="toggler"></span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="ta-field ta-field-toggle" x-show="agent.id === 'grok'">
|
|
<div class="field-label">
|
|
<div class="field-title">Always approve</div>
|
|
<div class="field-description">Pass <code>--always-approve</code> for headless runs.</div>
|
|
</div>
|
|
<div class="field-control">
|
|
<label class="toggle">
|
|
<input type="checkbox" x-model="config[agent.id].always_approve" />
|
|
<span class="toggler"></span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="ta-field ta-field-toggle" x-show="agent.id === 'grok'">
|
|
<div class="field-label">
|
|
<div class="field-title">No auto update</div>
|
|
<div class="field-description">Pass <code>--no-auto-update</code> in automation.</div>
|
|
</div>
|
|
<div class="field-control">
|
|
<label class="toggle">
|
|
<input type="checkbox" x-model="config[agent.id].no_auto_update" />
|
|
<span class="toggler"></span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="ta-field ta-field-toggle" x-show="agent.id === 'opencode'">
|
|
<div class="field-label">
|
|
<div class="field-title">Auto approve</div>
|
|
<div class="field-description">Pass <code>--auto</code> for non-interactive runs.</div>
|
|
</div>
|
|
<div class="field-control">
|
|
<label class="toggle">
|
|
<input type="checkbox" x-model="config[agent.id].auto" />
|
|
<span class="toggler"></span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="ta-field" x-show="agent.id === 'a0'">
|
|
<div class="field-label">
|
|
<div class="field-title">Host</div>
|
|
<div class="field-description">Empty uses the local Agent Zero runtime.</div>
|
|
</div>
|
|
<div class="field-control">
|
|
<input type="text" x-model.trim="config[agent.id].host" placeholder="http://localhost:80" spellcheck="false" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="ta-field" x-show="agent.id === 'claude'">
|
|
<div class="field-label">
|
|
<div class="field-title">Permission mode</div>
|
|
<div class="field-description">Claude Code permission preset.</div>
|
|
</div>
|
|
<div class="field-control">
|
|
<select x-model="config[agent.id].permission_mode">
|
|
<option value="bypassPermissions">Skip permissions</option>
|
|
<option value="acceptEdits">Accept edits</option>
|
|
<option value="default">Default</option>
|
|
<option value="plan">Plan</option>
|
|
<option value="auto">Auto</option>
|
|
<option value="dontAsk">Do not ask</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="ta-field" x-show="agent.id === 'claude'">
|
|
<div class="field-label">
|
|
<div class="field-title">Allowed tools</div>
|
|
<div class="field-description">Passed to <code>--allowedTools</code>.</div>
|
|
</div>
|
|
<div class="field-control">
|
|
<input type="text" x-model.trim="config[agent.id].allowed_tools" placeholder="Bash,Read,Edit" spellcheck="false" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="ta-field ta-field-toggle" x-show="agent.id === 'claude'">
|
|
<div class="field-label">
|
|
<div class="field-title">Bare mode</div>
|
|
<div class="field-description">Skip local Claude Code project discovery.</div>
|
|
</div>
|
|
<div class="field-control">
|
|
<label class="toggle">
|
|
<input type="checkbox" x-model="config[agent.id].bare" />
|
|
<span class="toggler"></span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="ta-field" x-show="agent.id === 'hermes'">
|
|
<div class="field-label">
|
|
<div class="field-title">Toolsets</div>
|
|
<div class="field-description">Comma-separated Hermes toolsets.</div>
|
|
</div>
|
|
<div class="field-control">
|
|
<input type="text" x-model.trim="config[agent.id].toolsets" placeholder="terminal,files" spellcheck="false" />
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<template x-if="$store.orchestratorStore.login && $store.orchestratorStore.login.agentId === agent.id">
|
|
<div class="ta-login">
|
|
<div>
|
|
1. Open
|
|
<a :href="$store.orchestratorStore.login.verificationUrl" target="_blank"
|
|
x-text="$store.orchestratorStore.login.verificationUrl"></a>
|
|
</div>
|
|
<div>
|
|
2. Enter code:
|
|
<code x-text="$store.orchestratorStore.login.userCode"></code>
|
|
</div>
|
|
<div>
|
|
Waiting for confirmation…
|
|
<button class="ta-action secondary" type="button" @click="$store.orchestratorStore.cancelLogin()">Cancel</button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</details>
|
|
</template>
|
|
|
|
<div x-show="!$store.orchestratorStore.loading && $store.orchestratorStore.agents.length === 0" style="opacity: 0.7;">
|
|
No agents registered.
|
|
</div>
|
|
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</body>
|
|
</html>
|