Skip to content

Conversation

@Elyorcv
Copy link
Contributor

@Elyorcv Elyorcv commented Apr 22, 2025

Overview

Closes AUTH-1599

  • Replace fake PD with real generation
  • UI changes
    • We see the warning only if PD is selected
    • Removed Write a protocol ... API v2 ... because PD protocol is nothing to do with PAPI
    • Replace the question in ChatDisplay by Protocol Format

With PAPI
image

With PD
image

With ChatDisplay
image

Review requests

  • Please run and confirm you see the changes in UI
  • Make the following Serial dilution in UI
Serial Dilution

**Protocol Format**
- Protocol Designer

**Robot**
- Flex

**Labware**
- Tiprack-1: Opentrons Flex 96 Filter Tip Rack 1000 μL (Slot D1)
- Tiprack-2: Opentrons Flex 96 Filter Tip Rack 1000 μL (Slot C1)
- Reservoir: NEST 12 Well Reservoir 15 mL (Slot D2)
- Plate: NEST 96 Well Plate 200 μL Flat (Slot D3)


**Pipette**
- Left mount: p1000 single channel Flex pipette


**Liquids**
- Diluent liquid (green, 12 mL in reservoir well A1)
- Sample liquid (red, 150 μL in each well of column 1 of the plate)

**Steps**
1 Distribute 100 μL of diluent from reservoir well A1 to all wells in columns 2-11 of the plate (with 10 μL air gap during aspiration and 5 μL disposal volume)

2. Perform serial dilutions for Row A:
 - Transfer 50 μL from A1 to A2, mix 5× with 75 μL
 - Transfer 50 μL from A2 to A3, mix 5× with 75 μL
 - Continue this pattern through A10 to A11
 - Use 10 μL air gap during aspiration
 - Change tip once for the entire row

3-9. Repeat the same serial dilution pattern for Rows B through H (one row at a time)

10. Add 100 μL blank (diluent) to the last column (column 12) of the plate

Risk assessment

Medium

@Elyorcv Elyorcv force-pushed the AUTH-1599-model-update-generate-different-protocol-formats-2 branch from 8d113d0 to 7043f22 Compare April 22, 2025 18:01
@codecov
Copy link

codecov bot commented Apr 22, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 57.48%. Comparing base (5c861e5) to head (ee163a7).
Report is 6 commits behind head on edge.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             edge   #18146      +/-   ##
==========================================
- Coverage   57.48%   57.48%   -0.01%     
==========================================
  Files        3043     3043              
  Lines      255276   255275       -1     
  Branches    30517    30516       -1     
==========================================
- Hits       146756   146755       -1     
  Misses     108333   108333              
  Partials      187      187              
Flag Coverage Δ
protocol-designer 18.93% <ø> (ø)
step-generation 4.37% <ø> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

see 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Elyorcv Elyorcv force-pushed the AUTH-1599-model-update-generate-different-protocol-formats-2 branch 6 times, most recently from 4c50455 to eca8934 Compare April 22, 2025 20:33
@Elyorcv Elyorcv marked this pull request as ready for review April 22, 2025 20:57
@Elyorcv Elyorcv requested review from a team as code owners April 22, 2025 20:57
@Elyorcv Elyorcv changed the title feat(opentrons-ai-client,-opentrons-ai-server): replace fake pd gener… feat(opentrons-ai-client,-opentrons-ai-server): generate PD protocol Apr 22, 2025
@Elyorcv Elyorcv requested review from koji, shlokamin and y3rsh April 22, 2025 20:59
Copy link
Member

@y3rsh y3rsh Apr 23, 2025

Choose a reason for hiding this comment

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

Thanks for pushing this forward 🙌 A few thoughts on the current logic around determining whether the session is a Protocol Designer session or a Python Protocol session:

  • We need to make this decision logic more explicit and structured, formalizing it in the API.
  • The branching logic for "is this a Protocol Designer session?" should live outside the fast.py handler. Ideally, the handler should only:
    • Accept and validate incoming message shapes
    • Pass incoming data/requests off to dedicated processors
    • Return the data to the user

