docsif 0.1.0__py3-none-any.whl

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.
Files changed (86) hide show
  1. docsif-0.1.0.dist-info/METADATA +393 -0
  2. docsif-0.1.0.dist-info/RECORD +86 -0
  3. docsif-0.1.0.dist-info/WHEEL +4 -0
  4. docsif-0.1.0.dist-info/entry_points.txt +3 -0
  5. docsif-0.1.0.dist-info/licenses/LICENSE +21 -0
  6. sif/__init__.py +24 -0
  7. sif/_version.py +3 -0
  8. sif/cli/__init__.py +11 -0
  9. sif/cli/commands/__init__.py +18 -0
  10. sif/cli/commands/bench.py +148 -0
  11. sif/cli/commands/collection.py +360 -0
  12. sif/cli/commands/context.py +154 -0
  13. sif/cli/commands/get.py +200 -0
  14. sif/cli/commands/index.py +294 -0
  15. sif/cli/commands/ls.py +67 -0
  16. sif/cli/commands/mcp.py +93 -0
  17. sif/cli/commands/pull.py +111 -0
  18. sif/cli/commands/search.py +574 -0
  19. sif/cli/config.py +206 -0
  20. sif/cli/formatters.py +269 -0
  21. sif/cli/main.py +205 -0
  22. sif/config/__init__.py +30 -0
  23. sif/config/constants.py +52 -0
  24. sif/config/settings.py +217 -0
  25. sif/core/__init__.py +21 -0
  26. sif/core/collection.py +161 -0
  27. sif/core/context.py +167 -0
  28. sif/core/document.py +125 -0
  29. sif/core/models.py +298 -0
  30. sif/database/__init__.py +23 -0
  31. sif/database/connection.py +139 -0
  32. sif/database/database.py +136 -0
  33. sif/database/migrations.py +187 -0
  34. sif/database/repositories.py +500 -0
  35. sif/database/repository.py +171 -0
  36. sif/database/schema.py +362 -0
  37. sif/embedding/__init__.py +22 -0
  38. sif/embedding/cache.py +196 -0
  39. sif/embedding/embedder.py +328 -0
  40. sif/embedding/factory.py +92 -0
  41. sif/embedding/manager.py +200 -0
  42. sif/embedding/model.py +126 -0
  43. sif/indexing/__init__.py +21 -0
  44. sif/indexing/chunker.py +226 -0
  45. sif/indexing/indexer.py +226 -0
  46. sif/indexing/parser.py +192 -0
  47. sif/indexing/scanner.py +148 -0
  48. sif/indexing/watcher.py +156 -0
  49. sif/mcp/README.md +258 -0
  50. sif/mcp/__init__.py +9 -0
  51. sif/mcp/claude_desktop_config.json +16 -0
  52. sif/mcp/cli.py +92 -0
  53. sif/mcp/protocol.py +336 -0
  54. sif/mcp/server.py +433 -0
  55. sif/mcp/server_http.py +54 -0
  56. sif/mcp/test_mcp.py +108 -0
  57. sif/mcp/tools.py +497 -0
  58. sif/mcp/transport_http.py +424 -0
  59. sif/mcp/transport_stdio.py +292 -0
  60. sif/mcp_server/__init__.py +26 -0
  61. sif/mcp_server/handlers.py +68 -0
  62. sif/mcp_server/server.py +58 -0
  63. sif/mcp_server/tools.py +216 -0
  64. sif/mcp_server/transport.py +221 -0
  65. sif/models/__init__.py +70 -0
  66. sif/models/collection.py +51 -0
  67. sif/models/context.py +45 -0
  68. sif/models/document.py +76 -0
  69. sif/models/download.py +208 -0
  70. sif/models/embedding.py +71 -0
  71. sif/models/search.py +92 -0
  72. sif/search/__init__.py +22 -0
  73. sif/search/benchmark.py +110 -0
  74. sif/search/bm25.py +216 -0
  75. sif/search/expansion.py +157 -0
  76. sif/search/hybrid.py +323 -0
  77. sif/search/rerank.py +390 -0
  78. sif/search/rrf.py +186 -0
  79. sif/search/snippets.py +130 -0
  80. sif/search/strategy.py +97 -0
  81. sif/search/vector.py +177 -0
  82. sif/utils/__init__.py +26 -0
  83. sif/utils/logging.py +143 -0
  84. sif/utils/paths.py +82 -0
  85. sif/utils/progress.py +83 -0
  86. sif/utils/text.py +128 -0
