Results polled one drafts endpoint per schedule every minute, archived ones included, so the Network tab filled with video-drafts reads. Each poll now reads GET /agents/status once (with If-None-Match, mostly a 304) and reads a schedule's drafts again only when its status changed, while a production plan is at work, or after 30 minutes so signed video URLs stay valid. Without the status read, every schedule is read as before. The poll is now every 30s. Also documents how Express uses the engine API in docs/engine-api.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7.7 KiB
Alur API Express → Engine learning-lab
Express tidak punya backend sendiri. Semua logika AI (perencanaan, pembuatan materi, video, riset) ada di engine learning-lab (FastAPI, /api/v1). Express hanya membuat agent (jadwal) beserta konfigurasinya, lalu membaca dan meninjau hasilnya.
Jalur request
| Lingkungan | Jalur |
|---|---|
| Production | express.bawana.com/api/* → redirect Netlify (netlify.toml) → https://learningstudio.bawana.com/api/* |
| Dev | Proxy Vite /api → ENGINE_URL (default http://localhost:8000, vite.config.ts) |
- Prefix
/api/v1ditambahkan di src/api/client.ts. Setiap request membawaAuthorization: Bearer <Clerk session token>. - Request baca dan aksi diatur lajunya oleh
pacediclient.ts, supaya tidak terkena rate limit proxy (503/429). - Endpoint agent ada di
learning-lab/backend/app/api/v1/endpoints/agents.py(semua di bawah/organizations/current/agents). Endpoint produksi konten ada diagent_content.py(/organizations/current/agents/{id}/content).
Di bawah ini, AGENTS = /organizations/current/agents.
Jadwal = agent
Setiap jadwal Express adalah satu agent engine. Namanya diawali prefix Express, lalu dibaca lewat expressAgents() di schedules.ts.
Membuat jadwal (createSchedule)
| Langkah | Endpoint |
|---|---|
| (khusus video) Ambil harga satu video sebagai budget run | GET AGENTS/video-quote?scenes=…&duration_seconds=… |
Buat agent dengan konfigurasi dari configFor() |
POST AGENTS |
| Pasang dokumen Brain (semua dokumen yang siap, atau hanya yang dipilih) | PUT AGENTS/{id}/knowledge-sources |
| Aktifkan (menyetujui aturan produksi; sebelum aktif tidak ada yang berjalan) | POST AGENTS/{id}/activate |
Mengelola jadwal
| Aksi | Endpoint |
|---|---|
| Ubah brief (engine mengembalikan agent ke draft, jadi langsung diaktifkan ulang atau dipause) | PATCH AGENTS/{id}, lalu POST AGENTS/{id}/activate atau /pause |
| Pause / resume | POST AGENTS/{id}/pause, POST AGENTS/{id}/activate |
| Arsipkan | POST AGENTS/{id}/archive |
| Riwayat run | GET AGENTS/{id}/runs |
| Kesiapan knowledge | GET AGENTS/{id}/knowledge-readiness |
1. Konten materi (summary, quiz, flashcard, slide, audio, SCORM, …)
Konfigurasi agent (configFor):
enabled_tools: ['knowledge.retrieve', 'compose.graph.retrieve', 'compose.create_material']
material_outputs: outputsFor(kind)
content_goal: { enabled: true, weekly_target, execution_mode: 'automatic' }
Audio dan SCORM adalah jenis buatan Express sendiri, disusun dari output Compose. Audio adalah summary narasi; SCORM adalah pasangan summary dan quiz dari satu item rencana.
Produksi (AGENTS/{id}/content):
| Langkah | Endpoint |
|---|---|
| "Produce now", atau tick otomatis jam 09:00 WIB | POST …/content/planning-quotes { target } |
| Konfirmasi rencana | POST …/content/plans/{plan}/confirm-planning { revision } |
| Approve dan start | Dijalankan otomatis oleh tick engine (mode automatic) |
| Retry satu item (maksimal 3 percobaan) | POST …/plans/{plan}/items/{item}/retry-quote, lalu POST …/plans/{plan}/start |
| Status rencana dan periode minggu ini | GET …/content (di-cache 30 detik oleh productionStatus) |
Di sisi engine (backend/app/services/):
agent_content_planning.py: model mengusulkan topik beserta bukti dari isi Brain.agent_content_execution.py: membuat quote dan memesan kredit untuk setiap item.agent_materials.py: menjalankan Compose (compose_creation) untuk membuat materinya.
Hasil: material-drafts.
2. Video
Konfigurasi agent:
enabled_tools: ['knowledge.retrieve', 'compose.graph.retrieve', 'studio.create_video']
video_options: { max_scenes, max_duration_seconds, art_style: 'realistic', language }
run_schedule: { cadence: 'weekly' | 'daily', hour: 9, minute: 0, weekday: 0 }
Memicu run: tick jadwal di engine, atau runNow, yaitu POST AGENTS/{id}/runs dengan header Idempotency-Key.
Di sisi engine, agent_worker.py menjalankan:
agent_video_drafts.py (membuat project Video Studio dan memesan kredit) → agent_video_script.py → agent_video_storyboard.py → agent_video_clips.py → agent_video_render.py
Hasil: video-drafts. Satu draft tidak bisa di-retry sendiri; yang dilakukan adalah run baru dari jadwalnya, dan tombol retry hanya muncul di draft terbaru.
3. Riset sumber web
Konfigurasi agent:
enabled_tools: ['knowledge.retrieve', 'compose.graph.retrieve', 'browse.search', 'library.add_url']
research_options: { max_results: 5 }
auto_approve_sources
Memicu run: jam 07:00 WIB, atau POST AGENTS/{id}/runs.
Hasil: source-drafts.
Membaca dan meninjau hasil (results.ts)
| Jenis | Daftar | Detail | Aksi |
|---|---|---|---|
| Materi | GET AGENTS/{id}/material-drafts |
GET AGENTS/{id}/material-drafts/{draft} |
POST …/material-drafts/{draft}/decision { expected_revision, decision } |
| Video | GET AGENTS/{id}/video-drafts |
(judul diambil dari daftar) | POST …/video-drafts/{draft}/review { decision }, POST …/video-drafts/{draft}/cancel |
| Sumber | GET AGENTS/{id}/source-drafts |
— | POST …/source-drafts/{draft}/review { expected_revision, decision } |
Ekspor slide deck ke PPTX memakai POST /slide-deck/{deckId}/export.
Pola polling
listResults() dipakai oleh halaman Results dan Production (query key ['results'], RESULTS_POLL = setiap 30 detik):
- Setiap poll membaca
GET AGENTS/status?archived=truesatu kali, denganIf-None-Match(opsirevalidatediclient.ts). Kalau tidak ada perubahan, engine menjawab 304. - Dari respons itu dibuat tanda per agent. Endpoint per jadwal (
material-drafts,video-drafts,source-drafts) hanya dibaca ulang untuk agent yang tandanya berubah. - Pembacaan ulang tetap dipaksa untuk jadwal konten dengan plan aktif (topik plan belum punya draft), setelah 30 menit (URL video bertanda tangan berlaku 1 jam), dan setelah setiap mutation (
forgetReads, main.tsx). - Kalau
/statussibuk, tanda terakhir dipakai. Kalau endpoint tidak tersedia, semua jadwal dibaca seperti dulu; jadwal arsip tetap cukup dibaca sekali. - Paling banyak 4 request per jadwal berjalan bersamaan (
PER_SCHEDULE_LIMIT). Konten dibaca dulu, baru riset. - Kalau engine membalas 503/429, request dicoba sekali lagi setelah 3 detik. Kalau tetap gagal, hasil poll sebelumnya yang dipakai.
- Di engine,
_video_draft_outmenjalankan sekitar 5 query untuk setiap draft (project, run step, dokumen, scene, kredit), dengan batas 100 draft per agent.
Brain dan kredit (src/api/engine.ts)
| Aksi | Endpoint |
|---|---|
| Daftar / status / hapus / unduh dokumen | GET /upload/list, GET /upload/{id}, DELETE /upload/{id}, GET /upload/{id}/file |
| Upload | POST /upload/ |
| Format yang didukung | GET /upload/supported-formats |
| Knowledge graph dokumen | GET /upload/{id}/knowledge, POST /upload/{id}/knowledge/build |
| Proses ulang | POST /upload/{id}/reprocess |
| Versi baru atau bukan | POST /upload/{id}/versions/link atau /decline |
| Saldo kredit | GET /organizations/me |
| Pemilik jadwal | GET /auth/me, GET /organizations/current/dashboard/members |
Kode lama yang tidak dipakai
Fungsi berikut di src/api/engine.ts tidak dipanggil di mana pun di src/. Ini sisa alur versi awal, yang memakai satu agent tunggal bernama Learning Lab Express dan memanggil Compose langsung:
generateText,generateQuiz:POST /compose/sets,/generate/summary,/generate/quizensureAgent,attachSources,setSchedule,research
resetAgentCache masih dipakai oleh AuthGate.tsx.