agentstr 0.1.7__py3-none-any.whl → 0.1.8__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/nostr.py CHANGED
@@ -1,53 +1,193 @@
1
+ import logging
1
2
  from typing import Optional
2
- from os import getenv
3
- import logging
4
3
 
5
- try:
4
+ try:
6
5
  import asyncio
7
6
  except ImportError:
8
- raise ImportError("`asyncio` not installed. Please install using `pip install asyncio`")
7
+ raise ImportError(
8
+ "`asyncio` not installed. Please install using `pip install asyncio`"
9
+ )
9
10
 
10
11
  try:
11
- from nostr_sdk import Keys, Client, EventBuilder, NostrSigner, SendEventOutput, Event, Metadata
12
+ from nostr_sdk import (
13
+ Client,
14
+ Coordinate,
15
+ Event,
16
+ EventBuilder,
17
+ EventId,
18
+ Keys,
19
+ Kind,
20
+ Metadata,
21
+ NostrSigner,
22
+ ProductData,
23
+ PublicKey,
24
+ ShippingCost,
25
+ ShippingMethod,
26
+ StallData,
27
+ Tag,
28
+ Timestamp,
29
+ )
30
+
12
31
  except ImportError:
13
- raise ImportError("`nostr_sdk` not installed. Please install using `pip install nostr_sdk`")
32
+ raise ImportError(
33
+ "`nostr_sdk` not installed. Please install using `pip install nostr_sdk`"
34
+ )
35
+
36
+
37
+ class NostrClient:
38
+ """
39
+ NostrClient implements the set of Nostr utilities required for higher level functions implementing
40
+ like the Marketplace.
41
+
42
+ Nostr is an asynchronous communication protocol. To hide this, NostrClient exposes synchronous functions.
43
+ Users of the NostrClient should ignore `_async_` functions which are for internal purposes only.
44
+ """
14
45
 
15
- class NostrClient():
16
-
17
46
  logger = logging.getLogger("NostrClient")
18
47
  ERROR: str = "ERROR"
19
48
  SUCCESS: str = "SUCCESS"
20
-
49
+
21
50
  def __init__(
22
51
  self,
23
- relay: str = None,
24
- nsec: str = None,
25
- ):
26
- """Initialize the Nostr client.
52
+ relay: str,
53
+ nsec: str,
54
+ ) -> None:
55
+ """
56
+ Initialize the Nostr client.
27
57
 
28
58
  Args:
29
- relay: Nostr relay that the client will connect to
59
+ relay: Nostr relay that the client will connect to
30
60
  nsec: Nostr private key in bech32 format
