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 )} " })
0 commit comments