epsimo-agent 0.1.0

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.
Files changed (49) hide show
  1. package/LICENSE +21 -0
  2. package/SKILL.md +85 -0
  3. package/assets/example_asset.txt +24 -0
  4. package/epsimo/__init__.py +3 -0
  5. package/epsimo/__main__.py +4 -0
  6. package/epsimo/auth.py +143 -0
  7. package/epsimo/cli.py +586 -0
  8. package/epsimo/client.py +53 -0
  9. package/epsimo/resources/assistants.py +47 -0
  10. package/epsimo/resources/credits.py +16 -0
  11. package/epsimo/resources/db.py +31 -0
  12. package/epsimo/resources/files.py +39 -0
  13. package/epsimo/resources/projects.py +30 -0
  14. package/epsimo/resources/threads.py +83 -0
  15. package/epsimo/templates/components/AuthModal/AuthModal.module.css +39 -0
  16. package/epsimo/templates/components/AuthModal/AuthModal.tsx +138 -0
  17. package/epsimo/templates/components/BuyCredits/BuyCreditsModal.module.css +96 -0
  18. package/epsimo/templates/components/BuyCredits/BuyCreditsModal.tsx +132 -0
  19. package/epsimo/templates/components/BuyCredits/CreditsDisplay.tsx +101 -0
  20. package/epsimo/templates/components/ThreadChat/ThreadChat.module.css +551 -0
  21. package/epsimo/templates/components/ThreadChat/ThreadChat.tsx +862 -0
  22. package/epsimo/templates/components/ThreadChat/components/ToolRenderers.module.css +509 -0
  23. package/epsimo/templates/components/ThreadChat/components/ToolRenderers.tsx +322 -0
  24. package/epsimo/templates/next-mvp/app/globals.css.tmpl +20 -0
  25. package/epsimo/templates/next-mvp/app/layout.tsx.tmpl +22 -0
  26. package/epsimo/templates/next-mvp/app/page.module.css.tmpl +84 -0
  27. package/epsimo/templates/next-mvp/app/page.tsx.tmpl +43 -0
  28. package/epsimo/templates/next-mvp/epsimo.yaml.tmpl +12 -0
  29. package/epsimo/templates/next-mvp/package.json.tmpl +26 -0
  30. package/epsimo/tools/library.yaml +51 -0
  31. package/package.json +27 -0
  32. package/references/api_reference.md +34 -0
  33. package/references/virtual_db_guide.md +57 -0
  34. package/requirements.txt +2 -0
  35. package/scripts/assistant.py +165 -0
  36. package/scripts/auth.py +195 -0
  37. package/scripts/credits.py +107 -0
  38. package/scripts/debug_run.py +41 -0
  39. package/scripts/example.py +19 -0
  40. package/scripts/files.py +73 -0
  41. package/scripts/find_thread.py +55 -0
  42. package/scripts/project.py +60 -0
  43. package/scripts/run.py +75 -0
  44. package/scripts/test_all_skills.py +387 -0
  45. package/scripts/test_sdk.py +83 -0
  46. package/scripts/test_streaming.py +167 -0
  47. package/scripts/test_vdb.py +65 -0
  48. package/scripts/thread.py +77 -0
  49. package/scripts/verify_skill.py +87 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 EpsimoAI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/SKILL.md ADDED
