flock-core 0.4.533__py3-none-any.whl → 0.4.534__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.

Potentially problematic release.


This version of flock-core might be problematic. Click here for more details.

flock/tools/web_tools.py CHANGED
@@ -19,7 +19,7 @@ def web_search_tavily(query: str):
19
19
  raise
20
20
  else:
21
21
  raise ImportError(
22
- "Optional tool dependencies not installed. Install with 'pip install flock-core[tools]'."
22
+ "Optional tool dependencies not installed. Install with 'pip install flock-mcp[all]'."
23
23
  )
24
24
 
25
25
 
@@ -28,8 +28,8 @@ def web_search_duckduckgo(
28
28
  keywords: str, search_type: Literal["news", "web"] = "web"
29
29
  ):
30
30
  try:
31
- if importlib.util.find_spec("duckduckgo_search") is not None:
32
- from duckduckgo_search import DDGS
31
+ if importlib.util.find_spec("ddgs") is not None:
32
+ from ddgs import DDGS
33
33
 
34
34
  if search_type == "news":
35
35
  response = DDGS().news(keywords)
@@ -39,7 +39,7 @@ def web_search_duckduckgo(
39
39
  return response
40
40
  else:
41
41
  raise ImportError(
42
- "Optional tool dependencies not installed. Install with 'pip install flock-core[tools]'."
42
+ "Optional tool dependencies not installed. Install with 'pip install flock-mcp[all]'."
43
43
  )
44
44
  except Exception:
45
45
  raise
@@ -86,5 +86,7 @@ def web_content_as_markdown(url: str) -> str:
86
86
  raise
87
87
  else:
88
88
  raise ImportError(
89
- "Optional tool dependencies not installed. Install with 'pip install flock-core[tools]'."
89
+ "Optional tool dependencies not installed. Install with 'pip install flock-mcp[all]'."
90
90
  )
91
+
92
+
@@ -8,12 +8,18 @@ from mcp.server.fastmcp import FastMCP
8
8
  mcp = FastMCP("ZendeskTools")
9
9
 
10
10
 
11
- ZENDESK_BEARER_TOKEN = os.getenv("ZENDESK_BEARER_TOKEN")
12
11
 
13
- HEADERS = {
14
- "Authorization": f"Bearer {ZENDESK_BEARER_TOKEN}",
15
- "Accept": "application/json",
16
- }
12
+
13
+ def _get_headers() -> dict:
14
+ token = os.getenv("ZENDESK_BEARER_TOKEN")
15
+ if not token:
16
+ raise ValueError(
17
+ "ZENDESK_BEARER_TOKEN environment variable is not set"
18
+ )
19
+ return {
20
+ "Authorization": f"Bearer {token}",
21
+ "Accept": "application/json",
22
+ }
17
23
 
18
24
 
19
25
  @mcp.tool()
@@ -23,7 +29,7 @@ def zendesk_get_tickets(number_of_tickets: int = 10) -> list[dict]:
23
29
  BASE_URL = f"https://{ZENDESK_SUBDOMAIN}.zendesk.com"
24
30
  url = f"{BASE_URL}/api/v2/tickets.json"
25
31
  all_tickets = []
26
- with httpx.Client(headers=HEADERS, timeout=30.0) as client:
32
+ with httpx.Client(headers=_get_headers(), timeout=30.0) as client:
27
33
  while url and len(all_tickets) < number_of_tickets:
28
34
  response = client.get(url)
29
35
  response.raise_for_status()
@@ -41,7 +47,7 @@ def zendesk_get_ticket_by_id(ticket_id: str) -> dict:
41
47
  ZENDESK_SUBDOMAIN = os.getenv("ZENDESK_SUBDOMAIN_TICKET")
42
48
  BASE_URL = f"https://{ZENDESK_SUBDOMAIN}.zendesk.com"
43
49
  url = f"{BASE_URL}/api/v2/tickets/{ticket_id}"
44
- with httpx.Client(headers=HEADERS, timeout=30.0) as client:
50
+ with httpx.Client(headers=_get_headers(), timeout=30.0) as client:
45
51
  response = client.get(url)
46
52
  response.raise_for_status()
47
53
  return response.json()["ticket"]
@@ -52,7 +58,7 @@ def zendesk_get_comments_by_ticket_id(ticket_id: str) -> list[dict]:
52
58
  ZENDESK_SUBDOMAIN = os.getenv("ZENDESK_SUBDOMAIN_TICKET")
53
59
  BASE_URL = f"https://{ZENDESK_SUBDOMAIN}.zendesk.com"
54
60
  url = f"{BASE_URL}/api/v2/tickets/{ticket_id}/comments"
55
- with httpx.Client(headers=HEADERS, timeout=30.0) as client:
61
+ with httpx.Client(headers=_get_headers(), timeout=30.0) as client:
56
62
  response = client.get(url)
57
63
  response.raise_for_status()
58
64
  return response.json()["comments"]
@@ -66,7 +72,7 @@ def zendesk_get_article_by_id(article_id: str) -> dict:
66
72
  url = (
67
73
  f"{BASE_URL}/api/v2/help_center/{ZENDESK_LOCALE}/articles/{article_id}"
68
74
  )
69
- with httpx.Client(headers=HEADERS, timeout=30.0) as client:
75
+ with httpx.Client(headers=_get_headers(), timeout=30.0) as client:
70
76
  response = client.get(url)
71
77
  response.raise_for_status()
72
78
  return response.json()["article"]
@@ -78,15 +84,14 @@ def zendesk_get_articles() -> list[dict]:
78
84
  ZENDESK_SUBDOMAIN = os.getenv("ZENDESK_SUBDOMAIN_ARTICLE")
79
85
  BASE_URL = f"https://{ZENDESK_SUBDOMAIN}.zendesk.com"
80
86
  url = f"{BASE_URL}/api/v2/help_center/{ZENDESK_LOCALE}/articles.json"
81
- with httpx.Client(headers=HEADERS, timeout=30.0) as client:
87
+ with httpx.Client(headers=_get_headers(), timeout=30.0) as client:
82
88
  response = client.get(url)
83
89
  response.raise_for_status()
84
90
  return response.json()["articles"]
85
91
 
86
- @mcp.tool()
92
+ @mcp.tool()
87
93
  def zendesk_get_articles_count() -> int:
88
- """
89
- Count every Help-Center article in the configured locale.
94
+ """Count every Help-Center article in the configured locale.
90
95
 
91
96
  Uses cursor pagination (page[size]=100) because it’s faster and
92
97
  has no 10 000-record ceiling. Falls back to offset pagination
@@ -101,7 +106,7 @@ def zendesk_get_articles_count() -> int:
101
106
  )
