diff --git a/README.md b/README.md index 0eb1b047..f4a4a409 100644 --- a/README.md +++ b/README.md @@ -64,14 +64,17 @@ Initialize the AgentOps client and automatically get analytics on every LLM call import agentops # Beginning of program's code (i.e. main.py, __init__.py) -agentops.init() +agentops.init( < INSERT YOUR API KEY HERE >) ... + + # (optional: record specific functions) -@agentops.record_function('sample function being record') +@agentops.record_action('sample function being record') def sample_function(...): ... + # End of program agentops.end_session('Success') # Woohoo You're done 🎉 diff --git a/agentops/__init__.py b/agentops/__init__.py index 9397d6b3..19983548 100755 --- a/agentops/__init__.py +++ b/agentops/__init__.py @@ -4,7 +4,7 @@ from .client import Client from .event import Event, ActionEvent, LLMEvent, ToolEvent, ErrorEvent -from .decorators import record_function, track_agent, record_tool +from .decorators import record_action, track_agent, record_tool, record_function from .helpers import check_agentops_update from .log_config import logger from .session import Session diff --git a/agentops/decorators.py b/agentops/decorators.py index 68c54a26..3c74ce8d 100644 --- a/agentops/decorators.py +++ b/agentops/decorators.py @@ -11,6 +11,13 @@ def record_function(event_name: str): + logger.warning( + "DEPRECATION WARNING: record_function has been replaced with record_action and will be removed in the next minor version. Also see: record_tool" + ) + return record_action(event_name) + + +def record_action(event_name: str): """ Decorator to record an event before and after a function call. Usage: @@ -32,7 +39,7 @@ async def async_wrapper(*args, session: Optional[Session] = None, **kwargs): if session is None: if Client().is_multi_session: raise ValueError( - "If multiple sessions exists, `session` is a required parameter in the function decorated by @record_function" + "If multiple sessions exists, `session` is a required parameter in the function decorated by @record_action" ) func_args = inspect.signature(func).parameters arg_names = list(func_args.keys()) @@ -93,7 +100,7 @@ def sync_wrapper(*args, session: Optional[Session] = None, **kwargs): if session is None: if Client().is_multi_session: raise ValueError( - "If multiple sessions exists, `session` is a required parameter in the function decorated by @record_function" + "If multiple sessions exists, `session` is a required parameter in the function decorated by @record_action" ) func_args = inspect.signature(func).parameters arg_names = list(func_args.keys()) diff --git a/agentops/helpers.py b/agentops/helpers.py index 9e7e873a..e04f4b57 100644 --- a/agentops/helpers.py +++ b/agentops/helpers.py @@ -4,7 +4,8 @@ import json import inspect from typing import Union -import requests +import http.client +import json from importlib.metadata import version, PackageNotFoundError from .log_config import logger @@ -152,10 +153,15 @@ def get_agentops_version(): def check_agentops_update(): - response = requests.get("https://pypi.org/pypi/agentops/json") - - if response.status_code == 200: - latest_version = response.json()["info"]["version"] + # using http.client to avoid this call being caught by requests_mock on tests + conn = http.client.HTTPSConnection("pypi.org") + conn.request("GET", "/pypi/agentops/json") + response = conn.getresponse() + data = response.read().decode() + json_data = json.loads(data) + + if response.status == 200: + latest_version = json_data["info"]["version"] try: current_version = version("agentops") diff --git a/docs/v1/concepts/events.mdx b/docs/v1/concepts/events.mdx index 0400f4f5..a413fafa 100644 --- a/docs/v1/concepts/events.mdx +++ b/docs/v1/concepts/events.mdx @@ -26,14 +26,14 @@ The `ActionEvent` is a generic event for recording events that do not fit into t | logs | str | None | "Executed action successfully" | Logs generated during the action event | | screenshot | str | None | "/path/to/screenshot.png" | Path to screenshot captured during the action event | -An action event can be used the [same way as other events](/v1/usage/recording-events) but also with the `record_function` -decorator. +An action or tool event can be used the [same way as other events](/v1/usage/recording-events) but also with the `record_action` or `record_tool` +decorators. ```python python -from agentops import record_function +from agentops import record_action -@record_function() +@record_action() def some_action(params): return "some response" ``` diff --git a/docs/v1/examples/notebooks/openai-gpt.html b/docs/v1/examples/notebooks/openai-gpt.html index 51a79bdd..dc112599 100644 --- a/docs/v1/examples/notebooks/openai-gpt.html +++ b/docs/v1/examples/notebooks/openai-gpt.html @@ -307,10 +307,10 @@

