Skip to content

Conversation

@tuliocoppola
Copy link
Contributor

@tuliocoppola tuliocoppola commented Aug 28, 2025

This PR was discussed/showed to @nrfulton.

It introduces the concept of prompt_modules under the helpers, which are completely isolated modules, with a common interface, that can be composed into any kind of pipeline.
These modules are the blocks supporting the Decomposition Pipeline implemented under the CLI tools.

It's a lot of code, but all the introduced files are isolated under the new directory @ mellea/helpers/prompt_modules, and none of them interfere with any other part of the code base.

There's also modifications to the cli/decompose.

Usage example for one of the prompt_modules:

from mellea import MelleaSession
from mellea.backends.ollama import OllamaModelBackend

from mellea.helpers.prompt_modules import constraint_extractor

m_session = MelleaSession(
    OllamaModelBackend(
        model_id="mistral-small3.2:24b",
        model_options={
            ModelOption.CONTEXT_WINDOW: 32768,
            "timeout": 3600,
        },
    )
)

task_prompt: str = <task prompt example below this code block>

task_prompt_constraints: list[str] = constraint_extractor.generate(
    m_session, task_prompt
).parse()

print(task_prompt_constraints)

# e.g.
# [
#     "The entire text can't exceed 600 characters",
#     "The summary must be a maximum of 3 paragraphs",
#     "A specific celebrity name must be incorporated into the summary",
#     "The output must be in a JSON format with \"title\" and \"summary\" keys",
#     "The JSON output must not have any Markdown formatting"
# ]

Now an example of the Decomposition CLI Tool usage:

The example task prompt below is a short prompt, this tool can be used (and was meant) to break larger prompts, but it does work sufficiently well with short prompts also.

For this prompt text file:

my-task-prompt.txt

Summarize a news article into a text with a maximum of 3 paragraphs. The entire text can't exceed 600 characters.

You must also incorporate a specific celebrity name into your summary, the name will be provided per task.

I need you to output it in a JSON like this, but without any Markdown formatting, just the JSON (not enclosed in back quotes):
```
{
  "title": <come up with a good title>,
  "summary": <your summary>
}
```

The Decomposition CLI Tool supports task prompts that doesn't need any user input data, but also support the ones that need.

Note that the example task prompt above needs 2 user input variables to execute its task, it does not explicitly dictates the input variables names.

On the CLI command you must pass a descriptive name for each necessary user input variable, in this example we will call our variables NEWS_ARTICLE and CELEBRITY_NAME, but we could've just as well called them INPUT_ARTICLE and CELEBRITY_DATA, as you can see, the idea is to pass descriptive names for the LLM to correctly infer and reference the input data when generating the subtasks templates.

If your task prompt doesn't need user input data, then you can just omit the --input-var options.

All of this information is also contained on the CLI command help string.

Usage example of the new Decomposition Pipeline CLI Tool:

m decompose run \
--out-dir . \
--prompt-file path/to/text/file/my-task-prompt.txt \
--out-name output_files_name \ # Generates a "output_files_name.json" and a "output_files_name.py".
--input-var NEWS_ARTICLE \
--input-var CELEBRITY_NAME

@nrfulton
Copy link
Contributor

@HendrikStrobelt This is Tulio's new prompt decomposition pipeline.

You do not need to review the full PR -- it's a lot of code, and Tulio gave me a high-level overview. But do please chime in on where this code should live. A few options:

  1. mellea.helpers.dprompt_modules <- current
  2. mellea.prompt_modules <- probably not, right?
  3. cli.decompose.prompt_modules <- also reasonable

@nrfulton
Copy link
Contributor

The failed test seems like a false negative. @tuliocoppola can you run the python 3.12 tests locally and confirm they pass there?

@tuliocoppola
Copy link
Contributor Author

The failed test seems like a false negative. @tuliocoppola can you run the python 3.12 tests locally and confirm they pass there?

@nrfulton
Does look like a false negative, on my fork all tests passed -> https://github.com/tuliocoppola/mellea/actions/runs/17297553591/job/49099508067

@nrfulton
Copy link
Contributor

@tuliocoppola Overall LGTM. Can you move the code to mellea.helpers.prompt_modules.decompose so that folks aren't confused about what prompt_modules means / understand that this is all related to the decomposition pipeline?

Once that's done we can squash and merge.

@tuliocoppola
Copy link
Contributor Author

@nrfulton
Done, moved the modules.

@jakelorocco
Copy link
Contributor

@tuliocoppola, this looks good; can you please move mellea/helpers/prompt_modules/ directly into the cli decompose folder? My reasoning is that most of these helpers are specific to decompose and there are examples, etc... in there.

@mergify
Copy link

mergify bot commented Sep 3, 2025

Merge Protections

Your pull request matches the following merge protections and will not be merged until they are valid.

🟢 Enforce conventional commit

