Commit Graph

177 Commits

Author SHA1 Message Date
lidia9 7d6ddd3a4f tool output streaming works 2025-04-25 12:35:56 +02:00
lidia9 734ef479f4 FIX streaming output tool - still some visualization duplicates 2025-04-25 10:33:12 +02:00
lidia9 ac9135b75e remove prints 2025-04-23 12:28:47 +00:00
lidia9 b6457bb329 UI - fix display metrics, token count, pricing, session cost - REMOVE some prints 2025-04-23 10:03:51 +00:00
lidia9 960215976b UI - fix display metrics, token count, pricing, session cost and so on 2025-04-23 09:58:29 +00:00
Mery-Sanz 2eb2eb7a59 final fiz 2025-04-23 09:04:48 +02:00
lidia9 f21b8119e7 FIX UI - remove duplicated tool call print 2025-04-22 15:17:14 +00:00
lidia9 58872b6667 FIX UI - CAI_STREAM=false - one panel for each message, tool call, output 2025-04-22 15:12:49 +00:00
Mery-Sanz aa6ea56ca8 add test to ci 2025-04-22 16:58:07 +02:00
Mery-Sanz dae41dbba7 add test 2025-04-22 16:48:12 +02:00
Mery-Sanz 702a93b6c3 fix agent and add primary test 2025-04-22 16:32:26 +02:00
lidia9 19b314efc7 FIX UI - CAI_STREAM=false - print messages well parsed & parsed tool calls 2025-04-22 12:59:42 +00:00
Mery-Sanz 49f5ccb235 fix tools 2025-04-22 13:35:42 +02:00
Víctor Mayoral Vilches e0ca89f3d1 Merge branch 'test_ci' into 'v0.4.0'
Bring unite tests from 0.3.x

See merge request aliasrobotics/alias_research/cai!141
2025-04-22 07:39:16 +00:00
lidia9 0bced4cbf3 removing prints from pricing changes 2025-04-22 07:15:01 +00:00
Lidia 2ba7c90693 remove prints 2025-04-11 11:18:07 +02:00
Lidia 0bcd3fff05 remove prints 2025-04-11 11:13:23 +02:00
Lidia d4909c5288 FIX show pricing for CAI_STREAM=true 2025-04-11 11:02:30 +02:00
Lidia 2cf6bc01c3 undo changes in openai_responses.py and leave it as it was originally in v0.4.0 2025-04-11 09:53:51 +02:00
Mery-Sanz 59e8e444ca add test 2025-04-10 07:58:40 +02:00
Mery-Sanz 1bc4b8fd9e final fix 2025-04-09 16:17:06 +02:00
Lidia 6cc4c4c501 FIX show pricing - calculate pricing 2025-04-09 15:48:59 +02:00
Víctor Mayoral Vilches fa198de051 Fix streaming responses in CAI and examples
Signed-off-by: Víctor Mayoral Vilches <v.mayoralv@gmail.com>
2025-04-03 10:53:33 +02:00
Víctor Mayoral Vilches 9f5073c3a5 CLI output operational
Signed-off-by: Víctor Mayoral Vilches <v.mayoralv@gmail.com>
2025-04-03 08:19:42 +02:00
Víctor Mayoral Vilches 47bd38b4aa Fix docs
Signed-off-by: Víctor Mayoral Vilches <v.mayoralv@gmail.com>
2025-04-02 16:48:23 +02:00
Víctor Mayoral Vilches 62212d04b5 Address issues with litellm and agents SDK
Squeezed in some additional features such as:
- updated get_version()
- various examples for streaming and non-streaming testing

Signed-off-by: Víctor Mayoral Vilches <v.mayoralv@gmail.com>
2025-04-02 14:03:00 +02:00
Víctor Mayoral Vilches d3b6f8a1ed Merge remote-tracking branch 'origin/main' into cai 2025-03-31 13:21:34 +02:00
Víctor Mayoral Vilches 28d98cd3cd Streaming now working for OLLAMA models, but not the rest. Figure it out
Signed-off-by: Víctor Mayoral Vilches <v.mayoralv@gmail.com>
2025-03-30 09:21:25 +02:00
Víctor Mayoral Vilches c75c272f36 Made local models work by switching into litellm python APIs
Still some issues with stream versions which needs further
investigation

