agentstr 0.0.9__py3-none-any.whl → 0.0.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agentstr/marketplace.py +163 -0
- agentstr/nostr.py +141 -0
- {agentstr-0.0.9.dist-info → agentstr-0.0.10.dist-info}/METADATA +44 -26
- agentstr-0.0.10.dist-info/RECORD +8 -0
- agentstr/core.py +0 -42
- agentstr-0.0.9.dist-info/RECORD +0 -7
- {agentstr-0.0.9.dist-info → agentstr-0.0.10.dist-info}/LICENSE +0 -0
- {agentstr-0.0.9.dist-info → agentstr-0.0.10.dist-info}/WHEEL +0 -0
- {agentstr-0.0.9.dist-info → agentstr-0.0.10.dist-info}/top_level.txt +0 -0
agentstr/marketplace.py
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
import logging
|
2
|
+
from typing import Optional
|
3
|
+
from . import nostr
|
4
|
+
|
5
|
+
try:
|
6
|
+
from phi.tools import Toolkit
|
7
|
+
except ImportError:
|
8
|
+
raise ImportError("`phidata` not installed. Please install using `pip install phidata`")
|
9
|
+
|
10
|
+
try:
|
11
|
+
import asyncio
|
12
|
+
except ImportError:
|
13
|
+
raise ImportError("`asyncio` not installed. Please install using `pip install asyncio`")
|
14
|
+
|
15
|
+
class MerchantProfile():
|
16
|
+
|
17
|
+
logger = logging.getLogger("MerchantProfile")
|
18
|
+
|
19
|
+
def __init__(
|
20
|
+
self,
|
21
|
+
name: str,
|
22
|
+
about: str,
|
23
|
+
picture: str,
|
24
|
+
nsec: Optional[str] = None
|
25
|
+
):
|
26
|
+
"""Initialize the Merchant profile.
|
27
|
+
|
28
|
+
Args:
|
29
|
+
name: Name for the merchant
|
30
|
+
about: brief description about the merchant
|
31
|
+
picture: url to a png file with a picture for the merchant
|
32
|
+
nsec: private key to be used by this Merchant
|
33
|
+
"""
|
34
|
+
|
35
|
+
# Set log handling for MerchantProfile
|
36
|
+
if not MerchantProfile.logger.hasHandlers():
|
37
|
+
console_handler = logging.StreamHandler()
|
38
|
+
console_handler.setLevel(logging.INFO)
|
39
|
+
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
40
|
+
console_handler.setFormatter(formatter)
|
41
|
+
MerchantProfile.logger.addHandler(console_handler)
|
42
|
+
|
43
|
+
self.name = name
|
44
|
+
self.about = about
|
45
|
+
self.picture = picture
|
46
|
+
|
47
|
+
if nsec:
|
48
|
+
self.private_key = nsec
|
49
|
+
keys = nostr.Keys.parse(self.private_key)
|
50
|
+
self.public_key = keys.public_key().to_bech32()
|
51
|
+
MerchantProfile.logger.info(f"Pre-defined private key reused for {self.name}: {self.private_key}")
|
52
|
+
MerchantProfile.logger.info(f"Pre-defined public key reused for {self.name}: {self.public_key}")
|
53
|
+
else:
|
54
|
+
keys = nostr.Keys.generate()
|
55
|
+
self.private_key = keys.secret_key().to_bech32()
|
56
|
+
self.public_key = keys.public_key().to_bech32()
|
57
|
+
MerchantProfile.logger.info(f"New private key created for {self.name}: {self.private_key}")
|
58
|
+
MerchantProfile.logger.info(f"New public key created for {self.name}: {self.public_key}")
|
59
|
+
|
60
|
+
def merchant_profile_to_str(self) -> str:
|
61
|
+
return (
|
62
|
+
f"Merchant name: {self.name}. "
|
63
|
+
f"Merchant description: {self.about}. "
|
64
|
+
f"Merchant picture URL: {self.picture}. "
|
65
|
+
f"Private key: {self.private_key}. "
|
66
|
+
f"Public key: {self.public_key}."
|
67
|
+
)
|
68
|
+
|
69
|
+
def get_public_key(self) -> str:
|
70
|
+
return self.public_key
|
71
|
+
|
72
|
+
def get_private_key(self) -> str:
|
73
|
+
return self.private_key
|
74
|
+
|
75
|
+
def get_name(self) -> str:
|
76
|
+
return self.name
|
77
|
+
|
78
|
+
def get_about(self) -> str:
|
79
|
+
return self.about
|
80
|
+
|
81
|
+
def get_picture(self) -> str:
|
82
|
+
return self.picture
|
83
|
+
|
84
|
+
|
85
|
+
|
86
|
+
class Merchant(Toolkit):
|
87
|
+
|
88
|
+
WEB_URL: str = "http://njump.me/"
|
89
|
+
|
90
|
+
def __init__(
|
91
|
+
self,
|
92
|
+
merchant_profile: MerchantProfile,
|
93
|
+
relay: str,
|
94
|
+
):
|
95
|
+
"""Initialize the Merchant toolkit.
|
96
|
+
|
97
|
+
Args:
|
98
|
+
merchant_profile: profile of the merchant using this agent
|
99
|
+
relay: Nostr relay to use for communications
|
100
|
+
"""
|
101
|
+
super().__init__(name="merchant")
|
102
|
+
self.relay = relay
|
103
|
+
self.merchant_profile = merchant_profile
|
104
|
+
|
105
|
+
# Register all methods
|
106
|
+
self.register(self.publish_merchant_profile)
|
107
|
+
self.register(self.get_merchant_url)
|
108
|
+
|
109
|
+
def publish_merchant_profile(
|
110
|
+
self
|
111
|
+
) -> str:
|
112
|
+
"""
|
113
|
+
Publishes the merchant profile on Nostr
|
114
|
+
|
115
|
+
Returns:
|
116
|
+
str: with event id and other details if successful or "error" string if unsuccesful
|
117
|
+
"""
|
118
|
+
# Run the async pubilshing function synchronously
|
119
|
+
return asyncio.run(self._async_publish_merchant_profile())
|
120
|
+
|
121
|
+
async def _async_publish_merchant_profile(
|
122
|
+
self
|
123
|
+
) -> str:
|
124
|
+
"""
|
125
|
+
Asynchronous method to publish the merchant profile on Nostr
|
126
|
+
|
127
|
+
Returns:
|
128
|
+
str: with event id and other details if successful or "error" string if unsuccesful
|
129
|
+
"""
|
130
|
+
|
131
|
+
nostr_client = nostr.NostrClient(self.relay, self.merchant_profile.get_private_key())
|
132
|
+
|
133
|
+
# Connect to the relay
|
134
|
+
outcome = await nostr_client.connect()
|
135
|
+
|
136
|
+
# Check if the operation resulted in an error
|
137
|
+
if outcome == nostr.NostrClient.ERROR:
|
138
|
+
return nostr.NostrClient.ERROR
|
139
|
+
else:
|
140
|
+
eventid = await nostr_client.publish_profile(
|
141
|
+
self.merchant_profile.get_name(),
|
142
|
+
self.merchant_profile.get_about(),
|
143
|
+
self.merchant_profile.get_picture()
|
144
|
+
)
|
145
|
+
|
146
|
+
# Check if the operation resulted in an error
|
147
|
+
if eventid == nostr.NostrClient.ERROR:
|
148
|
+
return nostr.NostrClient.ERROR
|
149
|
+
|
150
|
+
# Return the event ID and merchant profile details
|
151
|
+
return eventid + self.merchant_profile.merchant_profile_to_str()
|
152
|
+
|
153
|
+
def get_merchant_url(
|
154
|
+
self
|
155
|
+
) -> str:
|
156
|
+
"""
|
157
|
+
Returns URL with merchant profile
|
158
|
+
|
159
|
+
Returns:
|
160
|
+
str: valid URL with merchant profile
|
161
|
+
"""
|
162
|
+
|
163
|
+
return self.WEB_URL + self.merchant_profile.get_public_key()
|
agentstr/nostr.py
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
from typing import Optional
|
2
|
+
from os import getenv
|
3
|
+
import logging
|
4
|
+
|
5
|
+
try:
|
6
|
+
import asyncio
|
7
|
+
except ImportError:
|
8
|
+
raise ImportError("`asyncio` not installed. Please install using `pip install asyncio`")
|
9
|
+
|
10
|
+
try:
|
11
|
+
from nostr_sdk import Keys, Client, EventBuilder, NostrSigner, SendEventOutput, Event, Metadata
|
12
|
+
except ImportError:
|
13
|
+
raise ImportError("`nostr_sdk` not installed. Please install using `pip install nostr_sdk`")
|
14
|
+
|
15
|
+
class NostrClient():
|
16
|
+
|
17
|
+
logger = logging.getLogger("NostrClient")
|
18
|
+
ERROR: str = "ERROR"
|
19
|
+
SUCCESS: str = "SUCCESS"
|
20
|
+
|
21
|
+
def __init__(
|
22
|
+
self,
|
23
|
+
relay: str = None,
|
24
|
+
nsec: str = None,
|
25
|
+
):
|
26
|
+
"""Initialize the Nostr client.
|
27
|
+
|
28
|
+
Args:
|
29
|
+
relay: Nostr relay that the client will connect to
|
30
|
+
nsec: Nostr private key in bech32 format
|
31
|
+
"""
|
32
|
+
# Set log handling
|
33
|
+
if not NostrClient.logger.hasHandlers():
|
34
|
+
console_handler = logging.StreamHandler()
|
35
|
+
console_handler.setLevel(logging.INFO)
|
36
|
+
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
37
|
+
console_handler.setFormatter(formatter)
|
38
|
+
NostrClient.logger.addHandler(console_handler)
|
39
|
+
|
40
|
+
self.relay = relay
|
41
|
+
self.keys = Keys.parse(nsec)
|
42
|
+
self.nostr_signer = NostrSigner.keys(self.keys)
|
43
|
+
self.client = Client(self.nostr_signer)
|
44
|
+
|
45
|
+
|
46
|
+
async def connect(
|
47
|
+
self
|
48
|
+
) -> str:
|
49
|
+
|
50
|
+
"""Add relay to the NostrClient instance and connect to it.
|
51
|
+
|
52
|
+
Returns:
|
53
|
+
str: NostrClient.SUCCESS or NostrClient.ERROR
|
54
|
+
"""
|
55
|
+
try:
|
56
|
+
await self.client.add_relay(self.relay)
|
57
|
+
NostrClient.logger.info(f"Relay {self.relay} succesfully added.")
|
58
|
+
await self.client.connect()
|
59
|
+
NostrClient.logger.info("Connected to relay.")
|
60
|
+
return NostrClient.SUCCESS
|
61
|
+
except Exception as e:
|
62
|
+
NostrClient.logger.error(f"Unable to connect to relay {self.relay}. Exception: {e}.")
|
63
|
+
return NostrClient.ERROR
|
64
|
+
|
65
|
+
async def publish_text_note(
|
66
|
+
self,
|
67
|
+
text: str
|
68
|
+
) -> str:
|
69
|
+
|
70
|
+
"""Publish kind 1 event (text note) to the relay
|
71
|
+
|
72
|
+
Args:
|
73
|
+
text: text to be published as kind 1 event
|
74
|
+
|
75
|
+
Returns:
|
76
|
+
str: event id if successful and "error" string if unsuccesful
|
77
|
+
"""
|
78
|
+
builder = EventBuilder.text_note(text)
|
79
|
+
|
80
|
+
try:
|
81
|
+
output = await self.client.send_event_builder(builder)
|
82
|
+
NostrClient.logger.info(f"Text note published with event id: {output.id.to_bech32()}")
|
83
|
+
return output.id.to_bech32()
|
84
|
+
except Exception as e:
|
85
|
+
NostrClient.logger.error(f"Unable to publish text note to relay {self.relay}. Exception: {e}.")
|
86
|
+
return NostrClient.ERROR
|
87
|
+
|
88
|
+
async def publish_event(
|
89
|
+
self,
|
90
|
+
builder: EventBuilder
|
91
|
+
) -> str:
|
92
|
+
|
93
|
+
"""Publish generic Nostr event to the relay
|
94
|
+
|
95
|
+
Returns:
|
96
|
+
str: event id if successful or "error" string if unsuccesful
|
97
|
+
"""
|
98
|
+
try:
|
99
|
+
output = await self.client.send_event_builder(builder)
|
100
|
+
NostrClient.logger.info(f"Event published with event id: {output.id.to_bech32()}")
|
101
|
+
return output.id.to_bech32()
|
102
|
+
except Exception as e:
|
103
|
+
NostrClient.logger.error(f"Unable to publish event to relay {self.relay}. Exception: {e}.")
|
104
|
+
return NostrClient.ERROR
|
105
|
+
|
106
|
+
async def publish_profile(self, name: str, about: str, picture: str) -> str:
|
107
|
+
"""Publish a Nostr profile.
|
108
|
+
|
109
|
+
Args:
|
110
|
+
name: name of the Nostr profile
|
111
|
+
about: brief description about the profile
|
112
|
+
picture: url to a png file with a picture for the profile
|
113
|
+
|
114
|
+
Returns:
|
115
|
+
str: event id if successful or "error" string if unsuccesful
|
116
|
+
"""
|
117
|
+
metadata_content = Metadata().set_name(name)
|
118
|
+
metadata_content = metadata_content.set_about(about)
|
119
|
+
metadata_content = metadata_content.set_picture(picture)
|
120
|
+
|
121
|
+
builder = EventBuilder.metadata(metadata_content)
|
122
|
+
try:
|
123
|
+
output = await self.client.send_event_builder(builder)
|
124
|
+
NostrClient.logger.info(f"Profile note published with event id: {output.id.to_bech32()}")
|
125
|
+
return output.id.to_bech32()
|
126
|
+
except Exception as e:
|
127
|
+
NostrClient.logger.error(f"Unable to publish profile to relay {self.relay}. Exception: {e}.")
|
128
|
+
return NostrClient.ERROR
|
129
|
+
|
130
|
+
@classmethod
|
131
|
+
def set_logging_level(cls, logging_level: int):
|
132
|
+
"""
|
133
|
+
Set the logging level for the NostrClient logger.
|
134
|
+
|
135
|
+
Args:
|
136
|
+
logging_level (int): The logging level (e.g., logging.DEBUG, logging.INFO).
|
137
|
+
"""
|
138
|
+
cls.logger.setLevel(logging_level)
|
139
|
+
for handler in cls.logger.handlers:
|
140
|
+
handler.setLevel(logging_level)
|
141
|
+
cls.logger.info(f"Logging level set to {logging.getLevelName(logging_level)}")
|
@@ -1,9 +1,7 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: agentstr
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.10
|
4
4
|
Summary: A library for collaborative AI agents
|
5
|
-
Home-page: https://github.com/synvya/agentstr
|
6
|
-
Author: Alejandro Gil
|
7
5
|
Author-email: Alejandro Gil <info@synvya.com>
|
8
6
|
License: MIT
|
9
7
|
Project-URL: Homepage, https://github.com/synvya/agentstr
|
@@ -13,14 +11,13 @@ Keywords: AI,agents,collaboration,library
|
|
13
11
|
Classifier: Programming Language :: Python :: 3
|
14
12
|
Classifier: License :: OSI Approved :: MIT License
|
15
13
|
Classifier: Operating System :: OS Independent
|
16
|
-
Requires-Python:
|
14
|
+
Requires-Python: <3.13,>=3.9
|
17
15
|
Description-Content-Type: text/markdown
|
18
16
|
License-File: LICENSE
|
19
17
|
Requires-Dist: phidata>=2.7.0
|
20
18
|
Requires-Dist: openai>=1.50.0
|
21
|
-
|
22
|
-
|
23
|
-
Dynamic: requires-python
|
19
|
+
Requires-Dist: packaging>=24.0
|
20
|
+
Requires-Dist: nostr-sdk>=0.38.0
|
24
21
|
|
25
22
|
AgentStr
|
26
23
|
========
|
@@ -28,6 +25,10 @@ AgentStr is an extension of [Phidata](https://www.phidata.com) AI agents that al
|
|
28
25
|
|
29
26
|
The goal is for Agent A operated by Company A to be able to work with Agent B operated by Company B to achieve a common goal. For example: Company A wants to buy a product sold by Company B so Agent A and Agent B can coordinate and execute the transaction.
|
30
27
|
|
28
|
+
The basic communication tools are implemented in `agentstr/nostr.py`.
|
29
|
+
|
30
|
+
As a first example, AgentStr provides the tools to create and operate a marketplace using the [NIP-15](https://github.com/nostr-protocol/nips/blob/master/15.md) Nostr Marketplace as its foundation. The file `agentstr/marketplace.py` includes NIP-15 `merchant` and `customer` profiles implemented each as a Phidata Toolkit.
|
31
|
+
|
31
32
|
# License
|
32
33
|
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
|
33
34
|
|
@@ -36,16 +37,13 @@ The library is in its infancy.
|
|
36
37
|
|
37
38
|
Done:
|
38
39
|
- Workflow to package and distribute the library
|
39
|
-
-
|
40
|
-
|
40
|
+
- Users can create a Merchant profile and create an agent with the `merchant` toolkit that acts on behalf of the Merchant profile
|
41
|
+
|
41
42
|
|
42
43
|
To be done:
|
43
|
-
-
|
44
|
-
-
|
45
|
-
-
|
46
|
-
- Expose capabilities via Nostr
|
47
|
-
- Agent B retrieves capabilities exposed by Agent A
|
48
|
-
- Agent B coordinates transaction with Agent A
|
44
|
+
- Create a `marketplace` with `stalls`
|
45
|
+
- Merchants to define `products`
|
46
|
+
- Create a `customer` Toolkit
|
49
47
|
|
50
48
|
# Installation
|
51
49
|
AgentStr is offered as a python library available at https://pypi.org/project/agentstr/.
|
@@ -56,10 +54,11 @@ Here is an example on how to use the library:
|
|
56
54
|
```
|
57
55
|
cd ~/
|
58
56
|
python3 -m venv ~/.venvs/aienv
|
59
|
-
source ~/.venvs/aienv/bin/
|
57
|
+
source ~/.venvs/aienv/bin/activate
|
60
58
|
```
|
61
59
|
2. Install the agentstr library
|
62
60
|
```
|
61
|
+
pip install --upgrade pip
|
63
62
|
pip install agentstr
|
64
63
|
mkdir ~/mysampleapp
|
65
64
|
cd ~/mysampleapp
|
@@ -70,24 +69,43 @@ Here is an example on how to use the library:
|
|
70
69
|
```
|
71
70
|
4. Copy paste this code to the main.py file
|
72
71
|
```
|
73
|
-
from
|
74
|
-
|
75
|
-
agent
|
72
|
+
from dotenv import load_dotenv
|
73
|
+
from os import getenv
|
74
|
+
from phi.agent import Agent
|
75
|
+
from phi.model.openai import OpenAIChat
|
76
|
+
from agentstr.marketplace import MerchantProfile, Merchant
|
76
77
|
|
77
|
-
# Test AgentStr new capabilities
|
78
|
-
print(f"Public key: {agent.get_public_key()}\nPrivate key: {agent.get_private_key()}")
|
79
|
-
print(f"Company: {agent.get_company()}\nRole: {agent.get_role()}")
|
80
78
|
|
81
|
-
|
82
|
-
|
79
|
+
profile = MerchantProfile(
|
80
|
+
"Synvya",
|
81
|
+
"Testing stuff",
|
82
|
+
"https://i.nostr.build/ocjZ5GlAKwrvgRhx.png",
|
83
|
+
getenv("NSEC_KEY")
|
84
|
+
)
|
85
|
+
|
86
|
+
agent = Agent(
|
87
|
+
name="Merchant Assistant",
|
88
|
+
model=OpenAIChat(id="gpt-4o"),
|
89
|
+
tools=[Merchant(merchant_profile=profile, relay="wss://relay.damus.io")],
|
90
|
+
show_tool_calls=True,
|
91
|
+
markdown=True,
|
92
|
+
debug_mode=True
|
93
|
+
)
|
94
|
+
|
95
|
+
agent.print_response("Publish the merchant information and tell me the event id used")
|
83
96
|
```
|
84
|
-
5.
|
97
|
+
5. Export your OpenAI key and optionally a Nostr private key before running the code
|
85
98
|
```
|
99
|
+
export OPENAI_API_KEY="sk-***"
|
100
|
+
export NSEC_KEY="nsec***"
|
86
101
|
python main.py
|
87
102
|
```
|
88
103
|
|
104
|
+
This example will attempt to load a Nostr private key defined as NSEC_KEY in bech32 format. If a private key is not provided, the `MerchantProfile` class initializer will assign it a new one.
|
105
|
+
|
89
106
|
# Contributing
|
90
107
|
Refer to [CONTRIBUTING.md](CONTRIBUTING.md) for specific instructions on installation instructions for developers and how to contribute.
|
91
108
|
|
92
109
|
# Acknowledgments
|
93
|
-
- [Phidata](https://www.phidata.com
|
110
|
+
- [Phidata](https://www.phidata.com) - For building robust AI agents.
|
111
|
+
- [Rust-Nostr](https://rust-nostr.org/index.html) - For providing a python based Nostr SDK.
|
@@ -0,0 +1,8 @@
|
|
1
|
+
agentstr/__init__.py,sha256=sXLh7g3KC4QCFxcZGBTpG2scR7hmmBsMjq6LqRptkRg,22
|
2
|
+
agentstr/marketplace.py,sha256=XYF2ZrF6MpmxgCEOz3uN436cj7F4VHyUATFk8gmr7Zg,5245
|
3
|
+
agentstr/nostr.py,sha256=C5zMWKBbXLkarZxBoTydJCZVzqGoCogBd_9v8Gll0VU,5012
|
4
|
+
agentstr-0.0.10.dist-info/LICENSE,sha256=xF8akIKB07gOtkhjENT0xVbWGdFp4-srDKpZKjD03Js,1063
|
5
|
+
agentstr-0.0.10.dist-info/METADATA,sha256=GuVKTLwjr6Skj4HH387GQP7YYMnTKulqgh8OQuuJGvs,4082
|
6
|
+
agentstr-0.0.10.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
7
|
+
agentstr-0.0.10.dist-info/top_level.txt,sha256=KZObFRHppZvKUGYB_m9w5HhLwps7jj7w6Xrw73dH2ss,9
|
8
|
+
agentstr-0.0.10.dist-info/RECORD,,
|
agentstr/core.py
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
from phi.agent import Agent
|
2
|
-
from phi.model.openai import OpenAIChat
|
3
|
-
from pydantic import Field
|
4
|
-
from typing import Optional
|
5
|
-
|
6
|
-
|
7
|
-
class AgentStr(Agent):
|
8
|
-
|
9
|
-
# -*- Agent settings
|
10
|
-
# Company operating the agent.
|
11
|
-
# Used as seed for public / private key identifier together with the agent role
|
12
|
-
company: str = None
|
13
|
-
|
14
|
-
# -*- Agent public / private key identifiers
|
15
|
-
# The public / private key should be deterministic for a given 'company' and 'role' combination
|
16
|
-
# Public key for the agent
|
17
|
-
npub: str = None
|
18
|
-
# Private key for the agent
|
19
|
-
nsec: str = None
|
20
|
-
|
21
|
-
# Call the parent class (Agent) constructor
|
22
|
-
def __init__(self, company: str, role: str):
|
23
|
-
super().__init__(role = role, model=OpenAIChat(id="gpt-4o"))
|
24
|
-
self.company = company
|
25
|
-
self.npub = f"npub - {self.company} - {self.role}"
|
26
|
-
self.nsec = f"nsec - {self.company} - {self.role}"
|
27
|
-
|
28
|
-
def get_public_key(self) -> str:
|
29
|
-
return self.npub
|
30
|
-
|
31
|
-
def get_private_key(self) -> str:
|
32
|
-
return self.nsec
|
33
|
-
|
34
|
-
def get_company(self) -> str:
|
35
|
-
return self.company
|
36
|
-
|
37
|
-
def get_role(self) -> str:
|
38
|
-
return self.role
|
39
|
-
|
40
|
-
def add(a, b):
|
41
|
-
"""Add two numbers."""
|
42
|
-
return a + b
|
agentstr-0.0.9.dist-info/RECORD
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
agentstr/__init__.py,sha256=sXLh7g3KC4QCFxcZGBTpG2scR7hmmBsMjq6LqRptkRg,22
|
2
|
-
agentstr/core.py,sha256=xS5q8ltl81DqLjKgiVtjUQ5r-jbEPXXjTlJ0pWcV5p8,1214
|
3
|
-
agentstr-0.0.9.dist-info/LICENSE,sha256=xF8akIKB07gOtkhjENT0xVbWGdFp4-srDKpZKjD03Js,1063
|
4
|
-
agentstr-0.0.9.dist-info/METADATA,sha256=0H9Gophcg8p8Hw3vCZhQanTZTb9EGkCNvMWXsA_aOo0,3194
|
5
|
-
agentstr-0.0.9.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
6
|
-
agentstr-0.0.9.dist-info/top_level.txt,sha256=KZObFRHppZvKUGYB_m9w5HhLwps7jj7w6Xrw73dH2ss,9
|
7
|
-
agentstr-0.0.9.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|