Skip to content

Commit

Permalink
Fix crash endtimestamp (#189)
Browse files Browse the repository at this point in the history
* Setting session to none if server does not return 200 for /sessions

* Fixed crash on end_timestamp does not exist

* notebook update

* bump version number

* end_timestamp optional

* Making code more explicit

---------

Co-authored-by: Shawn Qiu <[email protected]>
  • Loading branch information
HowieG and siyangqiu authored May 7, 2024
1 parent c8c4d74 commit 6059741
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 88 deletions.
37 changes: 22 additions & 15 deletions agentops/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ def __init__(self,
self._worker: Optional[Worker] = None
self._tags: Optional[List[str]] = tags

self._env_data_opt_out = os.getenv('AGENTOPS_ENV_DATA_OPT_OUT') and os.getenv('AGENTOPS_ENV_DATA_OPT_OUT').lower() == 'true'
self._env_data_opt_out = os.getenv('AGENTOPS_ENV_DATA_OPT_OUT') and os.getenv(
'AGENTOPS_ENV_DATA_OPT_OUT').lower() == 'true'

try:
self.config = Configuration(api_key=api_key,
Expand Down Expand Up @@ -136,19 +137,24 @@ def record(self, event: Union[Event, ErrorEvent]):
Args:
event (Event): The event to record.
"""
if isinstance(event, Event) and not event.end_timestamp or event.init_timestamp == event.end_timestamp:
event.end_timestamp = get_ISO_time()
if self._session is not None and not self._session.has_ended and self._worker is not None:
if isinstance(event, ErrorEvent):
if event.trigger_event:
event.trigger_event_id = event.trigger_event.id
event.trigger_event_type = event.trigger_event.event_type
self._worker.add_event(event.trigger_event.__dict__)
event.trigger_event = None # removes trigger_event from serialization
self._worker.add_event(event.__dict__)
else:
logger.warning(
"🖇 AgentOps: Cannot record event - no current session")
if self._session is None or self._session.has_ended:
logger.warning("🖇 AgentOps: Cannot record event - no current session")
return

if isinstance(event, Event):
if not event.end_timestamp or event.init_timestamp == event.end_timestamp:
event.end_timestamp = get_ISO_time()
elif isinstance(event, ErrorEvent):
if event.trigger_event:
if not event.trigger_event.end_timestamp or event.trigger_event.init_timestamp == event.trigger_event.end_timestamp:
event.trigger_event.end_timestamp = get_ISO_time()

event.trigger_event_id = event.trigger_event.id
event.trigger_event_type = event.trigger_event.event_type
self._worker.add_event(event.trigger_event.__dict__)
event.trigger_event = None # removes trigger_event from serialization

self._worker.add_event(event.__dict__)

def _record_event_sync(self, func, event_name, *args, **kwargs):
init_time = get_ISO_time()
Expand Down Expand Up @@ -240,7 +246,8 @@ def start_session(self, tags: Optional[List[str]] = None, config: Optional[Confi
if not config and not self.config:
return logger.warning("🖇 AgentOps: Cannot start session - missing configuration")

self._session = Session(inherited_session_id or uuid4(), tags or self._tags_for_future_session, host_env=get_host_env(self._env_data_opt_out))
self._session = Session(inherited_session_id or uuid4(),
tags or self._tags_for_future_session, host_env=get_host_env(self._env_data_opt_out))
self._worker = Worker(config or self.config)
start_session_result = self._worker.start_session(self._session)
if not start_session_result:
Expand Down
9 changes: 4 additions & 5 deletions agentops/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,12 @@ class Event:
"""

event_type: str # EventType.ENUM.value
params: Optional[Union[str, Dict[str, Any]]] = None
returns: Optional[Union[str, Dict[str, Any]]] = None
init_timestamp: Optional[str] = field(default_factory=get_ISO_time)
end_timestamp: str = field(default_factory=get_ISO_time)
params: Optional[dict] = None
returns: Optional[str] = None
init_timestamp: str = field(default_factory=get_ISO_time)
end_timestamp: Optional[str] = None
agent_id: Optional[UUID] = field(default_factory=check_call_stack_for_agent_id)
id: UUID = field(default_factory=uuid4)
# TODO: has_been_recorded: bool = False


@dataclass
Expand Down
143 changes: 75 additions & 68 deletions examples/recording-events.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,50 @@
"cells": [
{
"cell_type": "markdown",
"source": [
"# Recording Events\n",
"AgentOps has a number of different [Event Types](https://docs.agentops.ai/v1/details/events)"
],
"id": "dc8cfd2cfa8a594b",
"metadata": {
"collapsed": false
},
"id": "dc8cfd2cfa8a594b"
"source": [
"# Recording Events\n",
"AgentOps has a number of different [Event Types](https://docs.agentops.ai/v1/details/events)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "168ecd05cc123de0",
"metadata": {
"collapsed": false,
"is_executing": true
},
"outputs": [],
"source": [
"import agentops\n",
"# Create new session\n",
"agentops.start_session()\n",
"agentops.init()\n",
"\n",
"# Optionally, we can add tags to the session\n",
"# agentops.start_session(['Hello Tracker'])"
],
"metadata": {
"collapsed": false,
"is_executing": true
},
"id": "168ecd05cc123de0",
"execution_count": null
"# agentops.init(tags=['Hello Tracker'])"
]
},
{
"cell_type": "markdown",
"source": [
"The easiest way to record actions is through the use of AgentOp's decorators"
],
"id": "c6d06ee8c66dad17",
"metadata": {
"collapsed": false
},
"id": "c6d06ee8c66dad17"
"source": [
"The easiest way to record actions is through the use of AgentOp's decorators"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b460318317adc624",
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from agentops import record_function\n",
Expand All @@ -49,25 +55,25 @@
" return x + y\n",
"\n",
"add(2,4)"
],
"metadata": {
"collapsed": false
},
"id": "b460318317adc624",
"execution_count": 0
]
},
{
"cell_type": "markdown",
"source": [
"We can also manually craft an event exactly the way we want"
],
"id": "9068a4cdd328f652",
"metadata": {
"collapsed": false
},
"id": "9068a4cdd328f652"
"source": [
"We can also manually craft an event exactly the way we want"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b62ad88921ff26f2",
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from agentops import ActionEvent\n",
Expand All @@ -78,38 +84,38 @@
"\n",
"if \"hello\" in str(response.choices[0].message.content).lower():\n",
" agentops.record(ActionEvent(action_type=\"Agent says hello\", params=str(message), returns=str(response.choices[0].message.content) ))"
],
"metadata": {
"collapsed": false
},
"id": "b62ad88921ff26f2",
"execution_count": 0
]
},
{
"cell_type": "code",
"outputs": [],
"source": [
"agentops.end_session('Success')"
],
"execution_count": null,
"id": "e10a89e06fe6b2be",
"metadata": {
"collapsed": false
},
"id": "e10a89e06fe6b2be",
"execution_count": null
"outputs": [],
"source": [
"agentops.end_session('Success')"
]
},
{
"cell_type": "markdown",
"source": [
"## Tool Event\n",
"Agents use tools. These tools are useful to track with information such as name, end status, runtime, etc. To record tool usage, you can create and record a `ToolEvent` similar to above."
],
"id": "f7c947d815f581e7",
"metadata": {
"collapsed": false
},
"id": "f7c947d815f581e7"
"source": [
"## Tool Event\n",
"Agents use tools. These tools are useful to track with information such as name, end status, runtime, etc. To record tool usage, you can create and record a `ToolEvent` similar to above."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5d387a071a1c70cf",
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from agentops import ToolEvent, record\n",
Expand All @@ -118,41 +124,42 @@
" result = integration.scrape_website(data) # perform tool logic\n",
" tool_event.returns = result\n",
" record(tool_event)"
],
"metadata": {
"collapsed": false
},
"id": "5d387a071a1c70cf"
]
},
{
"cell_type": "markdown",
"source": [
"## Error Events\n",
"Error events can be used alone or in reference to another event. Lets add a catch block to the code above"
],
"id": "968d1503dd0aae9a",
"metadata": {
"collapsed": false
},
"id": "968d1503dd0aae9a"
"source": [
"## Error Events\n",
"Error events can be used alone or in reference to another event. Lets add a catch block to the code above"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "eb23c1325298e22f",
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from agentops import ToolEvent, record, ErrorEvent\n",
"\n",
"def scrape_website(url: str):\n",
" tool_event = ToolEvent(name='scrape_website', params={'url':url}) # the start timestamp is set when the obj is created\n",
"\n",
" try:\n",
" result = integration.scrape_website(data) # perform tool logic\n",
" tool_event.returns = result\n",
" except Error as e:\n",
" record(ErrorEvent(message=e, trigger_event=tool_event))\n",
" record(tool_event)"
],
"metadata": {
"collapsed": false
},
"id": "eb23c1325298e22f"
" 1 / 0 # Ooops! Something went wrong\n",
" except Exception as e:\n",
" record(ErrorEvent(exception=e, trigger_event=tool_event))\n",
"\n",
"scrape_website('https://app.agentops.ai') \n",
"\n",
"agentops.end_session('Success')"
]
}
],
"metadata": {
Expand All @@ -164,14 +171,14 @@
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.6"
"pygments_lexer": "ipython3",
"version": "3.12.3"
}
},
"nbformat": 4,
Expand Down

0 comments on commit 6059741

Please sign in to comment.