agentic-fabriq-sdk 0.1.22__py3-none-any.whl → 0.1.24__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 agentic-fabriq-sdk might be problematic. Click here for more details.

@@ -18,17 +18,21 @@ app = typer.Typer(help="Manage registered applications")
18
18
  console = Console()
19
19
 
20
20
 
21
- @app.command("create")
22
- def create_application(
21
+ @app.command("register")
22
+ def register_application(
23
23
  app_id: str = typer.Option(..., "--app-id", help="Application identifier (no spaces)"),
24
24
  connections: str = typer.Option(..., "--connections", help="Tool connections (format: 'tool1:conn-id,tool2:conn-id')"),
25
25
  scopes: Optional[str] = typer.Option(None, "--scopes", help="Scopes (format: 'scope1,scope2,scope3')"),
26
26
  ):
27
27
  """
28
- Register a new application.
28
+ Step 1: Register a new application (returns activation token).
29
+
30
+ This registers your application and returns a temporary activation token
31
+ that expires in 1 hour. Use this token with 'afctl applications connect'
32
+ to complete the setup and save credentials locally.
29
33
 
30
34
  Example:
31
- afctl applications create \\
35
+ afctl applications register \\
32
36
  --app-id my-slack-bot \\
33
37
  --connections slack:my-slack-conn,github:my-github-conn \\
34
38
  --scopes slack:read,slack:write,github:repo:read
@@ -58,10 +62,10 @@ def create_application(
58
62
  for conn_id in tool_connections:
59
63
  tool_connections[conn_id] = scope_list
60
64
 
61
- # Make API request
65
+ # Make API request to register (returns activation token)
62
66
  try:
63
67
  response = httpx.post(
64
- f"{config.gateway_url}/api/v1/applications",
68
+ f"{config.gateway_url}/api/v1/applications/register",
65
69
  headers={"Authorization": f"Bearer {config.access_token}"},
66
70
  json={
67
71
  "app_id": app_id,
@@ -83,6 +87,76 @@ def create_application(
83
87
 
84
88
  data = response.json()
85
89
 
90
+ # Display activation token
91
+ console.print("\n✅ Application registered successfully!", style="green bold")
92
+ console.print(f"\n📋 App ID: {data['app_id']}", style="cyan")
93
+ console.print(f"\n🔑 Activation Token:", style="yellow bold")
94
+ console.print(f" {data['activation_token']}", style="yellow")
95
+ console.print(f"\n⏰ Token expires: {data['expires_at'][:19]} UTC", style="white")
96
+ console.print(f" (Valid for 1 hour)", style="dim")
97
+
98
+ console.print("\n📋 Next Steps:", style="cyan bold")
99
+ console.print(f" 1. Navigate to your project directory", style="white")
100
+ console.print(f" 2. Make sure you're authenticated: afctl auth login", style="white")
101
+ console.print(f" 3. Run the connect command:", style="white")
102
+ console.print(f"\n afctl applications connect {app_id} --token <activation-token>", style="green")
103
+ console.print(f"\n⚠️ Save the activation token! It expires in 1 hour and can only be used once.", style="yellow bold")
104
+
105
+ except httpx.HTTPError as e:
106
+ console.print(f"❌ Network error: {e}", style="red")
107
+ raise typer.Exit(1)
108
+
109
+
110
+ @app.command("connect")
111
+ def connect_application(
112
+ app_id: str = typer.Argument(..., help="Application identifier"),
113
+ token: str = typer.Option(..., "--token", help="Activation token from registration"),
114
+ ):
115
+ """
116
+ Step 2: Connect/activate an application (saves credentials locally).
117
+
118
+ Uses the activation token from 'afctl applications register' to activate
119
+ the application and save credentials to the current directory.
120
+
121
+ Example:
122
+ afctl applications connect my-slack-bot --token <activation-token>
123
+ """
124
+ config = get_config()
125
+
126
+ if not config.is_authenticated():
127
+ console.print("❌ Not authenticated. Run 'afctl auth login' first.", style="red")
128
+ raise typer.Exit(1)
129
+
130
+ # Make API request to activate (returns final credentials)
131
+ try:
132
+ response = httpx.post(
133
+ f"{config.gateway_url}/api/v1/applications/activate",
134
+ headers={"Authorization": f"Bearer {config.access_token}"},
135
+ json={"activation_token": token},
136
+ timeout=30.0
137
+ )
138
+
139
+ if response.status_code == 404:
140
+ console.print("❌ Invalid or expired activation token", style="red")
141
+ console.print(" The token may have expired (valid for 1 hour) or was already used.", style="yellow")
142
+ console.print(" Register again with 'afctl applications register'", style="white")
143
+ raise typer.Exit(1)
144
+ elif response.status_code == 403:
145
+ console.print("❌ This activation token does not belong to you", style="red")
146
+ raise typer.Exit(1)
147
+ elif response.status_code != 201:
148
+ error_detail = response.text
149
+ try:
150
+ error_json = response.json()
151
+ error_detail = error_json.get("detail", response.text)
152
+ except:
153
+ pass
154
+
155
+ console.print(f"❌ Failed to activate application: {error_detail}", style="red")
156
+ raise typer.Exit(1)
157
+
158
+ data = response.json()
159
+
86
160
  # Save credentials locally
87
161
  from af_sdk import save_application_config
88
162
 
@@ -99,7 +173,7 @@ def create_application(
99
173
  app_file = save_application_config(data["app_id"], app_config)
100
174
 
101
175
  # Display success
102
- console.print("\n✅ Application registered successfully!", style="green bold")
176
+ console.print("\n✅ Application activated successfully!", style="green bold")
103
177
  console.print(f"\n📋 App ID: {data['app_id']}", style="cyan")
104
178
  console.print(f"🔑 Secret Key: {data['secret_key']}", style="yellow")
105
179
  console.print(f"\n💾 Credentials saved to: {app_file}", style="green")
af_cli/commands/tools.py CHANGED
@@ -14,14 +14,86 @@ app = typer.Typer(help="Tool management commands")
14
14
  @app.command()
15
15
  def list(
16
16
  format: str = typer.Option("table", "--format", help="Output format"),
17
+ page: int = typer.Option(1, "--page", help="Page number (starts from 1)", min=1),
18
+ page_size: int = typer.Option(20, "--page-size", help="Number of items per page (1-100)", min=1, max=100),
19
+ search: str = typer.Option(None, "--search", help="Search query (searches tool IDs from registry like 'gmail', 'slack', and user connection names)"),
20
+ tool_filter: str = typer.Option(None, "--tool", help="Filter by tool type from registry (e.g., 'gmail' shows Gmail connections, 'google' shows all Google tools)"),
17
21
  ):
18
- """List your tool connections (configured and connected tools)."""
22
+ """List your tool connections (configured and connected tools).
23
+
24
+ The command supports pagination and search to help you navigate large numbers
25
+ of connections efficiently.
26
+
27
+ Examples:
28
+ # List all connections (default: page 1, 20 per page)
29
+ afctl tools list
30
+
31
+ # List first page with 10 items per page
32
+ afctl tools list --page 1 --page-size 10
33
+
34
+ # Search for tool types (exact match against registry - shows all connections of that type)
35
+ afctl tools list --search gmail # Shows all Gmail connections
36
+ afctl tools list --search google # Shows all Google Workspace tools
37
+ afctl tools list --search slack # Shows all Slack connections
38
+ afctl tools list --search notion # Shows all Notion connections
39
+ afctl tools list --search github # Shows all GitHub connections
40
+
41
+ # Filter by tool type (shows all connections of that tool)
42
+ afctl tools list --tool gmail # Shows all Gmail connections
43
+ afctl tools list --tool google # Shows all Google Workspace tools
44
+ afctl tools list --tool slack # Shows all Slack connections
45
+
46
+ # Search and paginate together
47
+ afctl tools list --search google --page 1 --page-size 5
48
+
49
+ # Find connections by name (fallback search)
50
+ afctl tools list --search work # Connections with "work" in name
51
+ afctl tools list --search personal # Connections with "personal" in name
52
+
53
+ # Combined search and filtering (AND logic - must match both)
54
+ afctl tools list --tool google --search gmail # Google tools containing "gmail"
55
+ afctl tools list --search drive --tool google # Google tools with "drive"
56
+ afctl tools list --search team --tool slack # Slack connections with "team"
57
+
58
+ Pagination:
59
+ - Pages start from 1
60
+ - Page size range: 1-100 items
61
+ - Shows helpful tips when more results are available
62
+
63
+ Search:
64
+ - **Primary**: Searches available tool IDs from registry (e.g., "gmail" matches "gmail", "google" matches "google_drive")
65
+ - **Secondary**: Searches user connection IDs and display names (e.g., "gmail" matches "gmail_work")
66
+ - Case-insensitive matching
67
+ - Shows all connections matching the search criteria
68
+
69
+ Tool Filtering:
70
+ - Filters by tool type from connector registry
71
+ - Shows all user connections for that tool type
72
+ - "google" shows all Google Workspace tools (Drive, Docs, Sheets, Gmail, etc.)
73
+ - "gmail" shows only Gmail connections
74
+ - "slack" shows only Slack connections
75
+ - Combines with search and pagination
76
+ """
19
77
  try:
20
78
  with get_client() as client:
21
- connections = client.get("/api/v1/user-connections")
22
-
79
+ # Build query parameters
80
+ params = {}
81
+ if page != 1:
82
+ params["page"] = page
83
+ if page_size != 20:
84
+ params["page_size"] = page_size
85
+ if search:
86
+ params["search"] = search
87
+ if tool_filter:
88
+ params["tool_filter"] = tool_filter
89
+
90
+ connections = client.get("/api/v1/user-connections", params=params)
91
+
23
92
  if not connections:
24
- warning("No tool connections found. Add connections in the dashboard UI.")
93
+ if search or tool_filter:
94
+ warning(f"No tool connections found matching your criteria. Try adjusting your search or filter.")
95
+ else:
96
+ warning("No tool connections found. Add connections in the dashboard UI.")
25
97
  return
26
98
 
27
99
  # Format for better display
@@ -42,11 +114,27 @@ def list(
42
114
  "Added": conn.get("created_at", "N/A")[:10] if conn.get("created_at") else "N/A",
43
115
  })
44
116
 
117
+ # Show pagination info if not on first page or if filters applied
118
+ total_info = ""
119
+ if page != 1 or page_size != 20 or search or tool_filter:
120
+ total_info = f" (Page {page}, {len(connections)} shown"
121
+ if search:
122
+ total_info += f", Search: '{search}'"
123
+ if tool_filter:
124
+ total_info += f", Tool: '{tool_filter}'"
125
+ total_info += ")"
126
+
45
127
  print_output(
46
128
  display_data,
47
129
  format_type=format,
48
- title="Your Tool Connections"
130
+ title=f"Your Tool Connections{total_info}"
49
131
  )
132
+
133
+ # Show helpful tips for pagination
134
+ if len(connections) == page_size:
135
+ info(f"💡 Tip: Use --page {page + 1} to see more results, or --page-size to adjust items per page")
136
+ if search or tool_filter:
137
+ info(f"💡 Tip: Use --search or --tool filters to find specific connections")
50
138
 
51
139
  except Exception as e:
52
140
  error(f"Failed to list tool connections: {e}")
@@ -197,7 +285,7 @@ def add(
197
285
  tool: str = typer.Argument(..., help="Tool name (google_drive, google_slides, slack, notion, github, etc.)"),
198
286
  connection_id: str = typer.Option(..., "--connection-id", help="Unique connection ID"),
199
287
  display_name: str = typer.Option(None, "--display-name", help="Human-readable name"),
200
- method: str = typer.Option(..., "--method", help="Connection method: 'api_credentials' or 'oauth'"),
288
+ method: str = typer.Option(..., "--method", help="Connection method: 'api_credentials', 'oauth3' (Google platform OAuth), or 'oauth'"),
201
289
 
202
290
  # API credentials method fields (can be either a token OR client_id/secret)
203
291
  token: str = typer.Option(None, "--token", help="API token (for simple token-based auth like Notion, Slack bot)"),
@@ -212,7 +300,16 @@ def add(
212
300
  # Notion (api_credentials method - single token)
213
301
  afctl tools add notion --connection-id notion-work --method api_credentials --token "secret_abc123"
214
302
 
215
- # Google (api_credentials method - OAuth app)
303
+ # Google (oauth3 method - uses platform OAuth, no credentials needed)
304
+ afctl tools add google_drive --connection-id google-work --method oauth3
305
+
306
+ # Slack (oauth3 method - uses platform OAuth, no credentials needed)
307
+ afctl tools add slack --connection-id slack-work --method oauth3
308
+
309
+ # Notion (oauth3 method - uses platform OAuth, no credentials needed)
310
+ afctl tools add notion --connection-id notion-work --method oauth3
311
+
312
+ # Google (api_credentials method - your own OAuth app)
216
313
  afctl tools add google_drive --connection-id google-work --method api_credentials \\
217
314
  --client-id "123.apps.googleusercontent.com" \\
218
315
  --client-secret "GOCSPX-abc123"
@@ -247,10 +344,17 @@ def add(
247
344
  raise typer.Exit(1)
248
345
 
249
346
  # Validate method
250
- if method not in ["api_credentials", "oauth"]:
251
- error("Method must be 'api_credentials' or 'oauth'")
347
+ if method not in ["api_credentials", "oauth3", "oauth"]:
348
+ error("Method must be 'api_credentials', 'oauth3', or 'oauth'")
252
349
  raise typer.Exit(1)
253
350
 
351
+ # Validate oauth3 method is only for Google, Slack, and Notion tools
352
+ if method == "oauth3":
353
+ if not (tool.startswith("google_") or tool == "gmail" or tool == "slack" or tool == "notion"):
354
+ error("oauth3 method is only available for Google Workspace tools, Slack, and Notion")
355
+ info("For other tools, use 'api_credentials' method")
356
+ raise typer.Exit(1)
357
+
254
358
  # Validate api_credentials method requirements
255
359
  if method == "api_credentials":
256
360
  # Must have either token OR (client_id + client_secret)
@@ -282,8 +386,14 @@ def add(
282
386
  client.post("/api/v1/user-connections", data=connection_data)
283
387
  success(f"✅ Connection entry created: {connection_id}")
284
388
 
285
- # Step 2: Store credentials based on what was provided
286
- if method == "api_credentials":
389
+ # Step 2: Store credentials based on method
390
+ if method == "oauth3":
391
+ # OAuth3 uses platform credentials - no need to store user credentials
392
+ success("✅ Connection configured with platform OAuth")
393
+ info("")
394
+ info(f"Next: Run 'afctl tools connect {connection_id}' to authenticate")
395
+
396
+ elif method == "api_credentials":
287
397
  # Determine the API base tool name (Google tools all use "google")
288
398
  api_tool_name = "google" if (tool.startswith("google_") or tool == "gmail") else tool
289
399
 
@@ -384,17 +494,27 @@ def connect(
384
494
  if not confirm:
385
495
  return
386
496
 
387
- # Determine the API base tool name (Google tools all use "google")
388
- api_tool_name = "google" if (tool.startswith("google_") or tool == "gmail") else tool
497
+ # Determine the API base tool name
498
+ # - Google tools all use "google" for API credentials, "google_oauth" for oauth3
499
+ # - Notion uses "notion" for API credentials, "notion_oauth" for oauth3
500
+ if tool.startswith("google_") or tool == "gmail":
501
+ api_tool_name = "google_oauth" if method == "oauth3" else "google"
502
+ elif tool == "notion":
503
+ api_tool_name = "notion_oauth" if method == "oauth3" else "notion"
504
+ else:
505
+ api_tool_name = tool
389
506
 
390
507
  # Initiate OAuth flow
391
508
  info(f"Initiating OAuth for {tool}...")
392
509
 
393
510
  # For Google tools, pass the specific tool_type parameter
394
- tool_type_param = f"&tool_type={tool}" if tool != api_tool_name else ""
511
+ tool_type_param = f"&tool_type={tool}" if (tool.startswith("google_") or tool == "gmail") else ""
512
+
513
+ # For oauth3 method, pass the method parameter to use platform credentials
514
+ method_param = f"&method={method}" if method == "oauth3" else ""
395
515
 
396
516
  result = client.post(
397
- f"/api/v1/tools/{api_tool_name}/connect/initiate?connection_id={connection_id}{tool_type_param}",
517
+ f"/api/v1/tools/{api_tool_name}/connect/initiate?connection_id={connection_id}{tool_type_param}{method_param}",
398
518
  data={}
399
519
  )
400
520
 
af_sdk/auth/oauth.py CHANGED
@@ -47,6 +47,9 @@ def oauth_required(*, scopes: List[str], refresh_if_expired: bool = True):
47
47
  refresh_if_expired=refresh_if_expired,
48
48
  )
49
49
 
50
+ # Log token info (first 20 chars for debugging)
51
+ ctx.logger.info(f"OAuth decorator injecting token for {tool_id}: {token[:20]}...")
52
+
50
53
  # Inject Authorization header
51
54
  headers = kwargs.setdefault("headers", {})
52
55
  headers.setdefault("Authorization", f"Bearer {token}")
af_sdk/connectors/base.py CHANGED
@@ -204,10 +204,18 @@ class HTTPConnectorMixin:
204
204
  url = f"{self.base_url.rstrip('/')}/{path.lstrip('/')}"
205
205
  request_headers = {**self.default_headers, **(headers or {})}
206
206
 
207
+ # Log request details for debugging
208
+ auth_header = request_headers.get("Authorization", "")
209
+ auth_preview = f"{auth_header[:30]}..." if auth_header else "None"
210
+ self.logger.info(f"[HTTP Request] {method} {url}")
211
+ self.logger.info(f"[HTTP Request] Authorization: {auth_preview}")
212
+ self.logger.info(f"[HTTP Request] Headers: {list(request_headers.keys())}")
213
+
207
214
  try:
208
215
  response = await self.session.request(
209
216
  method, url, headers=request_headers, **kwargs
210
217
  )
218
+ self.logger.info(f"[HTTP Response] Status: {response.status_code}")
211
219
  response.raise_for_status()
212
220
  return response
213
221
  except httpx.HTTPError as e:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentic-fabriq-sdk
3
- Version: 0.1.22
3
+ Version: 0.1.24
4
4
  Summary: Agentic Fabriq SDK: high-level client, CLI tool, DX helpers, and auth for AI agents
5
5
  License: Apache-2.0
6
6
  Keywords: fabriq,agentic-fabriq,sdk,ai,agents,agentic,fabric,cli
@@ -88,15 +88,34 @@ async def main():
88
88
  tools = await af.list_tools()
89
89
  agents = await af.list_agents()
90
90
 
91
- # Invoke tools using connection ID
91
+ # Invoke Slack tools
92
92
  result = await af.invoke_connection("my-slack", method="get_channels")
93
93
 
94
- # Or post a message
94
+ # Post a Slack message
95
95
  await af.invoke_connection(
96
96
  "my-slack",
97
97
  method="post_message",
98
98
  parameters={"channel": "test", "text": "Hello from SDK!"}
99
99
  )
100
+
101
+ # Get Gmail emails
102
+ result = await af.invoke_connection(
103
+ "gmail_work",
104
+ method="get_emails",
105
+ parameters={"max_results": 10, "q": "is:unread"}
106
+ )
107
+ emails = result.get("emails", [])
108
+
109
+ # Send an email
110
+ await af.invoke_connection(
111
+ "gmail_work",
112
+ method="send_email",
113
+ parameters={
114
+ "to": "recipient@example.com",
115
+ "subject": "Hello from SDK",
116
+ "body": "This email was sent via Agentic Fabric SDK!"
117
+ }
118
+ )
100
119
  ```
101
120
 
102
121
  DX orchestration:
@@ -1,11 +1,11 @@
1
1
  af_cli/__init__.py,sha256=F2T4x4H3VIdmTjHRyV5DkaRvbZcdHYzAWD2hxtTplE4,188
2
2
  af_cli/commands/__init__.py,sha256=Qngm2Yks6oTKazlxCZA_tIAHXwHoU6Oc7Pw5BGkA7W4,49
3
- af_cli/commands/applications.py,sha256=o6P-rJHO3tdqOQTBksntlVO7Y6hoDSPQp_9nB1azwzc,11958
3
+ af_cli/commands/applications.py,sha256=gw5wY2_cTlhvgnoeuUerviwtyb0WXU3mVL28eV_WGhQ,15496
4
4
  af_cli/commands/auth.py,sha256=gz7DLiTTV0nv2DnKaa7_9nLHevCWslG54rRKRA1alx0,11967
5
5
  af_cli/commands/config.py,sha256=_k4ixGZfa7Yl_yUL-W1jeMQzykFcPcbw20Yr1v6_ShM,2748
6
6
  af_cli/commands/mcp_servers.py,sha256=1hEb4tX80dYb-j_2Z3gDud_v1FcMxl83syJ2N2eLWzI,2390
7
7
  af_cli/commands/secrets.py,sha256=z_rHfn8-KEonTC5dioBgH7sc1ppMOltFVFz-58Nqwa0,3436
8
- af_cli/commands/tools.py,sha256=2D8b6WwgKflk6JOoRxi-1j9k08mwLNeKlaUU8eOqPxs,24525
8
+ af_cli/commands/tools.py,sha256=CRtxGzMfm9etq9SLrC3v_MvBNIh3Myw4xblv5aMVTL0,30828
9
9
  af_cli/core/__init__.py,sha256=cQ0H7rGfaMISQPhoNe4Xfu_EKU2TqRVt2OMI7tPea5U,51
10
10
  af_cli/core/client.py,sha256=AYNWdCMNtDx7LOGXwoS7_rruss479T0lD6PZ1hG5dMA,5082
11
11
  af_cli/core/config.py,sha256=fwLUF0blNII2RKdFlJ3Hat51vwwNyxpIkU_HvViz8To,8538
@@ -17,10 +17,10 @@ af_sdk/__init__.py,sha256=uKLl3Sqlg_TgmGZtI0Tt14JNXIhdHSb6dplw6acBDvU,1569
17
17
  af_sdk/auth/__init__.py,sha256=laIiIwgxy0mEgRoXEakoEs7BuUYnyrlzHJbdf8Sqa5E,1137
18
18
  af_sdk/auth/applications.py,sha256=Tc5j47S5WWGFPOhsjEI40SZuCd5ynzzAohy1NS0DyAM,7474
19
19
  af_sdk/auth/dpop.py,sha256=s0uiyxxuzsVQNtSexji1htJoxrALwlf1P9507xa-M3Y,1285
20
- af_sdk/auth/oauth.py,sha256=WRTrrBzs9ieiNnWfxagP6Ag4oI9k0soYjEkjfS2y5Lg,8120
20
+ af_sdk/auth/oauth.py,sha256=iAXrOYRTWUqo2eEzX_gRmzHZRTzdo3DrZwxOeYFAZ28,8284
21
21
  af_sdk/auth/token_cache.py,sha256=X36E6K0lWqMAqlJXC3i343y8oy-uFm1q-FEdVKXdL1Y,11300
22
22
  af_sdk/connectors/__init__.py,sha256=8SDknAjPH5Swk3fJZRh6Mi19zDZQO7vcej3BzOdHGCc,411
23
- af_sdk/connectors/base.py,sha256=m3NtB4ozPtfjjs6t91OCLjCsj1xtzyK7jc7ox-HooPg,7319
23
+ af_sdk/connectors/base.py,sha256=Y0gBw9o0botNmi_hNiVgvoevnJei_XWOO7IE0v0gGDE,7799
24
24
  af_sdk/connectors/registry.py,sha256=ZH0wYIZBqDnTWJ_IhfwZzifO5r3Rkb0VlEyXDhrGWIY,8799
25
25
  af_sdk/dx/__init__.py,sha256=oiLKoDKu8I62hGj3AKzvZu8WlZbGHb_80qlmxkVWc-k,130
26
26
  af_sdk/dx/decorators.py,sha256=o_EmvE_8pp2vTgMJMgfTy5SXG_24yabuKdoytah02Hk,1294
@@ -35,7 +35,7 @@ af_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
35
  af_sdk/transport/__init__.py,sha256=HsOc6MmlxIS-PSYC_-6E36-dZYyT_auZeoXvGzVAqeg,104
36
36
  af_sdk/transport/http.py,sha256=QB3eqQbwug95QHf5PG_714NKtlTjV9PzVTo8izJCylc,13203
37
37
  af_sdk/vault.py,sha256=QVNGigIw8ND5sVXt05gvUY222b5-i9EbzLWNsDGdOU4,17926
38
- agentic_fabriq_sdk-0.1.22.dist-info/METADATA,sha256=rZ0O5voq0PTXDLRAFCEBmjE9ynQKIZXaMJTmgvGJfII,3678
39
- agentic_fabriq_sdk-0.1.22.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
40
- agentic_fabriq_sdk-0.1.22.dist-info/entry_points.txt,sha256=XUO2EaJhUtUS5pwVIkhemC-nEeFbKgXXLW97gQCCGm8,41
41
- agentic_fabriq_sdk-0.1.22.dist-info/RECORD,,
38
+ agentic_fabriq_sdk-0.1.24.dist-info/METADATA,sha256=47ZTjyyssrBYglw22NuRaQwXB89SsdJHEm1r6yfycAU,4259
39
+ agentic_fabriq_sdk-0.1.24.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
40
+ agentic_fabriq_sdk-0.1.24.dist-info/entry_points.txt,sha256=XUO2EaJhUtUS5pwVIkhemC-nEeFbKgXXLW97gQCCGm8,41
41
+ agentic_fabriq_sdk-0.1.24.dist-info/RECORD,,