mrmd-ai 0.1.0__py3-none-any.whl → 0.1.2__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.
@@ -0,0 +1,173 @@
1
+ """Signature definitions for cursor-based editing and comment processing."""
2
+
3
+ import dspy
4
+ from pydantic import BaseModel, Field
5
+ from typing import List, Optional
6
+
7
+
8
+ class Edit(BaseModel):
9
+ """A single find/replace edit operation.
10
+
11
+ For insertions at cursor, use find="" and the text will be inserted
12
+ at the cursor position.
13
+ """
14
+ find: str = Field(
15
+ description="Exact text to find in document. Use empty string for insertion at cursor."
16
+ )
17
+ replace: str = Field(
18
+ description="Text to replace the found text with, or text to insert if find is empty."
19
+ )
20
+
21
+
22
+ class CommentInfo(BaseModel):
23
+ """Information about a comment in the document."""
24
+ text: str = Field(description="The comment text content")
25
+ context_before: str = Field(description="Text immediately before the comment")
26
+ context_after: str = Field(description="Text immediately after the comment")
27
+
28
+
29
+ class EditAtCursorSignature(dspy.Signature):
30
+ """
31
+ Execute a user instruction by generating precise find/replace edits.
32
+
33
+ You are given the cursor context and a natural language instruction.
34
+ Generate a list of edits that implement the instruction.
35
+
36
+ CRITICAL RULES:
37
+ 1. Each edit has `find` (exact text to locate) and `replace` (replacement text)
38
+ 2. For INSERTIONS at cursor: use find="" - the replace text will be inserted at cursor
39
+ 3. For MODIFICATIONS: find must match the EXACT text in the document (character-for-character)
40
+ 4. find strings must be UNIQUE enough to match only the intended location
41
+ 5. Include surrounding context in find to ensure uniqueness (e.g., "def process_data(items)" not just "process_data")
42
+ 6. Edits are applied in order - earlier edits may shift positions of later ones
43
+
44
+ Examples:
45
+ - Instruction: "add a docstring" → find the function definition, replace with definition + docstring
46
+ - Instruction: "rename x to count" → find=" x " (with spaces), replace=" count "
47
+ - Instruction: "insert a comment here" → find="", replace="# comment\\n"
48
+ - Instruction: "delete this line" → find="the line content\\n", replace=""
49
+
50
+ When the user has selected text, that text is provided in `selection`.
51
+ Prefer to operate on the selection when it's relevant to the instruction.
52
+ """
53
+
54
+ text_before: str = dspy.InputField(
55
+ desc="Text immediately before the cursor (up to 500 characters for context)"
56
+ )
57
+ text_after: str = dspy.InputField(
58
+ desc="Text immediately after the cursor (up to 500 characters for context)"
59
+ )
60
+ selection: str = dspy.InputField(
61
+ desc="Currently selected text, or empty string if no selection"
62
+ )
63
+ full_document: str = dspy.InputField(
64
+ desc="The complete document content for full context"
65
+ )
66
+ instruction: str = dspy.InputField(
67
+ desc="User's natural language instruction for what to do"
68
+ )
69
+
70
+ edits: List[Edit] = dspy.OutputField(
71
+ desc="List of find/replace edits to apply. Order matters - applied sequentially."
72
+ )
73
+
74
+
75
+ class AddressCommentSignature(dspy.Signature):
76
+ """
77
+ Address a single comment/instruction embedded in the document.
78
+
79
+ Comments are marked with <!--! comment text !--> syntax.
80
+ The comment contains instructions or notes that should be addressed.
81
+ Generate edits that fulfill the comment's request.
82
+
83
+ After addressing, you may optionally remove the comment marker itself.
84
+
85
+ Guidelines:
86
+ - Read the comment carefully to understand what's requested
87
+ - Look at the surrounding context to understand where changes should go
88
+ - Generate precise edits that address the comment
89
+ - If the comment asks for something that's already done, return empty edits
90
+ - Consider removing the comment after addressing it (include that as an edit)
91
+ """
92
+
93
+ full_document: str = dspy.InputField(
94
+ desc="The complete document content"
95
+ )
96
+ comment_text: str = dspy.InputField(
97
+ desc="The text content of the comment (without the <!--! !--> markers)"
98
+ )
99
+ comment_context_before: str = dspy.InputField(
100
+ desc="Text immediately before the comment marker"
101
+ )
102
+ comment_context_after: str = dspy.InputField(
103
+ desc="Text immediately after the comment marker"
104
+ )
105
+ comment_raw: str = dspy.InputField(
106
+ desc="The full raw comment including markers (e.g., '<!--! add error handling !-->')"
107
+ )
108
+
109
+ edits: List[Edit] = dspy.OutputField(
110
+ desc="List of find/replace edits to address the comment"
111
+ )
112
+
113
+
114
+ class AddressAllCommentsSignature(dspy.Signature):
115
+ """
116
+ Address ALL comments/instructions in a document.
117
+
118
+ Scan the document for all <!--! ... !--> comment markers and generate
119
+ edits that address each one.
120
+
121
+ Guidelines:
122
+ - Process comments in document order (top to bottom)
123
+ - Each comment should be addressed appropriately
124
+ - Comments that conflict should be resolved sensibly
125
+ - After addressing, remove the comment markers
126
+ - Return all edits as a single list (they'll be applied in order)
127
+ """
128
+
129
+ full_document: str = dspy.InputField(
130
+ desc="The complete document content with embedded comments"
131
+ )
132
+ comments: List[CommentInfo] = dspy.InputField(
133
+ desc="List of all comments found in the document with their context"
134
+ )
135
+
136
+ edits: List[Edit] = dspy.OutputField(
137
+ desc="List of all find/replace edits to address all comments"
138
+ )
139
+
140
+
141
+ class AddressNearbyCommentSignature(dspy.Signature):
142
+ """
143
+ Address the comment nearest to the cursor position.
144
+
145
+ Find the comment that's closest to where the user's cursor is and
146
+ generate edits to address that specific comment.
147
+
148
+ Guidelines:
149
+ - Focus only on the comment nearest to the cursor
150
+ - Use the cursor context to identify which comment is relevant
151
+ - Generate edits that address that comment
152
+ - Optionally remove the comment marker after addressing
153
+ """
154
+
155
+ full_document: str = dspy.InputField(
156
+ desc="The complete document content"
157
+ )
158
+ cursor_context_before: str = dspy.InputField(
159
+ desc="Text before the cursor position"
160
+ )
161
+ cursor_context_after: str = dspy.InputField(
162
+ desc="Text after the cursor position"
163
+ )
164
+ nearby_comment: CommentInfo = dspy.InputField(
165
+ desc="The comment closest to the cursor"
166
+ )
167
+ nearby_comment_raw: str = dspy.InputField(
168
+ desc="The full raw comment including markers"
169
+ )
170
+
171
+ edits: List[Edit] = dspy.OutputField(
172
+ desc="List of find/replace edits to address the nearby comment"
173
+ )
@@ -1,7 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mrmd-ai
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: AI programs for MRMD editor - completions, fixes, and corrections
5
+ License-File: LICENSE
5
6
  Requires-Python: >=3.11
