hyperpocket-anthropic 0.1.3__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,194 @@
1
+ Metadata-Version: 2.1
2
+ Name: hyperpocket-anthropic
3
+ Version: 0.1.3
4
+ Summary:
5
+ Author: moon
6
+ Author-email: moon@vessl.ai
7
+ Requires-Python: >=3.11,<4.0
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.11
10
+ Classifier: Programming Language :: Python :: 3.12
11
+ Classifier: Programming Language :: Python :: 3.13
12
+ Requires-Dist: anthropic (>=0.40.0,<0.41.0)
13
+ Requires-Dist: hyperpocket (>=0.0.1,<0.0.2)
14
+ Description-Content-Type: text/markdown
15
+
16
+ ## Anthropic extensions
17
+
18
+ ### Get Pocket Anthropic Tool Spec
19
+
20
+ ```python
21
+ import hyperpocket as pk
22
+ from pocket_anthropic import PocketAnthropic
23
+
24
+ pocket = PocketAnthropic(tools=[
25
+ *pk.curated_tools.SLACK, # SLACK = [slack_get_message, slack_post_message, ..]
26
+ *pk.curated_tools.LINEAR,
27
+ "https://github.com/my-org/some-awesome-tool"]
28
+ )
29
+
30
+ # get anthropic compatible tool specs from pocket
31
+ tool_specs = pocket.get_anthropic_tool_specs()
32
+ ```
33
+
34
+
35
+ ### Tool Injection
36
+
37
+ ```python
38
+ import os
39
+
40
+ from anthropic import Anthropic
41
+
42
+ messages = [
43
+ {
44
+ "role": "user",
45
+ "content": "get slack message",
46
+ }
47
+ ]
48
+
49
+ llm = Anthropic()
50
+ response = llm.messages.create(
51
+ model=os.getenv("ANTHROPIC_MODEL_NAME"),
52
+ max_tokens=500,
53
+ messages=messages,
54
+ tools=tool_specs, # pass the tool specs as an tools argument
55
+ )
56
+ ```
57
+
58
+
59
+ ### Tool Call
60
+
61
+ ```python
62
+ response = llm.messages.create(
63
+ model=os.getenv("ANTHROPIC_MODEL_NAME"),
64
+ max_tokens=500,
65
+ messages=messages,
66
+ tools=tool_specs, # pass the tool specs as an tools argument
67
+ )
68
+
69
+ tool_result_blocks = []
70
+ for block in response.content:
71
+ if block.type == "tool_use":
72
+ tool_result_block = pocket.invoke(block)
73
+ tool_result_blocks.append(tool_result_block)
74
+
75
+ messages.append({"role": "user", "content": tool_result_blocks})
76
+
77
+ response_after_tool_call = llm.messages.create(
78
+ model=os.getenv("ANTHROPIC_MODEL_NAME"),
79
+ max_tokens=500,
80
+ messages=messages,
81
+ tools=tool_specs, # pass the tool specs as an tools argument
82
+ )
83
+
84
+ # ...
85
+ ```
86
+
87
+ ### Full Code
88
+
89
+ ```python
90
+ import os
91
+
92
+ from anthropic import Anthropic
93
+
94
+ import hyperpocket as pk
95
+ from pocket_anthropic import PocketAnthropic
96
+
97
+ pocket = PocketAnthropic(tools=[
98
+ *pk.curated_tools.SLACK, # SLACK = [slack_get_message, slack_post_message, ..]
99
+ *pk.curated_tools.LINEAR,
100
+ "https://github.com/my-org/some-awesome-tool"]
101
+ )
102
+
103
+ # get anthropic compatible tool specs from pocket
104
+ tool_specs = pocket.get_anthropic_tool_specs()
105
+ messages = [
106
+ {
107
+ "role": "user",
108
+ "content": "get slack message",
109
+ }
110
+ ]
111
+
112
+ llm = Anthropic()
113
+ response = llm.messages.create(
114
+ model=os.getenv("ANTHROPIC_MODEL_NAME"),
115
+ max_tokens=500,
116
+ messages=messages,
117
+ tools=tool_specs, # pass the tool specs as an tools argument
118
+ )
119
+
120
+ tool_result_blocks = []
121
+ for block in response.content:
122
+ if block.type == "tool_use":
123
+ tool_result_block = pocket.invoke(block) # tool call by pocket
124
+ tool_result_blocks.append(tool_result_block)
125
+
126
+ messages.append({"role": "user", "content": tool_result_blocks})
127
+
128
+ response_after_tool_call = llm.messages.create(
129
+ model=os.getenv("ANTHROPIC_MODEL_NAME"),
130
+ max_tokens=500,
131
+ messages=messages,
132
+ tools=tool_specs, # pass the tool specs as an tools argument
133
+ )
134
+
135
+ ```
136
+
137
+
138
+ ### Examples
139
+
140
+ ```python
141
+ import os
142
+
143
+ from anthropic import Anthropic
144
+
145
+ import hyperpocket as pk
146
+ from pocket_anthropic import PocketAnthropic
147
+
148
+ client = Anthropic()
149
+ pocket = PocketAnthropic(
150
+ tools=[
151
+ *pk.curated_tools.SLACK, # SLACK = [slack_get_message, slack_post_message, ..]
152
+ *pk.curated_tools.LINEAR,
153
+ "https://github.com/my-org/some-awesome-tool"]
154
+ )
155
+
156
+ tool_specs = pocket.get_anthropic_tool_specs()
157
+
158
+ messages = []
159
+ while True:
160
+ print("user(q to quit) : ", end="")
161
+ user_input = input()
162
+ if user_input == "q":
163
+ break
164
+ if user_input == "":
165
+ continue
166
+
167
+ messages.append({"role": "user", "content": user_input})
168
+
169
+ while True:
170
+ response = client.messages.create(
171
+ model=os.getenv("ANTHROPIC_MODEL_NAME"),
172
+ max_tokens=500,
173
+ messages=messages,
174
+ tools=tool_specs,
175
+ )
176
+
177
+ messages.append({"role": "assistant", "content": response.content})
178
+
179
+ tool_result_blocks = []
180
+ for block in response.content:
181
+ if block.type == "text":
182
+ print("[ai] response : ", block.text)
183
+
184
+ elif block.type == "tool_use":
185
+ tool_result_block = pocket.invoke(block)
186
+ tool_result_blocks.append(tool_result_block)
187
+
188
+ print("[tool] response : ", tool_result_block["content"])
189
+
190
+ messages.append({"role": "user", "content": tool_result_blocks})
191
+
192
+ if response.stop_reason != "tool_use":
193
+ break
194
+ ```
@@ -0,0 +1,179 @@
1
+ ## Anthropic extensions
2
+
3
+ ### Get Pocket Anthropic Tool Spec
4
+
5
+ ```python
6
+ import hyperpocket as pk
7
+ from pocket_anthropic import PocketAnthropic
8
+
9
+ pocket = PocketAnthropic(tools=[
10
+ *pk.curated_tools.SLACK, # SLACK = [slack_get_message, slack_post_message, ..]
11
+ *pk.curated_tools.LINEAR,
12
+ "https://github.com/my-org/some-awesome-tool"]
13
+ )
14
+
15
+ # get anthropic compatible tool specs from pocket
16
+ tool_specs = pocket.get_anthropic_tool_specs()
17
+ ```
18
+
19
+
20
+ ### Tool Injection
21
+
22
+ ```python
23
+ import os
24
+
25
+ from anthropic import Anthropic
26
+
27
+ messages = [
28
+ {
29
+ "role": "user",
30
+ "content": "get slack message",
31
+ }
32
+ ]
33
+
34
+ llm = Anthropic()
35
+ response = llm.messages.create(
36
+ model=os.getenv("ANTHROPIC_MODEL_NAME"),
37
+ max_tokens=500,
38
+ messages=messages,
39
+ tools=tool_specs, # pass the tool specs as an tools argument
40
+ )
41
+ ```
42
+
43
+
44
+ ### Tool Call
45
+
46
+ ```python
47
+ response = llm.messages.create(
48
+ model=os.getenv("ANTHROPIC_MODEL_NAME"),
49
+ max_tokens=500,
50
+ messages=messages,
51
+ tools=tool_specs, # pass the tool specs as an tools argument
52
+ )
53
+
54
+ tool_result_blocks = []
55
+ for block in response.content:
56
+ if block.type == "tool_use":
57
+ tool_result_block = pocket.invoke(block)
58
+ tool_result_blocks.append(tool_result_block)
59
+
60
+ messages.append({"role": "user", "content": tool_result_blocks})
61
+
62
+ response_after_tool_call = llm.messages.create(
63
+ model=os.getenv("ANTHROPIC_MODEL_NAME"),
64
+ max_tokens=500,
65
+ messages=messages,
66
+ tools=tool_specs, # pass the tool specs as an tools argument
67
+ )
68
+
69
+ # ...
70
+ ```
71
+
72
+ ### Full Code
73
+
74
+ ```python
75
+ import os
76
+
77
+ from anthropic import Anthropic
78
+
79
+ import hyperpocket as pk
80
+ from pocket_anthropic import PocketAnthropic
81
+
82
+ pocket = PocketAnthropic(tools=[
83
+ *pk.curated_tools.SLACK, # SLACK = [slack_get_message, slack_post_message, ..]
84
+ *pk.curated_tools.LINEAR,
85
+ "https://github.com/my-org/some-awesome-tool"]
86
+ )
87
+
88
+ # get anthropic compatible tool specs from pocket
89
+ tool_specs = pocket.get_anthropic_tool_specs()
90
+ messages = [
91
+ {
92
+ "role": "user",
93
+ "content": "get slack message",
94
+ }
95
+ ]
96
+
97
+ llm = Anthropic()
98
+ response = llm.messages.create(
99
+ model=os.getenv("ANTHROPIC_MODEL_NAME"),
100
+ max_tokens=500,
101
+ messages=messages,
102
+ tools=tool_specs, # pass the tool specs as an tools argument
103
+ )
104
+
105
+ tool_result_blocks = []
106
+ for block in response.content:
107
+ if block.type == "tool_use":
108
+ tool_result_block = pocket.invoke(block) # tool call by pocket
109
+ tool_result_blocks.append(tool_result_block)
110
+
111
+ messages.append({"role": "user", "content": tool_result_blocks})
112
+
113
+ response_after_tool_call = llm.messages.create(
114
+ model=os.getenv("ANTHROPIC_MODEL_NAME"),
115
+ max_tokens=500,
116
+ messages=messages,
117
+ tools=tool_specs, # pass the tool specs as an tools argument
118
+ )
119
+
120
+ ```
121
+
122
+
123
+ ### Examples
124
+
125
+ ```python
126
+ import os
127
+
128
+ from anthropic import Anthropic
129
+
130
+ import hyperpocket as pk
131
+ from pocket_anthropic import PocketAnthropic
132
+
133
+ client = Anthropic()
134
+ pocket = PocketAnthropic(
135
+ tools=[
136
+ *pk.curated_tools.SLACK, # SLACK = [slack_get_message, slack_post_message, ..]
137
+ *pk.curated_tools.LINEAR,
138
+ "https://github.com/my-org/some-awesome-tool"]
139
+ )
140
+
141
+ tool_specs = pocket.get_anthropic_tool_specs()
142
+
143
+ messages = []
144
+ while True:
145
+ print("user(q to quit) : ", end="")
146
+ user_input = input()
147
+ if user_input == "q":
148
+ break
149
+ if user_input == "":
150
+ continue
151
+
152
+ messages.append({"role": "user", "content": user_input})
153
+
154
+ while True:
155
+ response = client.messages.create(
156
+ model=os.getenv("ANTHROPIC_MODEL_NAME"),
157
+ max_tokens=500,
158
+ messages=messages,
159
+ tools=tool_specs,
160
+ )
161
+
162
+ messages.append({"role": "assistant", "content": response.content})
163
+
164
+ tool_result_blocks = []
165
+ for block in response.content:
166
+ if block.type == "text":
167
+ print("[ai] response : ", block.text)
168
+
169
+ elif block.type == "tool_use":
170
+ tool_result_block = pocket.invoke(block)
171
+ tool_result_blocks.append(tool_result_block)
172
+
173
+ print("[tool] response : ", tool_result_block["content"])
174
+
175
+ messages.append({"role": "user", "content": tool_result_blocks})
176
+
177
+ if response.stop_reason != "tool_use":
178
+ break
179
+ ```
@@ -0,0 +1,3 @@
1
+ from hyperpocket_anthropic.pocket_anthropic import PocketAnthropic
2
+
3
+ __all__ = ["PocketAnthropic"]
@@ -0,0 +1,77 @@
1
+ import json
2
+ from typing import List
3
+
4
+ try:
5
+ from anthropic.types import ToolResultBlockParam, ToolUseBlock
6
+ except ImportError:
7
+ raise ImportError("You need to install anthropic to use pocket anthropic.")
8
+
9
+ from hyperpocket import Pocket
10
+ from hyperpocket.tool import Tool
11
+
12
+ from hyperpocket_anthropic.util import tool_to_anthropic_spec
13
+
14
+
15
+ class PocketAnthropic(Pocket):
16
+ def invoke(self, tool_use_block: ToolUseBlock, **kwargs) -> ToolResultBlockParam:
17
+ body = self.parse_input(tool_use_block)
18
+ result, interrupted = self.invoke_with_state(
19
+ tool_use_block.name, body=body, **kwargs
20
+ )
21
+ say = result
22
+ if interrupted:
23
+ say = (
24
+ f"{say}\n\nThe tool execution interrupted. Please talk to me to resume."
25
+ )
26
+
27
+ tool_result_block = ToolResultBlockParam(
28
+ tool_use_id=tool_use_block.id, type="tool_result", content=say
29
+ )
30
+
31
+ return tool_result_block
32
+
33
+ async def ainvoke(
34
+ self, tool_use_block: ToolUseBlock, **kwargs
35
+ ) -> ToolResultBlockParam:
36
+ body = self.parse_input(tool_use_block)
37
+ result, interrupted = await self.ainvoke_with_state(
38
+ tool_use_block.name, body=body, **kwargs
39
+ )
40
+ say = result
41
+
42
+ if interrupted:
43
+ say = (
44
+ f"{say}\n\nThe tool execution interrupted. Please talk to me to resume."
45
+ )
46
+
47
+ tool_result_block = ToolResultBlockParam(
48
+ tool_use_id=tool_use_block.id, type="tool_result", content=say
49
+ )
50
+
51
+ return tool_result_block
52
+
53
+ @staticmethod
54
+ def parse_input(tool_use_block):
55
+ if isinstance(tool_use_block.input, str):
56
+ arg = json.loads(tool_use_block.input)
57
+ body = arg["body"]
58
+ else:
59
+ arg = tool_use_block.input
60
+ body = arg["body"]
61
+
62
+ if isinstance(body, str):
63
+ body = json.loads(body)
64
+
65
+ return body
66
+
67
+ def get_anthropic_tool_specs(self) -> List[dict]:
68
+ specs = []
69
+ for tool in self.tools.values():
70
+ spec = self.get_anthropic_tool_spec(tool)
71
+ specs.append(spec)
72
+ return specs
73
+
74
+ @staticmethod
75
+ def get_anthropic_tool_spec(tool: Tool) -> dict:
76
+ spec = tool_to_anthropic_spec(tool)
77
+ return spec
@@ -0,0 +1,3 @@
1
+ from hyperpocket_anthropic.util.tool_to_anthropic_spec import tool_to_anthropic_spec
2
+
3
+ __all__ = ["tool_to_anthropic_spec"]
@@ -0,0 +1,22 @@
1
+ from hyperpocket.tool import Tool
2
+ from hyperpocket.util.flatten_json_schema import flatten_json_schema
3
+
4
+
5
+ def tool_to_anthropic_spec(tool: Tool) -> dict:
6
+ name = tool.name
7
+ description = tool.description
8
+ arg_schema = tool.schema_model()
9
+ json_schema = flatten_json_schema(arg_schema.model_json_schema())
10
+
11
+ anthropic_spec = {
12
+ "name": name,
13
+ "description": description.strip(),
14
+ "input_schema": {
15
+ "type": json_schema["type"],
16
+ "properties": json_schema["properties"],
17
+ "required": json_schema.get("required", []),
18
+ "title": json_schema.get("title", ""),
19
+ },
20
+ }
21
+
22
+ return anthropic_spec
@@ -0,0 +1,16 @@
1
+ [tool.poetry]
2
+ name = "hyperpocket-anthropic"
3
+ version = "0.1.3"
4
+ description = ""
5
+ authors = ["moon <moon@vessl.ai>"]
6
+ readme = "README.md"
7
+
8
+ [tool.poetry.dependencies]
9
+ python = "^3.11"
10
+ anthropic = "^0.40.0"
11
+ hyperpocket = "^0.0.1"
12
+
13
+
14
+ [build-system]
15
+ requires = ["poetry-core"]
16
+ build-backend = "poetry.core.masonry.api"