OpsDeskOpsDesk · Applied AI workshop
Try the ticket preview ↗Get the project Code · prompts · workflows
Build something visible · understand what runs beneath it

Describe it. Click it. Trace it.

Build a working AI app in the first hour. Add new capabilities to that same app in every later part.

First: what is an agent?
App→Agent + harness→Evidence→OCI
PART 1 OF THE SIX-PART OPSDESK COURSEBuild one useful app around one case: payments feel slow after a release. Collect evidence; do not assume the release caused it. Explore all six parts → · Choose your learner path · Home setup · Langfuse lab
BUILD WITHOpen chosen tool ↗

v0: start with the visible preview, then add a private server route for the agent.

Pick one tool. Start building.

Use the same OpsDesk app prompt in any of these four tools. Choose one for the workshop.

Get help shaping the idea

Use an assistant to refine your app definition, explain code or plan a test. Then bring the result back to your chosen builder.

These links open the assistant websites. They do not connect a model to OpsDesk or provide runtime API credits.

Oracle AI Agent Studio & LiveLabs

Oracle AI Agent Studio for Fusion Applications ↗

For the related OCI-hosted visual walkthrough, open the hands-on Private Agent Factory lab.

Open Oracle LiveLabs · Private Agent Factory ↗
Open your toolkit · official links

Choose one builder and one model backend. The other tools are optional stages; use your own accounts, project and credentials.

BuildBase44 ↗Describe the app and inspect its preview.Buildv0 ↗Generate and iterate on the visible interface.BuildLovable ↗Build an app from the same product definition.BuildCodex ↗Build locally and inspect the actual agent code.AssistantGrok ↗Optional help to refine the app definition and explain the code; configure runtime models separately.AssistantPerplexity ↗Optional help to refine the app definition and explain the code; configure runtime models separately.AssistantClaude ↗Optional help to refine the app definition and explain the code; configure runtime models separately.AssistantGemini ↗Optional help to refine the app definition and explain the code; configure runtime models separately.ModelOllama ↗Optional local model runtime; choose a tool-capable model.ModelLiteLLM ↗Optional gateway to your own approved models.ObserveOpenTelemetry ↗Record spans around real agent actions.ObserveLangfuse ↗Inspect your own project traces, usage and costs.ObserveOCI APM ↗Follow application traces in a configured APM domain.ObserveOCI Log Analytics ↗Query collected logs; correlate by trace ID.HostOCI AI Applications ↗Review the custom agent hosting path.HostOCI CLI ↗Run scoped cloud commands from your own account.RunDocker ↗Optional container runtime.RunColima ↗Optional Mac container runtime.RunPodman ↗Alternative container runtime.VisualizeD3 ↗Interactive teaching diagrams in this guide.VisualizeExcalidraw ↗Edit workflow drawings.VisualizeDraw.io ↗Edit the architecture.ShareGitHub Pages ↗Serve the static student guide from your repository.ReferenceOracle AI Agent Studio ↗Visual agent building for Fusion Applications; a separate product from Private Agent Factory.ReferenceOracle LiveLabs · Private Agent Factory ↗Related hands-on visual agent walkthrough on OCI.
01 · See itStatic ticket preview
No model or credentials
Explore OpsDesk →
02 · Build itYour chosen builder
Your app and backend
03 · Prove itReal action + trace ID
Independent readback
00–05 minutes

Define a small useful app

An incident inbox with one AI action. Start with the visible product.

A helpful investigator with a toolbox

You ask, “Why is payments slow?” A chatbot can write an answer. An agent can also ask a permitted tool for evidence, read the result and decide what to do next. It repeats a small loop until it can answer or a rule tells it to stop.

The model suggests; the harness runs the job

The model is the part that proposes words or a tool call. The harness is the surrounding program: it gives context, checks permissions, runs an allowed tool, remembers the conversation and records the result. A model cannot add a new permission just by asking for it.

What we will build live

OpsDesk gives an operator a ticket inbox and one useful AI action. First the inbox works by itself. Later, Analyze safely asks the runtime investigator to collect synthetic service/release evidence. A convincing answer is not proof: we will look for the actual tool call and its trace.

What should I build first?

One operator, one ticket inbox and one read-only investigation. You do not need a database or cloud account to explore the product sketch.

Try asking: “Which information would let an operator decide their next safe check?” Write that down before choosing a model.

Remember: The coding assistant creates the source; the runtime agent is the program the finished app calls.

Setup, glossary and more help →
MEET YOUR AI TEAMMATE

Follow the helper, one step at a time