6
7
  Requires-Dist: dspy>=2.6
7
8
  Requires-Dist: fastapi>=0.115
@@ -1,26 +1,30 @@
1
1
  mrmd_ai/__init__.py,sha256=RocuoOEEJCUNinxqsXWjm_bIimCu8aDCDha-G5pU4fU,105
2
- mrmd_ai/juice.py,sha256=0_h7_M89IDhSt4iohdz0J5StcFXOaLF33d3fTxdBO-o,14442
3
- mrmd_ai/server.py,sha256=Jgl-bsQYbBMtv_tGu_2FwSN9BxgFpt-fmb9_pjIcqNw,14416
2
+ mrmd_ai/custom_programs.py,sha256=owdMbWzHNDAoF2LbOpWZnri9xnFIq2BocFtiQLtoDXU,6826
3
+ mrmd_ai/juice.py,sha256=SJjJailZ3o84RbG8XvBIyKAh0ZqDcbKmbekCj6UJa4Q,28544
4
+ mrmd_ai/server.py,sha256=RPZhnp9Gl3tt5x8q2MjlzVrjSvuE-r8yA536JIPQbm8,23515
4
5
  mrmd_ai/metrics/__init__.py,sha256=6BngKqh0a09phOzUdYeWjhsUXznCIx5jEjrEt7DIDu4,62
5
- mrmd_ai/modules/__init__.py,sha256=4V4IzurDZs_nhBTGlHyXco24iwEkum58kRNrKfm4IjQ,1793
6
+ mrmd_ai/modules/__init__.py,sha256=OO-5alsFmR1bLtsvxAJ2wNO5nOtHRmWChTexEI6Y9xU,2097
6
7
  mrmd_ai/modules/code.py,sha256=8cK6LF0ZTrSp2srt1ltvUnmYjPlt5NZTj1yWctpJ7j0,4099
