supermemory 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.
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Supermemory
4
+ module Resources
5
+ class Documents < Base
6
+ # Add a document
7
+ # @param content [String] Text, URL, PDF, image, or video content
8
+ # @param container_tag [String, nil] Container tag (max 100 chars)
9
+ # @param custom_id [String, nil] Custom identifier (max 100 chars)
10
+ # @param entity_context [String, nil] Context to guide memory extraction (max 1500 chars)
11
+ # @param metadata [Hash, nil] Key-value metadata
12
+ # @return [Hash] { "id" => "...", "status" => "..." }
13
+ def add(content:, container_tag: nil, custom_id: nil, entity_context: nil, metadata: nil)
14
+ body = { content: content }
15
+ body[:containerTag] = container_tag if container_tag
16
+ body[:customId] = custom_id if custom_id
17
+ body[:entityContext] = entity_context if entity_context
18
+ body[:metadata] = metadata if metadata
19
+ client.post("/v3/documents", body)
20
+ end
21
+
22
+ # Batch add documents
23
+ # @param documents [Array<Hash>, Array<String>] Array of document objects or content strings
24
+ # @param container_tag [String, nil] Applied to all documents
25
+ # @param metadata [Hash, nil] Applied to all documents
26
+ # @return [Array<Hash>] Array of { "id" => "...", "status" => "..." }
27
+ def batch_add(documents:, container_tag: nil, metadata: nil)
28
+ body = { documents: documents }
29
+ body[:containerTag] = container_tag if container_tag
30
+ body[:metadata] = metadata if metadata
31
+ client.post("/v3/documents/batch", body)
32
+ end
33
+
34
+ # Get a document by ID
35
+ # @param id [String] Document ID
36
+ # @return [Hash] Full document object
37
+ def get(id)
38
+ client.get("/v3/documents/#{id}")
39
+ end
40
+
41
+ # Update a document
42
+ # @param id [String] Document ID
43
+ # @param options [Hash] Fields to update (content, container_tag, custom_id, metadata)
44
+ # @return [Hash] { "id" => "...", "status" => "..." }
45
+ def update(id, **options)
46
+ body = {}
47
+ body[:content] = options[:content] if options.key?(:content)
48
+ body[:containerTag] = options[:container_tag] if options.key?(:container_tag)
49
+ body[:customId] = options[:custom_id] if options.key?(:custom_id)
50
+ body[:metadata] = options[:metadata] if options.key?(:metadata)
51
+ client.patch("/v3/documents/#{id}", body)
52
+ end
53
+
54
+ # Delete a document
55
+ # @param id [String] Document ID
56
+ # @return [nil]
57
+ def delete(id)
58
+ client.delete("/v3/documents/#{id}")
59
+ nil
60
+ end
61
+
62
+ # List documents
63
+ # @param filters [Hash, nil] Filter expression ({ "AND" => [...] } or { "OR" => [...] })
64
+ # @param include_content [Boolean] Include document content in response
65
+ # @param limit [Integer, nil] Results per page
66
+ # @param page [Integer, nil] Page number
67
+ # @param sort [String, nil] Sort field ("createdAt" or "updatedAt")
68
+ # @param order [String, nil] Sort order ("asc" or "desc")
69
+ # @return [Hash] { "memories" => [...], "pagination" => { ... } }
70
+ def list(filters: nil, include_content: false, limit: nil, page: nil, sort: nil, order: nil)
71
+ body = {}
72
+ body[:filters] = filters if filters
73
+ body[:includeContent] = include_content if include_content
74
+ body[:limit] = limit if limit
75
+ body[:page] = page if page
76
+ body[:sort] = sort if sort
77
+ body[:order] = order if order
78
+ client.post("/v3/documents/list", body)
79
+ end
80
+
81
+ # Bulk delete documents
82
+ # @param ids [Array<String>, nil] Document IDs to delete (max 100)
83
+ # @param container_tags [Array<String>, nil] Delete all docs in these containers
84
+ # @return [Hash] { "deletedCount" => ..., "success" => true/false }
85
+ def delete_bulk(ids: nil, container_tags: nil)
86
+ body = {}
87
+ body[:ids] = ids if ids
88
+ body[:containerTags] = container_tags if container_tags
89
+ client.delete("/v3/documents/bulk", body)
90
+ end
91
+
92
+ # List documents currently processing
93
+ # @return [Hash] { "documents" => [...], "totalCount" => ... }
94
+ def list_processing
95
+ client.get("/v3/documents/processing")
96
+ end
97
+
98
+ # Upload a file
99
+ # @param file [Faraday::Multipart::FilePart, IO] File to upload
100
+ # @param file_type [String, nil] Override file type detection
101
+ # @param mime_type [String, nil] Required for image/video file types
102
+ # @param metadata [Hash, nil] Metadata as a hash (will be JSON-encoded)
103
+ # @param container_tag [String, nil] Container tag
104
+ # @return [Hash] { "id" => "...", "status" => "..." }
105
+ def upload_file(file:, file_type: nil, mime_type: nil, metadata: nil, container_tag: nil)
106
+ body = { file: file }
107
+ body[:fileType] = file_type if file_type
108
+ body[:mimeType] = mime_type if mime_type
109
+ body[:metadata] = metadata.to_json if metadata
110
+ body[:containerTags] = container_tag if container_tag
111
+ client.multipart_post("/v3/documents/file", body)
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Supermemory
4
+ module Resources
5
+ class Memories < Base
6
+ # Forget (soft-delete) a memory
7
+ # @param container_tag [String] Scope identifier
8
+ # @param id [String, nil] Memory ID (use id or content)
9
+ # @param content [String, nil] Exact content match (alternative to id)
10
+ # @param reason [String, nil] Optional reason for forgetting
11
+ # @return [Hash] { "id" => "...", "forgotten" => true/false }
12
+ def forget(container_tag:, id: nil, content: nil, reason: nil)
13
+ body = { containerTag: container_tag }
14
+ body[:id] = id if id
15
+ body[:content] = content if content
16
+ body[:reason] = reason if reason
17
+ client.delete("/v4/memories", body)
18
+ end
19
+
20
+ # Update a memory (creates a new version)
21
+ # @param container_tag [String] Scope identifier
22
+ # @param new_content [String] Replacement content
23
+ # @param id [String, nil] Target memory ID
24
+ # @param content [String, nil] Exact content match for lookup
25
+ # @param metadata [Hash, nil] Metadata for the new version
26
+ # @return [Hash] { "id" => "...", "memory" => "...", "version" => ... }
27
+ def update_memory(container_tag:, new_content:, id: nil, content: nil, metadata: nil)
28
+ body = { containerTag: container_tag, newContent: new_content }
29
+ body[:id] = id if id
30
+ body[:content] = content if content
31
+ body[:metadata] = metadata if metadata
32
+ client.patch("/v4/memories", body)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Supermemory
4
+ module Resources
5
+ class Search < Base
6
+ # Search documents (v3 API)
7
+ # @param q [String] Search query
8
+ # @param chunk_threshold [Float, nil] 0 (most results) to 1 (most precise)
9
+ # @param doc_id [String, nil] Limit search to a specific document
10
+ # @param filters [Hash, nil] Filter expression
11
+ # @param include_full_docs [Boolean] Include full document content
12
+ # @param include_summary [Boolean] Include document summaries
13
+ # @param limit [Integer, nil] Max results
14
+ # @param only_matching_chunks [Boolean] Skip surrounding context chunks
15
+ # @param rerank [Boolean] Rerank results by relevance
16
+ # @param rewrite_query [Boolean] LLM query rewrite (~400ms extra latency)
17
+ # @return [Hash] { "results" => [...], "timing" => ..., "total" => ... }
18
+ def documents(q:, chunk_threshold: nil, doc_id: nil, filters: nil,
19
+ include_full_docs: false, include_summary: false,
20
+ limit: nil, only_matching_chunks: false,
21
+ rerank: false, rewrite_query: false)
22
+ body = { q: q }
23
+ body[:chunkThreshold] = chunk_threshold if chunk_threshold
24
+ body[:docId] = doc_id if doc_id
25
+ body[:filters] = filters if filters
26
+ body[:includeFullDocs] = include_full_docs if include_full_docs
27
+ body[:includeSummary] = include_summary if include_summary
28
+ body[:limit] = limit if limit
29
+ body[:onlyMatchingChunks] = only_matching_chunks if only_matching_chunks
30
+ body[:rerank] = rerank if rerank
31
+ body[:rewriteQuery] = rewrite_query if rewrite_query
32
+ client.post("/v3/search", body)
33
+ end
34
+
35
+ # Alias for documents search
36
+ # @see #documents
37
+ def execute(**params)
38
+ documents(**params)
39
+ end
40
+
41
+ # Search memories (v4 API - lower latency, conversational use)
42
+ # @param q [String] Search query
43
+ # @param container_tag [String, nil] Scope to a container
44
+ # @param filters [Hash, nil] Filter expression
45
+ # @param include [Hash, nil] Control included fields
46
+ # @param limit [Integer, nil] Max results
47
+ # @param rerank [Boolean] Rerank results
48
+ # @param rewrite_query [Boolean] LLM query rewrite
49
+ # @param search_mode [String, nil] "memories", "hybrid", or "documents"
50
+ # @param threshold [Float, nil] Score threshold (0 to 1)
51
+ # @return [Hash] { "results" => [...], "timing" => ..., "total" => ... }
52
+ def memories(q:, container_tag: nil, filters: nil, include: nil,
53
+ limit: nil, rerank: false, rewrite_query: false,
54
+ search_mode: nil, threshold: nil)
55
+ body = { q: q }
56
+ body[:containerTag] = container_tag if container_tag
57
+ body[:filters] = filters if filters
58
+ body[:include] = include if include
59
+ body[:limit] = limit if limit
60
+ body[:rerank] = rerank if rerank
61
+ body[:rewriteQuery] = rewrite_query if rewrite_query
62
+ body[:searchMode] = search_mode if search_mode
63
+ body[:threshold] = threshold if threshold
64
+ client.post("/v4/search", body)
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Supermemory
4
+ module Resources
5
+ class Settings < Base
6
+ # Get current settings
7
+ # @return [Hash]
8
+ def get
9
+ client.get("/v3/settings")
10
+ end
11
+
12
+ # Update settings
13
+ # @param options [Hash] Settings to update
14
+ # @option options [Integer, nil] :chunk_size
15
+ # @option options [String, nil] :filter_prompt
16
+ # @option options [Boolean, nil] :should_llm_filter
17
+ # @option options [String, nil] :github_client_id
18
+ # @option options [String, nil] :github_client_secret
19
+ # @option options [Boolean, nil] :github_custom_key_enabled
20
+ # @option options [String, nil] :google_drive_client_id
21
+ # @option options [String, nil] :google_drive_client_secret
22
+ # @option options [Boolean, nil] :google_drive_custom_key_enabled
23
+ # @option options [String, nil] :notion_client_id
24
+ # @option options [String, nil] :notion_client_secret
25
+ # @option options [Boolean, nil] :notion_custom_key_enabled
26
+ # @option options [String, nil] :onedrive_client_id
27
+ # @option options [String, nil] :onedrive_client_secret
28
+ # @option options [Boolean, nil] :onedrive_custom_key_enabled
29
+ # @return [Hash]
30
+ def update(**options)
31
+ body = {}
32
+ SETTINGS_KEY_MAP.each do |ruby_key, api_key|
33
+ body[api_key] = options[ruby_key] if options.key?(ruby_key)
34
+ end
35
+ client.patch("/v3/settings", body)
36
+ end
37
+
38
+ SETTINGS_KEY_MAP = {
39
+ chunk_size: :chunkSize,
40
+ filter_prompt: :filterPrompt,
41
+ should_llm_filter: :shouldLLMFilter,
42
+ exclude_items: :excludeItems,
43
+ include_items: :includeItems,
44
+ github_client_id: :githubClientId,
45
+ github_client_secret: :githubClientSecret,
46
+ github_custom_key_enabled: :githubCustomKeyEnabled,
47
+ google_drive_client_id: :googleDriveClientId,
48
+ google_drive_client_secret: :googleDriveClientSecret,
49
+ google_drive_custom_key_enabled: :googleDriveCustomKeyEnabled,
50
+ notion_client_id: :notionClientId,
51
+ notion_client_secret: :notionClientSecret,
52
+ notion_custom_key_enabled: :notionCustomKeyEnabled,
53
+ onedrive_client_id: :onedriveClientId,
54
+ onedrive_client_secret: :onedriveClientSecret,
55
+ onedrive_custom_key_enabled: :onedriveCustomKeyEnabled
56
+ }.freeze
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Supermemory
4
+ VERSION = '0.1.0'
5
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "supermemory/version"
4
+ require_relative "supermemory/errors"
5
+ require_relative "supermemory/configuration"
6
+ require_relative "supermemory/client"
7
+ require_relative "supermemory/resources/base"
8
+ require_relative "supermemory/resources/documents"
9
+ require_relative "supermemory/resources/search"
10
+ require_relative "supermemory/resources/memories"
11
+ require_relative "supermemory/resources/settings"
12
+ require_relative "supermemory/resources/connections"
13
+
14
+ module Supermemory
15
+ class << self
16
+ # Create a new client instance
17
+ # @param options [Hash] Client options (api_key:, base_url:, timeout:, max_retries:)
18
+ # @return [Supermemory::Client]
19
+ def new(**options)
20
+ Client.new(**options)
21
+ end
22
+ end
23
+ end
metadata ADDED
@@ -0,0 +1,173 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: supermemory
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Supermemory
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: faraday
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '1.0'
19
+ - - "<"
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: '1.0'
29
+ - - "<"
30
+ - !ruby/object:Gem::Version
31
+ version: '3.0'
32
+ - !ruby/object:Gem::Dependency
33
+ name: faraday-multipart
34
+ requirement: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '1.0'
39
+ - - "<"
40
+ - !ruby/object:Gem::Version
41
+ version: '2.0'
42
+ type: :runtime
43
+ prerelease: false
44
+ version_requirements: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '1.0'
49
+ - - "<"
50
+ - !ruby/object:Gem::Version
51
+ version: '2.0'
52
+ - !ruby/object:Gem::Dependency
53
+ name: bundler
54
+ requirement: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: '2.0'
59
+ type: :development
60
+ prerelease: false
61
+ version_requirements: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '2.0'
66
+ - !ruby/object:Gem::Dependency
67
+ name: rake
68
+ requirement: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - "~>"
71
+ - !ruby/object:Gem::Version
72
+ version: '13.0'
73
+ type: :development
74
+ prerelease: false
75
+ version_requirements: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '13.0'
80
+ - !ruby/object:Gem::Dependency
81
+ name: rspec
82
+ requirement: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - "~>"
85
+ - !ruby/object:Gem::Version
86
+ version: '3.0'
87
+ type: :development
88
+ prerelease: false
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - "~>"
92
+ - !ruby/object:Gem::Version
93
+ version: '3.0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: rubocop
96
+ requirement: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - "~>"
99
+ - !ruby/object:Gem::Version
100
+ version: '1.0'
101
+ type: :development
102
+ prerelease: false
103
+ version_requirements: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - "~>"
106
+ - !ruby/object:Gem::Version
107
+ version: '1.0'
108
+ - !ruby/object:Gem::Dependency
109
+ name: webmock
110
+ requirement: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - "~>"
113
+ - !ruby/object:Gem::Version
114
+ version: '3.0'
115
+ type: :development
116
+ prerelease: false
117
+ version_requirements: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - "~>"
120
+ - !ruby/object:Gem::Version
121
+ version: '3.0'
122
+ description: Official Ruby SDK for Supermemory. Add persistent memory to AI applications
123
+ with document management, semantic search, user profiling, and integrations with
124
+ ruby-openai, graph-agent, and langchainrb.
125
+ email:
126
+ - support@supermemory.ai
127
+ executables: []
128
+ extensions: []
129
+ extra_rdoc_files: []
130
+ files:
131
+ - CHANGELOG.md
132
+ - LICENSE
133
+ - README.md
134
+ - lib/supermemory.rb
135
+ - lib/supermemory/client.rb
136
+ - lib/supermemory/configuration.rb
137
+ - lib/supermemory/errors.rb
138
+ - lib/supermemory/integrations/graph_agent.rb
139
+ - lib/supermemory/integrations/langchain.rb
140
+ - lib/supermemory/integrations/openai.rb
141
+ - lib/supermemory/resources/base.rb
142
+ - lib/supermemory/resources/connections.rb
143
+ - lib/supermemory/resources/documents.rb
144
+ - lib/supermemory/resources/memories.rb
145
+ - lib/supermemory/resources/search.rb
146
+ - lib/supermemory/resources/settings.rb
147
+ - lib/supermemory/version.rb
148
+ homepage: https://github.com/supermemoryai/ruby-sdk
149
+ licenses:
150
+ - MIT
151
+ metadata:
152
+ homepage_uri: https://github.com/supermemoryai/ruby-sdk
153
+ source_code_uri: https://github.com/supermemoryai/ruby-sdk
154
+ changelog_uri: https://github.com/supermemoryai/ruby-sdk/blob/main/CHANGELOG.md
155
+ documentation_uri: https://supermemory.ai/docs
156
+ rdoc_options: []
157
+ require_paths:
158
+ - lib
159
+ required_ruby_version: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - ">="
162
+ - !ruby/object:Gem::Version
163
+ version: 3.0.0
164
+ required_rubygems_version: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - ">="
167
+ - !ruby/object:Gem::Version
168
+ version: '0'
169
+ requirements: []
170
+ rubygems_version: 3.6.9
171
+ specification_version: 4
172
+ summary: Ruby SDK for the Supermemory API - Memory API for the AI era
173
+ test_files: []