sif/utils/text.py ADDED
@@ -0,0 +1,128 @@
1
+ """Text processing utilities for SIF."""
2
+
3
+ import re
4
+ from re import Pattern
5
+ from typing import Any
6
+
7
+
8
+ # Compile regex patterns once
9
+ WHITESPACE_PATTERN: Pattern[str] = re.compile(r"\s+")
10
+ NON_ALPHANUMERIC_PATTERN: Pattern[str] = re.compile(r"[^\w\s-]")
11
+
12
+
13
+ def normalize_text(text: str) -> str:
14
+ """Normalize text by cleaning whitespace and special characters.
15
+
16
+ Args:
17
+ text: Input text
18
+
19
+ Returns:
20
+ Normalized text
21
+ """
22
+ # Replace multiple whitespace with single space
23
+ text = WHITESPACE_PATTERN.sub(" ", text)
24
+ # Strip leading/trailing whitespace
25
+ text = text.strip()
26
+ return text
27
+
28
+
29
+ def truncate_text(text: str, max_length: int, suffix: str = "...") -> str:
30
+ """Truncate text to maximum length.
31
+
32
+ Args:
33
+ text: Input text
34
+ max_length: Maximum length
35
+ suffix: Suffix to add if truncated
36
+
37
+ Returns:
38
+ Truncated text
39
+ """
40
+ if len(text) <= max_length:
41
+ return text
42
+
43
+ truncated = text[: max_length - len(suffix)]
44
+ return truncated + suffix
45
+
46
+
47
+ def count_tokens(text: str, tokenizer: Any | None = None) -> int:
48
+ """Count tokens in text.
49
+
50
+ Uses a rough estimate if no tokenizer is provided.
51
+
52
+ Args:
53
+ text: Input text
54
+ tokenizer: Optional tokenizer to use
55
+
56
+ Returns:
57
+ Estimated token count
58
+ """
59
+ if tokenizer is not None:
60
+ try:
61
+ return len(tokenizer.encode(text))
62
+ except Exception:
63
+ pass
64
+
65
+ # Rough estimate: 1 token ~= 4 characters for English text
66
+ return len(text) // 4
67
+
68
+
69
+ def split_into_sentences(text: str) -> list[str]:
70
+ """Split text into sentences.
71
+
72
+ Args:
73
+ text: Input text
74
+
75
+ Returns:
76
+ List of sentences
77
+ """
78
+ # Simple sentence splitting on punctuation
79
+ sentences = re.split(r"(?<=[.!?])\s+", text)
80
+ return [s.strip() for s in sentences if s.strip()]
81
+
82
+
83
+ def extract_code_blocks(text: str) -> list[tuple[str, str]]:
84
+ """Extract code blocks from markdown text.
85
+
86
+ Args:
87
+ text: Markdown text
88
+
89
+ Returns:
90
+ List of (language, code) tuples
91
+ """
92
+ pattern = r"```(\w+)?\n(.*?)```"
93
+ matches = re.findall(pattern, text, re.DOTALL)
94
+ return [(lang or "text", code.strip()) for lang, code in matches]
95
+
96
+
97
+ def remove_code_blocks(text: str) -> str:
98
+ """Remove code blocks from markdown text.
99
+
100
+ Args:
101
+ text: Markdown text
102
+
103
+ Returns:
104
+ Text without code blocks
105
+ """
106
+ pattern = r"```.*?```"
107
+ return re.sub(pattern, "", text, flags=re.DOTALL).strip()
108
+
109
+
110
+ def slugify(text: str) -> str:
111
+ """Convert text to URL-friendly slug.
112
+
113
+ Args:
114
+ text: Input text
115
+
116
+ Returns:
117
+ Slugified text
118
+ """
119
+ # Convert to lowercase
120
+ text = text.lower()
121
+ # Remove non-alphanumeric characters except hyphens
122
+ text = NON_ALPHANUMERIC_PATTERN.sub("", text)
123
+ # Replace spaces with hyphens
124
+ text = text.replace(" ", "-")
125
+ # Remove multiple hyphens
126
+ text = re.sub(r"-+", "-", text)
127
+ # Strip leading/trailing hyphens
128
+ return text.strip("-")