Actionable Proposals

  • Find a way to determine from the data in the API request what type of session this is instead of inferring from the history.
  • Extract the session type resolution logic out of fast.py

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@y3rsh Thanks for this awesome comments. I pushed the changes. Please have a look if I am on the right path. Thanks!

Comment on lines 210 to 217
first_message_content: Optional[str] = None
if body.history and len(body.history) > 0:
first_message = body.history[0]
# Assuming message structure is dict-like, check 'content' key
if isinstance(first_message, dict):
content_value = first_message.get("content")
if isinstance(content_value, str):
first_message_content = content_value
Copy link
Contributor

Choose a reason for hiding this comment

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

This chunk of code can be simplified in a couple ways. First off, if body.history will return True only if it is not None and it's not an empty list. Furthermore, according to the documentation I'm reading, "content" is a required field and is set to be a str, so the additional checks of types is unnecessary here. So we could have something like

first_message_content: Optional[str] = None
if body.history:
    first_message_content = body.history[0]["content"]

Now if for some reason "content" is not guaranteed, keeping it as .get("content") would be fine, as that returns None if the key doesn't exist which is the default value to begin with. And if they history objects weren't guaranteed to be dictionaries, using a try/except catching TypeError would be another one of simplyfing this.

Furthermore, if the suggestion above is causing mypy errors, sometimes we use assert in the code to silence those, but assert should only be used for internal errors and not anything user facing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did this complex only because of mypy :)

Comment on lines 219 to 222
# Determine protocol option based on content
protocol_option = "update" # Default
if first_message_content and "Write a protocol using" in first_message_content:
protocol_option = "create"
Copy link
Contributor

Choose a reason for hiding this comment

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

A couple things here. First off, if first_message_content is an empty string it will be False here, which seems to be fine in this case but just something to be aware of, as sometimes is None is the more accurate check. This can also be simplified to be a ternary statement, like
protocol_option = "create" if first_message_content and "Write a protocol using" in first_message_content else "update"

The other thing is using string values like this is a bad code smell since it's very easy for typos to sneak in. I'd either refactor this to be an Enum or a boolean if possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jbleon95 I did some changes, please have a look. Thanks!

@Elyorcv Elyorcv force-pushed the AUTH-1599-model-update-generate-different-protocol-formats-2 branch 3 times, most recently from 3d001ad to 0a9187c Compare April 25, 2025 08:32
@Elyorcv Elyorcv force-pushed the AUTH-1599-model-update-generate-different-protocol-formats-2 branch from e521085 to bdf9aba Compare April 25, 2025 20:36
@Elyorcv Elyorcv force-pushed the AUTH-1599-model-update-generate-different-protocol-formats-2 branch from bdf9aba to b512e89 Compare April 25, 2025 21:01
@Elyorcv Elyorcv force-pushed the AUTH-1599-model-update-generate-different-protocol-formats-2 branch 2 times, most recently from eb455eb to 2ce661c Compare April 28, 2025 10:31
@Elyorcv Elyorcv force-pushed the AUTH-1599-model-update-generate-different-protocol-formats-2 branch from 2ce661c to f6d080c Compare April 28, 2025 10:41
Copy link
Contributor

@jbleon95 jbleon95 left a comment

Choose a reason for hiding this comment

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

Some more minor Python nitpicks but the Python code otherwise looks better with the recent changes

user_id: str,
prompt: str,
history: Optional[List[Any]] = None,
protocol_format: Optional[ProtocolFormat] = None,
Copy link
Contributor

Choose a reason for hiding this comment

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

Some of the arguments listed as optional don't seem like they are optional where they're used in the code. Maybe I'm missing something but if they can't be None, do let that be a return type

Copy link
Contributor Author

@Elyorcv Elyorcv Apr 29, 2025

Choose a reason for hiding this comment

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

A good point.

  • This is a generic function and used in several places. For update_protocol, protocol_format is passed as None since it is not used.
  • history can also be None: used only create_protocol and update_protocol, while not used in create_chat_completion.

@Elyorcv Elyorcv merged commit cf71fec into edge May 1, 2025
39 checks passed
@Elyorcv Elyorcv deleted the AUTH-1599-model-update-generate-different-protocol-formats-2 branch May 1, 2025 20:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants