| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Apple-first local search and semantic retrieval for Swift apps.
SwiftlyFetch is now shelved indefinitely, along with other simultaneous projects made sustainable by cheap, automated assistance which I can no longer afford. Should the economy and job market ever improve, I'll pick this back up.
SwiftlyFetch is a Swift package family for apps that need to index local documents, search them, and assemble useful retrieval context without sending the job to a remote service. The current package is early, but useful: it ships semantic retrieval through RAGCore and RAGKit, conventional search through FetchCore and FetchKit, and the first umbrella SwiftlyFetch facade for one-corpus ingestion.
Use SwiftlyFetch when you want:
The package family is intentionally split by job:
SwiftlyFetch has tagged releases stable enough to try locally, and the umbrella SwiftlyFetch surface is available in the current codebase. See GitHub Releases for the latest published version details.
SwiftlyFetch is not a chat framework, LLM SDK, agent runtime, or remote-provider abstraction. Its job is local retrieval: document preparation, indexing, search, filtering, and context assembly.
Add SwiftlyFetch to your Package.swift dependencies:
.package(url: "https://github.com/gaelic-ghost/SwiftlyFetch", from: "0.2.0"),Then add the library product to your target dependencies:
.product(name: "SwiftlyFetch", package: "SwiftlyFetch"),The package is still a bit early, but the retrieval surface is real enough to try locally. For the coordinated corpus surface, import SwiftlyFetch:
import FetchCore
import RAGCore
import SwiftlyFetch
let library = SwiftlyFetchLibrary.default()
try await library.addDocument(
FetchDocumentRecord(
id: "guide",
title: "Fruit Guide",
body: "Apples are bright and crisp.",
contentType: .markdown,
kind: .guide,
language: "en"
)
)
let searchResults = try await library.search(FetchSearchQuery("fruit guide"))
let semanticResults = try await library.retrieve(SearchQuery("bright fruit"))For lower-level semantic retrieval, import RAGCore and RAGKit directly:
import RAGCore
import RAGKit
let kb = KnowledgeBase.hashingDefault()
try await kb.addDocument(
Document(
id: "guide",
content: .markdown(
"""
# Fruit Guide
## Apples
Apples are bright and crisp.
"""
)
)
)
let results = try await kb.search("bright fruit")
let context = try await kb.makeContext(for: "bright fruit")The current public surface centers on five library products: RAGCore, RAGKit, FetchCore, FetchKit, and SwiftlyFetch.
For coordinated one-corpus ingestion, use SwiftlyFetchLibrary from SwiftlyFetch:
import FetchCore
import RAGCore
import SwiftlyFetch
let library = SwiftlyFetchLibrary.default()
let mutation = try await library.addDocument(
FetchDocumentRecord(
id: "guide",
title: "Apple Guide",
body: "Apples are bright and crisp.",
contentType: .markdown
)
)
let conventionalResults = try await library.search(FetchSearchQuery("apple guide"))
let semanticResults = try await library.retrieve(SearchQuery("bright crisp"))
let sideBySideResults = try await library.searchAndRetrieve(
conventional: FetchSearchQuery("apple guide"),
semantic: SearchQuery("bright crisp")
)SwiftlyFetchMutationResult reports conventional and semantic outcomes separately. If the corpus write succeeds but semantic indexing fails, the facade queues a semantic retry instead of pretending the whole write failed. retrySemanticIndexing(limit:) respects retry cooldowns through nextRetryAt and reports deferred document IDs separately from completed, missing, and failed retries. searchAndRetrieve(...) returns conventional and semantic results side by side without combining scores; ranked hybrid search remains future work.
For semantic retrieval, use KnowledgeBase from RAGKit:
import RAGCore
import RAGKit
let localKB = KnowledgeBase.hashingDefault()
let appleKB = try await KnowledgeBase.naturalLanguageDefault(languageHint: "en")
let semanticStore = FileManager.default
.temporaryDirectory
.appendingPathComponent("SwiftlyFetchSemantic.sqlite")
let persistentKB = try await KnowledgeBase.persistentHashingDefault(
configuration: .init(store: .sqlite(semanticStore))
)For conventional search, use FetchKitLibrary from FetchKit:
import FetchCore
import FetchKit
let library = FetchKitLibrary()
try await library.addDocument(
FetchDocumentRecord(
id: "guide",
title: "Apple Guide",
body: "Apples are bright and crisp.",
contentType: .markdown,
kind: .guide,
language: "en"
)
)
let results = try await library.search("apple guide")
let firstResult = results.first
let matchedFields = firstResult?.matchedFields
let snippetField = firstResult?.snippetField
try await library.removeDocuments(withIDs: ["guide"])matchedFields identifies every indexed field that contributed to a search result. snippetField identifies the field used to build the returned snippet. Simple result lists can show why a result appeared immediately, while richer UIs can render title evidence differently from body evidence. Mutation results report the affected document IDs, including removeAllDocuments(), so app code can update local UI state without re-deriving which records changed.
On macOS, the persistent conventional-search surface is now also shaped around one library storage location instead of separate store and index URLs:
import FetchKit
let persistentLibrary = try await FetchKitLibrary.macOSPersistentLibrary()
let previewLibrary = try await FetchKitLibrary.macOSPersistentLibrary(
at: URL(fileURLWithPath: "/tmp/SwiftlyFetchPreview", isDirectory: true)
)If a caller needs raw markdown link destinations for downstream indexing or fetch-oriented work, opt in at the chunker boundary instead of widening default chunk text:
import RAGKit
let chunker = HeadingAwareMarkdownChunker(linkDestinationMetadataMode: .include)Current defaults:
SwiftlyFetch is usable today as a local Apple-first package family, but it is still early in the broader product arc.
Good current fits:
Current constraints:
For contributor setup, branch workflow, verification commands, and review expectations, use CONTRIBUTING.md. Maintainer planning and architecture notes live under docs/maintainers/.
See the repository's GitHub releases for published package notes. Release workflow details belong in CONTRIBUTING.md and the maintainer docs, not in this user-facing README.
Licensed under the Apache License 2.0. See LICENSE.
| Back | FazBrowse Home | New Git URL |