code-review-ai-cli 2.2.2__tar.gz → 2.2.3__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.
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/PKG-INFO +16 -1
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/README.md +11 -0
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/code_review_ai_cli.egg-info/PKG-INFO +16 -1
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/code_review_ai_cli.egg-info/SOURCES.txt +3 -1
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/code_review_ai_cli.egg-info/requires.txt +4 -0
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/pyproject.toml +5 -1
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/src/__init__.py +3 -0
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/src/ai_review.py +13 -0
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/src/config.py +3 -0
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/src/context_extractor.py +3 -0
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/src/formatter.py +3 -0
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/src/git_utils.py +3 -0
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/src/llm_client.py +18 -0
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/src/prompt_utils.py +3 -0
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/src/tfs_client.py +3 -0
- code_review_ai_cli-2.2.3/src/token_estimator.py +98 -0
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/tests/test_ai_review.py +3 -0
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/tests/test_config.py +389 -386
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/tests/test_context_extractor.py +3 -0
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/tests/test_formatter.py +3 -0
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/tests/test_git_utils.py +159 -156
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/tests/test_llm_client.py +3 -0
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/tests/test_prompt_utils.py +3 -0
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/tests/test_tfs_client.py +3 -0
- code_review_ai_cli-2.2.3/tests/test_token_estimator.py +102 -0
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/code_review_ai_cli.egg-info/dependency_links.txt +0 -0
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/code_review_ai_cli.egg-info/entry_points.txt +0 -0
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/code_review_ai_cli.egg-info/top_level.txt +0 -0
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/setup.cfg +0 -0
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/src/prompts/config.yaml.template +0 -0
- {code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/src/prompts/review_prompt.md.template +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-review-ai-cli
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.3
|
|
4
4
|
Summary: Automated AI-powered code review CLI for Azure DevOps / TFS Pull Requests
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: code-review,ai,azure-devops,tfs,pull-request,llm
|
|
@@ -17,6 +17,8 @@ Requires-Python: >=3.10
|
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
Requires-Dist: requests>=2.28.0
|
|
19
19
|
Requires-Dist: PyYAML>=6.0
|
|
20
|
+
Requires-Dist: litellm>=1.40.0
|
|
21
|
+
Requires-Dist: tiktoken>=0.7.0
|
|
20
22
|
Provides-Extra: bedrock
|
|
21
23
|
Requires-Dist: boto3>=1.34.0; extra == "bedrock"
|
|
22
24
|
Provides-Extra: openai
|
|
@@ -29,6 +31,8 @@ Provides-Extra: tree-sitter
|
|
|
29
31
|
Requires-Dist: tree-sitter-languages>=1.10.2; extra == "tree-sitter"
|
|
30
32
|
Provides-Extra: all
|
|
31
33
|
Requires-Dist: boto3>=1.34.0; extra == "all"
|
|
34
|
+
Requires-Dist: litellm>=1.40.0; extra == "all"
|
|
35
|
+
Requires-Dist: tiktoken>=0.7.0; extra == "all"
|
|
32
36
|
Requires-Dist: openai>=1.0.0; extra == "all"
|
|
33
37
|
Requires-Dist: google-generativeai>=0.3.0; extra == "all"
|
|
34
38
|
Requires-Dist: anthropic>=0.18.0; extra == "all"
|
|
@@ -51,6 +55,7 @@ AI Code Review is an automated AI-powered code review CLI, compatible with vario
|
|
|
51
55
|
- Configuration exclusively via `config.yaml`
|
|
52
56
|
- Providers LLM: OpenAI, Azure OpenAI, Gemini, Claude, Ollama, GitHub Copilot, AWS Bedrock
|
|
53
57
|
- Diff filtering by **excluded path prefixes** (`excluded_paths`) and/or **file extensions** (`file_extensions_filter`)
|
|
58
|
+
- Prompt token estimation with LiteLLM (`Total Prompt`)
|
|
54
59
|
|
|
55
60
|
## Documentation
|
|
56
61
|
|
|
@@ -63,6 +68,13 @@ AI Code Review is an automated AI-powered code review CLI, compatible with vario
|
|
|
63
68
|
|
|
64
69
|

|
|
65
70
|
|
|
71
|
+
During a PR review, the terminal also displays `Total Prompt`, an estimate of
|
|
72
|
+
the input tokens in the complete payload sent to the configured provider. The
|
|
73
|
+
provider comes from `llm.provider` and the model comes from `llm.model` or its
|
|
74
|
+
default one. If LiteLLM cannot resolve the provider/model combination,
|
|
75
|
+
the tool tries the model without a provider prefix and then uses local
|
|
76
|
+
`tiktoken` as a final fallback.
|
|
77
|
+
|
|
66
78
|
## Installation
|
|
67
79
|
|
|
68
80
|
Install from PyPI:
|
|
@@ -144,3 +156,6 @@ output:
|
|
|
144
156
|
- `AI Review: PR (Dry-Run)`
|
|
145
157
|
- `AI Review: List Active PRs`
|
|
146
158
|
- `AI Review: Interactive Mode`
|
|
159
|
+
|
|
160
|
+
## Licence
|
|
161
|
+
This project is licensed under the Apache Licence 2.0 — see the [LICENSE](/License).
|
|
@@ -11,6 +11,7 @@ AI Code Review is an automated AI-powered code review CLI, compatible with vario
|
|
|
11
11
|
- Configuration exclusively via `config.yaml`
|
|
12
12
|
- Providers LLM: OpenAI, Azure OpenAI, Gemini, Claude, Ollama, GitHub Copilot, AWS Bedrock
|
|
13
13
|
- Diff filtering by **excluded path prefixes** (`excluded_paths`) and/or **file extensions** (`file_extensions_filter`)
|
|
14
|
+
- Prompt token estimation with LiteLLM (`Total Prompt`)
|
|
14
15
|
|
|
15
16
|
## Documentation
|
|
16
17
|
|
|
@@ -23,6 +24,13 @@ AI Code Review is an automated AI-powered code review CLI, compatible with vario
|
|
|
23
24
|
|
|
24
25
|

|
|
25
26
|
|
|
27
|
+
During a PR review, the terminal also displays `Total Prompt`, an estimate of
|
|
28
|
+
the input tokens in the complete payload sent to the configured provider. The
|
|
29
|
+
provider comes from `llm.provider` and the model comes from `llm.model` or its
|
|
30
|
+
default one. If LiteLLM cannot resolve the provider/model combination,
|
|
31
|
+
the tool tries the model without a provider prefix and then uses local
|
|
32
|
+
`tiktoken` as a final fallback.
|
|
33
|
+
|
|
26
34
|
## Installation
|
|
27
35
|
|
|
28
36
|
Install from PyPI:
|
|
@@ -104,3 +112,6 @@ output:
|
|
|
104
112
|
- `AI Review: PR (Dry-Run)`
|
|
105
113
|
- `AI Review: List Active PRs`
|
|
106
114
|
- `AI Review: Interactive Mode`
|
|
115
|
+
|
|
116
|
+
## Licence
|
|
117
|
+
This project is licensed under the Apache Licence 2.0 — see the [LICENSE](/License).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-review-ai-cli
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.3
|
|
4
4
|
Summary: Automated AI-powered code review CLI for Azure DevOps / TFS Pull Requests
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: code-review,ai,azure-devops,tfs,pull-request,llm
|
|
@@ -17,6 +17,8 @@ Requires-Python: >=3.10
|
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
Requires-Dist: requests>=2.28.0
|
|
19
19
|
Requires-Dist: PyYAML>=6.0
|
|
20
|
+
Requires-Dist: litellm>=1.40.0
|
|
21
|
+
Requires-Dist: tiktoken>=0.7.0
|
|
20
22
|
Provides-Extra: bedrock
|
|
21
23
|
Requires-Dist: boto3>=1.34.0; extra == "bedrock"
|
|
22
24
|
Provides-Extra: openai
|
|
@@ -29,6 +31,8 @@ Provides-Extra: tree-sitter
|
|
|
29
31
|
Requires-Dist: tree-sitter-languages>=1.10.2; extra == "tree-sitter"
|
|
30
32
|
Provides-Extra: all
|
|
31
33
|
Requires-Dist: boto3>=1.34.0; extra == "all"
|
|
34
|
+
Requires-Dist: litellm>=1.40.0; extra == "all"
|
|
35
|
+
Requires-Dist: tiktoken>=0.7.0; extra == "all"
|
|
32
36
|
Requires-Dist: openai>=1.0.0; extra == "all"
|
|
33
37
|
Requires-Dist: google-generativeai>=0.3.0; extra == "all"
|
|
34
38
|
Requires-Dist: anthropic>=0.18.0; extra == "all"
|
|
@@ -51,6 +55,7 @@ AI Code Review is an automated AI-powered code review CLI, compatible with vario
|
|
|
51
55
|
- Configuration exclusively via `config.yaml`
|
|
52
56
|
- Providers LLM: OpenAI, Azure OpenAI, Gemini, Claude, Ollama, GitHub Copilot, AWS Bedrock
|
|
53
57
|
- Diff filtering by **excluded path prefixes** (`excluded_paths`) and/or **file extensions** (`file_extensions_filter`)
|
|
58
|
+
- Prompt token estimation with LiteLLM (`Total Prompt`)
|
|
54
59
|
|
|
55
60
|
## Documentation
|
|
56
61
|
|
|
@@ -63,6 +68,13 @@ AI Code Review is an automated AI-powered code review CLI, compatible with vario
|
|
|
63
68
|
|
|
64
69
|

|
|
65
70
|
|
|
71
|
+
During a PR review, the terminal also displays `Total Prompt`, an estimate of
|
|
72
|
+
the input tokens in the complete payload sent to the configured provider. The
|
|
73
|
+
provider comes from `llm.provider` and the model comes from `llm.model` or its
|
|
74
|
+
default one. If LiteLLM cannot resolve the provider/model combination,
|
|
75
|
+
the tool tries the model without a provider prefix and then uses local
|
|
76
|
+
`tiktoken` as a final fallback.
|
|
77
|
+
|
|
66
78
|
## Installation
|
|
67
79
|
|
|
68
80
|
Install from PyPI:
|
|
@@ -144,3 +156,6 @@ output:
|
|
|
144
156
|
- `AI Review: PR (Dry-Run)`
|
|
145
157
|
- `AI Review: List Active PRs`
|
|
146
158
|
- `AI Review: Interactive Mode`
|
|
159
|
+
|
|
160
|
+
## Licence
|
|
161
|
+
This project is licensed under the Apache Licence 2.0 — see the [LICENSE](/License).
|
{code_review_ai_cli-2.2.2 → code_review_ai_cli-2.2.3}/code_review_ai_cli.egg-info/SOURCES.txt
RENAMED
|
@@ -15,6 +15,7 @@ src/git_utils.py
|
|
|
15
15
|
src/llm_client.py
|
|
16
16
|
src/prompt_utils.py
|
|
17
17
|
src/tfs_client.py
|
|
18
|
+
src/token_estimator.py
|
|
18
19
|
src/prompts/config.yaml.template
|
|
19
20
|
src/prompts/review_prompt.md.template
|
|
20
21
|
tests/test_ai_review.py
|
|
@@ -24,4 +25,5 @@ tests/test_formatter.py
|
|
|
24
25
|
tests/test_git_utils.py
|
|
25
26
|
tests/test_llm_client.py
|
|
26
27
|
tests/test_prompt_utils.py
|
|
27
|
-
tests/test_tfs_client.py
|
|
28
|
+
tests/test_tfs_client.py
|
|
29
|
+
tests/test_token_estimator.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "code-review-ai-cli"
|
|
7
|
-
version = "2.2.
|
|
7
|
+
version = "2.2.3"
|
|
8
8
|
description = "Automated AI-powered code review CLI for Azure DevOps / TFS Pull Requests"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -24,6 +24,8 @@ classifiers = [
|
|
|
24
24
|
dependencies = [
|
|
25
25
|
"requests>=2.28.0",
|
|
26
26
|
"PyYAML>=6.0",
|
|
27
|
+
"litellm>=1.40.0",
|
|
28
|
+
"tiktoken>=0.7.0",
|
|
27
29
|
]
|
|
28
30
|
|
|
29
31
|
[project.optional-dependencies]
|
|
@@ -34,6 +36,8 @@ claude = ["anthropic>=0.18.0"]
|
|
|
34
36
|
tree-sitter = ["tree-sitter-languages>=1.10.2"]
|
|
35
37
|
all = [
|
|
36
38
|
"boto3>=1.34.0",
|
|
39
|
+
"litellm>=1.40.0",
|
|
40
|
+
"tiktoken>=0.7.0",
|
|
37
41
|
"openai>=1.0.0",
|
|
38
42
|
"google-generativeai>=0.3.0",
|
|
39
43
|
"anthropic>=0.18.0",
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
+
# License: Apache-2.0
|
|
3
|
+
# Copyright 2026 Sérgio Sereno
|
|
4
|
+
|
|
2
5
|
"""
|
|
3
6
|
AI Code Review - Main Script
|
|
4
7
|
==============================
|
|
@@ -516,6 +519,16 @@ def run_pr_review_workflow(args: argparse.Namespace, config: ReviewConfig,
|
|
|
516
519
|
elapsed = time.time() - start_time
|
|
517
520
|
progress.stop(formatter.format_success(f"Review completed in {elapsed:.1f}s"))
|
|
518
521
|
|
|
522
|
+
token_estimate = getattr(llm, "last_token_estimate", None)
|
|
523
|
+
if token_estimate is not None and token_estimate.total_prompt_tokens is not None:
|
|
524
|
+
print(formatter.format_info(
|
|
525
|
+
f"Total Prompt: {token_estimate.total_prompt_tokens} tokens"
|
|
526
|
+
))
|
|
527
|
+
else:
|
|
528
|
+
print(formatter.format_warning(
|
|
529
|
+
"Total Prompt: unavailable (LiteLLM and local tiktoken could not count the model)"
|
|
530
|
+
))
|
|
531
|
+
|
|
519
532
|
# --- Show structured comments preview ---
|
|
520
533
|
print(formatter.format_structured_comments(
|
|
521
534
|
structured_comments,
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
# License: Apache-2.0
|
|
2
|
+
# Copyright 2026 Sérgio Sereno
|
|
3
|
+
|
|
1
4
|
"""
|
|
2
5
|
LLM Client Module - AI Code Review
|
|
3
6
|
=====================================
|
|
@@ -18,6 +21,7 @@ import os
|
|
|
18
21
|
|
|
19
22
|
from .config import ReviewConfig
|
|
20
23
|
from .prompt_utils import detect_langs, filter_prompt_by_langs
|
|
24
|
+
from .token_estimator import TokenEstimate, TokenEstimator
|
|
21
25
|
|
|
22
26
|
|
|
23
27
|
class LLMError(Exception):
|
|
@@ -317,6 +321,11 @@ class LLMClient:
|
|
|
317
321
|
|
|
318
322
|
def __init__(self, config: ReviewConfig):
|
|
319
323
|
self.config = config
|
|
324
|
+
self.last_token_estimate = TokenEstimate(
|
|
325
|
+
total_prompt_tokens=None,
|
|
326
|
+
model=config.get_effective_model(),
|
|
327
|
+
error="No review has been performed yet.",
|
|
328
|
+
)
|
|
320
329
|
|
|
321
330
|
def _dump_prompt_debug(self, system_prompt: str, user_message: str) -> None:
|
|
322
331
|
"""
|
|
@@ -420,6 +429,15 @@ class LLMClient:
|
|
|
420
429
|
user_message = build_user_message(diff, files_summary, merged_context)
|
|
421
430
|
self._dump_prompt_debug(system_prompt, user_message)
|
|
422
431
|
|
|
432
|
+
self.last_token_estimate = TokenEstimator().estimate(
|
|
433
|
+
provider=self.config.llm_provider,
|
|
434
|
+
model=self.config.get_effective_model(),
|
|
435
|
+
messages=[
|
|
436
|
+
{"role": "system", "content": system_prompt},
|
|
437
|
+
{"role": "user", "content": user_message},
|
|
438
|
+
],
|
|
439
|
+
)
|
|
440
|
+
|
|
423
441
|
provider = self.config.llm_provider.lower()
|
|
424
442
|
|
|
425
443
|
if provider == "openai":
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# License: Apache-2.0
|
|
2
|
+
# Copyright 2026 Sérgio Sereno
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass(frozen=True)
|
|
9
|
+
class TokenEstimate:
|
|
10
|
+
"""Result of estimating the input tokens for an LLM request."""
|
|
11
|
+
|
|
12
|
+
total_prompt_tokens: int | None
|
|
13
|
+
model: str
|
|
14
|
+
error: str = ""
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class TokenEstimator:
|
|
18
|
+
"""Estimates prompt tokens with LiteLLM for configured providers."""
|
|
19
|
+
|
|
20
|
+
_PROVIDER_PREFIXES = {
|
|
21
|
+
"azure_openai": "azure",
|
|
22
|
+
"gemini": "gemini",
|
|
23
|
+
"claude": "anthropic",
|
|
24
|
+
"ollama": "ollama",
|
|
25
|
+
"copilot": "github",
|
|
26
|
+
"bedrock": "bedrock",
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
def estimate(
|
|
30
|
+
self,
|
|
31
|
+
provider: str,
|
|
32
|
+
model: str,
|
|
33
|
+
messages: list[dict[str, str]],
|
|
34
|
+
) -> TokenEstimate:
|
|
35
|
+
"""Estimates input tokens, falling back to the unqualified model.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
provider: Provider configured for the LLM request.
|
|
39
|
+
model: Effective model name, including configured defaults.
|
|
40
|
+
messages: Complete chat payload sent to the provider.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
A token estimate, or an unavailable result when LiteLLM cannot
|
|
44
|
+
resolve either the provider-qualified or raw model name.
|
|
45
|
+
"""
|
|
46
|
+
qualified_model = self._qualified_model(provider, model)
|
|
47
|
+
errors: list[str] = []
|
|
48
|
+
|
|
49
|
+
for candidate in dict.fromkeys((qualified_model, model)):
|
|
50
|
+
try:
|
|
51
|
+
token_count = self._count(candidate, messages)
|
|
52
|
+
return TokenEstimate(token_count, candidate)
|
|
53
|
+
except Exception as exc:
|
|
54
|
+
errors.append(f"{candidate}: {exc}")
|
|
55
|
+
|
|
56
|
+
try:
|
|
57
|
+
token_count = self._count_locally(model, messages)
|
|
58
|
+
return TokenEstimate(token_count, "local/tiktoken")
|
|
59
|
+
except Exception as exc:
|
|
60
|
+
errors.append(f"local/tiktoken: {exc}")
|
|
61
|
+
|
|
62
|
+
return TokenEstimate(
|
|
63
|
+
total_prompt_tokens=None,
|
|
64
|
+
model=qualified_model,
|
|
65
|
+
error="; ".join(errors),
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
@classmethod
|
|
69
|
+
def _qualified_model(cls, provider: str, model: str) -> str:
|
|
70
|
+
"""Builds the LiteLLM model name for a configured provider."""
|
|
71
|
+
normalized_provider = provider.lower().strip()
|
|
72
|
+
prefix = cls._PROVIDER_PREFIXES.get(normalized_provider)
|
|
73
|
+
if not prefix:
|
|
74
|
+
return model
|
|
75
|
+
return f"{prefix}/{model}"
|
|
76
|
+
|
|
77
|
+
@staticmethod
|
|
78
|
+
def _count(model: str, messages: list[dict[str, str]]) -> int:
|
|
79
|
+
"""Calls LiteLLM lazily so importing the CLI remains lightweight."""
|
|
80
|
+
from litellm import token_counter
|
|
81
|
+
|
|
82
|
+
return int(token_counter(model=model, messages=messages))
|
|
83
|
+
|
|
84
|
+
@staticmethod
|
|
85
|
+
def _count_locally(model: str, messages: list[dict[str, str]]) -> int:
|
|
86
|
+
"""Counts message text locally when LiteLLM has no model support."""
|
|
87
|
+
import tiktoken
|
|
88
|
+
|
|
89
|
+
try:
|
|
90
|
+
encoding = tiktoken.encoding_for_model(model)
|
|
91
|
+
except KeyError:
|
|
92
|
+
encoding = tiktoken.get_encoding("cl100k_base")
|
|
93
|
+
|
|
94
|
+
serialized_messages = "\n".join(
|
|
95
|
+
f"{message.get('role', '')}: {message.get('content', '')}"
|
|
96
|
+
for message in messages
|
|
97
|
+
)
|
|
98
|
+
return len(encoding.encode(serialized_messages))
|