7
8
  mrmd_ai/modules/correct.py,sha256=TWnE1HD_Ip7xZ5yQwJi1n01tNXgBtYNvkTK--kAknak,1478
8
9
  mrmd_ai/modules/document.py,sha256=o6iLR2amscn-DHZ95JFQuEwhaj8cLs4bBISf7G9cT9Y,1106
10
+ mrmd_ai/modules/edit.py,sha256=lGa0tNB7d9tRG4rtdQ6uNIi3lzSbC588c3r86ccPXZc,2736
9
11
  mrmd_ai/modules/finish.py,sha256=VtyE-45-8iM6iWjNg57wRWL0Ln3mSF0RcZq8CO5CoSk,2638
10
12
  mrmd_ai/modules/fix.py,sha256=fb4flKWyyyelheigeb1sI0dixd2scL9HZX-0_M_Uh-o,1506
11
13
  mrmd_ai/modules/notebook.py,sha256=w8Dg-NKVL6_kPOKkvb84kGrwgv5zHxvFNWBtXHLHww8,477
12
14
  mrmd_ai/modules/text.py,sha256=9MCO__EDalwi-iFf__sd8t7orsUy7WiBBf6Lp4bxxGE,2010
13
15
  mrmd_ai/optimizers/__init__.py,sha256=Ay6ZrQu8fLQaG7-dl6hTMruQY5AdGOT_YnlRhhZGgag,60
14
- mrmd_ai/signatures/__init__.py,sha256=wWT2D8beisIpYMPxN4j4JncQmUqcamD6v5BTKp2zFWc,655
16
+ mrmd_ai/signatures/__init__.py,sha256=UoIplXOXxPidkaXi9u-7l2LziDJX2MN4PmwtXVsC04U,1013
15
17
  mrmd_ai/signatures/code.py,sha256=zBM_Nl2NImfOw49fVWCGlXcE_sm8xgWCN1ksDbEa6e8,11245
16
18
  mrmd_ai/signatures/correct.py,sha256=tIhYCONgGhuTV0eJCiLSXcGZSAEi06XY35ommtTTsRE,2920
17
19
  mrmd_ai/signatures/document.py,sha256=4Y-9SeXJGCq098Vy-PIbb_rexS2dYDlkU-kxnKAPVSU,1828
20
+ mrmd_ai/signatures/edit.py,sha256=OBAYsh88Qg_EIoEJHHa28QRuSh2xbGM3OSGWtPJ8u_A,6524
18
21
  mrmd_ai/signatures/finish.py,sha256=x-ZB0U8GQJdNoGGO80FBOxHXjYsCmTFq9fnkXlHDeUY,5294
19
22
  mrmd_ai/signatures/fix.py,sha256=LJNvu9_XjPl90Wtt3xn6s-jGXA9GB5rdIL0MeFyRGtE,3042
20
23
  mrmd_ai/signatures/notebook.py,sha256=ZBioHA9ZTkLUD_UovdfiRYiDaUKuKOCDhiZP1NDFY8o,1226
21
24
  mrmd_ai/signatures/text.py,sha256=GhmFtEZqwivbevPI_NSBzh6AlH6JKLt2rA_LaYGK2lQ,5223
22
25
  mrmd_ai/utils/__init__.py,sha256=T4e9jmFWDSj1HOyz5_Qv-JQSC08GwT_9CACcAn37vWg,46
23
- mrmd_ai-0.1.0.dist-info/METADATA,sha256=4w17Do4YbBpwoT3PFN2i01zswTPJCVzR6rgib0zZXME,1167
24
- mrmd_ai-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
25
- mrmd_ai-0.1.0.dist-info/entry_points.txt,sha256=Bq6nXiXxhNSPEgYWBgrrgJH1DeGjKM6hfCijcWClApw,55
26
- mrmd_ai-0.1.0.dist-info/RECORD,,
26
+ mrmd_ai-0.1.2.dist-info/METADATA,sha256=XP2KXado_UWlhsbveBajtLEdAl9Cjeq3e3XGovqK1sg,1189
27
+ mrmd_ai-0.1.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
28
+ mrmd_ai-0.1.2.dist-info/entry_points.txt,sha256=Bq6nXiXxhNSPEgYWBgrrgJH1DeGjKM6hfCijcWClApw,55
29
+ mrmd_ai-0.1.2.dist-info/licenses/LICENSE,sha256=7WBExfg4gC1NdkdBtnOFRbt_bOD3gKPmEc-7hHMIcXQ,1070
30
+ mrmd_ai-0.1.2.dist-info/RECORD,,
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Maxime Rivest
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.