The diagram teaches the loop. It does not run a model or send a trace.

  1. Choose one build path: Base44, v0, Lovable or Codex.
  2. Use invented tickets. Keep persistence, real accounts and production connectors out of the first preview.
  3. In the next step, copy the app definition. The AI panel must initially say it is disconnected.
CHECK THE ACTUAL RESULTYou can explain the user, the useful action and which features need a backend.
05–25 minutes

Build and click the app

Get something useful on screen before discussing agent code.

Choose the workshop path that fits your tool

Base44, v0 and Lovable generate a preview from a description. Codex edits files in your chosen workspace. Pick one path for the hour; the app definition and acceptance checks are the same. The Codex tab includes local build instructions and an OCI preparation prompt.

Review capabilities before adding more features

Create a synthetic ticket, search for it, filter by priority and select its detail. These are real UI interactions. Until a backend exists, the AI panel says it is disconnected. Persistence, production login and real operational connectors are additional capabilities, not things a polished preview proves.

The coding assistant is not the runtime agent

The builder or Codex uses its own coding model to produce source. The finished app later calls a separately configured model through a controlled server. An account in a builder does not automatically provide a model key, OCI identity or Langfuse project to your deployed app.

My preview looks good. Am I done?

Create a new synthetic ticket, search for its title, filter it out, clear the filter and select it again. A screenshot alone cannot prove these controls work.

If a control is decorative, ask the builder to implement only that interaction and retest it. Keep the AI panel disconnected until the controls work.

Remember: A hosted builder preview cannot reach a server bound to your laptop’s 127.0.0.1 address.

Setup, glossary and more help →
Prompt to copy
Build OpsDesk, a small incident board for an operations team. Start with the visible
app only. I should be able to click and use it before adding AI.

Create three synthetic tickets: payments is slow (high), checkout needs a health
check (medium), catalog availability check (low). Each has id, title, description,
service and priority. Show an inbox, priority filter, search, selected-ticket detail
and a New ticket form. Ticket edits stay in memory for this first exercise.

Add an Ask AI panel with Analyze safely, a result area and an initial state reading
"AI is not connected yet". Do not generate a fake AI response, pretend to authenticate
a user, or imply that a database exists. Mark all tickets as synthetic training data.

Use Oracle Redwood for a clear desktop/mobile layout: Oracle red accents, warm stone
surfaces, Georgia headings and local Figtree/system UI text. Use only approved brand
assets. Keep compact incident rows and one clear action. Make loading, empty,
validation and failure states usable. Render ticket text as text, never raw HTML.
No paid integrations, real customer data, production connectors, automatic publishing,
real model calls or secrets in this first build. Show which visible features work
and which capabilities still need a backend. Then stop for a review of the preview.
  1. Paste the app definition in your chosen tool and inspect the preview or local app.
  2. Create a synthetic ticket, search for it, change the priority filter and open its detail.
  3. Ask the builder to fix an actual UI problem. Keep the agent disconnected until these controls work.
CHECK THE ACTUAL RESULTTicket interactions work. A polished fake AI answer does not count.
25–45 minutes

Connect the investigator

One button calls a real agent through a server-owned integration.

Explore how the app, harness, model and optional RAG connect
EXPLORE THE CONNECTIONS · D3

The model proposes. Your runtime decides.

An agent is the working loop: a model, a harness and approved capabilities. Choose a story, then select any component to see its job and its boundary.

Solid arrows: request, context or result. Dashed arrows: optional retrieval or telemetry. Color follows the selected step; it does not indicate measured traffic.

Illustration, not execution. This diagram makes no model, retrieval, export or cloud calls. The verified Lovable baseline uses two synthetic tools; RAG is an optional extension. A retrieved document cannot grant permissions. Each telemetry destination needs its own configuration and independent readback.
SECURE IT. THEN OBSERVE IT.

The guardrails below control execution. Langfuse shows what actually ran.

Open the Langfuse setup and trace lab → · Tools to repeat this at home →
AGENT SECURITY · GUARDRAILS IN THE EXECUTION PATH

The model proposes. Your code decides.

A guardrail is a check around an agent action. A system prompt guides the model; a deterministic control decides whether the action can run. Use both, and test the boundary.

1 · BEFORE THE MODEL

Check the request and scope

Validate request shape and size. Resolve the server-owned session and ticket. Reject an explicit change intent before constructing a model.

Enforced in the local referencestudio.py: make_server, Studio.run
desk_backend.py: create_ticket, action
2 · BEFORE EACH TOOL

Limit what the agent can do

Allow only registered tools. Validate names, types, enums and extra/duplicate arguments before a handler runs. Bound steps, context, output and reported usage.

Enforced in the local referencestudio.py: SCHEMAS, _unique_fields, _validate
studio_model.py: streaming bounds
3 · AROUND UNTRUSTED CONTENT