31
61
  """
32
62
  # Set log handling
33
63
  if not NostrClient.logger.hasHandlers():
34
64
  console_handler = logging.StreamHandler()
35
65
  console_handler.setLevel(logging.INFO)
36
- formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
66
+ formatter = logging.Formatter(
67
+ "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
68
+ )
37
69
  console_handler.setFormatter(formatter)
38
70
  NostrClient.logger.addHandler(console_handler)
39
-
71
+
72
+ # configure relay and keys for the client
40
73
  self.relay = relay
41
74
  self.keys = Keys.parse(nsec)
42
75
  self.nostr_signer = NostrSigner.keys(self.keys)
43
76
  self.client = Client(self.nostr_signer)
44
-
45
77
 
46
- async def connect(
47
- self
48
- ) -> str:
49
-
50
- """Add relay to the NostrClient instance and connect to it.
78
+ def delete_event(self, event_id: EventId, reason: Optional[str] = None) -> EventId:
79
+ """
80
+ Requests the relay to delete an event. Relays may or may not honor the request.
81
+
82
+ Args:
83
+ event_id: EventId associated with the event to be deleted
84
+ reason: optional reason for deleting the event
85
+
86
+ Returns:
87
+ EventId: if of the event requesting the deletion of event_id
88
+
89
+ Raises:
90
+ RuntimeError: if the deletion event can't be published
91
+ """
92
+ event_builder = EventBuilder.delete(ids=[event_id], reason=reason)
93
+ # Run the async publishing function synchronously
94
+ return asyncio.run(self._async_publish_event(event_builder))
95
+
96
+ def publish_event(self, event_builder: EventBuilder) -> EventId:
97
+ """
98
+ Publish generic Nostr event to the relay
99
+
100
+ Returns:
101
+ EventId: event id if successful or NostrClient.ERROR if unsuccesful
102
+
103
+ Raises:
104
+ RuntimeError: if the product can't be published
105
+ """
106
+ # Run the async publishing function synchronously
107
+ return asyncio.run(self._async_publish_event(event_builder))
108
+
109
+ def publish_note(self, text: str) -> EventId:
110
+ """Publish note with event kind 1
111
+
112
+ Args:
113
+ text: text to be published as kind 1 event
114
+
115
+ Returns:
116
+ EventId: EventId if successful or NostrClient.ERROR if unsuccesful
117
+
118
+ Raises:
119
+ RuntimeError: if the product can't be published
120
+ """
121
+ # Run the async publishing function synchronously
122
+ return asyncio.run(self._async_publish_note(text))
123
+
124
+ def publish_product(self, product: ProductData) -> EventId:
125
+ """
126
+ Create or update a NIP-15 Marketplace product with event kind 30018
127
+
128
+ Args:
129
+ product: product to be published
130
+
131
+ Returns:
132
+ EventId: event id if successful or NostrClient.ERROR if unsuccesful
133
+
134
+ Raises:
135
+ RuntimeError: if the product can't be published
136
+ """
137
+ # Run the async publishing function synchronously
138
+ return asyncio.run(self._async_publish_product(product))
139
+
140
+ def publish_profile(self, name: str, about: str, picture: str) -> EventId:
141
+ """
142
+ Publish a Nostr profile with event kind 0
143
+
144
+ Args:
145
+ name: name of the Nostr profile
146
+ about: brief description about the profile
147
+ picture: url to a png file with a picture for the profile
148
+
149
+ Returns:
150
+ EventId: event id if successful or NostrClient.ERROR if unsuccesful
151
+
152
+ Raises:
153
+ RuntimeError: if the profile can't be published
154
+ """
155
+ # Run the async publishing function synchronously
156
+ return asyncio.run(self._async_publish_profile(name, about, picture))
157
+
158
+ def publish_stall(self, stall: StallData) -> EventId:
159
+ """Publish a stall to nostr
160
+
161
+ Args:
162
+ stall: stall to be published
163
+
164
+ Returns:
165
+ EventId: event id if successful or NostrClient.ERROR if unsuccesful
166
+ """
167
+ try:
168
+ return asyncio.run(self._async_publish_stall(stall))
169
+ except Exception as e:
170
+ self.logger.error(f"Failed to publish stall: {e}")
171
+ return NostrClient.ERROR
172
+
173
+ @classmethod
174
+ def set_logging_level(cls, logging_level: int) -> None:
175
+ """Set the logging level for the NostrClient logger.
176
+
177
+ Args:
178
+ logging_level: The logging level (e.g., logging.DEBUG, logging.INFO)
179
+ """
180
+ cls.logger.setLevel(logging_level)
181
+ for handler in cls.logger.handlers:
182
+ handler.setLevel(logging_level)
183
+ cls.logger.info(f"Logging level set to {logging.getLevelName(logging_level)}")
184
+
185
+ # ----------------------------------------------------------------------------------------------
186
+ # --*-- async functions for internal use only. Developers should use synchronous functions above
187
+ # ----------------------------------------------------------------------------------------------
188
+
189
+ async def _async_connect(self) -> str:
190
+ """Asynchronous function to add relay to the NostrClient instance and connect to it.
51
191
 
52
192
  Returns:
53
193
  str: NostrClient.SUCCESS or NostrClient.ERROR
@@ -59,83 +199,129 @@ class NostrClient():
59
199
  NostrClient.logger.info("Connected to relay.")
60
200
  return NostrClient.SUCCESS
61
201
  except Exception as e:
62
- NostrClient.logger.error(f"Unable to connect to relay {self.relay}. Exception: {e}.")
202
+ NostrClient.logger.error(
203
+ f"Unable to connect to relay {self.relay}. Exception: {e}."
204
+ )
63
205
  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
206
 
72
- Args:
73
- text: text to be published as kind 1 event
207
+ async def _async_publish_event(self, event_builder: EventBuilder) -> EventId:
208
+ """
209
+ Publish generic Nostr event to the relay
74
210
 
75
211
  Returns:
