Infra for AI Companions
Project description
Emotion Machine Python SDK
Official Python helper for the Emotion Machine Companion API. It wraps the /v1 endpoints
documented in docs/client-companion-api-plan.md so you can provision companions, ingest
knowledge, and chat/stream with them in just a few lines of code.
Installation
pip install emotion-machine
The client depends on httpx and targets Python 3.9+.
Quickstart
- Export your project API key (project-scoped):
export EM_API_KEY="emk_prod_...."
export EM_API_BASE_URL="https://api.emotionmachine.ai" # or http://localhost:8100 for local dev
- Bootstrap a companion, ingest curated knowledge, and chat:
from emotion_machine import EmotionMachine
client = EmotionMachine() # reads EM_API_KEY / EM_API_BASE_URL
# Create a fresh companion
companion = client.create_companion(
name="Luteal Support Coach",
description="Helps users track luteal phase cravings",
config={
"system_prompt": {
"full_system_prompt": "You are an encouraging health coach."
}
},
)
companion_id = companion["id"]
# Optionally shape the profile schema for per-user traits
client.upsert_profile_schema(
companion_id,
schema={
"type": "object",
"properties": {
"craving_intensity": {"type": "integer", "minimum": 0, "maximum":5}
},
},
)
# Ingest curated luteal-phase knowledge via the built-in key
job = client.ingest_knowledge(
companion_id,
payload_type="json",
key="data_id_x",
)
job_result = client.wait_for_job(job["id"], timeout=20)
assert job_result["status"] == "succeeded", job_result
# Or upload & ingest your own JSON/Markdown/TXT file in one step.
# The helper uploads the file, kicks off ingestion, waits for completion,
# and raises if the job fails.
result = client.ingest_file(
companion_id,
file_path="important_app_related_knowledge.jsonl",
payload_type="json",
)
print(result["job"]["status"]) # -> "succeeded"
# Run a synchronous chat completion
completion = client.chat_completion(
companion_id,
message="Hi! I'm feeling intense salt cravings today, what should I know?",
external_user_id="user-123",
)
print(completion["choices"][0]["message"]["content"])
# Stream responses (Server-Sent Events) and collect message chunks
stream = client.chat_stream(
companion_id,
message="Can you summarise key luteal phase symptoms?",
external_user_id="user-123",
)
for event in stream:
if event["event"] == "delta":
chunk = event["data"]["choices"][0]["delta"].get("content", "")
if chunk:
print(chunk, end="", flush=True)
elif event["event"] == "done":
conversation_id = event["data"]["conversation_id"]
# Retrieve the full conversation transcript
transcript = client.get_conversation(conversation_id)
for message in transcript["messages"]:
print(f"{message['role']}: {message['content']}")
- Tidy up when finished:
client.close()
or use with EmotionMachine() as client: to auto-close the HTTP session.
Knowledge management tips
client.list_knowledge_assets(companion_id)shows the latest uploads plus their statuses (ready,superseded, etc.).- Uploading a file with the same filename automatically replaces older ingestions for that companion’s vector store—no manual delete required.
client.search_knowledge(..., mode="semantic" | "keyword" | "hybrid")lets you compare retrieval strategies against the same dataset.client.wait_for_job()andclient.ingest_file()raiseKnowledgeJobFailedif OpenAI reports the ingestion job asfailed, so you can catch mistakes early in CI.
API Coverage
| Resource | Method | SDK helper |
|---|---|---|
| Companions | GET /v1/companions |
client.list_companions() |
POST /v1/companions |
client.create_companion(...) |
|
GET /v1/companions/{id} |
client.get_companion(id) |
|
PATCH /v1/companions/{id} |
client.update_companion(...) |
|
| Profile Schema | PUT /v1/companions/{id}/profile-schema |
client.upsert_profile_schema(...) |
GET /v1/companions/{id}/profile-schema |
client.get_profile_schema(...) |
|
| Knowledge | POST /v1/companions/{id}/knowledge |
client.ingest_knowledge(...) |
GET /v1/knowledge-jobs/{job_id} |
client.knowledge.get_job(job_id) |
|
| Chat | POST /v1/companions/{id}/chat |
client.chat_completion(...) |
| Chat (stream) | POST /v1/companions/{id}/chat/stream |
client.chat_stream(...) |
| Conversations | GET /v1/conversations/{conversation_id} |
client.get_conversation(...) |
All helpers raise emotion_machine.APIError on non-success HTTP codes. Inspect
e.status_code and e.payload for diagnostics.
Development
cd packages/pip-emotion-machine
pip install -e .[dev]
The package ships from src/emotion_machine. Update pyproject.toml to bump versions.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file emotion_machine-0.0.5.tar.gz.
File metadata
- Download URL: emotion_machine-0.0.5.tar.gz
- Upload date:
- Size: 7.7 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.5.21
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c873e2074c2abf8f05d15cc115c15d33eb96149266dfb2598cbdcbdce5643955
|
|
| MD5 |
08eeb9f04fbc31162b507493ae7a584c
|
|
| BLAKE2b-256 |
05b3fc884305cd4bcfe955c51f8c1ec046be8d9f9128a5719a6046b1501b4ebb
|
File details
Details for the file emotion_machine-0.0.5-py3-none-any.whl.
File metadata
- Download URL: emotion_machine-0.0.5-py3-none-any.whl
- Upload date:
- Size: 10.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.5.21
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ac78b14ddb721d1fa3c7f8adac49f1e0f29fa0280ff1ec56a772b1e283a50970
|
|
| MD5 |
89d49a7c38407f2b8b831d07f763f9a8
|
|
| BLAKE2b-256 |
01dc6138c0f0d58e06de5efac3e73c95bacbf66e5faa2407469da4ad84bcc673
|