Skip to content

Commit a9fdc57

Browse files
committed
feat: conversation API
- bump Typesense to version 27.0 in github workflow file
1 parent f0f1c03 commit a9fdc57

15 files changed

+466
-29
lines changed

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
mkdir $(pwd)/typesense-data
3333
docker run -p 8108:8108 \
3434
-d \
35-
-v$(pwd)/typesense-data:/data typesense/typesense:27.0.rc35 \
35+
-v$(pwd)/typesense-data:/data typesense/typesense:27.0 \
3636
--data-dir /data \
3737
--api-key=xyz \
3838
--enable-cors

Sources/Typesense/Client.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ public struct Client {
1616
return Collection(apiCall: apiCall, collectionName: name)
1717
}
1818

19+
public func conversations() -> Conversations {
20+
return Conversations(apiCall: apiCall)
21+
}
22+
1923
public func keys() -> ApiKeys {
2024
return ApiKeys(apiCall: apiCall)
2125
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import Foundation
2+
#if canImport(FoundationNetworking)
3+
import FoundationNetworking
4+
#endif
5+
6+
public struct ConversationModel {
7+
private var apiCall: ApiCall
8+
var modelId: String
9+
10+
init(apiCall: ApiCall, modelId: String) {
11+
self.apiCall = apiCall
12+
self.modelId = modelId
13+
}
14+
15+
public func update(params: ConversationModelUpdateSchema) async throws -> (ConversationModelSchema?, URLResponse?) {
16+
let schemaData = try encoder.encode(params)
17+
let (data, response) = try await self.apiCall.put(endPoint: endpointPath(), body: schemaData)
18+
if let result = data {
19+
let decodedData = try decoder.decode(ConversationModelSchema.self, from: result)
20+
return (decodedData, response)
21+
}
22+
return (nil, response)
23+
}
24+
25+
public func retrieve() async throws -> (ConversationModelSchema?, URLResponse?) {
26+
let (data, response) = try await self.apiCall.get(endPoint: endpointPath())
27+
if let result = data {
28+
let decodedData = try decoder.decode(ConversationModelSchema.self, from: result)
29+
return (decodedData, response)
30+
}
31+
return (nil, response)
32+
}
33+
34+
public func delete() async throws -> (ConversationModelSchema?, URLResponse?) {
35+
let (data, response) = try await self.apiCall.delete(endPoint: endpointPath())
36+
if let result = data {
37+
let decodedData = try decoder.decode(ConversationModelSchema.self, from: result)
38+
return (decodedData, response)
39+
}
40+
return (nil, response)
41+
}
42+
43+
private func endpointPath() throws -> String {
44+
return try "\(Conversations.RESOURCE_PATH)/\(ConversationModels.RESOURCE_PATH)/\(modelId.encodeURL())"
45+
}
46+
47+
48+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import Foundation
2+
#if canImport(FoundationNetworking)
3+
import FoundationNetworking
4+
#endif
5+
6+
public struct ConversationModels {
7+
static let RESOURCE_PATH = "models"
8+
private var apiCall: ApiCall
9+
10+
11+
init(apiCall: ApiCall) {
12+
self.apiCall = apiCall
13+
}
14+
15+
public func create(params: ConversationModelCreateSchema) async throws -> (ConversationModelSchema?, URLResponse?) {
16+
let schemaData = try encoder.encode(params)
17+
let (data, response) = try await self.apiCall.post(endPoint: endpointPath(), body: schemaData)
18+
if let result = data {
19+
let decodedData = try decoder.decode(ConversationModelSchema.self, from: result)
20+
return (decodedData, response)
21+
}
22+
return (nil, response)
23+
}
24+
25+
public func retrieve() async throws -> ([ConversationModelSchema]?, URLResponse?) {
26+
let (data, response) = try await self.apiCall.get(endPoint: endpointPath())
27+
if let result = data {
28+
let decodedData = try decoder.decode([ConversationModelSchema].self, from: result)
29+
return (decodedData, response)
30+
}
31+
return (nil, response)
32+
}
33+
34+
private func endpointPath() throws -> String {
35+
return "\(Conversations.RESOURCE_PATH)/\(ConversationModels.RESOURCE_PATH)"
36+
}
37+
38+
39+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import Foundation
2+
3+
public struct Conversations {
4+
static let RESOURCE_PATH = "conversations"
5+
private var apiCall: ApiCall
6+
7+
8+
init(apiCall: ApiCall) {
9+
self.apiCall = apiCall
10+
}
11+
12+
public func models() -> ConversationModels {
13+
return ConversationModels(apiCall: apiCall)
14+
}
15+
16+
public func model(modelId: String) -> ConversationModel {
17+
return ConversationModel(apiCall: apiCall, modelId: modelId)
18+
}
19+
20+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//
2+
// ConversationModelCreateSchema.swift
3+
//
4+
// Generated by swagger-codegen
5+
// https://github.com/swagger-api/swagger-codegen
6+
//
7+
8+
import Foundation
9+
10+
11+
12+
public struct ConversationModelCreateSchema: Codable {
13+
14+
/** An explicit id for the model, otherwise the API will return a response with an auto-generated conversation model id. */
15+
public var _id: String?
16+
/** Name of the LLM model offered by OpenAI, Cloudflare or vLLM */
17+
public var modelName: String
18+
/** The LLM service's API Key */
19+
public var apiKey: String?
20+
/** Typesense collection that stores the historical conversations */
21+
public var historyCollection: String?
22+
/** LLM service's account ID (only applicable for Cloudflare) */
23+
public var accountId: String?
24+
/** The system prompt that contains special instructions to the LLM */
25+
public var systemPrompt: String?
26+
/** Time interval in seconds after which the messages would be deleted. Default: 86400 (24 hours) */
27+
public var ttl: Int?
28+
/** The maximum number of bytes to send to the LLM in every API call. Consult the LLM's documentation on the number of bytes supported in the context window. */
29+
public var maxBytes: Int
30+
/** URL of vLLM service */
31+
public var vllmUrl: String?
32+
33+
public init(_id: String? = nil, modelName: String, apiKey: String? = nil, historyCollection: String? = nil, accountId: String? = nil, systemPrompt: String? = nil, ttl: Int? = nil, maxBytes: Int, vllmUrl: String? = nil) {
34+
self._id = _id
35+
self.modelName = modelName
36+
self.apiKey = apiKey
37+
self.historyCollection = historyCollection
38+
self.accountId = accountId
39+
self.systemPrompt = systemPrompt
40+
self.ttl = ttl
41+
self.maxBytes = maxBytes
42+
self.vllmUrl = vllmUrl
43+
}
44+
45+
public enum CodingKeys: String, CodingKey {
46+
case _id = "id"
47+
case modelName = "model_name"
48+
case apiKey = "api_key"
49+
case historyCollection = "history_collection"
50+
case accountId = "account_id"
51+
case systemPrompt = "system_prompt"
52+
case ttl
53+
case maxBytes = "max_bytes"
54+
case vllmUrl = "vllm_url"
55+
}
56+
57+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//
2+
// ConversationModelSchema.swift
3+
//
4+
// Generated by swagger-codegen
5+
// https://github.com/swagger-api/swagger-codegen
6+
//
7+
8+
import Foundation
9+
10+
11+
12+
public struct ConversationModelSchema: Codable {
13+
14+
/** An explicit id for the model, otherwise the API will return a response with an auto-generated conversation model id. */
15+
public var _id: String
16+
/** Name of the LLM model offered by OpenAI, Cloudflare or vLLM */
17+
public var modelName: String?
18+
/** The LLM service's API Key */
19+
public var apiKey: String?
20+
/** Typesense collection that stores the historical conversations */
21+
public var historyCollection: String?
22+
/** LLM service's account ID (only applicable for Cloudflare) */
23+
public var accountId: String?
24+
/** The system prompt that contains special instructions to the LLM */
25+
public var systemPrompt: String?
26+
/** Time interval in seconds after which the messages would be deleted. Default: 86400 (24 hours) */
27+
public var ttl: Int?
28+
/** The maximum number of bytes to send to the LLM in every API call. Consult the LLM's documentation on the number of bytes supported in the context window. */
29+
public var maxBytes: Int?
30+
/** URL of vLLM service */
31+
public var vllmUrl: String?
32+
33+
public init(_id: String, modelName: String? = nil, apiKey: String? = nil, historyCollection: String? = nil, accountId: String? = nil, systemPrompt: String? = nil, ttl: Int? = nil, maxBytes: Int? = nil, vllmUrl: String? = nil) {
34+
self._id = _id
35+
self.modelName = modelName
36+
self.apiKey = apiKey
37+
self.historyCollection = historyCollection
38+
self.accountId = accountId
39+
self.systemPrompt = systemPrompt
40+
self.ttl = ttl
41+
self.maxBytes = maxBytes
42+
self.vllmUrl = vllmUrl
43+
}
44+
45+
public enum CodingKeys: String, CodingKey {
46+
case _id = "id"
47+
case modelName = "model_name"
48+
case apiKey = "api_key"
49+
case historyCollection = "history_collection"
50+
case accountId = "account_id"
51+
case systemPrompt = "system_prompt"
52+
case ttl
53+
case maxBytes = "max_bytes"
54+
case vllmUrl = "vllm_url"
55+
}
56+
57+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//
2+
// ConversationModelUpdateSchema.swift
3+
//
4+
// Generated by swagger-codegen
5+
// https://github.com/swagger-api/swagger-codegen
6+
//
7+
8+
import Foundation
9+
10+
11+
12+
public struct ConversationModelUpdateSchema: Codable {
13+
14+
/** An explicit id for the model, otherwise the API will return a response with an auto-generated conversation model id. */
15+
public var _id: String?
16+
/** Name of the LLM model offered by OpenAI, Cloudflare or vLLM */
17+
public var modelName: String?
18+
/** The LLM service's API Key */
19+
public var apiKey: String?
20+
/** Typesense collection that stores the historical conversations */
21+
public var historyCollection: String?
22+
/** LLM service's account ID (only applicable for Cloudflare) */
23+
public var accountId: String?
24+
/** The system prompt that contains special instructions to the LLM */
25+
public var systemPrompt: String?
26+
/** Time interval in seconds after which the messages would be deleted. Default: 86400 (24 hours) */
27+
public var ttl: Int?
28+
/** The maximum number of bytes to send to the LLM in every API call. Consult the LLM's documentation on the number of bytes supported in the context window. */
29+
public var maxBytes: Int?
30+
/** URL of vLLM service */
31+
public var vllmUrl: String?
32+
33+
public init(_id: String? = nil, modelName: String? = nil, apiKey: String? = nil, historyCollection: String? = nil, accountId: String? = nil, systemPrompt: String? = nil, ttl: Int? = nil, maxBytes: Int? = nil, vllmUrl: String? = nil) {
34+
self._id = _id
35+
self.modelName = modelName
36+
self.apiKey = apiKey
37+
self.historyCollection = historyCollection
38+
self.accountId = accountId
39+
self.systemPrompt = systemPrompt
40+
self.ttl = ttl
41+
self.maxBytes = maxBytes
42+
self.vllmUrl = vllmUrl
43+
}
44+
45+
public enum CodingKeys: String, CodingKey {
46+
case _id = "id"
47+
case modelName = "model_name"
48+
case apiKey = "api_key"
49+
case historyCollection = "history_collection"
50+
case accountId = "account_id"
51+
case systemPrompt = "system_prompt"
52+
case ttl
53+
case maxBytes = "max_bytes"
54+
case vllmUrl = "vllm_url"
55+
}
56+
57+
}

Sources/Typesense/Models/MultiSearchParameters.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,14 @@ public struct MultiSearchParameters: Codable {
120120
public var facetReturnParent: String?
121121
/** The base64 encoded audio file in 16 khz 16-bit WAV format. */
122122
public var voiceQuery: String?
123+
/** Enable conversational search. */
124+
public var conversation: Bool?
125+
/** The Id of Conversation Model to be used. */
126+
public var conversationModelId: String?
127+
/** The Id of a previous conversation to continue, this tells Typesense to include prior context when communicating with the LLM. */
128+
public var conversationId: String?
123129

124-
public init(q: String? = nil, queryBy: String? = nil, queryByWeights: String? = nil, textMatchType: String? = nil, _prefix: String? = nil, _infix: String? = nil, maxExtraPrefix: Int? = nil, maxExtraSuffix: Int? = nil, filterBy: String? = nil, sortBy: String? = nil, facetBy: String? = nil, maxFacetValues: Int? = nil, facetQuery: String? = nil, numTypos: String? = nil, page: Int? = nil, perPage: Int? = nil, limit: Int? = nil, offset: Int? = nil, groupBy: String? = nil, groupLimit: Int? = nil, groupMissingValues: Bool? = nil, includeFields: String? = nil, excludeFields: String? = nil, highlightFullFields: String? = nil, highlightAffixNumTokens: Int? = nil, highlightStartTag: String? = nil, highlightEndTag: String? = nil, snippetThreshold: Int? = nil, dropTokensThreshold: Int? = nil, typoTokensThreshold: Int? = nil, pinnedHits: String? = nil, hiddenHits: String? = nil, overrideTags: String? = nil, highlightFields: String? = nil, preSegmentedQuery: Bool? = nil, preset: String? = nil, enableOverrides: Bool? = nil, prioritizeExactMatch: Bool? = nil, prioritizeTokenPosition: Bool? = nil, prioritizeNumMatchingFields: Bool? = nil, enableTyposForNumericalTokens: Bool? = nil, exhaustiveSearch: Bool? = nil, searchCutoffMs: Int? = nil, useCache: Bool? = nil, cacheTtl: Int? = nil, minLen1typo: Int? = nil, minLen2typo: Int? = nil, vectorQuery: String? = nil, remoteEmbeddingTimeoutMs: Int? = nil, remoteEmbeddingNumTries: Int? = nil, facetStrategy: String? = nil, stopwords: String? = nil, facetReturnParent: String? = nil, voiceQuery: String? = nil) {
130+
public init(q: String? = nil, queryBy: String? = nil, queryByWeights: String? = nil, textMatchType: String? = nil, _prefix: String? = nil, _infix: String? = nil, maxExtraPrefix: Int? = nil, maxExtraSuffix: Int? = nil, filterBy: String? = nil, sortBy: String? = nil, facetBy: String? = nil, maxFacetValues: Int? = nil, facetQuery: String? = nil, numTypos: String? = nil, page: Int? = nil, perPage: Int? = nil, limit: Int? = nil, offset: Int? = nil, groupBy: String? = nil, groupLimit: Int? = nil, groupMissingValues: Bool? = nil, includeFields: String? = nil, excludeFields: String? = nil, highlightFullFields: String? = nil, highlightAffixNumTokens: Int? = nil, highlightStartTag: String? = nil, highlightEndTag: String? = nil, snippetThreshold: Int? = nil, dropTokensThreshold: Int? = nil, typoTokensThreshold: Int? = nil, pinnedHits: String? = nil, hiddenHits: String? = nil, overrideTags: String? = nil, highlightFields: String? = nil, preSegmentedQuery: Bool? = nil, preset: String? = nil, enableOverrides: Bool? = nil, prioritizeExactMatch: Bool? = nil, prioritizeTokenPosition: Bool? = nil, prioritizeNumMatchingFields: Bool? = nil, enableTyposForNumericalTokens: Bool? = nil, exhaustiveSearch: Bool? = nil, searchCutoffMs: Int? = nil, useCache: Bool? = nil, cacheTtl: Int? = nil, minLen1typo: Int? = nil, minLen2typo: Int? = nil, vectorQuery: String? = nil, remoteEmbeddingTimeoutMs: Int? = nil, remoteEmbeddingNumTries: Int? = nil, facetStrategy: String? = nil, stopwords: String? = nil, facetReturnParent: String? = nil, voiceQuery: String? = nil, conversation: Bool? = nil, conversationModelId: String? = nil, conversationId: String? = nil) {
125131
self.q = q
126132
self.queryBy = queryBy
127133
self.queryByWeights = queryByWeights
@@ -176,6 +182,9 @@ public struct MultiSearchParameters: Codable {
176182
self.stopwords = stopwords
177183
self.facetReturnParent = facetReturnParent
178184
self.voiceQuery = voiceQuery
185+
self.conversation = conversation
186+
self.conversationModelId = conversationModelId
187+
self.conversationId = conversationId
179188
}
180189

181190
public enum CodingKeys: String, CodingKey {
@@ -233,6 +242,9 @@ public struct MultiSearchParameters: Codable {
233242
case stopwords
234243
case facetReturnParent = "facet_return_parent"
235244
case voiceQuery = "voice_query"
245+
case conversation
246+
case conversationModelId = "conversation_model_id"
247+
case conversationId = "conversation_id"
236248
}
237249

238250
}

Sources/Typesense/Models/MultiSearchResult.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ import Foundation
1212
public struct MultiSearchResult<T: Codable>: Codable {
1313

1414
public var results: [SearchResult<T>]
15+
public var conversation: SearchResultConversation?
1516

16-
public init(results: [SearchResult<T>]) {
17+
public init(results: [SearchResult<T>], conversation: SearchResultConversation? = nil) {
1718
self.results = results
19+
self.conversation = conversation
1820
}
1921

2022

0 commit comments

Comments
 (0)