glaip-sdk 0.0.17__py3-none-any.whl → 0.0.19__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.
@@ -45,16 +45,21 @@ from glaip_sdk.utils.rendering.steps import StepManager
45
45
  # Configure logger
46
46
  logger = logging.getLogger("glaip_sdk.run_renderer")
47
47
 
48
+ # Constants
49
+ LESS_THAN_1MS = "[<1ms]"
50
+
48
51
 
49
52
  @dataclass
50
53
  class RendererState:
51
54
  """Internal state for the renderer."""
52
55
 
53
- buffer: list[str] = None
56
+ buffer: list[str] | None = None
54
57
  final_text: str = ""
55
58
  streaming_started_at: float | None = None
56
59
  printed_final_panel: bool = False
57
60
  finalizing_ui: bool = False
61
+ final_duration_seconds: float | None = None
62
+ final_duration_text: str | None = None
58
63
 
59
64
  def __post_init__(self) -> None:
60
65
  """Initialize renderer state after dataclass creation.
@@ -212,59 +217,76 @@ class RichStreamRenderer:
212
217
 
213
218
  # Handle different event types
214
219
  if kind == "status":
215
- # Status events
216
- status = ev.get("status")
217
- if status == "streaming_started":
218
- self.state.streaming_started_at = monotonic()
219
- return
220
-
220
+ self._handle_status_event(ev)
221
221
  elif kind == "content":
222
- # Content streaming events
223
- if content:
224
- self.state.buffer.append(content)
225
- self._ensure_live()
226
- return
227
-
222
+ self._handle_content_event(content)
228
223
  elif kind == "final_response":
229
- # Final response events
230
- if content:
231
- self.state.buffer.append(content)
232
- self.state.final_text = content
233
- self._ensure_live()
224
+ self._handle_final_response_event(content, metadata)
225
+ elif kind in {"agent_step", "agent_thinking_step"}:
226
+ self._handle_agent_step_event(ev)
227
+ else:
228
+ # Update live display for unhandled events
229
+ self._ensure_live()
234
230
 
235
- # In verbose mode, show the final result in a panel
236
- if self.verbose and content and content.strip():
237
- final_panel = create_final_panel(content, theme=self.cfg.theme)
238
- self.console.print(final_panel)
239
- self.state.printed_final_panel = True
240
- return
231
+ def _handle_status_event(self, ev: dict[str, Any]) -> None:
232
+ """Handle status events."""
233
+ status = ev.get("status")
234
+ if status == "streaming_started":
235
+ self.state.streaming_started_at = monotonic()
241
236
 
242
- elif kind in {"agent_step", "agent_thinking_step"}:
243
- # Agent step events
244
- # Note: Thinking gaps are primarily a visual aid. Keep minimal here.
245
-
246
- # Extract tool information
247
- (
248
- tool_name,
249
- tool_args,
250
- tool_out,
251
- tool_calls_info,
252
- ) = self.stream_processor.parse_tool_calls(ev)
253
-
254
- # Track tools and sub-agents
255
- self.stream_processor.track_tools_and_agents(
256
- tool_name, tool_calls_info, is_delegation_tool
257
- )
237
+ def _handle_content_event(self, content: str) -> None:
238
+ """Handle content streaming events."""
239
+ if content:
240
+ self.state.buffer.append(content)
241
+ self._ensure_live()
242
+
243
+ def _handle_final_response_event(
244
+ self, content: str, metadata: dict[str, Any]
245
+ ) -> None:
246
+ """Handle final response events."""
247
+ if content:
248
+ self.state.buffer.append(content)
249
+ self.state.final_text = content
258
250
 
259
- # Handle tool execution
260
- self._handle_agent_step(ev, tool_name, tool_args, tool_out, tool_calls_info)
251
+ meta_payload = metadata.get("metadata") or {}
252
+ self._update_final_duration(meta_payload.get("time"))
253
+
254
+ self._ensure_live()
255
+
256
+ # In verbose mode, show the final result in a panel
257
+ if self.verbose and content.strip():
258
+ final_panel = create_final_panel(
259
+ content,
260
+ title=self._final_panel_title(),
261
+ theme=self.cfg.theme,
262
+ )
263
+ self.console.print(final_panel)
264
+ self.state.printed_final_panel = True
265
+
266
+ def _handle_agent_step_event(self, ev: dict[str, Any]) -> None:
267
+ """Handle agent step events."""
268
+ # Extract tool information
269
+ (
270
+ tool_name,
271
+ tool_args,
272
+ tool_out,
273
+ tool_calls_info,
274
+ ) = self.stream_processor.parse_tool_calls(ev)
275
+
276
+ # Track tools and sub-agents
277
+ self.stream_processor.track_tools_and_agents(
278
+ tool_name, tool_calls_info, is_delegation_tool
279
+ )
280
+
281
+ # Handle tool execution
282
+ self._handle_agent_step(ev, tool_name, tool_args, tool_out, tool_calls_info)
261
283
 
262
284
  # Update live display
263
285
  self._ensure_live()
264
286
 
265
287
  def _finish_running_steps(self) -> None:
266
288
  """Mark any running steps as finished to avoid lingering spinners."""
267
- for st in list(self.steps.by_id.values()):
289
+ for st in self.steps.by_id.values():
268
290
  if not is_step_finished(st):
269
291
  st.finish(None)
270
292
 
@@ -289,14 +311,31 @@ class RichStreamRenderer:
289
311
  if self.verbose and not self.state.printed_final_panel:
290
312
  body = ("".join(self.state.buffer) or "").strip()
291
313
  if body:
292
- final_panel = create_final_panel(body, theme=self.cfg.theme)
314
+ final_panel = create_final_panel(
315
+ body,
316
+ title=self._final_panel_title(),
317
+ theme=self.cfg.theme,
318
+ )
293
319
  self.console.print(final_panel)
294
320
  self.state.printed_final_panel = True
295
321
 
296
- def on_complete(self, _stats: RunStats) -> None:
322
+ def on_complete(self, stats: RunStats) -> None:
297
323
  """Handle completion event."""
298
324
  self.state.finalizing_ui = True
299
325
 
326
+ if isinstance(stats, RunStats):
327
+ duration = None
328
+ try:
329
+ if stats.finished_at is not None and stats.started_at is not None:
330
+ duration = max(
331
+ 0.0, float(stats.finished_at) - float(stats.started_at)
332
+ )
333
+ except Exception:
334
+ duration = None
335
+
336
+ if duration is not None:
337
+ self._update_final_duration(duration, overwrite=True)
338
+
300
339
  # Mark any running steps as finished to avoid lingering spinners
301
340
  self._finish_running_steps()
302
341
 
@@ -394,15 +433,23 @@ class RichStreamRenderer:
394
433
  if not self.verbose:
395
434
  final_content = (self.state.final_text or "").strip()
396
435
  if final_content:
436
+ title = self._final_panel_title()
397
437
  return create_final_panel(
398
438
  final_content,
399
- title="Final Result",
439
+ title=title,
400
440
  theme=self.cfg.theme,
401
441
  )
402
442
  # Dynamic title with spinner + elapsed/hints
403
443
  title = self._format_enhanced_main_title()
404
444
  return create_main_panel(body, title, self.cfg.theme)
405
445
 
446
+ def _final_panel_title(self) -> str:
447
+ """Compose title for the final result panel including duration."""
448
+ title = "Final Result"
449
+ if self.state.final_duration_text:
450
+ title = f"{title} · {self.state.final_duration_text}"
451
+ return title
452
+
406
453
  def apply_verbosity(self, verbose: bool) -> None:
407
454
  """Update verbose behaviour at runtime."""
408
455
  if self.verbose == verbose:
@@ -507,27 +554,43 @@ class RichStreamRenderer:
507
554
  """Process additional tool calls to avoid duplicates."""
508
555
  for call_name, call_args, _ in tool_calls_info or []:
509
556
  if call_name and call_name != tool_name:
510
- self._ensure_tool_panel(call_name, call_args, task_id, context_id)
511
- if is_delegation_tool(call_name):
512
- st2 = self.steps.start_or_get(
513
- task_id=task_id,
514
- context_id=context_id,
515
- kind="delegate",
516
- name=call_name,
517
- args=call_args,
518
- )
519
- else:
520
- st2 = self.steps.start_or_get(
521
- task_id=task_id,
522
- context_id=context_id,
523
- kind="tool",
524
- name=call_name,
525
- args=call_args,
526
- )
527
- if self.stream_processor.server_elapsed_time is not None and st2:
528
- self._step_server_start_times[st2.step_id] = (
529
- self.stream_processor.server_elapsed_time
530
- )
557
+ self._process_single_tool_call(
558
+ call_name, call_args, task_id, context_id
559
+ )
560
+
561
+ def _process_single_tool_call(
562
+ self, call_name: str, call_args: Any, task_id: str, context_id: str
563
+ ) -> None:
564
+ """Process a single additional tool call."""
565
+ self._ensure_tool_panel(call_name, call_args, task_id, context_id)
566
+
567
+ st2 = self._create_step_for_tool_call(call_name, call_args, task_id, context_id)
568
+
569
+ if self.stream_processor.server_elapsed_time is not None and st2:
570
+ self._step_server_start_times[st2.step_id] = (
571
+ self.stream_processor.server_elapsed_time
572
+ )
573
+
574
+ def _create_step_for_tool_call(
575
+ self, call_name: str, call_args: Any, task_id: str, context_id: str
576
+ ) -> Any:
577
+ """Create appropriate step for tool call."""
578
+ if is_delegation_tool(call_name):
579
+ return self.steps.start_or_get(
580
+ task_id=task_id,
581
+ context_id=context_id,
582
+ kind="delegate",
583
+ name=call_name,
584
+ args=call_args,
585
+ )
586
+ else:
587
+ return self.steps.start_or_get(
588
+ task_id=task_id,
589
+ context_id=context_id,
590
+ kind="tool",
591
+ name=call_name,
592
+ args=call_args,
593
+ )
531
594
 
532
595
  def _detect_tool_completion(
533
596
  self, metadata: dict, content: str
@@ -941,19 +1004,19 @@ class RichStreamRenderer:
941
1004
  """Format step status with elapsed time or duration."""
942
1005
  if is_step_finished(step):
943
1006
  if step.duration_ms is None:
944
- return "[<1ms]"
1007
+ return LESS_THAN_1MS
945
1008
  elif step.duration_ms >= 1000:
946
1009
  return f"[{step.duration_ms / 1000:.2f}s]"
947
1010
  elif step.duration_ms > 0:
948
1011
  return f"[{step.duration_ms}ms]"
949
- return "[<1ms]"
1012
+ return LESS_THAN_1MS
950
1013
  else:
951
1014
  # Calculate elapsed time for running steps
952
1015
  elapsed = self._calculate_step_elapsed_time(step)
953
1016
  if elapsed >= 1:
954
1017
  return f"[{elapsed:.2f}s]"
955
1018
  ms = int(elapsed * 1000)
956
- return f"[{ms}ms]" if ms > 0 else "[<1ms]"
1019
+ return f"[{ms}ms]" if ms > 0 else LESS_THAN_1MS
957
1020
 
958
1021
  def _calculate_step_elapsed_time(self, step: Step) -> float:
959
1022
  """Calculate elapsed time for a running step."""
@@ -1024,6 +1087,29 @@ class RichStreamRenderer:
1024
1087
  and sid not in self.stream_processor.current_event_finished_panels
1025
1088
  )
1026
1089
 
1090
+ def _update_final_duration(
1091
+ self, duration: float | None, *, overwrite: bool = False
1092
+ ) -> None:
1093
+ """Store formatted duration for eventual final panels."""
1094
+ if duration is None:
1095
+ return
1096
+
1097
+ try:
1098
+ duration_val = max(0.0, float(duration))
1099
+ except Exception:
1100
+ return
1101
+
1102
+ existing = self.state.final_duration_seconds
1103
+
1104
+ if not overwrite and existing is not None:
1105
+ return
1106
+
1107
+ if overwrite and existing is not None:
1108
+ duration_val = max(existing, duration_val)
1109
+
1110
+ self.state.final_duration_seconds = duration_val
1111
+ self.state.final_duration_text = self._format_elapsed_time(duration_val)
1112
+
1027
1113
  def _calculate_elapsed_time(self, meta: dict[str, Any]) -> str:
1028
1114
  """Calculate elapsed time string for running tools."""
1029
1115
  server_elapsed = self.stream_processor.server_elapsed_time
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: glaip-sdk
3
- Version: 0.0.17
3
+ Version: 0.0.19
4
4
  Summary: Python SDK for GL AIP (GDP Labs AI Agent Package) - Simplified CLI Design
5
5
  License: MIT
6
6
  Author: Raymond Christopher
@@ -7,7 +7,7 @@ glaip_sdk/cli/auth.py,sha256=eYdtGmJ3XgiO96hq_69GF6b3W-aRWZrDQ-6bHuaRX4M,13517
7
7
  glaip_sdk/cli/commands/__init__.py,sha256=x0CZlZbZHoHvuzfoTWIyEch6WmNnbPzxajrox6riYp0,173
8
8
  glaip_sdk/cli/commands/agents.py,sha256=FtWGhbl4QRlqxXFNMEnZUpw5mjQ0KPjY0_6o0hYyoaU,41251
9
9
  glaip_sdk/cli/commands/configure.py,sha256=h2GgBpnBWYHAhp3zqkAiy8QNgwPD_7pToZBZRpuMoNM,7869
10
- glaip_sdk/cli/commands/mcps.py,sha256=V41Te3IG8jNFRMb1v1XQV1t461uxpPsrmDFIO6cZPOk,28185
10
+ glaip_sdk/cli/commands/mcps.py,sha256=wqUbkQ6qUUhr6B0n2jJxPUkbxHwfsEnYvdLKew_qorM,36800
11
11
  glaip_sdk/cli/commands/models.py,sha256=G1ce-wZOfvMP6SMnIVuSQ89CF444Kz8Ja6nrNOQXCqU,1729
12
12
  glaip_sdk/cli/commands/tools.py,sha256=YfkB7HRBGcAOC6N-wXTV5Ch5XTXqjKTtyq-Cfb0-18c,18908
13
13
  glaip_sdk/cli/config.py,sha256=jCLJxTBAnOU6EJI6JjcpwUTEAWCJRoALbMrhOvvAofc,946
@@ -19,24 +19,24 @@ glaip_sdk/cli/masking.py,sha256=BOZjwUqxQf3LQlYgUMwq7UYgve8x4_1Qk04ixiJJPZ8,4399
19
19
  glaip_sdk/cli/mcp_validators.py,sha256=SeDbgXkRuBXyDtCmUMpL-1Vh7fmGldz-shAaHhOqbCc,10125
20
20
  glaip_sdk/cli/pager.py,sha256=n9ypOGPPSaseJlwPG1X38qSz1yV3pjRWunzA4xx5E7M,8052
21
21
  glaip_sdk/cli/parsers/__init__.py,sha256=Ycd4HDfYmA7GUGFt0ndBPBo5uTbv15XsXnYUj-a89ug,183
22
- glaip_sdk/cli/parsers/json_input.py,sha256=6NqzVM5l8g0pwCNLKeTVL9SeLM9W_Fl4H__X0dfaQEA,4039
22
+ glaip_sdk/cli/parsers/json_input.py,sha256=ZBhJNUR4bKDX3A5s9lRvuCicaztvQyP0lWuiNYMIO08,5721
23
23
  glaip_sdk/cli/resolution.py,sha256=jXUNpKKhs30n7Ke0uz1Hbny5DTo2_sxvchIhTbeBubE,2393
24
24
  glaip_sdk/cli/rich_helpers.py,sha256=ByUOmK16IisoXWE7nEiI55BF1KWDrm6KCYAxqHu0XOU,825
25
25
  glaip_sdk/cli/slash/__init__.py,sha256=Vdv6Y8bu-pA8dxDlyP4XrhudBPivztUozhLAz9vaLig,682
26
26
  glaip_sdk/cli/slash/agent_session.py,sha256=-woZkqH70YUSaEHDF9XpxP-cbh36Jx7yuJW7aA3JszI,7078
27
- glaip_sdk/cli/slash/prompt.py,sha256=2CLAfdmX6yQedcNLnwZ4g6QFoV9TVv8il9OF8iaJwdc,7977
28
- glaip_sdk/cli/slash/session.py,sha256=JsTHZB8gPFFdcp_bhtw-nig37Z61OWK_okPMx47H86c,31484
27
+ glaip_sdk/cli/slash/prompt.py,sha256=Cfd6nL1T-F51WNuRCO09RxXfuJn0I1OyBi5dx3xKtaY,8407
28
+ glaip_sdk/cli/slash/session.py,sha256=WZKAwkio1DMK72r6myR8Ou7weIS5JsQutbtVMox7ctc,32515
29
29
  glaip_sdk/cli/update_notifier.py,sha256=nfQ-jRQKn-nZyt7EhxNfZq9Z7nBrYjZJKAgAtuHffnw,3410
30
30
  glaip_sdk/cli/utils.py,sha256=pgbV0f5rdjAHeZ-ULCntH7HUG6FdFB9kODv0a9puB40,35503
31
31
  glaip_sdk/cli/validators.py,sha256=USbBgY86AwuDHO-Q_g8g7hu-ot4NgITBsWjTWIl62ms,5569
32
32
  glaip_sdk/client/__init__.py,sha256=nYLXfBVTTWwKjP0e63iumPYO4k5FifwWaELQPaPIKIg,188
33
33
  glaip_sdk/client/_agent_payloads.py,sha256=sYlMzrfAdd8KC37qxokLy2uDd3aOhzQirnv7UYlvwYc,16385
34
- glaip_sdk/client/agents.py,sha256=GpDlxzhUQaMn9IUq_kCsbZo5TBfwWXFYs1bbpPLiSok,35492
34
+ glaip_sdk/client/agents.py,sha256=-ORfxYaoX6JkgGS9B7ZCQmr1o9H5KEr0GesbfeiSros,37594
35
35
  glaip_sdk/client/base.py,sha256=OPRlAWhZ77rUK0MRGA83-zW5NVhxJ1RgdfcfGOYr8rI,16267
36
- glaip_sdk/client/main.py,sha256=tfyyx9utReq7nXdtHKOCXQIUXXeZ1-D6u4OGTu6h8Es,8632
36
+ glaip_sdk/client/main.py,sha256=tELAA36rzthnNKTgwZ6lLPb3Au8Wh1mF8Kz-9N-YtCg,8652
37
37
  glaip_sdk/client/mcps.py,sha256=-O-I15qjbwfSA69mouHY6g5_qgPWC4rM98VJLpOkh1A,8975
38
38
  glaip_sdk/client/run_rendering.py,sha256=fXUj1FBw8n-nAzjI_zaG7-Ap_UXXe0z4tMdL7m2R7Ek,9213
39
- glaip_sdk/client/tools.py,sha256=n8DIiOOf1YU_j9JK3Bx2-rDnkpckPi0MI9Ok2s1kwa4,16634
39
+ glaip_sdk/client/tools.py,sha256=rWxfNO30sS468513IoE5PfEaqNq6HBwmcHVh4FzhvYQ,17532
40
40
  glaip_sdk/client/validators.py,sha256=NtPsWjQLjj25LiUnmR-WuS8lL5p4MVRaYT9UVRmj9bo,8809
41
41
  glaip_sdk/config/constants.py,sha256=B9CSlYG8LYjQuo_vNpqy-eSks3ej37FMcvJMy6d_F4U,888
42
42
  glaip_sdk/exceptions.py,sha256=ILquxC4QGPFR9eY6RpeXzkQsblfsvZMGFqz38ZjeW3E,2345
@@ -45,16 +45,16 @@ glaip_sdk/payload_schemas/__init__.py,sha256=fJamlkpS3IfS9xyKAQaUbnalvrtG5Ied69O
45
45
  glaip_sdk/payload_schemas/agent.py,sha256=nlizuv2w4SVzmMJSE90rE6Ll0Hfpcr5hvPsW_NtXCV0,3204
46
46
  glaip_sdk/rich_components.py,sha256=veaps1hrSkC3nSVunAevvynSux8Cg3yFEDmbJk66p7w,1267
47
47
  glaip_sdk/utils/__init__.py,sha256=fmVGcUFa7G0CCfSMSqfNU2BqFl36G1gOFyDfTvtJfVw,926
48
- glaip_sdk/utils/agent_config.py,sha256=b7_J5DELyk0b_XEoi7tsxbS3wqzAKbMa-3_C-65pPIY,6791
48
+ glaip_sdk/utils/agent_config.py,sha256=p3uK5qC0M5uQv9uY7-U8ej11Vh81fwKAPSsYcRoNdlk,7342
49
49
  glaip_sdk/utils/client_utils.py,sha256=x27kHQNOxvyVN5GLUiymi0eHzkXRKw-x3s0q0VkMvY4,13938
50
50
  glaip_sdk/utils/display.py,sha256=94s9lYF_8ra8jpeqOkbVrUm8oidtCE6OtucyxLQPKmU,3105
51
51
  glaip_sdk/utils/general.py,sha256=V5hJrIpYDvDsldU_nChHpuvV2AwhFLUI7Qvcaihq_8A,2270
52
52
  glaip_sdk/utils/import_export.py,sha256=jEhl5U6hWWMR1wo5AXpV-_jN_56DcWcemOa2UaFHapk,5217
53
53
  glaip_sdk/utils/rendering/__init__.py,sha256=vXjwk5rPhhfPyD8S0DnV4GFFEtPJp4HCCg1Um9SXfs0,70
54
- glaip_sdk/utils/rendering/formatting.py,sha256=I8nN4H3DxTOYIExn6gozcxyAn_GO1lSztbcrSCkcscg,7351
54
+ glaip_sdk/utils/rendering/formatting.py,sha256=mS4xvbNy1NSH4nXm8mKj03jEXMNinxfbtVJGYf3sXlk,7770
55
55
  glaip_sdk/utils/rendering/models.py,sha256=AM9JbToyA3zrAzXQYjh6oxjBkgZDfWEbs5MmNKODnOY,2259
56
56
  glaip_sdk/utils/rendering/renderer/__init__.py,sha256=EXwVBmGkSYcype4ocAXo69Z1kXu0gpNXmhH5LW0_B7A,2939
57
- glaip_sdk/utils/rendering/renderer/base.py,sha256=HGljrxMcDq4QCsWcwR45qZYjKWZprBunnZJYYea8FTQ,42764
57
+ glaip_sdk/utils/rendering/renderer/base.py,sha256=Tk-N0Fpi4kyuJYb-YaYEAytpho2vcWBKdDmzqIK_Pto,45543
58
58
  glaip_sdk/utils/rendering/renderer/config.py,sha256=-P35z9JO_1ypJXAqxJ1ybHraH4i-I1LPopeW3Lh7ACE,785
59
59
  glaip_sdk/utils/rendering/renderer/console.py,sha256=4cLOw4Q1fkHkApuj6dWW8eYpeYdcT0t2SO5MbVt5UTc,1844
60
60
  glaip_sdk/utils/rendering/renderer/debug.py,sha256=FEYxAu4ZB0CjrJKevqQ2TKDgElA2cf6GqZXCNm12sNQ,3721
@@ -67,7 +67,7 @@ glaip_sdk/utils/rich_utils.py,sha256=-Ij-1bIJvnVAi6DrfftchIlMcvOTjVmSE0Qqax0EY_s
67
67
  glaip_sdk/utils/run_renderer.py,sha256=d_VMI6LbvHPUUeRmGqh5wK_lHqDEIAcym2iqpbtDad0,1365
68
68
  glaip_sdk/utils/serialization.py,sha256=AFbucakFaCtQDfcgsm2gHZ1iZDA8OaJSZUsS6FhWFR0,12820
69
69
  glaip_sdk/utils/validation.py,sha256=QNORcdyvuliEs4EH2_mkDgmoyT9utgl7YNhaf45SEf8,6992
70
- glaip_sdk-0.0.17.dist-info/METADATA,sha256=z1GiwKAgE5eXkCbBfUXrQuMZBUQ14XWuOZhgj5ugyAw,5164
71
- glaip_sdk-0.0.17.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
72
- glaip_sdk-0.0.17.dist-info/entry_points.txt,sha256=EGs8NO8J1fdFMWA3CsF7sKBEvtHb_fujdCoNPhfMouE,47
73
- glaip_sdk-0.0.17.dist-info/RECORD,,
70
+ glaip_sdk-0.0.19.dist-info/METADATA,sha256=CxTXRqseeY6CsuhudOT_ddbxuK5WLfkkM6oSaaMSxdY,5164
71
+ glaip_sdk-0.0.19.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
72
+ glaip_sdk-0.0.19.dist-info/entry_points.txt,sha256=EGs8NO8J1fdFMWA3CsF7sKBEvtHb_fujdCoNPhfMouE,47
73
+ glaip_sdk-0.0.19.dist-info/RECORD,,