stefanches7 commited on
Commit
9887d83
Β·
1 Parent(s): 9d1b729

allow a feedback question, remove 2nd prompt

Browse files
Files changed (3) hide show
  1. agent.py +20 -16
  2. cli.py +24 -15
  3. prompts.py +4 -18
agent.py CHANGED
@@ -3,7 +3,7 @@ import os
3
  from dotenv import load_dotenv
4
  import dspy
5
 
6
- import prompts as prompts_mod
7
 
8
 
9
  class BIDSifierAgent:
@@ -13,13 +13,13 @@ class BIDSifierAgent:
13
  load_dotenv()
14
 
15
  if provider=="openai":
16
- if model == "gpt-5":
17
  temperature = 1.0
18
  lm = dspy.LM(f"{provider}/{model}", api_key=os.getenv("OPENAI_API_KEY"), temperature = temperature, max_tokens = 40000)
19
  else:
20
- lm = dspy.LM(f"{provider}/{model}", api_key=os.getenv("OPENAI_API_KEY"), temperature = temperature)
21
  else:
22
- lm = dspy.LM(f"{provider}/{model}", api_key="")
23
 
24
 
25
 
@@ -35,34 +35,27 @@ class BIDSifierAgent:
35
  output_root = context.get("output_root", "./bids_output")
36
 
37
  if step == "summary":
38
- return prompts_mod.summarize_dataset_prompt(
39
- dataset_xml=dataset_xml,
40
- readme_text=readme_text,
41
- publication_text=publication_text,
42
- )
43
- if step == "create_root":
44
- return prompts_mod.create_root_prompt(
45
- output_root=output_root,
46
  dataset_xml=dataset_xml,
47
  readme_text=readme_text,
48
  publication_text=publication_text,
49
  )
50
  if step == "create_metadata":
51
- return prompts_mod.create_metadata_prompt(
52
  output_root=output_root,
53
  dataset_xml=dataset_xml,
54
  readme_text=readme_text,
55
  publication_text=publication_text,
56
  )
57
  if step == "create_structure":
58
- return prompts_mod.create_structure_prompt(
59
  output_root=output_root,
60
  dataset_xml=dataset_xml,
61
  readme_text=readme_text,
62
  publication_text=publication_text,
63
  )
64
  if step == "rename_move":