102
107
 
103
108
  total = 0
104
- with httpx.Client(headers=HEADERS, timeout=30.0) as client:
109
+ with httpx.Client(headers=_get_headers(), timeout=30.0) as client:
105
110
  while url:
106
111
  resp = client.get(url)
107
112
  resp.raise_for_status()
@@ -136,11 +141,36 @@ def zendesk_search_articles(query: str) -> list[dict]:
136
141
  "sort_order": "desc",
137
142
  }
138
143
 
139
- with httpx.Client(headers=HEADERS, timeout=30.0) as client:
144
+ with httpx.Client(headers=_get_headers(), timeout=30.0) as client:
140
145
  response = client.get(url, params=params)
141
146
  response.raise_for_status()
142
147
  return response.json().get("results", [])
143
148
 
149
+ def zendesk_add_comment_to_ticket(ticket_id: str, comment_body: str, public: bool = True) -> dict:
150
+ """Add a comment to a Zendesk ticket.
151
+
152
+ Updates the ticket with a new comment via Zendesk Ticketing API:
153
+ PUT /api/v2/tickets/{ticket_id}.json
154
+ """
155
+ ZENDESK_SUBDOMAIN = os.getenv("ZENDESK_SUBDOMAIN_TICKET")
156
+ BASE_URL = f"https://{ZENDESK_SUBDOMAIN}.zendesk.com"
157
+ url = f"{BASE_URL}/api/v2/tickets/{ticket_id}.json"
158
+
159
+ payload = {
160
+ "ticket": {
161
+ "comment": {
162
+ "body": comment_body,
163
+ "public": public,
164
+ }
165
+ }
166
+ }
167
+
168
+ import httpx
169
+ with httpx.Client(headers=_get_headers(), timeout=30.0) as client:
170
+ response = client.put(url, json=payload)
171
+ response.raise_for_status()
172
+ return response.json()["ticket"]
173
+
144
174
 
145
175
  if __name__ == "__main__":
146
176
  transport = os.getenv("ZENDESK_MCP_TRANSPORT", "stdio")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flock-core
3
- Version: 0.4.533
3
+ Version: 0.4.534
4
4
  Summary: Declarative LLM Orchestration at Scale
5
5
  Author-email: Andre Ratzenberger <andre.ratzenberger@whiteduck.de>
6
6
  License-File: LICENSE
@@ -58,8 +58,8 @@ Requires-Dist: azure-search-documents>=11.5.2; extra == 'all'
58
58
  Requires-Dist: azure-storage-blob>=12.25.1; extra == 'all'
59
59
  Requires-Dist: chromadb>=0.6.3; extra == 'all'
60
60
  Requires-Dist: datasets>=3.2.0; extra == 'all'
61
+ Requires-Dist: ddgs>=9.2.0; extra == 'all'
61
62
  Requires-Dist: docling>=2.34.0; extra == 'all'
62
- Requires-Dist: duckduckgo-search>=7.3.2; extra == 'all'
63
63
  Requires-Dist: markdownify>=0.14.1; extra == 'all'
64
64
  Requires-Dist: matplotlib>=3.10.0; extra == 'all'
65
65
  Requires-Dist: mem0ai[graph]>=0.1.101; extra == 'all'
@@ -72,9 +72,9 @@ Provides-Extra: all-tools
72
72
  Requires-Dist: azure-identity>=1.23.0; extra == 'all-tools'
73
73
  Requires-Dist: azure-search-documents>=11.5.2; extra == 'all-tools'
