All examples in this page assume environment variables are available. For convenience, create a .env file in the repository root (you can copy from .env.example) with:
Set TUDELFT_TULIP_BASE_URL to host root only (for example https://api.tulip.tudelft.nl). The Python helper normalizes it to a capability-specific /v1 endpoint automatically.
What these examples assume
The Python snippets on this page assume a local helper file common.py that loads environment variables and exports shared constants.
If you cloned this repository, examples/common.py is already present and the scripts run as shown below.
If you have not cloned the repo and are working with Python, expand the helper snippet below and place common.py next to the example you want to run.
Python run commands use pixi run python ...; dependencies come from pixi.toml.
Bash examples pretty-print JSON using jq, so you may need to install it.
TUDELFT_TULIP_CAPABILITY chooses the path segment (for example code or chat).
TUDELFT_TULIP_MODEL_ALIAS chooses the deployed model alias.
For strict OpenAI-style tool_calls output, use the currently verified code alias.
If you have not cloned the repo and are working with Python, create common.py next to the example
importosfromdotenvimportload_dotenvload_dotenv()# loads .env if presentTUDELFT_TULIP_BASE_URL=os.getenv("TUDELFT_TULIP_BASE_URL","https://api.tulip.tudelft.nl")TUDELFT_TULIP_CAPABILITY=os.getenv("TUDELFT_TULIP_CAPABILITY","chat")TUDELFT_TULIP_API_KEY=os.getenv("TUDELFT_TULIP_API_KEY","DUMMY_KEY")TUDELFT_TULIP_MODEL_ALIAS=os.getenv("TUDELFT_TULIP_MODEL_ALIAS","chat")# Normalize TUDELFT_TULIP_BASE_URL to capability/v1. Docs recommend host root only,# but we also accept URLs that already include capability or capability/v1._base_url=TUDELFT_TULIP_BASE_URL.rstrip("/")if_base_url.endswith("/v1"):TUDELFT_TULIP_BASE_URL=_base_urlelif_base_url.endswith(f"/{TUDELFT_TULIP_CAPABILITY}"):TUDELFT_TULIP_BASE_URL=f"{_base_url}/v1"else:TUDELFT_TULIP_BASE_URL=f"{_base_url}/{TUDELFT_TULIP_CAPABILITY}/v1"
Endpoint
Tool calling is available at /v1/chat/completions via the tools parameter.
Endpoint And Format Limitations
These examples use Chat Completions endpoint (client.chat.completions.create, messages=[...]).
Although OpenAI also documents a Responses API variant (client.responses.create, input=[...]), tool calling via Responses currently does not work in this environment due to a backend serving limitation.
Tool-calling output shape is model/capability dependent; some configurations emit raw tool markup in message.content instead of structured message.tool_calls.
For strict OpenAI-style checks in this tutorial, treat a non-empty message.tool_calls array as the pass condition.
fromcommonimport(TUDELFT_TULIP_API_KEY,TUDELFT_TULIP_BASE_URL,TUDELFT_TULIP_MODEL_ALIAS,)fromopenaiimportOpenAIclient=OpenAI(base_url=TUDELFT_TULIP_BASE_URL,api_key=TUDELFT_TULIP_API_KEY)model=TUDELFT_TULIP_MODEL_ALIAStools=[{"type":"function","function":{"name":"get_system_health","description":"Returns current health status.","parameters":{"type":"object","properties":{},},},}]completion=client.chat.completions.create(model=model,messages=[{"role":"user","content":("Call the get_system_health tool now. ""Do not answer in natural language."),}],tools=tools,tool_choice="required",temperature=0,max_tokens=64,)print(completion.model_dump_json(indent=2))
fromcommonimport(TUDELFT_TULIP_API_KEY,TUDELFT_TULIP_BASE_URL,TUDELFT_TULIP_MODEL_ALIAS,)fromopenaiimportOpenAIclient=OpenAI(base_url=TUDELFT_TULIP_BASE_URL,api_key=TUDELFT_TULIP_API_KEY)model=TUDELFT_TULIP_MODEL_ALIAStools=[{"type":"function","function":{"name":"get_system_health","description":"Returns current health status.","parameters":{"type":"object","properties":{},},},}]completion=client.chat.completions.create(model=model,messages=[{"role":"user","content":"Hey, quick check: is everything up and running?",},{"role":"assistant","tool_calls":[{"id":"call-1","type":"function","function":{"name":"get_system_health","arguments":"{}",},}],},{"role":"tool","tool_call_id":"call-1","content":'{"status":"ok","uptime_seconds":372045}',},],tools=tools,temperature=0,max_tokens=128,)print(completion.model_dump_json(indent=2))
Run:
pixirunpythonexamples/python_tool_call_loop.py
Success looks like
The model consumes the provided tool message.
Final assistant response is coherent and consistent with tool output.