pachet commited on
Commit
e4d36be
·
1 Parent(s): d8ff4c6

Update Continuator context-BP adapter

Browse files
backend/app/continuator_adapter.py CHANGED
@@ -290,16 +290,56 @@ class ContinuatorSessionEngine:
290
  engine.set_transpose(self._transposition)
291
  engine.set_forget(self._forget_past)
292
  engine.set_keep_last(self._keep_last_inputs)
293
- engine.set_decay_mode(self._decay_mode)
 
 
 
294
  self._seed_sequence_count = (
295
- len(getattr(engine.vom, "input_sequences", [])) if load_seed_material else 0
296
  )
297
  return engine
298
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
299
  def _is_input_sequence_end_address(self, note_address: object) -> bool:
300
  try:
301
  sequence_index, note_index = note_address
302
- sequences = getattr(self._continuator.vom, "input_sequences", [])
303
  sequence = sequences[int(sequence_index)]
304
  except (AttributeError, IndexError, TypeError, ValueError):
305
  return False
@@ -314,7 +354,7 @@ class ContinuatorSessionEngine:
314
  if not force_ending_realization or not vp_sequence:
315
  return self._continuator.realize_vp_sequence(vp_sequence)
316
 
317
- realizations_by_viewpoint = getattr(self._continuator.vom, "viewpoints_realizations", {})
318
  note_addresses = []
319
  for index, viewpoint in enumerate(vp_sequence):
320
  realizations = list(realizations_by_viewpoint.get(viewpoint, []))
@@ -432,7 +472,9 @@ class ContinuatorSessionEngine:
432
  if keep_last_inputs is not None:
433
  self._continuator.set_keep_last(keep_last_inputs)
434
  if decay_mode is not None:
435
- self._continuator.set_decay_mode(decay_mode)
 
 
436
 
437
  def reset(self) -> None:
438
  with self._lock:
@@ -440,7 +482,7 @@ class ContinuatorSessionEngine:
440
 
441
  def get_memory_snapshot(self) -> tuple[list[PhrasePayload], int]:
442
  with self._lock:
443
- sequences = list(getattr(self._continuator.vom, "input_sequences", []))
444
  payloads = [_build_phrase_payload(sequence) for sequence in sequences]
445
  seed_count = min(self._seed_sequence_count, len(payloads))
446
  return payloads, seed_count
@@ -523,7 +565,7 @@ class ContinuatorSessionEngine:
523
  str | None,
524
  ]:
525
  with self._lock:
526
- if not getattr(self._continuator.vom, "input_sequences", []):
527
  raise NoContinuationAvailable(
528
  "The Continuator memory is empty. Load MIDI or learn a phrase first."
529
  )
@@ -684,7 +726,7 @@ class ContinuatorSessionEngine:
684
  ),
685
  )
686
  if requested_handoff_viewpoint is not None:
687
- if self._continuator.vom.has_viewpoint(requested_handoff_viewpoint):
688
  prefix_for_generation = None
689
  start_viewpoint = requested_handoff_viewpoint
690
  else:
@@ -699,7 +741,7 @@ class ContinuatorSessionEngine:
699
  )
700
 
701
  if start_viewpoint is None:
702
- if not self._continuator.vom.has_viewpoint(input_handoff_viewpoint):
703
  prefix_for_generation = None
704
  constraints_status.start.applied = False
705
  constraints_status.start.relaxed = True
 
290
  engine.set_transpose(self._transposition)
291
  engine.set_forget(self._forget_past)
292
  engine.set_keep_last(self._keep_last_inputs)
293
+ set_decay_mode = getattr(engine, "set_decay_mode", None)
294
+ if callable(set_decay_mode):
295
+ set_decay_mode(self._decay_mode)
296
+ midi_store = self._engine_midi_store(engine)
297
  self._seed_sequence_count = (
298
+ len(getattr(midi_store, "input_sequences", [])) if load_seed_material else 0
299
  )
300
  return engine
301
 
