Skip to content

Commit ffbabca

Browse files
committed
Allow invoking durable activities
1 parent e54397f commit ffbabca

File tree

3 files changed

+64
-9
lines changed

3 files changed

+64
-9
lines changed

samples-v2/openai_agents/durable_ai_agent_context.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ def get_activity_call_result(self, activity_name, input: str):
2525
result_json = completed_tasks[self.activities_called - 1].Result
2626
result = json.loads(result_json)
2727
return result
28+
29+
def call_activity_yieldable(self, activity_name, input: str):
30+
task = self.context.call_activity(activity_name, input)
31+
self.activities_called += 1
32+
return task
2833

2934
def yield_and_clear_tasks(self):
3035
"""Yield all accumulated tasks and clear the tasks list."""

samples-v2/openai_agents/durable_decorators.py

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from functools import wraps
2+
import inspect
23
from agents.run import set_default_agent_runner
34
from azure.durable_functions.models.DurableOrchestrationContext import DurableOrchestrationContext
45
from durable_openai_runner import DurableOpenAIRunner
@@ -15,13 +16,47 @@ def wrapper(durable_orchestration_context: DurableOrchestrationContext):
1516
durable_openai_runner = DurableOpenAIRunner(context=durable_ai_agent_context)
1617
set_default_agent_runner(durable_openai_runner)
1718

18-
try:
19-
result = func(durable_ai_agent_context)
20-
return result
21-
except YieldException as e:
22-
yield from durable_ai_agent_context.yield_and_clear_tasks()
23-
yield e.task
24-
finally:
25-
yield from durable_ai_agent_context.yield_and_clear_tasks()
19+
if inspect.isgeneratorfunction(func):
20+
gen = iter(func(durable_ai_agent_context))
21+
try:
22+
# prime the subiterator
23+
value = next(gen)
24+
yield from durable_ai_agent_context.yield_and_clear_tasks()
25+
while True:
26+
try:
27+
# send whatever was sent into us down to the subgenerator
28+
sent = yield value
29+
except GeneratorExit:
30+
# ensure the subgenerator is closed
31+
if hasattr(gen, "close"):
32+
gen.close()
33+
raise
34+
except BaseException as exc:
35+
# forward thrown exceptions if possible
36+
if hasattr(gen, "throw"):
37+
value = gen.throw(type(exc), exc, exc.__traceback__)
38+
else:
39+
raise
40+
else:
41+
# normal path: forward .send (or .__next__)
42+
if hasattr(gen, "send"):
43+
value = gen.send(sent)
44+
else:
45+
value = next(gen)
46+
except StopIteration as e:
47+
yield from durable_ai_agent_context.yield_and_clear_tasks()
48+
return e.value
49+
except YieldException as e:
50+
yield from durable_ai_agent_context.yield_and_clear_tasks()
51+
yield e.task
52+
else:
53+
try:
54+
result = func(durable_ai_agent_context)
55+
return result
56+
except YieldException as e:
57+
yield from durable_ai_agent_context.yield_and_clear_tasks()
58+
yield e.task
59+
finally:
60+
yield from durable_ai_agent_context.yield_and_clear_tasks()
2661

2762
return wrapper

samples-v2/openai_agents/function_app.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@
1010
create_invoke_model_activity(app) # TODO: Can we hide this line?
1111

1212

13+
@app.activity_trigger(input_name="name")
14+
async def hello(name: str):
15+
"""A simple durable activity that returns a greeting message."""
16+
return f"Hello {name}!"
17+
18+
1319
@app.route(route="orchestrators/{functionName}")
1420
@app.durable_client_input(client_name="client")
1521
async def orchestration_starter(req: func.HttpRequest, client):
@@ -47,12 +53,21 @@ def haiku_judge(context):
4753

4854
haiku = Runner.run_sync(writer, "Tell me about recursion in programming.")
4955

56+
response = yield context.call_activity_yieldable("hello", "World")
57+
5058
judge = Agent(
5159
name="Judge",
5260
instructions="You judge haikus.",
5361
)
5462

5563
evaluation = Runner.run_sync(judge, f"Is this a good haiku? {haiku.final_output}")
5664

57-
return [haiku.final_output, "\n\n" + evaluation.final_output]
65+
return [haiku.final_output, "\n\n" + evaluation.final_output, response]
5866

67+
68+
@app.orchestration_trigger(context_name="context")
69+
@durable_openai_agent_orchestrator
70+
def hello_cities(context):
71+
task = context.call_activity_yieldable("hello", "Seattle")
72+
result = yield task
73+
return result

0 commit comments

Comments
 (0)