Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,8 @@ edit both products' core copies, that is evidence it belongs here.
bus/fan-in orchestration, resource management, task budgets, and the
backend-injected DAG scheduler. Product tool assembly, persistence backends,
and workflow policy remain downstream.
9. **Provider substrate** (next): converge the shared provider transports,
fallback engine, prompt cache, usage metering, and non-blocking streaming
9. **Provider substrate** (complete in AgentCore): shared provider transports,
fallback engine, prompt cache, usage metadata normalization, and non-blocking streaming
behind product configuration and session-affinity adapters.
10. Remove product compatibility facades after downstream imports have moved to
`agent_core`.
Expand Down
15 changes: 15 additions & 0 deletions agent_core/llm.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,21 @@ class StreamDelta:
# consumer read an empty vendor, which split one model's usage across
# a ``provider=""`` bucket and a named bucket.
provider: str = ""
# VERBATIM provider content blocks for the assembled turn, carried only by
# providers whose replay contract needs the structured block list rather
# than flattened text — currently Anthropic extended thinking, where each
# ``thinking`` block's cryptographic ``signature`` (and any opaque
# ``redacted_thinking`` payload) MUST be echoed back unmodified on the next
# turn or the model cannot continue the signed reasoning state.
#
# ``content``/``reasoning_content`` above are the flattened text channels;
# they cannot represent a signature, so without this field the streaming
# path silently produced reasoning that ``thinking_format="content_block"``
# could not replay. Providers that need no block list leave it empty and
# the stream assembler keeps using the flattened string.
reasoning_blocks: list[dict[str, Any]] = field(
default_factory=list[dict[str, Any]],
)


@runtime_checkable
Expand Down
27 changes: 27 additions & 0 deletions agent_core/llm_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""Small product-neutral LLM helpers."""

from __future__ import annotations


def extract_boxed_content(text: str) -> str:
r"""Return the content of the last balanced ``\boxed{...}``."""
if not text:
return ""
matches: list[str] = []
offset = 0
while (start := text.find(r"\boxed{", offset)) >= 0:
content_start = start + 7
depth = 1
pos = content_start
while pos < len(text) and depth:
depth += (text[pos] == "{") - (text[pos] == "}")
pos += 1
if depth == 0:
matches.append(text[content_start : pos - 1])
offset = pos
else:
offset = content_start
return matches[-1] if matches else ""


__all__ = ["extract_boxed_content"]
43 changes: 43 additions & 0 deletions agent_core/providers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""Provider transports and provider-neutral client wrappers."""

from agent_core.providers.anthropic import AnthropicClient
from agent_core.providers.fallback import FallbackEntry, LLMFallbackChain
from agent_core.providers.nonblocking_stream import NonBlockingStream, nonblocking_stderr
from agent_core.providers.openai_chat import (
OpenAIClient,
SessionQueryResolver,
SessionScopeResolver,
configure_session_query_resolver,
configure_session_scope_resolver,
)
from agent_core.providers.openai_responses import OpenAIResponsesClient
from agent_core.providers.prompt_cache import (
AnthropicPromptCacheAdapter,
maybe_wrap_for_prompt_cache,
)
from agent_core.providers.protocol_client import (
build_protocol_client,
protocol_of,
provider_label,
thinking_format_for_protocol,
)

__all__ = [
"AnthropicClient",
"AnthropicPromptCacheAdapter",
"FallbackEntry",
"LLMFallbackChain",
"NonBlockingStream",
"OpenAIClient",
"OpenAIResponsesClient",
"SessionQueryResolver",
"SessionScopeResolver",
"build_protocol_client",
"configure_session_query_resolver",
"configure_session_scope_resolver",
"maybe_wrap_for_prompt_cache",
"nonblocking_stderr",
"protocol_of",
"provider_label",
"thinking_format_for_protocol",
]
Loading