// script.js – Shared logic
// Utilities
const $ = (sel) => document.querySelector(sel);
const $$ = (sel) => [...document.querySelectorAll(sel)];
// Router
function showPage(id) {
$$('.page').forEach(p => p.classList.add('hidden'));
$(`#${id}`).classList.remove('hidden');
}
window.showPage = showPage;
// Mock Model Registry
export const MODELS = [
{
id: 1,
name: "HuggingFace BERT",
type: "language",
description: "Pre-trained transformer for NLP tasks like classification or Q&A.",
endpoint: "https://api.mock/bert",
tags: ["text", "classification", "embedding", "transformer"]
},
{
id: 2,
name: "Facebook Prophet",
type: "time-series",
description: "Forecasting tool for seasonal and trend time-series data.",
endpoint: "https://api.mock/prophet",
tags: ["forecast", "timeseries", "seasonality", "trend"]
},
{
id: 3,
name: "YOLOv8",
type: "vision",
description: "State-of-the-art object detection and segmentation model.",
endpoint: "https://api.mock/yolo",
tags: ["image", "detection", "objects", "realtime"]
},
{
id: 4,
name: "Stable Diffusion",
type: "generative",
description: "Generate high-quality images from text prompts.",
endpoint: "https://api.mock/sd",
tags: ["image", "generation", "text2img", "diffusion"]
}
];
// Knowledge Graph
export const TASK_KEYWORDS = {
"forecast": ["time-series"],
"sales": ["time-series"],
"image": ["vision", "generative"],
"generate": ["generative"],
"text": ["language"],
"detect": ["vision"],
"report": ["language"],
"trend": ["time-series"]
};
// Simple state
window.workflowModels = [];
// Render Marketplace
function renderModels(filter = "") {
const grid = $("#model-grid");
grid.innerHTML = "";
const typeFilter = $(".tag-btn.active")?.dataset.type || "";
MODELS.filter(m => {
if (typeFilter && m.type !== typeFilter) return false;
if (filter && !m.name.toLowerCase().includes(filter.toLowerCase()) && !m.tags.some(t => t.toLowerCase().includes(filter.toLowerCase()))) return false;
return true;
}).forEach(m => {
const card = document.createElement("model-card");
card.setAttribute("data-id", m.id);
card.setAttribute("data-name", m.name);
card.setAttribute("data-type", m.type);
card.setAttribute("data-desc", m.description);
card.setAttribute("data-tags", JSON.stringify(m.tags));
grid.appendChild(card);
});
feather.replace();
}
window.renderModels = renderModels;
// Planner Agent
function planWorkflow(task) {
const logs = [];
logs.push(`🔍 Planner received task: "${task}"`);
const words = task.toLowerCase().split(/\W+/);
const matchedTypes = new Set();
words.forEach(w => {
if (TASK_KEYWORDS[w]) {
TASK_KEYWORDS[w].forEach(t => matchedTypes.add(t));
}
});
logs.push(`📊 Matched types: ${[...matchedTypes].join(", ")}`);
const suggested = MODELS.filter(m => matchedTypes.has(m.type));
logs.push(`✅ Suggested models: ${suggested.map(m => m.name).join(", ")}`);
const panel = $("#workflow-suggestion");
panel.innerHTML = `
Suggested Workflow:
${suggested.map(m => `
${m.name}
${m.description}
`).join("")}
`;
// Log Panel Update
const logPanel = document.querySelector("log-panel");
if (logPanel) logPanel.logs = logs;
// Bind add buttons
$$(".add-to-workflow-btn").forEach(btn => {
btn.onclick = () => {
const id = Number(btn.dataset.id);
if (!window.workflowModels.find(m => m.id === id)) {
window.workflowModels.push(MODELS.find(m => m.id === id));
renderWorkflowStudio();
}
};
});
}
// Workflow Studio
function renderWorkflowStudio() {
const studio = $("#workflow-studio");
if (!window.workflowModels.length) {
studio.innerHTML = `No models added yet. Visit Marketplace or Agents to add.
`;
return;
}
studio.innerHTML = `
${window.workflowModels.map((m, idx) => `
${m.name}
${m.type} • ${m.description}
`).join("")}
`;
feather.replace();
bindReorder();
$$(".remove-model-btn").forEach(btn => {
btn.onclick = () => {
const idx = Number(btn.dataset.index);
window.workflowModels.splice(idx, 1);
renderWorkflowStudio();
};
};
$("#run-workflow-btn").onclick = runWorkflow;
}
// Drag Reorder
function bindReorder() {
const list = $("#workflow-list");
let dragged = null;
list.querySelectorAll("[draggable=true]").forEach(el => {
el.ondragstart = (e) => { dragged = e.target.closest("[data-index]"); };
el.ondragover = (e) => e.preventDefault();
el.ondrop = (e) => {
e.preventDefault();
const target = e.target.closest("[data-index]");
if (!target || target === dragged) return;
const from = Number(dragged.dataset.index);
const to = Number(target.dataset.index);
const temp = window.workflowModels[from];
window.workflowModels[from] = window.workflowModels[to];
window.workflowModels[to] = temp;
renderWorkflowStudio();
};
});
}
// Run Workflow
async function runWorkflow() {
const results = $("#workflow-results");
results.innerHTML = `Running...
`;
const logs = [];
const outputs = [];
for (const m of window.workflowModels) {
logs.push(`🚀 Calling ${m.name} at ${m.endpoint}`);
await new Promise(r => setTimeout(r, 600)); // mock latency
let out = `[Mock Output] ${m.name}: `;
if (m.type === "language") out += "Generated text summary.";
if (m.type === "time-series") out += "Sales forecast chart data.";
if (m.type === "vision") out += "Detected 5 objects.";
if (m.type === "generative") out += `
`;
outputs.push(out);
logs.push(`✅ ${m.name} responded`);
}
logs.push("✨ Workflow complete");
const logPanel = document.querySelector("log-panel");
if (logPanel) logPanel.logs = logs;
results.innerHTML = `
Results:
${outputs.map(o => `
${o}
`).join("")}
`;
}
// Init
document.addEventListener("DOMContentLoaded", () => {
renderModels();
// Search
$("#search-input").addEventListener("input", e => renderModels(e.target.value));
// Type Filter
$(".tag-btn").forEach(btn => {
btn.onclick = () => {
$(".tag-btn").forEach(b => b.classList.remove("active"));
btn.classList.add("active");
renderModels();
};
});
// Planner
$("#plan-btn").onclick = () => {
const task = $("#task-input").value.trim();
if (!task) return;
planWorkflow(task);
};
// Workflow Studio
window.renderWorkflowStudio = renderWorkflowStudio;
renderWorkflowStudio();
});