76
- str: event id if successful and "error" string if unsuccesful
212
+ EventId: event id of the published event
213
+
214
+ Raises:
215
+ RuntimeError: if the event can't be published
77
216
  """
78
- builder = EventBuilder.text_note(text)
217
+ connected = await self._async_connect()
218
+
219
+ if connected == NostrClient.ERROR:
220
+ raise RuntimeError("Unable to connect to the relay")
79
221
 
80
222
  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()
223
+ output = await self.client.send_event_builder(event_builder)
224
+ if len(output.success) > 0:
225
+ NostrClient.logger.info(
226
+ f"Event published with event id: {output.id.to_bech32()}"
227
+ )
228
+ return output.id
229
+ else:
230
+ raise RuntimeError("Unable to publish event")
84
231
  except Exception as e:
85
- NostrClient.logger.error(f"Unable to publish text note to relay {self.relay}. Exception: {e}.")
86
- return NostrClient.ERROR
232
+ NostrClient.logger.error(
233
+ f"NostrClient instance not properly initialized. Exception: {e}."
234
+ )
235
+ raise RuntimeError(
236
+ f"NostrClient instance not properly initialized. Exception: {e}."
237
+ )
87
238
 
88
- async def publish_event(
89
- self,
90
- builder: EventBuilder
91
- ) -> str:
92
-
93
- """Publish generic Nostr event to the relay
239
+ async def _async_publish_note(self, text: str) -> EventId:
240
+ """
241
+ Asynchronous funcion to publish kind 1 event (text note) to the relay
242
+
243
+ Args:
244
+ text: text to be published as kind 1 event
94
245
 
95
246
  Returns:
96
- str: event id if successful or "error" string if unsuccesful
247
+ EventId: event id if successful or NostrClient.ERROR if unsuccesful
248
+
249
+ Raises:
250
+ RuntimeError: if the event can't be published
97
251
  """
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.
252
+ event_builder = EventBuilder.text_note(text)
253
+ return await self._async_publish_event(event_builder)
254
+
255
+ async def _async_publish_product(self, product: ProductData) -> EventId:
256
+ """
257
+ Asynchronous function to create or update a NIP-15 Marketplace product with event kind 30018
258
+
259
+ Args:
260
+ product: product to publish
261
+
262
+ Returns:
263
+ EventId: event id if successful or NostrClient.ERROR if unsuccesfull
264
+
265
+ Raises:
266
+ RuntimeError: if the product can't be published
267
+ """
268
+ coordinate_tag = Coordinate(
269
+ Kind(30017), self.keys.public_key(), product.stall_id
270
+ )
271
+
272
+ # EventBuilder.product_data() has a bug with tag handling.
273
+ # We use the function to create the content field and discard the eventbuilder
274
+ bad_event_builder = EventBuilder.product_data(product)
275
+
276
+ # create an event from bad_event_builder to extract the content - not broadcasted
277
+ bad_event = await self.client.sign_event_builder(bad_event_builder)
278
+ content = bad_event.content()
279
+
280
+ # build a new event with the right tags and the content
281
+ good_event_builder = EventBuilder(Kind(30018), content).tags(
282
+ [Tag.identifier(product.id), Tag.coordinate(coordinate_tag)]
283
+ )
284
+ self.logger.info("Product event: " + str(good_event_builder))
285
+ return await self._async_publish_event(good_event_builder)
286
+
287
+ async def _async_publish_profile(
288
+ self, name: str, about: str, picture: str
289
+ ) -> EventId:
290
+ """
291
+ Asynchronous function to publish a Nostr profile with event kind 0
108
292
 
109
293
  Args:
110
294
  name: name of the Nostr profile
111
295
  about: brief description about the profile
112
296
  picture: url to a png file with a picture for the profile
113
-
297
+
114
298
  Returns:
115
- str: event id if successful or "error" string if unsuccesful
299
+ EventId: event id if successful or NostrClient.ERROR if unsuccesful
300
+
301
+ Raises:
302
+ RuntimeError: if the profile can't be published
116
303
  """
117
304
  metadata_content = Metadata().set_name(name)
118
305
  metadata_content = metadata_content.set_about(about)
119
306
  metadata_content = metadata_content.set_picture(picture)
120
307
 
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
308
+ event_builder = EventBuilder.metadata(metadata_content)
309
+ return await self._async_publish_event(event_builder)
129
310
 
