Platform bundle: marketing publish, IT ops, packaging, agents mesh.

Volledige Foodlinkk Command Center uitbreiding met social automatisering,
reclamefolder filters, Proxmox monitoring en documentatie.
This commit is contained in:
Aissa
2026-06-09 00:41:27 +00:00
commit 5d60d33db1
212 changed files with 30044 additions and 0 deletions
+92
View File
@@ -0,0 +1,92 @@
{% extends "base.html" %}
{% block content %}
<div x-data="hermanChat()" class="chat-layout">
<header class="page-header">
<h1>Herman</h1>
<p class="subtitle page-tip">Co-CEO orchestrator — routes your message to specialist agents.</p>
</header>
<div class="card card-compact" style="margin-bottom:1rem;">
<h2 style="font-size:1rem;margin:0 0 .5rem;">Foto genereren (ComfyUI)</h2>
<p class="page-tip" style="margin:0 0 .75rem;">Beschrijf wat je wilt zien. Op CPU duurt dit 13 minuten.</p>
<form class="chat-input" @submit.prevent="generateImage">
<input class="form-input" x-model="imagePrompt" placeholder="bijv. halal kipnuggets productfoto, studio licht" autocomplete="off" />
<button class="btn btn-primary" type="submit" :disabled="generating">
<span x-show="!generating">Genereer</span>
<span x-show="generating">Bezig…</span>
</button>
</form>
<div x-show="generating" class="page-tip" style="margin-top:.5rem;">Ik ga even de gegevens ophalen — afbeelding wordt gemaakt…</div>
<div x-show="lastImage" style="margin-top:1rem;">
<img :src="lastImage" alt="Gegenereerde afbeelding" style="max-width:100%;border-radius:8px;border:1px solid var(--border);" />
</div>
</div>
<div class="chat-messages" id="chat-log">
{% if user_message %}<div class="chat-msg user"><p>{{ user_message }}</p></div>{% endif %}
{% if last_reply %}<div class="chat-msg agent"><span class="badge">{{ last_agent }}</span><p>{{ last_reply }}</p></div>{% endif %}
{% for h in history[:10] %}
<div class="chat-msg agent"><small>{{ h.created_at }}</small><p>{{ h.title or h.body }}</p></div>
{% endfor %}
</div>
<form class="chat-input" @submit.prevent="send">
<input class="form-input" x-model="message" placeholder="Message Herman… (bijv. maak foto: product op witte achtergrond)" autocomplete="off" />
<button class="btn btn-primary" type="submit" :disabled="loading">Send</button>
</form>
</div>
{% endblock %}
{% block scripts %}
<script>
function esc(s) { const d = document.createElement('div'); d.textContent = s || ''; return d.innerHTML; }
function hermanChat() {
return {
message: '',
imagePrompt: '',
loading: false,
generating: false,
lastImage: '',
async send() {
if (!this.message.trim()) return;
this.loading = true;
const msg = this.message;
try {
const r = await Cockpit.api('/api/herman/chat', { method: 'POST', body: JSON.stringify({ message: msg }) });
const log = document.getElementById('chat-log');
log.innerHTML += '<div class="chat-msg user"><p>' + esc(msg) + '</p></div>';
let badge = esc(r.agent_label || 'Herman');
if (r.delegated_agents && r.delegated_agents.length > 1) {
badge += ' · ' + esc(r.delegated_agents.join(', '));
}
let html = '<div class="chat-msg agent"><span class="badge">' + badge + '</span><p>' + esc(r.reply || '') + '</p>';
if (r.image_url) {
html += '<img src="' + r.image_url + '" alt="Gegenereerd" style="max-width:100%;margin-top:.5rem;border-radius:8px;" />';
this.lastImage = r.image_url;
}
html += '</div>';
log.innerHTML += html;
this.message = '';
} catch (e) { Cockpit.toast(e.message, 'error'); }
this.loading = false;
},
async generateImage() {
if (!this.imagePrompt.trim()) return;
this.generating = true;
this.lastImage = '';
try {
const r = await Cockpit.api('/api/ai/generate-image', {
method: 'POST',
body: JSON.stringify({ prompt: this.imagePrompt, width: 512, height: 512, steps: 15 })
});
if (r.proxy_url) {
this.lastImage = r.proxy_url;
const log = document.getElementById('chat-log');
log.innerHTML += '<div class="chat-msg agent"><span class="badge">Design</span><p>Afbeelding klaar: ' + esc(this.imagePrompt) + '</p><img src="' + r.proxy_url + '" alt="Gegenereerd" style="max-width:100%;margin-top:.5rem;border-radius:8px;" /></div>';
}
Cockpit.toast('Afbeelding gegenereerd', 'success');
} catch (e) { Cockpit.toast(e.message, 'error'); }
this.generating = false;
}
};
}
</script>
{% endblock %}