Skip to content

Commit 8e5f214

Browse files
BazookaMusicCopilot
andcommitted
Fix OpenRouter Python API and expand model coverage
Verified all prompt-injection framework models against the real Python SDK sources: - OpenRouter: the official openrouter SDK uses client.chat.send(messages=) (not chat.completions.create), client.embeddings.generate(input=) (not embeddings.create), and client.responses.send(input=, instructions=). Corrected the framework qll and model, and fixed the test files that used the wrong API. - Anthropic: added the managed-agents system prompt sink (beta.agents.create/update Argument[system:]). - Google GenAI: added models.edit_image Argument[prompt:] as user content. OpenAI, agents and LangChain models were confirmed correct against their SDK sources. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 72bc52b commit 8e5f214

10 files changed

Lines changed: 88 additions & 34 deletions

File tree

python/ql/lib/semmle/python/frameworks/OpenRouter.qll

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,10 @@ module OpenRouter {
2222
result = API::moduleImport("openrouter").getMember("OpenRouter").getReturn()
2323
}
2424

25-
/** Gets the message dictionaries passed to `chat.completions.create`. */
25+
/** Gets the message dictionaries passed to `chat.send`. */
2626
private API::Node chatMessage() {
2727
result =
28-
clientRef()
29-
.getMember("chat")
30-
.getMember("completions")
31-
.getMember("create")
32-
.getKeywordParameter("messages")
33-
.getASubscript()
28+
clientRef().getMember("chat").getMember("send").getKeywordParameter("messages").getASubscript()
3429
}
3530

3631
/** Gets the content sink of a message dictionary, including the `text` of structured content. */

python/ql/lib/semmle/python/frameworks/anthropic.model.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ extensions:
88
- ['Anthropic', 'Member[messages].Member[create,stream].Argument[system:].ListElement.DictionaryElement[text]', 'system-prompt-injection']
99
- ['Anthropic', 'Member[beta].Member[messages].Member[create,stream].Argument[system:]', 'system-prompt-injection']
1010
- ['Anthropic', 'Member[beta].Member[messages].Member[create,stream].Argument[system:].ListElement.DictionaryElement[text]', 'system-prompt-injection']
11+
# The managed agents `system` field is a system-level prompt
12+
- ['Anthropic', 'Member[beta].Member[agents].Member[create,update].Argument[system:]', 'system-prompt-injection']
1113

1214
- addsTo:
1315
pack: codeql/python-all

python/ql/lib/semmle/python/frameworks/google-genai.model.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ extensions:
77
- ['google.genai', 'Member[types].Member[GenerateContentConfig].Argument[system_instruction:]', 'system-prompt-injection']
88
# User-level content
99
- ['GoogleGenAI', 'Member[models].Member[generate_content,generate_content_stream].Argument[contents:]', 'user-prompt-injection']
10-
- ['GoogleGenAI', 'Member[models].Member[generate_images,generate_videos].Argument[prompt:]', 'user-prompt-injection']
10+
- ['GoogleGenAI', 'Member[models].Member[generate_images,generate_videos,edit_image].Argument[prompt:]', 'user-prompt-injection']
1111
- ['GoogleGenAI', 'Member[chats].Member[create].ReturnValue.Member[send_message,send_message_stream].Argument[0]', 'user-prompt-injection']
1212
- ['GoogleGenAI', 'Member[chats].Member[create].ReturnValue.Member[send_message,send_message_stream].Argument[message:]', 'user-prompt-injection']
1313

python/ql/lib/semmle/python/frameworks/openrouter.model.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ extensions:
33
pack: codeql/python-all
44
extensible: sinkModel
55
data:
6+
# `responses.send` instructions is a system-level prompt; input is user content
7+
- ['OpenRouter', 'Member[responses].Member[send].Argument[instructions:]', 'system-prompt-injection']
8+
- ['OpenRouter', 'Member[responses].Member[send].Argument[input:]', 'user-prompt-injection']
69
# Embeddings input is user-level content
7-
- ['OpenRouter', 'Member[embeddings].Member[create].Argument[input:]', 'user-prompt-injection']
10+
- ['OpenRouter', 'Member[embeddings].Member[generate].Argument[input:]', 'user-prompt-injection']
811

