Compare commits
3 Commits
8aed9f97a2
...
66d1e8c4b1
| Author | SHA1 | Date | |
|---|---|---|---|
| 66d1e8c4b1 | |||
| 2eeac255f6 | |||
| 6097cfc263 |
@@ -16,3 +16,4 @@ futures = "0.3"
|
|||||||
rusqlite = { version = "0.31", features = ["bundled"] }
|
rusqlite = { version = "0.31", features = ["bundled"] }
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
base64 = "0.22"
|
base64 = "0.22"
|
||||||
|
reqwest = { version = "0.12", features = ["json"] }
|
||||||
|
|||||||
Binary file not shown.
@@ -386,6 +386,7 @@ async fn main() {
|
|||||||
.route("/api/v1/chat/completions", axum::routing::post(api_chat_completions))
|
.route("/api/v1/chat/completions", axum::routing::post(api_chat_completions))
|
||||||
.route("/api/v1/model", axum::routing::post(api_change_model))
|
.route("/api/v1/model", axum::routing::post(api_change_model))
|
||||||
.route("/api/v1/hardware", get(api_hardware))
|
.route("/api/v1/hardware", get(api_hardware))
|
||||||
|
.route("/api/v1/ollama/tags", get(api_ollama_tags))
|
||||||
.route("/admin", get(admin_page))
|
.route("/admin", get(admin_page))
|
||||||
.nest_service("/", {
|
.nest_service("/", {
|
||||||
let static_dir = std::env::var("STATIC_DIR").unwrap_or_else(|_| "../static".to_string());
|
let static_dir = std::env::var("STATIC_DIR").unwrap_or_else(|_| "../static".to_string());
|
||||||
@@ -960,6 +961,20 @@ struct ChatCompletionResponse {
|
|||||||
tokens_generated: u64,
|
tokens_generated: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn api_ollama_tags() -> axum::response::Response {
|
||||||
|
let ollama_url = std::env::var("OLLAMA_URL").unwrap_or_else(|_| "http://ollama:11434".to_string());
|
||||||
|
match reqwest::get(format!("{}/api/tags", ollama_url)).await {
|
||||||
|
Ok(resp) => {
|
||||||
|
if let Ok(body) = resp.json::<serde_json::Value>().await {
|
||||||
|
axum::Json(body).into_response()
|
||||||
|
} else {
|
||||||
|
axum::Json(serde_json::json!({ "models": [] })).into_response()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => axum::Json(serde_json::json!({ "models": [] })).into_response(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn api_hardware(
|
async fn api_hardware(
|
||||||
axum::extract::State(state): axum::extract::State<Arc<AppState>>,
|
axum::extract::State(state): axum::extract::State<Arc<AppState>>,
|
||||||
) -> axum::response::Response {
|
) -> axum::response::Response {
|
||||||
|
|||||||
@@ -1708,8 +1708,9 @@ IMPORTANT: Include get_db() dependency for FastAPI` },
|
|||||||
|
|
||||||
// URL-hash navigointi
|
// URL-hash navigointi
|
||||||
const initHash = window.location.hash.replace('#', '');
|
const initHash = window.location.hash.replace('#', '');
|
||||||
if (['codelab', 'agents', 'guide'].includes(initHash)) {
|
const hashMap = { 'laskentaverkko': 'network', 'network': 'network', 'codelab': 'codelab', 'agents': 'agents', 'guide': 'guide' };
|
||||||
switchMainTab(initHash);
|
if (hashMap[initHash]) {
|
||||||
|
switchMainTab(hashMap[initHash]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Synkronoi coder-status kun WS on jo auki (suora #codelab navigointi)
|
// Synkronoi coder-status kun WS on jo auki (suora #codelab navigointi)
|
||||||
@@ -2829,19 +2830,11 @@ ${generatedFiles['Dockerfile'] || '(puuttuu)'}`;
|
|||||||
if (content) content.textContent = spinFrames[spinIdx] + ' Ladataan ' + selected.name + '...';
|
if (content) content.textContent = spinFrames[spinIdx] + ' Ladataan ' + selected.name + '...';
|
||||||
}, 100);
|
}, 100);
|
||||||
// Vaihdetaan malli hubille + Ollama pull
|
// Vaihdetaan malli hubille + Ollama pull
|
||||||
Promise.all([
|
|
||||||
fetch('/api/v1/model', {
|
fetch('/api/v1/model', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ model: selected.name }),
|
body: JSON.stringify({ model: selected.name }),
|
||||||
}).then(r => r.json()),
|
}).then(r => r.json()).then(hubData => {
|
||||||
// Suora pull Ollamasta — odotetaan kunnes malli on ladattu
|
|
||||||
fetch('http://' + window.location.hostname + ':11434/api/pull', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({ name: selected.name, stream: false }),
|
|
||||||
}).then(r => r.json()).catch(() => ({ status: 'ok' })),
|
|
||||||
]).then(([hubData, _]) => {
|
|
||||||
clearInterval(spinTimer);
|
clearInterval(spinTimer);
|
||||||
pullLine.remove();
|
pullLine.remove();
|
||||||
if (hubData.status === 'ok') {
|
if (hubData.status === 'ok') {
|
||||||
@@ -2877,7 +2870,7 @@ ${generatedFiles['Dockerfile'] || '(puuttuu)'}`;
|
|||||||
// Haetaan ladatut mallit Ollamasta
|
// Haetaan ladatut mallit Ollamasta
|
||||||
Promise.all([
|
Promise.all([
|
||||||
fetch('/api/v1/hardware').then(r => r.json()).catch(() => ({})),
|
fetch('/api/v1/hardware').then(r => r.json()).catch(() => ({})),
|
||||||
fetch('http://' + window.location.hostname + ':11434/api/tags').then(r => r.json()).catch(() => ({ models: [] })),
|
fetch('/api/v1/ollama/tags').then(r => r.json()).catch(() => ({ models: [] })),
|
||||||
]).then(([hw, ollama]) => {
|
]).then(([hw, ollama]) => {
|
||||||
const loadedNames = (ollama.models || []).map(m => m.name.replace(':latest', ''));
|
const loadedNames = (ollama.models || []).map(m => m.name.replace(':latest', ''));
|
||||||
const btn = document.getElementById('agent-compute-btn');
|
const btn = document.getElementById('agent-compute-btn');
|
||||||
|
|||||||
Reference in New Issue
Block a user