Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
ecb31ed
chore: bootstrap native tool-calling feature branch
JasonW404 Nov 9, 2026
64bf7f4
Introduce capability-aware native tool-calling runtime on develop
JasonW404 Nov 9, 2026
c44641f
Keep runtime validation in the shared configuration parser
JasonW404 Nov 9, 2026
213cc77
Stream native provider reasoning and retain model diagnostics
JasonW404 Nov 9, 2026
ab378a4
Normalize reasoning API regression file ending
JasonW404 Nov 9, 2026
4779f59
Expose native finish and cache diagnostics to token events
JasonW404 Nov 9, 2026
084cd8a
Bootstrap shared context maintenance recovery feature
JasonW404 Nov 10, 2026
75710dc
feat(context): keep context maintenance non-blocking and calibrate pr…
JasonW404 Nov 10, 2026
7529942
fix(context): honor explicit overflow independently of local estimates
JasonW404 Nov 10, 2026
caa674b
Merge branch 'feature/context-maintenance-recovery' into feature/nati…
JasonW404 Nov 10, 2026
c7e3216
feat(agent): integrate shared context maintenance with native tool ex…
JasonW404 Nov 10, 2026
b697eac
fix(context): keep usage observations independent of model package lo…
JasonW404 Nov 10, 2026
5797cd2
Merge branch 'feature/context-maintenance-recovery' into feature/nati…
JasonW404 Nov 10, 2026
9102cde
fix(agent): use neutral shared usage observation module
JasonW404 Nov 10, 2026
0241c3c
test(context): align isolated namespaces with neutral usage module
JasonW404 Nov 10, 2026
17555ab
Merge branch 'feature/context-maintenance-recovery' into feature/nati…
JasonW404 Nov 10, 2026
7a40127
test: cover native output ownership and rebuild controls
JasonW404 Nov 10, 2026
8a4d77e
docs(test): link native context matrix acceptance evidence
JasonW404 Nov 10, 2026
5dd1ae2
fix(agent): preserve legacy action compaction in native integration
JasonW404 Nov 10, 2026
bb68f39
fix(agent): preserve legacy native stream event contract
JasonW404 Nov 11, 2026
3948eb1
test(agent): assert full direct completion for native text
JasonW404 Nov 11, 2026
f68a742
test(agent): add required observer test copyright
JasonW404 Nov 11, 2026
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
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,5 @@ sdk/uv.lock

# CI toolchain is not application source.
.ci-python/
# Task-local development artifacts and connection metadata.
.runtime/
8 changes: 8 additions & 0 deletions backend/contracts/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ def parse_positive_int(raw_value: object, name: str, default: int) -> int:
return parsed


def parse_agent_runtime(raw_value: object) -> str:
"""Validate the runtime switch while keeping environment declarations simple."""
value = "codeagent" if raw_value is None else raw_value
if value not in ("codeagent", "toolcalling"):
raise ValueError("NEXENT_AGENT_RUNTIME must be codeagent or toolcalling")
return value


def parse_port(raw_value: object, name: str, default: int) -> int:
"""Parse a TCP port while keeping environment declarations assignment-only."""
port = parse_positive_int(raw_value, name, default)
Expand Down
5 changes: 4 additions & 1 deletion backend/contracts/constants/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import os
from pathlib import Path
from dotenv import load_dotenv
from ..configuration import parse_positive_float, parse_positive_int, parse_port, _require_positive, _build_otlp_headers, _resolve_app_version
from ..configuration import parse_agent_runtime, parse_positive_float, parse_positive_int, parse_port, _require_positive, _build_otlp_headers, _resolve_app_version

# Environment initialization
# Repository-root callers import this module through the backend namespace.
Expand Down Expand Up @@ -461,3 +461,6 @@
MODEL_RESPONSE_DIAGNOSTIC_CHUNKS = os.getenv('NEXENT_MODEL_DIAGNOSTIC_CHUNKS', os.getenv('NEXENT_PROTOCOL_DIAGNOSTIC_CONTENT', '0')) == '1'
# Read OAuth settings centrally, including provider-specific credential names.
GET_OAUTH_SETTING = os.getenv

# Agent runtime request; effective mode is selected per resolved model capability.
NEXENT_AGENT_RUNTIME = parse_agent_runtime(os.getenv("NEXENT_AGENT_RUNTIME"))
2 changes: 2 additions & 0 deletions backend/management/services/agent/preparation/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from typing import Any, Dict, List, Optional

