SDKs
Official client libraries for Python, TypeScript, Java, and LangChain/LangGraph. Submit intents, retrieve decisions, handle errors — with full type safety.
At a Glance
| Language | Package | Install | Requirements |
|---|---|---|---|
| Python | gaas-sdk |
pip install gaas-sdk |
Python 3.11+ |
| TypeScript | @gaas/sdk |
npm install @gaas/sdk |
Node.js 18+ |
| Java | com.gaas:gaas-sdk |
Maven / Gradle | Java 17+ |
| LangChain / LangGraph | gaas-langchain |
pip install gaas-langchain |
Python 3.11+ |
sdks/.
Python
Install
pip install gaas-sdk
Submit an Intent
from gaas_sdk import GaaSClient, build_intent, ActionType, TargetType
async with GaaSClient(
"https://api.gaas.is",
headers={"X-API-Key": "your_key"},
) as client:
intent = build_intent(
agent_id="billing_bot",
action_type=ActionType.COMMUNICATE,
verb="send_email",
target_type=TargetType.PERSON,
target_identifier="patient@example.com",
summary="Send billing statement to patient",
content={"recipient": "patient@example.com", "channel": "email"},
)
response = await client.submit_intent(intent)
if response.data.verdict == "approve":
send_email(response.data)
elif response.data.verdict == "block":
log(response.data.reasoning)
Sync Client
A synchronous client is available for non-async codebases:
from gaas_sdk import GaaSClientSync
with GaaSClientSync(
"https://api.gaas.is",
headers={"X-API-Key": "your_key"},
) as client:
response = client.submit_intent(intent)
Bulk Submission
Submit up to 50 intents concurrently with partial failure support:
intents = [build_intent(...) for _ in range(10)]
response = await client.submit_intents_bulk(intents)
for result in response.data.results:
if result.success:
print(f"Decision: {result.decision.verdict}")
else:
print(f"Error: {result.error}")
Field Filtering
Request only specific fields to reduce response size:
response = await client.submit_intent(
intent,
fields="verdict,reasoning.summary,risk_assessment.overall_score"
)
Idempotency
Prevent duplicate submissions with idempotency keys (header-based recommended):
# Header-based (recommended)
response = await client.submit_intent(
intent,
headers={"Idempotency-Key": "unique-key-123"}
)
# Body-based (legacy)
intent = build_intent(
idempotency_key="unique-key-123",
agent_id="my-agent",
# ...
)
Error Handling
from gaas_sdk import (
GaaSError,
GaaSValidationError,
GaaSSemanticError,
GaaSNotFoundError,
GaaSConflictError,
GaaSServerError,
GaaSConnectionError,
)
try:
response = await client.submit_intent(intent)
except GaaSValidationError as e:
print(f"Validation failed (400): {e.message}")
except GaaSSemanticError as e:
print(f"Semantic error (422): {e.message}")
except GaaSConflictError as e:
print(f"Conflict (409): {e.message}")
except GaaSConnectionError:
print("Could not reach GaaS server")
except GaaSError as e:
# Catches all other GaaS errors (401, 402, 429, 500, etc.)
print(f"GaaS error {e.code}: {e.message}")
Best Practices
- Rate Limiting: Implement exponential backoff for 429 errors. Default limit: 100 requests/minute per organization.
- Quota Monitoring: Check
X-GaaS-Quota-Remainingresponse header to track quota usage proactively. - Idempotency: Always use idempotency keys for critical actions to prevent duplicate processing on retry.
- Error Retry: Retry 5xx server errors with exponential backoff. Do not retry 4xx client errors (except 429).
TypeScript
Install
npm install @gaas/sdk
Submit an Intent
import { GaaSClient, buildIntent, ActionType, TargetType } from '@gaas/sdk';
const client = new GaaSClient({
baseUrl: 'https://api.gaas.is',
headers: { 'X-API-Key': 'your_key' },
});
const intent = buildIntent({
agentId: 'billing_bot',
actionType: ActionType.Communicate,
verb: 'send_email',
targetType: TargetType.Person,
targetIdentifier: 'patient@example.com',
summary: 'Send billing statement to patient',
content: { recipient: 'patient@example.com', channel: 'email' },
});
const response = await client.submitIntent(intent);
if (response.data.verdict === 'approve') {
sendEmail(response.data);
} else if (response.data.verdict === 'block') {
console.log(response.data.verdictReason);
}
buildIntent({ agentId }) sends agent_id over the wire; response.data.riskAssessment comes from risk_assessment.
Error Handling
import { GaaSValidationError, GaaSConnectionError } from '@gaas/sdk';
try {
const response = await client.submitIntent(intent);
} catch (error) {
if (error instanceof GaaSValidationError) {
console.error(`Validation failed: ${error.message}`);
} else if (error instanceof GaaSConnectionError) {
console.error('Could not reach GaaS server');
}
}
Java
Install
Maven:
<dependency>
<groupId>com.gaas</groupId>
<artifactId>gaas-sdk</artifactId>
<version>0.2.0</version>
</dependency>
Gradle:
implementation 'com.gaas:gaas-sdk:0.2.0'
Submit an Intent
import com.gaas.sdk.*;
try (GaaSClient client = new GaaSClient("https://api.gaas.is", "your_key")) {
IntentDeclaration intent = IntentBuilder.create()
.agentId("billing_bot")
.actionType(ActionType.COMMUNICATE)
.verb("send_email")
.targetType(TargetType.PERSON)
.targetIdentifier("patient@example.com")
.summary("Send billing statement to patient")
.content(Map.of("recipient", "patient@example.com", "channel", "email"))
.build();
GaaSResponse<GovernanceDecision> response = client.submitIntent(intent);
if (response.getData().getVerdict() == Verdict.APPROVE) {
sendEmail(response.getData());
} else if (response.getData().getVerdict() == Verdict.BLOCK) {
System.out.println(response.getData().getReasoning());
}
}
Async API
CompletableFuture<GaaSResponse<GovernanceDecision>> future =
client.submitIntentAsync(intent);
Error Handling
try {
GaaSResponse<GovernanceDecision> response = client.submitIntent(intent);
} catch (GaaSValidationException e) {
System.out.println("Validation failed: " + e.getMessage());
} catch (GaaSConnectionException e) {
System.out.println("Could not reach GaaS server");
}
LangChain / LangGraph
Install
pip install gaas-langchain
Optional extras: pip install gaas-langchain[langchain], gaas-langchain[langgraph], or gaas-langchain[all].
Configuration
from gaas_langchain import GaaSGovernanceConfig
config = GaaSGovernanceConfig(
api_url="https://api.gaas.is",
api_key="gsk_your_key",
agent_id="my-langchain-agent",
block_on_escalate=True, # raise on ESCALATE verdicts too
timeout_seconds=5.0,
sensitivity="INTERNAL",
)
Govern a Single Tool
from gaas_langchain import govern_tool
safe_tool = govern_tool(my_tool, config=config)
# safe_tool.run() and safe_tool.arun() now submit governance
# intents before execution. Blocked actions raise GovernanceBlockedError.
Govern Multiple Tools
from gaas_langchain import govern_tools
safe_tools = govern_tools([tool_a, tool_b, tool_c], config=config)
LangGraph Node Decorator
from gaas_langchain import govern_node
@govern_node(config=config, node_name="send_email_node", financial_exposure_usd=0.0)
async def send_email(state):
# Only executes if governance approves
return {"status": "sent"}
Supports both sync and async node functions. Uses functools.wraps to preserve function metadata.
Additional parameters: sensitivity, regulatory_domains.
Callback Handler (Observability)
from gaas_langchain import GaaSCallbackHandler
handler = GaaSCallbackHandler(config, enforce=False)
# Pass as a LangChain callback — logs all governance decisions
# Set enforce=True to raise GovernanceBlockedError on BLOCK/ESCALATE
# After agent run:
print(handler.summary())
# {"total_tool_calls": 5, "approved": 4, "blocked": 1, "block_rate": 0.2, ...}
handler.reset() # clear log between runs
Error Handling
from gaas_langchain import GovernanceBlockedError
try:
result = safe_tool.run("send payment")
except GovernanceBlockedError as e:
print(e.verdict) # "BLOCK" or "ESCALATE"
print(e.decision_id) # GaaS decision ID
print(e.risk_score) # 0.0–1.0
print(e.blocking_policies) # ["pol_t1_002", ...]
print(e.governance_proof_token) # ECDSA-signed proof token ID
Common Patterns
Builder Pattern
All three SDKs provide a builder function (build_intent in Python, buildIntent in TypeScript, IntentBuilder in Java) that flattens the nested intent model into a flat argument list. This handles the agent.id, action.type, action.target.identifier nesting so you don't have to construct nested objects manually.
Response Structure
Every SDK method returns a typed response with two fields:
data— the response payload (e.g.,GovernanceDecision,AuditRecord,HealthStatus)meta— request metadata: request ID, decision ID, pipeline latency, status code
Retrieving Decisions
Python:
decision = await client.get_decision("intent-id")
TypeScript:
const decision = await client.getDecision('intent-id');
Java:
GaaSResponse<GovernanceDecision> decision = client.getDecision("intent-id");
Related Pages
- Getting Started — full quickstart walkthrough
- Intent Declaration API — endpoint reference and schema details
- Shadow Mode — test governance without enforcement