@macaw-ai/client 0.0.0-stage → 0.9.10
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.
- package/LICENSE.md +339 -0
- package/bin/install.js +278 -0
- package/package.json +37 -4
- package/payload/README.md +56 -0
- package/payload/secureAI/LICENSE +190 -0
- package/payload/secureAI/NOTICE +5 -0
- package/payload/secureAI/demos/policy-controls/1_uncontrolled.py +139 -0
- package/payload/secureAI/demos/policy-controls/2_with_macaw.py +139 -0
- package/payload/secureAI/demos/policy-controls/3_with_user_policies.py +162 -0
- package/payload/secureAI/demos/policy-controls/credentials.txt +12 -0
- package/payload/secureAI/demos/policy-controls/malicious_report.txt +21 -0
- package/payload/secureAI/demos/policy-controls/sales_report.txt +20 -0
- package/payload/secureAI/demos/tutorial-1-rbac/README.md +143 -0
- package/payload/secureAI/demos/tutorial-1-rbac/app.py +147 -0
- package/payload/secureAI/demos/tutorial-1-rbac/authprompts_demo.py +306 -0
- package/payload/secureAI/demos/tutorial-1-rbac/config/claims-config.yaml +152 -0
- package/payload/secureAI/demos/tutorial-1-rbac/demo_secureopenai_with_policies.py +150 -0
- package/payload/secureAI/demos/tutorial-1-rbac/policies/bu_Analytics.json +8 -0
- package/payload/secureAI/demos/tutorial-1-rbac/policies/company_FinTech_Corp.json +70 -0
- package/payload/secureAI/demos/tutorial-1-rbac/policies/llm-base.json +69 -0
- package/payload/secureAI/demos/tutorial-1-rbac/policies/team_Reporting.json +8 -0
- package/payload/secureAI/demos/tutorial-1-rbac/policies/user_alice.json +32 -0
- package/payload/secureAI/demos/tutorial-1-rbac/policies/user_bob.json +28 -0
- package/payload/secureAI/demos/tutorial-1-rbac/policies/user_carol.json +34 -0
- package/payload/secureAI/demos/tutorial-1-rbac/requirements.txt +6 -0
- package/payload/secureAI/demos/tutorial-1-rbac/setup/auth0_complete_setup.sh +392 -0
- package/payload/secureAI/demos/tutorial-1-rbac/setup/keycloak_complete_setup.sh +320 -0
- package/payload/secureAI/demos/tutorial-2-intent/Policies/alation-remote-proxy.json +155 -0
- package/payload/secureAI/demos/tutorial-2-intent/Policies/bu.json +22 -0
- package/payload/secureAI/demos/tutorial-2-intent/Policies/company.json +17 -0
- package/payload/secureAI/demos/tutorial-2-intent/Policies/user_alice.json +48 -0
- package/payload/secureAI/demos/tutorial-2-intent/Policies/user_bob.json +83 -0
- package/payload/secureAI/demos/tutorial-2-intent/README.md +213 -0
- package/payload/secureAI/demos/tutorial-2-intent/script.py +188 -0
- package/payload/secureAI/demos/tutorial-2-intent/setup/alation_verifier.py +177 -0
- package/payload/secureAI/demos/tutorial-2-intent/setup/get_alation_user_token.py +180 -0
- package/payload/secureAI/examples/README.md +244 -0
- package/payload/secureAI/examples/anthropic/anthropic_1a_dropin_simple.py +103 -0
- package/payload/secureAI/examples/anthropic/anthropic_1b_multiuser_bind.py +190 -0
- package/payload/secureAI/examples/anthropic/anthropic_1b_multiuser_bind_streaming.py +190 -0
- package/payload/secureAI/examples/anthropic/anthropic_1c_a2a_invoke.py +156 -0
- package/payload/secureAI/examples/attestations/1a_trade_alice.py +215 -0
- package/payload/secureAI/examples/attestations/1a_trade_bob.py +164 -0
- package/payload/secureAI/examples/attestations/1b_grant_admin.py +170 -0
- package/payload/secureAI/examples/attestations/1b_grant_researcher.py +231 -0
- package/payload/secureAI/examples/attestations/README.md +128 -0
- package/payload/secureAI/examples/langchain/langchain_1a_dropin_simple.py +199 -0
- package/payload/secureAI/examples/langchain/langchain_1b_multiuser.py +262 -0
- package/payload/secureAI/examples/langchain/langchain_1c_orchestration.py +332 -0
- package/payload/secureAI/examples/langchain/langchain_1d_llm_openai.py +130 -0
- package/payload/secureAI/examples/langchain/langchain_1e_llm_anthropic.py +130 -0
- package/payload/secureAI/examples/langchain/langchain_1f_memory.py +214 -0
- package/payload/secureAI/examples/litellm/litellm_1a_dropin_simple.py +131 -0
- package/payload/secureAI/examples/mcp/1a_simple_invocation.py +115 -0
- package/payload/secureAI/examples/mcp/1b_discovery_and_resources.py +142 -0
- package/payload/secureAI/examples/mcp/1c_logging_client.py +100 -0
- package/payload/secureAI/examples/mcp/1d_progress_client.py +100 -0
- package/payload/secureAI/examples/mcp/1e_sampling_client.py +150 -0
- package/payload/secureAI/examples/mcp/1e_sampling_server.py +90 -0
- package/payload/secureAI/examples/mcp/1f_elicitation_client.py +127 -0
- package/payload/secureAI/examples/mcp/1f_elicitation_server.py +73 -0
- package/payload/secureAI/examples/mcp/1g_roots_client.py +122 -0
- package/payload/secureAI/examples/mcp/1g_roots_server.py +85 -0
- package/payload/secureAI/examples/mcp/2a_proxy_snowflake.py +212 -0
- package/payload/secureAI/examples/mcp/2b_proxy_databricks.py +299 -0
- package/payload/secureAI/examples/mcp/2c_proxy_stdio_fetch.py +91 -0
- package/payload/secureAI/examples/mcp/2d_proxy_stdio_salesforce.py +119 -0
- package/payload/secureAI/examples/mcp/2e_proxy_multiuser.py +136 -0
- package/payload/secureAI/examples/mcp/2f_proxy_stdio_databricks.py +144 -0
- package/payload/secureAI/examples/mcp/3a_native_mcp_client.py +104 -0
- package/payload/secureAI/examples/mcp/3b_native_mcp_proxy.py +114 -0
- package/payload/secureAI/examples/mcp/3c_native_mcp_sampling.py +180 -0
- package/payload/secureAI/examples/mcp/3d_native_mcp_2026.py +135 -0
- package/payload/secureAI/examples/mcp/securemcp_calculator.py +248 -0
- package/payload/secureAI/examples/mcp/securemcp_server.py +75 -0
- package/payload/secureAI/examples/openai/openai_1a_dropin_simple.py +102 -0
- package/payload/secureAI/examples/openai/openai_1b_multiuser_bind.py +193 -0
- package/payload/secureAI/examples/openai/openai_1b_multiuser_bind_streaming.py +199 -0
- package/payload/secureAI/examples/openai/openai_1c_a2a_invoke.py +156 -0
- package/payload/secureAI/examples/openai/openai_1d_invocation_patterns.py +337 -0
- package/payload/secureAI/examples/phishing-resistance/1a_login_alice.py +180 -0
- package/payload/secureAI/examples/phishing-resistance/1b_trade_alice.py +241 -0
- package/payload/secureAI/examples/phishing-resistance/1b_trade_bob.py +164 -0
- package/payload/secureAI/examples/phishing-resistance/README.md +124 -0
- package/payload/secureAI/examples/phishing-resistance/get_token.py +114 -0
- package/payload/secureAI/examples/pydantic_ai/README.md +88 -0
- package/payload/secureAI/examples/pydantic_ai/policies/app_pydantic-agent.json +10 -0
- package/payload/secureAI/examples/pydantic_ai/pydanticai_1a_dropin_simple.py +90 -0
- package/payload/secureAI/examples/pydantic_ai/pydanticai_1b_model_routing.py +85 -0
- package/payload/secureAI/examples/pydantic_ai/pydanticai_1c_native_tools.py +83 -0
- package/payload/secureAI/examples/pydantic_ai/pydanticai_1d_multiuser_bind.py +104 -0
- package/payload/secureAI/examples/pydantic_ai/pydanticai_1e_mcp_compose.py +92 -0
- package/payload/secureAI/macaw_adapters/__init__.py +55 -0
- package/payload/secureAI/macaw_adapters/anthropic/REFERENCE.md +374 -0
- package/payload/secureAI/macaw_adapters/anthropic/__init__.py +22 -0
- package/payload/secureAI/macaw_adapters/anthropic/secure_anthropic.py +792 -0
- package/payload/secureAI/macaw_adapters/anthropic_ext_tools/__init__.py +25 -0
- package/payload/secureAI/macaw_adapters/anthropic_ext_tools/secure_anthropic.py +840 -0
- package/payload/secureAI/macaw_adapters/langchain/REFERENCE.md +234 -0
- package/payload/secureAI/macaw_adapters/langchain/__init__.py +100 -0
- package/payload/secureAI/macaw_adapters/langchain/_utils.py +83 -0
- package/payload/secureAI/macaw_adapters/langchain/agents.py +296 -0
- package/payload/secureAI/macaw_adapters/langchain/anthropic.py +456 -0
- package/payload/secureAI/macaw_adapters/langchain/callbacks.py +306 -0
- package/payload/secureAI/macaw_adapters/langchain/memory.py +352 -0
- package/payload/secureAI/macaw_adapters/langchain/openai.py +410 -0
- package/payload/secureAI/macaw_adapters/langchain/tools.py +174 -0
- package/payload/secureAI/macaw_adapters/litellm/README.md +216 -0
- package/payload/secureAI/macaw_adapters/litellm/__init__.py +143 -0
- package/payload/secureAI/macaw_adapters/litellm/secure_litellm.py +686 -0
- package/payload/secureAI/macaw_adapters/mcp/REFERENCE.md +460 -0
- package/payload/secureAI/macaw_adapters/mcp/__init__.py +65 -0
- package/payload/secureAI/macaw_adapters/mcp/_endpoint.py +193 -0
- package/payload/secureAI/macaw_adapters/mcp/_endpoint2.py +225 -0
- package/payload/secureAI/macaw_adapters/mcp/_serve.py +25 -0
- package/payload/secureAI/macaw_adapters/mcp/client.py +721 -0
- package/payload/secureAI/macaw_adapters/mcp/decorators.py +228 -0
- package/payload/secureAI/macaw_adapters/mcp/fastmcp_compat.py +353 -0
- package/payload/secureAI/macaw_adapters/mcp/mcp.py +785 -0
- package/payload/secureAI/macaw_adapters/mcp/proxy.py +626 -0
- package/payload/secureAI/macaw_adapters/mcp/server.py +317 -0
- package/payload/secureAI/macaw_adapters/mcp/subscriptions.py +450 -0
- package/payload/secureAI/macaw_adapters/openai/REFERENCE.md +368 -0
- package/payload/secureAI/macaw_adapters/openai/__init__.py +22 -0
- package/payload/secureAI/macaw_adapters/openai/secure_openai.py +833 -0
- package/payload/secureAI/macaw_adapters/openai_ext_tools/REFERENCE.md +368 -0
- package/payload/secureAI/macaw_adapters/openai_ext_tools/__init__.py +25 -0
- package/payload/secureAI/macaw_adapters/openai_ext_tools/secure_openai.py +876 -0
- package/payload/secureAI/macaw_adapters/pydantic_ai/__init__.py +36 -0
- package/payload/secureAI/macaw_adapters/pydantic_ai/_core.py +257 -0
- package/payload/secureAI/macaw_adapters/pydantic_ai/agent.py +218 -0
- package/payload/secureAI/macaw_adapters/pydantic_ai/model.py +99 -0
- package/payload/secureAI/macaw_adapters/pydantic_ai/toolset.py +86 -0
- package/payload/secureAI/test_harness_quick.py +296 -0
- package/wheels/macaw_adapters-0.9.10.1-py3-none-any.whl +0 -0
- package/wheels/macaw_client-0.9.10.1-cp312-cp312-macosx_11_0_arm64.whl +0 -0
- package/wheels/macaw_client-0.9.10.1-cp312-cp312-manylinux_2_17_x86_64.whl +0 -0
- package/wheels/macaw_client-0.9.10.1-cp314-cp314-macosx_11_0_arm64.whl +0 -0
- package/wheels/macaw_client-0.9.10.1-cp314-cp314-manylinux_2_17_x86_64.whl +0 -0
- package/wheels/macaw_client-0.9.10.1-cp314-cp314-win_amd64.whl +0 -0
- package/wheels/macaw_client-0.9.10.1-cp39-cp39-macosx_11_0_arm64.whl +0 -0
- package/README.md +0 -3
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
# SecureOpenAI Reference
|
|
2
|
+
|
|
3
|
+
Drop-in replacement for OpenAI client with MACAW security. Supports three usage paths for different scenarios.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```python
|
|
8
|
+
from macaw_adapters.openai import SecureOpenAI
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Install the package:
|
|
12
|
+
```bash
|
|
13
|
+
pip install -e /path/to/secureAI
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## When to Use Each Path
|
|
19
|
+
|
|
20
|
+
| Scenario | Path | Example |
|
|
21
|
+
|----------|------|---------|
|
|
22
|
+
| Simple app, no user distinction | Direct on service | `client.chat.completions.create()` |
|
|
23
|
+
| Multi-user, per-user policies | bind_to_user | `service.bind_to_user(user_client)` |
|
|
24
|
+
| A2A communication, explicit control | invoke_tool | `user.invoke_tool("tool:xxx/generate", ...)` |
|
|
25
|
+
| CLI tool, single operator | Direct on service | `client.chat.completions.create()` |
|
|
26
|
+
| SaaS with user accounts | bind_to_user | Different users = different permissions |
|
|
27
|
+
|
|
28
|
+
### Why bind_to_user?
|
|
29
|
+
|
|
30
|
+
Without `bind_to_user`, everyone uses the **service's identity**. With `bind_to_user`, each user's **JWT identity flows through** for policy evaluation.
|
|
31
|
+
|
|
32
|
+
This enables scenarios like:
|
|
33
|
+
- Alice: GPT-3.5 only, max 500 tokens
|
|
34
|
+
- Bob: GPT-3.5/4, max 2000 tokens
|
|
35
|
+
|
|
36
|
+
Same service, different permissions based on WHO is calling.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Path 1: Direct on Service (Simplest)
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
from macaw_adapters.openai import SecureOpenAI
|
|
44
|
+
|
|
45
|
+
# Just like using regular OpenAI client
|
|
46
|
+
client = SecureOpenAI(
|
|
47
|
+
app_name="my-app",
|
|
48
|
+
intent_policy={"purpose": "financial analysis"}
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
# Same API as OpenAI
|
|
52
|
+
response = client.chat.completions.create(
|
|
53
|
+
model="gpt-4",
|
|
54
|
+
max_tokens=500,
|
|
55
|
+
messages=[{"role": "user", "content": "What is compound interest?"}]
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
print(response.choices[0].message.content)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Use when**: Single app, no user distinction, app-level policies.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Path 2: bind_to_user (Multi-user)
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from macaw_adapters.openai import SecureOpenAI
|
|
69
|
+
from macaw_client import MACAWClient, RemoteIdentityProvider
|
|
70
|
+
|
|
71
|
+
# 1. Create SINGLE service (shared across all users)
|
|
72
|
+
service = SecureOpenAI(app_name="financial-service")
|
|
73
|
+
|
|
74
|
+
# 2. User login -> JWT -> MACAWClient
|
|
75
|
+
jwt_token, _ = RemoteIdentityProvider().login("alice", "Alice123!")
|
|
76
|
+
user = MACAWClient(
|
|
77
|
+
user_name="alice",
|
|
78
|
+
iam_token=jwt_token,
|
|
79
|
+
agent_type="user",
|
|
80
|
+
app_name="financial-app"
|
|
81
|
+
)
|
|
82
|
+
user.register()
|
|
83
|
+
|
|
84
|
+
# 3. Bind user to service
|
|
85
|
+
user_openai = service.bind_to_user(user)
|
|
86
|
+
|
|
87
|
+
# 4. Same API, user's identity flows through for policy evaluation
|
|
88
|
+
response = user_openai.chat.completions.create(
|
|
89
|
+
model="gpt-3.5-turbo",
|
|
90
|
+
messages=[{"role": "user", "content": "Hello"}]
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# 5. Cleanup when user session ends
|
|
94
|
+
user_openai.unbind()
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Use when**: SaaS app, different users need different permissions.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Path 3: invoke_tool (A2A)
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
from macaw_adapters.openai import SecureOpenAI
|
|
105
|
+
from macaw_client import MACAWClient, RemoteIdentityProvider
|
|
106
|
+
|
|
107
|
+
# 1. Create OpenAI service
|
|
108
|
+
service = SecureOpenAI(app_name="openai-service")
|
|
109
|
+
|
|
110
|
+
# 2. Create user agent
|
|
111
|
+
jwt_token, _ = RemoteIdentityProvider().login("alice", "Alice123!")
|
|
112
|
+
user = MACAWClient(
|
|
113
|
+
user_name="alice",
|
|
114
|
+
iam_token=jwt_token,
|
|
115
|
+
agent_type="user",
|
|
116
|
+
app_name="my-agent"
|
|
117
|
+
)
|
|
118
|
+
user.register()
|
|
119
|
+
|
|
120
|
+
# 3. Explicit invoke_tool - you control everything
|
|
121
|
+
result = user.invoke_tool(
|
|
122
|
+
tool_name="tool:openai-service/generate", # MAPL tool name
|
|
123
|
+
parameters={
|
|
124
|
+
"model": "gpt-3.5-turbo",
|
|
125
|
+
"max_tokens": 500,
|
|
126
|
+
"messages": [{"role": "user", "content": "What is compound interest?"}]
|
|
127
|
+
},
|
|
128
|
+
target_agent=service.server_id # Explicit routing
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
# Result is raw dict
|
|
132
|
+
content = result["choices"][0]["message"]["content"]
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Use when**: Building agent systems, need explicit control, cross-service communication.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## SecureOpenAI Class
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
client = SecureOpenAI(
|
|
143
|
+
api_key="sk-...", # Optional: uses OPENAI_API_KEY env var
|
|
144
|
+
app_name="my-app", # Application name for MACAW registration
|
|
145
|
+
intent_policy={...}, # Application-defined security policy (MAPL format)
|
|
146
|
+
jwt_token="...", # Optional: creates user-mode client
|
|
147
|
+
user_name="alice" # Optional: user name for user mode
|
|
148
|
+
)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Constructor Parameters
|
|
152
|
+
|
|
153
|
+
| Parameter | Type | Default | Description |
|
|
154
|
+
|-----------|------|---------|-------------|
|
|
155
|
+
| `api_key` | str | env var | OpenAI API key |
|
|
156
|
+
| `app_name` | str | `"secure-openai-app"` | Application name for MACAW |
|
|
157
|
+
| `intent_policy` | dict | `{}` | Security policy (MAPL format) |
|
|
158
|
+
| `jwt_token` | str | None | JWT token for user mode |
|
|
159
|
+
| `user_name` | str | None | User name for user mode |
|
|
160
|
+
|
|
161
|
+
### Properties
|
|
162
|
+
|
|
163
|
+
| Property | Type | Description |
|
|
164
|
+
|----------|------|-------------|
|
|
165
|
+
| `client.server_id` | str | Agent ID after registration |
|
|
166
|
+
| `client.macaw_client` | MACAWClient | MACAW client instance |
|
|
167
|
+
| `client.openai_client` | OpenAI | Underlying OpenAI client |
|
|
168
|
+
| `client._mode` | str | "service" or "user" |
|
|
169
|
+
|
|
170
|
+
### Methods
|
|
171
|
+
|
|
172
|
+
#### bind_to_user(user_client) -> BoundSecureOpenAI
|
|
173
|
+
|
|
174
|
+
Bind service to a user's MACAW client for per-user identity.
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
user_openai = service.bind_to_user(user_client)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Only valid in service mode. Returns `BoundSecureOpenAI` wrapper.
|
|
181
|
+
|
|
182
|
+
#### register_tool(name, handler) -> SecureOpenAI
|
|
183
|
+
|
|
184
|
+
Register a tool that OpenAI can call.
|
|
185
|
+
|
|
186
|
+
```python
|
|
187
|
+
client.register_tool("get_weather", get_weather_fn)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## BoundSecureOpenAI Class
|
|
193
|
+
|
|
194
|
+
Per-user wrapper created via `bind_to_user()`.
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
user_openai = service.bind_to_user(user_client)
|
|
198
|
+
|
|
199
|
+
# Same API as SecureOpenAI
|
|
200
|
+
response = user_openai.chat.completions.create(...)
|
|
201
|
+
|
|
202
|
+
# Check binding status
|
|
203
|
+
if user_openai.is_bound:
|
|
204
|
+
...
|
|
205
|
+
|
|
206
|
+
# Cleanup
|
|
207
|
+
user_openai.unbind()
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Properties
|
|
211
|
+
|
|
212
|
+
| Property | Type | Description |
|
|
213
|
+
|----------|------|-------------|
|
|
214
|
+
| `is_bound` | bool | Whether wrapper is still bound |
|
|
215
|
+
| `service` | SecureOpenAI | The bound service (raises if unbound) |
|
|
216
|
+
| `user_client` | MACAWClient | The bound user client (raises if unbound) |
|
|
217
|
+
|
|
218
|
+
### Methods
|
|
219
|
+
|
|
220
|
+
#### unbind()
|
|
221
|
+
|
|
222
|
+
Invalidate this binding. All future calls will raise `RuntimeError`.
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## API Surface
|
|
227
|
+
|
|
228
|
+
SecureOpenAI mirrors the OpenAI API structure:
|
|
229
|
+
|
|
230
|
+
```python
|
|
231
|
+
# Chat completions
|
|
232
|
+
response = client.chat.completions.create(
|
|
233
|
+
model="gpt-4",
|
|
234
|
+
messages=[{"role": "user", "content": "..."}],
|
|
235
|
+
tools=[...], # Optional: auto-discovered
|
|
236
|
+
tool_choice="auto"
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
# Text completions
|
|
240
|
+
response = client.completions.create(
|
|
241
|
+
model="gpt-3.5-turbo-instruct",
|
|
242
|
+
prompt="..."
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
# Embeddings
|
|
246
|
+
response = client.embeddings.create(
|
|
247
|
+
model="text-embedding-ada-002",
|
|
248
|
+
input="..."
|
|
249
|
+
)
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## MAPL Tool Names
|
|
255
|
+
|
|
256
|
+
SecureOpenAI uses MAPL-compliant tool names:
|
|
257
|
+
|
|
258
|
+
| Operation | Tool Name |
|
|
259
|
+
|-----------|-----------|
|
|
260
|
+
| Chat completions | `tool:{app_name}/generate` |
|
|
261
|
+
| Text completions | `tool:{app_name}/complete` |
|
|
262
|
+
| Embeddings | `tool:{app_name}/embed` |
|
|
263
|
+
|
|
264
|
+
Example: If `app_name="openai-service"`, the generate tool is `tool:openai-service/generate`.
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## Tool Auto-Discovery
|
|
269
|
+
|
|
270
|
+
SecureOpenAI automatically discovers tool implementations from the caller's scope:
|
|
271
|
+
|
|
272
|
+
```python
|
|
273
|
+
# Define tools in your code
|
|
274
|
+
def get_weather(location: str) -> str:
|
|
275
|
+
return f"Weather in {location}: Sunny, 72F"
|
|
276
|
+
|
|
277
|
+
# Define tool schemas for OpenAI
|
|
278
|
+
tools = [
|
|
279
|
+
{
|
|
280
|
+
"type": "function",
|
|
281
|
+
"function": {
|
|
282
|
+
"name": "get_weather", # Must match function name
|
|
283
|
+
"description": "Get weather for a location",
|
|
284
|
+
"parameters": {
|
|
285
|
+
"type": "object",
|
|
286
|
+
"properties": {"location": {"type": "string"}},
|
|
287
|
+
"required": ["location"]
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
]
|
|
292
|
+
|
|
293
|
+
# Tools are auto-discovered and routed through MACAW PEP
|
|
294
|
+
response = client.chat.completions.create(
|
|
295
|
+
model="gpt-4",
|
|
296
|
+
messages=[{"role": "user", "content": "What's the weather in Paris?"}],
|
|
297
|
+
tools=tools
|
|
298
|
+
)
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Intent Policy Format (MAPL)
|
|
304
|
+
|
|
305
|
+
```python
|
|
306
|
+
intent_policy = {
|
|
307
|
+
# Deny access to sensitive resources
|
|
308
|
+
"denied_resources": ["*password*", "*credential*", "*secret*"],
|
|
309
|
+
|
|
310
|
+
# Allow specific resources
|
|
311
|
+
"resources": ["tool:get_weather", "tool:search_files"],
|
|
312
|
+
|
|
313
|
+
# Parameter constraints
|
|
314
|
+
"constraints": {
|
|
315
|
+
"parameters": {
|
|
316
|
+
"tool:search_files": {
|
|
317
|
+
"path": ["*public*", "*reports*"]
|
|
318
|
+
}
|
|
319
|
+
},
|
|
320
|
+
"denied_parameters": {
|
|
321
|
+
"tool:*": {
|
|
322
|
+
"query": ["*password*"]
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
},
|
|
326
|
+
|
|
327
|
+
# Application metadata
|
|
328
|
+
"purpose": "weather and file search app"
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## Authenticated Prompts
|
|
335
|
+
|
|
336
|
+
SecureOpenAI supports authenticated prompts for cryptographic proof of prompt origin:
|
|
337
|
+
|
|
338
|
+
```python
|
|
339
|
+
# Tools declare which parameters are prompts
|
|
340
|
+
self.tools = {
|
|
341
|
+
f"tool:{self.app_name}/generate": {
|
|
342
|
+
"handler": self._handle_generate,
|
|
343
|
+
"prompts": ["messages"] # messages param is authenticated
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
Authenticated prompts are auto-created when `agent.authenticate_prompts` is enabled.
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
## Migration from OpenAI
|
|
353
|
+
|
|
354
|
+
```python
|
|
355
|
+
# Before
|
|
356
|
+
from openai import OpenAI
|
|
357
|
+
client = OpenAI()
|
|
358
|
+
|
|
359
|
+
# After (drop-in replacement)
|
|
360
|
+
from macaw_adapters.openai import SecureOpenAI
|
|
361
|
+
client = SecureOpenAI(
|
|
362
|
+
app_name="my-app",
|
|
363
|
+
intent_policy={"denied_resources": ["*sensitive*"]}
|
|
364
|
+
)
|
|
365
|
+
|
|
366
|
+
# Same API - no other code changes needed
|
|
367
|
+
response = client.chat.completions.create(...)
|
|
368
|
+
```
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""
|
|
2
|
+
MACAW OpenAI Adapter - Secure drop-in replacement for OpenAI client.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
# Before
|
|
6
|
+
from openai import OpenAI
|
|
7
|
+
client = OpenAI()
|
|
8
|
+
|
|
9
|
+
# After (one line change!)
|
|
10
|
+
from macaw_adapters.openai import SecureOpenAI
|
|
11
|
+
client = SecureOpenAI()
|
|
12
|
+
|
|
13
|
+
Features:
|
|
14
|
+
- Drop-in replacement for OpenAI client
|
|
15
|
+
- Policy-enforced tool execution
|
|
16
|
+
- Cryptographic audit trail
|
|
17
|
+
- Multi-user identity binding
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from macaw_adapters.openai.secure_openai import SecureOpenAI
|
|
21
|
+
|
|
22
|
+
__all__ = ["SecureOpenAI"]
|