Events

from agentops import record_function
+class="sourceCode python">from agentops import record_action
 
 
-@record_function("add numbers")
+@record_action("add numbers")
 def add(x, y):
     return x + y
 
diff --git a/docs/v1/quickstart.mdx b/docs/v1/quickstart.mdx
index 889b5dbd..9dc09f37 100644
--- a/docs/v1/quickstart.mdx
+++ b/docs/v1/quickstart.mdx
@@ -47,12 +47,12 @@ import EnvTooltip from '/snippets/add-env-tooltip.mdx'
 
 
 
-  You can instrument other functions inside your code with the handy `@record_function`
+  You can instrument other functions inside your code with the handy `@record_action`
   decorator, which will record an `action_type`, the parameters, and the returns. You
   will see these function calls alongside your LLM calls from instantiating the AgentOps client.
   ```python python
   # (record specific functions)
-  @agentops.record_function('sample function being record')
+  @agentops.record_action('sample function being record')
   def sample_function(...):
     ...
 ```
@@ -94,7 +94,7 @@ import agentops
 agentops.init()
 
 # (record specific functions)
-@agentops.record_function('sample function being record')
+@agentops.record_action('sample function being record')
 def sample_function(...):
   ...
 
diff --git a/docs/v1/usage/recording-events.mdx b/docs/v1/usage/recording-events.mdx
index 2eb17f49..f7fec071 100644
--- a/docs/v1/usage/recording-events.mdx
+++ b/docs/v1/usage/recording-events.mdx
@@ -6,23 +6,40 @@ description: "Log events such as agent actions, LLM calls, tool calls, and error
 To get the most out of AgentOps, it is best to carefully consider what events to record -
 not simply record whatever your agent is logging. AgentOps offers two ways to record events:
 
-## `@record_function` Decorator
+## `@record_action` Decorator
 
 - **`event_type`** (str): Type of the event.
 
-To make AgentOps easier to integrate, we also provide a function decorator to automatically creates
-and records an event for your function.
+To make AgentOps easier to integrate, we also provide a function decorator to automatically create
+and record an event for your function.
 
 ```python python
-from agentops import record_function
+from agentops import record_action
 
-@record_function('sample function being record')
+@record_action('sample function being record')
 def sample_function(...):
     ...
 ```
 
 The decorator will record the function's parameters, returns, and the time duration. We suggest using this on functions that take a long time and contain nested functions. For example, if you decorate a function that makes several openai calls, then each openai call will show in the replay graph as a child of the decorated function.
 
+## `@record_tool` Decorator
+
+- **`tool_name`** (str): The name of the tool represented by the python function
+
+Additionally, we provide a function decorator to automatically create tool events for python functions.
+
+```python python
+from agentops import record_tool
+
+@record_tool('SampleToolName')
+def sample_tool(...):
+    ...
+```
+
+The decorator will record the function's parameters, returns, and the time duration. We suggest using this on functions that take a long time and contain nested functions. For example, if you decorate a function that makes several openai calls, then each openai call will show in the replay graph as a child of the decorated function.
+
+
 ## `record()` Method
 
 From this point, simply call the .record() method in the AgentOps client:
diff --git a/examples/openai-gpt.ipynb b/examples/openai-gpt.ipynb
index 7898b5fe..6b9bfd1d 100644
--- a/examples/openai-gpt.ipynb
+++ b/examples/openai-gpt.ipynb
@@ -70,7 +70,8 @@
    "metadata": {
     "collapsed": false
    },
