ai-nk-cce 0.1.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.
- ai_nk_cce-0.1.0/PKG-INFO +118 -0
- ai_nk_cce-0.1.0/README.md +89 -0
- ai_nk_cce-0.1.0/pyproject.toml +135 -0
- ai_nk_cce-0.1.0/src/api/__init__.py +0 -0
- ai_nk_cce-0.1.0/src/api/mpcdf_vllm.py +94 -0
- ai_nk_cce-0.1.0/src/evals/nk_model.py +277 -0
- ai_nk_cce-0.1.0/src/model/README.md +64 -0
- ai_nk_cce-0.1.0/src/model/config/dataset_conv_v1.yml +9 -0
- ai_nk_cce-0.1.0/src/model/config/dataset_conv_v2_m2.yml +9 -0
- ai_nk_cce-0.1.0/src/model/config/dataset_conv_v3_m2_assembl_nearest.yml +9 -0
- ai_nk_cce-0.1.0/src/model/config/dataset_debug.yml +9 -0
- ai_nk_cce-0.1.0/src/model/config/dataset_v4_int_format.yml +9 -0
- ai_nk_cce-0.1.0/src/model/config/dataset_v5.yml +9 -0
- ai_nk_cce-0.1.0/src/model/config/inference.yml +7 -0
- ai_nk_cce-0.1.0/src/model/config/train.yml +24 -0
- ai_nk_cce-0.1.0/src/model/config/train_debug.yml +19 -0
- ai_nk_cce-0.1.0/src/model/config/train_from_checkpoint.yml +24 -0
- ai_nk_cce-0.1.0/src/model/config/train_from_checkpoint_debug.yml +19 -0
- ai_nk_cce-0.1.0/src/model/config/train_grpo.yml +30 -0
- ai_nk_cce-0.1.0/src/model/config/train_grpo_debug.yml +30 -0
- ai_nk_cce-0.1.0/src/model/config/train_grpo_debug_vllm.yml +32 -0
- ai_nk_cce-0.1.0/src/model/config.py +54 -0
- ai_nk_cce-0.1.0/src/model/dataset.py +324 -0
- ai_nk_cce-0.1.0/src/model/inference.py +51 -0
- ai_nk_cce-0.1.0/src/model/nk_assistant.py +207 -0
- ai_nk_cce-0.1.0/src/model/parser.py +70 -0
- ai_nk_cce-0.1.0/src/model/run_slurm.py +335 -0
- ai_nk_cce-0.1.0/src/model/score.ipynb +596 -0
- ai_nk_cce-0.1.0/src/model/scripts/template.slurm +54 -0
- ai_nk_cce-0.1.0/src/model/scripts/template_rl.slurm +54 -0
- ai_nk_cce-0.1.0/src/model/train.py +293 -0
- ai_nk_cce-0.1.0/src/nk_model/__init__.py +0 -0
- ai_nk_cce-0.1.0/src/nk_model/assembler.py +112 -0
- ai_nk_cce-0.1.0/src/nk_model/biased_prediction_agent.py +389 -0
- ai_nk_cce-0.1.0/src/nk_model/dataset.py +434 -0
- ai_nk_cce-0.1.0/src/nk_model/enums.py +21 -0
- ai_nk_cce-0.1.0/src/nk_model/landscape_cache.py +149 -0
- ai_nk_cce-0.1.0/src/nk_model/models.py +172 -0
- ai_nk_cce-0.1.0/src/nk_model/nk_landscape.py +498 -0
- ai_nk_cce-0.1.0/src/simulation/hill_climber_simulation.py +211 -0
- ai_nk_cce-0.1.0/src/simulation/hill_climber_vs_ai_simulation.py +132 -0
- ai_nk_cce-0.1.0/src/simulation/landscape_selection.py +179 -0
- ai_nk_cce-0.1.0/src/utils/__init__.py +0 -0
- ai_nk_cce-0.1.0/src/utils/binary_conversion.py +128 -0
- ai_nk_cce-0.1.0/src/utils/logging.py +33 -0
- ai_nk_cce-0.1.0/src/utils/utils.py +51 -0
ai_nk_cce-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: ai-nk-cce
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: This repository is used to train AI agents to predict good strategies in a social learning game based on a NK landscape.
|
|
5
|
+
Author: Luis Mienhardt
|
|
6
|
+
Author-email: mienhardt@mpib-berlin.mpg.de
|
|
7
|
+
Requires-Python: >=3.10,<4.0
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Provides-Extra: model
|
|
14
|
+
Requires-Dist: dataframe-image (>=0.2.7,<0.3.0)
|
|
15
|
+
Requires-Dist: evaluate (>=0.4.3,<0.5.0)
|
|
16
|
+
Requires-Dist: matplotlib (>=3.9.2,<4.0.0)
|
|
17
|
+
Requires-Dist: networkx (>=3.4.2,<4.0.0)
|
|
18
|
+
Requires-Dist: numpy (>=1.26.0,<2.0.0)
|
|
19
|
+
Requires-Dist: openai (>=1.52.0,<2.0.0)
|
|
20
|
+
Requires-Dist: pandas (>=2.2.3,<3.0.0)
|
|
21
|
+
Requires-Dist: pydantic (>=2.0.0,<3.0.0)
|
|
22
|
+
Requires-Dist: python-dotenv (>=1.0.1,<2.0.0)
|
|
23
|
+
Requires-Dist: pyyaml (>=6.0.2,<7.0.0)
|
|
24
|
+
Requires-Dist: scikit-learn (>=1.5.2,<2.0.0)
|
|
25
|
+
Requires-Dist: tiktoken (>=0.8.0,<0.9.0)
|
|
26
|
+
Requires-Dist: tqdm (>=4.66.0,<5.0.0)
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# human-ai-social-learning
|
|
30
|
+
|
|
31
|
+
[](https://github.com/psf/black) [](https://www.python.org/dev/peps/pep-0008/)
|
|
32
|
+
|
|
33
|
+
## Description
|
|
34
|
+
|
|
35
|
+
## Installation
|
|
36
|
+
|
|
37
|
+
This project uses Poetry for package management. If you haven't installed Poetry yet, please follow the instructions on the [official Poetry website](https://python-poetry.org/docs/#installation).
|
|
38
|
+
|
|
39
|
+
To install the project:
|
|
40
|
+
|
|
41
|
+
1. Clone the repository:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
git clone https://github.com/your-username/human-ai-social-learning.git
|
|
45
|
+
cd human-ai-social-learning
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
2. Install dependencies with Poetry:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
poetry install
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
3. Activate the virtual environment:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
poetry shell
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
4. (Optional) Set up Jupyter kernel for notebooks:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
poetry run python -m ipykernel install --user --name nk-cce-kernel
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Now your development environment is set up and ready to use.
|
|
67
|
+
|
|
68
|
+
## Contributing
|
|
69
|
+
|
|
70
|
+
We welcome contributions! Please note:
|
|
71
|
+
|
|
72
|
+
1. Please create a descriptive branch for each contribution (naming convention *feature_type/feature_name*)
|
|
73
|
+
2. Follow the project style (PEP 8 for Python).
|
|
74
|
+
3. Add tests and run all before commit. (At least one test per function or method.)
|
|
75
|
+
4. Write meaningful commit messages.
|
|
76
|
+
5. Keep in line with pre-commit linting.
|
|
77
|
+
6. Submit a Pull Request, to include your code into main.
|
|
78
|
+
|
|
79
|
+
### Pre-commit Hooks
|
|
80
|
+
|
|
81
|
+
We use pre-commit hooks. Installation:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
poetry add pre-commit
|
|
85
|
+
pre-commit install
|
|
86
|
+
pre-commit run --all-files
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Running Tests
|
|
90
|
+
|
|
91
|
+
Tests need to be run in the virtual environment. You can use Poetry or Visual Studio Code settings to do so automatically.
|
|
92
|
+
|
|
93
|
+
To run all tests using Poetry run:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
poetry run pytest
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
We included Visual Studio Code settings in the repository.
|
|
100
|
+
You can try to use them to run the tests within Visual Studio Code.
|
|
101
|
+
|
|
102
|
+
```text
|
|
103
|
+
.vscode/
|
|
104
|
+
├── settings.json
|
|
105
|
+
├── launch.json
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Documentation
|
|
109
|
+
|
|
110
|
+
For an overview of the repository structure, module organization, and
|
|
111
|
+
dependencies, see the [Repository Structure Guide](doc/repository_structure.md).
|
|
112
|
+
|
|
113
|
+
Additional documentation is available in the `doc/` directory:
|
|
114
|
+
|
|
115
|
+
- [How to compare hill climber vs AI](doc/how_to_compare_hill_climber_vs_ai.md)
|
|
116
|
+
- [How to find average hill climber landscape](doc/how_to_find_average_hill_climber_landscape.md)
|
|
117
|
+
- [Using MPCDF LLM inference](doc/use_mpcdf_llm_inference.md)
|
|
118
|
+
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# human-ai-social-learning
|
|
2
|
+
|
|
3
|
+
[](https://github.com/psf/black) [](https://www.python.org/dev/peps/pep-0008/)
|
|
4
|
+
|
|
5
|
+
## Description
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
This project uses Poetry for package management. If you haven't installed Poetry yet, please follow the instructions on the [official Poetry website](https://python-poetry.org/docs/#installation).
|
|
10
|
+
|
|
11
|
+
To install the project:
|
|
12
|
+
|
|
13
|
+
1. Clone the repository:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
git clone https://github.com/your-username/human-ai-social-learning.git
|
|
17
|
+
cd human-ai-social-learning
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
2. Install dependencies with Poetry:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
poetry install
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
3. Activate the virtual environment:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
poetry shell
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
4. (Optional) Set up Jupyter kernel for notebooks:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
poetry run python -m ipykernel install --user --name nk-cce-kernel
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Now your development environment is set up and ready to use.
|
|
39
|
+
|
|
40
|
+
## Contributing
|
|
41
|
+
|
|
42
|
+
We welcome contributions! Please note:
|
|
43
|
+
|
|
44
|
+
1. Please create a descriptive branch for each contribution (naming convention *feature_type/feature_name*)
|
|
45
|
+
2. Follow the project style (PEP 8 for Python).
|
|
46
|
+
3. Add tests and run all before commit. (At least one test per function or method.)
|
|
47
|
+
4. Write meaningful commit messages.
|
|
48
|
+
5. Keep in line with pre-commit linting.
|
|
49
|
+
6. Submit a Pull Request, to include your code into main.
|
|
50
|
+
|
|
51
|
+
### Pre-commit Hooks
|
|
52
|
+
|
|
53
|
+
We use pre-commit hooks. Installation:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
poetry add pre-commit
|
|
57
|
+
pre-commit install
|
|
58
|
+
pre-commit run --all-files
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Running Tests
|
|
62
|
+
|
|
63
|
+
Tests need to be run in the virtual environment. You can use Poetry or Visual Studio Code settings to do so automatically.
|
|
64
|
+
|
|
65
|
+
To run all tests using Poetry run:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
poetry run pytest
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
We included Visual Studio Code settings in the repository.
|
|
72
|
+
You can try to use them to run the tests within Visual Studio Code.
|
|
73
|
+
|
|
74
|
+
```text
|
|
75
|
+
.vscode/
|
|
76
|
+
├── settings.json
|
|
77
|
+
├── launch.json
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Documentation
|
|
81
|
+
|
|
82
|
+
For an overview of the repository structure, module organization, and
|
|
83
|
+
dependencies, see the [Repository Structure Guide](doc/repository_structure.md).
|
|
84
|
+
|
|
85
|
+
Additional documentation is available in the `doc/` directory:
|
|
86
|
+
|
|
87
|
+
- [How to compare hill climber vs AI](doc/how_to_compare_hill_climber_vs_ai.md)
|
|
88
|
+
- [How to find average hill climber landscape](doc/how_to_find_average_hill_climber_landscape.md)
|
|
89
|
+
- [Using MPCDF LLM inference](doc/use_mpcdf_llm_inference.md)
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "ai-nk-cce"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "This repository is used to train AI agents to predict good strategies in a social learning game based on a NK landscape."
|
|
5
|
+
authors = [
|
|
6
|
+
"Luis Mienhardt <mienhardt@mpib-berlin.mpg.de>",
|
|
7
|
+
"Levin Brinkmann <brinkmann@mpib-berlin.mpg.de>",
|
|
8
|
+
"Bramantyo Ibrahim Supriyatno <supriyatno@mpib-berlin.mpg.de>",
|
|
9
|
+
]
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
packages = [
|
|
12
|
+
{ include = "api", from = "src" },
|
|
13
|
+
{ include = "evals", from = "src" },
|
|
14
|
+
{ include = "model", from = "src" },
|
|
15
|
+
{ include = "nk_model", from = "src" },
|
|
16
|
+
{ include = "simulation", from = "src" },
|
|
17
|
+
{ include = "utils", from = "src" },
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
[tool.poetry.dependencies]
|
|
21
|
+
numpy = "^1.26.0"
|
|
22
|
+
pandas = "^2.2.3"
|
|
23
|
+
pyyaml = "^6.0.2"
|
|
24
|
+
python = "^3.10"
|
|
25
|
+
matplotlib = "^3.9.2"
|
|
26
|
+
networkx = "^3.4.2"
|
|
27
|
+
openai = "^1.52.0"
|
|
28
|
+
python-dotenv = "^1.0.1"
|
|
29
|
+
scikit-learn = "^1.5.2"
|
|
30
|
+
evaluate = "^0.4.3"
|
|
31
|
+
tiktoken = "^0.8.0"
|
|
32
|
+
dataframe-image = "^0.2.7"
|
|
33
|
+
pydantic = "^2.0.0"
|
|
34
|
+
tqdm = "^4.66.0"
|
|
35
|
+
|
|
36
|
+
[tool.poetry.extras]
|
|
37
|
+
model = [
|
|
38
|
+
"seaborn",
|
|
39
|
+
"accelerate",
|
|
40
|
+
"transformers",
|
|
41
|
+
"tokenizers",
|
|
42
|
+
"torch",
|
|
43
|
+
"datasets",
|
|
44
|
+
"wandb",
|
|
45
|
+
"trl",
|
|
46
|
+
"git-lfs",
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
[tool.poetry.group.dev.dependencies]
|
|
50
|
+
black = "^24.10.0"
|
|
51
|
+
pylint = "^3.3.1"
|
|
52
|
+
pytest = "^8.3.3"
|
|
53
|
+
pre-commit = "^4.0.1"
|
|
54
|
+
pytest-mock = "^3.14.0"
|
|
55
|
+
coverage = "^7.10.3"
|
|
56
|
+
ipykernel = "^6.0.0"
|
|
57
|
+
jupyter = "^1.1.1"
|
|
58
|
+
pytest-asyncio = "^0.25.3"
|
|
59
|
+
tqdm = "^4.66.0"
|
|
60
|
+
|
|
61
|
+
[tool.poetry.group.model.dependencies]
|
|
62
|
+
seaborn = "^0.13.2"
|
|
63
|
+
accelerate = "^1.0.1"
|
|
64
|
+
transformers = "^4.57.3"
|
|
65
|
+
tokenizers = "^0.22.1"
|
|
66
|
+
torch = "^2.1.0"
|
|
67
|
+
datasets = "4.0.0"
|
|
68
|
+
wandb = "^0.18.7"
|
|
69
|
+
trl = "^0.18.1"
|
|
70
|
+
git-lfs = "^1.6"
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
[tool.black]
|
|
74
|
+
line-length = 79
|
|
75
|
+
target-version = ['py310']
|
|
76
|
+
include = '\.pyi?$'
|
|
77
|
+
extend-exclude = '''
|
|
78
|
+
/(
|
|
79
|
+
# directories
|
|
80
|
+
\.eggs
|
|
81
|
+
| \.git
|
|
82
|
+
| \.hg
|
|
83
|
+
| \.mypy_cache
|
|
84
|
+
| \.tox
|
|
85
|
+
| \.venv
|
|
86
|
+
| build
|
|
87
|
+
| dist
|
|
88
|
+
)/
|
|
89
|
+
'''
|
|
90
|
+
|
|
91
|
+
[tool.isort]
|
|
92
|
+
profile = "black"
|
|
93
|
+
line_length = 79
|
|
94
|
+
|
|
95
|
+
[tool.flake8]
|
|
96
|
+
max-line-length = 79
|
|
97
|
+
extend-ignore = "E203, W503"
|
|
98
|
+
max-complexity = 10
|
|
99
|
+
|
|
100
|
+
[tool.pytest.ini_options]
|
|
101
|
+
testpaths = ["."]
|
|
102
|
+
python_files = "test_*.py"
|
|
103
|
+
python_classes = "Test*"
|
|
104
|
+
python_functions = "test_*"
|
|
105
|
+
addopts = "-v -ra -s"
|
|
106
|
+
pythonpath = [
|
|
107
|
+
"src"
|
|
108
|
+
]
|
|
109
|
+
|
|
110
|
+
[tool.coverage.run]
|
|
111
|
+
source = ["src"]
|
|
112
|
+
omit = [
|
|
113
|
+
"*/tests/*",
|
|
114
|
+
"*/test_*.py",
|
|
115
|
+
"*/__pycache__/*",
|
|
116
|
+
"*/conftest.py",
|
|
117
|
+
]
|
|
118
|
+
|
|
119
|
+
[tool.coverage.report]
|
|
120
|
+
exclude_lines = [
|
|
121
|
+
"pragma: no cover",
|
|
122
|
+
"def __repr__",
|
|
123
|
+
"raise AssertionError",
|
|
124
|
+
"raise NotImplementedError",
|
|
125
|
+
"if __name__ == .__main__.:",
|
|
126
|
+
"if TYPE_CHECKING:",
|
|
127
|
+
"@abstractmethod",
|
|
128
|
+
]
|
|
129
|
+
precision = 2
|
|
130
|
+
show_missing = true
|
|
131
|
+
skip_covered = false
|
|
132
|
+
|
|
133
|
+
[build-system]
|
|
134
|
+
requires = ["poetry-core"]
|
|
135
|
+
build-backend = "poetry.core.masonry.api"
|
|
File without changes
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import time
|
|
3
|
+
from typing import Any, Optional
|
|
4
|
+
|
|
5
|
+
import httpx
|
|
6
|
+
from dotenv import load_dotenv
|
|
7
|
+
|
|
8
|
+
from src.utils.logging import log_dec
|
|
9
|
+
|
|
10
|
+
load_dotenv()
|
|
11
|
+
|
|
12
|
+
BASE_URL = os.getenv("MPCDF_BASE_URL")
|
|
13
|
+
API_KEY = os.getenv("MPCDF_API_KEY")
|
|
14
|
+
MODEL_NAME = "center-for-humans-and-machines/assembl_nk_1"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@log_dec
|
|
18
|
+
def mpcdf_vllm_request(
|
|
19
|
+
prompt: str,
|
|
20
|
+
model: Optional[str] = None,
|
|
21
|
+
max_tokens: int = 150,
|
|
22
|
+
temperature: float = 0.7,
|
|
23
|
+
timeout: float = 30.0,
|
|
24
|
+
max_retries: int = 3,
|
|
25
|
+
initial_backoff: float = 1.0,
|
|
26
|
+
**kwargs: Any,
|
|
27
|
+
) -> str:
|
|
28
|
+
"""Make request to vLLM model with tokenized input.
|
|
29
|
+
|
|
30
|
+
Uses the /v1/completions endpoint which supports prompt_token_ids
|
|
31
|
+
directly, bypassing the tokenizer. This function tokenizes the prompt
|
|
32
|
+
and sends it as token IDs.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
prompt: Text prompt string to send to the model.
|
|
36
|
+
model: Model name (defaults to MODEL_NAME).
|
|
37
|
+
max_tokens: Maximum tokens to generate.
|
|
38
|
+
temperature: Sampling temperature.
|
|
39
|
+
timeout: Request timeout in seconds.
|
|
40
|
+
max_retries: Maximum number of retry attempts (default: 3).
|
|
41
|
+
initial_backoff: Initial backoff delay in seconds (default: 1.0).
|
|
42
|
+
**kwargs: Additional parameters for completion request.
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
Generated text content.
|
|
46
|
+
"""
|
|
47
|
+
# Build request URL - ensure /v1 prefix if not present
|
|
48
|
+
base = BASE_URL.rstrip("/")
|
|
49
|
+
if not base.endswith("/v1"):
|
|
50
|
+
base = f"{base}/v1"
|
|
51
|
+
url = f"{base}/completions"
|
|
52
|
+
|
|
53
|
+
# Prepare payload - use prompt_token_ids for completions endpoint
|
|
54
|
+
payload = {
|
|
55
|
+
"model": model or MODEL_NAME,
|
|
56
|
+
"prompt": prompt,
|
|
57
|
+
"max_tokens": max_tokens,
|
|
58
|
+
"temperature": temperature,
|
|
59
|
+
**kwargs,
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
# Make HTTP request
|
|
63
|
+
headers = {
|
|
64
|
+
"Authorization": f"Bearer {API_KEY}",
|
|
65
|
+
"Content-Type": "application/json",
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
last_exception = None
|
|
69
|
+
for attempt in range(max_retries + 1):
|
|
70
|
+
try:
|
|
71
|
+
with httpx.Client(timeout=timeout) as http_client:
|
|
72
|
+
response = http_client.post(url, json=payload, headers=headers)
|
|
73
|
+
response.raise_for_status()
|
|
74
|
+
result = response.json()
|
|
75
|
+
|
|
76
|
+
# Completions endpoint returns text directly
|
|
77
|
+
return result["choices"][0]["text"]
|
|
78
|
+
except (
|
|
79
|
+
httpx.HTTPStatusError,
|
|
80
|
+
httpx.RequestError,
|
|
81
|
+
httpx.TimeoutException,
|
|
82
|
+
httpx.NetworkError,
|
|
83
|
+
) as e:
|
|
84
|
+
last_exception = e
|
|
85
|
+
if attempt < max_retries:
|
|
86
|
+
backoff = initial_backoff * (2**attempt)
|
|
87
|
+
time.sleep(backoff)
|
|
88
|
+
continue
|
|
89
|
+
raise
|
|
90
|
+
|
|
91
|
+
# This should never be reached, but type checker needs it
|
|
92
|
+
if last_exception:
|
|
93
|
+
raise last_exception
|
|
94
|
+
raise RuntimeError("Request failed unexpectedly")
|