From d4de8b361929c545d880c8c4a996e55232e15d13 Mon Sep 17 00:00:00 2001 From: vegard Date: Wed, 18 Mar 2026 06:50:29 +0000 Subject: [PATCH] =?UTF-8?q?Fullf=C3=B8rer=20oppgave=2018.4:=20AI-verkt?= =?UTF-8?q?=C3=B8y=20panel=20(frontend)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Svelte-komponent for AI-prosessering i arbeidsflaten: - AiToolPanel.svelte: Viser ai_preset-noder fra STDB som velgbare verktøy, med modell-indikator (flash/standard) og prompt-forhåndsvisning - Drag-and-drop mottak for tekstnoder med visuell feedback - Validerer kompatibilitet (kun content/communication-noder) - Kaller /intentions/ai_process via ny aiProcess()-funksjon i api.ts - Integrert i collection-siden, tilgjengelig for alle innloggede brukere - EditorTrait: innholdsnoder er nå draggable for AI-prosessering - Fritekst-felt for egendefinert instruksjon (backend-støtte kommer i 18.6) Co-Authored-By: Claude Opus 4.6 (1M context) --- frontend/src/lib/api.ts | 21 ++ .../src/lib/components/AiToolPanel.svelte | 312 ++++++++++++++++++ .../lib/components/traits/EditorTrait.svelte | 11 +- .../src/routes/collection/[id]/+page.svelte | 8 + tasks.md | 3 +- 5 files changed, 352 insertions(+), 3 deletions(-) create mode 100644 frontend/src/lib/components/AiToolPanel.svelte diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts index 9ffb80f..6c2488c 100644 --- a/frontend/src/lib/api.ts +++ b/frontend/src/lib/api.ts @@ -1193,6 +1193,27 @@ export function leaveCommunication( }); } +// ============================================================================= +// AI-prosessering +// ============================================================================= + +export interface AiProcessRequest { + source_node_id: string; + ai_preset_id: string; + direction: 'node_to_tool' | 'tool_to_node'; +} + +export interface AiProcessResponse { + job_id: string; +} + +export function aiProcess( + accessToken: string, + data: AiProcessRequest +): Promise { + return post(accessToken, '/intentions/ai_process', data); +} + /** Hent ressursforbruk for en spesifikk node (kun eier). */ export async function fetchNodeUsage( accessToken: string, diff --git a/frontend/src/lib/components/AiToolPanel.svelte b/frontend/src/lib/components/AiToolPanel.svelte new file mode 100644 index 0000000..1ba8218 --- /dev/null +++ b/frontend/src/lib/components/AiToolPanel.svelte @@ -0,0 +1,312 @@ + + +
+
+ +

AI-verktøy