Separate evidence from authority

A ticket or runbook can contain “ignore the rules.” It remains untrusted data. Model instructions say to ignore that request; the code-owned tool registry limits executable capabilities.

Instruction guidance + enforced tool boundarystudio.py: SYSTEM, tool dispatch
4 · BEFORE DISPLAY AND EXPORT

Handle the result safely

Render answers as text, keep failures visible and keep provider keys on the server. The Studio telemetry configuration rejects content capture; verify delivery and readback separately.

Safe rendering and metadata defaults existweb/desk.js: textContent
studio.py: Settings.load
observability.py: Observer

Try a guardrail scenario

These are teaching illustrations, not live security tests. Choose a case and inspect where the execution path should stop.

What does a guardrail NOT replace?

Authentication, least-privilege service identity, secrets management, network policy and runtime isolation still need their own controls. A refusal message, moderation score or trace is not permission enforcement. The current approval_required response is terminal; there is no approval-resume API.

Before production, design authenticated user/tenant ownership, rate limits and spend monitoring, sensitive-data handling, supply-chain checks, secure deployment and human review of privileged actions. None of these is automatically supplied by a chat model.

A two-minute proof to show live
  1. Use the local change-request control. Inspect its actual approval_required outcome and zero model steps.
  2. Run the isolated API and tool-contract tests in the terminal. They use explicit model doubles; they do not attack a provider.
  3. Show which code rejects the action, and distinguish that result from the agent’s final wording.
PYTHONPATH=src .venv/bin/python -m unittest discover -s tests -p 'test_desk_backend.py' -v
PYTHONPATH=src .venv/bin/python -m unittest discover -s tests -p 'test_studio.py' -v

Guardrail implementation map and test plan → · Extend the controls in Part 5 → · OWASP prompt-injection guidance ↗

One button crosses a backend boundary

The browser submits a bounded ticket action to its own server. The server authenticates the user, checks the ticket and selects an allowed agent/model configuration. Provider keys and OCI request signing stay on that server. A SaaS preview cannot call a private laptop loopback address. The local reference is a loopback workshop server, not a production login or tenant boundary.

How the agent is assembled from the harness

Start with the job and the messages it needs. Register narrow tool schemas and reviewed handlers. Add the loop that accepts a model proposal, validates its arguments, executes the handler and appends the observation for the next model call. Add authorization, budgets and metadata spans around those steps.

A framework is useful scaffolding, not an automatic guarantee

The local Studio shows native tool calls; the existing hosted sample uses a LangGraph coordinator and JSON protocol. A framework can organize the flow, but your code still defines ownership, stopping conditions, safe tools and evidence. Matching HTTP paths or changing a URL does not make two different APIs compatible.

Why does Analyze safely fail?

Check whether the request reaches your own server, then inspect its sanitized error. Confirm the exact configured model alias, authentication binding and native tool support.

Start with one ordinary greeting, then one health question. Change one setting at a time; never substitute a canned answer for a failed model call.

Remember: The server chooses the model and looks up the session-owned ticket. Never accept an endpoint or a key from the browser.

Setup, glossary and more help →
INSIDE THE AGENT ENGINE

What does the harness actually contain?

Choose a component to connect the idea with its real source boundary.

Browser action → own server → authenticate and validate
→ bounded agent loop → permitted tool → observation → answer
Prompt to copy
Connect OpsDesk's AI panel to a server-owned agent, keeping the visible app unchanged.
Use the workshop API contract and the exact operator-approved endpoint supplied
outside this prompt. Do not invent a URL, model, key or successful response.

The agent must inspect the selected synthetic incident, use read-only service_health
and release_diff if registered, separate observations from hypotheses and recommend
one safe next check. It cannot run shell, read credentials, deploy or roll back.
Use the explicitly selected model; no automatic provider or scripted fallback.

Keep credentials in your platform's server-side secret store. Browser code calls
our same-origin server function, not the provider or OCI IAM endpoint directly.
Derive session/user scope on the server; never trust a browser-supplied tenant or
permission claim. Validate ticket IDs/fields and cap body size, steps and output.

Add a Test a change request control. Enforce its change intent in code before model
construction; return approval_required without any model invocation or real change.
Implement busy, failure and unavailable-backend states. No automatic retry of AI.
Keep real failures visible and verify that creating/filtering tickets still works.
Do not expose a local server through a public tunnel or enable wildcard CORS.
  1. Provide the exact approved backend through the server integration; no browser keys.
  2. Use Analyze safely. Inspect actual health/release evidence and a cautious next step.
  3. Explain the harness in one sentence: it decides which tools the model may call and when to stop.
