AppSDK
Application SDK
Lightweight SDK for invoking healthcare AI agents in your medical applications and EHR systems.HIPAA-ready, fast, and production-ready with streaming responses for clinical workflows and session support for patient consultations.
Installation
Using pip
pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ hikigai-appsdkQuick Start
from hikigai.appsdk import AppClient
#Initialize client
client = AppClient(
token="your-access-token",
project_id="your-project-id"
)
# Get an agent
agent = client.agent("medical-coder")
# Invoke the agent
response = agent.invoke("Patient presents with fever and cough...")
print(response.content)
# Stream responses
for chunk in agent.stream("Tell me about diabetes"):
print(chunk, end="", flush=True)
# Session-based conversations
session_agent = agent.with_session("user-123")
session_agent.invoke("What is hypertension?")
session_agent.invoke("How is it treated?") # Remembers contextClient Reference
class AppClient
AppClientCoreMain client for invoking AI agents. Manages authentication, HTTP connections, and provides access to deployed agents.
Constructor
client = AppClient(
token: Optional[str] = None, # Access token from SSO (or set HIKIGAI_TOKEN env var)
project_id: Optional[str] = None, # Project ID (or set HIKIGAI_PROJECT_ID env var)
base_url: Optional[str] = None, # API endpoint (defaults to production)
timeout: float = 30.0, # Request timeout in seconds
)Methods
| Method | Returns | Description |
|---|---|---|
agent(agent_id: str) | RuntimeAgent | Get agent by ID or slug for invocation |
list_agents(category, tags, search) | List[RuntimeAgent] | List all available agents with optional filters |
Context Manager
with AppClient() as client:
agent = client.agent("my-agent")
response = agent.invoke("Hello")
# Resources automatically releasedAgent Reference
class RuntimeAgent
RuntimeAgentModelRepresents a deployed agent ready for invocation. Provides methods for synchronous invocation, streaming, and session management.
Properties
| Property | Type | Description |
|---|---|---|
id | str | Unique agent ID |
name | str | Agent name |
slug | str | URL-friendly slug |
version | str | Agent version |
description | str | None | Agent description |
status | str | Deployment status ('active', 'pending', etc.) |
endpoint | str | None | Invocation endpoint URL |
Methods
| Method | Returns | Description |
|---|---|---|
invoke(input, session_id=None, timeout=None) | InvokeResponse | Invoke agent synchronously with optional session |
stream(input, session_id=None) | Iterator[str] | Stream agent response chunks in real-time |
with_session(session_id: str) | RuntimeAgent | Create agent instance with persistent session |
Basic Usage
agent = client.agent("medical-coder")
# Synchronous invocation
response = agent.invoke("Patient has diabetes...")
print(response.content)
# Streaming
for chunk in agent.stream("Explain hypertension"):
print(chunk, end="")
# With session
response = agent.invoke("My name is Alice", session_id="user-123")
response = agent.invoke("What's my name?", session_id="user-123") # Remembers "Alice"Response Types
class InvokeResponse
InvokeResponsePydantic ModelResponse from a synchronous agent invocation containing output content and metadata.
| Property | Type | Description |
|---|---|---|
content* | str | Agent output content |
agent_id | str | ID of the agent that responded |
agent_version | str | None | Version of the agent |
session_id | str | None | Session ID if used |
metadata | InvocationMetadata | Invocation metadata (latency, tokens, etc.) |
Example
response = agent.invoke("Hello")
print(response.content) # "Hi! How can I help you?"
print(response.metadata.latency_ms) # 234
print(response.metadata.tokens_used) # 156
print(response.metadata.tools_called) # ["web_search"]class InvocationMetadata
InvocationMetadataPydantic ModelMetadata about an agent invocation including performance metrics and execution details.
invocation_id | str | Unique invocation ID |
latency_ms | float | None | Response latency in milliseconds |
timestamp | datetime | Invocation timestamp |
status | str | Status ('success', 'error', etc.) |
tokens_used | int | None | Total tokens consumed |
tools_called | List[str] | List of tools used by agent |
Session Management
Maintain conversation context across multiple invocations using sessions. Sessions enable multi-turn conversations where the agent remembers previous interactions.
Per-Invocation Sessions
Pass a session_id to each invocation to maintain context.
agent = client.agent("chatbot")
# First message
response1 = agent.invoke(
"My name is Alice",
session_id="user-123"
)
# Follow-up - agent remembers the name
response2 = agent.invoke(
"What's my name?",
session_id="user-123"
)
print(response2.content) # "Your name is Alice"Persistent Session Agent
Create a session-bound agent using with_session(). All invocations automatically use the same session.
agent = client.agent("assistant")
# Create session-bound agent
session_agent = agent.with_session("user-456")
# All invocations share the same session
session_agent.invoke("I live in New York")
session_agent.invoke("What's the weather like here?") # Knows "here" = NYC
# Streaming works too
for chunk in session_agent.stream("Tell me more about my city"):
print(chunk, end="")Multiple Users
Maintain separate contexts for different users with different session IDs.
agent = client.agent("support-bot")
# User 1's conversation
user1 = agent.with_session("user-001")
user1.invoke("I'm having trouble logging in")
# User 2's isolated conversation
user2 = agent.with_session("user-002")
user2.invoke("How do I reset my password?")
# Contexts are completely separate
# User 1's issues don't affect User 2's conversationEnd-User Identity
Add signup, login, MFA, QR badge login, and SSO for your app's end users — clinicians, patients, staff. Each app is backed by a dedicated AWS Cognito user pool the platform provisions for you; login returns standard OIDC tokens. Everything is reached through client.identity.
class IdentityClient
client.identityCoreEnd-user authentication and account management for the app's Cognito pool, plus QR/PIN badge credentials. Access it as a property on AppClient.
Account & auth methods
| Method | Returns | Description |
|---|---|---|
signup(app_id, email, password, display_name=None, attributes=None) | dict | Register a new end user in the app's pool |
confirm(app_id, email, code) | dict | Confirm a signup with the emailed code |
login(app_id, email, password) | dict | Authenticate — returns OIDC tokens or an MFA challenge |
refresh(app_id, refresh_token) | dict | Exchange a refresh token for fresh tokens |
logout(app_id, email) | dict | Globally sign the user out |
list_app_users(app_id, limit=50, offset=0) | list[dict] | List the app's end users |
delete_app_user(app_id, email) | None | Delete a user from the pool |
MFA, QR & SSO
| Method | Returns | Description |
|---|---|---|
mfa_associate(app_id, access_token) | dict | Begin TOTP enrollment — returns secret for a QR code |
mfa_verify(app_id, access_token, code, device_name=None) | dict | Verify the first code to finish enrollment |
mfa_set_preference(app_id, access_token, enabled=True) | dict | Turn TOTP MFA on or off |
mfa_respond(app_id, email, session, code) | dict | Complete a login that returned an MFA challenge |
issue_qr_login(app_id, email) | dict | Issue a QR badge credential for a user |
qr_login(app_id, qr_payload) | dict | Exchange a scanned QR payload for tokens |
configure_sso(app_id, provider_name, provider_type, …) | dict | Add a Google/Okta/SAML/OIDC provider |
sso_authorize_url(app_id, redirect_uri, provider=None) | dict | Build the hosted-UI authorize URL |
sso_exchange(app_id, code, redirect_uri) | dict | Exchange the callback code for tokens |
Setup (one-time, per app)
enable_identity(app_id, mode='managed', enabled_methods=…) | dict | Provision the app's Cognito pool |
get_identity_config(app_id) | dict | Get config + provisioning status |
byo_setup() | dict | CloudFormation params for bring-your-own Cognito |
byo_test(role_arn, region=None) | dict | Verify a cross-account role before enabling BYO |
Sign up, confirm, log in
from hikigai.appsdk import AppClient
client = AppClient(api_key="hikigai_...", project_id="proj_123")
# 1. Register the end user
client.identity.signup(
app_id="app_123",
email="clinician@hospital.com",
password="Temp#Pass2026",
display_name="Dr. Mehta",
attributes={"role": "clinician"},
)
# 2. Confirm (skip if the pool auto-confirms)
client.identity.confirm("app_123", "clinician@hospital.com", code="123456")
# 3. Log in -> OIDC tokens
tokens = client.identity.login("app_123", "clinician@hospital.com", "Temp#Pass2026")
print(tokens["access_token"])
# 4. Refresh later
fresh = client.identity.refresh("app_123", tokens["refresh_token"])Multi-factor login
# Login may return an MFA challenge instead of tokens
result = client.identity.login("app_123", "clinician@hospital.com", "Temp#Pass2026")
if result.get("status") == "challenge":
code = input("Enter your authenticator code: ")
tokens = client.identity.mfa_respond(
app_id="app_123",
email="clinician@hospital.com",
session=result["session"],
code=code,
)
print(tokens["access_token"])QR badge login
# Admin: issue a badge for the user (payload shown once)
badge = client.identity.issue_qr_login("app_123", "clinician@hospital.com")
print(badge["qr_payload"]) # encode into the printed badge
# Kiosk: scan the badge, exchange it for tokens
tokens = client.identity.qr_login("app_123", scanned_payload)signup vs create_user
Use identity.signup() for real Cognito accounts (password, MFA, SSO). Use identity.create_user() only for the lightweight QR/PIN badge flow (no password), paired with verify_qr() / verify_pin().
Complete Examples
Basic Agent Invocation
from hikigai.appsdk import AppClient
client = AppClient()
# Get agent
agent = client.agent("customer-support")
# Invoke
response = agent.invoke("How do I reset my password?")
print(response.content)
print(f"Latency: {response.metadata.latency_ms}ms")Streaming Responses
agent = client.agent("content-writer")
# Stream in real-time
print("Agent response: ", end="")
for chunk in agent.stream("Write a paragraph about AI"):
print(chunk, end="", flush=True)
print() # New lineSession-Based Chat Application
import uuid
from hikigai.appsdk import AppClient
def chat_session(user_id: str):
"""Start a chat session for a user."""
client = AppClient()
agent = client.agent("chatbot")
# Create session-bound agent
session = agent.with_session(user_id)
print("Chat started. Type 'exit' to quit.")
while True:
user_input = input("You: ")
if user_input.lower() == "exit":
break
# Invoke with session context
response = session.invoke(user_input)
print(f"Bot: {response.content}")
# Start chat for a user
chat_session(f"user-{uuid.uuid4()}")Listing and Filtering Agents
client = AppClient()
# List all agents
agents = client.list_agents()
for agent in agents:
print(f"{agent.name} (v{agent.version}): {agent.status}")
# Filter by category
medical_agents = client.list_agents(category="Medical Coding")
# Search
search_results = client.list_agents(search="diagnosis")Error Handling
from hikigai.appsdk import (
AppClient,
AgentNotFoundError,
InvocationError,
RateLimitError
)
client = AppClient()
try:
agent = client.agent("my-agent")
response = agent.invoke("Hello")
print(response.content)
except AgentNotFoundError:
print("Agent not found. Check the agent ID.")
except InvocationError as e:
print(f"Invocation failed: {e}")
except RateLimitError:
print("Rate limit exceeded. Please wait.")
except Exception as e:
print(f"Unexpected error: {e}")Invocation Methods
Two approaches to invoke agents: SDK methods for simplicity, or Direct API for advanced control.
SDK Methods (.invoke)
The recommended approach. Simple, type-safe, and handles all authentication and error handling automatically.
from hikigai.appsdk import AppClient
client = AppClient(
api_key="your-api-key",
project_id="your-project-id"
)
agent = client.agent("medical-coder")
response = agent.invoke("Patient presents with fever and cough...")
print(response.content)✓ Use SDK Method When:
- • Invoking from Python applications
- • You need streaming or session support
- • Type hints and IDE autocomplete are valuable
Error Handling
AgentNotFoundError
Raised when the requested agent doesn't exist
from hikigai.appsdk import AgentNotFoundError
try:
agent = client.agent("nonexistent-agent")
except AgentNotFoundError as e:
print(f"Agent not found: {e}")InvocationError
Raised when agent invocation fails
from hikigai.appsdk import InvocationError
try:
response = agent.invoke("Complex query...")
except InvocationError as e:
print(f"Invocation failed: {e}")
print(f"Agent ID: {e.agent_id}")
print(f"Session ID: {e.session_id}")AuthenticationError
Raised when token is invalid or missing
from hikigai.appsdk import AuthenticationError
try:
client = AppClient(token="invalid-token")
except AuthenticationError as e:
print(f"Authentication failed: {e}")RateLimitError
Raised when API rate limit is exceeded
from hikigai.appsdk import RateLimitError
import time
try:
response = agent.invoke("Query")
except RateLimitError as e:
print(f"Rate limit hit. Retry after: {e.retry_after}s")
time.sleep(e.retry_after)
response = agent.invoke("Query") # Retry