general-augment-sdk 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,55 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.so
5
+ .coverage
6
+ .mypy_cache/
7
+ .pytest_cache/
8
+ .ruff_cache/
9
+ .venv/
10
+ packages/cli/uv.lock
11
+
12
+ # Environment
13
+ .env
14
+ .env.local
15
+ .env.gcp
16
+ hermes-tenants/
17
+
18
+ # Secrets
19
+ *.pem
20
+ *.key
21
+ *.p12
22
+ *.pfx
23
+ .jks
24
+ service-account.json
25
+ .clerk/
26
+
27
+ # Docker
28
+ *.log
29
+ docker-data/
30
+
31
+ # IDE
32
+ .idea/
33
+ .vscode/
34
+
35
+ # Build
36
+ build/
37
+ dist/
38
+ *.egg-info/
39
+ node_modules/
40
+ .next/
41
+ dashboard/.vercel/
42
+ coverage/
43
+ playwright-report/
44
+ test-results/
45
+ *.tsbuildinfo
46
+ artifacts/
47
+ dashboard/artifacts/
48
+
49
+ # Kubernetes secrets
50
+ k8s/secrets/*
51
+ !k8s/secrets/.gitkeep
52
+
53
+ # OS
54
+ .DS_Store
55
+ .vercel
@@ -0,0 +1,14 @@
1
+ # Python SDK Agent Instructions
2
+
3
+ These instructions apply under `packages/python-sdk/`.
4
+
5
+ Inherit [`packages/AGENTS.md`](../AGENTS.md) and the repo root
6
+ [`AGENTS.md`](../../AGENTS.md).
7
+
8
+ ## Scope
9
+
10
+ - This package directory keeps a historical name. Public docs and examples should
11
+ describe General Augment and the `genaug` import path.
12
+ - Use current hosted endpoints, `genaug-agent.yaml`, and `/v1/responses`-aligned flows in
13
+ examples and READMEs.
14
+ - Update docs plus tests when public behavior changes.
@@ -0,0 +1,165 @@
1
+ Metadata-Version: 2.4
2
+ Name: general-augment-sdk
3
+ Version: 0.1.0
4
+ Summary: Python SDK for the General Augment admin and integration APIs.
5
+ Project-URL: Documentation, https://docs.generalaugment.com
6
+ Project-URL: Source, https://github.com/Bikz/general-augment-platform
7
+ Author: General Augment
8
+ License-Expression: MIT
9
+ Requires-Python: >=3.10
10
+ Requires-Dist: httpx>=0.28.0
11
+ Requires-Dist: pyyaml>=6.0.0
12
+ Description-Content-Type: text/markdown
13
+
14
+ # General Augment Python SDK
15
+
16
+ Backend SDK for General Augment app integrations. Use it from trusted server code.
17
+ Project-scoped keys are for app traffic such as Responses and memory calls. Admin and
18
+ setup helpers require a management/admin-capable key and send it as `X-Admin-Key`.
19
+
20
+ During private beta, package publishing may not be available in every package index. If
21
+ installing the package fails, use the repository package path for local tests or raw HTTP
22
+ examples in the public docs until `scripts/package-registry-readiness.py` reports the
23
+ expected package version as published.
24
+
25
+ ```bash
26
+ pip install general-augment-sdk
27
+ ```
28
+
29
+ ```python
30
+ import os
31
+
32
+ from genaug import (
33
+ GeneralAugmentClient,
34
+ __version__,
35
+ response_output_text,
36
+ response_structured_output,
37
+ )
38
+
39
+ client = GeneralAugmentClient(
40
+ api_key=os.environ["GENAUG_API_KEY"],
41
+ base_url=os.getenv("GENAUG_API_BASE_URL", "https://api.generalaugment.com"),
42
+ )
43
+
44
+ print(f"General Augment SDK {__version__}")
45
+ ```
46
+
47
+ ## Responses
48
+
49
+ ```python
50
+ response = client.create_response(
51
+ {
52
+ "model": "balanced",
53
+ "user": "app-user-123",
54
+ "input": "Reply with a concise onboarding summary.",
55
+ "metadata": {"feature": "onboarding"},
56
+ },
57
+ idempotency_key="onboarding-turn-1",
58
+ request_id="req_app_123",
59
+ )
60
+
61
+ print(response_output_text(response))
62
+ ```
63
+
64
+ Structured output:
65
+
66
+ ```python
67
+ structured_response = client.create_response(
68
+ {
69
+ "model": "balanced",
70
+ "user": "app-user-123",
71
+ "input": "Extract the user's preference: window seat.",
72
+ "text": {
73
+ "format": {
74
+ "type": "json_schema",
75
+ "name": "preference",
76
+ "strict": True,
77
+ "schema": {
78
+ "type": "object",
79
+ "required": ["seat"],
80
+ "properties": {"seat": {"type": "string"}},
81
+ "additionalProperties": False,
82
+ },
83
+ }
84
+ },
85
+ }
86
+ )
87
+
88
+ preference = response_structured_output(structured_response)
89
+ ```
90
+
91
+ Streaming:
92
+
93
+ ```python
94
+ for event in client.stream_response(
95
+ {
96
+ "model": "balanced",
97
+ "user": "app-user-123",
98
+ "input": "Draft a two sentence welcome message.",
99
+ }
100
+ ):
101
+ if event["event"] == "response.output_text.delta":
102
+ print(event["data"].get("delta", ""), end="")
103
+ ```
104
+
105
+ ## Memory
106
+
107
+ ```python
108
+ stored = client.store_memory(
109
+ {
110
+ "user_id": "app-user-123",
111
+ "fact": "User prefers window seats",
112
+ "fact_type": "preference",
113
+ "importance_score": 0.9,
114
+ "idempotency_key": "memory-window-seat-1",
115
+ }
116
+ )
117
+
118
+ client.search_memory({"user_id": "app-user-123", "query": "seat preference"})
119
+ client.memory_profile("app-user-123")
120
+ client.delete_memory(str(stored["memory_id"]), user_id="app-user-123")
121
+ client.purge_user_memory("app-user-123")
122
+ ```
123
+
124
+ ## Usage
125
+
126
+ ```python
127
+ usage = client.usage("project_123", start_date="2026-04-01", end_date="2026-04-24")
128
+ print(usage["totals"])
129
+ ```
130
+
131
+ ## Error Handling
132
+
133
+ ```python
134
+ from genaug import GeneralAugmentAPIError
135
+
136
+ try:
137
+ client.create_response({"model": "balanced", "input": "Hello"})
138
+ except GeneralAugmentAPIError as exc:
139
+ if exc.reason == "rate_limit_exceeded":
140
+ print(f"Retry after {exc.retry_after} seconds")
141
+ print(exc.request_id, exc.trace_id, exc.detail)
142
+ ```
143
+
144
+ `GeneralAugmentAPIError` preserves the HTTP status, stable `reason`/`code` when the
145
+ API returns one, `Retry-After`, `X-RateLimit-*`, request/trace IDs, and the decoded JSON
146
+ body. Existing code that only reads `status_code` or `detail` keeps working.
147
+
148
+ ## Local Tests
149
+
150
+ Run the local mock server and point the SDK at it:
151
+
152
+ ```bash
153
+ uv run --project packages/cli genaug mock --host 127.0.0.1 --port 8787 --quiet
154
+ export GENAUG_API_BASE_URL="http://127.0.0.1:8787"
155
+ export GENAUG_API_KEY="local-test"
156
+ PYTHONPATH=src python examples/contract_test.py
157
+ ```
158
+
159
+ The contract example covers a Responses turn plus memory store/search against the same
160
+ deterministic routes used by app backend CI.
161
+
162
+ ## Other Helpers
163
+
164
+ The SDK also includes `create_project_from_config`, `register_openapi_tools`,
165
+ `link_user`, `usage`, and `test_agent` for admin and integration workflows.
@@ -0,0 +1,152 @@
1
+ # General Augment Python SDK
2
+
3
+ Backend SDK for General Augment app integrations. Use it from trusted server code.
4
+ Project-scoped keys are for app traffic such as Responses and memory calls. Admin and
5
+ setup helpers require a management/admin-capable key and send it as `X-Admin-Key`.
6
+
7
+ During private beta, package publishing may not be available in every package index. If
8
+ installing the package fails, use the repository package path for local tests or raw HTTP
9
+ examples in the public docs until `scripts/package-registry-readiness.py` reports the
10
+ expected package version as published.
11
+
12
+ ```bash
13
+ pip install general-augment-sdk
14
+ ```
15
+
16
+ ```python
17
+ import os
18
+
19
+ from genaug import (
20
+ GeneralAugmentClient,
21
+ __version__,
22
+ response_output_text,
23
+ response_structured_output,
24
+ )
25
+
26
+ client = GeneralAugmentClient(
27
+ api_key=os.environ["GENAUG_API_KEY"],
28
+ base_url=os.getenv("GENAUG_API_BASE_URL", "https://api.generalaugment.com"),
29
+ )
30
+
31
+ print(f"General Augment SDK {__version__}")
32
+ ```
33
+
34
+ ## Responses
35
+
36
+ ```python
37
+ response = client.create_response(
38
+ {
39
+ "model": "balanced",
40
+ "user": "app-user-123",
41
+ "input": "Reply with a concise onboarding summary.",
42
+ "metadata": {"feature": "onboarding"},
43
+ },
44
+ idempotency_key="onboarding-turn-1",
45
+ request_id="req_app_123",
46
+ )
47
+
48
+ print(response_output_text(response))
49
+ ```
50
+
51
+ Structured output:
52
+
53
+ ```python
54
+ structured_response = client.create_response(
55
+ {
56
+ "model": "balanced",
57
+ "user": "app-user-123",
58
+ "input": "Extract the user's preference: window seat.",
59
+ "text": {
60
+ "format": {
61
+ "type": "json_schema",
62
+ "name": "preference",
63
+ "strict": True,
64
+ "schema": {
65
+ "type": "object",
66
+ "required": ["seat"],
67
+ "properties": {"seat": {"type": "string"}},
68
+ "additionalProperties": False,
69
+ },
70
+ }
71
+ },
72
+ }
73
+ )
74
+
75
+ preference = response_structured_output(structured_response)
76
+ ```
77
+
78
+ Streaming:
79
+
80
+ ```python
81
+ for event in client.stream_response(
82
+ {
83
+ "model": "balanced",
84
+ "user": "app-user-123",
85
+ "input": "Draft a two sentence welcome message.",
86
+ }
87
+ ):
88
+ if event["event"] == "response.output_text.delta":
89
+ print(event["data"].get("delta", ""), end="")
90
+ ```
91
+
92
+ ## Memory
93
+
94
+ ```python
95
+ stored = client.store_memory(
96
+ {
97
+ "user_id": "app-user-123",
98
+ "fact": "User prefers window seats",
99
+ "fact_type": "preference",
100
+ "importance_score": 0.9,
101
+ "idempotency_key": "memory-window-seat-1",
102
+ }
103
+ )
104
+
105
+ client.search_memory({"user_id": "app-user-123", "query": "seat preference"})
106
+ client.memory_profile("app-user-123")
107
+ client.delete_memory(str(stored["memory_id"]), user_id="app-user-123")
108
+ client.purge_user_memory("app-user-123")
109
+ ```
110
+
111
+ ## Usage
112
+
113
+ ```python
114
+ usage = client.usage("project_123", start_date="2026-04-01", end_date="2026-04-24")
115
+ print(usage["totals"])
116
+ ```
117
+
118
+ ## Error Handling
119
+
120
+ ```python
121
+ from genaug import GeneralAugmentAPIError
122
+
123
+ try:
124
+ client.create_response({"model": "balanced", "input": "Hello"})
125
+ except GeneralAugmentAPIError as exc:
126
+ if exc.reason == "rate_limit_exceeded":
127
+ print(f"Retry after {exc.retry_after} seconds")
128
+ print(exc.request_id, exc.trace_id, exc.detail)
129
+ ```
130
+
131
+ `GeneralAugmentAPIError` preserves the HTTP status, stable `reason`/`code` when the
132
+ API returns one, `Retry-After`, `X-RateLimit-*`, request/trace IDs, and the decoded JSON
133
+ body. Existing code that only reads `status_code` or `detail` keeps working.
134
+
135
+ ## Local Tests
136
+
137
+ Run the local mock server and point the SDK at it:
138
+
139
+ ```bash
140
+ uv run --project packages/cli genaug mock --host 127.0.0.1 --port 8787 --quiet
141
+ export GENAUG_API_BASE_URL="http://127.0.0.1:8787"
142
+ export GENAUG_API_KEY="local-test"
143
+ PYTHONPATH=src python examples/contract_test.py
144
+ ```
145
+
146
+ The contract example covers a Responses turn plus memory store/search against the same
147
+ deterministic routes used by app backend CI.
148
+
149
+ ## Other Helpers
150
+
151
+ The SDK also includes `create_project_from_config`, `register_openapi_tools`,
152
+ `link_user`, `usage`, and `test_agent` for admin and integration workflows.
@@ -0,0 +1,54 @@
1
+ """Mock-backed contract example for the General Augment Python SDK.
2
+
3
+ Run `uv run --project packages/cli genaug mock --host 127.0.0.1 --port 8787 --quiet`
4
+ from the repository root, then run this file with GENAUG_API_BASE_URL pointed at the
5
+ mock server.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import os
11
+
12
+ from genaug import GeneralAugmentClient, response_output_text
13
+
14
+
15
+ def main() -> None:
16
+ """Exercise Responses and memory against the local mock contract."""
17
+ client = GeneralAugmentClient(
18
+ api_key=os.getenv("GENAUG_API_KEY", "local-test"),
19
+ base_url=os.getenv("GENAUG_API_BASE_URL", "http://127.0.0.1:8787"),
20
+ )
21
+
22
+ response = client.create_response(
23
+ {
24
+ "model": "balanced",
25
+ "user": "sdk-contract-user",
26
+ "input": "Reply exactly with: local-mock-ok",
27
+ "metadata": {"fixture": "sdk-contract"},
28
+ },
29
+ idempotency_key="sdk-contract-turn-1",
30
+ request_id="req_sdk_contract_py",
31
+ )
32
+ assert response["status"] == "completed"
33
+ assert response_output_text(response)
34
+
35
+ stored = client.store_memory(
36
+ {
37
+ "user_id": "sdk-contract-user",
38
+ "fact": "User prefers window seats",
39
+ "fact_type": "preference",
40
+ "idempotency_key": "sdk-contract-memory-1",
41
+ }
42
+ )
43
+ assert stored.get("memory_id") or stored.get("id")
44
+
45
+ search = client.search_memory(
46
+ {"user_id": "sdk-contract-user", "query": "seat preference", "limit": 3}
47
+ )
48
+ assert isinstance(search.get("facts"), list)
49
+
50
+ print("General Augment Python SDK contract example passed.")
51
+
52
+
53
+ if __name__ == "__main__":
54
+ main()
@@ -0,0 +1,40 @@
1
+ """Minimal General Augment Python SDK quickstart."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from pathlib import Path
7
+
8
+ from genaug import GeneralAugmentClient, response_output_text
9
+ from genaug.identity import link_user
10
+ from genaug.tools import register_from_openapi
11
+
12
+
13
+ def main() -> None:
14
+ """Deploy a config, register tools, link a user, and call Responses."""
15
+ api_key = os.environ["GENAUG_API_KEY"]
16
+ spec_url = os.environ["OPENAPI_SPEC_URL"]
17
+ with GeneralAugmentClient(api_key=api_key) as client:
18
+ project = client.deploy_config_file(Path("genaug-agent.yaml"))
19
+ register_from_openapi(spec_url, client=client, project_id=str(project["id"]))
20
+ link_user(
21
+ client,
22
+ str(project["id"]),
23
+ phone="+15551234567",
24
+ app_user_id="app-user-123",
25
+ )
26
+ response = client.create_response(
27
+ {
28
+ "model": "balanced",
29
+ "user": "app-user-123",
30
+ "input": "Reply with a concise onboarding summary.",
31
+ "metadata": {"feature": "sdk-quickstart"},
32
+ },
33
+ idempotency_key="sdk-quickstart-turn-1",
34
+ request_id="req_sdk_quickstart",
35
+ )
36
+ print(response_output_text(response))
37
+
38
+
39
+ if __name__ == "__main__":
40
+ main()
@@ -0,0 +1,23 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "general-augment-sdk"
7
+ version = "0.1.0"
8
+ description = "Python SDK for the General Augment admin and integration APIs."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ authors = [{ name = "General Augment" }]
13
+ dependencies = [
14
+ "httpx>=0.28.0",
15
+ "pyyaml>=6.0.0",
16
+ ]
17
+
18
+ [project.urls]
19
+ Documentation = "https://docs.generalaugment.com"
20
+ Source = "https://github.com/Bikz/general-augment-platform"
21
+
22
+ [tool.hatch.build.targets.wheel]
23
+ packages = ["src/genaug"]
@@ -0,0 +1,20 @@
1
+ """General Augment Python SDK public import path."""
2
+
3
+ from genaug.agent import AgentClient
4
+ from genaug.client import (
5
+ GeneralAugmentAPIError,
6
+ GeneralAugmentClient,
7
+ response_output_text,
8
+ response_structured_output,
9
+ )
10
+
11
+ __version__ = "0.1.0"
12
+
13
+ __all__ = [
14
+ "AgentClient",
15
+ "GeneralAugmentAPIError",
16
+ "GeneralAugmentClient",
17
+ "__version__",
18
+ "response_output_text",
19
+ "response_structured_output",
20
+ ]
@@ -0,0 +1,48 @@
1
+ """Agent test helpers for General Augment SDK users."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from genaug.client import GeneralAugmentClient
8
+
9
+
10
+ class AgentClient:
11
+ """Convenience wrapper scoped to one General Augment project."""
12
+
13
+ def __init__(self, client: GeneralAugmentClient, project_id: str) -> None:
14
+ """Initialize a project-scoped agent client."""
15
+ self.client = client
16
+ self.project_id = project_id
17
+
18
+ def test(
19
+ self,
20
+ message: str,
21
+ *,
22
+ phone_e164: str = "+15550000000",
23
+ channel: str = "whatsapp",
24
+ ) -> dict[str, Any]:
25
+ """Send a test message to the configured agent."""
26
+ return self.client.test_agent(
27
+ self.project_id,
28
+ message,
29
+ phone_e164=phone_e164,
30
+ channel=channel,
31
+ )
32
+
33
+
34
+ def test(
35
+ client: GeneralAugmentClient,
36
+ project_id: str,
37
+ message: str,
38
+ *,
39
+ phone_e164: str = "+15550000000",
40
+ channel: str = "whatsapp",
41
+ ) -> dict[str, Any]:
42
+ """Send a one-off test message to a General Augment project."""
43
+ return client.test_agent(
44
+ project_id,
45
+ message,
46
+ phone_e164=phone_e164,
47
+ channel=channel,
48
+ )