65
- return prompts_mod.rename_and_move_prompt(
66
  output_root=output_root,
67
  dataset_xml=dataset_xml,
68
  readme_text=readme_text,
@@ -71,7 +64,7 @@ class BIDSifierAgent:
71
  raise ValueError(f"Unknown step: {step}")
72
 
73
  def run_step(self, step: str, context: Dict[str, Any]) -> str:
74
- system_msg = prompts_mod.system_prompt()
75
  user_msg = self._build_user_prompt(step, context)
76
  resp = self.llm(
77
  messages=[
@@ -82,6 +75,17 @@ class BIDSifierAgent:
82
  )
83
  return resp[0]
84
 
 
 
 
 
 
 
 
 
 
 
 
85
 
86
  __all__ = ["BIDSifierAgent"]
87
 
 
3
  from dotenv import load_dotenv
4
  import dspy
5
 
6
+ import prompts
7
 
8
 
9
  class BIDSifierAgent:
 
13
  load_dotenv()
14
 
15
  if provider=="openai":
16
+ if model == "gpt-5": #reasoning model that requires special handling
17
  temperature = 1.0
18
  lm = dspy.LM(f"{provider}/{model}", api_key=os.getenv("OPENAI_API_KEY"), temperature = temperature, max_tokens = 40000)
19
  else:
20
+ lm = dspy.LM(f"{provider}/{model}", api_key=os.getenv("OPENAI_API_KEY"), temperature = temperature, max_tokens = 10000)
21
  else:
22
+ lm = dspy.LM(f"{provider}/{model}", api_key="", max_tokens=10000)
23
 
24
 
25
 
 
35
  output_root = context.get("output_root", "./bids_output")
36
 
37
  if step == "summary":
38
+ return prompts.summarize_dataset_prompt(
 
 
 
 
 
 
 
39
  dataset_xml=dataset_xml,
40
  readme_text=readme_text,
41
  publication_text=publication_text,
42
  )
43
  if step == "create_metadata":
44
+ return prompts.create_metadata_prompt(
45
  output_root=output_root,
46
  dataset_xml=dataset_xml,
47
  readme_text=readme_text,
48
  publication_text=publication_text,
49
  )
50
  if step == "create_structure":
51
+ return prompts.create_structure_prompt(
52
  output_root=output_root,
53
  dataset_xml=dataset_xml,
54
  readme_text=readme_text,
55
  publication_text=publication_text,
56
  )
57
  if step == "rename_move":
58
+ return prompts.rename_and_move_prompt(
59
  output_root=output_root,
60
  dataset_xml=dataset_xml,
61
  readme_text=readme_text,
 
64
  raise ValueError(f"Unknown step: {step}")
65
 
66
  def run_step(self, step: str, context: Dict[str, Any]) -> str:
67
+ system_msg = prompts.system_prompt()
68
  user_msg = self._build_user_prompt(step, context)
69
  resp = self.llm(
70
  messages=[
 
75
  )
76
  return resp[0]
77
 
78
+ def run_query(self, query: str) -> str:
79
+ system_msg = prompts.system_prompt()
80
+ resp = self.llm(
81
+ messages=[
82
+ {"role": "system", "content": system_msg},
83
+ {"role": "user", "content": query},
84
+ ],
85
+ temperature=self.temperature,
86
+ )
87
+ return resp[0]
88
+
89
 
90
  __all__ = ["BIDSifierAgent"]
91
 
cli.py CHANGED
@@ -36,7 +36,11 @@ def _print_commands(commands: List[str]) -> None:
36
  if not commands:
37
  print("(No commands detected in fenced bash block.)")
38
  return
39
- print("\nProposed commands (NOT executed):")
 
 
 
 
40
  for c in commands:
41
  print(f" {c}")
42
 
@@ -53,7 +57,15 @@ def short_divider(title: str) -> None:
53
  print("\n" + "=" * 80)
54
  print(title)
55
  print("=" * 80 + "\n")
56
-
 
 
 
 
 
 
 
 
57
 
58
  def main(argv: Optional[List[str]] = None) -> int:
59
  parser = argparse.ArgumentParser(
@@ -82,6 +94,7 @@ def main(argv: Optional[List[str]] = None) -> int:
82
  "readme_text": readme_text,
83
  "publication_text": publication_text,
84
  "output_root": args.output_root,
 
85
  }
86
 
87
  command_env = {
@@ -99,40 +112,36 @@ def main(argv: Optional[List[str]] = None) -> int:
99
  short_divider("Step 1: Understand dataset")
100
  summary = agent.run_step("summary", context)
101
  print(summary)
 
102
  if not prompt_yes_no("Proceed to create BIDS root?", default=True):
103
  return 0
104
-
105
- short_divider("Step 2: Propose commands to create BIDS root")
106
- root_plan = agent.run_step("create_root", context)
107
- print(root_plan)
108
- cmds = parse_commands_from_markdown(root_plan)
109
- _print_commands(cmds)
110
- if not prompt_yes_no("Proceed to create metadata files?", default=True):
111
- return 0
112
-
113
- short_divider("Step 3: Propose commands to create metadata files")
114
  meta_plan = agent.run_step("create_metadata", context)
115
  print(meta_plan)
116
  cmds = parse_commands_from_markdown(meta_plan)
117
  _print_commands(cmds)
 
118
  if not prompt_yes_no("Proceed to create empty BIDS structure?", default=True):
119
  return 0
120
 
121
- short_divider("Step 4: Propose commands to create dataset structure")
122
  struct_plan = agent.run_step("create_structure", context)
123
  print(struct_plan)
124
  cmds = parse_commands_from_markdown(struct_plan)
125
  _print_commands(cmds)
 
126
  if not prompt_yes_no("Proceed to propose renaming/moving?", default=True):
127
  return 0
128
 
129
- short_divider("Step 5: Propose commands to rename/move files")
130
  move_plan = agent.run_step("rename_move", context)
131
  print(move_plan)
132
  cmds = parse_commands_from_markdown(move_plan)
133
  _print_commands(cmds)
 
134
 
135
- print("\nAll steps completed. Commands were only displayed (never executed). Use them manually or in a future Gradio/HF Space interface.")
136
  return 0
137
 
138
 
 
36
  if not commands:
37
  print("(No commands detected in fenced bash block.)")
38
  return
39
+ print("-----"*10)
40
+
41
+ print("COMMANDS TO EXECUTE:")
42
+
43
+ print("-----"*10)
44
  for c in commands:
45
  print(f" {c}")
46
 
 
57
  print("\n" + "=" * 80)
58
  print(title)
59
  print("=" * 80 + "\n")
60
+
61
+ def enter_feedback_loop(agent: BIDSifierAgent, context: dict) -> dict:
62
+ feedback = input("\nAny comments or corrections to the summary? (press Enter to skip): ").strip()
63
+ while feedback:
64
+ context["user_feedback"] += feedback
65
+ agent_response = agent.run_query(feedback)
66
+ print(agent_response)
67
+ feedback = input("\nAny additional comments or corrections? (press Enter to skip): ").strip()
68
+ return context
69
 
70
  def main(argv: Optional[List[str]] = None) -> int:
71
  parser = argparse.ArgumentParser(
 
94
  "readme_text": readme_text,
95
  "publication_text": publication_text,
96
  "output_root": args.output_root,
97
+ "user_feedback": "",
98
  }
99
 
100
  command_env = {
 
112
  short_divider("Step 1: Understand dataset")
113
  summary = agent.run_step("summary", context)
114
  print(summary)
115
+ context = enter_feedback_loop(agent, context)
116
  if not prompt_yes_no("Proceed to create BIDS root?", default=True):
117
  return 0
118
+
119
+ short_divider("Step 2: Propose commands to create metadata files")
 
 
 
 
 
 
 
 
120
  meta_plan = agent.run_step("create_metadata", context)
121
  print(meta_plan)
122
  cmds = parse_commands_from_markdown(meta_plan)
123
  _print_commands(cmds)
124
+ context = enter_feedback_loop(agent, context)
125
  if not prompt_yes_no("Proceed to create empty BIDS structure?", default=True):
126
  return 0
127
 
128
+ short_divider("Step 3: Propose commands to create dataset structure")
129
  struct_plan = agent.run_step("create_structure", context)
130
  print(struct_plan)
131
  cmds = parse_commands_from_markdown(struct_plan)
132
  _print_commands(cmds)
133
+ context = enter_feedback_loop(agent, context)
134
  if not prompt_yes_no("Proceed to propose renaming/moving?", default=True):
135
  return 0
136
 
137
+ short_divider("Step 4: Propose commands to rename/move files")
138
  move_plan = agent.run_step("rename_move", context)
139
  print(move_plan)
140
  cmds = parse_commands_from_markdown(move_plan)
141
  _print_commands(cmds)
142
+ context = enter_feedback_loop(agent, context)
143
 
144
+ print("\nAll steps completed. Commands were only displayed - use them manually")
145
  return 0
146
 
147
 
prompts.py CHANGED
@@ -33,7 +33,7 @@ def system_prompt() -> str:
33
 
34
  def summarize_dataset_prompt(*, dataset_xml: Optional[str], readme_text: Optional[str], publication_text: Optional[str]) -> str:
35
  return f"""
36
- Step 1/5 β€” Understand the dataset and produce a short summary.
37
 
38
  Requirements:
39
  - 8–15 concise bullets covering subjects/sessions, modalities (T1w/T2w/DWI/fMRI/etc.), tasks, naming patterns, id conventions.
@@ -47,25 +47,11 @@ Output:
47
  """
48
 
49
 
50
- def create_root_prompt(*, output_root: str, dataset_xml: Optional[str], readme_text: Optional[str], publication_text: Optional[str]) -> str:
51
- return f"""
52
- Step 2/5 β€” Propose commands to create a new BIDS root directory.
53
-
54
- Constraints:
55
- - Use $OUTPUT_ROOT if present, otherwise use: {output_root}
56
- - Use mkdir -p; don't overwrite existing files.
57
- - Optionally create a minimal skeleton (.bidsignore, empty dirs if helpful).
58
-
59
- Context:\n{_ctx(dataset_xml, readme_text, publication_text)}
60
-
61
- Output:
62
- - A brief plan (2–5 bullets) followed by exactly one fenced bash block with commands only.
63
- """
64
 
65
 
66
  def create_metadata_prompt(*, output_root: str, dataset_xml: Optional[str], readme_text: Optional[str], publication_text: Optional[str]) -> str:
67
  return f"""
68
- Step 3/5 β€” Propose commands to create required BIDS metadata files.
69
 
70
  Must include:
71
  - dataset_description.json (Name, BIDSVersion, License if known)
@@ -86,7 +72,7 @@ Output:
86
 
87
  def create_structure_prompt(*, output_root: str, dataset_xml: Optional[str], readme_text: Optional[str], publication_text: Optional[str]) -> str:
88
  return f"""
89
- Step 4/5 β€” Propose commands to create the BIDS directory structure.
90
 
91
  Goals:
92
  - Infer subjects, sessions, and modalities; create sub-<label>/, optional ses-<label>/, and modality folders (anat, dwi, func, fmap, etc.).
@@ -105,7 +91,7 @@ Output:
105
 
106
  def rename_and_move_prompt(*, output_root: str, dataset_xml: Optional[str], readme_text: Optional[str], publication_text: Optional[str]) -> str:
107
  return f"""
108
- Step 5/5 β€” Propose commands to rename and move files into the BIDS structure.
109
 
110
  Requirements:
111
  - Map original names to BIDS filenames; demonstrate patterns (e.g., with find/xargs) carefully.
 
33
 
34
  def summarize_dataset_prompt(*, dataset_xml: Optional[str], readme_text: Optional[str], publication_text: Optional[str]) -> str:
35
  return f"""
36
+ Step 1/4 β€” Understand the dataset and produce a short summary.
37
 
38
  Requirements:
39
  - 8–15 concise bullets covering subjects/sessions, modalities (T1w/T2w/DWI/fMRI/etc.), tasks, naming patterns, id conventions.
 
47
  """
48
 
49
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
 
52
  def create_metadata_prompt(*, output_root: str, dataset_xml: Optional[str], readme_text: Optional[str], publication_text: Optional[str]) -> str:
53
  return f"""
54
+ Step 2/4 β€” Propose commands to create required BIDS metadata files.
55
 
56
  Must include:
57
  - dataset_description.json (Name, BIDSVersion, License if known)
 
72
 
73
  def create_structure_prompt(*, output_root: str, dataset_xml: Optional[str], readme_text: Optional[str], publication_text: Optional[str]) -> str:
74
  return f"""
75
+ Step 3/4 β€” Propose commands to create the BIDS directory structure.
76
 
77
  Goals:
78
  - Infer subjects, sessions, and modalities; create sub-<label>/, optional ses-<label>/, and modality folders (anat, dwi, func, fmap, etc.).
 
91
 
92
  def rename_and_move_prompt(*, output_root: str, dataset_xml: Optional[str], readme_text: Optional[str], publication_text: Optional[str]) -> str:
93
  return f"""
94
+ Step 4/4 β€” Propose commands to rename and move files into the BIDS structure.
95
 
96
  Requirements:
97
  - Map original names to BIDS filenames; demonstrate patterns (e.g., with find/xargs) carefully.