CHECK THE ACTUAL RESULTThe selected ticket produces an actual model/tool answer in the app. A provider failure is a blocker to fix, not first-hour completion.
45–50 minutes

Verify the complete user journey

The result must work as an app, not just a terminal experiment.

The app must complete the whole journey

Create a synthetic ticket, search for it, open its detail and run a real investigation. The answer must come from your configured model and permitted tool. A static preview is only a sketch.

The first-hour finish line

Your app has a usable inbox, a connected AI action and clear loading/failure states. Keep its limited in-memory lifetime explicit. Durable persistence and production authentication are separate capabilities.

Tracing is the next addition

Keep the local runtime receipt, but do not spend this build hour provisioning telemetry systems. Part 4 adds the full trace/export/readback workflow to this same app.

How do I know the answer belongs to this ticket?

Create a fresh synthetic ticket, select it and run analysis. Inspect the submitted ticket ID, actual server lookup and tool evidence. Clear stale results when selecting a different ticket.

Repeat the journey once in the actual app. An answer shown only in a terminal or a static preview does not pass the app check.

Remember: The app must work by the end of Part 1. Full export/readback is added in Part 4.

Setup, glossary and more help →
Preview Part 4: tracing the app
SYNTHETIC TRACE · NO LIVE TELEMETRY

Read a trace before opening a real one

Bars use invented durations. Actual OpsDesk evidence is recorded separately; unknown usage and costs remain unknown.
agent.run · one action / one trace
  security.authorize · evaluate intent
  llm.complete · actual generation + reported usage
  tool.service_health · permitted read-only handler
  llm.complete · answer from its observation

OTLP HTTP → own Langfuse /api/public/otel/v1/traces
Project keys remain in the runtime; ticket text stays out of exports.
  1. Create a fresh synthetic ticket, find it, select it and run analysis.
  2. Check that the answer belongs to that selected ticket and repeated clicks do not create concurrent runs.
CHECK THE ACTUAL RESULTThe real app completes ticket creation → selection → AI answer.
50–55 minutes

Test loading and failure states

A usable app explains when its backend cannot answer.

Make errors understandable

Use an isolated test to show a failed request. The UI must clear its loading state and show an honest error without inventing an answer or automatically retrying inference.

Keep the initial boundary small

The initial investigator is read-only and has no shell or infrastructure mutation tool. Keys stay on the server. Part 5 expands the tests and controls without rebuilding the app.

The app stays busy after an error. What should I check?

Inspect the request lifecycle and cleanup path. Both successful and failed responses must clear the busy state and display the actual outcome.

Use an isolated model double or controlled failed request, not a service shutdown. Ensure a later permitted request can run.

Remember: A canned answer is not recovery. Keep real failures visible; add broader security regression tests in Part 5.

Setup, glossary and more help →
  1. Use an isolated test or model double to simulate a failed request without changing shared provider settings.
  2. Verify loading clears, failure stays visible and a later valid action can run.
CHECK THE ACTUAL RESULTNo spinner stays stuck and no canned answer masks a failed provider.
55–60 minutes

Save the working baseline

Every later part extends this same app.

Save the app you can run

Record the source baseline, exact launch commands, model alias requirements and synthetic acceptance journey. Restart it before handing it over.

Extend this app in every next part

Part 2 adds your engine; Part 3 adds model choice and cost; Part 4 adds observability; Part 5 adds security regressions; Part 6 prepares hosting. Keep the working inbox and AI action throughout.

Do I need OCI to complete the first hour?

No. You can finish the local app and explain its target architecture. A live hosted invocation needs your own scoped tenancy, identity, image and network path.

Save the source baseline, exact start/stop command and private config requirements. Restart the app locally before proceeding to Part 2. OCI hosting is added in Part 6.

Remember: The local Studio and hosted coordinator have different request protocols. An adapter and authentication are required; replacing a URL is not a migration.

Setup, glossary and more help →
Preview Part 6: the OCI hosting architecture
Target hosting architecture: browser, app server, OCI application, agent and OTel destinations
Target design, not deployment proof. Editable: Draw.io · Excalidraw · Mermaid
  1. Write exact start/stop steps, private config requirements and the working app URL.
  2. Save a local baseline copy or approved revision; do not publish credentials.
  3. List the next addition: your own bounded engine in Part 2.
CHECK THE ACTUAL RESULTAnother learner can restart this scoped app and reproduce its AI action with their own model.

0 of 6 results checked · checks are self-reported

Illustrations teach the system; live OpsDesk receipts prove execution. SaaS generation, real model behavior, telemetry readback and OCI deployment are separate checks. This guide does not invoke a model, spend credits or create resources.