130
- @classmethod
131
- def set_logging_level(cls, logging_level: int):
311
+ async def _async_publish_stall(self, stall: StallData) -> EventId:
132
312
  """
133
- Set the logging level for the NostrClient logger.
313
+ Asynchronous function to create or update a NIP-15 Marketplace stall with event kind 30017
134
314
 
135
315
  Args:
136
- logging_level (int): The logging level (e.g., logging.DEBUG, logging.INFO).
316
+ stall: stall to be published
317
+
318
+ Returns:
319
+ EventId: event id if successful or NostrClient.ERROR if unsuccesfull
320
+
321
+ Raises:
322
+ RuntimeError: if the profile can't be published
137
323
  """
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)}")
324
+
325
+ self.logger.info(f"Stall: {stall}")
326
+ event_builder = EventBuilder.stall_data(stall)
327
+ return await self._async_publish_event(event_builder)
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 Synvya
3
+ Copyright (c) 2025 Synvya
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -0,0 +1,110 @@
1
+ Metadata-Version: 2.2
2
+ Name: agentstr
3
+ Version: 0.1.8
4
+ Summary: Nostr extension for Phidata AI agents
5
+ Project-URL: Homepage, https://github.com/synvya/agentstr
6
+ Project-URL: Documentation, https://github.com/synvya/agentstr#readme
7
+ Project-URL: BugTracker, https://github.com/synvya/agentstr/issues
8
+ Requires-Python: <3.13,>=3.9
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE
11
+ Requires-Dist: phidata>=2.7.0
12
+ Requires-Dist: openai>=1.50.0
13
+ Requires-Dist: packaging>=24.0
14
+ Requires-Dist: nostr-sdk>=0.38.0
15
+ Requires-Dist: pydantic>=2.0.0
16
+ Provides-Extra: dev
17
+ Requires-Dist: pytest>=7.0; extra == "dev"
18
+ Requires-Dist: black>=23.0; extra == "dev"
19
+ Requires-Dist: isort>=5.0; extra == "dev"
20
+ Requires-Dist: mypy>=1.0; extra == "dev"
21
+ Requires-Dist: python-dotenv>=1.0; extra == "dev"
22
+
23
+ # AgentStr
24
+
25
+ AgentStr is an extension of [Phidata](https://www.phidata.com) AI agents that enables peer-to-peer agent communication using the Nostr protocol.
26
+
27
+ ## Overview
28
+
29
+ AgentStr allows AI agents operated by different organizations to communicate and collaborate. For example:
30
+ - Agent A from Company A can coordinate with Agent B from Company B to execute a transaction
31
+ - Agents can discover and interact with each other through the decentralized Nostr network
32
+ - No central authority or intermediary required
33
+
34
+ ## Project Structure
35
+
36
+ ```
37
+ agentstr/
38
+ ├── src/ # Source code
39
+ │ └── agentstr/
40
+ │ ├── __init__.py
41
+ │ ├── marketplace.py
42
+ │ └── nostr.py
43
+ ├── tests/ # Test files
44
+ ├── docs/ # Documentation
45
+ ├── examples/ # Example implementations
46
+ └── ...
47
+ ```
48
+
49
+ ## Features
50
+
51
+ ### Current Features
52
+ - Create Merchant agents with Nostr identities
53
+ - Publish and manage merchant products using [NIP-15](https://github.com/nostr-protocol/nips/blob/master/15.md) marketplace protocol
54
+ - Create merchant stalls to organize products
55
+ - Handle shipping zones and costs
56
+ - Secure communication using Nostr keys
57
+
58
+ ### Roadmap
59
+ - [ ] Create marketplace with stalls
60
+ - [ ] Create Buyer agents
61
+ - [ ] Enable merchants to define products
62
+ - [ ] Add customer toolkit for buyers
63
+ - [ ] Support additional Nostr NIPs
64
+ - [ ] Add more agent interaction patterns
65
+
66
+ ## Installation
67
+
68
+ ```bash
69
+ # Create a new python environment
70
+ python3 -m venv ~/.venvs/aienv
71
+ source ~/.venvs/aienv/bin/activate
72
+
73
+ # Install agentstr
74
+ pip install --upgrade pip
75
+ pip install agentstr
76
+ ```
77
+
78
+ ## Examples
79
+
80
+ See our [examples directory](examples/) for complete working implementations:
81
+
82
+ - [Basic CLI Agent](examples/basic_cli/main.py) - A complete example showing:
83
+ - Setting up merchant profiles
84
+ - Creating stalls with shipping methods
85
+ - Defining products with shipping costs
86
+ - Configuring the agent with the merchant toolkit
87
+ - Running an interactive CLI application
88
+
89
+
90
+ ## Documentation
91
+
92
+ For more detailed documentation and examples, see [Docs](docs/docs.md)
93
+
94
+ ## Development
95
+
96
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for:
97
+ - Development setup
98
+ - Testing instructions
99
+ - Contribution guidelines
100
+
101
+ ## License
102
+
103
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
104
+
105
+ ## Acknowledgments
106
+
107
+ - [Phidata](https://www.phidata.com) - For their AI agent framework
108
+ - [Rust-Nostr](https://rust-nostr.org) - For their Python Nostr SDK
109
+ - [Nostr Protocol](https://github.com/nostr-protocol/nips) - For the protocol specification
110
+
@@ -0,0 +1,8 @@
1
+ agentstr/__init__.py,sha256=bPXCN4fDtqII9UtDCwhWhkR6bi1LR4w0rR0vGeKPNoI,567
2
+ agentstr/marketplace.py,sha256=CavX0WQaCiz1sQhVs-PaHZ4YYUdcabW5V5eXrhtbT5A,40406
3
+ agentstr/nostr.py,sha256=PId6477VuShPq7nKgansgyJhJNNy9S8ycCf_3niizg4,11242
4
+ agentstr-0.1.8.dist-info/LICENSE,sha256=20H0yoEDN5XO1xPXyZCyJjvSTP0YiarRMKWPfiaBhQY,1063
5
+ agentstr-0.1.8.dist-info/METADATA,sha256=iHwN1hOoezYlYtYLAETT1evku9GAOzWthol7K7roYfs,3376
6
+ agentstr-0.1.8.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
7
+ agentstr-0.1.8.dist-info/top_level.txt,sha256=KZObFRHppZvKUGYB_m9w5HhLwps7jj7w6Xrw73dH2ss,9
8
+ agentstr-0.1.8.dist-info/RECORD,,
@@ -1,111 +0,0 @@
1
- Metadata-Version: 2.2
2
- Name: agentstr
3
- Version: 0.1.7
4
- Summary: A library for collaborative AI agents
5
- Author-email: Alejandro Gil <info@synvya.com>
6
- License: MIT
7
- Project-URL: Homepage, https://github.com/synvya/agentstr
8
- Project-URL: Documentation, https://github.com/synvya/agentstr#readme
9
- Project-URL: BugTracker, https://github.com/synvya/agentstr/issues
10
- Keywords: AI,agents,collaboration,library
11
- Classifier: Programming Language :: Python :: 3
12
- Classifier: License :: OSI Approved :: MIT License
13
- Classifier: Operating System :: OS Independent
14
- Requires-Python: <3.13,>=3.9
15
- Description-Content-Type: text/markdown
16
- License-File: LICENSE
17
- Requires-Dist: phidata>=2.7.0
18
- Requires-Dist: openai>=1.50.0
19
- Requires-Dist: packaging>=24.0
20
- Requires-Dist: nostr-sdk>=0.38.0
21
-
22
- AgentStr
23
- ========
24
- AgentStr is an extension of [Phidata](https://www.phidata.com) AI agents that allows for agents to communicate with other agents in separate computers using the Nostr communication protocol.
25
-
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.
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
-
32
- # License
33
- This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
34
-
35
- # Current status
36
- The library is in its infancy.
37
-
38
- Done:
39
- - Workflow to package and distribute the library
40
- - Users can create a Merchant profile and create an agent with the `merchant` toolkit that acts on behalf of the Merchant profile
41
-
42
-
43
- To be done:
44
- - Create a `marketplace` with `stalls`
45
- - Merchants to define `products`
46
- - Create a `customer` Toolkit
47
-
48
- # Installation
49
- AgentStr is offered as a python library available at https://pypi.org/project/agentstr/.
50
-
51
- Here is an example on how to use the library:
52
-
53
- 1. Create a new python environment for your app
54
- ```
55
- cd ~/
56
- python3 -m venv ~/.venvs/aienv
57
- source ~/.venvs/aienv/bin/activate
58
- ```
59
- 2. Install the agentstr library
60
- ```
61
- pip install --upgrade pip
62
- pip install agentstr
63
- mkdir ~/mysampleapp
64
- cd ~/mysampleapp
65
- ```
66
- 3. Create a new python file
67
- ```
68
- touch main.py
69
- ```
70
- 4. Copy paste this code to the main.py file
71
- ```
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
77
-
78
-
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 full URL where I can find it")
96
- ```
97
- 5. Export your OpenAI key and optionally a Nostr private key before running the code
98
- ```
99
- export OPENAI_API_KEY="sk-***"
100
- export NSEC_KEY="nsec***"
101
- python main.py
102
- ```
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
-
106
- # Contributing
107
- Refer to [CONTRIBUTING.md](CONTRIBUTING.md) for specific instructions on installation instructions for developers and how to contribute.
108
-
109
- # Acknowledgments
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.
@@ -1,8 +0,0 @@
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.1.7.dist-info/LICENSE,sha256=xF8akIKB07gOtkhjENT0xVbWGdFp4-srDKpZKjD03Js,1063
5
- agentstr-0.1.7.dist-info/METADATA,sha256=gz4B0qomWjGErWCDqZi2B5j4rEpa0mT7kY03WLThGXg,4092
6
- agentstr-0.1.7.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
7
- agentstr-0.1.7.dist-info/top_level.txt,sha256=KZObFRHppZvKUGYB_m9w5HhLwps7jj7w6Xrw73dH2ss,9
8
- agentstr-0.1.7.dist-info/RECORD,,