Skip to content

Commit 33eb5d3

Browse files
authored
Merge pull request #355 from chaithanyak42/main
feat: Add HyperSpell integration with search, document addition, and file upload functionalities
2 parents a793d4e + 8645eab commit 33eb5d3

File tree

2 files changed

+152
-0
lines changed

2 files changed

+152
-0
lines changed
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import os
2+
import json
3+
from typing import List, Optional, Dict, Any
4+
from pathlib import Path
5+
from hyperspell import Hyperspell
6+
7+
# Get environment variables
8+
HYPERSPELL_API_KEY = os.getenv('HYPERSPELL_API_KEY')
9+
default_user_id = os.getenv('HYPERSPELL_USER_ID')
10+
11+
12+
def hyperspell_search(query: str, sources: Optional[str] = None, answer: bool = False, user_id: Optional[str] = None) -> str:
13+
"""
14+
Search across your HyperSpell knowledge base (documents, integrations like Notion, Gmail, etc.).
15+
16+
Args:
17+
query: The search query to find relevant information
18+
sources: Comma-separated list of sources to search (e.g., "collections,notion,gmail").
19+
If None, searches all available sources.
20+
answer: If True, returns a direct answer to the query instead of just documents
21+
user_id: Optional user ID to use for this request. Defaults to HYPERSPELL_USER_ID env var.
22+
23+
Returns:
24+
JSON string containing search results or answer
25+
"""
26+
try:
27+
# Create client for this request
28+
client = Hyperspell(api_key=HYPERSPELL_API_KEY, user_id=user_id or default_user_id)
29+
# Parse sources if provided
30+
sources_list = sources.split(',') if sources else None
31+
32+
# Build options based on sources
33+
options = {}
34+
if sources_list and 'collections' in sources_list:
35+
options['collections'] = {}
36+
37+
response = client.query.search(
38+
query=query,
39+
sources=sources_list or ["collections"],
40+
answer=answer,
41+
options=options
42+
)
43+
44+
if answer:
45+
return json.dumps({
46+
"answer": response.answer,
47+
"sources_used": [doc.source for doc in response.documents],
48+
"document_count": len(response.documents)
49+
})
50+
else:
51+
return json.dumps({
52+
"documents": [
53+
{
54+
"title": getattr(doc, 'filename', getattr(doc, 'title', 'No title')),
55+
"content": getattr(doc, 'summary', 'No content available')[:500] + "..." if len(getattr(doc, 'summary', '')) > 500 else getattr(doc, 'summary', 'No content available'),
56+
"source": doc.source,
57+
"score": getattr(doc, 'score', 0),
58+
"resource_id": doc.resource_id,
59+
"content_type": getattr(doc, 'content_type', None)
60+
}
61+
for doc in response.documents
62+
],
63+
"total_results": len(response.documents)
64+
})
65+
66+
except Exception as e:
67+
return json.dumps({"error": f"Error searching HyperSpell: {str(e)}"})
68+
69+
70+
def hyperspell_add_document(text: str, title: Optional[str] = None, collection: Optional[str] = None, user_id: Optional[str] = None) -> str:
71+
"""
72+
Add a text document to your HyperSpell knowledge base.
73+
74+
Args:
75+
text: The full text content to add
76+
title: Optional title for the document
77+
collection: Optional collection name to organize the document
78+
user_id: Optional user ID to use for this request. Defaults to HYPERSPELL_USER_ID env var.
79+
80+
Returns:
81+
JSON string with the document ID and status
82+
"""
83+
try:
84+
# Create client for this request
85+
client = Hyperspell(api_key=HYPERSPELL_API_KEY, user_id=user_id or default_user_id)
86+
response = client.documents.add(
87+
text=text,
88+
title=title,
89+
collection=collection
90+
)
91+
92+
return json.dumps({
93+
"document_id": response.id,
94+
"resource_id": response.resource_id,
95+
"status": response.status,
96+
"collection": collection
97+
})
98+
99+
except Exception as e:
100+
return json.dumps({"error": f"Error adding document to HyperSpell: {str(e)}"})
101+
102+
103+
def hyperspell_upload_file(file_path: str, collection: Optional[str] = None, user_id: Optional[str] = None) -> str:
104+
"""
105+
Upload a file (PDF, Word doc, spreadsheet, etc.) to your HyperSpell knowledge base.
106+
107+
Args:
108+
file_path: Path to the file to upload
109+
collection: Optional collection name to organize the document
110+
user_id: Optional user ID to use for this request. Defaults to HYPERSPELL_USER_ID env var.
111+
112+
Returns:
113+
JSON string with the document ID and status
114+
"""
115+
try:
116+
# Create client for this request
117+
client = Hyperspell(api_key=HYPERSPELL_API_KEY, user_id=user_id or default_user_id)
118+
# Convert to Path object for proper MIME type detection
119+
file_path_obj = Path(file_path)
120+
121+
if not file_path_obj.exists():
122+
return json.dumps({"error": f"File not found: {file_path}"})
123+
124+
response = client.documents.upload(
125+
file=file_path_obj, # Use Path object directly
126+
collection=collection
127+
)
128+
129+
return json.dumps({
130+
"document_id": response.id,
131+
"resource_id": response.resource_id,
132+
"status": response.status,
133+
"filename": file_path_obj.name,
134+
"collection": collection
135+
})
136+
137+
except Exception as e:
138+
return json.dumps({"error": f"Error uploading file to HyperSpell: {str(e)}"})
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "hyperspell",
3+
"url": "https://hyperspell.com",
4+
"category": "knowledge",
5+
"env": {
6+
"HYPERSPELL_API_KEY": null,
7+
"HYPERSPELL_USER_ID": null
8+
},
9+
"dependencies": [
10+
"hyperspell>=0.1.0"
11+
],
12+
"tools": ["hyperspell_search", "hyperspell_add_document", "hyperspell_upload_file"],
13+
"cta": "Get your HyperSpell API key at https://app.hyperspell.com/dashboard and set your user ID"
14+
}

0 commit comments

Comments
 (0)