912
- addsTo:
1013
pack: codeql/python-all

python/ql/test/query-tests/Security/CWE-1427-SystemPromptInjection/SystemPromptInjection.expected

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,62 +7,70 @@
77
| anthropic_test.py:21:28:21:44 | ControlFlowNode for BinaryExpr | anthropic_test.py:2:26:2:32 | ControlFlowNode for ImportMember | anthropic_test.py:21:28:21:44 | ControlFlowNode for BinaryExpr | This system prompt depends on a $@. | anthropic_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value |
88
| anthropic_test.py:33:16:33:37 | ControlFlowNode for BinaryExpr | anthropic_test.py:2:26:2:32 | ControlFlowNode for ImportMember | anthropic_test.py:33:16:33:37 | ControlFlowNode for BinaryExpr | This system prompt depends on a $@. | anthropic_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value |
99
| anthropic_test.py:45:16:45:37 | ControlFlowNode for BinaryExpr | anthropic_test.py:2:26:2:32 | ControlFlowNode for ImportMember | anthropic_test.py:45:16:45:37 | ControlFlowNode for BinaryExpr | This system prompt depends on a $@. | anthropic_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value |
10+
| anthropic_test.py:57:16:57:37 | ControlFlowNode for BinaryExpr | anthropic_test.py:2:26:2:32 | ControlFlowNode for ImportMember | anthropic_test.py:57:16:57:37 | ControlFlowNode for BinaryExpr | This system prompt depends on a $@. | anthropic_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value |
11+
| anthropic_test.py:63:16:63:37 | ControlFlowNode for BinaryExpr | anthropic_test.py:2:26:2:32 | ControlFlowNode for ImportMember | anthropic_test.py:63:16:63:37 | ControlFlowNode for BinaryExpr | This system prompt depends on a $@. | anthropic_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value |
1012
| openai_test.py:17:22:17:46 | ControlFlowNode for BinaryExpr | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | openai_test.py:17:22:17:46 | ControlFlowNode for BinaryExpr | This system prompt depends on a $@. | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value |
1113
| openai_test.py:22:22:22:46 | ControlFlowNode for BinaryExpr | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | openai_test.py:22:22:22:46 | ControlFlowNode for BinaryExpr | This system prompt depends on a $@. | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value |
1214
| openai_test.py:26:28:26:51 | ControlFlowNode for BinaryExpr | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | openai_test.py:26:28:26:51 | ControlFlowNode for BinaryExpr | This system prompt depends on a $@. | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value |
1315
| openai_test.py:44:28:44:51 | ControlFlowNode for BinaryExpr | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | openai_test.py:44:28:44:51 | ControlFlowNode for BinaryExpr | This system prompt depends on a $@. | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value |
1416
| openai_test.py:61:28:61:51 | ControlFlowNode for BinaryExpr | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | openai_test.py:61:28:61:51 | ControlFlowNode for BinaryExpr | This system prompt depends on a $@. | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value |
1517
| openai_test.py:73:22:73:46 | ControlFlowNode for BinaryExpr | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | openai_test.py:73:22:73:46 | ControlFlowNode for BinaryExpr | This system prompt depends on a $@. | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value |
1618
| openrouter_test.py:18:28:18:51 | ControlFlowNode for BinaryExpr | openrouter_test.py:2:26:2:32 | ControlFlowNode for ImportMember | openrouter_test.py:18:28:18:51 | ControlFlowNode for BinaryExpr | This system prompt depends on a $@. | openrouter_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value |
19+
| openrouter_test.py:29:22:29:45 | ControlFlowNode for BinaryExpr | openrouter_test.py:2:26:2:32 | ControlFlowNode for ImportMember | openrouter_test.py:29:22:29:45 | ControlFlowNode for BinaryExpr | This system prompt depends on a $@. | openrouter_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value |
1720
edges
1821
| agent_test.py:2:26:2:32 | ControlFlowNode for ImportMember | agent_test.py:2:26:2:32 | ControlFlowNode for request | provenance | |
1922
| agent_test.py:2:26:2:32 | ControlFlowNode for request | agent_test.py:9:15:9:21 | ControlFlowNode for request | provenance | |
2023
| agent_test.py:2:26:2:32 | ControlFlowNode for request | agent_test.py:10:13:10:19 | ControlFlowNode for request | provenance | |
21-
| agent_test.py:9:5:9:11 | ControlFlowNode for persona | agent_test.py:21:22:21:63 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:6 |
22-
| agent_test.py:9:5:9:11 | ControlFlowNode for persona | agent_test.py:22:29:22:53 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:5 |
24+
| agent_test.py:9:5:9:11 | ControlFlowNode for persona | agent_test.py:21:22:21:63 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:8 |
25+
| agent_test.py:9:5:9:11 | ControlFlowNode for persona | agent_test.py:22:29:22:53 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:7 |
2326
| agent_test.py:9:5:9:11 | ControlFlowNode for persona | agent_test.py:31:28:31:51 | ControlFlowNode for BinaryExpr | provenance | |
2427
| agent_test.py:9:15:9:21 | ControlFlowNode for request | agent_test.py:9:15:9:26 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep |
2528
| agent_test.py:9:15:9:21 | ControlFlowNode for request | agent_test.py:10:13:10:24 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep |
2629
| agent_test.py:9:15:9:26 | ControlFlowNode for Attribute | agent_test.py:9:15:9:41 | ControlFlowNode for Attribute() | provenance | dict.get |
2730
| agent_test.py:9:15:9:41 | ControlFlowNode for Attribute() | agent_test.py:9:5:9:11 | ControlFlowNode for persona | provenance | |
28-
| agent_test.py:10:5:10:9 | ControlFlowNode for topic | agent_test.py:14:21:14:63 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:7 |
31+
| agent_test.py:10:5:10:9 | ControlFlowNode for topic | agent_test.py:14:21:14:63 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:9 |
2932
| agent_test.py:10:13:10:19 | ControlFlowNode for request | agent_test.py:10:13:10:24 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep |
3033
| agent_test.py:10:13:10:24 | ControlFlowNode for Attribute | agent_test.py:10:13:10:37 | ControlFlowNode for Attribute() | provenance | dict.get |
3134
| agent_test.py:10:13:10:37 | ControlFlowNode for Attribute() | agent_test.py:10:5:10:9 | ControlFlowNode for topic | provenance | |
3235
| anthropic_test.py:2:26:2:32 | ControlFlowNode for ImportMember | anthropic_test.py:2:26:2:32 | ControlFlowNode for request | provenance | |
3336
| anthropic_test.py:2:26:2:32 | ControlFlowNode for request | anthropic_test.py:11:15:11:21 | ControlFlowNode for request | provenance | |
34-
| anthropic_test.py:11:5:11:11 | ControlFlowNode for persona | anthropic_test.py:17:16:17:37 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:2 |
37+
| anthropic_test.py:11:5:11:11 | ControlFlowNode for persona | anthropic_test.py:17:16:17:37 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:3 |
3538
| anthropic_test.py:11:5:11:11 | ControlFlowNode for persona | anthropic_test.py:21:28:21:44 | ControlFlowNode for BinaryExpr | provenance | |
36-
| anthropic_test.py:11:5:11:11 | ControlFlowNode for persona | anthropic_test.py:33:16:33:37 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:2 |
37-
| anthropic_test.py:11:5:11:11 | ControlFlowNode for persona | anthropic_test.py:45:16:45:37 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:1 |
39+
| anthropic_test.py:11:5:11:11 | ControlFlowNode for persona | anthropic_test.py:33:16:33:37 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:3 |
40+
| anthropic_test.py:11:5:11:11 | ControlFlowNode for persona | anthropic_test.py:45:16:45:37 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:2 |
41+
| anthropic_test.py:11:5:11:11 | ControlFlowNode for persona | anthropic_test.py:57:16:57:37 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:1 |
42+
| anthropic_test.py:11:5:11:11 | ControlFlowNode for persona | anthropic_test.py:63:16:63:37 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:1 |
3843
| anthropic_test.py:11:15:11:21 | ControlFlowNode for request | anthropic_test.py:11:15:11:26 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep |
3944
| anthropic_test.py:11:15:11:26 | ControlFlowNode for Attribute | anthropic_test.py:11:15:11:41 | ControlFlowNode for Attribute() | provenance | dict.get |
4045
| anthropic_test.py:11:15:11:41 | ControlFlowNode for Attribute() | anthropic_test.py:11:5:11:11 | ControlFlowNode for persona | provenance | |
4146
| openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | openai_test.py:2:26:2:32 | ControlFlowNode for request | provenance | |
4247
| openai_test.py:2:26:2:32 | ControlFlowNode for request | openai_test.py:12:15:12:21 | ControlFlowNode for request | provenance | |
43-
| openai_test.py:12:5:12:11 | ControlFlowNode for persona | openai_test.py:17:22:17:46 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:4 |
44-
| openai_test.py:12:5:12:11 | ControlFlowNode for persona | openai_test.py:22:22:22:46 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:4 |
48+
| openai_test.py:12:5:12:11 | ControlFlowNode for persona | openai_test.py:17:22:17:46 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:5 |
49+
| openai_test.py:12:5:12:11 | ControlFlowNode for persona | openai_test.py:22:22:22:46 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:5 |
4550
| openai_test.py:12:5:12:11 | ControlFlowNode for persona | openai_test.py:26:28:26:51 | ControlFlowNode for BinaryExpr | provenance | |
4651
| openai_test.py:12:5:12:11 | ControlFlowNode for persona | openai_test.py:44:28:44:51 | ControlFlowNode for BinaryExpr | provenance | |
4752
| openai_test.py:12:5:12:11 | ControlFlowNode for persona | openai_test.py:61:28:61:51 | ControlFlowNode for BinaryExpr | provenance | |
48-
| openai_test.py:12:5:12:11 | ControlFlowNode for persona | openai_test.py:73:22:73:46 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:3 |
53+
| openai_test.py:12:5:12:11 | ControlFlowNode for persona | openai_test.py:73:22:73:46 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:4 |
4954
| openai_test.py:12:15:12:21 | ControlFlowNode for request | openai_test.py:12:15:12:26 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep |
5055
| openai_test.py:12:15:12:26 | ControlFlowNode for Attribute | openai_test.py:12:15:12:41 | ControlFlowNode for Attribute() | provenance | dict.get |
5156
| openai_test.py:12:15:12:41 | ControlFlowNode for Attribute() | openai_test.py:12:5:12:11 | ControlFlowNode for persona | provenance | |
5257
| openrouter_test.py:2:26:2:32 | ControlFlowNode for ImportMember | openrouter_test.py:2:26:2:32 | ControlFlowNode for request | provenance | |
5358
| openrouter_test.py:2:26:2:32 | ControlFlowNode for request | openrouter_test.py:10:15:10:21 | ControlFlowNode for request | provenance | |
5459
| openrouter_test.py:10:5:10:11 | ControlFlowNode for persona | openrouter_test.py:18:28:18:51 | ControlFlowNode for BinaryExpr | provenance | |
60+
| openrouter_test.py:10:5:10:11 | ControlFlowNode for persona | openrouter_test.py:29:22:29:45 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:6 |
5561
| openrouter_test.py:10:15:10:21 | ControlFlowNode for request | openrouter_test.py:10:15:10:26 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep |
5662
| openrouter_test.py:10:15:10:26 | ControlFlowNode for Attribute | openrouter_test.py:10:15:10:41 | ControlFlowNode for Attribute() | provenance | dict.get |
5763
| openrouter_test.py:10:15:10:41 | ControlFlowNode for Attribute() | openrouter_test.py:10:5:10:11 | ControlFlowNode for persona | provenance | |
5864
models
59-
| 1 | Sink: Anthropic; Member[beta].Member[messages].Member[create,stream].Argument[system:]; system-prompt-injection |
60-
| 2 | Sink: Anthropic; Member[messages].Member[create,stream].Argument[system:]; system-prompt-injection |
61-
| 3 | Sink: OpenAI; Member[beta].Member[assistants].Member[create].Argument[instructions:]; system-prompt-injection |
62-
| 4 | Sink: OpenAI; Member[responses].Member[create].Argument[instructions:]; system-prompt-injection |
63-
| 5 | Sink: agents; Member[Agent].Argument[handoff_description:]; system-prompt-injection |
64-
| 6 | Sink: agents; Member[Agent].Argument[instructions:]; system-prompt-injection |
65-
| 7 | Sink: agents; Member[FunctionTool].Argument[description:]; system-prompt-injection |
65+
| 1 | Sink: Anthropic; Member[beta].Member[agents].Member[create,update].Argument[system:]; system-prompt-injection |
66+
| 2 | Sink: Anthropic; Member[beta].Member[messages].Member[create,stream].Argument[system:]; system-prompt-injection |
67+
| 3 | Sink: Anthropic; Member[messages].Member[create,stream].Argument[system:]; system-prompt-injection |
68+
| 4 | Sink: OpenAI; Member[beta].Member[assistants].Member[create].Argument[instructions:]; system-prompt-injection |
69+
| 5 | Sink: OpenAI; Member[responses].Member[create].Argument[instructions:]; system-prompt-injection |
70+
| 6 | Sink: OpenRouter; Member[responses].Member[send].Argument[instructions:]; system-prompt-injection |
71+
| 7 | Sink: agents; Member[Agent].Argument[handoff_description:]; system-prompt-injection |
72+
| 8 | Sink: agents; Member[Agent].Argument[instructions:]; system-prompt-injection |
73+
| 9 | Sink: agents; Member[FunctionTool].Argument[description:]; system-prompt-injection |
6674
nodes
6775
| agent_test.py:2:26:2:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember |
6876
| agent_test.py:2:26:2:32 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
@@ -88,6 +96,8 @@ nodes
8896
| anthropic_test.py:21:28:21:44 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
8997
| anthropic_test.py:33:16:33:37 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
9098
| anthropic_test.py:45:16:45:37 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
99+
| anthropic_test.py:57:16:57:37 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
100+
| anthropic_test.py:63:16:63:37 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
91101
| openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember |
92102
| openai_test.py:2:26:2:32 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
93103
| openai_test.py:12:5:12:11 | ControlFlowNode for persona | semmle.label | ControlFlowNode for persona |
@@ -107,6 +117,7 @@ nodes
107117
| openrouter_test.py:10:15:10:26 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
108118
| openrouter_test.py:10:15:10:41 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
109119
| openrouter_test.py:18:28:18:51 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
120+
| openrouter_test.py:29:22:29:45 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
110121
subpaths
111122
testFailures
112123
| gemini_test.py:3:35:3:44 | Comment # $ Source | Missing result: Source |