@@ -0,0 +1,85 @@
1
+ ---
2
+ name: epsimo-agent
3
+ description: Comprehensive framework for building AI applications using EpsimoAI. Manage agents, projects, threads, and persistent state (Virtual Database). Includes CLI tools, Python SDK for automation, and React components for frontend integration.
4
+ ---
5
+
6
+ # Epsimo Agent Framework (Beta)
7
+
8
+ > [!NOTE]
9
+ > This is a **Beta** version of the Epsimo Agent Framework. Features and APIs may be subject to change.
10
+
11
+ The Epsimo Agent Framework allows you to build sophisticated AI-powered applications with agents, persistent threads, and a "Virtual Database" state layer. It provides a unified **CLI**, a **Python SDK**, and a **React UI Kit**.
12
+
13
+ **Base URL:** `https://api.epsimoagents.com`
14
+ **Frontend URL:** `https://app.epsimoagents.com`
15
+
16
+ ## 🛠️ Unified CLI (`epsimo`)
17
+
18
+ The `epsimo` CLI is the main tool for managing your agents and data.
19
+
20
+ ### Authentication
21
+ ```bash
22
+ python3 -m epsimo.cli auth login
23
+ python3 -m epsimo.cli whoami
24
+ ```
25
+
26
+ ### Project Scaffolding
27
+ - `python3 -m epsimo.cli create <name>`: Scaffolds a full Next.js application with Epsimo integrated.
28
+ - `python3 -m epsimo.cli init`: Links a local directory to an Epsimo project.
29
+ - `python3 -m epsimo.cli deploy`: Syncs your `epsimo.yaml` configuration to the platform.
30
+
31
+ ### Virtual Database
32
+ Threads can serve as a persistent structured storage layer.
33
+ - `python3 -m epsimo.cli db query --project-id <P_ID> --thread-id <T_ID>`: View structured thread state.
34
+ - `python3 -m epsimo.cli db set --project-id <P_ID> --thread-id <T_ID> --key <K> --value <V>`: Seed state.
35
+
36
+ ### Credits
37
+ - `python3 -m epsimo.cli credits balance`: Check current token balance.
38
+ - `python3 -m epsimo.cli credits buy --quantity <N>`: Generate a Stripe checkout URL.
39
+
40
+ ## 📦 Python SDK
41
+
42
+ The framework includes a powerful Python SDK for automation or backend services.
43
+
44
+ ```python
45
+ from epsimo import EpsimoClient
46
+
47
+ c = EpsimoClient(api_key="your-token")
48
+
49
+ # Virtual DB Access
50
+ user_pref = c.db.get(project_id, thread_id, "user_preferences")
51
+
52
+ # Conversation Streaming
53
+ for chunk in c.threads.run_stream(project_id, thread_id, assistant_id, "Hello!"):
54
+ print(chunk)
55
+ ```
56
+
57
+ ## 🎨 React UI Kit
58
+
59
+ The UI Kit provides high-level components for immediate integration. Found in `.agent/skills/epsimo-agent/epsimo/templates/components`.
60
+
61
+ - **`ThreadChat`**: A modern, dark-themed chat interface with streaming and tool support.
62
+ - **`useChat`**: A headless hook for managing conversation state.
63
+
64
+ ### Implementation Patterns
65
+ See `references/api_reference.md` for detailed frontend implementation patterns and API schemas.
66
+
67
+ ## 🧪 Verification
68
+ Ensure your environment is correctly configured:
69
+ ```bash
70
+ python3 .agent/skills/epsimo-agent/scripts/verify_skill.py
71
+ ```
72
+
73
+ ## 📚 Bundled Resources
74
+
75
+ ### Scripts (`scripts/`)
76
+ - `auth.py`: Interactive and environment-based login.
77
+ - `project.py`, `assistant.py`, `thread.py`, `run.py`: Low-level API interaction scripts.
78
+ - `credits.py`: Balance check and credit purchasing.
79
+
80
+ ### Templates (`epsimo/templates/`)
81
+ - `components/`: Ready-to-use React components (ThreadChat, AuthModal, BuyCredits).
82
+
83
+ ### References (`references/`)
84
+ - `api_reference.md`: Detailed API documentation and schemas.
85
+ - `virtual_db_guide.md`: Comprehensive guide for managing persistent state.
@@ -0,0 +1,24 @@
1
+ # Example Asset File
2
+
3
+ This placeholder represents where asset files would be stored.
4
+ Replace with actual asset files (templates, images, fonts, etc.) or delete if not needed.
5
+
6
+ Asset files are NOT intended to be loaded into context, but rather used within
7
+ the output Claude produces.
8
+
9
+ Example asset files from other skills:
10
+ - Brand guidelines: logo.png, slides_template.pptx
11
+ - Frontend builder: hello-world/ directory with HTML/React boilerplate
12
+ - Typography: custom-font.ttf, font-family.woff2
13
+ - Data: sample_data.csv, test_dataset.json
14
+
15
+ ## Common Asset Types
16
+
17
+ - Templates: .pptx, .docx, boilerplate directories
18
+ - Images: .png, .jpg, .svg, .gif
19
+ - Fonts: .ttf, .otf, .woff, .woff2
20
+ - Boilerplate code: Project directories, starter files
21
+ - Icons: .ico, .svg
22
+ - Data files: .csv, .json, .xml, .yaml
23
+
24
+ Note: This is a text placeholder. Actual assets can be any file type.
@@ -0,0 +1,3 @@
1
+ from .client import EpsimoClient
2
+
3
+ __all__ = ["EpsimoClient"]
@@ -0,0 +1,4 @@
1
+ from .cli import main
2
+
3
+ if __name__ == "__main__":
4
+ main()
package/epsimo/auth.py ADDED
@@ -0,0 +1,143 @@
1
+
2
+ import os
3
+ import json
4
+ import time
5
+ import requests
6
+ import getpass
7
+ import sys
8
+ import subprocess
9
+ from pathlib import Path
10
+
11
+ # Configuration
12
+ API_BASE_URL = os.environ.get("EPSIMO_API_URL", "https://api.epsimoagents.com")
13
+ TOKEN_FILE = Path.home() / "code/epsimo-frontend/.epsimo_token" # Keeping the same path for compatibility for now
14
+
15
+ def get_token():
16
+ """Retrieve a valid JWT token, refreshing if necessary."""
17
+
18
+ # Check if token file exists
19
+ if TOKEN_FILE.exists():
20
+ try:
21
+ with open(TOKEN_FILE, 'r') as f:
22
+ data = json.load(f)
23
+ return data.get('access_token') or data.get('token') or data.get('jwt_token')
24
+ except json.JSONDecodeError:
25
+ pass
26
+
27
+ # Try logging in with env vars if file doesn't exist/is invalid
28
+ if os.environ.get("EPSIMO_EMAIL") and os.environ.get("EPSIMO_PASSWORD"):
29
+ return perform_login(os.environ.get("EPSIMO_EMAIL"), os.environ.get("EPSIMO_PASSWORD"))
30
+
31
+ # Return None instead of raising Error to let caller handle it (e.g. prompt login)
32
+ return None
33
+
34
+ def perform_signup(email, password):
35
+ """Register a new user."""
36
+ print(f"Attempting to register new user: {email}")
37
+ url = f"{API_BASE_URL}/auth/signup"
38
+ payload = {
39
+ "email": email,
40
+ "password": password
41
+ }
42
+
43
+ try:
44
+ response = requests.post(url, json=payload)
45
+ response.raise_for_status()
46
+ print("✅ Signup successful! Logging in...")
47
+ return perform_login(email, password)
48
+ except requests.exceptions.HTTPError as e:
49
+ if e.response.status_code == 400: # Usually "User already exists" or validation error
50
+ print(f"⚠️ Signup failed: {e.response.text}")
51
+ else:
52
+ print(f"❌ Signup failed: {e}")
53
+ raise
54
+
55
+ def get_input_via_applescript(prompt, hidden=False):
56
+ """Get input using macOS native dialog."""
57
+ try:
58
+ script = f'display dialog "{prompt}" default answer ""'
59
+ if hidden:
60
+ script += ' with hidden answer'
61
+ script += ' buttons {"Cancel", "OK"} default button "OK"'
62
+
63
+ cmd = ['osascript', '-e', script]
64
+ result = subprocess.run(cmd, capture_output=True, text=True, check=True)
65
+ # Parse result: button returned:OK, text returned:foobar
66
+ output = result.stdout.strip()
67
+ if "text returned:" in output:
68
+ return output.split("text returned:")[-1]
69
+ return ""
70
+ except subprocess.CalledProcessError:
71
+ return None
72
+
73
+ def login_interactive():
74
+ """Interactive login flow."""
75
+ use_modal = os.environ.get("USE_GUI_PROMPT") == "1"
76
+
77
+ email = None
78
+ if use_modal and sys.platform == 'darwin':
79
+ email = get_input_via_applescript("Enter your Epsimo Email:")
80
+ else:
81
+ email = input("Email: ")
82
+
83
+ if not email:
84
+ print("Email is required.")
85
+ return
86
+
87
+ password = None
88
+ if 'EPSIMO_PASSWORD' in os.environ:
89
+ password = os.environ['EPSIMO_PASSWORD']
90
+ elif use_modal and sys.platform == 'darwin':
91
+ password = get_input_via_applescript("Enter your Epsimo Password:", hidden=True)
92
+ else:
93
+ password = getpass.getpass("Password: ")
94
+
95
+ if not password:
96
+ print("Password is required.")
97
+ return
98
+
99
+ try:
100
+ perform_login(email, password, attempt_signup_on_fail=True)
101
+ except Exception:
102
+ pass
103
+
104
+ def perform_login(email, password, attempt_signup_on_fail=False):
105
+ """Login logic."""
106
+ if not email or not password:
107
+ raise ValueError("Email and password are required.")
108
+
109
+ url = f"{API_BASE_URL}/auth/login"
110
+ payload = {
111
+ "email": email,
112
+ "password": password
113
+ }
114
+
115
+ try:
116
+ response = requests.post(url, json=payload)
117
+ response.raise_for_status()
118
+
119
+ data = response.json()
120
+ token = data.get('access_token') or data.get('token') or data.get('jwt_token')
121
+
122
+ if not token:
123
+ raise ValueError("Failed to obtain access token from login response.")
124
+
125
+ # Save token
126
+ # Create dir if not exists?
127
+ # TOKEN_FILE.parent.mkdir(parents=True, exist_ok=True)
128
+ # For now assume path exists as per user setup
129
+
130
+ with open(TOKEN_FILE, 'w') as f:
131
+ json.dump(data, f)
132
+
133
+ print(f"✅ Successfully logged in as {email}")
134
+ return token
135
+
136
+ except requests.exceptions.HTTPError as e:
137
+ print(f"❌ Login failed: {e}")
138
+ if attempt_signup_on_fail:
139
+ print("\nUser might not exist or password is wrong.")
140
+ choice = input("Do you want to create a new account with these credentials? (y/n): ")
141
+ if choice.lower() == 'y':
142
+ return perform_signup(email, password)
143
+ raise