74
74
  Requires-Dist: azure-storage-blob>=12.25.1; extra == 'all-tools'
75
+ Requires-Dist: ddgs>=9.2.0; extra == 'all-tools'
75
76
  Requires-Dist: docker>=7.1.0; extra == 'all-tools'
76
77
  Requires-Dist: docling>=2.34.0; extra == 'all-tools'
77
- Requires-Dist: duckduckgo-search>=7.3.2; extra == 'all-tools'
78
78
  Requires-Dist: markdownify>=0.14.1; extra == 'all-tools'
79
79
  Requires-Dist: nltk>=3.9.1; extra == 'all-tools'
80
80
  Requires-Dist: tavily-python>=0.5.0; extra == 'all-tools'
@@ -83,8 +83,7 @@ Requires-Dist: azure-identity>=1.23.0; extra == 'azure-tools'
83
83
  Requires-Dist: azure-search-documents>=11.5.2; extra == 'azure-tools'
84
84
  Requires-Dist: azure-storage-blob>=12.25.1; extra == 'azure-tools'
85
85
  Provides-Extra: basic-tools
86
- Requires-Dist: docling>=2.34.0; extra == 'basic-tools'
87
- Requires-Dist: duckduckgo-search>=7.3.2; extra == 'basic-tools'
86
+ Requires-Dist: ddgs>=9.2.0; extra == 'basic-tools'
88
87
  Requires-Dist: markdownify>=0.14.1; extra == 'basic-tools'
89
88
  Requires-Dist: tavily-python>=0.5.0; extra == 'basic-tools'
90
89
  Provides-Extra: code-tools
@@ -487,8 +487,8 @@ flock/tools/github_tools.py,sha256=HH47-4K3HL6tRJhZhUttWDo2aloP9Hs12wRC_f_-Vkc,5
487
487
  flock/tools/markdown_tools.py,sha256=94fjGAJ5DEutoioD0ke-YRbxF6IWJQKuPVBLkNqdBo4,6345
488
488
  flock/tools/system_tools.py,sha256=IUB8MiSxtQH5ZfTGOck3vl4TKva8m1lfU4-W5D5b-4w,202
489
489
  flock/tools/text_tools.py,sha256=mMQ8tkyYDxIorqqzl9ccGyWYjrSynYiYFIeP9qypfdg,22491
490
- flock/tools/web_tools.py,sha256=Wl3qO5lKq4PYtmYahgeFGBQ8tDC0uKY4k9A1Zn-MqFw,2588
491
- flock/tools/zendesk_tools.py,sha256=e7KMfHVl7wGbstwdz9CvoChyuoZfpS9n4TEtvrxawgI,5162
490
+ flock/tools/web_tools.py,sha256=h44L5rknxGw1mVnFTYO-z0xwUr5ctOvMiJBIfeq56UE,2555
491
+ flock/tools/zendesk_tools.py,sha256=aWXAjfwcl2AL5gRoNO4KPbXQbaKr35jDWC46zt2TsQk,6156
492
492
  flock/webapp/__init__.py,sha256=YtRbbyciN3Z2oMB9fdXZuvM3e49R8m2mY5qHLDoapRA,37
493
493
  flock/webapp/run.py,sha256=btKVwIqrFg3FhLRuj2RN_fazwaFat3Ue5yiFiIg60rQ,9054
494
494
  flock/webapp/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -563,8 +563,8 @@ flock/workflow/agent_execution_activity.py,sha256=hLqWEWsxwTgjsE9wvBejf3pN2TdIfU
563
563
  flock/workflow/flock_workflow.py,sha256=iSUF_soFvWar0ffpkzE4irkDZRx0p4HnwmEBi_Ne2sY,9666
564
564
  flock/workflow/temporal_config.py,sha256=3_8O7SDEjMsSMXsWJBfnb6XTp0TFaz39uyzSlMTSF_I,3988
565
565
  flock/workflow/temporal_setup.py,sha256=YIHnSBntzOchHfMSh8hoLeNXrz3B1UbR14YrR6soM7A,1606
566
- flock_core-0.4.533.dist-info/METADATA,sha256=QywKdW1rEI93QL09X4r5vvo9OXJBwuEJZh52pl48hf4,22894
567
- flock_core-0.4.533.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
568
- flock_core-0.4.533.dist-info/entry_points.txt,sha256=rWaS5KSpkTmWySURGFZk6PhbJ87TmvcFQDi2uzjlagQ,37
569
- flock_core-0.4.533.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
570
- flock_core-0.4.533.dist-info/RECORD,,
566
+ flock_core-0.4.534.dist-info/METADATA,sha256=IqO9_ei3jgBQtqkGa8aQJBwJBQ3TrSVpUY00IyFJSkQ,22800
567
+ flock_core-0.4.534.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
568
+ flock_core-0.4.534.dist-info/entry_points.txt,sha256=rWaS5KSpkTmWySURGFZk6PhbJ87TmvcFQDi2uzjlagQ,37
569
+ flock_core-0.4.534.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
570
+ flock_core-0.4.534.dist-info/RECORD,,