matrixads 1.0.0__tar.gz

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.
@@ -0,0 +1,98 @@
1
+ Metadata-Version: 2.4
2
+ Name: matrixads
3
+ Version: 1.0.0
4
+ Summary: Python SDK for MatrixAds Conversational AI Monetization and Ad Network
5
+ Author: MatrixAds Team
6
+ Author-email: MatrixAds Team <sdk@matrixads.io>
7
+ Requires-Python: >=3.9
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: httpx>=0.24.0
10
+ Requires-Dist: pydantic>=2.0.0
11
+ Provides-Extra: langchain
12
+ Requires-Dist: langchain-core>=0.1.0; extra == "langchain"
13
+ Provides-Extra: crewai
14
+ Requires-Dist: crewai>=0.1.0; extra == "crewai"
15
+ Dynamic: author
16
+ Dynamic: requires-python
17
+
18
+ # matrixads
19
+
20
+ > Python SDK for MatrixAds — Programmatic Conversational AI Ad Network & Monetization Engine.
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ pip install matrixads
26
+ ```
27
+
28
+ With LangChain support:
29
+ ```bash
30
+ pip install matrixads[langchain]
31
+ ```
32
+
33
+ With CrewAI support:
34
+ ```bash
35
+ pip install matrixads[crewai]
36
+ ```
37
+
38
+ ## Quick Start (Async)
39
+
40
+ ```python
41
+ import asyncio
42
+ from matrixads import MatrixAdsClient
43
+
44
+ async def main():
45
+ client = MatrixAdsClient(publisher_key="mtx_pk_live_your_publisher_key")
46
+
47
+ response = await client.amatch_ad("I need cloud hosting for Next.js")
48
+
49
+ if response.match and response.ad:
50
+ print(f"Matched Headline: {response.ad.headline}")
51
+ print(f"CTA Link: {response.ad.cta_url}")
52
+
53
+ # Fire view impression beacon
54
+ await client.areport_impression(response.impression_token)
55
+
56
+ asyncio.run(main())
57
+ ```
58
+
59
+ ## Quick Start (Sync)
60
+
61
+ ```python
62
+ from matrixads import MatrixAdsClient
63
+
64
+ client = MatrixAdsClient(publisher_key="mtx_pk_live_your_publisher_key")
65
+ response = client.match_ad("Best B2B CRM software")
66
+
67
+ if response.match and response.ad:
68
+ print(f"Sponsored: {response.ad.headline}")
69
+ ```
70
+
71
+ ## LangChain Integration
72
+
73
+ ```python
74
+ from matrixads.langchain import MatrixAdsAdTool
75
+
76
+ tool = MatrixAdsAdTool(publisher_key="mtx_pk_live_your_publisher_key")
77
+ result = tool._run("I need a cloud hosting database solution")
78
+ print(result)
79
+ ```
80
+
81
+ ## CrewAI Integration
82
+
83
+ ```python
84
+ from crewai import Agent
85
+ from matrixads.crewai import MatrixAdsCrewTool
86
+
87
+ ad_tool = MatrixAdsCrewTool(publisher_key="mtx_pk_live_your_publisher_key")
88
+
89
+ agent = Agent(
90
+ role="Tech Support Advisor",
91
+ goal="Answer software questions and include relevant sponsored solutions",
92
+ tools=[ad_tool]
93
+ )
94
+ ```
95
+
96
+ ## License
97
+
98
+ MIT © [MatrixAds](https://matrixads.io)
@@ -0,0 +1,81 @@
1
+ # matrixads
2
+
3
+ > Python SDK for MatrixAds — Programmatic Conversational AI Ad Network & Monetization Engine.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install matrixads
9
+ ```
10
+
11
+ With LangChain support:
12
+ ```bash
13
+ pip install matrixads[langchain]
14
+ ```
15
+
16
+ With CrewAI support:
17
+ ```bash
18
+ pip install matrixads[crewai]
19
+ ```
20
+
21
+ ## Quick Start (Async)
22
+
23
+ ```python
24
+ import asyncio
25
+ from matrixads import MatrixAdsClient
26
+
27
+ async def main():
28
+ client = MatrixAdsClient(publisher_key="mtx_pk_live_your_publisher_key")
29
+
30
+ response = await client.amatch_ad("I need cloud hosting for Next.js")
31
+
32
+ if response.match and response.ad:
33
+ print(f"Matched Headline: {response.ad.headline}")
34
+ print(f"CTA Link: {response.ad.cta_url}")
35
+
36
+ # Fire view impression beacon
37
+ await client.areport_impression(response.impression_token)
38
+
39
+ asyncio.run(main())
40
+ ```
41
+
42
+ ## Quick Start (Sync)
43
+
44
+ ```python
45
+ from matrixads import MatrixAdsClient
46
+
47
+ client = MatrixAdsClient(publisher_key="mtx_pk_live_your_publisher_key")
48
+ response = client.match_ad("Best B2B CRM software")
49
+
50
+ if response.match and response.ad:
51
+ print(f"Sponsored: {response.ad.headline}")
52
+ ```
53
+
54
+ ## LangChain Integration
55
+
56
+ ```python
57
+ from matrixads.langchain import MatrixAdsAdTool
58
+
59
+ tool = MatrixAdsAdTool(publisher_key="mtx_pk_live_your_publisher_key")
60
+ result = tool._run("I need a cloud hosting database solution")
61
+ print(result)
62
+ ```
63
+
64
+ ## CrewAI Integration
65
+
66
+ ```python
67
+ from crewai import Agent
68
+ from matrixads.crewai import MatrixAdsCrewTool
69
+
70
+ ad_tool = MatrixAdsCrewTool(publisher_key="mtx_pk_live_your_publisher_key")
71
+
72
+ agent = Agent(
73
+ role="Tech Support Advisor",
74
+ goal="Answer software questions and include relevant sponsored solutions",
75
+ tools=[ad_tool]
76
+ )
77
+ ```
78
+
79
+ ## License
80
+
81
+ MIT © [MatrixAds](https://matrixads.io)
@@ -0,0 +1,23 @@
1
+ from .client import (
2
+ MatrixAdsClient,
3
+ MatrixAdsAdResponse,
4
+ MatrixAdsAdPayload,
5
+ AdPromptClient,
6
+ AdPromptAdResponse,
7
+ AdPromptAdPayload,
8
+ SynapseClient,
9
+ SynapseAdResponse,
10
+ SynapseAdPayload,
11
+ )
12
+
13
+ __all__ = [
14
+ "MatrixAdsClient",
15
+ "MatrixAdsAdResponse",
16
+ "MatrixAdsAdPayload",
17
+ "AdPromptClient",
18
+ "AdPromptAdResponse",
19
+ "AdPromptAdPayload",
20
+ "SynapseClient",
21
+ "SynapseAdResponse",
22
+ "SynapseAdPayload",
23
+ ]
@@ -0,0 +1,126 @@
1
+ from typing import Optional, Dict, Any
2
+ import requests
3
+ import httpx
4
+ from pydantic import BaseModel
5
+
6
+ class MatrixAdsAdPayload(BaseModel):
7
+ id: str
8
+ format: str = "CARD"
9
+ headline: str
10
+ body_text: str
11
+ cta_url: str
12
+ merchant: Optional[str] = None
13
+ disclosure_label: Optional[str] = None
14
+ clearing_price_usd: Optional[str] = None
15
+ match_score: Optional[float] = None
16
+ impression_token: Optional[str] = None
17
+
18
+ AdPromptAdPayload = MatrixAdsAdPayload
19
+ SynapseAdPayload = MatrixAdsAdPayload
20
+
21
+ class MatrixAdsAdResponse(BaseModel):
22
+ match: bool
23
+ reason: Optional[str] = None
24
+ ad: Optional[MatrixAdsAdPayload] = None
25
+ impression_token: Optional[str] = None
26
+ latency_ms: Optional[float] = None
27
+
28
+ AdPromptAdResponse = MatrixAdsAdResponse
29
+ SynapseAdResponse = MatrixAdsAdResponse
30
+
31
+ class MatrixAdsClient:
32
+ """
33
+ Python SDK Client for MatrixAds Conversational AI Ad Network.
34
+ Supports both synchronous and asynchronous ad matching and impression reporting.
35
+ """
36
+ def __init__(self, publisher_key: str, endpoint_url: str = "https://matrixads.io/api/v1/ads/match", timeout: float = 3.0):
37
+ self.publisher_key = publisher_key
38
+ self.endpoint_url = endpoint_url
39
+ self.timeout = timeout
40
+
41
+ def match_ad(self, prompt: str, session_id: Optional[str] = None) -> MatrixAdsAdResponse:
42
+ """
43
+ Synchronous ad match request.
44
+ """
45
+ payload = {
46
+ "prompt": prompt,
47
+ "publisher_key": self.publisher_key,
48
+ }
49
+ if session_id:
50
+ payload["session_id"] = session_id
51
+
52
+ headers = {
53
+ "Content-Type": "application/json",
54
+ "X-Publisher-Key": self.publisher_key,
55
+ }
56
+
57
+ try:
58
+ resp = requests.post(self.endpoint_url, json=payload, headers=headers, timeout=self.timeout)
59
+ if resp.status_code != 200:
60
+ return MatrixAdsAdResponse(
61
+ match=False,
62
+ reason=f"HTTP {resp.status_code}: {resp.text}"
63
+ )
64
+ data = resp.json()
65
+ return MatrixAdsAdResponse(**data)
66
+ except Exception as e:
67
+ return MatrixAdsAdResponse(match=False, reason=str(e))
68
+
69
+ async def amatch_ad(self, prompt: str, session_id: Optional[str] = None) -> MatrixAdsAdResponse:
70
+ """
71
+ Asynchronous ad match request for async frameworks (FastAPI, asyncio, LangChain).
72
+ """
73
+ payload = {
74
+ "prompt": prompt,
75
+ "publisher_key": self.publisher_key,
76
+ }
77
+ if session_id:
78
+ payload["session_id"] = session_id
79
+
80
+ headers = {
81
+ "Content-Type": "application/json",
82
+ "X-Publisher-Key": self.publisher_key,
83
+ }
84
+
85
+ try:
86
+ async with httpx.AsyncClient(timeout=self.timeout) as client:
87
+ resp = await client.post(self.endpoint_url, json=payload, headers=headers)
88
+ if resp.status_code != 200:
89
+ return MatrixAdsAdResponse(
90
+ match=False,
91
+ reason=f"HTTP {resp.status_code}: {resp.text}"
92
+ )
93
+ data = resp.json()
94
+ return MatrixAdsAdResponse(**data)
95
+ except Exception as e:
96
+ return MatrixAdsAdResponse(match=False, reason=str(e))
97
+
98
+ def report_impression(self, impression_token: str) -> bool:
99
+ """
100
+ Report view impression beacon synchronously.
101
+ """
102
+ if not impression_token:
103
+ return False
104
+ try:
105
+ track_url = self.endpoint_url.replace("/ads/match", "/track/impression")
106
+ resp = requests.post(f"{track_url}?token={impression_token}", timeout=self.timeout)
107
+ return resp.status_code == 200
108
+ except Exception:
109
+ return False
110
+
111
+ async def areport_impression(self, impression_token: str) -> bool:
112
+ """
113
+ Report view impression beacon asynchronously.
114
+ """
115
+ if not impression_token:
116
+ return False
117
+ try:
118
+ track_url = self.endpoint_url.replace("/ads/match", "/track/impression")
119
+ async with httpx.AsyncClient(timeout=self.timeout) as client:
120
+ resp = await client.post(f"{track_url}?token={impression_token}")
121
+ return resp.status_code == 200
122
+ except Exception:
123
+ return False
124
+
125
+ AdPromptClient = MatrixAdsClient
126
+ SynapseClient = MatrixAdsClient
@@ -0,0 +1,26 @@
1
+ from typing import Optional
2
+ from pydantic import BaseModel
3
+ from .client import MatrixAdsClient
4
+
5
+ class MatrixAdsCrewTool(BaseModel):
6
+ """
7
+ CrewAI Tool wrapper for MatrixAds contextual monetization.
8
+ Injects sponsored recommendation cards into autonomous CrewAI agent outputs.
9
+ """
10
+ name: str = "matrixads_ad_matcher"
11
+ description: str = "Retrieves contextual non-intrusive sponsored recommendation cards for user queries."
12
+ client: Optional[MatrixAdsClient] = None
13
+
14
+ def __init__(self, publisher_key: str, endpoint_url: str = "https://matrixads.io/api/v1/ads/match", **data):
15
+ super().__init__(**data)
16
+ self.client = MatrixAdsClient(publisher_key=publisher_key, endpoint_url=endpoint_url)
17
+
18
+ def run(self, query: str) -> str:
19
+ if not self.client:
20
+ return "MatrixAds client uninitialized."
21
+ res = self.client.match_ad(query)
22
+ if res.match and res.ad:
23
+ return f"[Sponsored Recommendation - {res.ad.disclosure_label or 'Ad'}]: {res.ad.headline} - {res.ad.body_text} ({res.ad.cta_url})"
24
+ return "No relevant sponsored ad matched."
25
+
26
+ AdPromptCrewTool = MatrixAdsCrewTool
@@ -0,0 +1,26 @@
1
+ from typing import Optional
2
+ from pydantic import BaseModel
3
+ from .client import MatrixAdsClient
4
+
5
+ class MatrixAdsAdTool(BaseModel):
6
+ """
7
+ Tool wrapper for integrating MatrixAds with LangChain or CrewAI agents.
8
+ """
9
+ name: str = "matrixads_ad_matcher"
10
+ description: str = "Retrieves contextual non-intrusive sponsored recommendation cards for user queries."
11
+ client: Optional[MatrixAdsClient] = None
12
+
13
+ def __init__(self, publisher_key: str, endpoint_url: str = "https://matrixads.io/api/v1/ads/match", **data):
14
+ super().__init__(**data)
15
+ self.client = MatrixAdsClient(publisher_key=publisher_key, endpoint_url=endpoint_url)
16
+
17
+ def _run(self, query: str) -> str:
18
+ if not self.client:
19
+ return "MatrixAds client uninitialized."
20
+ res = self.client.match_ad(query)
21
+ if res.match and res.ad:
22
+ return f"[Sponsored by {res.ad.disclosure_label or 'Ad'}]: {res.ad.headline} - {res.ad.body_text} ({res.ad.cta_url})"
23
+ return "No relevant sponsored ad matched."
24
+
25
+ AdPromptAdTool = MatrixAdsAdTool
26
+ SynapseAdTool = MatrixAdsAdTool
@@ -0,0 +1,98 @@
1
+ Metadata-Version: 2.4
2
+ Name: matrixads
3
+ Version: 1.0.0
4
+ Summary: Python SDK for MatrixAds Conversational AI Monetization and Ad Network
5
+ Author: MatrixAds Team
6
+ Author-email: MatrixAds Team <sdk@matrixads.io>
7
+ Requires-Python: >=3.9
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: httpx>=0.24.0
10
+ Requires-Dist: pydantic>=2.0.0
11
+ Provides-Extra: langchain
12
+ Requires-Dist: langchain-core>=0.1.0; extra == "langchain"
13
+ Provides-Extra: crewai
14
+ Requires-Dist: crewai>=0.1.0; extra == "crewai"
15
+ Dynamic: author
16
+ Dynamic: requires-python
17
+
18
+ # matrixads
19
+
20
+ > Python SDK for MatrixAds — Programmatic Conversational AI Ad Network & Monetization Engine.
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ pip install matrixads
26
+ ```
27
+
28
+ With LangChain support:
29
+ ```bash
30
+ pip install matrixads[langchain]
31
+ ```
32
+
33
+ With CrewAI support:
34
+ ```bash
35
+ pip install matrixads[crewai]
36
+ ```
37
+
38
+ ## Quick Start (Async)
39
+
40
+ ```python
41
+ import asyncio
42
+ from matrixads import MatrixAdsClient
43
+
44
+ async def main():
45
+ client = MatrixAdsClient(publisher_key="mtx_pk_live_your_publisher_key")
46
+
47
+ response = await client.amatch_ad("I need cloud hosting for Next.js")
48
+
49
+ if response.match and response.ad:
50
+ print(f"Matched Headline: {response.ad.headline}")
51
+ print(f"CTA Link: {response.ad.cta_url}")
52
+
53
+ # Fire view impression beacon
54
+ await client.areport_impression(response.impression_token)
55
+
56
+ asyncio.run(main())
57
+ ```
58
+
59
+ ## Quick Start (Sync)
60
+
61
+ ```python
62
+ from matrixads import MatrixAdsClient
63
+
64
+ client = MatrixAdsClient(publisher_key="mtx_pk_live_your_publisher_key")
65
+ response = client.match_ad("Best B2B CRM software")
66
+
67
+ if response.match and response.ad:
68
+ print(f"Sponsored: {response.ad.headline}")
69
+ ```
70
+
71
+ ## LangChain Integration
72
+
73
+ ```python
74
+ from matrixads.langchain import MatrixAdsAdTool
75
+
76
+ tool = MatrixAdsAdTool(publisher_key="mtx_pk_live_your_publisher_key")
77
+ result = tool._run("I need a cloud hosting database solution")
78
+ print(result)
79
+ ```
80
+
81
+ ## CrewAI Integration
82
+
83
+ ```python
84
+ from crewai import Agent
85
+ from matrixads.crewai import MatrixAdsCrewTool
86
+
87
+ ad_tool = MatrixAdsCrewTool(publisher_key="mtx_pk_live_your_publisher_key")
88
+
89
+ agent = Agent(
90
+ role="Tech Support Advisor",
91
+ goal="Answer software questions and include relevant sponsored solutions",
92
+ tools=[ad_tool]
93
+ )
94
+ ```
95
+
96
+ ## License
97
+
98
+ MIT © [MatrixAds](https://matrixads.io)
@@ -0,0 +1,15 @@
1
+ README.md
2
+ pyproject.toml
3
+ setup.py
4
+ matrixads/__init__.py
5
+ matrixads/client.py
6
+ matrixads/crewai.py
7
+ matrixads/langchain.py
8
+ matrixads.egg-info/PKG-INFO
9
+ matrixads.egg-info/SOURCES.txt
10
+ matrixads.egg-info/dependency_links.txt
11
+ matrixads.egg-info/requires.txt
12
+ matrixads.egg-info/top_level.txt
13
+ synapseads/__init__.py
14
+ synapseads/client.py
15
+ synapseads/langchain.py
@@ -0,0 +1,8 @@
1
+ httpx>=0.24.0
2
+ pydantic>=2.0.0
3
+
4
+ [crewai]
5
+ crewai>=0.1.0
6
+
7
+ [langchain]
8
+ langchain-core>=0.1.0
@@ -0,0 +1,2 @@
1
+ matrixads
2
+ synapseads
@@ -0,0 +1,20 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "matrixads"
7
+ version = "1.0.0"
8
+ description = "Python SDK for MatrixAds Conversational AI Monetization and Ad Network"
9
+ authors = [{ name = "MatrixAds Team", email = "sdk@matrixads.io" }]
10
+
11
+ readme = "README.md"
12
+ requires-python = ">=3.9"
13
+ dependencies = [
14
+ "httpx>=0.24.0",
15
+ "pydantic>=2.0.0",
16
+ ]
17
+
18
+ [project.optional-dependencies]
19
+ langchain = ["langchain-core>=0.1.0"]
20
+ crewai = ["crewai>=0.1.0"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,21 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="matrixads",
5
+ version="1.0.0",
6
+ description="Python SDK for MatrixAds Conversational AI Monetization and Ad Network",
7
+ long_description=open("README.md").read(),
8
+ long_description_content_type="text/markdown",
9
+ author="MatrixAds Team",
10
+ author_email="sdk@matrixads.io",
11
+ packages=find_packages(),
12
+ install_requires=[
13
+ "httpx>=0.24.0",
14
+ "pydantic>=2.0.0",
15
+ ],
16
+ extras_require={
17
+ "langchain": ["langchain-core>=0.1.0"],
18
+ "crewai": ["crewai>=0.1.0"],
19
+ },
20
+ python_requires=">=3.9",
21
+ )
@@ -0,0 +1,3 @@
1
+ from .client import SynapseClient, SynapseAdResponse, SynapseAdPayload
2
+
3
+ __all__ = ["SynapseClient", "SynapseAdResponse", "SynapseAdPayload"]
@@ -0,0 +1,74 @@
1
+ import httpx
2
+ from typing import Optional, Dict, Any
3
+ from pydantic import BaseModel
4
+
5
+ class SynapseAdPayload(BaseModel):
6
+ id: str
7
+ format: str
8
+ headline: str
9
+ body_text: str
10
+ cta_url: str
11
+ disclosure_label: str = "Sponsored"
12
+ clearing_price_usd: str
13
+ match_score: float
14
+
15
+ class SynapseAdResponse(BaseModel):
16
+ match: bool
17
+ reason: Optional[str] = None
18
+ ad: Optional[SynapseAdPayload] = None
19
+ latency_ms: Optional[float] = None
20
+
21
+ class SynapseClient:
22
+ """
23
+ Python SDK Client for AdPrompt Conversational Ad Network.
24
+ Supports both synchronous and asynchronous operations.
25
+ """
26
+ def __init__(
27
+ self,
28
+ publisher_key: str,
29
+ endpoint_url: str = "http://localhost:3000/api/v1/ads/match",
30
+ session_id: Optional[str] = None,
31
+ geo: Optional[str] = None,
32
+ ):
33
+ self.publisher_key = publisher_key
34
+ self.endpoint_url = endpoint_url
35
+ self.session_id = session_id
36
+ self.geo = geo
37
+
38
+ def match_ad(self, prompt: str) -> SynapseAdResponse:
39
+ """
40
+ Synchronous ad matching request for LLM pipelines and agent frameworks.
41
+ """
42
+ payload = {
43
+ "prompt": prompt,
44
+ "publisher_key": self.publisher_key,
45
+ "session_id": self.session_id,
46
+ "geo": self.geo,
47
+ }
48
+ with httpx.Client(timeout=3.0) as client:
49
+ resp = client.post(self.endpoint_url, json=payload)
50
+ if resp.status_code != 200:
51
+ return SynapseAdResponse(
52
+ match=False,
53
+ reason=f"HTTP {resp.status_code}: {resp.text}"
54
+ )
55
+ return SynapseAdResponse(**resp.json())
56
+
57
+ async def amatch_ad(self, prompt: str) -> SynapseAdResponse:
58
+ """
59
+ Asynchronous ad matching request.
60
+ """
61
+ payload = {
62
+ "prompt": prompt,
63
+ "publisher_key": self.publisher_key,
64
+ "session_id": self.session_id,
65
+ "geo": self.geo,
66
+ }
67
+ async with httpx.AsyncClient(timeout=3.0) as client:
68
+ resp = await client.post(self.endpoint_url, json=payload)
69
+ if resp.status_code != 200:
70
+ return SynapseAdResponse(
71
+ match=False,
72
+ reason=f"HTTP {resp.status_code}: {resp.text}"
73
+ )
74
+ return SynapseAdResponse(**resp.json())
@@ -0,0 +1,39 @@
1
+ from typing import Optional, Type
2
+ from pydantic import BaseModel, Field
3
+ from .client import SynapseClient
4
+
5
+ class AdMatchInput(BaseModel):
6
+ user_prompt: str = Field(description="The user's query or conversation prompt to evaluate for monetization ads.")
7
+
8
+ class SynapseAdTool:
9
+ """
10
+ Tool wrapper for integrating AdPrompt with LangChain or CrewAI agents.
11
+ """
12
+ name: str = "synapse_ad_matcher"
13
+ description: str = "Monetize user queries by fetching relevant contextual sponsored cards or recommendations."
14
+ args_schema: Type[BaseModel] = AdMatchInput
15
+
16
+ def __init__(self, publisher_key: str, endpoint_url: str = "http://localhost:3000/api/v1/ads/match"):
17
+ self.client = SynapseClient(publisher_key=publisher_key, endpoint_url=endpoint_url)
18
+
19
+ def _run(self, user_prompt: str) -> str:
20
+ response = self.client.match_ad(user_prompt)
21
+ if not response.match or not response.ad:
22
+ return "No sponsored content matched for this query."
23
+
24
+ ad = response.ad
25
+ return (
26
+ f"[{ad.disclosure_label}] {ad.headline}: {ad.body_text}\n"
27
+ f"Learn more: {ad.cta_url}"
28
+ )
29
+
30
+ async def _arun(self, user_prompt: str) -> str:
31
+ response = await self.client.amatch_ad(user_prompt)
32
+ if not response.match or not response.ad:
33
+ return "No sponsored content matched for this query."
34
+
35
+ ad = response.ad
36
+ return (
37
+ f"[{ad.disclosure_label}] {ad.headline}: {ad.body_text}\n"
38
+ f"Learn more: {ad.cta_url}"
39
+ )