Signed-off-by: Víctor Mayoral Vilches <v.mayoralv@gmail.com>
2025-03-29 20:17:42 +01:00
Víctor Mayoral Vilches 859799c9f4 CLI responding, but only to proprietary models
Need to investigate why self-hosted models via OLLAMA fail API-wise

Signed-off-by: Víctor Mayoral Vilches <v.mayoralv@gmail.com>
2025-03-28 09:48:16 +01:00
Víctor Mayoral Vilches ba25c5234f Address error while streaming
[Error occurred during streaming: 1 validation error for ResponseUsage
input_tokens_details
  Input should be a valid dictionary or instance of InputTokensDetails [type=model_type, input_value=InputTokensDetails(prompt...ens=17, cached_tokens=0), input_type=InputTokensDetails]
    For further information visit https://errors.pydantic.dev/2.10/v/model_type]
Location: Traceback (most recent call last):
  File /Users/alias/Alias/research/openai-agents-python/src/cai/cli.py, line 209, in process_streamed_response
    async for event in result.stream_events():
  File /Users/alias/Alias/research/openai-agents-python/src/cai/sdk/agents/result.py, line 186, in stream_events
    raise self._stored_exception
  File /Users/alias/Alias/research/openai-agents-python/src/cai/sdk/agents/run.py, line 539, in _run_streamed_impl
    turn_result = await cls._run_single_turn_streamed(
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File /Users/alias/Alias/research/openai-agents-python/src/cai/sdk/agents/run.py, line 641, in _run_single_turn_streamed
    async for event in model.stream_response(
  File /Users/alias/Alias/research/openai-agents-python/src/cai/sdk/agents/models/openai_chatcompletions.py, line 421, in stream_response
    ResponseUsage(
  File /Users/alias/Alias/research/openai-agents-python/env/lib/python3.12/site-packages/pydantic/main.py, line 214, in __init__
    validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pydantic_core._pydantic_core.ValidationError: 1 validation error for ResponseUsage
input_tokens_details
  Input should be a valid dictionary or instance of InputTokensDetails [type=model_type, input_value=InputTokensDetails(prompt...ens=17, cached_tokens=0), input_type=InputTokensDetails]
    For further information visit https://errors.pydantic.dev/2.10/v/model_type

Signed-off-by: Víctor Mayoral Vilches <v.mayoralv@gmail.com>
2025-03-28 08:35:11 +01:00
Víctor Mayoral Vilches 82054a2e1c Fix docs
Signed-off-by: Víctor Mayoral Vilches <v.mayoralv@gmail.com>
2025-03-28 07:55:41 +01:00
Víctor Mayoral Vilches 7b1d89db78 Advanced aligning agents but various missing bits:
- agents can't translate directly it seems, see current error
- in addition, it appears streaming mode leads to other problems

Signed-off-by: Víctor Mayoral Vilches <v.mayoralv@gmail.com>
2025-03-27 19:36:58 +01:00
Víctor Mayoral Vilches a45f1fb22f Add blue team agent
Signed-off-by: Víctor Mayoral Vilches <v.mayoralv@gmail.com>
2025-03-27 15:14:35 +01:00
Víctor Mayoral Vilches 21d3f78ff5 Add tools, prompts and agents
Signed-off-by: Víctor Mayoral Vilches <v.mayoralv@gmail.com>
2025-03-27 15:06:12 +01:00
Víctor Mayoral Vilches 34a7bad920 Re-structure under sdk/agents, get CLI mockup
Signed-off-by: Víctor Mayoral Vilches <v.mayoralv@gmail.com>
2025-03-27 14:31:38 +01:00
Steven Heidel aad8accc86
Expose the "store" parameter through ModelSettings (#357)
Closes https://github.com/openai/openai-agents-python/issues/173

This will also set stored completions to True by default, encouraging a
best practice.
2025-03-26 19:01:28 -04:00
Rohan Mehta 4854a745e8
Raise error on more invalid function schemas (#356)
Towards #345

## Summary:
Using a `dict` or `Mapping` isn't strict-mode compliant. But we were
checking for the literal `True` whereas the value can also be an array,
for example. Fix that.

## Test Plan:

Unit tests
2025-03-26 15:52:19 -04:00
pakrym-oai 6d95a3f191
Mark handoff span as errored when multiple handoffs are requested (#344)
Also includes the set of requested agents in the error data.
<img width="968" alt="image"
src="https://github.com/user-attachments/assets/0c5c2e81-08f7-445c-bbb0-3e169ef744a5"
/>
2025-03-26 10:44:59 -04:00
Rohan Mehta b5ba22904a
[5/n] MCP tracing (#342)
## Summary:

Adds tracing and tests for tracing.
- Tools are added to the agents
- Theres a span for the mcp tools lookup
- Functions have MCP data

## Test Plan:

Unit tests
.
2025-03-25 19:54:28 -04:00
Rohan Mehta 010022777b [5/n] MCP tracing
## Summary:

Adds tracing and tests for tracing.
- Tools are added to the agents
- Theres a span for the mcp tools lookup
- Functions have MCP data

## Test Plan:

Unit tests
.
2025-03-25 19:28:48 -04:00
Rohan Mehta dd881eed9a
feat: Add Graphviz-based agent visualization functionality (#147)
This pull request introduces functionality for visualizing agent
structures using Graphviz. The changes include adding a new dependency,
implementing functions to generate and draw graphs, and adding tests for
these functions.

New functionality for visualizing agent structures:

* Added `graphviz` as a new dependency in `pyproject.toml`.
* Implemented functions in `src/agents/visualizations.py` to generate
and draw graphs for agents using Graphviz. These functions include
`get_main_graph`, `get_all_nodes`, `get_all_edges`, and `draw_graph`.

Testing the new visualization functionality:

* Added tests in `tests/test_visualizations.py` to verify the
correctness of the graph generation and drawing functions. The tests
cover `get_main_graph`, `get_all_nodes`, `get_all_edges`, and
`draw_graph`.

For example, given the following code:

```python
from agents import Agent, function_tool
from agents.visualizations import draw_graph


@function_tool
def get_weather(city: str) -> str:
    return f"The weather in {city} is sunny."


spanish_agent = Agent(
    name="Spanish agent",
    instructions="You only speak Spanish.",
)

english_agent = Agent(
    name="English agent",
    instructions="You only speak English",
)

triage_agent = Agent(
    name="Triage agent",
    instructions="Handoff to the appropriate agent based on the language of the request.",
    handoffs=[spanish_agent, english_agent],
    tools=[get_weather],
)


draw_graph(triage_agent)
```

Generates the following image:

<img width="614" alt="Screenshot 2025-03-13 at 18 36 23"
src="https://github.com/user-attachments/assets/d01fe502-6886-4efb-aaf8-c92e4524b0fe"
/>
2025-03-25 19:22:58 -04:00
Martín Bravo 70aff1d39d linting 2025-03-25 19:18:57 +01:00
Martín Bravo 3068e42029 Fix type ignore comment for agent check in get_all_edges function 2025-03-25 19:17:35 +01:00
Martín Bravo 351b6074e5 Refactor visualization functions to improve formatting and streamline edge generation 2025-03-25 19:12:40 +01:00
Martín Bravo 5ad53d8000 Add start and end nodes to graph visualization and update edge generation 2025-03-25 19:11:43 +01:00
Martín Bravo b9d32cda0f Refactor get_all_edges function to remove unused parent parameter 2025-03-25 19:02:21 +01:00
Martín Bravo 2f2606e5ea Add graphviz as a dependency and update import statements 2025-03-25 18:46:23 +01:00
Rohan Mehta 6fb5792b77 Make the reset behavior on tool use configurable
## Summary:

#263 added this behavior. The goal was to prevent infinite loops when tool choice was set. The key change I'm making is:
1. Making it configurable on the agent.
2. Doing bookkeeping in the Runner to track this, to prevent mutating agents.
3. Not resetting the global tool choice in RunConfig.

## Test Plan:
Unit tests.
.
2025-03-25 13:29:32 -04:00
Rohan Mehta b98a6bd4ac [4/n] Add docs for MCP
Just adding docs.
-
2025-03-25 13:25:50 -04:00
Martín Bravo 57ecebfe35 Refactor visualization node label formatting in get_all_nodes function 2025-03-25 18:16:29 +01:00
Martín Bravo 48fad9e2d3 Merge branch 'main' of https://github.com/openai/openai-agents-python into feat/draw_graph 2025-03-25 18:02:51 +01:00
Rohan Mehta 4f8cbfa676
[2/n] Add MCP support to Runner (#321)
### Summary:
This enables users to **use** MCP inside the SDK.
1. You add a list of MCP servers to `Agent`, via `mcp_server=[...]`
2. When an agent runs, we look up its MCP tools and add them to the list
of tools.
3. When a tool call occurs, we call the relevant MCP server.

Notes:
1. There's some refactoring to make sure we send the full list of tools
to the Runner/Model etc.
2. Right now, you could have a locally defined tool that conflicts with
an MCP defined tool. I didn't add errors for that, will do in a
followup.

### Test Plan:
See unit tests. Also has an end to end example next PR.

---
[//]: # (BEGIN SAPLING FOOTER)
* #324
* #322
* __->__ #321
* #320
2025-03-25 12:53:29 -04:00
Rohan Mehta 97e3dc3c76 [1/n] Add MCP types to the SDK
### Summary:
1. Add the MCP dep for python 3.10, since it doesn't support 3.9 and below
2. Create MCPServer, which is the agents SDK representation of an MCP server
3. Create implementations for HTTP-SSE and StdIO servers, directly copying the [MCP SDK example](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/clients/simple-chatbot/mcp_simple_chatbot/main.py)
4. Add a util to transform MCP tools into Agent SDK tools

Note: I added optional caching support to the servers. That way, if you happen to know a server's tools don't change, you can just cache them.

### Test Plan:

Checks pass. I added tests at the end of the stack.
2025-03-25 12:51:40 -04:00
Martín Bravo 900a97fa55 Merge branch 'main' of https://github.com/openai/openai-agents-python into feat/draw_graph 2025-03-25 16:58:01 +01:00
Rohan Mehta 923a3547eb
Fix parallel_tool_calls when False (#333)
Currently, when we set `parallel_tool_calls=False` in the
`model_settings`, the responses API is called with `parallel_tool_calls
== NotGiven`, which defaults to true on the Response API side
(https://platform.openai.com/docs/api-reference/responses/create#responses-create-parallel_tool_calls).

This PR attempts to fix that.

```
agent = Agent(
    ...,
    model_settings=ModelSettings(
        parallel_tool_calls=False,
    ),
)
```
2025-03-25 11:31:06 -04:00
Rohan Mehta 927a29c56b
Fix potential infinite tool call loop by resetting tool_choice after … (#263)
# Fix potential infinite tool call loop by resetting tool_choice after
tool execution

## Summary

This PR fixes an issue where setting `tool_choice` to "required" or a
specific function name could cause models to get stuck in an infinite
tool call loop.

When `tool_choice` is set to force tool usage, this setting persists
across model invocations. This PR automatically resets `tool_choice` to
"auto" after tool execution, allowing the model to decide whether to
make additional tool calls in subsequent turns.

Unlike using `tool_use_behavior="stop_on_first_tool"`, this approach
lets the model continue processing tool results while preventing forced
repeated tool calls.

## Test plan

- Added tests to verify tool_choice reset behavior for both agent and
run_config settings
- Added integration test to verify the solution prevents infinite loops
- All tests pass

## Checks

- [x] I've added new tests for the fix
- [x] I've updated the relevant documentation (added comment in code)
- [x] I've run `make lint` and `make format`
- [x] I've made sure tests pass
2025-03-25 11:30:53 -04:00
apeccaud 326ff09127 Fix parallel_tool_calls when False 2025-03-25 14:52:48 +00:00
Rohan Mehta 68c800d2a3 [2/n] Add MCP support to Runner
### Summary:
This enables users to **use** MCP inside the SDK.
1. You add a list of MCP servers to `Agent`, via `mcp_server=[...]`
2. When an agent runs, we look up its MCP tools and add them to the list of tools.
3. When a tool call occurs, we call the relevant MCP server.

Notes:
1. There's some refactoring to make sure we send the full list of tools to the Runner/Model etc.
2. Right now, you could have a locally defined tool that conflicts with an MCP defined tool. I didn't add errors for that, will do in a followup.

### Test Plan:
See unit tests. Also has an end to end example next PR.
2025-03-24 15:08:02 -04:00
Rohan Mehta 300e12c198 [1/n] Add MCP types to the SDK
### Summary:
1. Add the MCP dep for python 3.10, since it doesn't support 3.9 and below
2. Create MCPServer, which is the agents SDK representation of an MCP server
3. Create implementations for HTTP-SSE and StdIO servers, directly copying the [MCP SDK example](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/clients/simple-chatbot/mcp_simple_chatbot/main.py)
4. Add a util to transform MCP tools into Agent SDK tools

Note: I added optional caching support to the servers. That way, if you happen to know a server's tools don't change, you can just cache them.

### Test Plan:

Checks pass. I added tests at the end of the stack.
2025-03-24 15:08:02 -04:00
Víctor Mayoral Vilches 722601045b Initial re-structuring towards CAI
Signed-off-by: Víctor Mayoral Vilches <v.mayoralv@gmail.com>
2025-03-24 19:47:41 +01:00
Martín Bravo 623063b633 refactor: clean up visualization functions by removing unused nodes and improving type hints 2025-03-24 09:47:21 +01:00
Martín Bravo a5b7abe8b4 feat: enhance visualization functions with optional type hints and improved handling of agents and handoffs 2025-03-24 09:30:13 +01:00
Rohan Mehta 4cb011c4d2
Fix Typos (#258)
Noticed a bunch of typos when reading code, fixing.
2025-03-23 20:28:14 -04:00
Rohan Mehta 668fac0f74 Improve tracing error messages 2025-03-23 18:14:10 -04:00
xianghuijin 07a4af1fe2 refactor: improve comments for clarity in tool_choice reset logic 2025-03-23 20:41:18 +08:00
xianghuijin 0c747af743 refactor: streamline tool_choice reset logic
This update moves the tool_choice reset logic to a more appropriate location within the RunImpl class, ensuring that the original agent's model_settings remains unmodified during the reset process. The logic now checks for problematic scenarios before creating a modified copy of the agent's settings, maintaining expected behavior across sequential runs. This change enhances clarity and efficiency in handling tool choices.

Addresses previous feedback regarding the modification of the agent instance and improves the overall structure of the reset logic.
2025-03-23 20:04:39 +08:00
xianghuijin 6ed0bee672 fix: prevent modifying the original agent's model_settings
This fixes the issue where the original agent's model_settings was being directly modified during the tool choice reset process. The original implementation caused the agent's tool_choice to unintentionally reset to "auto" for subsequent runs, which could be unexpected behavior.

The fix creates new copies of the agent and model settings objects using dataclasses.replace() instead of modifying the original objects. This ensures that the tool choice reset is limited to the current run only, maintaining the expected behavior for sequential runs with the same agent.

Addresses feedback from @baderalfahad about the agent instance being modified when it should maintain its original state between runs.
2025-03-23 17:20:23 +08:00
xianghuijin bbcda753df fix: optimize tool_choice reset logic and fix lint errors
- Refactor tool_choice reset to target only problematic edge cases
- Replace manual ModelSettings recreation with dataclasses.replace
- Fix line length and error handling lint issues in tests
2025-03-22 14:10:09 +08:00
Raduan77 ab0d940f19 revert src/ change per request 2025-03-22 01:06:01 +01:00
Rohan Mehta c0794a90ec Read tracing API data lazily 2025-03-21 15:32:37 -04:00
Richie Caputo b5305810d7
Create py.typed
- Ensure library is properly typehinted
2025-03-21 11:16:24 -04:00
Kazuhiro Sera 98c4b45b6a Make the optional dependency installation compatible with zsh 2025-03-21 10:01:24 +09:00
Rohan Mehta 1771c1e856 update tests 2025-03-20 13:08:38 -04:00
Dominik Kundel c7ce154637 feat: add voice pipeline support
> Co-authored-by: rm@openai.com
2025-03-20 09:43:13 -07:00
xianghuijin fb77c74fa1 Fix potential infinite tool call loop by resetting tool_choice after tool execution 2025-03-20 21:22:27 +08:00
Raduan77 e9f6d08260 fix typos in src/ 2025-03-20 11:24:08 +01:00
Rohan Mehta 8c9974bc90 Fix breaking changes from openai 1.66.2 2025-03-19 12:30:45 -04:00
Rohan Mehta 10aa5555af Introduce tool_use_behavior on agents 2025-03-18 21:55:12 -04:00
Rohan Mehta 6f7e801da0
Update tests and docs for strict mode decorator (#205)
As titled. Test plan: unit tests/docs.
2025-03-18 21:35:00 -04:00
Martín Bravo f4edc1f372 style: improve string formatting in visualization functions 2025-03-18 10:15:41 +01:00
Martín Bravo b7627cb642 style: improve string formatting 2025-03-18 10:14:52 +01:00
Martín Bravo 0079bca717 style: improve code formatting and readability in visualization functions 2025-03-18 10:09:44 +01:00
Martín Bravo 53367be893 feat: add visualization module for agent graphs using Graphviz 2025-03-18 09:55:30 +01:00
Martín Bravo f7c594da08 feat: add visualization functions for agent graphs 2025-03-18 09:53:48 +01:00
Martín Bravo aff1d60ea1 Merge branch 'main' of https://github.com/openai/openai-agents-python into feat/draw_graph 2025-03-17 23:50:52 +01:00
Rohan Mehta d0a7b00086
Fix typo on Agent documentation (#151)
Argument name is not description but handoff_description
2025-03-17 16:51:47 -04:00
Carlos Souza 64150c8aea Fix lint 2025-03-17 16:14:28 -04:00
Rohan Mehta 0989cd9184
Add TracingProcessor export to __init__.py (#192)
# Summary
This adds the missing TracingProcessor export to  __init__.py.

# Behavior
When trying to add a custom tracing processor, the TracingProcessor
importing fails with not found error when trying the example usage
proposed in issue #164

Specifically this line throws the error:
`add_trace_processor(MyTracingProcessor("output"))`

# Expected Behavior
Inspecting the init file, simply the import/export was missing. Adding
these made the example code work for me

# Test plan
Local dev of example code in #164

# Issue number
#164

# Checks
None
2025-03-17 15:39:04 -04:00
Rohan Mehta 47aed7d362 Update tests and docs for strict mode decorator 2025-03-17 15:06:57 -04:00
Rohan Mehta 64e263b614 Pretty print result classes 2025-03-17 11:11:39 -04:00
Vincenzo Domina 1f58528f1c
Add TracingProcessor export to __init__.py 2025-03-17 10:37:43 +01:00
MartinEBravo e984274da1 Merge branch 'main' of https://github.com/openai/openai-agents-python into feat/draw_graph 2025-03-17 10:17:36 +01:00
Rohan Mehta 09d70c074d utils directory 2025-03-16 18:48:45 -04:00
Rohan Mehta 951193bd21
feat: Add strict_mode option to function_schema and function_tool (#60)
This PR introduces a `strict_mode: bool = True` option to
`@function_tool`, allowing optional parameters when set to False. This
change enables more flexibility while maintaining strict JSON schema
validation by default.

resolves #43 

## Changes:

- Added `strict_mode` parameter to `@function_tool` and passed it to
`function_schema` and `FunctionTool`.
- Updated `function_schema.py` to respect `strict_mode` and allow
optional parameters when set to False.
- Added unit tests to verify optional parameters work correctly,
including multiple optional params with different types.

## Tests:

- Verified function calls with missing optional parameters behave as
expected.
- Added async tests to validate behavior under different configurations.
2025-03-16 17:43:46 -04:00
Carlos Souza 26828e5e68
Fix typo on Agent documentation
Argument name is not description but handoff_description
2025-03-13 16:18:40 -04:00
Rohan Mehta 7f68a7da2a
Consolidate to one logger (#149)
Results in double logging if we dont. Closes #141.
2025-03-13 11:38:18 -07:00
Rohan Mehta 17f0a425ba Consolidate to one logger 2025-03-13 13:55:15 -04:00
Martín Bravo 29e9983ae8 Linting 2025-03-13 18:49:12 +01:00
Martín Bravo cecdcd0af4 Add visualization functions for agents using Graphviz 2025-03-13 18:33:12 +01:00