from contracts.constants.environment import (
NEXENT_AGENT_RUNTIME,
AGENT_WORKSPACE_ROOT,
MCP_REQUEST_TIMEOUT_SECONDS,
NEXENT_SANDBOX_CONTAINER_WORKSPACE_ROOT,
Expand Down Expand Up @@ -412,6 +413,7 @@ async def create_agent_run_info(
outlet_profiles=outlet_profiles, agent_overrides=model_params_override)

agent_run_info = build_run_info(
agent_runtime=NEXENT_AGENT_RUNTIME,
query=final_query,
model_config_list=model_list,
language=language,
Expand Down
1 change: 1 addition & 0 deletions backend/services/nl2agent_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -1546,6 +1546,7 @@ async def build_nl2agent_run_info(

stop_event = threading.Event()
run_info = AgentRunInfo(
agent_runtime="codeagent",
tenant_id=tenant_id,
query=final_query,
model_config_list=model_config_list,
Expand Down
1 change: 1 addition & 0 deletions backend/services/nl2skill_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ async def build_nl2skill_run_info(
compaction_target_tokens=context_budget.compaction_target_tokens if context_budget else 0,
)
run_info = AgentRunInfo(
agent_runtime="codeagent",
tenant_id=tenant_id,
query=template.get("user_prompt") or final_query,
model_config_list=model_config_list,
Expand Down
5 changes: 5 additions & 0 deletions deploy/env/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -405,3 +405,8 @@ NEXENT_LITELLM_JSON=/opt/nexent/litellm_models.json
# MODEL_REASONING_WIRE_PROFILES_PATH=/opt/backend/configs/model_reasoning_wire_profiles.json
# Short-lived structural diagnostics only; generated text and tool arguments are always redacted.
NEXENT_MODEL_DIAGNOSTIC_CHUNKS=0

# Requested agent runtime: codeagent (default) or toolcalling (opt-in).
# toolcalling is effective only for models with declared tool support; unknown/unsupported models use CodeAgent.
# Reasoning follows the resolved model profile independently; no simulated reasoning fallback is added.
NEXENT_AGENT_RUNTIME=codeagent
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Introduction and future integration

The current branch is based directly on develop and targets develop in draft PR4315. Its model-service integration is implemented here rather than deferred to a future migration. The v2.8.4 branch is a standalone hotfix-like experiment and is not intended to merge into either main or develop.

Before enabling the new mode, select and validate model/provider profiles and retain their resolved capability/parameter configuration. Set NEXENT_AGENT_RUNTIME=toolcalling and recreate application services. Models without declared tool support continue through CodeAgent. Rollback is the default codeagent setting; no Agent Definition schema migration is introduced by the runtime.

Future work includes native-history compaction, multimodal projection, provider-specific opaque reasoning continuation and the explicitly unverified harness journeys in the compatibility matrix. Those are separate from the completed generation-terminal and staged-text contract. Reconcile current develop and repeat required verification before merge; no branch protection or workflow settings are changed by this feature.

Host deployment data for PR4315 is separate from the earlier experiment. Preserve both worktrees' private deployment directories while either installation is required. The VM remains stopped by user preference.
262 changes: 262 additions & 0 deletions docs/experimental-native-runtime/evidence/acceptance.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
{
"date": "2026-11-09",
"unit_tests": {
"modules": [
{
"file": "test/sdk/core/agents/test_native_runtime.py",
"exit_code": 0,
"tests": 28,
"failures": 0,
"skipped": 0
},
{
"file": "test/sdk/core/agents/test_native_runtime_harness.py",
"exit_code": 0,
"tests": 19,
"failures": 0,
"skipped": 0
},
{
"file": "test/sdk/core/agents/test_native_completion.py",
"exit_code": 0,
"tests": 23,
"failures": 0,
"skipped": 0
},
{
"file": "test/sdk/core/agents/test_native_public_text.py",
"exit_code": 0,
"tests": 2,
"failures": 0,
"skipped": 0
},
{
"file": "test/sdk/core/agents/test_nexent_agent.py",
"exit_code": 0,
"tests": 248,
"failures": 0,
"skipped": 0
},
{
"file": "test/sdk/core/agents/test_core_agent.py",
"exit_code": 0,
"tests": 182,
"failures": 0,
"skipped": 0
},
{
"file": "test/sdk/core/agents/test_run_agent.py",
"exit_code": 0,
"tests": 61,
"failures": 0,
"skipped": 0
},
{
"file": "test/sdk/core/utils/test_observer.py",
"exit_code": 0,
"tests": 107,
"failures": 0,
"skipped": 0
},
{
"file": "test/sdk/core/utils/test_observer_final_answers.py",
"exit_code": 0,
"tests": 19,
"failures": 0,
"skipped": 0
},
{
"file": "test/sdk/core/utils/test_observer_model_attempts.py",
"exit_code": 0,
"tests": 3,
"failures": 0,
"skipped": 0
},
{
"file": "test/sdk/core/utils/test_observer_nl2agent_protocol.py",
"exit_code": 0,
"tests": 6,
"failures": 0,
"skipped": 0
},
{
"file": "test/backend/utils/test_final_answer_projection.py",
"exit_code": 0,
"tests": 24,
"failures": 0,
"skipped": 0
},
{
"file": "test/backend/services/test_agent_run_final_answers.py",
"exit_code": 0,
"tests": 4,
"failures": 0,
"skipped": 0
},
{
"file": "test/sdk/core/model_service/test_native_service_model.py",
"exit_code": 0,
"tests": 20,
"failures": 0,
"skipped": 0
},
{
"file": "test/sdk/core/model_service/test_native_stream_compatibility.py",
"exit_code": 0,
"tests": 4,
"failures": 0,
"skipped": 0
},
{
"file": "test/sdk/core/model_service/test_openai_chat_adapter.py",
"exit_code": 0,
"tests": 54,
"failures": 0,
"skipped": 0
},
{
"file": "test/sdk/core/model_service/test_openai_stream.py",
"exit_code": 0,
"tests": 45,
"failures": 0,
"skipped": 0
},
{
"file": "test/sdk/core/model_service/test_model_service.py",
"exit_code": 0,
"tests": 41,
"failures": 0,
"skipped": 0
},
{
"file": "test/sdk/core/model_service/test_legacy_chat_model.py",
"exit_code": 0,
"tests": 25,
"failures": 0,
"skipped": 0
},
{
"file": "test/sdk/core/model_service/test_legacy_tool_continuation.py",
"exit_code": 0,
"tests": 25,
"failures": 0,
"skipped": 0
},
{
"file": "test/backend/agents/test_create_agent_info.py",
"exit_code": 0,
"tests": 253,
"failures": 0,
"skipped": 0
},
{
"file": "test/backend/services/test_nl2agent_service.py",
"exit_code": 0,
"tests": 59,
"failures": 0,
"skipped": 0
},
{
"file": "test/backend/services/test_nl2skill_service.py",
"exit_code": 0,
"tests": 24,
"failures": 0,
"skipped": 0
},
{
"file": "test/backend/contracts/test_agent_runtime_config.py",
"exit_code": 0,
"tests": 6,
"failures": 0,
"skipped": 0
},
{
"file": "test/backend/management/test_agent_runtime_boundaries.py",
"exit_code": 0,
"tests": 7,
"failures": 0,
"skipped": 0
},
{
"file": "test/sdk/core/model_service/test_native_service_observability.py",
"exit_code": 0,
"tests": 2,
"failures": 0,
"skipped": 0
},
{
"file": "test/backend/management/test_contracts_directory_architecture.py",
"exit_code": 0,
"tests": 7,
"failures": 0,
"skipped": 0
}
],
"total_tests": 1298,
"failures": 0,
"skipped": 0
},
"frontend_tests": {
"node_projection": 5,
"vitest_adapter_and_regressions": 17,
"typescript": "PASS"
},
"formal": [
{
"case_id": "AGENT-NATIVE-D2-001",
"run_id": "20261109T113417066776Z-AGENT-NATIVE-D2-001",
"status": "PASS",
"test_summary": {
"tests": 5,
"failures": 0,
"errors": 0,
"skipped": 0
},
"semantic_review": "PASS: terminal/side-effect assertions, observed actual results and Phoenix or image identity evidence reviewed separately."
},
{
"case_id": "AGENT-NATIVE-D3-001",
"run_id": "20261109T110956381299Z-AGENT-NATIVE-D3-001",
"status": "PASS",
"test_summary": {
"tests": 17,
"failures": 0,
"errors": 0,
"skipped": 0
},
"semantic_review": "PASS: terminal/side-effect assertions, observed actual results and Phoenix or image identity evidence reviewed separately."
},
{
"case_id": "AGENT-NATIVE-D3-002",
"run_id": "20261109T111137175271Z-AGENT-NATIVE-D3-002",
"status": "PASS",
"test_summary": {
"tests": 10,
"failures": 0,
"errors": 0,
"skipped": 0
},
"semantic_review": "PASS: terminal/side-effect assertions, observed actual results and Phoenix or image identity evidence reviewed separately."
},
{
"case_id": "AGENT-NATIVE-D5-001",
"run_id": "20261109T113519378102Z-AGENT-NATIVE-D5-001",
"status": "PASS",
"test_summary": {
"tests": 1,
"failures": 0,
"errors": 0,
"skipped": 0
},
"semantic_review": "PASS: terminal/side-effect assertions, observed actual results and Phoenix or image identity evidence reviewed separately."
}
],
"browser": {
"status": "PASS (manual)",
"screenshot": "interleaved-browser.png",
"tool_detail_screenshot": "interleaved-tools.png",
"observations": "Public progress before direct directory call and Python execution; final observed 323. Reload/reopen retained text/tool order and one final answer.",
"note": "No invented filename when the new workspace was empty."
},
"ci_correction": "Pure runtime parser moved to existing configuration helpers to satisfy constants architecture; six configuration and seven architecture tests pass. Rebuilt/deployed main, API and image checks repeated; unchanged SDK/frontend proofs retained."
}
Loading
Loading