ship method

Future<void> ship(
  1. DVPromptVersion version
)

Stores version and makes it answer.

A stored version carries wording, not shape: the call site was compiled against the inputs and output it has. And a number already used, by the compiled prompt, the lockfile or the store, cannot carry other text.

Implementation

Future<void> ship(DVPromptVersion version) async {
  final DVPromptVersion? compiled = _compiled[version.id];
  if (compiled == null) {
    throw ArgumentError.value(version.id, 'version',
        'no compiled prompt has this id, so no call site can use it');
  }
  if (version.shape != compiled.shape) {
    throw ArgumentError.value(
        version,
        'version',
        'changes the inputs, output or schema the call site was compiled '
            'against; a stored version changes wording only');
  }
  String? usedBy;
  if (compiled.version == version.version &&
      compiled.fingerprint != version.fingerprint) {
    usedBy = 'the compiled prompt';
  }
  final DVPromptLockEntry? locked = lock?.entry(version.id, version.version);
  if (locked != null && locked.fingerprint != version.fingerprint) {
    usedBy ??= 'the lockfile';
  }
  for (final DVPromptVersion existing in await store.versions(version.id)) {
    if (existing.version == version.version &&
        existing.fingerprint != version.fingerprint) {
      usedBy ??= 'an earlier stored version';
    }
  }
  if (usedBy != null) {
    throw DVAIOpsError(
      'DV-AIOPS-006',
      'prompt "${version.id}" version ${version.version} is already '
          '$usedBy with other text; a changed prompt takes a new version',
    );
  }
  await store.put(version);
}