Wonderful, this rule succeeded.

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|docs|style|refactor|perf|test|build|ci|chore|revert)(?:\(.+\))?:

@nrfulton
Copy link
Contributor

nrfulton commented Sep 4, 2025

@tuliocoppola, this looks good; can you please move mellea/helpers/prompt_modules/ directly into the cli decompose folder? My reasoning is that most of these helpers are specific to decompose and there are examples, etc... in there.

And sorry for the back-and-forth here... my fault, and this is really the last move request.

@nrfulton nrfulton changed the title Full refactor of the Decompose CLI Tool & introduction of prompt_modules refactor: Full refactor of the Decompose CLI Tool & introduction of prompt_modules Sep 4, 2025
Signed-off-by: Tulio Coppola <tulio.cppl@icloud.com>
Signed-off-by: Tulio Coppola <tulio.cppl@icloud.com>
@tuliocoppola
Copy link
Contributor Author

@jakelorocco & @nrfulton
Done. Should be ready for merging now.

Copy link
Contributor

@jakelorocco jakelorocco left a comment

Choose a reason for hiding this comment

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

lgtm (except for the one thing noted below @tuliocoppola); we chatted and agree that longterm, we will work on porting this code to be more melleaic; for now, keeping it in the cli directory should be good

I was able to run the command, so it looks good

model_id=model_id,
model_options={
ModelOption.CONTEXT_WINDOW: 32768,
"timeout": backend_req_timeout,
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's fine to leave this in for now, but I believe ollama actually sets this as an environment variable. Error from my ollama logs:

time=2025-09-04T15:16:14.510-04:00 level=WARN source=types.go:654 msg="invalid option provided" option=timeout

Copy link
Contributor Author

@tuliocoppola tuliocoppola Sep 4, 2025

Choose a reason for hiding this comment

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

@jakelorocco
There's an argument when spinning up the client locally with ollama where you can define the request timeout for that client:
https://github.com/ollama/ollama-python/blob/main/ollama/_client.py#L81

So this option would need to be mapped on these lines I guess:
https://github.com/generative-computing/mellea/blob/main/mellea/backends/ollama.py#L67-L68

We can open an issue for this to be implemented later.
I guess that, for now, I can comment that timeout and add a TODO comment to re-enable it when it's supported by the backend class. Since this will probably have to be made available through the special ModelOption thing.

Comment on lines +82 to +98
case DecompBackend.rits:
assert backend_endpoint is not None, (
'Required to provide "backend_endpoint" for this configuration'
)
assert backend_api_key is not None, (
'Required to provide "backend_api_key" for this configuration'
)

from mellea_ibm.rits import RITSBackend, RITSModelIdentifier # type: ignore

m_session = MelleaSession(
RITSBackend(
RITSModelIdentifier(endpoint=backend_endpoint, model_name=model_id),
api_key=backend_api_key,
model_options={"timeout": backend_req_timeout},
)
)
Copy link
Contributor

Choose a reason for hiding this comment

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

We should also remove this and somehow add it through our internal library. We don't want to expose this.

Copy link
Contributor

Choose a reason for hiding this comment

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

@tuliocoppola, sorry should've spotted this earlier; last change request!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jakelorocco
I've actually went through this specific matter with @nrfulton, we basically agreed that there's no harm, the service name is not a trade secret or anything, and there's no implementation code exposed, it's just 2 class names.

I'm not sure how we could make this work easily if not like that, and we do need to support this backend asap for the decomposition pipeline.

One thing that might be good is to omit the "rits" option from the CLI's "--backend", and trigger it by providing an in-line environment variable like this:
BACKEND_OVERRIDE=rits m decompose run ...

Just for people to not mistakenly try to use it when looking at the possible values on the CLI's help strings.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If you know an easy way for making this work through the internal library, then we can do it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh okay; if it's already been addressed, I'm fine with it as is. I agree that it's not exposing implementation details here.

@jakelorocco jakelorocco merged commit 5116b21 into generative-computing:main Sep 4, 2025
2 of 4 checks passed
yelkurdi pushed a commit to yelkurdi/mellea_tbf that referenced this pull request Sep 7, 2025
…rompt_modules (generative-computing#105)

* Implements "prompt_modules" and complete refactor of the "decompose" feature

* typo: missing period

* minor fix: changed the "NotRequired" import

* fix: minor fixes

* moves prompt_modules to utils

* moves decompose modules to appropriate path

* refactor: moves prompt_modules to cli scope

Signed-off-by: Tulio Coppola <tulio.cppl@icloud.com>

* adds README.md to write later

Signed-off-by: Tulio Coppola <tulio.cppl@icloud.com>

---------

Signed-off-by: Tulio Coppola <tulio.cppl@icloud.com>
Co-authored-by: Tulio Coppola <tuliocoppola@ibm.com>
Co-authored-by: Nathan Fulton <nathan@ibm.com>
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.

3 participants