302
+ @staticmethod
303
+ def _engine_midi_store(engine: object) -> object | None:
304
+ store_for_engine = getattr(engine, "_midi_store", None)
305
+ if callable(store_for_engine):
306
+ try:
307
+ return store_for_engine()
308
+ except AttributeError:
309
+ pass
310
+ store = getattr(engine, "realization_store", None)
311
+ if store is not None:
312
+ return store
313
+ return getattr(engine, "vom", None)
314
+
315
+ def _midi_store(self) -> object | None:
316
+ return self._engine_midi_store(self._continuator)
317
+
318
+ def _input_sequences(self) -> list[object]:
319
+ store = self._midi_store()
320
+ if store is None:
321
+ return []
322
+ return list(getattr(store, "input_sequences", []))
323
+
324
+ def _viewpoint_realizations(self) -> object:
325
+ store = self._midi_store()
326
+ if store is None:
327
+ return {}
328
+ return getattr(store, "viewpoints_realizations", {})
329
+
330
+ def _has_viewpoint(self, viewpoint: object) -> bool:
331
+ store = self._midi_store()
332
+ if store is None:
333
+ return False
334
+ has_viewpoint = getattr(store, "has_viewpoint", None)
335
+ if callable(has_viewpoint):
336
+ return bool(has_viewpoint(viewpoint))
337
+ return viewpoint in getattr(store, "viewpoints_realizations", {})
338
+
339
  def _is_input_sequence_end_address(self, note_address: object) -> bool:
340
  try:
341
  sequence_index, note_index = note_address
342
+ sequences = self._input_sequences()
343
  sequence = sequences[int(sequence_index)]
344
  except (AttributeError, IndexError, TypeError, ValueError):
345
  return False
 
354
  if not force_ending_realization or not vp_sequence:
355
  return self._continuator.realize_vp_sequence(vp_sequence)
356
 
357
+ realizations_by_viewpoint = self._viewpoint_realizations()
358
  note_addresses = []
359
  for index, viewpoint in enumerate(vp_sequence):
360
  realizations = list(realizations_by_viewpoint.get(viewpoint, []))
 
472
  if keep_last_inputs is not None:
473
  self._continuator.set_keep_last(keep_last_inputs)
474
  if decay_mode is not None:
475
+ set_decay_mode = getattr(self._continuator, "set_decay_mode", None)
476
+ if callable(set_decay_mode):
477
+ set_decay_mode(decay_mode)
478
 
479
  def reset(self) -> None:
480
  with self._lock:
 
482
 
483
  def get_memory_snapshot(self) -> tuple[list[PhrasePayload], int]:
484
  with self._lock:
485
+ sequences = self._input_sequences()
486
  payloads = [_build_phrase_payload(sequence) for sequence in sequences]
487
  seed_count = min(self._seed_sequence_count, len(payloads))
488
  return payloads, seed_count
 
565
  str | None,
566
  ]:
567
  with self._lock:
568
+ if not self._input_sequences():
569
  raise NoContinuationAvailable(
570
  "The Continuator memory is empty. Load MIDI or learn a phrase first."
571
  )
 
726
  ),
727
  )
728
  if requested_handoff_viewpoint is not None:
729
+ if self._has_viewpoint(requested_handoff_viewpoint):
730
  prefix_for_generation = None
731
  start_viewpoint = requested_handoff_viewpoint
732
  else:
 
741
  )
742
 
743
  if start_viewpoint is None:
744
+ if not self._has_viewpoint(input_handoff_viewpoint):
745
  prefix_for_generation = None
746
  constraints_status.start.applied = False
747
  constraints_status.start.relaxed = True
backend/requirements.txt CHANGED
@@ -4,4 +4,4 @@ pydantic>=2.7,<3
4
  numpy>=2.0,<3
5
  mido>=1.3,<2
6
  python-multipart>=0.0.9,<1
7
- continuator @ git+https://github.com/fpachet/continuator.git@7660b0246e1e03d5e16575836857afcf7e633a64
 
4
  numpy>=2.0,<3
5
  mido>=1.3,<2
6
  python-multipart>=0.0.9,<1
7
+ continuator @ git+https://github.com/fpachet/continuator.git@d6cee2aabfab8e573d651ce9601a980fa389f003