Build an AI agent that reads and writes to a Progress OpenEdge database and books automotive service appointments. This workshop is designed for OpenEdge developers with no prior Python/agent experience. You’ll follow a guided path, copying working examples at each step and learning how they fit together.
We’ll use PASOE REST services for data access, a small Python driver to call those services, and a LiveKit agent (with OpenAI) that converses with users, manages car records, and schedules bookings. We’ll initially run the agent through the LiveKit Agents Playground and if time, implement a React front end and python token service to complete the app.
- OpenEdge REST services for
CarandBookingrecords. - A small, testable Python driver (
OEDatabaseDriver) that calls those REST endpoints. - A LiveKit agent that uses function tools to call your driver:
- Lookup/add car details.
- Offer/confirm bookings.
- A multi-agent version showing a handoff from an Account agent → Booking agent.
- (Optional, if time permits) A lightweight React + Token server demo UI.
You’ll copy the code for each step from the provided examples/ folders and focus on wiring/config + understanding.
- Progress OpenEdge Developers Kit (CLASSROOM edition is sufficient) https://www.progress.com/oedk
- Visual Studio Code (Code editor for python and js) — https://code.visualstudio.com/
- Node.js (for React frontend) — https://nodejs.org/
- Python 3.10+ (venv)
- A modern browser with mic access (if testing voice)
- Accounts/keys:
- LiveKit (API key/secret, URL)
- OpenAI (API key)
You’ll place secrets in a local
.envfile during setup.
- Progress OpenEdge Developers Kit https://www.progress.com/oedk
- Visual Studio Code — https://code.visualstudio.com/
- Python (For agent server-side code) — https://www.python.org/downloads/
- LiveKit — https://livekit.io/
- LiveKit Agents Playground — https://agents-playground.livekit.io/
- OpenAI Platform (Create API key) — https://platform.openai.com/
- Node.js (Optional frontend) — https://nodejs.org/
/openedge/ # ABL handlers/services templates for Car/Booking and test app
/python/
/step2/ # OEDatabaseDriver env sanity-check
/step3/ # save_car() via POST
/step4/ # get_car() via GET + dataclass
/step5/ # Single-agent (car lookup/add) with LiveKit
/step6/ # Adds booking tools + driver methods
/step7/ # Multi-agent architecture AccountAgent → BookingAgent handoff
/frontend/ # (Optional) React demo UI
/token-server/ # (Optional) LiveKit token server (Python)
README.md
- Create working directories:
C:\OpenEdge\WRK\oeautos C:\OpenEdge\WRK\oeautos\db - Create an empty database:
prodb oeautos empty - Load schema file:
load oeautos.df - Add
oeautosdatabase to Progress OE Explorer and start it (make a note of the port number i.e 25150). - Create a new Progress Application Server with the following settings:
- Instance name:
oeautos - AdminServer:
localhost - Location: Local
- Security model: Developer
- Autostart: checked
- Instance name:
- Edit the
oeautosABL application configuration:- Startup parameters:
-db oeautos -H localhost -S 25150 - Add
C:\OpenEdge\WRK\oeautosto PROPATH
- Startup parameters:
- Start the AppServer.
- In OE Developer:
- Choose
C:\OpenEdge\WRK\oeautosas the new workspace - Create a new OpenEdge project named AgentTools
- Server project
- Transport: REST
- Finish → Open Perspective
- Delete Defined Services → AgentToolsService (we will create are own')
- Choose
- Add database to project:
- Right-click project → Properties → Progress OpenEdge → Database Connections → Configure database connections
- Click New to add new connection for
oeautosserver. - Connection name: oeautos
- Physical name: db\oeautos
- Host name: localhost
- Service/Port: 25150
- Press Next to Finish, then Apply and Close
- Select checkbox next to the new connection, Apply and Close
- Add Server to project:
- Right-click project → New → Server
- Select Progress Software Corporation → Progress Application Server for OpenEdge, and press Next
- Select oeautos PAS and press Finish
- Add a new webhandler:
- Name:
carRestHandler - Unselect all method stubs
- Copy in template code
- Name:
- Add REST service:
- Right-click project → New → ABL Service
- Transport: REST
- Name:
carService - Relative URI:
/carService
- Right-click project → New → ABL Service
- Add saveCar resources:
- select carService in Project Explorer
- press the green + button to the right of ABL Resources
- Resource URI: /saveCar
- Press OK
- Select ... to the right of Verb='POST'
- Select Resource PASOEContent → WEB-INF → openedge → carRestHandler.cls
- Select ABL routines → saveCar
- Press OK
- In Mapping Resources → Input → HTTP Message, right click Form Parameters and select Add Node
- Type: Form Parameter
- Form Parameter: reg
- In Mapping Resources → Input → HTTP Message → Form Parameters left click over reg and drag the connector to Parameters → Interface Parameters → reg
- Repeat to add and bind Form Parameters for make, model and year
- Select the Output tab under Mapping Resources
- Drag a connector from Mapping Resources → Output → Parameters → Interface Parameters → response to Mapping Resources → Output → Response → HTTP Message → Body (NB: Be careful to drag the connector to the line that contains 'Body', not the line below that displays [Drop a parameter here...])
- Add getCar resources:
- select carService in Project Explorer
- press the green + button to the right of ABL Resources
- Resource URI: /getCar
- Press OK
- Select ... to the right of Verb='GET'
- Select Resource PASOEContent → WEB-INF → openedge → carRestHandler.cls
- Select ABL routines → getCar
- Press OK
- In Mapping Resources → Input → URL Parameters, right click Query String Parameters and select Add Node
- Type: Query String Parameter
- Query String Parameter: reg
- In Mapping Resources → Input → URL Parameters → Query String Parameters left click over reg and drag the connector to Parameters → Interface Parameters → reg
- Drag a connector from Mapping Resources → Output → Parameters → Interface Parameters → ttCar to Mapping Resources → Output → Response → HTTP Message → Body (NB: Be careful to drag the connector to the line that contains 'Body', not the line below that displays [Drop a parameter here...])
- Publish the service to the
oeautosserver:- Save carService changes
- In the Servers panel, right click oeautos in .. and select Add and Remove
- Select carService in the Available list, and press Add>
- Press Finish
- Install VSCode and Python (if you don't already have them).
- Visual Studio Code — https://code.visualstudio.com/
- Python (For agent server-side code) — https://www.python.org/downloads/
- Create directory C:\Work\Agent and open folder in VSCode
- Create and activate a virtual environment:
py -m venv .venv .\.venv\Scripts\activate
- Create a
C:\work\Agent\requirements.txtfile and add:Then install:python-dotenvpip install -r requirements.txt
- Create a
.envfile with:OE_SERVICE_URL=http://localhost:8080/AgentTools/rest/ - Copy
OEDatabaseDriver.pyStep 2 code to C:\Work\Agent\OEDatabaseDriver.py (load.envand printOE_SERVICE_URL). - Run the code to test
py OEDatabaseDriver.py- Copy requirements.txt and OEDatabaseDriver.py from Step 3 into C:\work\Agents. Note 'requests' has been added to requirements.txt and OEDatabaseDriver.py now shows errors
- Install new dependencies
pip install -r requirements.txt
- Review save_car method
- Run the code to test
py OEDatabaseDriver.py- Use OpenEdge\ViewCars.w to confirm record has been created
- Copy OEDatabaseDriver.py from Step 4 into C:\work\Agents.
- Review get_car method
- Run the code to test
py OEDatabaseDriver.py- Copy contents of Step 5 into c:\work\Agent
- Install new dependencies
pip install -r requirements.txt
- Create a LiveKit account:
- Goto https://livekit.io
- Click Start Building
- Create account
- Create you first project: name 'PUG Challenge'
- Complete survey
- Settings → API Keys
- Select API Key
- Press Reveal Secret
- Copy Environmental Variables
- Paste into .env
- Create an OpenAI account
- Create an account at https://platform.openai.com/ (you will need to add some credit. $5 is plenty.)
- Click cog icon (top right)
- Select API keys
- press + Create new secret key
- Copy secret
- Add OPENAI_API_KEY=[YOUR KEY] to .env and save
- Review code
- Start agent:
py main.py dev- Log into https://agents-playground.livekit.io/ and connect
- Check the agent can create a car in the DB. Disconnect, and re-connect, check the agent can look up a car.
- Add new OpenEdge web handler for bookings (
bookingRestHandler), copy code from Step 6 - Add new ABL Service (
bookingService) - Add REST resource (
getNextAvailableBooking), GET verb bound to GetNextAvailableBooking, with input query parameter startDate, and output bookingDate to the Body. - Add REST resource (
saveBooking), POST bound to verb bound to SaveBooking, with form parameters reg, bookingDate and description and output response bound to Body. - ADD REST resource (
getBooking), GET verb bound to GetBooking, with query parameter reg, and output parameters BookingDate and Description bound to the Body parameters Note: You need to bind these parameters to the parameters section of the body ([Drop a parameter here]), not the body itself - Save your changes, and publish to the server.
- Copy in code from STEP 6 and review.
- Start agent:
py main.py dev- Log into https://agents-playground.livekit.io/ and connect
- Check the agent can create a booking in the DB. Disconnect, and re-connect, check the agent can look up a booking.
- Copy in code from STEP 7 and review.
- Start agent:
py main.py dev- Log into https://agents-playground.livekit.io/ and check agent behaviour
- If you don’t already have it, download and install node.js https://nodejs.org/
- Open new cmd and cd to C:\Work
- Run command
npm create vite@latest frontend -- --template react- Open frontend directory in a new VSCode window
- Install dependencies:
npm install npm install @livekit/components-react @livekit/components-styles livekit-client --save
- Delete “C:\Work\frontend\src\assets” and “C:\Work\frontend\public” folders
- Copy in contents of frontend\step 1
- Log in to https://LiveKit.io, got settings..API Keys .. Generate Token
- Copy token to line 16 of src/components/LiveKitModal.jsx
- Create a .env file and enter
VITE_LIVEKIT_URL=[YOUR LIVEKIT URL]
- Run front end with
npm run dev- Create directory C:\work\TokenServer
- Open a new VSCode window, and open directory C:\work\TokenServer
- New Terminal
- Create virtual environment
py -m venv .venv - Activate the virtual environment
.\.venv\Scripts\activate- copy contents of TokenServer from the workshop files
- Install requirements
pip install -r requirements.txt- Enter livekit values into .env
- Start server
py server.py- Copy contents of frontend\step 2
- Run frontend with
npm run dev”In the LiveKit Agents Playground:
- The agent greets and asks for your registration.
- Provide a reg (e.g.,
AB12 CDE).- If found, it shows car details.
- If not, it asks for make, model, year and adds the car.
- The agent asks if you’d like to book an appointment or check existing.
- Try “Book me in for the next available date for an annual service.”
- Agent retrieves next slot, confirms, and saves the booking.
- Ask “What’s my next booking?” to verify.
- Python venv: keep dependencies isolated (
python -m venv .venv→ activate →pip install -r requirements.txt). - .env: never commit secrets; store
OE_SERVICE_URL, LiveKit & OpenAI keys locally. - Run steps: each
python/stepXfolder contains a small script (main.pyor similar) to run that step.
- PASOE service not reachable: confirm it’s published, note the correct port/context, and that
OE_SERVICE_URLends with/rest/. - LiveKit connection: verify
LIVEKIT_URL,LIVEKIT_API_KEY, andLIVEKIT_API_SECRETin.env. - OpenAI: ensure
OPENAI_API_KEYis set and your model name is valid for your account.
- Whitespace = blocks (no
END.). Indentation is syntax. - Run files directly (
python myfile.py); manage deps with venv + pip (requirements.txt). - Functions use
defand return values directly (multiple returns via tuples). - Dataclasses (
@dataclass) create light DTOs for records likeCar. - Requests library is the go‑to for HTTP calls (
requests.get/post,r.json()). - OO Basics:
class,__init__,self(likeTHIS-OBJECT, but explicit). Inherit withclass Sub(Super):.
MIT
- LiveKit Agents
- Progress OpenEdge
- OpenAI