-   "id": "5d424a02e30ce7f4"
+   "id": "5d424a02e30ce7f4",
+   "execution_count": null
   },
   {
    "cell_type": "markdown",
@@ -104,7 +105,8 @@
    "metadata": {
     "collapsed": false
    },
-   "id": "2704d6d625efa77f"
+   "id": "2704d6d625efa77f",
+   "execution_count": null
   },
   {
    "cell_type": "markdown",
@@ -125,7 +127,8 @@
    "metadata": {
     "collapsed": false
    },
-   "id": "537abd77cd0e0d25"
+   "id": "537abd77cd0e0d25",
+   "execution_count": null
   },
   {
    "cell_type": "markdown",
@@ -159,7 +162,8 @@
    "metadata": {
     "collapsed": false
    },
-   "id": "544c8f1bdb8c6e4b"
+   "id": "544c8f1bdb8c6e4b",
+   "execution_count": null
   },
   {
    "cell_type": "markdown",
@@ -178,10 +182,10 @@
    },
    "outputs": [],
    "source": [
-    "from agentops import record_function\n",
+    "from agentops import record_action\n",
     "\n",
     "\n",
-    "@record_function(\"add numbers\")\n",
+    "@record_action(\"add numbers\")\n",
     "def add(x, y):\n",
     "    return x + y\n",
     "\n",
diff --git a/examples/recording-events.ipynb b/examples/recording-events.ipynb
index 018b6344..b766a716 100644
--- a/examples/recording-events.ipynb
+++ b/examples/recording-events.ipynb
@@ -66,10 +66,10 @@
    },
    "outputs": [],
    "source": [
-    "from agentops import record_function\n",
+    "from agentops import record_action\n",
     "\n",
     "\n",
-    "@record_function(\"add numbers\")\n",
+    "@record_action(\"add numbers\")\n",
     "def add(x, y):\n",
     "    return x + y\n",
     "\n",
diff --git a/tests/openai_handlers/_test_llm_tracker_ge_1_async.py b/tests/openai_handlers/_test_llm_tracker_ge_1_async.py
index 7a7099b9..aba2a024 100644
--- a/tests/openai_handlers/_test_llm_tracker_ge_1_async.py
+++ b/tests/openai_handlers/_test_llm_tracker_ge_1_async.py
@@ -1,7 +1,7 @@
 from openai import AsyncOpenAI
 import asyncio
 import agentops
-from agentops import record_function
+from agentops import record_action
 from dotenv import load_dotenv
 
 load_dotenv()
@@ -9,7 +9,7 @@
 agentops.init()
 
 
-@record_function("openai v1 async no streaming")
+@record_action("openai v1 async no streaming")
 async def call_openai_v1_async_no_streaming():
     client = AsyncOpenAI()
 
@@ -25,7 +25,7 @@ async def call_openai_v1_async_no_streaming():
     # raise ValueError("This is an intentional error for testing.")
 
 
-@record_function("openai v1 async with streaming")
+@record_action("openai v1 async with streaming")
 async def call_openai_v1_async_streaming():
     client = AsyncOpenAI()  # Using the async client
 
diff --git a/tests/openai_handlers/_test_llm_tracker_ge_1_sync.py b/tests/openai_handlers/_test_llm_tracker_ge_1_sync.py
index 90a9fab1..56053b26 100644
--- a/tests/openai_handlers/_test_llm_tracker_ge_1_sync.py
+++ b/tests/openai_handlers/_test_llm_tracker_ge_1_sync.py
@@ -1,6 +1,6 @@
 from openai import OpenAI
 import agentops
-from agentops import record_function
+from agentops import record_action
 from packaging.version import parse
 from importlib import import_module
 import sys
@@ -19,7 +19,7 @@
             print("openai version: ", module_version)
 
 
-@record_function("openai v1 sync no streaming")
+@record_action("openai v1 sync no streaming")
 def call_openai_v1_sync_no_streaming():
     client = OpenAI()
     chat_completion = client.chat.completions.create(
@@ -34,7 +34,7 @@ def call_openai_v1_sync_no_streaming():
     # raise ValueError("This is an intentional error for testing.")
 
 
-@record_function("openai v1 sync with streaming")
+@record_action("openai v1 sync with streaming")
 def call_openai_v1_sync_streaming():
     client = OpenAI()
     chat_completion = client.chat.completions.create(
diff --git a/tests/openai_handlers/_test_llm_tracker_lt_1_sync.py b/tests/openai_handlers/_test_llm_tracker_lt_1_sync.py
index 808ee43f..9c280b92 100644
--- a/tests/openai_handlers/_test_llm_tracker_lt_1_sync.py
+++ b/tests/openai_handlers/_test_llm_tracker_lt_1_sync.py
@@ -1,6 +1,6 @@
 from openai import ChatCompletion
 import agentops
-from agentops import record_function
+from agentops import record_action
 from packaging.version import parse
 from importlib import import_module
 import sys
@@ -19,7 +19,7 @@
             print("openai version: ", module_version)
 
 
-@record_function("openai v0 sync no streaming")
+@record_action("openai v0 sync no streaming")
 def call_openai_v0_sync_no_streaming():
     chat_completion = ChatCompletion.create(
         model="gpt-3.5-turbo",
@@ -33,7 +33,7 @@ def call_openai_v0_sync_no_streaming():
     # raise ValueError("This is an intentional error for testing.")
 
 
-@record_function("openai v0 sync with streaming")
+@record_action("openai v0 sync with streaming")
 def call_openai_v0_sync_with_streaming():
     chat_completion = ChatCompletion.create(
         model="gpt-3.5-turbo",
diff --git a/tests/test_record_function.py b/tests/test_record_action.py
similarity index 93%
rename from tests/test_record_function.py
rename to tests/test_record_action.py
index 2fc8cd29..d3258583 100644
--- a/tests/test_record_function.py
+++ b/tests/test_record_action.py
@@ -2,7 +2,7 @@
 import requests_mock
 import time
 import agentops
-from agentops import record_function
+from agentops import record_action
 from datetime import datetime
 from agentops.helpers import clear_singletons
 import contextlib
@@ -46,10 +46,10 @@ def setup_method(self):
         self.event_type = "test_event_type"
         agentops.init(self.api_key, max_wait_time=5, auto_start_session=False)
 
-    def test_record_function_decorator(self, mock_req):
+    def test_record_action_decorator(self, mock_req):
         agentops.start_session()
 
-        @record_function(event_name=self.event_type)
+        @record_action(event_name=self.event_type)
         def add_two(x, y):
             return x + y
 
@@ -67,11 +67,11 @@ def add_two(x, y):
 
         agentops.end_session(end_state="Success")
 
-    def test_record_function_decorator_multiple(self, mock_req):
+    def test_record_action_decorator_multiple(self, mock_req):
         agentops.start_session()
 
         # Arrange
-        @record_function(event_name=self.event_type)
+        @record_action(event_name=self.event_type)
         def add_three(x, y, z=3):
             return x + y + z
 
@@ -92,10 +92,10 @@ def add_three(x, y, z=3):
         agentops.end_session(end_state="Success")
 
     @pytest.mark.asyncio
-    async def test_async_function_call(self, mock_req):
+    async def test_async_action_call(self, mock_req):
         agentops.start_session()
 
-        @record_function(self.event_type)
+        @record_action(self.event_type)
         async def async_add(x, y):
             time.sleep(0.1)
             return x + y
@@ -128,7 +128,7 @@ def test_multiple_sessions_sync(self, mock_req):
         assert session_2 is not None
 
         # Arrange
-        @record_function(event_name=self.event_type)
+        @record_action(event_name=self.event_type)
         def add_three(x, y, z=3):
             return x + y + z
 
@@ -174,7 +174,7 @@ async def test_multiple_sessions_async(self, mock_req):
         assert session_2 is not None
 
         # Arrange
-        @record_function(self.event_type)
+        @record_action(self.event_type)
         async def async_add(x, y):
             time.sleep(0.1)
             return x + y
@@ -217,7 +217,7 @@ def test_require_session_if_multiple(self):
         session_2 = agentops.start_session()
 
         # Arrange
-        @record_function(self.event_type)
+        @record_action(self.event_type)
         def add_two(x, y):
             time.sleep(0.1)
             return x + y
diff --git a/tests/test_record_tool.py b/tests/test_record_tool.py
index d6f8fe4e..c9f44471 100644
--- a/tests/test_record_tool.py
+++ b/tests/test_record_tool.py
@@ -2,7 +2,7 @@
 import requests_mock
 import time
 import agentops
-from agentops.decorators import record_tool
+from agentops import record_tool
 from datetime import datetime
 
 from agentops.helpers import clear_singletons