+ {#if modelLabel} + + {modelLabel} + + {/if} +
+ +
+ +
+ + {#if presets.length === 0} +

Ingen AI-presets tilgjengelig.

+ {:else} +
+ {#each presets as preset (preset.id)} + {@const meta = parseMetadata(preset)} + + {/each} +
+ {/if} +
+ + + {#if selectedPreset && selectedMeta} +
+

{selectedPreset.title}

+

{selectedMeta.prompt}

+
+ Modell: {modelLabel} + Retning: { + defaultDirection === 'node_to_tool' ? 'Ny node' + : defaultDirection === 'tool_to_node' ? 'In-place' + : 'Begge' + } +
+
+ {/if} + + +
+ + +

+ Kommer i tillegg til valgt preset (funksjon under utvikling). +

+
+ + +
+ {#if droppedNode} + +
+

+ {droppedNode.title || 'Uten tittel'} +

+

+ {droppedNode.content?.slice(0, 120)}{(droppedNode.content?.length ?? 0) > 120 ? '…' : ''} +

+
+ + +
+
+ {:else if dragOver} +

Slipp her for AI-prosessering

+ {:else} +

Dra en tekstnode hit

+

Støtter innholds- og kommunikasjonsnoder

+ {/if} +
+ + + {#if lastResult} +
+ {lastResult.message} +
+ {/if} +
+
diff --git a/frontend/src/lib/components/traits/EditorTrait.svelte b/frontend/src/lib/components/traits/EditorTrait.svelte index 479f189..6153940 100644 --- a/frontend/src/lib/components/traits/EditorTrait.svelte +++ b/frontend/src/lib/components/traits/EditorTrait.svelte @@ -123,7 +123,16 @@ {:else}
    {#each contentItems as item (item.node.id)} -
  • +
  • { + if (e.dataTransfer) { + e.dataTransfer.effectAllowed = 'copy'; + e.dataTransfer.setData('text/plain', item.node.id); + } + }} + >

    {item.node.title || 'Uten tittel'}

    diff --git a/frontend/src/routes/collection/[id]/+page.svelte b/frontend/src/routes/collection/[id]/+page.svelte index 645baac..f7bf23d 100644 --- a/frontend/src/routes/collection/[id]/+page.svelte +++ b/frontend/src/routes/collection/[id]/+page.svelte @@ -18,6 +18,7 @@ import GenericTrait from '$lib/components/traits/GenericTrait.svelte'; import TraitAdmin from '$lib/components/traits/TraitAdmin.svelte'; import NodeUsage from '$lib/components/NodeUsage.svelte'; + import AiToolPanel from '$lib/components/AiToolPanel.svelte'; const session = $derived($page.data.session as Record | undefined); const nodeId = $derived(session?.nodeId as string | undefined); @@ -181,6 +182,13 @@
    {/if} + + {#if connected && accessToken} +
    + +
    + {/if} + {#if accessToken && collectionId}
    diff --git a/tasks.md b/tasks.md index 4dfbe37..6133821 100644 --- a/tasks.md +++ b/tasks.md @@ -204,8 +204,7 @@ Ref: `docs/features/ai_verktoy.md`, `docs/retninger/arbeidsflaten.md` - [x] 18.1 AI-preset node-type: `node_kind: 'ai_preset'` med metadata (prompt, model_profile, category, icon, color). Maskinrommet validerer ved opprettelse. Seed standardprompter (rens tekst, korrektør, oppsummering, oversett, skriv om, trekk ut fakta, forenkle, endre tone). - [x] 18.2 AI-prosessering endepunkt: `POST /intentions/ai_process` med source_node_id, ai_preset_id, direction (node_to_tool / tool_to_node). Maskinrommet henter kilde-content og preset-prompt, mapper modellprofil → LiteLLM-alias, sender til AI Gateway. Logg forbruk i ai_usage_log. - [x] 18.3 Direction-logikk: `tool_to_node` → lagre original som revisjon, oppdater node content. `node_to_tool` → opprett ny node med AI-output, opprett `derived_from`-edge til kilde + `processed_by`-edge til AI-preset. -- [~] 18.4 AI-verktøy panel (frontend): Svelte-komponent for arbeidsflaten. Prompt-velger med standardprompter, fritekst-felt for egendefinert prompt, modell-indikator (readonly). Drag-and-drop mottak for tekstnoder. - > Påbegynt: 2026-03-18T06:42 +- [x] 18.4 AI-verktøy panel (frontend): Svelte-komponent for arbeidsflaten. Prompt-velger med standardprompter, fritekst-felt for egendefinert prompt, modell-indikator (readonly). Drag-and-drop mottak for tekstnoder. - [ ] 18.5 Drag-and-drop integrasjon: node → verktøy (ny node), verktøy → node (in-place revisjon). Drop-sone feedback med verktøyets farge. Inkompatibilitet for lyd/bilde-noder med forklaring. - [ ] 18.6 Egendefinerte presets: brukere kan opprette egne AI-preset-noder med custom prompt. Dele via edges til samling/team. Modellprofil satt av admin.