strike-ai 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.
@@ -0,0 +1,25 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ workflow_dispatch:
7
+
8
+ jobs:
9
+ pypi:
10
+ name: Publish
11
+ runs-on: ubuntu-latest
12
+ environment: pypi
13
+ permissions:
14
+ id-token: write
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.12"
20
+ - name: Build
21
+ run: |
22
+ python -m pip install --upgrade build
23
+ python -m build
24
+ - name: Publish
25
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,5 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .venv/
4
+ dist/
5
+ *.egg-info/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Strike
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,96 @@
1
+ Metadata-Version: 2.5
2
+ Name: strike-ai
3
+ Version: 0.1.0
4
+ Summary: Client for the Strike API: typed yes/no, choice, and score decisions.
5
+ Project-URL: Homepage, https://strike-ai.eu
6
+ Project-URL: Documentation, https://strike-ai.eu/docs
7
+ Project-URL: Repository, https://github.com/strikeai/strike
8
+ Author-email: Strike <hello@strike-ai.eu>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: decisions,strike
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Typing :: Typed
14
+ Requires-Python: >=3.10
15
+ Requires-Dist: httpx>=0.25
16
+ Description-Content-Type: text/markdown
17
+
18
+ # strike-ai
19
+
20
+ Python client for the [Strike](https://strike-ai.eu) API. You send content and typed questions. You get one answer per question, with probabilities.
21
+
22
+ ```bash
23
+ pip install strike-ai
24
+ ```
25
+
26
+ ```python
27
+ import os
28
+ from strike_ai import Client
29
+
30
+ client = Client(api_key=os.environ["STRIKE_API_KEY"])
31
+ result = client.decide(
32
+ "My card was charged twice for the same order. Please fix this today.",
33
+ {
34
+ "is_urgent": {
35
+ "type": "noul",
36
+ "instructions": "Does the customer express time pressure?",
37
+ },
38
+ "team": {
39
+ "type": "choice",
40
+ "instructions": "Which team should handle this message?",
41
+ "criteria": {
42
+ "billing": "Payments, refunds, invoices",
43
+ "technical": "Bugs, outages, integrations",
44
+ "other": None,
45
+ },
46
+ },
47
+ },
48
+ )
49
+ ```
50
+
51
+ `STRIKE_API_URL` overrides the default base URL, `https://strike-ai.eu`.
52
+
53
+ Strike is in beta. `strike-1` returns real model probabilities. They are not calibrated for production routing yet.
54
+
55
+ This repository is the public client. Model weights, training, and the API server are not in it.
56
+
57
+ ## Endpoint
58
+
59
+ `POST https://strike-ai.eu/v1/systemone`
60
+
61
+ | Type | You ask | You get |
62
+ | --- | --- | --- |
63
+ | `noul` | A yes/no question | A value from 0 (no) to 1 (yes) |
64
+ | `choice` | One option from a set you define | The top option and a probability for every option |
65
+ | `score` | A rating on levels you define | A probability-weighted score and a probability per level |
66
+
67
+ The same call with curl:
68
+
69
+ ```bash
70
+ curl https://strike-ai.eu/v1/systemone \
71
+ -H "Authorization: Bearer $STRIKE_API_KEY" \
72
+ -H "Content-Type: application/json" \
73
+ -d '{
74
+ "model": "strike-1",
75
+ "state": "My card was charged twice for the same order. Please fix this today.",
76
+ "questions": {
77
+ "is_urgent": {
78
+ "type": "noul",
79
+ "instructions": "Does the customer express time pressure?"
80
+ },
81
+ "team": {
82
+ "type": "choice",
83
+ "instructions": "Which team should handle this message?",
84
+ "criteria": {
85
+ "billing": "Payments, refunds, invoices",
86
+ "technical": "Bugs, outages, integrations",
87
+ "other": null
88
+ }
89
+ }
90
+ }
91
+ }'
92
+ ```
93
+
94
+ Docs: [strike-ai.eu/docs](https://strike-ai.eu/docs). Contact: [hello@strike-ai.eu](mailto:hello@strike-ai.eu).
95
+
96
+ Strike is not affiliated with TypeSafe. The hosted API speaks a System One-compatible wire format.
@@ -0,0 +1,79 @@
1
+ # strike-ai
2
+
3
+ Python client for the [Strike](https://strike-ai.eu) API. You send content and typed questions. You get one answer per question, with probabilities.
4
+
5
+ ```bash
6
+ pip install strike-ai
7
+ ```
8
+
9
+ ```python
10
+ import os
11
+ from strike_ai import Client
12
+
13
+ client = Client(api_key=os.environ["STRIKE_API_KEY"])
14
+ result = client.decide(
15
+ "My card was charged twice for the same order. Please fix this today.",
16
+ {
17
+ "is_urgent": {
18
+ "type": "noul",
19
+ "instructions": "Does the customer express time pressure?",
20
+ },
21
+ "team": {
22
+ "type": "choice",
23
+ "instructions": "Which team should handle this message?",
24
+ "criteria": {
25
+ "billing": "Payments, refunds, invoices",
26
+ "technical": "Bugs, outages, integrations",
27
+ "other": None,
28
+ },
29
+ },
30
+ },
31
+ )
32
+ ```
33
+
34
+ `STRIKE_API_URL` overrides the default base URL, `https://strike-ai.eu`.
35
+
36
+ Strike is in beta. `strike-1` returns real model probabilities. They are not calibrated for production routing yet.
37
+
38
+ This repository is the public client. Model weights, training, and the API server are not in it.
39
+
40
+ ## Endpoint
41
+
42
+ `POST https://strike-ai.eu/v1/systemone`
43
+
44
+ | Type | You ask | You get |
45
+ | --- | --- | --- |
46
+ | `noul` | A yes/no question | A value from 0 (no) to 1 (yes) |
47
+ | `choice` | One option from a set you define | The top option and a probability for every option |
48
+ | `score` | A rating on levels you define | A probability-weighted score and a probability per level |
49
+
50
+ The same call with curl:
51
+
52
+ ```bash
53
+ curl https://strike-ai.eu/v1/systemone \
54
+ -H "Authorization: Bearer $STRIKE_API_KEY" \
55
+ -H "Content-Type: application/json" \
56
+ -d '{
57
+ "model": "strike-1",
58
+ "state": "My card was charged twice for the same order. Please fix this today.",
59
+ "questions": {
60
+ "is_urgent": {
61
+ "type": "noul",
62
+ "instructions": "Does the customer express time pressure?"
63
+ },
64
+ "team": {
65
+ "type": "choice",
66
+ "instructions": "Which team should handle this message?",
67
+ "criteria": {
68
+ "billing": "Payments, refunds, invoices",
69
+ "technical": "Bugs, outages, integrations",
70
+ "other": null
71
+ }
72
+ }
73
+ }
74
+ }'
75
+ ```
76
+
77
+ Docs: [strike-ai.eu/docs](https://strike-ai.eu/docs). Contact: [hello@strike-ai.eu](mailto:hello@strike-ai.eu).
78
+
79
+ Strike is not affiliated with TypeSafe. The hosted API speaks a System One-compatible wire format.
@@ -0,0 +1,27 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "strike-ai"
7
+ version = "0.1.0"
8
+ description = "Client for the Strike API: typed yes/no, choice, and score decisions."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "Strike", email = "hello@strike-ai.eu" }]
14
+ dependencies = ["httpx>=0.25"]
15
+ classifiers = [
16
+ "Programming Language :: Python :: 3",
17
+ "Typing :: Typed",
18
+ ]
19
+ keywords = ["strike", "decisions"]
20
+
21
+ [project.urls]
22
+ Homepage = "https://strike-ai.eu"
23
+ Documentation = "https://strike-ai.eu/docs"
24
+ Repository = "https://github.com/strikeai/strike"
25
+
26
+ [tool.hatch.build.targets.wheel]
27
+ packages = ["strike_ai"]
@@ -0,0 +1,53 @@
1
+ """Client for the hosted Strike API."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from typing import Any
7
+
8
+ import httpx
9
+
10
+ __version__ = "0.1.0"
11
+
12
+ _DEFAULT_URL = "https://strike-ai.eu"
13
+
14
+
15
+ class Client:
16
+ """Call ``POST /v1/systemone`` on the hosted Strike API."""
17
+
18
+ def __init__(
19
+ self,
20
+ api_key: str | None = None,
21
+ *,
22
+ base_url: str | None = None,
23
+ timeout: float = 60.0,
24
+ ) -> None:
25
+ self.api_key = api_key if api_key is not None else os.environ.get("STRIKE_API_KEY", "")
26
+ self.base_url = (base_url or os.environ.get("STRIKE_API_URL", _DEFAULT_URL)).rstrip("/")
27
+ self.timeout = timeout
28
+
29
+ def decide(
30
+ self,
31
+ state: Any,
32
+ questions: dict[str, Any],
33
+ *,
34
+ model: str = "strike-1",
35
+ options: dict[str, Any] | None = None,
36
+ idempotency_key: str | None = None,
37
+ ) -> dict[str, Any]:
38
+ body: dict[str, Any] = {"model": model, "state": state, "questions": questions}
39
+ if options:
40
+ body["options"] = options
41
+ headers = {"Content-Type": "application/json"}
42
+ if self.api_key:
43
+ headers["Authorization"] = f"Bearer {self.api_key}"
44
+ if idempotency_key:
45
+ headers["Idempotency-Key"] = idempotency_key
46
+ response = httpx.post(
47
+ f"{self.base_url}/v1/systemone",
48
+ json=body,
49
+ headers=headers,
50
+ timeout=self.timeout,
51
+ )
52
+ response.raise_for_status()
53
+ return response.json()
File without changes