python/ql/test/query-tests/Security/CWE-1427-SystemPromptInjection/anthropic_test.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,16 @@ async def get_input_anthropic():
5151
],
5252
)
5353

54+
agent = client.beta.agents.create(
55+
model="claude-sonnet-4-20250514",
56+
name="assistant",
57+
system="Talk like " + persona, # $ Alert[py/system-prompt-injection]
58+
)
59+
60+
client.beta.agents.update(
61+
agent_id=agent.id,
62+
version=1,
63+
system="Talk like " + persona, # $ Alert[py/system-prompt-injection]
64+
)
65+
5466
print(response1, response2, response3)

python/ql/test/query-tests/Security/CWE-1427-SystemPromptInjection/openrouter_test.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def get_input_openrouter():
1010
persona = request.args.get("persona")
1111
query = request.args.get("query")
1212

13-
completion = client.chat.completions.create(
13+
completion = client.chat.send(
1414
model="openai/gpt-4.1",
1515
messages=[
1616
{
@@ -23,4 +23,10 @@ def get_input_openrouter():
2323
}
2424
]
2525
)
26-
print(completion)
26+
27+
response = client.responses.send(
28+
model="openai/gpt-4.1",
29+
instructions="Talk like a " + persona, # $ Alert[py/system-prompt-injection]
30+
input=query,
31+
)
32+
print(completion, response)

0 commit comments

Comments
 (0)