Compare commits
15 Commits
4d74c38618
...
4e83569194
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4e83569194 | ||
|
|
f42b692eeb | ||
|
|
f79bb16f3d | ||
|
|
e81fc33faf | ||
|
|
433726c553 | ||
|
|
dec2e24e2f | ||
|
|
9058033669 | ||
|
|
8bd86e6325 | ||
|
|
c1133bb075 | ||
|
|
6502d75efc | ||
|
|
9f8b7fe920 | ||
|
|
746bc20fcb | ||
|
|
93f6baa0ea | ||
|
|
cc8e871735 | ||
|
|
e90f3460c3 |
21
network-poc/Dockerfile.native
Normal file
21
network-poc/Dockerfile.native
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Native-node: Rust + Ollama-client (ei GPU-tunnistusta)
|
||||||
|
FROM rust:slim AS builder
|
||||||
|
RUN apt-get update && apt-get install -y pkg-config libssl-dev && rm -rf /var/lib/apt/lists/*
|
||||||
|
WORKDIR /app
|
||||||
|
COPY Cargo.toml Cargo.lock* ./
|
||||||
|
COPY native-node/Cargo.toml native-node/Cargo.toml
|
||||||
|
COPY native-node/src native-node/src
|
||||||
|
# Dummy-cratet workspace-yhteensopivuuteen
|
||||||
|
COPY hub/Cargo.toml hub/Cargo.toml
|
||||||
|
COPY node/Cargo.toml node/Cargo.toml
|
||||||
|
COPY cli/Cargo.toml cli/Cargo.toml
|
||||||
|
RUN mkdir -p hub/src node/src cli/src && touch hub/src/main.rs node/src/lib.rs cli/src/main.rs
|
||||||
|
RUN --mount=type=cache,target=/usr/local/cargo/registry \
|
||||||
|
--mount=type=cache,target=/app/target \
|
||||||
|
cargo build --release -p native-node --no-default-features \
|
||||||
|
&& cp /app/target/release/native-node /usr/local/bin/native-node
|
||||||
|
|
||||||
|
FROM debian:bookworm-slim
|
||||||
|
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
|
||||||
|
COPY --from=builder /usr/local/bin/native-node /usr/local/bin/native-node
|
||||||
|
CMD ["native-node"]
|
||||||
38
network-poc/build-binaries.sh
Executable file
38
network-poc/build-binaries.sh
Executable file
@@ -0,0 +1,38 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Käännä kipina-node binäärit kaikille alustoille
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
OUT="$SCRIPT_DIR/frontend/public/download"
|
||||||
|
mkdir -p "$OUT"
|
||||||
|
|
||||||
|
echo "=== Kipinä Node — Binary Build ==="
|
||||||
|
|
||||||
|
# macOS ARM (natiivi)
|
||||||
|
echo "[1/3] macOS ARM64..."
|
||||||
|
cd "$SCRIPT_DIR"
|
||||||
|
cargo build --release -p native-node --no-default-features 2>&1 | tail -1
|
||||||
|
cp target/release/native-node "$OUT/kipina-node-macos-arm64"
|
||||||
|
echo " $(ls -lh "$OUT/kipina-node-macos-arm64" | awk '{print $5}')"
|
||||||
|
|
||||||
|
# Linux x86_64 (Docker)
|
||||||
|
echo "[2/3] Linux x86_64..."
|
||||||
|
docker run --rm \
|
||||||
|
-v "$SCRIPT_DIR":/app -w /app \
|
||||||
|
--platform linux/amd64 \
|
||||||
|
rust:slim \
|
||||||
|
bash -c "apt-get update -qq && apt-get install -y -qq pkg-config libssl-dev >/dev/null 2>&1 && cargo build --release -p native-node --no-default-features 2>&1 | tail -1 && cp target/release/native-node /app/frontend/public/download/kipina-node-linux-x86_64"
|
||||||
|
echo " $(ls -lh "$OUT/kipina-node-linux-x86_64" | awk '{print $5}')"
|
||||||
|
|
||||||
|
# Linux ARM64 (Docker)
|
||||||
|
echo "[3/3] Linux ARM64..."
|
||||||
|
docker run --rm \
|
||||||
|
-v "$SCRIPT_DIR":/app -w /app \
|
||||||
|
--platform linux/arm64 \
|
||||||
|
rust:slim \
|
||||||
|
bash -c "apt-get update -qq && apt-get install -y -qq pkg-config libssl-dev >/dev/null 2>&1 && cargo build --release -p native-node --no-default-features 2>&1 | tail -1 && cp target/release/native-node /app/frontend/public/download/kipina-node-linux-arm64"
|
||||||
|
echo " $(ls -lh "$OUT/kipina-node-linux-arm64" | awk '{print $5}')"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Binäärit valmiina ==="
|
||||||
|
ls -lh "$OUT"/kipina-node-*
|
||||||
28
network-poc/deploy-fast.sh
Executable file
28
network-poc/deploy-fast.sh
Executable file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Nopea deploy: päivittää vain frontendin (ei kontin uudelleenkäynnistystä)
|
||||||
|
# Hub-binäärin päivitys: käytä deploy.sh tai deploy-light.sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SERVER="ubuntu@86.50.252.98"
|
||||||
|
REMOTE_DIR="~/code/agentic-studio/network-poc"
|
||||||
|
SSH_OPTS="-o StrictHostKeyChecking=no"
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
|
||||||
|
echo "=== Kipinä Studio — Frontend Deploy ==="
|
||||||
|
|
||||||
|
# 1. Buildaa frontend paikallisesti
|
||||||
|
echo "[1/2] Rakennetaan frontend..."
|
||||||
|
cd "$SCRIPT_DIR/frontend"
|
||||||
|
[ -d node_modules ] || npm install --silent
|
||||||
|
npm run build --silent 2>&1 | tail -1
|
||||||
|
|
||||||
|
# 2. Synkataan dist/ palvelimelle (vain muuttuneet tiedostot)
|
||||||
|
echo "[2/2] Synkataan dist/ → palvelin..."
|
||||||
|
ssh $SSH_OPTS $SERVER "mkdir -p $REMOTE_DIR/frontend/dist"
|
||||||
|
rsync -az --delete -e "ssh $SSH_OPTS" "$SCRIPT_DIR/frontend/dist/" "$SERVER:$REMOTE_DIR/frontend/dist/"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Valmis! Frontend päivitetty — ei uudelleenkäynnistystä ==="
|
||||||
|
echo " https://kipina.studio"
|
||||||
|
echo ""
|
||||||
|
echo "Huom: Jos Rust-koodi (hub/) muuttui, aja: ./deploy.sh"
|
||||||
@@ -19,8 +19,12 @@ services:
|
|||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
- DATABASE_PATH=/data/nodes.db
|
- DATABASE_PATH=/data/nodes.db
|
||||||
|
- STATIC_DIR=/app/frontend/dist
|
||||||
|
- ADMIN_PASSWORD=${ADMIN_PASSWORD:-}
|
||||||
|
- NODE_API_KEY=${NODE_API_KEY:-}
|
||||||
volumes:
|
volumes:
|
||||||
- hub_data:/data
|
- hub_data:/data
|
||||||
|
- ./frontend/dist:/app/frontend/dist:ro
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
caddy_data:
|
caddy_data:
|
||||||
|
|||||||
BIN
network-poc/frontend/public/download/kipina-node-linux-x86_64
Executable file
BIN
network-poc/frontend/public/download/kipina-node-linux-x86_64
Executable file
Binary file not shown.
BIN
network-poc/frontend/public/download/kipina-node-macos-arm64
Executable file
BIN
network-poc/frontend/public/download/kipina-node-macos-arm64
Executable file
Binary file not shown.
73
network-poc/frontend/public/join.sh
Normal file
73
network-poc/frontend/public/join.sh
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Kipinä — liitä koneesi laskentaverkkoon
|
||||||
|
set -e
|
||||||
|
|
||||||
|
HUB_URL="${KIPINA_HUB:-wss://kipina.studio/ws}"
|
||||||
|
MODEL="${KIPINA_MODEL:-qwen2.5-coder:3b}"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo " ╔══════════════════════════════════════╗"
|
||||||
|
echo " ║ Kipinä Agentic Network — Node Join ║"
|
||||||
|
echo " ╚══════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 1. Ollama
|
||||||
|
if command -v ollama &>/dev/null; then
|
||||||
|
echo " ✓ Ollama löytyi: $(ollama --version 2>/dev/null || echo 'asennettu')"
|
||||||
|
else
|
||||||
|
echo " Ollama ei ole asennettu."
|
||||||
|
echo ""
|
||||||
|
read -p " Asennetaanko Ollama? (k/e) " -n 1 -r; echo
|
||||||
|
if [[ $REPLY =~ ^[Kk]$ ]]; then
|
||||||
|
echo " Asennetaan Ollama..."
|
||||||
|
curl -fsSL https://ollama.ai/install.sh | sh
|
||||||
|
else
|
||||||
|
echo " Ollama vaaditaan laskentaan. Asenna: https://ollama.ai"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. Varmistetaan että Ollama on käynnissä
|
||||||
|
if ! curl -s http://localhost:11434/api/tags &>/dev/null; then
|
||||||
|
echo " Käynnistetään Ollama..."
|
||||||
|
ollama serve &>/dev/null &
|
||||||
|
sleep 3
|
||||||
|
if ! curl -s http://localhost:11434/api/tags &>/dev/null; then
|
||||||
|
echo " ✗ Ollama ei käynnistynyt. Aja: ollama serve"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo " ✓ Ollama käynnissä"
|
||||||
|
|
||||||
|
# 3. Malli
|
||||||
|
if ollama list 2>/dev/null | grep -q "$MODEL"; then
|
||||||
|
echo " ✓ Malli $MODEL ladattu"
|
||||||
|
else
|
||||||
|
echo " Ladataan malli $MODEL..."
|
||||||
|
ollama pull "$MODEL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 4. Native-node
|
||||||
|
echo ""
|
||||||
|
echo " Yhdistetään hubiin: $HUB_URL"
|
||||||
|
echo " Malli: $MODEL"
|
||||||
|
echo " Ctrl+C pysäyttää"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Tarkistetaan onko native-node käännetty
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
NATIVE_BIN="$SCRIPT_DIR/target/release/native-node"
|
||||||
|
|
||||||
|
if [ -f "$NATIVE_BIN" ]; then
|
||||||
|
HUB_URL="$HUB_URL" OLLAMA_MODEL="$MODEL" "$NATIVE_BIN"
|
||||||
|
elif command -v cargo &>/dev/null && [ -f "$SCRIPT_DIR/native-node/Cargo.toml" ]; then
|
||||||
|
echo " Käännetään native-node..."
|
||||||
|
cd "$SCRIPT_DIR"
|
||||||
|
cargo build --release -p native-node --no-default-features 2>&1 | tail -1
|
||||||
|
HUB_URL="$HUB_URL" OLLAMA_MODEL="$MODEL" "$NATIVE_BIN"
|
||||||
|
else
|
||||||
|
echo " ✗ native-node binääriä ei löydy eikä Rust ole asennettu."
|
||||||
|
echo " Asenna Rust: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh"
|
||||||
|
echo " Tai lataa valmis binääri: https://kipina.studio/download"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
67
network-poc/frontend/public/kipina-node
Normal file
67
network-poc/frontend/public/kipina-node
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Kipinä Node — lataa oikea binääri ja käynnistä
|
||||||
|
set -e
|
||||||
|
|
||||||
|
BASE_URL="https://kipina.studio/download"
|
||||||
|
HUB_URL="${KIPINA_HUB:-wss://kipina.studio/ws}"
|
||||||
|
MODEL="${KIPINA_MODEL:-qwen2.5-coder:3b}"
|
||||||
|
|
||||||
|
# Tunnista OS ja arkkitehtuuri
|
||||||
|
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
|
||||||
|
ARCH=$(uname -m)
|
||||||
|
|
||||||
|
case "$OS-$ARCH" in
|
||||||
|
darwin-arm64) BINARY="kipina-node-macos-arm64" ;;
|
||||||
|
darwin-x86_64) BINARY="kipina-node-macos-arm64" ;; # Rosetta
|
||||||
|
linux-x86_64) BINARY="kipina-node-linux-x86_64" ;;
|
||||||
|
linux-aarch64) BINARY="kipina-node-linux-arm64" ;;
|
||||||
|
*) echo "Ei tuettu: $OS-$ARCH"; exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo " ╔══════════════════════════════════════╗"
|
||||||
|
echo " ║ Kipinä Agentic Node ║"
|
||||||
|
echo " ╚══════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
echo " OS: $OS ($ARCH)"
|
||||||
|
echo " Hub: $HUB_URL"
|
||||||
|
echo " Malli: $MODEL"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Tarkista Ollama
|
||||||
|
if ! command -v ollama &>/dev/null; then
|
||||||
|
echo " ✗ Ollama ei ole asennettu."
|
||||||
|
echo " Asenna: curl -fsSL https://ollama.ai/install.sh | sh"
|
||||||
|
echo " macOS: brew install ollama"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Varmista Ollama käynnissä
|
||||||
|
if ! curl -s http://localhost:11434/api/tags &>/dev/null; then
|
||||||
|
echo " Käynnistetään Ollama..."
|
||||||
|
ollama serve &>/dev/null &
|
||||||
|
sleep 3
|
||||||
|
fi
|
||||||
|
echo " ✓ Ollama käynnissä"
|
||||||
|
|
||||||
|
# Lataa malli
|
||||||
|
if ! ollama list 2>/dev/null | grep -q "$MODEL"; then
|
||||||
|
echo " Ladataan $MODEL..."
|
||||||
|
ollama pull "$MODEL"
|
||||||
|
fi
|
||||||
|
echo " ✓ Malli $MODEL valmis"
|
||||||
|
|
||||||
|
# Lataa binääri
|
||||||
|
BIN_PATH="./kipina-node-bin"
|
||||||
|
if [ ! -f "$BIN_PATH" ]; then
|
||||||
|
echo " Ladataan $BINARY..."
|
||||||
|
curl -sSL "$BASE_URL/$BINARY" -o "$BIN_PATH"
|
||||||
|
chmod +x "$BIN_PATH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo " ✓ Yhdistetään laskentaverkkoon..."
|
||||||
|
echo " Ctrl+C pysäyttää"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
HUB_URL="$HUB_URL" OLLAMA_MODEL="$MODEL" exec "$BIN_PATH"
|
||||||
@@ -10,6 +10,39 @@
|
|||||||
<span id="compute-dot" class="status-dot" style="background:#30363d"></span>
|
<span id="compute-dot" class="status-dot" style="background:#30363d"></span>
|
||||||
<span style="color:#8b949e">Laskenta:</span>
|
<span style="color:#8b949e">Laskenta:</span>
|
||||||
<span id="compute-label" style="color:#8b949e">—</span>
|
<span id="compute-label" style="color:#8b949e">—</span>
|
||||||
<button id="compute-btn" class="btn btn-accent" title="Käynnistä kielimalli">Alusta</button>
|
<button id="compute-btn" class="btn btn-accent" title="Käynnistä kielimalli selaimessa">Alusta</button>
|
||||||
|
</span>
|
||||||
|
<span class="status-separator">│</span>
|
||||||
|
<span class="status-group">
|
||||||
|
<button id="join-btn" class="btn btn-green" onclick="showJoinDialog()" title="Liitä oma koneesi laskentaverkkoon (natiivi, nopea)">+ Liitä koneesi</button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Join-dialogi -->
|
||||||
|
<div id="join-dialog" style="display:none;margin-top:8px;padding:16px;background:var(--panel);border:1px solid var(--border);border-radius:6px;font-size:14px">
|
||||||
|
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px">
|
||||||
|
<span style="color:#e6edf3;font-weight:600;font-size:16px">Liitä koneesi laskentaverkkoon</span>
|
||||||
|
<button onclick="document.getElementById('join-dialog').style.display='none'" style="background:none;border:none;color:#8b949e;cursor:pointer;font-size:18px">✕</button>
|
||||||
|
</div>
|
||||||
|
<p style="color:#8b949e;margin-bottom:16px">Koneesi suorittaa tehtäviä ~10-50x nopeammin kuin selainlaskenta. Kaksi vaihetta:</p>
|
||||||
|
|
||||||
|
<!-- Vaihe 1: Ollama -->
|
||||||
|
<div style="margin-bottom:14px;padding:12px;background:var(--bg);border-radius:4px;border-left:3px solid var(--accent)">
|
||||||
|
<div style="color:#e6edf3;font-weight:600;margin-bottom:6px">1. Asenna Ollama <span style="color:#8b949e;font-weight:normal">(kielimallimoottori)</span></div>
|
||||||
|
<div style="display:flex;gap:6px;align-items:center;margin-bottom:6px">
|
||||||
|
<code style="flex:1;background:#010409;padding:8px 12px;border-radius:4px;color:var(--green);font-family:'Courier New',monospace;font-size:13px;user-select:all">curl -fsSL https://ollama.ai/install.sh | sh</code>
|
||||||
|
<button onclick="navigator.clipboard.writeText('curl -fsSL https://ollama.ai/install.sh | sh');this.textContent='✓';setTimeout(()=>this.textContent='Kopioi',1500)" class="btn btn-accent" style="padding:6px 10px">Kopioi</button>
|
||||||
|
</div>
|
||||||
|
<div style="color:#8b949e;font-size:12px">macOS: <code style="color:var(--accent)">brew install ollama</code> · Windows: <a href="https://ollama.ai/download" target="_blank" style="color:var(--accent)">ollama.ai/download</a> · Jos jo asennettu → siirry vaiheeseen 2.</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Vaihe 2: Kipinä-node -->
|
||||||
|
<div style="padding:12px;background:var(--bg);border-radius:4px;border-left:3px solid var(--green)">
|
||||||
|
<div style="color:#e6edf3;font-weight:600;margin-bottom:6px">2. Käynnistä Kipinä-node</div>
|
||||||
|
<div style="display:flex;gap:6px;align-items:center;margin-bottom:6px">
|
||||||
|
<code style="flex:1;background:#010409;padding:8px 12px;border-radius:4px;color:var(--green);font-family:'Courier New',monospace;font-size:13px;user-select:all">curl -sSL https://kipina.studio/kipina-node -o kipina-node && chmod +x kipina-node && ./kipina-node</code>
|
||||||
|
<button onclick="navigator.clipboard.writeText('curl -sSL https://kipina.studio/kipina-node -o kipina-node && chmod +x kipina-node && ./kipina-node');this.textContent='✓';setTimeout(()=>this.textContent='Kopioi',1500)" class="btn btn-green" style="padding:6px 10px">Kopioi</button>
|
||||||
|
</div>
|
||||||
|
<div style="color:#8b949e;font-size:12px">Lataa kielimallin (~2GB) automaattisesti ensimmäisellä kerralla. Ctrl+C pysäyttää.</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -53,6 +53,11 @@ import Settings from "../components/Settings.astro";
|
|||||||
|
|
||||||
<script is:inline>
|
<script is:inline>
|
||||||
// === Helpers ===
|
// === Helpers ===
|
||||||
|
window.showJoinDialog = function() {
|
||||||
|
const d = document.getElementById('join-dialog');
|
||||||
|
d.style.display = d.style.display === 'none' ? 'block' : 'none';
|
||||||
|
};
|
||||||
|
|
||||||
function esc(str) {
|
function esc(str) {
|
||||||
if (!str) return '';
|
if (!str) return '';
|
||||||
return String(str).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"');
|
return String(str).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"');
|
||||||
|
|||||||
@@ -14,19 +14,20 @@
|
|||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
background: var(--bg);
|
background: var(--bg);
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container { max-width: 1200px; margin: 0 auto; padding: 20px; }
|
.container { max-width: 1600px; margin: 0 auto; padding: 20px 40px; }
|
||||||
|
|
||||||
/* Tabs */
|
/* Tabs */
|
||||||
.tabs { display: flex; gap: 4px; margin-bottom: 16px; }
|
.tabs { display: flex; gap: 4px; margin-bottom: 16px; }
|
||||||
.tab {
|
.tab {
|
||||||
padding: 8px 16px; border-radius: 6px 6px 0 0; cursor: pointer;
|
padding: 10px 20px; border-radius: 6px 6px 0 0; cursor: pointer;
|
||||||
border: 1px solid var(--border); border-bottom: none;
|
border: 1px solid var(--border); border-bottom: none;
|
||||||
background: var(--bg); color: #8b949e; font-size: 14px;
|
background: var(--bg); color: #8b949e; font-size: 15px;
|
||||||
}
|
}
|
||||||
.tab.active { background: var(--panel); color: var(--accent); border-color: var(--border); }
|
.tab.active { background: var(--panel); color: var(--accent); border-color: var(--border); }
|
||||||
|
|
||||||
@@ -37,9 +38,9 @@ body {
|
|||||||
/* Status bar */
|
/* Status bar */
|
||||||
.status-bar {
|
.status-bar {
|
||||||
display: flex; align-items: center; gap: 12px;
|
display: flex; align-items: center; gap: 12px;
|
||||||
padding: 8px 14px; background: var(--bg);
|
padding: 10px 16px; background: var(--bg);
|
||||||
border: 1px solid var(--border); border-radius: 6px 6px 0 0;
|
border: 1px solid var(--border); border-radius: 6px 6px 0 0;
|
||||||
font-family: 'Courier New', monospace; font-size: 13px;
|
font-family: 'Courier New', monospace; font-size: 14px;
|
||||||
}
|
}
|
||||||
.status-dot {
|
.status-dot {
|
||||||
width: 8px; height: 8px; border-radius: 50%; display: inline-block;
|
width: 8px; height: 8px; border-radius: 50%; display: inline-block;
|
||||||
@@ -50,21 +51,22 @@ body {
|
|||||||
/* Terminal */
|
/* Terminal */
|
||||||
.terminal {
|
.terminal {
|
||||||
background: #010409; border: 1px solid var(--border); border-top: none;
|
background: #010409; border: 1px solid var(--border); border-top: none;
|
||||||
font-family: 'Courier New', monospace; font-size: 14px;
|
font-family: 'Courier New', monospace; font-size: 16px;
|
||||||
min-height: 300px; max-height: 60vh; overflow-y: auto;
|
min-height: 400px; max-height: 70vh; overflow-y: auto;
|
||||||
padding: 8px 12px;
|
padding: 12px 16px;
|
||||||
}
|
}
|
||||||
.terminal-line { padding: 1px 0; white-space: pre-wrap; word-break: break-word; }
|
.terminal-line { padding: 1px 0; white-space: pre-wrap; word-break: break-word; }
|
||||||
.terminal-prompt { color: var(--yellow); margin-right: 8px; }
|
.terminal-prompt { color: var(--yellow); margin-right: 8px; }
|
||||||
.terminal-input-row {
|
.terminal-input-row {
|
||||||
display: flex; align-items: center; position: relative;
|
display: flex; align-items: center; position: relative;
|
||||||
background: #010409; border: 1px solid var(--border); border-top: none;
|
background: #0d1117; border: 1px solid var(--accent); border-top: none;
|
||||||
border-radius: 0 0 6px 6px; padding: 8px 12px;
|
border-radius: 0 0 6px 6px; padding: 10px 14px;
|
||||||
font-family: 'Courier New', monospace; font-size: 14px;
|
font-family: 'Courier New', monospace; font-size: 15px;
|
||||||
|
box-shadow: 0 2px 8px rgba(88,166,255,0.1);
|
||||||
}
|
}
|
||||||
.terminal-input {
|
.terminal-input {
|
||||||
flex: 1; background: transparent; border: none; outline: none;
|
flex: 1; background: transparent; border: none; outline: none;
|
||||||
color: var(--green); font-family: inherit; font-size: inherit;
|
color: var(--green); font-family: inherit; font-size: 16px;
|
||||||
}
|
}
|
||||||
.terminal-dropdown {
|
.terminal-dropdown {
|
||||||
display: none; position: absolute; bottom: 100%; left: 30px;
|
display: none; position: absolute; bottom: 100%; left: 30px;
|
||||||
@@ -128,10 +130,10 @@ body {
|
|||||||
background: linear-gradient(145deg, rgba(33,38,45,0.4) 0%, rgba(13,17,23,0.8) 100%);
|
background: linear-gradient(145deg, rgba(33,38,45,0.4) 0%, rgba(13,17,23,0.8) 100%);
|
||||||
backdrop-filter: blur(12px);
|
backdrop-filter: blur(12px);
|
||||||
border: 1px solid rgba(240,246,252,0.1);
|
border: 1px solid rgba(240,246,252,0.1);
|
||||||
border-radius: 12px;
|
border-radius: 14px;
|
||||||
padding: 6px 6px 4px;
|
padding: 8px 8px 6px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: 72px;
|
width: 90px;
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||||
@@ -144,12 +146,12 @@ body {
|
|||||||
box-shadow: 0 8px 14px rgba(0,0,0,0.4);
|
box-shadow: 0 8px 14px rgba(0,0,0,0.4);
|
||||||
}
|
}
|
||||||
.agent-avatar img {
|
.agent-avatar img {
|
||||||
width: 50px; height: 50px; border-radius: 12px;
|
width: 64px; height: 64px; border-radius: 14px;
|
||||||
margin-bottom: 4px; border: 2px solid rgba(240,246,252,0.1);
|
margin-bottom: 4px; border: 2px solid rgba(240,246,252,0.1);
|
||||||
transition: all 0.4s ease; object-fit: cover;
|
transition: all 0.4s ease; object-fit: cover;
|
||||||
}
|
}
|
||||||
.agent-avatar .avatar-name {
|
.agent-avatar .avatar-name {
|
||||||
font-size: 10px; color: #8b949e; white-space: nowrap;
|
font-size: 11px; color: #8b949e; white-space: nowrap;
|
||||||
overflow: hidden; text-overflow: ellipsis;
|
overflow: hidden; text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
.agent-avatar.active {
|
.agent-avatar.active {
|
||||||
|
|||||||
@@ -347,22 +347,26 @@ async fn main() {
|
|||||||
|
|
||||||
if let Some(ref engine) = llm {
|
if let Some(ref engine) = llm {
|
||||||
let max_tokens = task.get("max_tokens").and_then(|v| v.as_u64()).unwrap_or(1024) as usize;
|
let max_tokens = task.get("max_tokens").and_then(|v| v.as_u64()).unwrap_or(1024) as usize;
|
||||||
tracing::info!("Generoidaan (task_id: {}, max_tokens: {}): \"{}\"", task_id, max_tokens, &prompt[..prompt.len().min(100)]);
|
let prompt_lines = prompt.lines().count();
|
||||||
|
let prompt_last: String = prompt.lines().last().unwrap_or("").chars().take(60).collect();
|
||||||
|
tracing::info!("→ task_id:{} | {}r prompti | \"{}...\"", task_id, prompt_lines, prompt_last);
|
||||||
|
|
||||||
let model_name = engine.model_name();
|
let model_name = engine.model_name();
|
||||||
match engine.generate(prompt, max_tokens).await {
|
match engine.generate(prompt, max_tokens).await {
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
tracing::info!(
|
tracing::info!(
|
||||||
"Tulos: {} tokenia | {:.0}ms | {:.1} tok/s | \"{}\"",
|
"✓ {} | {} tok | {:.0}ms | {:.1} tok/s",
|
||||||
|
model_name,
|
||||||
result.tokens_generated,
|
result.tokens_generated,
|
||||||
result.duration_ms,
|
result.duration_ms,
|
||||||
result.tokens_per_sec,
|
result.tokens_per_sec,
|
||||||
&result.text[..result.text.len().min(80)]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Lähetetään vain lyhyt prompti-esikatselu (ei koko kontekstia)
|
||||||
|
let prompt_short: String = prompt.lines().last().unwrap_or("").chars().take(100).collect();
|
||||||
let done = json!({
|
let done = json!({
|
||||||
"type": "llm_done",
|
"type": "llm_done",
|
||||||
"prompt": prompt,
|
"prompt": prompt_short,
|
||||||
"model": format!("{} (Ollama)", model_name),
|
"model": format!("{} (Ollama)", model_name),
|
||||||
"response": result.text,
|
"response": result.text,
|
||||||
"tokens_generated": result.tokens_generated,
|
"tokens_generated": result.tokens_generated,
|
||||||
|
|||||||
Reference in New Issue
Block a user