fred-runtime 2.0.2__tar.gz → 2.0.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/PKG-INFO +1 -1
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/app/agent_app.py +7 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/graph/graph_runtime.py +10 -2
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/react/react_runtime.py +33 -13
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime.egg-info/PKG-INFO +1 -1
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/pyproject.toml +1 -1
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/README.md +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/__init__.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/app/__init__.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/app/_catalogs.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/app/config.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/app/config_loader.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/app/container.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/app/context.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/app/dependencies.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/app/mcp_config.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/app/observability_factory.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/app/openai_compat_router.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/cli/__init__.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/cli/completion.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/cli/entrypoint.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/cli/history_display.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/cli/kpi_display.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/cli/pod_client.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/cli/repl.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/cli/repl_helpers.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/cli/url_helpers.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/client.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/common/__init__.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/common/context_aware_tool.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/common/kf_base_client.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/common/kf_fast_text_client.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/common/kf_http_client.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/common/kf_logs_client.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/common/kf_markdown_media_client.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/common/kf_vectorsearch_client.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/common/kf_workspace_client.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/common/mcp_interceptors.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/common/mcp_runtime.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/common/mcp_toolkit.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/common/mcp_utils.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/common/structures.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/common/token_expiry.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/common/tool_node_utils.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/deep/__init__.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/deep/deep_runtime.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/eval/__init__.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/eval/collector.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/graph/__init__.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/integrations/__init__.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/integrations/v2_runtime/__init__.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/integrations/v2_runtime/adapters.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/model_routing/__init__.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/model_routing/catalog.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/model_routing/contracts.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/model_routing/provider.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/model_routing/resolver.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/react/__init__.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/react/react_langchain_adapter.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/react/react_message_codec.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/react/react_model_adapter.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/react/react_prompting.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/react/react_stream_adapter.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/react/react_tool_binding.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/react/react_tool_loop.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/react/react_tool_rendering.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/react/react_tool_resolution.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/react/react_tool_utils.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/react/react_tracing.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/runtime_context.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/runtime_support/__init__.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/runtime_support/checkpoints.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/runtime_support/model_metadata.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/runtime_support/request_context_helpers.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/runtime_support/sql_checkpointer.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/runtime_support/user_token_refresher.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/support/__init__.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/support/filesystem_context.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/support/tool_approval.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/support/tool_loop.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime.egg-info/SOURCES.txt +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime.egg-info/dependency_links.txt +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime.egg-info/entry_points.txt +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime.egg-info/requires.txt +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime.egg-info/top_level.txt +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/setup.cfg +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/tests/test_agent_app.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/tests/test_client.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/tests/test_config_loader.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/tests/test_context.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/tests/test_eval_trace.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/tests/test_graph_runtime_observability.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/tests/test_history.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/tests/test_kf_workspace_client.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/tests/test_kpi_display.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/tests/test_mcp_config.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/tests/test_openai_compat_router.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/tests/test_smoke.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/tests/test_url_helpers.py +0 -0
- {fred_runtime-2.0.2 → fred_runtime-2.0.3}/tests/test_user_token_refresher.py +0 -0
|
@@ -67,6 +67,7 @@ from fred_sdk.contracts.context import (
|
|
|
67
67
|
AgentInvocationRequest,
|
|
68
68
|
AgentInvocationResult,
|
|
69
69
|
BoundRuntimeContext,
|
|
70
|
+
ConversationTurn,
|
|
70
71
|
PortableContext,
|
|
71
72
|
PortableEnvironment,
|
|
72
73
|
RuntimeContext,
|
|
@@ -567,6 +568,7 @@ class LocalRegistryAgentInvoker(AgentInvokerPort):
|
|
|
567
568
|
message=request.message,
|
|
568
569
|
context=context_dict,
|
|
569
570
|
resume_payload=None,
|
|
571
|
+
invocation_turns=request.prior_turns,
|
|
570
572
|
)
|
|
571
573
|
|
|
572
574
|
content_parts: list[str] = []
|
|
@@ -748,6 +750,10 @@ class _AgentExecuteRequest(BaseModel):
|
|
|
748
750
|
"LangGraph Command(resume=...) — the message field is ignored."
|
|
749
751
|
),
|
|
750
752
|
)
|
|
753
|
+
invocation_turns: tuple[ConversationTurn, ...] = Field(
|
|
754
|
+
default=(),
|
|
755
|
+
description="Prior conversation turns forwarded by the calling agent.",
|
|
756
|
+
)
|
|
751
757
|
|
|
752
758
|
@model_validator(mode="after")
|
|
753
759
|
def _require_message_or_resume(self) -> "_AgentExecuteRequest":
|
|
@@ -1783,6 +1789,7 @@ async def _iterate_runtime_event_payloads(
|
|
|
1783
1789
|
session_id=ctx.get("session_id") or request_id,
|
|
1784
1790
|
checkpoint_id=request.checkpoint_id,
|
|
1785
1791
|
resume_payload=request.resume_payload,
|
|
1792
|
+
invocation_turns=getattr(request, "invocation_turns", ()),
|
|
1786
1793
|
)
|
|
1787
1794
|
|
|
1788
1795
|
try:
|
|
@@ -37,6 +37,7 @@ from fred_sdk.contracts.context import (
|
|
|
37
37
|
ArtifactPublishRequest,
|
|
38
38
|
ArtifactScope,
|
|
39
39
|
BoundRuntimeContext,
|
|
40
|
+
ConversationTurn,
|
|
40
41
|
FetchedResource,
|
|
41
42
|
PublishedArtifact,
|
|
42
43
|
ResourceFetchRequest,
|
|
@@ -549,6 +550,8 @@ class _GraphNodeExecutionContext:
|
|
|
549
550
|
self,
|
|
550
551
|
agent_id: str,
|
|
551
552
|
message: str,
|
|
553
|
+
*,
|
|
554
|
+
prior_turns: tuple[ConversationTurn, ...] = (),
|
|
552
555
|
) -> AgentInvocationResult:
|
|
553
556
|
agent_invoker = self.services.agent_invoker
|
|
554
557
|
if agent_invoker is None:
|
|
@@ -587,6 +590,7 @@ class _GraphNodeExecutionContext:
|
|
|
587
590
|
agent_id=agent_id,
|
|
588
591
|
message=message,
|
|
589
592
|
context=self.binding.portable_context,
|
|
593
|
+
prior_turns=prior_turns,
|
|
590
594
|
)
|
|
591
595
|
)
|
|
592
596
|
if result.is_error:
|
|
@@ -1119,13 +1123,14 @@ class _DeterministicGraphExecutor(Executor[BaseModel, BaseModel]):
|
|
|
1119
1123
|
resume_payload = None
|
|
1120
1124
|
|
|
1121
1125
|
self._pending_checkpoints.pop(checkpoint_key, None)
|
|
1126
|
+
completed_state = self._definition.build_completed_state(state)
|
|
1122
1127
|
await self._store_completed_state(
|
|
1123
1128
|
checkpoint_key=checkpoint_key,
|
|
1124
1129
|
config=config,
|
|
1125
|
-
state=
|
|
1130
|
+
state=completed_state,
|
|
1126
1131
|
)
|
|
1127
1132
|
output_model = self._definition.output_model().model_validate(
|
|
1128
|
-
self._definition.build_output(
|
|
1133
|
+
self._definition.build_output(completed_state)
|
|
1129
1134
|
)
|
|
1130
1135
|
if emit_event is not None:
|
|
1131
1136
|
emit_event(
|
|
@@ -1278,10 +1283,13 @@ class _DeterministicGraphExecutor(Executor[BaseModel, BaseModel]):
|
|
|
1278
1283
|
# The runtime persists the last completed state for the conversation.
|
|
1279
1284
|
# The agent decides whether that prior state should influence the new
|
|
1280
1285
|
# turn, for example by remembering a parcel, case, or selected asset.
|
|
1286
|
+
# When invoked by another agent, invocation_turns seeds cross-turn
|
|
1287
|
+
# context on the first call (previous_state takes priority when it exists).
|
|
1281
1288
|
initial_state = self._definition.build_turn_state(
|
|
1282
1289
|
input_model,
|
|
1283
1290
|
self._binding,
|
|
1284
1291
|
previous_state=previous_state,
|
|
1292
|
+
invocation_turns=config.invocation_turns,
|
|
1285
1293
|
)
|
|
1286
1294
|
state = self._definition.state_model().model_validate(initial_state)
|
|
1287
1295
|
return state, self._graph.entry_node, None
|
|
@@ -50,6 +50,7 @@ from langgraph.types import Checkpointer
|
|
|
50
50
|
|
|
51
51
|
from fred_sdk.contracts.context import (
|
|
52
52
|
BoundRuntimeContext,
|
|
53
|
+
ConversationTurn,
|
|
53
54
|
UiPart,
|
|
54
55
|
)
|
|
55
56
|
from fred_sdk.contracts.models import ReActAgentDefinition, ToolApprovalPolicy
|
|
@@ -162,6 +163,17 @@ __all__ = [
|
|
|
162
163
|
]
|
|
163
164
|
|
|
164
165
|
|
|
166
|
+
def _format_invocation_turns(turns: tuple[ConversationTurn, ...]) -> str:
|
|
167
|
+
"""Render caller-provided prior turns into a compact context block."""
|
|
168
|
+
parts = []
|
|
169
|
+
for turn in turns:
|
|
170
|
+
speaker = f" ({turn.agent_name})" if turn.agent_name else ""
|
|
171
|
+
parts.append(
|
|
172
|
+
f"User: {turn.user_message}\nAssistant{speaker}: {turn.agent_response}"
|
|
173
|
+
)
|
|
174
|
+
return "\n\n".join(parts)
|
|
175
|
+
|
|
176
|
+
|
|
165
177
|
def _graph_input(
|
|
166
178
|
input_model: ReActInput,
|
|
167
179
|
config: ExecutionConfig,
|
|
@@ -169,26 +181,34 @@ def _graph_input(
|
|
|
169
181
|
"""
|
|
170
182
|
Convert Fred ReAct input to the compiled-agent graph input shape.
|
|
171
183
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
How to use:
|
|
179
|
-
- pass the validated `ReActInput` plus `ExecutionConfig` before invoking the
|
|
180
|
-
compiled agent
|
|
181
|
-
|
|
182
|
-
Example:
|
|
183
|
-
- `_graph_input(input_model, ExecutionConfig())`
|
|
184
|
+
When ``config.invocation_turns`` is non-empty (the agent is being called
|
|
185
|
+
from a team leader), a system message carrying the prior conversation
|
|
186
|
+
context is injected as the first message in the thread so the model
|
|
187
|
+
understands the follow-up without requiring the user to repeat themselves.
|
|
188
|
+
The baked-in system prompt (applied by LangGraph's state_modifier) is
|
|
189
|
+
separate and unaffected.
|
|
184
190
|
"""
|
|
185
191
|
|
|
186
|
-
|
|
192
|
+
base = _graph_input_adapter(
|
|
187
193
|
input_model,
|
|
188
194
|
config,
|
|
189
195
|
sanitize_tool_name=_sanitize_tool_name,
|
|
190
196
|
)
|
|
191
197
|
|
|
198
|
+
if not config.invocation_turns or config.resume_payload is not None:
|
|
199
|
+
return base
|
|
200
|
+
|
|
201
|
+
from langchain_core.messages import SystemMessage
|
|
202
|
+
|
|
203
|
+
context_block = (
|
|
204
|
+
"[Conversation context from calling agent]\n"
|
|
205
|
+
+ _format_invocation_turns(config.invocation_turns)
|
|
206
|
+
)
|
|
207
|
+
if isinstance(base, dict) and isinstance(base.get("messages"), list):
|
|
208
|
+
existing: list[object] = base["messages"] # type: ignore[assignment]
|
|
209
|
+
return {"messages": [SystemMessage(content=context_block), *existing]}
|
|
210
|
+
return base
|
|
211
|
+
|
|
192
212
|
|
|
193
213
|
class _TransportBackedReActExecutor(Executor[ReActInput, ReActOutput]):
|
|
194
214
|
"""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/runtime_support/request_context_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
{fred_runtime-2.0.2 → fred_runtime-2.0.3}/fred_runtime/runtime_support/user_token_refresher.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|