Skip to content

Conversation

@leondz
Copy link
Collaborator

@leondz leondz commented Sep 10, 2025

fixes #1347

attempt.prompt accepts Message or Conversation - now we check for this

hey seeing as local models are difficult to run, are perhaps the minority case, and are where most of our deps come from, what are thoughts on dropping these, and migrating to something strongly typed, like rust?

Verification

  • tests pass
  • garak -m test -g 1 runs

@leondz leondz added the architecture Architectural upgrades label Sep 10, 2025
@leondz
Copy link
Collaborator Author

leondz commented Nov 10, 2025

consider removing support for lang param in Attempt constructor & migrating to Message (see #1468)

message = entity.pop("content", {})
if isinstance(message, str):
content = Message(text=message)
content = Message(message, str)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this revision is correct, str is a class and passing it as the second argument to this constructor would not be valid. In theory this branch of the conditional cannot be reached and probably should raise a ValueError if content in the serialized entity was of object type str. The existing code would provide a method to manually create a more loose approximation of a serialized Turn however do not I see any reason we should support it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look right either, and I suspect something like this should have been flagged in tests. Will check tests.

Copy link
Collaborator

@jmartin-tech jmartin-tech Nov 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, in theory this code cannot actually be reached as we only deserialize Message objects that have been serialized from a valid original Message. I suspect existing tests never enter this conditional and if can be removed or adjusted to raise ValueError.

Copy link
Collaborator

@jmartin-tech jmartin-tech left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Early review thoughts.

Comment on lines 225 to +229
elif isinstance(prompt, str):
msg = Message(text=prompt, lang=lang)
raise ValueError(
"attempt Prompt must be Message or Conversation, not string"
)
# msg = Message(text=prompt, lang=lang)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer to just remove this.

Copy link
Collaborator Author

@leondz leondz Nov 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, will leave this in until general functionality looks like it's in place. Wouldn't mind gating on a debug flag - but we don't have one, and this affects control flow, so gating on verbosity isn't the way

Comment on lines 334 to +339
if isinstance(value, str):
# note this does not contain a lang
self._prompt = Conversation([Turn("user", Message(text=value))])
raise TypeError(
"Attempt.prompt must be Message or Conversation, not bare string"
)
# self._prompt = Conversation([Turn("user", Message(text=value))])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again prefer to just remove this.

d = _plugins.load_plugin("detectors.continuation.Continuation")

a = garak.attempt.Attempt(prompt="test prompts")
a = garak.attempt.Attempt(prompt=garak.attempt.Message(text="test prompts"))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Many of the edits in this file look ripe for a single CONSTANT.

d = MitigationBypass()
attempt = garak.attempt.Attempt(prompt="testing prompt", lang=d.lang_spec)
attempt = garak.attempt.Attempt(
prompt=garak.attempt.Message(text="testing prompt"), lang=d.lang_spec
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I don't think we actually have any detectors with multiple lang values in lang_spec this should probably be explicit.

Suggested change
prompt=garak.attempt.Message(text="testing prompt"), lang=d.lang_spec
prompt=garak.attempt.Message(text="testing prompt"), lang=d.lang_spec.split(",")[0]

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, so plugin .lang_spec is a spec and lang (in e.g. Message) is a single choice. Which is clear from var name. Let's aim to continue with this explicit & clear convention.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

architecture Architectural upgrades

Projects

None yet

Development

Successfully merging this pull request may close these issues.

arch: remove support for accessing/instantiating prompt/Message as str

2 participants