diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f3d70bf..1916c11 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -108,7 +108,7 @@ jobs: runs-on: ubuntu-latest environment: name: pypi - url: https://pypi.org/p/simagentplg + url: https://pypi.org/p/ejagent-core permissions: id-token: write steps: diff --git a/.gitignore b/.gitignore index 903380e..a344195 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,5 @@ my_skills .pytest_cache -.simagentplg-sessions \ No newline at end of file +.ejagent-sessions +.simagentplg-sessions diff --git a/README.md b/README.md index 002133b..279b886 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,12 @@ -# SimAgentPlg +# EJAgent Core [English](README.md) | [简体中文](README_zh-CN.md) -SimAgentPlg is a lightweight core for building stateful, extensible agents on -OpenAI-compatible model APIs. It provides the runtime mechanism—state, -orchestration, context construction, tool dispatch, middleware, MCP, and -skills—while derived agents own concrete tools such as shell, file editing, +EJAgent Core is an OpenAI-first Agent Harness Core built around eight capability +areas: execution, control, extensibility, safety, context management, durable +history, branching, and observability. It provides the runtime mechanisms for +state, orchestration, context construction, tool dispatch, middleware, MCP, and +skills, while derived agents own concrete tools such as shell, file editing, Git, or explicit completion. Requires Python 3.12 or newer. @@ -48,16 +49,28 @@ Derived agents should provide equivalent implementations when needed. ## Installation ```bash -uv sync +pip install ejagent-core +# or, for a source checkout: uv sync ``` MCP support is optional. Install its extra only when the agent uses MCP: ```bash uv sync --extra mcp -# or: pip install "SimAgentPlg[mcp]" +# or: pip install "ejagent-core[mcp]" ``` +Version 0.6.0 renames the PyPI distribution to `ejagent-core` and the Python +import package to `ejagent`: + +```python +from ejagent import BaseAgent +``` + +The former `simagentplg` import is not retained as a compatibility alias. +Existing JSONL Sessions remain readable; legacy internal message metadata is +filtered from provider requests during restoration. + ## Configuration Copy `.env.example` to `.env` and provide model credentials: @@ -75,7 +88,7 @@ LLM_INCLUDE_USAGE=true Configuration can also be supplied directly: ```python -from simagentplg import ModelConfig +from ejagent import ModelConfig config = ModelConfig( model="deepseek-v4-flash", @@ -95,7 +108,7 @@ provider-neutral stream events and the normalized `AssistantMessage` contract. Conversation history is preserved across calls: ```python -from simagentplg import BaseAgent, ModelConfig, OpenAIModelAdapter +from ejagent import BaseAgent, ModelConfig, OpenAIModelAdapter agent = BaseAgent( OpenAIModelAdapter(ModelConfig.from_env()), @@ -246,7 +259,7 @@ next Provider request. It is deliberately separate from read-only Event Sinks and Tool Middleware: ```python -from simagentplg import BehaviorDecision +from ejagent import BehaviorDecision class StopAfterFirstToolTurn: @@ -282,7 +295,7 @@ must explicitly declare a tool `READ_ONLY`, and the Runtime Policy must enable parallel calls: ```python -from simagentplg import ( +from ejagent import ( MethodToolHandler, RuntimePolicy, ToolDefinition, @@ -337,7 +350,7 @@ the handler and its middleware, not an automatic side-effect inference. text and provisional reasoning are observed through typed Delta events: ```python -from simagentplg import AssistantThinkingDelta, AssistantTextDelta +from ejagent import AssistantThinkingDelta, AssistantTextDelta class ConsoleSink: @@ -383,7 +396,7 @@ optional `CompactionPolicy` to assess the complete provider request before each model call: ```python -from simagentplg import CompactionPolicy, ContextBudget +from ejagent import CompactionPolicy, ContextBudget context_policy = CompactionPolicy( ContextBudget( @@ -417,7 +430,7 @@ Automatic behavior is opt-in and reuses the same `CompactionPolicy` and `Compactor`: ```python -from simagentplg import AutoCompactionPolicy +from ejagent import AutoCompactionPolicy agent = BaseAgent( model, @@ -494,7 +507,7 @@ or prompt. record for each accepted lifecycle mutation: ```python -from simagentplg import JsonlSessionStorage, SessionRecorder +from ejagent import JsonlSessionStorage, SessionRecorder storage = JsonlSessionStorage("./sessions") recorder = SessionRecorder(session_id="project-42", storage=storage) @@ -568,7 +581,7 @@ semantics or provide another `SessionTreeStorage` backend. Tool availability and completion policy are independent: ```python -from simagentplg import RuntimePolicy +from ejagent import RuntimePolicy policy = RuntimePolicy( max_steps=20, @@ -607,7 +620,7 @@ an async `do_add()` method: from collections.abc import Mapping from typing import Any -from simagentplg import ( +from ejagent import ( CancellationToken, MethodToolHandler, StepOutcome, @@ -677,7 +690,7 @@ Long-running tools can optionally accept a scoped `progress` reporter. Existing `do_*` methods that do not declare this keyword remain compatible: ```python -from simagentplg import ToolProgressReporter, ToolProgressUpdate +from ejagent import ToolProgressReporter, ToolProgressUpdate async def do_index( @@ -707,7 +720,7 @@ and are ignored after `ToolCompleted`. They never change `StepOutcome` or Tool payload and runtime control are separate: ```python -from simagentplg import StepOutcome, ToolControl +from ejagent import StepOutcome, ToolControl StepOutcome(data) # continue the provider-tool loop StepOutcome(data, control=ToolControl.COMPLETE) @@ -725,7 +738,7 @@ protocol. `ToolMiddleware` is the single interception chain around tool execution: ```python -from simagentplg import ToolMiddleware +from ejagent import ToolMiddleware class AuditMiddleware(ToolMiddleware): @@ -741,7 +754,7 @@ same chain. It does not add a second policy path or a special `BaseAgent` parameter: ```python -from simagentplg import ( +from ejagent import ( RuleBasedToolPolicy, ToolApprovalDecision, ToolEffect, @@ -803,7 +816,7 @@ invalid model arguments never consume policy limits, request approval, or reach a handler: ```python -from simagentplg import ( +from ejagent import ( ToolPolicyMiddleware, ToolSchemaValidationMiddleware, ) @@ -851,7 +864,7 @@ remains the distinct terminal `ToolControl.REJECT` path. MCP uses the same handler contract: ```python -from simagentplg import ( +from ejagent import ( BaseAgent, McpToolHandler, ModelConfig, @@ -876,7 +889,7 @@ Skills are prompt and resource extensions independent of handler tools: ```python from pathlib import Path -from simagentplg import BaseAgent, ModelConfig, OpenAIModelAdapter +from ejagent import BaseAgent, ModelConfig, OpenAIModelAdapter agent = BaseAgent( OpenAIModelAdapter(ModelConfig.from_env()), @@ -903,7 +916,7 @@ examples/skills/ ## Core boundary -SimAgentPlg core owns mechanisms: +EJAgent Core owns mechanisms: ```text Orchestration + State + Context + Runtime Policy + Run Result @@ -975,19 +988,22 @@ environment and PyPI publisher, merge the release commit into `main`, then push a version-matching tag: ```text -PyPI project: SimAgentPlg +PyPI project: ejagent-core GitHub owner: jyh20030112 -Repository: SimAgentPlg +Repository: SimAgentPlg (rename separately) Workflow: release.yml Environment: pypi ``` +Because `ejagent-core` is a new PyPI project name, configure its Trusted +Publisher before creating the `v0.6.0` release tag. + Protect the GitHub `pypi` environment with required reviewers and restrict creation of `v*` tags to maintainers. Then publish with: ```bash -git tag v0.5.0 -git push origin v0.5.0 +git tag v0.6.0 +git push origin v0.6.0 ``` The workflow rejects tags whose commit is not on `main` or whose value does not diff --git a/README_zh-CN.md b/README_zh-CN.md index 95f8005..e88c4d5 100644 --- a/README_zh-CN.md +++ b/README_zh-CN.md @@ -1,11 +1,11 @@ -# SimAgentPlg +# EJAgent Core [English](README.md) | [简体中文](README_zh-CN.md) -SimAgentPlg 是一个用于构建有状态、可扩展 Agent 的轻量级 Core,面向 -OpenAI-compatible 模型 API。Core 提供状态、编排、上下文、工具调度、 -Middleware、MCP 和 Skill 等运行机制;Shell、文件编辑、Git、审批界面和完成工具 -由具体派生 Agent 自行实现。 +EJAgent Core 是一个 OpenAI-first Agent Harness Core,围绕八个核心维度构建: +执行内核、运行控制、可组合扩展、安全边界、上下文管理、持久历史、分支演化与 +可观测性。Core 提供状态、编排、上下文、工具调度、Middleware、MCP 和 Skill 等 +运行机制;Shell、文件编辑、Git、审批界面和完成工具由具体派生 Agent 自行实现。 需要 Python 3.12 或更高版本。 @@ -45,16 +45,27 @@ CodeAgent 等派生 Agent。 ## 安装 ```bash -uv sync +pip install ejagent-core +# 或在源码仓库中执行:uv sync ``` MCP 支持是可选能力。只有使用 MCP 的 Agent 才需要安装额外依赖: ```bash uv sync --extra mcp -# 或:pip install "SimAgentPlg[mcp]" +# 或:pip install "ejagent-core[mcp]" ``` +0.6.0 将 PyPI Distribution 改名为 `ejagent-core`,Python Import Package 改为 +`ejagent`: + +```python +from ejagent import BaseAgent +``` + +旧的 `simagentplg` Import 不再作为兼容别名保留。已有 JSONL Session 仍可读取; +Restore 时会继续从 Provider 请求中剥离旧版内部消息元数据。 + ## 配置 复制 `.env.example` 为 `.env` 并填写模型配置: @@ -71,7 +82,7 @@ LLM_INCLUDE_USAGE=true `ModelConfig` 属于 `OpenAIModelAdapter`,不再属于 `BaseAgent`。也可以直接构造: ```python -from simagentplg import ModelConfig +from ejagent import ModelConfig config = ModelConfig( model="deepseek-v4-flash", @@ -89,7 +100,7 @@ Client 的创建、响应归一化以及可选的启动/关闭资源;`BaseAgen 多次调用之间会保留对话历史: ```python -from simagentplg import BaseAgent, ModelConfig, OpenAIModelAdapter +from ejagent import BaseAgent, ModelConfig, OpenAIModelAdapter agent = BaseAgent( OpenAIModelAdapter(ModelConfig.from_env()), @@ -189,7 +200,7 @@ Continue 分配新的 `run_id`、发布 `AgentContinued`,并通过 `SessionRun `BehaviorHook.after_turn()` 决定一个非终态完整 Turn 是否允许进入下一次 Provider 请求: ```python -from simagentplg import BehaviorDecision +from ejagent import BehaviorDecision class StopAfterFirstToolTurn: @@ -216,7 +227,7 @@ agent = BaseAgent( `ToolEffect.READ_ONLY`,Runtime Policy 也必须允许并行: ```python -from simagentplg import ( +from ejagent import ( MethodToolHandler, RuntimePolicy, ToolDefinition, @@ -273,7 +284,7 @@ Context Window 容量和累计 Run 消耗是两个独立概念。可以为 Agent `CompactionPolicy`,在每次模型请求前评估完整 Provider 上下文: ```python -from simagentplg import CompactionPolicy, ContextBudget +from ejagent import CompactionPolicy, ContextBudget context_policy = CompactionPolicy( ContextBudget( @@ -305,7 +316,7 @@ User/Assistant/Tool Turn,以及需要原文保留的最近 Turn。Tool Call 自动行为默认关闭;启用时复用同一个 `CompactionPolicy` 和 `Compactor`: ```python -from simagentplg import AutoCompactionPolicy +from ejagent import AutoCompactionPolicy agent = BaseAgent( model, @@ -372,7 +383,7 @@ Token metadata,最后原子替换成“受保护消息 + Summary + 最近 Turn 版本化语义 Record: ```python -from simagentplg import JsonlSessionStorage, SessionRecorder +from ejagent import JsonlSessionStorage, SessionRecorder storage = JsonlSessionStorage("./sessions") recorder = SessionRecorder(session_id="project-42", storage=storage) @@ -434,7 +445,7 @@ Revision 或静默覆盖 Branch Head;过期 Head 返回 `SessionConflictError` 工具是否存在和任务是否必须显式完成已经解耦: ```python -from simagentplg import RuntimePolicy +from ejagent import RuntimePolicy policy = RuntimePolicy( max_steps=20, @@ -472,7 +483,7 @@ policy = RuntimePolicy(require_explicit_finish=True) from collections.abc import Mapping from typing import Any -from simagentplg import ( +from ejagent import ( MethodToolHandler, StepOutcome, ToolDefinition, @@ -533,7 +544,7 @@ MethodToolHandler((OPENAI_TOOL_DICTIONARY,)) 现有 `do_*` 方法仍然兼容: ```python -from simagentplg import ToolProgressReporter, ToolProgressUpdate +from ejagent import ToolProgressReporter, ToolProgressUpdate async def do_index( @@ -562,7 +573,7 @@ Progress 保持顺序,在取消或 `ToolCompleted` 后停止接收;它不会 工具结果数据与运行控制已经分离: ```python -from simagentplg import StepOutcome, ToolControl +from ejagent import StepOutcome, ToolControl StepOutcome(data) # 继续模型—工具循环 StepOutcome(data, control=ToolControl.COMPLETE) @@ -577,7 +588,7 @@ StepOutcome(data, control=ToolControl.CANCEL) `ToolMiddleware` 是工具执行外围唯一的拦截链: ```python -from simagentplg import ToolMiddleware +from ejagent import ToolMiddleware class AuditMiddleware(ToolMiddleware): @@ -592,7 +603,7 @@ class AuditMiddleware(ToolMiddleware): Policy 通道,也不会给 `BaseAgent` 增加特殊参数: ```python -from simagentplg import ( +from ejagent import ( RuleBasedToolPolicy, ToolApprovalDecision, ToolEffect, @@ -651,7 +662,7 @@ Core 只提供策略和审批协议,不提供审批 UI,也不内置 Shell、 Policy 限额、请求审批或到达 Handler: ```python -from simagentplg import ( +from ejagent import ( ToolPolicyMiddleware, ToolSchemaValidationMiddleware, ) @@ -697,7 +708,7 @@ Schema 时则返回普通、非终态 Tool Result: MCP 使用相同的 Handler 协议: ```python -from simagentplg import ( +from ejagent import ( BaseAgent, McpToolHandler, ModelConfig, @@ -721,7 +732,7 @@ Skill 是独立于 Handler 工具的提示词和资源扩展: ```python from pathlib import Path -from simagentplg import BaseAgent, ModelConfig, OpenAIModelAdapter +from ejagent import BaseAgent, ModelConfig, OpenAIModelAdapter agent = BaseAgent( OpenAIModelAdapter(ModelConfig.from_env()), @@ -746,7 +757,7 @@ examples/skills/ ## Core 边界 -SimAgentPlg Core 负责机制: +EJAgent Core 负责机制: ```text Orchestration + State + Context + Runtime Policy + Run Result @@ -806,19 +817,22 @@ PyPI 发布由 `.github/workflows/release.yml` 和 Trusted Publishing 完成,G 合并到 `main`,再推送与项目版本一致的 Tag: ```text -PyPI 项目:SimAgentPlg +PyPI 项目:ejagent-core GitHub Owner:jyh20030112 -Repository:SimAgentPlg +Repository:SimAgentPlg(单独执行远程改名) Workflow:release.yml Environment:pypi ``` +`ejagent-core` 是新的 PyPI 项目名,因此创建 `v0.6.0` Release Tag 前,需要先为它 +配置 Trusted Publisher。 + 建议为 GitHub `pypi` Environment 配置 Required Reviewer,并限制只有 Maintainer 可以 创建 `v*` Tag。然后执行: ```bash -git tag v0.5.0 -git push origin v0.5.0 +git tag v0.6.0 +git push origin v0.6.0 ``` 工作流会拒绝不在 `main` 上或与 `project.version` 不一致的 Tag,重新执行完整质量矩阵, diff --git a/benchmarks/session_journal.py b/benchmarks/session_journal.py index cfbf5b0..5bb9835 100644 --- a/benchmarks/session_journal.py +++ b/benchmarks/session_journal.py @@ -10,7 +10,7 @@ from pathlib import Path from typing import Any -from simagentplg import AgentSession, JsonlSessionStorage +from ejagent import AgentSession, JsonlSessionStorage def journal_size(directory: str) -> int: diff --git a/docs/pi-harness-gap-analysis.md b/docs/pi-harness-gap-analysis.md index 9bb8deb..610cf3b 100644 --- a/docs/pi-harness-gap-analysis.md +++ b/docs/pi-harness-gap-analysis.md @@ -1,16 +1,16 @@ -# SimAgentPlg 与 Pi Agent Harness 能力对照 +# EJAgent Core 与 Pi Agent Harness 能力对照 > 更新日期:2026-07-22 > -> SimAgentPlg 基线:`4864804` 后的 Core 能力工作树,项目版本 `0.5.0` +> EJAgent Core 基线:`58d28f1` 后的 0.6.0 Rename 工作树 > > Pi 子模块基线:`f4e9ca74` > -> 对照范围:`pi/packages/agent`、`pi/packages/coding-agent` 与 SimAgentPlg Core +> 对照范围:`pi/packages/agent`、`pi/packages/coding-agent` 与 EJAgent Core ## 1. 当前结论 -SimAgentPlg 已经不只是 Agent Loop。当前实现覆盖了通用 Agent Core 的主要执行机制: +EJAgent Core 已经不只是 Agent Loop。当前实现覆盖了通用 Agent Core 的主要执行机制: - Provider-neutral 模型边界和 OpenAI-compatible Adapter - 模型—工具循环、结构化终止结果与 Runtime Policy @@ -358,7 +358,7 @@ CD 属于交付能力,不改变 Core Runtime 语义。 ## 4. 与 Pi 的能力矩阵 -| Harness 能力 | Pi 当前实现 | SimAgentPlg 当前实现 | 结论 | +| Harness 能力 | Pi 当前实现 | EJAgent Core 当前实现 | 结论 | |---|---|---|---| | Agent Loop | `agentLoop` / `Agent` | `AgentOrchestrator` / `BaseAgent` | 已对齐核心能力 | | 结构化终止 | Assistant stop reason 为主 | `AgentRunResult` + `StopReason` | Sim 更显式 | @@ -399,7 +399,7 @@ CD 属于交付能力,不改变 Core Runtime 语义。 ### 5.1 只读 Event 与行为型 Hook Pi 的 Agent 和 Coding Agent 允许 Hook 阻止 Tool、改写结果、停止 Turn、注入资源或修改 -Context。SimAgentPlg 当前坚持: +Context。EJAgent Core 当前坚持: - `AgentEventSink` 只观察,不修改行为。 - Tool 行为改写只通过 `ToolMiddleware`。 @@ -417,7 +417,7 @@ Pi 当前同时存在 Harness Session Repo 和 Coding Agent Session Manager: - Coding Agent 支持 Compaction、Branch Summary、Custom Entry、Label、Model Change 等类型。 - Repo Fork 可以把选定 Entry 路径复制到新的 JSONL Session,并记录 Parent Session。 -SimAgentPlg 使用一个 Session 一个 JSONL 文件,所有 Branch 共享祖先 Record: +EJAgent Core 使用一个 Session 一个 JSONL 文件,所有 Branch 共享祖先 Record: ```text main: r1 → r2 → r3 → r4 @@ -429,7 +429,7 @@ main: r1 → r2 → r3 → r4 ### 5.3 Retry 与外部副作用 -SimAgentPlg 不从 `ToolCompleted` 中间恢复,也不自动执行 Retry: +EJAgent Core 不从 `ToolCompleted` 中间恢复,也不自动执行 Retry: 1. 找到目标 `RUN_STARTED`。 2. 回到该 Run 之前的完成状态。 @@ -441,13 +441,13 @@ SimAgentPlg 不从 `ToolCompleted` 中间恢复,也不自动执行 Retry: ### 5.4 Compaction 边界 Pi Coding Agent 支持更丰富的 Branch Summary、Extension Compaction 和 mid-turn 相关语义。 -SimAgentPlg 当前只在完整 User Turn 边界切分,并让应用拥有 Summary Prompt。它更适合作为 +EJAgent Core 当前只在完整 User Turn 边界切分,并让应用拥有 Summary Prompt。它更适合作为 通用 Core,但在超大单 Turn 或复杂分支摘要方面能力较弱。 ### 5.5 Tool 执行顺序 Pi 当前默认并行执行允许并行的 Tool Call,同时保证最终 Tool Result 按 Assistant 源顺序 -写入 transcript。SimAgentPlg 采用更保守的双重 opt-in:Handler 必须声明 `READ_ONLY`,Agent +写入 transcript。EJAgent Core 采用更保守的双重 opt-in:Handler 必须声明 `READ_ONLY`,Agent 还必须开启并行策略。连续只读调用并发运行,但 `ToolCompleted` 与 Tool Message 在批次完成后 按源顺序提交;副作用工具不会与相邻只读批次重叠。 diff --git a/examples/01_stateful_chat.py b/examples/01_stateful_chat.py index da81a38..c854ca1 100644 --- a/examples/01_stateful_chat.py +++ b/examples/01_stateful_chat.py @@ -2,7 +2,7 @@ import asyncio -from simagentplg import BaseAgent, ModelConfig, OpenAIModelAdapter +from ejagent import BaseAgent, ModelConfig, OpenAIModelAdapter async def main() -> None: diff --git a/examples/02_custom_tool.py b/examples/02_custom_tool.py index 6d5900f..3afc6c9 100644 --- a/examples/02_custom_tool.py +++ b/examples/02_custom_tool.py @@ -4,7 +4,7 @@ from collections.abc import Mapping from typing import Any -from simagentplg import ( +from ejagent import ( BaseAgent, CancellationToken, MethodToolHandler, diff --git a/examples/04_mcp_tools.py b/examples/04_mcp_tools.py index 207fe58..d24e9cd 100644 --- a/examples/04_mcp_tools.py +++ b/examples/04_mcp_tools.py @@ -3,7 +3,7 @@ import asyncio from pathlib import Path -from simagentplg import ( +from ejagent import ( BaseAgent, McpToolHandler, ModelConfig, diff --git a/examples/06_skill.py b/examples/06_skill.py index 0bcea4f..ceb400f 100644 --- a/examples/06_skill.py +++ b/examples/06_skill.py @@ -3,7 +3,7 @@ import asyncio from pathlib import Path -from simagentplg import BaseAgent, ModelConfig, OpenAIModelAdapter +from ejagent import BaseAgent, ModelConfig, OpenAIModelAdapter SKILLS_DIR = Path(__file__).with_name("skills") @@ -22,7 +22,7 @@ async def main() -> None: try: result = await agent.runtime( task=( - "$release_notes Write release notes for SimAgentPlg 0.2.4. Changes: " + "$release_notes Write release notes for EJAgent Core 0.2.4. Changes: " "added an orchestrator, structured run results, and runtime " "policy controls." ) diff --git a/examples/07_event_observers.py b/examples/07_event_observers.py index 4d83212..1a9f2c2 100644 --- a/examples/07_event_observers.py +++ b/examples/07_event_observers.py @@ -3,7 +3,7 @@ import asyncio from collections import Counter -from simagentplg import ( +from ejagent import ( AgentEvent, AgentEventKind, BaseAgent, diff --git a/examples/08_session_resume.py b/examples/08_session_resume.py index 01ff241..0597936 100644 --- a/examples/08_session_resume.py +++ b/examples/08_session_resume.py @@ -2,7 +2,7 @@ import asyncio -from simagentplg import ( +from ejagent import ( BaseAgent, MemorySessionStorage, ModelConfig, @@ -27,7 +27,7 @@ async def main() -> None: try: first = await first_agent.run( task=( - "Store this exact statement and reply only ACK: SimAgentPlg " + "Store this exact statement and reply only ACK: EJAgent Core " "uses lifecycle events to build Sessions without coupling " "persistence to the Agent Loop." ) @@ -52,7 +52,7 @@ async def main() -> None: resumed_agent.reset(saved.messages) try: resumed = await resumed_agent.run( - task="Repeat the exact stored SimAgentPlg statement." + task="Repeat the exact stored EJAgent Core statement." ) print(f"resumed response: {resumed.output}") finally: diff --git a/examples/09_runtime_control.py b/examples/09_runtime_control.py index 83dd27e..353dc63 100644 --- a/examples/09_runtime_control.py +++ b/examples/09_runtime_control.py @@ -5,7 +5,7 @@ from collections.abc import AsyncIterator from typing import Any -from simagentplg import ( +from ejagent import ( AgentEvent, BaseAgent, CancellationToken, diff --git a/examples/10_composed_harness.py b/examples/10_composed_harness.py index 5d4eefa..cade140 100644 --- a/examples/10_composed_harness.py +++ b/examples/10_composed_harness.py @@ -4,7 +4,7 @@ from collections.abc import Mapping from typing import Any -from simagentplg import ( +from ejagent import ( AgentEvent, BaseAgent, CancellationToken, @@ -26,7 +26,7 @@ "type": "function", "function": { "name": "inspect_project", - "description": "Return current SimAgentPlg Harness metadata.", + "description": "Return current EJAgent Core Harness metadata.", "parameters": {"type": "object", "properties": {}}, }, } @@ -62,7 +62,7 @@ async def do_inspect_project( self.inspected = True return StepOutcome( { - "agent_core": "SimAgentPlg", + "agent_core": "EJAgent Core", "orchestrator": "AgentOrchestrator", "events": "AgentEvent + CompositeAgentEventSink", "session": "SessionRecorder + MemorySessionStorage", diff --git a/examples/11_streaming_events.py b/examples/11_streaming_events.py index 8c1d32b..c8dfad1 100644 --- a/examples/11_streaming_events.py +++ b/examples/11_streaming_events.py @@ -2,7 +2,7 @@ import asyncio -from simagentplg import ( +from ejagent import ( AgentEvent, AgentFinished, AssistantTextDelta, diff --git a/examples/12_tool_progress.py b/examples/12_tool_progress.py index 1e43204..87edc3e 100644 --- a/examples/12_tool_progress.py +++ b/examples/12_tool_progress.py @@ -4,7 +4,7 @@ from collections.abc import Mapping from typing import Any -from simagentplg import ( +from ejagent import ( AgentEvent, AgentFinished, BaseAgent, diff --git a/examples/13_usage_budget.py b/examples/13_usage_budget.py index 8f189d4..a111b23 100644 --- a/examples/13_usage_budget.py +++ b/examples/13_usage_budget.py @@ -5,7 +5,7 @@ from collections.abc import Mapping from typing import Any -from simagentplg import ( +from ejagent import ( AgentEvent, AgentFinished, BaseAgent, diff --git a/examples/14_context_pressure.py b/examples/14_context_pressure.py index 043f09d..abce0d3 100644 --- a/examples/14_context_pressure.py +++ b/examples/14_context_pressure.py @@ -5,7 +5,7 @@ from collections.abc import Mapping from typing import Any -from simagentplg import ( +from ejagent import ( AgentEvent, BaseAgent, CancellationToken, diff --git a/examples/15_explicit_compaction.py b/examples/15_explicit_compaction.py index 079f27a..2353b40 100644 --- a/examples/15_explicit_compaction.py +++ b/examples/15_explicit_compaction.py @@ -4,7 +4,7 @@ import json import os -from simagentplg import ( +from ejagent import ( AgentEvent, BaseAgent, CompactionCompleted, @@ -30,7 +30,7 @@ def build_compaction_context(request: CompactionRequest) -> ContextBuildResult: { key: value for key, value in message.items() - if key not in {"usage", "_simagentplg_summary"} + if key not in {"usage", "_ejagent_summary", "_simagentplg_summary"} } for message in request.preparation.messages_to_summarize ] diff --git a/examples/16_durable_session.py b/examples/16_durable_session.py index 426446f..4710667 100644 --- a/examples/16_durable_session.py +++ b/examples/16_durable_session.py @@ -5,7 +5,7 @@ import os from pathlib import Path -from simagentplg import ( +from ejagent import ( BaseAgent, JsonlSessionStorage, ModelConfig, @@ -77,7 +77,7 @@ async def main() -> None: parser.add_argument("command", choices=("record", "resume")) parser.add_argument( "--session-dir", - default=os.getenv("SIMAGENTPLG_SESSION_DIR", ".simagentplg-sessions"), + default=os.getenv("EJAGENT_SESSION_DIR", ".ejagent-sessions"), ) args = parser.parse_args() storage = JsonlSessionStorage(Path(args.session_dir)) diff --git a/examples/17_session_tree.py b/examples/17_session_tree.py index 84bbd8a..6c7ed59 100644 --- a/examples/17_session_tree.py +++ b/examples/17_session_tree.py @@ -5,7 +5,7 @@ import os from pathlib import Path -from simagentplg import JsonlSessionStorage +from ejagent import JsonlSessionStorage async def main() -> None: @@ -13,7 +13,7 @@ async def main() -> None: parser.add_argument("--session-id", default="durable-session-demo") parser.add_argument( "--session-dir", - default=os.getenv("SIMAGENTPLG_SESSION_DIR", ".simagentplg-sessions"), + default=os.getenv("EJAGENT_SESSION_DIR", ".ejagent-sessions"), ) commands = parser.add_subparsers(dest="command", required=True) commands.add_parser("branches") diff --git a/examples/README.md b/examples/README.md index e53d716..780a070 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,4 +1,4 @@ -# SimAgentPlg Examples +# EJAgent Core Examples All examples use the environment variables documented in the project README. Copy `.env.example` to `.env` and fill in credentials for an OpenAI-compatible diff --git a/pyproject.toml b/pyproject.toml index 5594aa3..09ff2bf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] -name = "SimAgentPlg" -version = "0.5.0" -description = "A lightweight stateful agent framework with ReAct reasoning, tool dispatch, and MCP integration" +name = "ejagent-core" +version = "0.6.0" +description = "An OpenAI-first agent harness core for controlled, durable, and observable agent runtimes" readme = "README.md" license = {file = "LICENSE"} requires-python = ">=3.12" @@ -36,7 +36,7 @@ requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] -packages = ["src/simagentplg"] +packages = ["src/ejagent"] [tool.hatch.build.targets.sdist] exclude = [ @@ -57,7 +57,7 @@ ignore = [ [tool.mypy] python_version = "3.12" -files = ["src/simagentplg"] +files = ["src/ejagent"] check_untyped_defs = true disallow_untyped_defs = true no_implicit_optional = true diff --git a/src/simagentplg/__init__.py b/src/ejagent/__init__.py similarity index 87% rename from src/simagentplg/__init__.py rename to src/ejagent/__init__.py index da6fd9e..13b08b1 100644 --- a/src/simagentplg/__init__.py +++ b/src/ejagent/__init__.py @@ -1,19 +1,19 @@ """Composable stateful agents with tool handlers and MCP integration.""" -from simagentplg.agent.base import BaseAgent -from simagentplg.agent.behavior import ( +from ejagent.agent.base import BaseAgent +from ejagent.agent.behavior import ( BehaviorAction, BehaviorDecision, BehaviorHook, BehaviorHookError, TurnSnapshot, ) -from simagentplg.agent.cancellation import ( +from ejagent.agent.cancellation import ( AgentCancelledError, CancellationSource, CancellationToken, ) -from simagentplg.agent.compaction import ( +from ejagent.agent.compaction import ( CompactionRequest, CompactionResult, CompactionRuntime, @@ -23,8 +23,8 @@ CompactorOutput, SummaryEntry, ) -from simagentplg.agent.context_builder import AgentContextBuilder, ContextBuildResult -from simagentplg.agent.context_management import ( +from ejagent.agent.context_builder import AgentContextBuilder, ContextBuildResult +from ejagent.agent.context_management import ( AutoCompactionPolicy, CompactionDecision, CompactionDecisionReason, @@ -38,7 +38,7 @@ estimate_context_usage, prepare_compaction, ) -from simagentplg.agent.control import ( +from ejagent.agent.control import ( ContinueRejectedError, ContinueRejectedReason, ControlInput, @@ -52,7 +52,7 @@ FollowUpHandle, FollowUpRejectedError, ) -from simagentplg.agent.events import ( +from ejagent.agent.events import ( AgentContinued, AgentEvent, AgentEventKind, @@ -77,28 +77,28 @@ TurnCompleted, TurnStarted, ) -from simagentplg.agent.model_compactor import ( +from ejagent.agent.model_compactor import ( CompactionContextBuilder, ModelCompactor, ) -from simagentplg.agent.orchestrator import AgentOrchestrator -from simagentplg.agent.result import ( +from ejagent.agent.orchestrator import AgentOrchestrator +from ejagent.agent.result import ( AgentRunError, AgentRunResult, RunStatus, StopReason, ) -from simagentplg.agent.runtime_policy import RuntimePolicy -from simagentplg.agent.state import AgentState, AgentStatus -from simagentplg.agent.types import ( +from ejagent.agent.runtime_policy import RuntimePolicy +from ejagent.agent.state import AgentState, AgentStatus +from ejagent.agent.types import ( StepOutcome, ToolCallResult, ToolControl, ToolProgressReporter, ToolProgressUpdate, ) -from simagentplg.agent.usage import RunUsage -from simagentplg.handlers import ( +from ejagent.agent.usage import RunUsage +from ejagent.handlers import ( BaseHandler, McpToolHandler, MethodToolHandler, @@ -107,7 +107,7 @@ ToolEffect, UnknownToolError, ) -from simagentplg.middleware import ( +from ejagent.middleware import ( Middleware, RuleBasedToolPolicy, ToolApprovalDecision, @@ -127,9 +127,9 @@ compose_tool_middlewares, format_tool_call_preview, ) -from simagentplg.plugins.mcp.mcp_manager import McpServerManager -from simagentplg.plugins.skill.skill_manager import SkillManager -from simagentplg.providers import ( +from ejagent.plugins.mcp.mcp_manager import McpServerManager +from ejagent.plugins.skill.skill_manager import SkillManager +from ejagent.providers import ( AssistantMessage, ContextOverflowError, ModelAdapter, @@ -147,7 +147,7 @@ ModelUsage, OpenAIModelAdapter, ) -from simagentplg.session import ( +from ejagent.session import ( DEFAULT_SESSION_BRANCH, SESSION_JOURNAL_SCHEMA_VERSION, SESSION_SCHEMA_VERSION, diff --git a/src/simagentplg/agent/__init__.py b/src/ejagent/agent/__init__.py similarity index 85% rename from src/simagentplg/agent/__init__.py rename to src/ejagent/agent/__init__.py index 5681bc9..0b8de8f 100644 --- a/src/simagentplg/agent/__init__.py +++ b/src/ejagent/agent/__init__.py @@ -1,19 +1,19 @@ """Agent runtime primitives.""" -from simagentplg.agent.base import BaseAgent -from simagentplg.agent.behavior import ( +from ejagent.agent.base import BaseAgent +from ejagent.agent.behavior import ( BehaviorAction, BehaviorDecision, BehaviorHook, BehaviorHookError, TurnSnapshot, ) -from simagentplg.agent.cancellation import ( +from ejagent.agent.cancellation import ( AgentCancelledError, CancellationSource, CancellationToken, ) -from simagentplg.agent.compaction import ( +from ejagent.agent.compaction import ( CompactionRequest, CompactionResult, CompactionRuntime, @@ -23,8 +23,8 @@ CompactorOutput, SummaryEntry, ) -from simagentplg.agent.context_builder import AgentContextBuilder, ContextBuildResult -from simagentplg.agent.context_management import ( +from ejagent.agent.context_builder import AgentContextBuilder, ContextBuildResult +from ejagent.agent.context_management import ( AutoCompactionPolicy, CompactionDecision, CompactionDecisionReason, @@ -38,7 +38,7 @@ estimate_context_usage, prepare_compaction, ) -from simagentplg.agent.control import ( +from ejagent.agent.control import ( ContinueRejectedError, ContinueRejectedReason, ControlInput, @@ -52,7 +52,7 @@ FollowUpHandle, FollowUpRejectedError, ) -from simagentplg.agent.events import ( +from ejagent.agent.events import ( AgentContinued, AgentEvent, AgentEventKind, @@ -77,28 +77,28 @@ TurnCompleted, TurnStarted, ) -from simagentplg.agent.model_compactor import ( +from ejagent.agent.model_compactor import ( CompactionContextBuilder, ModelCompactor, ) -from simagentplg.agent.orchestrator import AgentOrchestrator -from simagentplg.agent.result import ( +from ejagent.agent.orchestrator import AgentOrchestrator +from ejagent.agent.result import ( AgentRunError, AgentRunResult, RunStatus, StopReason, ) -from simagentplg.agent.runtime_policy import RuntimePolicy -from simagentplg.agent.state import AgentState, AgentStatus -from simagentplg.agent.types import ( +from ejagent.agent.runtime_policy import RuntimePolicy +from ejagent.agent.state import AgentState, AgentStatus +from ejagent.agent.types import ( StepOutcome, ToolCallResult, ToolControl, ToolProgressReporter, ToolProgressUpdate, ) -from simagentplg.agent.usage import RunUsage -from simagentplg.middleware import ( +from ejagent.agent.usage import RunUsage +from ejagent.middleware import ( Middleware, RuleBasedToolPolicy, ToolApprovalDecision, diff --git a/src/simagentplg/agent/base.py b/src/ejagent/agent/base.py similarity index 95% rename from src/simagentplg/agent/base.py rename to src/ejagent/agent/base.py index c1549ea..1077302 100644 --- a/src/simagentplg/agent/base.py +++ b/src/ejagent/agent/base.py @@ -6,22 +6,22 @@ from pathlib import Path from typing import TYPE_CHECKING, Any -from simagentplg.agent.behavior import BehaviorHook -from simagentplg.agent.cancellation import ( +from ejagent.agent.behavior import BehaviorHook +from ejagent.agent.cancellation import ( CancellationSource, ) -from simagentplg.agent.compaction import ( +from ejagent.agent.compaction import ( CompactionResult, CompactionRuntime, Compactor, ) -from simagentplg.agent.context_builder import AgentContextBuilder -from simagentplg.agent.context_management import ( +from ejagent.agent.context_builder import AgentContextBuilder +from ejagent.agent.context_management import ( AutoCompactionPolicy, CompactionPolicy, MessageTokenEstimator, ) -from simagentplg.agent.control import ( +from ejagent.agent.control import ( ContinueRejectedError, ContinueRejectedReason, ControlInput, @@ -34,25 +34,25 @@ _FollowUpQueue, _SteeringQueue, ) -from simagentplg.agent.events import ( +from ejagent.agent.events import ( AgentEventEmitter, AgentEventSink, ) -from simagentplg.agent.orchestrator import AgentOrchestrator -from simagentplg.agent.result import AgentRunResult -from simagentplg.agent.runtime_policy import RuntimePolicy -from simagentplg.agent.state import AgentState -from simagentplg.agent.tool_runtime import ToolRuntime -from simagentplg.agent.types import StepOutcome -from simagentplg.logger import get_logger -from simagentplg.middleware import ToolMiddleware -from simagentplg.plugins.skill.skill_manager import SkillManager -from simagentplg.providers.base import ModelAdapter +from ejagent.agent.orchestrator import AgentOrchestrator +from ejagent.agent.result import AgentRunResult +from ejagent.agent.runtime_policy import RuntimePolicy +from ejagent.agent.state import AgentState +from ejagent.agent.tool_runtime import ToolRuntime +from ejagent.agent.types import StepOutcome +from ejagent.logger import get_logger +from ejagent.middleware import ToolMiddleware +from ejagent.plugins.skill.skill_manager import SkillManager +from ejagent.providers.base import ModelAdapter if TYPE_CHECKING: - from simagentplg.handlers.base import BaseHandler - from simagentplg.handlers.definition import ToolDefinition - from simagentplg.session.types import AgentSession + from ejagent.handlers.base import BaseHandler + from ejagent.handlers.definition import ToolDefinition + from ejagent.session.types import AgentSession DEFAULT_SYSTEM_PROMPT = "You are a helpful, concise assistant." diff --git a/src/simagentplg/agent/behavior.py b/src/ejagent/agent/behavior.py similarity index 94% rename from src/simagentplg/agent/behavior.py rename to src/ejagent/agent/behavior.py index b3d3879..8a93342 100644 --- a/src/simagentplg/agent/behavior.py +++ b/src/ejagent/agent/behavior.py @@ -6,10 +6,10 @@ from enum import StrEnum from typing import Protocol -from simagentplg.agent.cancellation import CancellationToken -from simagentplg.agent.types import AgentMessage -from simagentplg.agent.usage import RunUsage -from simagentplg.providers.base import AssistantMessage +from ejagent.agent.cancellation import CancellationToken +from ejagent.agent.types import AgentMessage +from ejagent.agent.usage import RunUsage +from ejagent.providers.base import AssistantMessage class BehaviorAction(StrEnum): diff --git a/src/simagentplg/agent/cancellation.py b/src/ejagent/agent/cancellation.py similarity index 100% rename from src/simagentplg/agent/cancellation.py rename to src/ejagent/agent/cancellation.py diff --git a/src/simagentplg/agent/compaction.py b/src/ejagent/agent/compaction.py similarity index 97% rename from src/simagentplg/agent/compaction.py rename to src/ejagent/agent/compaction.py index fd0cf06..acfeec0 100644 --- a/src/simagentplg/agent/compaction.py +++ b/src/ejagent/agent/compaction.py @@ -8,20 +8,20 @@ from typing import TYPE_CHECKING, Any, Protocol from uuid import uuid4 -from simagentplg.agent.cancellation import ( +from ejagent.agent.cancellation import ( AgentCancelledError, CancellationToken, ) -from simagentplg.agent.context_management import ( +from ejagent.agent.context_management import ( CompactionPolicy, CompactionPreparation, MessageTokenEstimator, ) -from simagentplg.agent.state import AgentState -from simagentplg.agent.types import INTERNAL_METADATA_PREFIX, AgentMessage +from ejagent.agent.state import AgentState +from ejagent.agent.types import INTERNAL_METADATA_PREFIX, AgentMessage if TYPE_CHECKING: - from simagentplg.agent.events import AgentEventEmitter + from ejagent.agent.events import AgentEventEmitter SUMMARY_METADATA_KEY = f"{INTERNAL_METADATA_PREFIX}summary" @@ -338,7 +338,7 @@ async def compact_in_active_run( ) -> CompactionResult: """Compact while reusing the caller's active Agent event run.""" - from simagentplg.agent.events import ( + from ejagent.agent.events import ( CompactionCompleted, CompactionFailed, CompactionStarted, diff --git a/src/simagentplg/agent/context_builder.py b/src/ejagent/agent/context_builder.py similarity index 92% rename from src/simagentplg/agent/context_builder.py rename to src/ejagent/agent/context_builder.py index 844edce..0a8fe60 100644 --- a/src/simagentplg/agent/context_builder.py +++ b/src/ejagent/agent/context_builder.py @@ -4,14 +4,14 @@ from dataclasses import dataclass from typing import Any -from simagentplg.agent.state import AgentState -from simagentplg.agent.types import INTERNAL_METADATA_PREFIX, AgentMessage -from simagentplg.handlers.definition import ( +from ejagent.agent.state import AgentState +from ejagent.agent.types import AgentMessage, is_internal_metadata_key +from ejagent.handlers.definition import ( ToolDefinition, ToolDefinitionInput, normalize_tool_definitions, ) -from simagentplg.plugins.skill.skill_manager import SkillManager +from ejagent.plugins.skill.skill_manager import SkillManager @dataclass(frozen=True, slots=True) @@ -82,7 +82,7 @@ def _strip_internal_metadata( { key: value for key, value in message.items() - if key != "usage" and not key.startswith(INTERNAL_METADATA_PREFIX) + if key != "usage" and not is_internal_metadata_key(key) } for message in messages ] diff --git a/src/simagentplg/agent/context_management.py b/src/ejagent/agent/context_management.py similarity index 98% rename from src/simagentplg/agent/context_management.py rename to src/ejagent/agent/context_management.py index 78e05dd..4e62ce9 100644 --- a/src/simagentplg/agent/context_management.py +++ b/src/ejagent/agent/context_management.py @@ -8,8 +8,8 @@ from enum import StrEnum from typing import Any, Protocol -from simagentplg.agent.types import INTERNAL_METADATA_PREFIX, AgentMessage -from simagentplg.providers.base import ModelUsage +from ejagent.agent.types import AgentMessage, is_internal_metadata_key +from ejagent.providers.base import ModelUsage class ContextUsageSource(StrEnum): @@ -79,7 +79,7 @@ def estimate_message(self, message: Mapping[str, Any]) -> int: visible = { key: value for key, value in message.items() - if key != "usage" and not key.startswith(INTERNAL_METADATA_PREFIX) + if key != "usage" and not is_internal_metadata_key(key) } return self.message_overhead_tokens + self._estimate_value(visible) diff --git a/src/simagentplg/agent/control.py b/src/ejagent/agent/control.py similarity index 98% rename from src/simagentplg/agent/control.py rename to src/ejagent/agent/control.py index 67e66c1..45cae36 100644 --- a/src/simagentplg/agent/control.py +++ b/src/ejagent/agent/control.py @@ -7,8 +7,8 @@ from enum import StrEnum from uuid import uuid4 -from simagentplg.agent.result import AgentRunResult, StopReason -from simagentplg.agent.types import AgentMessage +from ejagent.agent.result import AgentRunResult, StopReason +from ejagent.agent.types import AgentMessage class ControlInputKind(StrEnum): diff --git a/src/simagentplg/agent/events.py b/src/ejagent/agent/events.py similarity index 96% rename from src/simagentplg/agent/events.py rename to src/ejagent/agent/events.py index ea56ed8..4afac91 100644 --- a/src/simagentplg/agent/events.py +++ b/src/ejagent/agent/events.py @@ -7,19 +7,19 @@ from typing import ClassVar, Protocol, TypeAlias from uuid import uuid4 -from simagentplg.agent.compaction import ( +from ejagent.agent.compaction import ( CompactionRequest, CompactionResult, CompactionStatus, ) -from simagentplg.agent.context_management import ( +from ejagent.agent.context_management import ( CompactionDecision, CompactionPreparation, ) -from simagentplg.agent.control import ControlInput, ControlInputKind -from simagentplg.agent.result import AgentRunResult, StopReason -from simagentplg.agent.types import ToolCallResult, ToolProgressUpdate -from simagentplg.providers.base import ( +from ejagent.agent.control import ControlInput, ControlInputKind +from ejagent.agent.result import AgentRunResult, StopReason +from ejagent.agent.types import ToolCallResult, ToolProgressUpdate +from ejagent.providers.base import ( AssistantMessage, ModelToolCall, ModelUsage, diff --git a/src/simagentplg/agent/model_compactor.py b/src/ejagent/agent/model_compactor.py similarity index 89% rename from src/simagentplg/agent/model_compactor.py rename to src/ejagent/agent/model_compactor.py index 54244eb..d8a2832 100644 --- a/src/simagentplg/agent/model_compactor.py +++ b/src/ejagent/agent/model_compactor.py @@ -2,13 +2,13 @@ from typing import Protocol -from simagentplg.agent.cancellation import CancellationToken -from simagentplg.agent.compaction import ( +from ejagent.agent.cancellation import CancellationToken +from ejagent.agent.compaction import ( CompactionRequest, CompactorOutput, ) -from simagentplg.agent.context_builder import ContextBuildResult -from simagentplg.providers.base import AssistantMessage, ModelAdapter +from ejagent.agent.context_builder import ContextBuildResult +from ejagent.providers.base import AssistantMessage, ModelAdapter class CompactionContextBuilder(Protocol): diff --git a/src/simagentplg/agent/orchestrator.py b/src/ejagent/agent/orchestrator.py similarity index 97% rename from src/simagentplg/agent/orchestrator.py rename to src/ejagent/agent/orchestrator.py index c07408e..73d3fca 100644 --- a/src/simagentplg/agent/orchestrator.py +++ b/src/ejagent/agent/orchestrator.py @@ -5,41 +5,41 @@ from contextlib import suppress from typing import Any, Protocol -from simagentplg.agent.behavior import ( +from ejagent.agent.behavior import ( BehaviorAction, BehaviorDecision, BehaviorHook, BehaviorHookError, TurnSnapshot, ) -from simagentplg.agent.cancellation import ( +from ejagent.agent.cancellation import ( AgentCancelledError, CancellationSource, CancellationToken, ) -from simagentplg.agent.compaction import ( +from ejagent.agent.compaction import ( CompactionRuntime, CompactionStatus, CompactionTrigger, Compactor, ) -from simagentplg.agent.context_builder import ( +from ejagent.agent.context_builder import ( AgentContextBuilder, ContextBuildResult, ) -from simagentplg.agent.context_management import ( +from ejagent.agent.context_management import ( AutoCompactionPolicy, CompactionPolicy, CompactionPreparation, MessageTokenEstimator, estimate_context_usage, ) -from simagentplg.agent.control import ( +from ejagent.agent.control import ( ContinueRejectedError, _continue_history_rejection_reason, _SteeringQueue, ) -from simagentplg.agent.events import ( +from ejagent.agent.events import ( AgentContinued, AgentEventEmitter, AgentFinished, @@ -53,18 +53,18 @@ TurnCompleted, TurnStarted, ) -from simagentplg.agent.result import AgentRunResult, RunStatus, StopReason -from simagentplg.agent.runtime_policy import RuntimePolicy -from simagentplg.agent.state import AgentState -from simagentplg.agent.tool_runtime import ( +from ejagent.agent.result import AgentRunResult, RunStatus, StopReason +from ejagent.agent.runtime_policy import RuntimePolicy +from ejagent.agent.state import AgentState +from ejagent.agent.tool_runtime import ( RepeatedToolCallError, ToolRuntime, ) -from simagentplg.agent.types import ToolCallResult, ToolControl -from simagentplg.agent.usage import UsageAccumulator -from simagentplg.handlers.definition import ToolDefinition, ToolEffect -from simagentplg.plugins.skill.skill_manager import SkillManager -from simagentplg.providers.base import ( +from ejagent.agent.types import ToolCallResult, ToolControl +from ejagent.agent.usage import UsageAccumulator +from ejagent.handlers.definition import ToolDefinition, ToolEffect +from ejagent.plugins.skill.skill_manager import SkillManager +from ejagent.providers.base import ( AssistantMessage, ContextOverflowError, ModelResponseCompleted, diff --git a/src/simagentplg/agent/result.py b/src/ejagent/agent/result.py similarity index 97% rename from src/simagentplg/agent/result.py rename to src/ejagent/agent/result.py index 8d24c3b..dbf5d73 100644 --- a/src/simagentplg/agent/result.py +++ b/src/ejagent/agent/result.py @@ -3,7 +3,7 @@ from dataclasses import dataclass, field from enum import StrEnum -from simagentplg.agent.usage import RunUsage +from ejagent.agent.usage import RunUsage class RunStatus(StrEnum): diff --git a/src/simagentplg/agent/runtime_policy.py b/src/ejagent/agent/runtime_policy.py similarity index 100% rename from src/simagentplg/agent/runtime_policy.py rename to src/ejagent/agent/runtime_policy.py diff --git a/src/simagentplg/agent/state.py b/src/ejagent/agent/state.py similarity index 97% rename from src/simagentplg/agent/state.py rename to src/ejagent/agent/state.py index 31cab06..841e86e 100644 --- a/src/simagentplg/agent/state.py +++ b/src/ejagent/agent/state.py @@ -4,8 +4,8 @@ from dataclasses import dataclass, field from enum import StrEnum -from simagentplg.agent.result import AgentRunResult -from simagentplg.agent.types import AgentMessage +from ejagent.agent.result import AgentRunResult +from ejagent.agent.types import AgentMessage class AgentStatus(StrEnum): diff --git a/src/simagentplg/agent/tool_runtime.py b/src/ejagent/agent/tool_runtime.py similarity index 97% rename from src/simagentplg/agent/tool_runtime.py rename to src/ejagent/agent/tool_runtime.py index 0136cf5..9c50e3d 100644 --- a/src/simagentplg/agent/tool_runtime.py +++ b/src/ejagent/agent/tool_runtime.py @@ -4,34 +4,34 @@ from collections.abc import Iterable, Mapping, Sequence from typing import Any -from simagentplg.agent.cancellation import ( +from ejagent.agent.cancellation import ( AgentCancelledError, CancellationSource, CancellationToken, ) -from simagentplg.agent.events import ( +from ejagent.agent.events import ( AgentEventEmitter, ToolCompleted, ToolProgressed, ToolStarted, ) -from simagentplg.agent.state import AgentState -from simagentplg.agent.types import ( +from ejagent.agent.state import AgentState +from ejagent.agent.types import ( StepOutcome, ToolCallResult, ToolControl, ToolProgressReporter, ToolProgressUpdate, ) -from simagentplg.handlers.base import BaseHandler -from simagentplg.handlers.definition import ToolDefinition, ToolEffect -from simagentplg.middleware import ( +from ejagent.handlers.base import BaseHandler +from ejagent.handlers.definition import ToolDefinition, ToolEffect +from ejagent.middleware import ( ToolCallContext, ToolMiddleware, ToolNext, compose_tool_middlewares, ) -from simagentplg.providers.base import ModelToolCall +from ejagent.providers.base import ModelToolCall class RepeatedToolCallError(RuntimeError): diff --git a/src/simagentplg/agent/types.py b/src/ejagent/agent/types.py similarity index 77% rename from src/simagentplg/agent/types.py rename to src/ejagent/agent/types.py index 0eff1a4..41b6f6f 100644 --- a/src/simagentplg/agent/types.py +++ b/src/ejagent/agent/types.py @@ -3,7 +3,18 @@ from typing import Any, Protocol AgentMessage = dict[str, Any] -INTERNAL_METADATA_PREFIX = "_simagentplg_" +INTERNAL_METADATA_PREFIX = "_ejagent_" +LEGACY_INTERNAL_METADATA_PREFIXES = ("_simagentplg_",) +INTERNAL_METADATA_PREFIXES = ( + INTERNAL_METADATA_PREFIX, + *LEGACY_INTERNAL_METADATA_PREFIXES, +) + + +def is_internal_metadata_key(key: str) -> bool: + """Return whether a message key belongs to current or legacy Core metadata.""" + + return key.startswith(INTERNAL_METADATA_PREFIXES) class ToolControl(StrEnum): diff --git a/src/simagentplg/agent/usage.py b/src/ejagent/agent/usage.py similarity index 99% rename from src/simagentplg/agent/usage.py rename to src/ejagent/agent/usage.py index 1b85e1f..12dcc52 100644 --- a/src/simagentplg/agent/usage.py +++ b/src/ejagent/agent/usage.py @@ -2,7 +2,7 @@ from dataclasses import dataclass -from simagentplg.providers.base import ModelUsage +from ejagent.providers.base import ModelUsage @dataclass(frozen=True, slots=True) diff --git a/src/simagentplg/handlers/__init__.py b/src/ejagent/handlers/__init__.py similarity index 71% rename from src/simagentplg/handlers/__init__.py rename to src/ejagent/handlers/__init__.py index 0a8c72b..35f6314 100644 --- a/src/simagentplg/handlers/__init__.py +++ b/src/ejagent/handlers/__init__.py @@ -1,16 +1,16 @@ """Composable local and external tool handlers.""" -from simagentplg.handlers.base import ( +from ejagent.handlers.base import ( BaseHandler, MethodToolHandler, UnknownToolError, ) -from simagentplg.handlers.definition import ( +from ejagent.handlers.definition import ( ToolDefinition, ToolDefinitionError, ToolEffect, ) -from simagentplg.handlers.mcp import McpToolHandler +from ejagent.handlers.mcp import McpToolHandler __all__ = [ "BaseHandler", diff --git a/src/simagentplg/handlers/base.py b/src/ejagent/handlers/base.py similarity index 96% rename from src/simagentplg/handlers/base.py rename to src/ejagent/handlers/base.py index 38c872c..5232dd1 100644 --- a/src/simagentplg/handlers/base.py +++ b/src/ejagent/handlers/base.py @@ -3,12 +3,12 @@ from inspect import Parameter, signature from typing import Any -from simagentplg.agent.cancellation import ( +from ejagent.agent.cancellation import ( CancellationSource, CancellationToken, ) -from simagentplg.agent.types import StepOutcome, ToolProgressReporter -from simagentplg.handlers.definition import ( +from ejagent.agent.types import StepOutcome, ToolProgressReporter +from ejagent.handlers.definition import ( ToolDefinition, ToolDefinitionError, ToolDefinitionInput, @@ -17,7 +17,7 @@ normalize_tool_definition, normalize_tool_definitions, ) -from simagentplg.middleware.base import ToolCallContext +from ejagent.middleware.base import ToolCallContext class UnknownToolError(KeyError): diff --git a/src/simagentplg/handlers/definition.py b/src/ejagent/handlers/definition.py similarity index 100% rename from src/simagentplg/handlers/definition.py rename to src/ejagent/handlers/definition.py diff --git a/src/simagentplg/handlers/mcp.py b/src/ejagent/handlers/mcp.py similarity index 93% rename from src/simagentplg/handlers/mcp.py rename to src/ejagent/handlers/mcp.py index fa9b330..9042c80 100644 --- a/src/simagentplg/handlers/mcp.py +++ b/src/ejagent/handlers/mcp.py @@ -2,16 +2,16 @@ from pathlib import Path from typing import Any -from simagentplg.agent.cancellation import ( +from ejagent.agent.cancellation import ( CancellationSource, CancellationToken, ) -from simagentplg.agent.types import StepOutcome, ToolProgressReporter -from simagentplg.handlers.base import ( +from ejagent.agent.types import StepOutcome, ToolProgressReporter +from ejagent.handlers.base import ( BaseHandler, UnknownToolError, ) -from simagentplg.handlers.definition import ( +from ejagent.handlers.definition import ( ToolDefinition, ToolDefinitionError, ToolEffect, @@ -19,7 +19,7 @@ normalize_tool_definition, normalize_tool_definitions, ) -from simagentplg.plugins.mcp.mcp_manager import McpServerManager +from ejagent.plugins.mcp.mcp_manager import McpServerManager class McpToolHandler(BaseHandler): diff --git a/src/simagentplg/logger.py b/src/ejagent/logger.py similarity index 90% rename from src/simagentplg/logger.py rename to src/ejagent/logger.py index e592c34..575f695 100644 --- a/src/simagentplg/logger.py +++ b/src/ejagent/logger.py @@ -2,7 +2,7 @@ def setup_logger( - name: str = "SimAgentPlg", + name: str = "ejagent", level: str = "INFO", fmt: str = "%(asctime)s | %(levelname)-8s | %(name)s | %(message)s", ) -> logging.Logger: @@ -32,7 +32,7 @@ def setup_logger( return logger -def get_logger(name: str = "SimAgentPlg") -> logging.Logger: +def get_logger(name: str = "ejagent") -> logging.Logger: """Return a configured logger by name. Args: diff --git a/src/simagentplg/middleware/__init__.py b/src/ejagent/middleware/__init__.py similarity index 88% rename from src/simagentplg/middleware/__init__.py rename to src/ejagent/middleware/__init__.py index 858e344..76d1b80 100644 --- a/src/simagentplg/middleware/__init__.py +++ b/src/ejagent/middleware/__init__.py @@ -1,6 +1,6 @@ """Composable middleware for core agent execution.""" -from simagentplg.middleware.base import ( +from ejagent.middleware.base import ( Middleware, ToolCallContext, ToolMiddleware, @@ -8,7 +8,7 @@ compose_tool_middlewares, format_tool_call_preview, ) -from simagentplg.middleware.policy import ( +from ejagent.middleware.policy import ( RuleBasedToolPolicy, ToolApprovalDecision, ToolApprovalRequest, @@ -20,7 +20,7 @@ ToolPolicyPredicate, ToolPolicyRule, ) -from simagentplg.middleware.validation import ( +from ejagent.middleware.validation import ( ToolSchemaConfigurationError, ToolSchemaValidationMiddleware, ) diff --git a/src/simagentplg/middleware/base.py b/src/ejagent/middleware/base.py similarity index 91% rename from src/simagentplg/middleware/base.py rename to src/ejagent/middleware/base.py index bc29dc7..af87a3e 100644 --- a/src/simagentplg/middleware/base.py +++ b/src/ejagent/middleware/base.py @@ -5,13 +5,13 @@ from dataclasses import dataclass from typing import TYPE_CHECKING, Any -from simagentplg.agent.types import StepOutcome +from ejagent.agent.types import StepOutcome if TYPE_CHECKING: - from simagentplg.agent.cancellation import CancellationToken - from simagentplg.agent.state import AgentState - from simagentplg.agent.types import ToolProgressReporter - from simagentplg.handlers.definition import ToolDefinition + from ejagent.agent.cancellation import CancellationToken + from ejagent.agent.state import AgentState + from ejagent.agent.types import ToolProgressReporter + from ejagent.handlers.definition import ToolDefinition @dataclass(frozen=True, slots=True) diff --git a/src/simagentplg/middleware/policy.py b/src/ejagent/middleware/policy.py similarity index 98% rename from src/simagentplg/middleware/policy.py rename to src/ejagent/middleware/policy.py index acc0d1b..8e256e8 100644 --- a/src/simagentplg/middleware/policy.py +++ b/src/ejagent/middleware/policy.py @@ -11,10 +11,10 @@ from types import MappingProxyType from typing import Any, Protocol -from simagentplg.agent.cancellation import AgentCancelledError -from simagentplg.agent.types import StepOutcome, ToolControl -from simagentplg.handlers.definition import ToolEffect -from simagentplg.middleware.base import ToolCallContext, ToolMiddleware, ToolNext +from ejagent.agent.cancellation import AgentCancelledError +from ejagent.agent.types import StepOutcome, ToolControl +from ejagent.handlers.definition import ToolEffect +from ejagent.middleware.base import ToolCallContext, ToolMiddleware, ToolNext logger = logging.getLogger(__name__) diff --git a/src/simagentplg/middleware/validation.py b/src/ejagent/middleware/validation.py similarity index 97% rename from src/simagentplg/middleware/validation.py rename to src/ejagent/middleware/validation.py index f5cd502..6860de6 100644 --- a/src/simagentplg/middleware/validation.py +++ b/src/ejagent/middleware/validation.py @@ -10,9 +10,9 @@ from referencing import Registry from referencing.exceptions import Unresolvable -from simagentplg.agent.types import StepOutcome -from simagentplg.handlers.definition import ToolDefinition -from simagentplg.middleware.base import ToolCallContext, ToolMiddleware, ToolNext +from ejagent.agent.types import StepOutcome +from ejagent.handlers.definition import ToolDefinition +from ejagent.middleware.base import ToolCallContext, ToolMiddleware, ToolNext class ToolSchemaConfigurationError(ValueError): diff --git a/src/ejagent/plugins/__init__.py b/src/ejagent/plugins/__init__.py new file mode 100644 index 0000000..afd4a6b --- /dev/null +++ b/src/ejagent/plugins/__init__.py @@ -0,0 +1,6 @@ +"""Plugin integrations for MCP services and local skills.""" + +from ejagent.plugins.mcp.mcp_manager import McpServerManager +from ejagent.plugins.skill.skill_manager import SkillManager + +__all__ = ["McpServerManager", "SkillManager"] diff --git a/src/simagentplg/plugins/mcp/mcp_manager.py b/src/ejagent/plugins/mcp/mcp_manager.py similarity index 98% rename from src/simagentplg/plugins/mcp/mcp_manager.py rename to src/ejagent/plugins/mcp/mcp_manager.py index 9192005..b8ffc36 100644 --- a/src/simagentplg/plugins/mcp/mcp_manager.py +++ b/src/ejagent/plugins/mcp/mcp_manager.py @@ -4,7 +4,7 @@ from pathlib import Path from typing import Any -from simagentplg.logger import get_logger +from ejagent.logger import get_logger logger = get_logger(name="MCP") @@ -42,7 +42,7 @@ async def startup(self) -> None: except ModuleNotFoundError as exc: raise RuntimeError( "MCP integration requires optional dependencies; " - "install SimAgentPlg[mcp]" + "install ejagent-core[mcp]" ) from exc stack = AsyncExitStack() diff --git a/src/simagentplg/plugins/skill/skill_manager.py b/src/ejagent/plugins/skill/skill_manager.py similarity index 99% rename from src/simagentplg/plugins/skill/skill_manager.py rename to src/ejagent/plugins/skill/skill_manager.py index 62f277d..8161433 100644 --- a/src/simagentplg/plugins/skill/skill_manager.py +++ b/src/ejagent/plugins/skill/skill_manager.py @@ -5,7 +5,7 @@ import yaml -from simagentplg.logger import get_logger +from ejagent.logger import get_logger logger = get_logger("skill") diff --git a/src/simagentplg/providers/__init__.py b/src/ejagent/providers/__init__.py similarity index 87% rename from src/simagentplg/providers/__init__.py rename to src/ejagent/providers/__init__.py index 9f98145..d0ca850 100644 --- a/src/simagentplg/providers/__init__.py +++ b/src/ejagent/providers/__init__.py @@ -1,6 +1,6 @@ """Model provider adapters for the agent core.""" -from simagentplg.providers.base import ( +from ejagent.providers.base import ( AssistantMessage, ContextOverflowError, ModelAdapter, @@ -16,7 +16,7 @@ ModelToolCall, ModelUsage, ) -from simagentplg.providers.openai import ModelConfig, OpenAIModelAdapter +from ejagent.providers.openai import ModelConfig, OpenAIModelAdapter __all__ = [ "AssistantMessage", diff --git a/src/simagentplg/providers/base.py b/src/ejagent/providers/base.py similarity index 98% rename from src/simagentplg/providers/base.py rename to src/ejagent/providers/base.py index c446fb9..32149b9 100644 --- a/src/simagentplg/providers/base.py +++ b/src/ejagent/providers/base.py @@ -7,8 +7,8 @@ from typing import TYPE_CHECKING, Any, TypeAlias if TYPE_CHECKING: - from simagentplg.agent.cancellation import CancellationToken - from simagentplg.agent.context_builder import ContextBuildResult + from ejagent.agent.cancellation import CancellationToken + from ejagent.agent.context_builder import ContextBuildResult class ModelErrorKind(StrEnum): diff --git a/src/simagentplg/providers/openai.py b/src/ejagent/providers/openai.py similarity index 98% rename from src/simagentplg/providers/openai.py rename to src/ejagent/providers/openai.py index 8f361b3..6d92155 100644 --- a/src/simagentplg/providers/openai.py +++ b/src/ejagent/providers/openai.py @@ -16,8 +16,8 @@ RateLimitError, ) -from simagentplg.agent.cancellation import AgentCancelledError -from simagentplg.providers.base import ( +from ejagent.agent.cancellation import AgentCancelledError +from ejagent.providers.base import ( AssistantMessage, ContextOverflowError, ModelAdapter, @@ -34,8 +34,8 @@ ) if TYPE_CHECKING: - from simagentplg.agent.cancellation import CancellationToken - from simagentplg.agent.context_builder import ContextBuildResult + from ejagent.agent.cancellation import CancellationToken + from ejagent.agent.context_builder import ContextBuildResult @dataclass(frozen=True, slots=True) diff --git a/src/simagentplg/py.typed b/src/ejagent/py.typed similarity index 100% rename from src/simagentplg/py.typed rename to src/ejagent/py.typed diff --git a/src/simagentplg/session/__init__.py b/src/ejagent/session/__init__.py similarity index 76% rename from src/simagentplg/session/__init__.py rename to src/ejagent/session/__init__.py index 687638b..d6ba0dc 100644 --- a/src/simagentplg/session/__init__.py +++ b/src/ejagent/session/__init__.py @@ -1,39 +1,39 @@ """Durable Agent Session projections built from lifecycle event trees.""" -from simagentplg.session.codec import ( +from ejagent.session.codec import ( SESSION_SCHEMA_VERSION, session_from_dict, session_to_dict, ) -from simagentplg.session.errors import ( +from ejagent.session.errors import ( SessionConflictError, SessionError, SessionLockTimeoutError, SessionSerializationError, SessionStorageError, ) -from simagentplg.session.journal import ( +from ejagent.session.journal import ( DEFAULT_SESSION_BRANCH, SESSION_JOURNAL_SCHEMA_VERSION, SessionRecord, SessionRecordDraft, SessionRecordKind, ) -from simagentplg.session.jsonl import JsonlSessionStorage -from simagentplg.session.memory import MemorySessionStorage -from simagentplg.session.recorder import SessionRecorder -from simagentplg.session.storage import ( +from ejagent.session.jsonl import JsonlSessionStorage +from ejagent.session.memory import MemorySessionStorage +from ejagent.session.recorder import SessionRecorder +from ejagent.session.storage import ( SessionJournalStorage, SessionStorage, SessionTreeStorage, ) -from simagentplg.session.tree import ( +from ejagent.session.tree import ( SessionBranch, SessionBranchIntent, SessionCheckout, SessionRetry, ) -from simagentplg.session.types import ( +from ejagent.session.types import ( AgentSession, SessionCompaction, SessionMessage, diff --git a/src/simagentplg/session/_file_lock.py b/src/ejagent/session/_file_lock.py similarity index 99% rename from src/simagentplg/session/_file_lock.py rename to src/ejagent/session/_file_lock.py index 3217ff2..50b0ff3 100644 --- a/src/simagentplg/session/_file_lock.py +++ b/src/ejagent/session/_file_lock.py @@ -11,7 +11,7 @@ from pathlib import Path from typing import Any -from simagentplg.session.errors import ( +from ejagent.session.errors import ( SessionLockTimeoutError, SessionStorageError, ) diff --git a/src/simagentplg/session/codec.py b/src/ejagent/session/codec.py similarity index 97% rename from src/simagentplg/session/codec.py rename to src/ejagent/session/codec.py index e4a0488..9a6c0d2 100644 --- a/src/simagentplg/session/codec.py +++ b/src/ejagent/session/codec.py @@ -4,11 +4,11 @@ from copy import deepcopy from typing import Any -from simagentplg.agent.compaction import SummaryEntry -from simagentplg.agent.result import AgentRunResult, RunStatus, StopReason -from simagentplg.agent.usage import RunUsage -from simagentplg.session.errors import SessionSerializationError -from simagentplg.session.types import ( +from ejagent.agent.compaction import SummaryEntry +from ejagent.agent.result import AgentRunResult, RunStatus, StopReason +from ejagent.agent.usage import RunUsage +from ejagent.session.errors import SessionSerializationError +from ejagent.session.types import ( AgentSession, SessionCompaction, SessionMessage, diff --git a/src/simagentplg/session/errors.py b/src/ejagent/session/errors.py similarity index 100% rename from src/simagentplg/session/errors.py rename to src/ejagent/session/errors.py diff --git a/src/simagentplg/session/journal.py b/src/ejagent/session/journal.py similarity index 98% rename from src/simagentplg/session/journal.py rename to src/ejagent/session/journal.py index 580ac58..676d465 100644 --- a/src/simagentplg/session/journal.py +++ b/src/ejagent/session/journal.py @@ -6,17 +6,17 @@ from enum import StrEnum from typing import Any -from simagentplg.agent.compaction import CompactionResult, SummaryEntry -from simagentplg.agent.result import AgentRunResult -from simagentplg.agent.types import AgentMessage -from simagentplg.session.codec import ( +from ejagent.agent.compaction import CompactionResult, SummaryEntry +from ejagent.agent.result import AgentRunResult +from ejagent.agent.types import AgentMessage +from ejagent.session.codec import ( agent_run_result_from_dict, agent_run_result_to_dict, session_from_dict, session_to_dict, ) -from simagentplg.session.errors import SessionSerializationError -from simagentplg.session.types import AgentSession +from ejagent.session.errors import SessionSerializationError +from ejagent.session.types import AgentSession SESSION_JOURNAL_SCHEMA_VERSION = 1 DEFAULT_SESSION_BRANCH = "main" diff --git a/src/simagentplg/session/jsonl.py b/src/ejagent/session/jsonl.py similarity index 99% rename from src/simagentplg/session/jsonl.py rename to src/ejagent/session/jsonl.py index 4150f47..53eb704 100644 --- a/src/simagentplg/session/jsonl.py +++ b/src/ejagent/session/jsonl.py @@ -12,26 +12,26 @@ from typing import Any, TypeVar from uuid import uuid4 -from simagentplg.session._file_lock import SessionFileLock -from simagentplg.session.errors import ( +from ejagent.session._file_lock import SessionFileLock +from ejagent.session.errors import ( SessionConflictError, SessionSerializationError, SessionStorageError, ) -from simagentplg.session.journal import ( +from ejagent.session.journal import ( DEFAULT_SESSION_BRANCH, SessionRecord, SessionRecordDraft, SessionRecordKind, apply_session_record, ) -from simagentplg.session.tree import ( +from ejagent.session.tree import ( SessionBranch, SessionBranchIntent, SessionCheckout, SessionRetry, ) -from simagentplg.session.types import AgentSession +from ejagent.session.types import AgentSession _ResultT = TypeVar("_ResultT") diff --git a/src/simagentplg/session/memory.py b/src/ejagent/session/memory.py similarity index 92% rename from src/simagentplg/session/memory.py rename to src/ejagent/session/memory.py index 3671874..90eebdb 100644 --- a/src/simagentplg/session/memory.py +++ b/src/ejagent/session/memory.py @@ -1,6 +1,6 @@ import asyncio -from simagentplg.session.types import AgentSession +from ejagent.session.types import AgentSession class MemorySessionStorage: diff --git a/src/simagentplg/session/recorder.py b/src/ejagent/session/recorder.py similarity index 95% rename from src/simagentplg/session/recorder.py rename to src/ejagent/session/recorder.py index 35a0efe..726f9f0 100644 --- a/src/simagentplg/session/recorder.py +++ b/src/ejagent/session/recorder.py @@ -1,6 +1,6 @@ import asyncio -from simagentplg.agent.events import ( +from ejagent.agent.events import ( AgentContinued, AgentEvent, AgentFinished, @@ -10,10 +10,10 @@ SteeringApplied, ToolCompleted, ) -from simagentplg.providers.base import serialize_assistant_message -from simagentplg.session.journal import DEFAULT_SESSION_BRANCH, SessionRecordDraft -from simagentplg.session.storage import SessionJournalStorage, SessionStorage -from simagentplg.session.types import AgentSession +from ejagent.providers.base import serialize_assistant_message +from ejagent.session.journal import DEFAULT_SESSION_BRANCH, SessionRecordDraft +from ejagent.session.storage import SessionJournalStorage, SessionStorage +from ejagent.session.types import AgentSession _RECORDED_PAYLOADS = ( AgentStarted, diff --git a/src/simagentplg/session/storage.py b/src/ejagent/session/storage.py similarity index 93% rename from src/simagentplg/session/storage.py rename to src/ejagent/session/storage.py index 7ee8730..089767a 100644 --- a/src/simagentplg/session/storage.py +++ b/src/ejagent/session/storage.py @@ -1,12 +1,12 @@ from typing import Protocol, runtime_checkable -from simagentplg.session.journal import ( +from ejagent.session.journal import ( DEFAULT_SESSION_BRANCH, SessionRecord, SessionRecordDraft, ) -from simagentplg.session.tree import SessionBranch, SessionCheckout, SessionRetry -from simagentplg.session.types import AgentSession +from ejagent.session.tree import SessionBranch, SessionCheckout, SessionRetry +from ejagent.session.types import AgentSession class SessionStorage(Protocol): diff --git a/src/simagentplg/session/tree.py b/src/ejagent/session/tree.py similarity index 93% rename from src/simagentplg/session/tree.py rename to src/ejagent/session/tree.py index 16c14ad..2a27c27 100644 --- a/src/simagentplg/session/tree.py +++ b/src/ejagent/session/tree.py @@ -3,8 +3,8 @@ from dataclasses import dataclass from enum import StrEnum -from simagentplg.session.journal import SessionRecord -from simagentplg.session.types import AgentSession +from ejagent.session.journal import SessionRecord +from ejagent.session.types import AgentSession class SessionBranchIntent(StrEnum): diff --git a/src/simagentplg/session/types.py b/src/ejagent/session/types.py similarity index 98% rename from src/simagentplg/session/types.py rename to src/ejagent/session/types.py index a4bdc17..bf846d4 100644 --- a/src/simagentplg/session/types.py +++ b/src/ejagent/session/types.py @@ -4,9 +4,9 @@ from dataclasses import dataclass, field, replace from enum import StrEnum -from simagentplg.agent.compaction import SummaryEntry -from simagentplg.agent.result import AgentRunResult -from simagentplg.agent.types import AgentMessage +from ejagent.agent.compaction import SummaryEntry +from ejagent.agent.result import AgentRunResult +from ejagent.agent.types import AgentMessage class SessionRunIntent(StrEnum): diff --git a/src/simagentplg/plugins/__init__.py b/src/simagentplg/plugins/__init__.py deleted file mode 100644 index 4df7171..0000000 --- a/src/simagentplg/plugins/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -"""Plugin integrations for MCP services and local skills.""" - -from simagentplg.plugins.mcp.mcp_manager import McpServerManager -from simagentplg.plugins.skill.skill_manager import SkillManager - -__all__ = ["McpServerManager", "SkillManager"] diff --git a/tests/package_artifact_smoke.py b/tests/package_artifact_smoke.py index 08b57e1..10eaba1 100644 --- a/tests/package_artifact_smoke.py +++ b/tests/package_artifact_smoke.py @@ -37,13 +37,19 @@ def main() -> None: with zipfile.ZipFile(wheel) as archive: names = archive.namelist() - if "simagentplg/py.typed" not in names: - raise AssertionError("wheel is missing simagentplg/py.typed") + if "ejagent/py.typed" not in names: + raise AssertionError("wheel is missing ejagent/py.typed") + if any(name.startswith("simagentplg/") for name in names): + raise AssertionError("wheel unexpectedly contains the legacy package") metadata_name = next( name for name in names if name.endswith(".dist-info/METADATA") ) metadata = archive.read(metadata_name).decode() + if "Name: ejagent-core\n" not in metadata: + raise AssertionError("wheel metadata has the wrong distribution name") + if "Version: 0.6.0\n" not in metadata: + raise AssertionError("wheel metadata has the wrong distribution version") if "Provides-Extra: mcp" not in metadata: raise AssertionError("wheel metadata does not declare the mcp extra") fastmcp_requirements = [ diff --git a/tests/public_api_smoke.py b/tests/public_api_smoke.py index 79f0da7..881692a 100644 --- a/tests/public_api_smoke.py +++ b/tests/public_api_smoke.py @@ -16,11 +16,13 @@ def main() -> None: if args.expect_no_mcp and importlib.util.find_spec("fastmcp") is not None: raise AssertionError("fastmcp must not be installed by the core package") + if importlib.util.find_spec("simagentplg") is not None: + raise AssertionError("the legacy simagentplg import must not be installed") - import simagentplg + import ejagent missing_attributes = [ - name for name in simagentplg.__all__ if not hasattr(simagentplg, name) + name for name in ejagent.__all__ if not hasattr(ejagent, name) ] if missing_attributes: raise AssertionError( @@ -87,25 +89,25 @@ def main() -> None: "session_to_dict", "session_from_dict", } - missing_exports = required_exports.difference(simagentplg.__all__) + missing_exports = required_exports.difference(ejagent.__all__) if missing_exports: raise AssertionError( f"required public exports are missing: {', '.join(sorted(missing_exports))}" ) - if not files("simagentplg").joinpath("py.typed").is_file(): + if not files("ejagent").joinpath("py.typed").is_file(): raise AssertionError("installed package is missing the py.typed marker") - if not version("SimAgentPlg"): - raise AssertionError("installed distribution has no version") + if version("ejagent-core") != "0.6.0": + raise AssertionError("installed distribution has the wrong version") if args.expect_no_mcp: async def check_missing_mcp_message() -> None: - manager = simagentplg.McpServerManager("unused.json") + manager = ejagent.McpServerManager("unused.json") try: await manager.startup() except RuntimeError as exc: - if "SimAgentPlg[mcp]" not in str(exc): + if "ejagent-core[mcp]" not in str(exc): raise AssertionError( "missing MCP dependencies produced no install guidance" ) from exc diff --git a/tests/test_agent.py b/tests/test_agent.py index 548ebae..0554c80 100644 --- a/tests/test_agent.py +++ b/tests/test_agent.py @@ -9,7 +9,7 @@ from typing import Any from unittest.mock import patch -from simagentplg import ( +from ejagent import ( AgentContextBuilder, AgentOrchestrator, AgentRunError, @@ -33,12 +33,12 @@ ToolMiddleware, ToolNext, ) -from simagentplg.agent.base import ( +from ejagent.agent.base import ( DEFAULT_SYSTEM_PROMPT, EXPLICIT_FINISH_PROTOCOL_PROMPT, TOOL_PROTOCOL_PROMPT, ) -from simagentplg.agent.orchestrator import TOOL_COMPLETION_RETRY_PROMPT +from ejagent.agent.orchestrator import TOOL_COMPLETION_RETRY_PROMPT TEST_CONFIG = ModelConfig( model="test-model", @@ -328,7 +328,7 @@ async def test_base_agent_owns_model_adapter_lifecycle(self) -> None: async def test_model_config_reads_chat_model_from_env(self) -> None: with ( - patch("simagentplg.providers.openai.load_dotenv"), + patch("ejagent.providers.openai.load_dotenv"), patch.dict( "os.environ", { diff --git a/tests/test_agent_cancellation.py b/tests/test_agent_cancellation.py index f38132b..e86ae11 100644 --- a/tests/test_agent_cancellation.py +++ b/tests/test_agent_cancellation.py @@ -3,7 +3,7 @@ import unittest from typing import Any -from simagentplg import ( +from ejagent import ( AgentEvent, AgentFinished, AgentStarted, diff --git a/tests/test_agent_continue.py b/tests/test_agent_continue.py index 00657c9..38082ba 100644 --- a/tests/test_agent_continue.py +++ b/tests/test_agent_continue.py @@ -3,7 +3,7 @@ import unittest from typing import Any -from simagentplg import ( +from ejagent import ( AgentContinued, AgentEvent, AgentFinished, diff --git a/tests/test_agent_events.py b/tests/test_agent_events.py index 9092060..e7d07ca 100644 --- a/tests/test_agent_events.py +++ b/tests/test_agent_events.py @@ -2,7 +2,7 @@ from dataclasses import FrozenInstanceError from typing import Any, get_type_hints -from simagentplg import ( +from ejagent import ( AgentEvent, AgentFinished, AgentStarted, diff --git a/tests/test_agent_follow_up.py b/tests/test_agent_follow_up.py index 0e7bb58..d109645 100644 --- a/tests/test_agent_follow_up.py +++ b/tests/test_agent_follow_up.py @@ -3,7 +3,7 @@ import unittest from typing import Any -from simagentplg import ( +from ejagent import ( AgentEvent, AgentFinished, AgentStarted, diff --git a/tests/test_agent_session.py b/tests/test_agent_session.py index 4d98c21..ed04fe5 100644 --- a/tests/test_agent_session.py +++ b/tests/test_agent_session.py @@ -1,7 +1,7 @@ import unittest from typing import Any -from simagentplg import ( +from ejagent import ( AgentEvent, AgentRunResult, AgentSession, diff --git a/tests/test_agent_steering.py b/tests/test_agent_steering.py index de4162f..93da522 100644 --- a/tests/test_agent_steering.py +++ b/tests/test_agent_steering.py @@ -3,7 +3,7 @@ import unittest from typing import Any -from simagentplg import ( +from ejagent import ( AgentEvent, AssistantMessage, BaseAgent, diff --git a/tests/test_agent_streaming.py b/tests/test_agent_streaming.py index 0a480b8..fdd22bf 100644 --- a/tests/test_agent_streaming.py +++ b/tests/test_agent_streaming.py @@ -4,7 +4,7 @@ from types import SimpleNamespace from typing import Any -from simagentplg import ( +from ejagent import ( AgentContextBuilder, AgentEvent, AgentFinished, diff --git a/tests/test_auto_compaction.py b/tests/test_auto_compaction.py index 1b46306..27673ee 100644 --- a/tests/test_auto_compaction.py +++ b/tests/test_auto_compaction.py @@ -3,7 +3,7 @@ from collections.abc import AsyncIterator, Mapping, Sequence from typing import Any -from simagentplg import ( +from ejagent import ( AgentEvent, AssistantMessage, AssistantTextDelta, @@ -249,7 +249,7 @@ async def test_pressure_compactor_failure_stops_safely(self) -> None: self.assertEqual(result.error, "summary provider failed") self.assertEqual(model.contexts, []) self.assertIn("old task", repr(agent.messages)) - self.assertNotIn("_simagentplg_summary", repr(agent.messages)) + self.assertNotIn("_ejagent_summary", repr(agent.messages)) async def test_abort_cancels_automatic_compaction(self) -> None: model = ScriptedStreamModel([completed()]) diff --git a/tests/test_behavior_hooks.py b/tests/test_behavior_hooks.py index 1d1cb0f..529f151 100644 --- a/tests/test_behavior_hooks.py +++ b/tests/test_behavior_hooks.py @@ -3,7 +3,7 @@ import unittest from typing import Any -from simagentplg import ( +from ejagent import ( AgentEvent, AgentFinished, AssistantMessage, diff --git a/tests/test_context_compaction.py b/tests/test_context_compaction.py index 3df6eab..bad662a 100644 --- a/tests/test_context_compaction.py +++ b/tests/test_context_compaction.py @@ -4,7 +4,7 @@ from copy import deepcopy from typing import Any -from simagentplg import ( +from ejagent import ( AgentEvent, AssistantMessage, BaseAgent, @@ -178,7 +178,7 @@ async def test_explicit_compaction_atomically_replaces_old_turns(self) -> None: ["system", "system", "user", "assistant"], ) summary_message = agent.messages[1] - self.assertIn("_simagentplg_summary", summary_message) + self.assertIn("_ejagent_summary", summary_message) self.assertNotIn("old-call", repr(agent.messages)) self.assertEqual( [type(event.payload) for event in sink.events], @@ -193,7 +193,7 @@ async def test_explicit_compaction_atomically_replaces_old_turns(self) -> None: await agent.run(task="continue from the summary") sent_summary = model.contexts[0].llm_messages[1] - self.assertNotIn("_simagentplg_summary", sent_summary) + self.assertNotIn("_ejagent_summary", sent_summary) self.assertIn("Conversation summary", sent_summary["content"]) async def test_compactor_failure_keeps_history_unchanged(self) -> None: @@ -345,7 +345,7 @@ async def test_repeated_compaction_replaces_and_merges_summary(self) -> None: "first summary", ) summary_messages = [ - message for message in agent.messages if "_simagentplg_summary" in message + message for message in agent.messages if "_ejagent_summary" in message ] self.assertEqual(len(summary_messages), 1) assert second.summary is not None @@ -423,7 +423,7 @@ async def test_session_restores_compacted_projection_and_new_runs( [message["role"] for message in session.messages], ["system", "user", "assistant", "user", "assistant"], ) - self.assertIn("_simagentplg_summary", session.messages[0]) + self.assertIn("_ejagent_summary", session.messages[0]) resumed_model = QueueModel(["resumed"]) resumed = BaseAgent( @@ -435,7 +435,7 @@ async def test_session_restores_compacted_projection_and_new_runs( llm_summary = resumed_model.contexts[0].llm_messages[1] self.assertIn("Conversation summary", llm_summary["content"]) - self.assertNotIn("_simagentplg_summary", llm_summary) + self.assertNotIn("_ejagent_summary", llm_summary) async def test_session_keeps_audit_entries_covered_by_compaction( self, diff --git a/tests/test_context_management.py b/tests/test_context_management.py index c883eb5..eb84db2 100644 --- a/tests/test_context_management.py +++ b/tests/test_context_management.py @@ -2,10 +2,12 @@ from collections.abc import Mapping, Sequence from typing import Any -from simagentplg import ( +from ejagent import ( + AgentContextBuilder, AgentEvent, AgentFinished, AgentStarted, + AgentState, AssistantMessage, BaseAgent, CancellationToken, @@ -51,6 +53,30 @@ async def complete( class ContextManagementTests(unittest.IsolatedAsyncioTestCase): + def test_context_builder_strips_current_and_legacy_internal_metadata(self) -> None: + state = AgentState( + messages=[ + { + "role": "system", + "content": "summary", + "_ejagent_summary": {"content": "current"}, + "_simagentplg_summary": {"content": "legacy"}, + } + ] + ) + + context = AgentContextBuilder().build(state) + + self.assertEqual( + context.agent_messages[0]["_ejagent_summary"], {"content": "current"} + ) + self.assertEqual( + context.agent_messages[0]["_simagentplg_summary"], + {"content": "legacy"}, + ) + self.assertNotIn("_ejagent_summary", context.llm_messages[0]) + self.assertNotIn("_simagentplg_summary", context.llm_messages[0]) + def test_heuristic_is_utf8_aware_and_ignores_usage_metadata(self) -> None: estimator = HeuristicMessageTokenEstimator() english = {"role": "user", "content": "a" * 40} @@ -65,10 +91,16 @@ def test_heuristic_is_utf8_aware_and_ignores_usage_metadata(self) -> None: } with_internal_summary = { **english, - "_simagentplg_summary": { + "_ejagent_summary": { "content": "internal metadata must not be counted" * 100, }, } + with_legacy_internal_summary = { + **english, + "_simagentplg_summary": { + "content": "legacy internal metadata must not be counted" * 100, + }, + } self.assertGreater( estimator.estimate_message(chinese), @@ -82,6 +114,10 @@ def test_heuristic_is_utf8_aware_and_ignores_usage_metadata(self) -> None: estimator.estimate_message(english), estimator.estimate_message(with_internal_summary), ) + self.assertEqual( + estimator.estimate_message(english), + estimator.estimate_message(with_legacy_internal_summary), + ) def test_estimate_without_usage_includes_messages_and_tools(self) -> None: estimate = estimate_context_usage( diff --git a/tests/test_examples.py b/tests/test_examples.py index cd9f67e..3fbbce6 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -2,7 +2,7 @@ import unittest from pathlib import Path -from simagentplg import MethodToolHandler, OpenAIModelAdapter, SkillManager +from ejagent import MethodToolHandler, OpenAIModelAdapter, SkillManager EXAMPLES_DIR = Path(__file__).parents[1] / "examples" diff --git a/tests/test_mcp_manager.py b/tests/test_mcp_manager.py index 0ae0be2..6096da4 100644 --- a/tests/test_mcp_manager.py +++ b/tests/test_mcp_manager.py @@ -3,7 +3,7 @@ from types import SimpleNamespace from typing import Any -from simagentplg.plugins.mcp.mcp_manager import McpServerManager +from ejagent.plugins.mcp.mcp_manager import McpServerManager class FakeMcpClient: diff --git a/tests/test_model_compactor.py b/tests/test_model_compactor.py index 1ec437a..a6d24b1 100644 --- a/tests/test_model_compactor.py +++ b/tests/test_model_compactor.py @@ -1,6 +1,6 @@ import unittest -from simagentplg import ( +from ejagent import ( AgentContextBuilder, AgentState, AssistantMessage, diff --git a/tests/test_parallel_tool_calls.py b/tests/test_parallel_tool_calls.py index 61ba796..bbff2b4 100644 --- a/tests/test_parallel_tool_calls.py +++ b/tests/test_parallel_tool_calls.py @@ -3,7 +3,7 @@ import unittest from typing import Any -from simagentplg import ( +from ejagent import ( AgentEvent, AssistantMessage, BaseAgent, diff --git a/tests/test_provider_errors.py b/tests/test_provider_errors.py index d13c73b..cdd49cf 100644 --- a/tests/test_provider_errors.py +++ b/tests/test_provider_errors.py @@ -3,7 +3,7 @@ import httpx from openai import APITimeoutError, AuthenticationError, RateLimitError -from simagentplg import ( +from ejagent import ( ContextOverflowError, ModelAuthenticationError, ModelErrorKind, @@ -11,7 +11,7 @@ ModelRateLimitError, ModelTimeoutError, ) -from simagentplg.providers.openai import _normalize_provider_error +from ejagent.providers.openai import _normalize_provider_error class StructuredProviderError(Exception): diff --git a/tests/test_session_persistence.py b/tests/test_session_persistence.py index 4644c2c..a2c3184 100644 --- a/tests/test_session_persistence.py +++ b/tests/test_session_persistence.py @@ -8,7 +8,7 @@ from typing import Any from unittest.mock import patch -from simagentplg import ( +from ejagent import ( SESSION_SCHEMA_VERSION, AgentRunResult, AgentSession, @@ -182,7 +182,7 @@ def start_append_process( import sys import time from pathlib import Path -from simagentplg import ( +from ejagent import ( JsonlSessionStorage, SessionConflictError, SessionRecordDraft, @@ -392,7 +392,7 @@ async def test_failed_append_preserves_previous_journal(self) -> None: with ( patch( - "simagentplg.session.jsonl.os.write", + "ejagent.session.jsonl.os.write", side_effect=OSError("disk failure"), ), self.assertRaises(SessionStorageError), @@ -410,7 +410,7 @@ async def test_separate_python_process_loads_saved_session(self) -> None: import asyncio import json import sys -from simagentplg import JsonlSessionStorage +from ejagent import JsonlSessionStorage async def main(): session = await JsonlSessionStorage(sys.argv[1]).load(sys.argv[2]) diff --git a/tests/test_tool_definitions.py b/tests/test_tool_definitions.py index 0bb8521..fcb26e7 100644 --- a/tests/test_tool_definitions.py +++ b/tests/test_tool_definitions.py @@ -2,7 +2,7 @@ from types import SimpleNamespace from typing import Any, cast -from simagentplg import ( +from ejagent import ( AgentContextBuilder, AgentState, AssistantMessage, diff --git a/tests/test_tool_policy.py b/tests/test_tool_policy.py index ebf3b74..1259166 100644 --- a/tests/test_tool_policy.py +++ b/tests/test_tool_policy.py @@ -5,7 +5,7 @@ import unittest from typing import Any -from simagentplg import ( +from ejagent import ( AssistantMessage, BaseAgent, CancellationToken, @@ -28,7 +28,7 @@ ToolPolicyMiddleware, ToolPolicyRule, ) -from simagentplg.agent.state import AgentState +from ejagent.agent.state import AgentState READ_TOOL = ToolDefinition( name="read", @@ -342,7 +342,7 @@ async def test_approval_exception_fails_closed(self) -> None: middlewares=[ToolPolicyMiddleware(policy, approver=RaisingApprover())], ) - with self.assertLogs("simagentplg.middleware.policy", level="ERROR"): + with self.assertLogs("ejagent.middleware.policy", level="ERROR"): outcome = await agent.dispatch("write", {"path": "/tmp/a"}) self.assertEqual(outcome.control.value, "reject") @@ -358,7 +358,7 @@ async def test_policy_exception_fails_closed(self) -> None: middlewares=[ToolPolicyMiddleware(RaisingPolicy())], ) - with self.assertLogs("simagentplg.middleware.policy", level="ERROR"): + with self.assertLogs("ejagent.middleware.policy", level="ERROR"): outcome = await agent.dispatch("read", {"path": "/tmp/a"}) self.assertEqual(outcome.control.value, "reject") diff --git a/tests/test_tool_progress.py b/tests/test_tool_progress.py index 28b790d..1af7bc8 100644 --- a/tests/test_tool_progress.py +++ b/tests/test_tool_progress.py @@ -3,7 +3,7 @@ from dataclasses import FrozenInstanceError from typing import Any -from simagentplg import ( +from ejagent import ( AgentEvent, AssistantMessage, BaseAgent, diff --git a/tests/test_tool_validation.py b/tests/test_tool_validation.py index 1e100a1..ce8714f 100644 --- a/tests/test_tool_validation.py +++ b/tests/test_tool_validation.py @@ -4,7 +4,7 @@ import unittest from typing import Any -from simagentplg import ( +from ejagent import ( AgentRunResult, AssistantMessage, BaseAgent, diff --git a/tests/test_usage_budget.py b/tests/test_usage_budget.py index 5cb5f44..a0e6bcb 100644 --- a/tests/test_usage_budget.py +++ b/tests/test_usage_budget.py @@ -3,7 +3,7 @@ from types import SimpleNamespace from typing import Any -from simagentplg import ( +from ejagent import ( AgentContextBuilder, AgentEvent, AgentState, diff --git a/uv.lock b/uv.lock index 605b32d..f646d7f 100644 --- a/uv.lock +++ b/uv.lock @@ -324,6 +324,50 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a7/5f/ed01f9a3cdffbd5a008556fc7b2a08ddb1cc6ace7effa7340604b1d16699/docstring_parser-0.18.0-py3-none-any.whl", hash = "sha256:b3fcbed555c47d8479be0796ef7e19c2670d428d72e96da63f3a40122860374b", size = 22484, upload-time = "2026-04-14T04:09:18.638Z" }, ] +[[package]] +name = "ejagent-core" +version = "0.6.0" +source = { editable = "." } +dependencies = [ + { name = "jsonschema" }, + { name = "openai" }, + { name = "python-dotenv" }, + { name = "pyyaml" }, + { name = "referencing" }, +] + +[package.optional-dependencies] +mcp = [ + { name = "fastmcp" }, +] + +[package.dev-dependencies] +dev = [ + { name = "mypy" }, + { name = "ruff" }, + { name = "types-jsonschema" }, + { name = "types-pyyaml" }, +] + +[package.metadata] +requires-dist = [ + { name = "fastmcp", marker = "extra == 'mcp'", specifier = ">=3.4.2" }, + { name = "jsonschema", specifier = ">=4.26.0" }, + { name = "openai", specifier = ">=2.41.0" }, + { name = "python-dotenv", specifier = ">=1.2.2" }, + { name = "pyyaml", specifier = ">=6.0.3" }, + { name = "referencing", specifier = ">=0.37.0" }, +] +provides-extras = ["mcp"] + +[package.metadata.requires-dev] +dev = [ + { name = "mypy", specifier = ">=1.18.2" }, + { name = "ruff", specifier = ">=0.14.0" }, + { name = "types-jsonschema", specifier = ">=4.26.0.20260518" }, + { name = "types-pyyaml", specifier = ">=6.0.12.20250915" }, +] + [[package]] name = "email-validator" version = "2.3.0" @@ -1375,50 +1419,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b7/46/f5af3402b579fd5e11573ce652019a67074317e18c1935cc0b4ba9b35552/secretstorage-3.5.0-py3-none-any.whl", hash = "sha256:0ce65888c0725fcb2c5bc0fdb8e5438eece02c523557ea40ce0703c266248137", size = 15554, upload-time = "2025-11-23T19:02:51.545Z" }, ] -[[package]] -name = "simagentplg" -version = "0.5.0" -source = { editable = "." } -dependencies = [ - { name = "jsonschema" }, - { name = "openai" }, - { name = "python-dotenv" }, - { name = "pyyaml" }, - { name = "referencing" }, -] - -[package.optional-dependencies] -mcp = [ - { name = "fastmcp" }, -] - -[package.dev-dependencies] -dev = [ - { name = "mypy" }, - { name = "ruff" }, - { name = "types-jsonschema" }, - { name = "types-pyyaml" }, -] - -[package.metadata] -requires-dist = [ - { name = "fastmcp", marker = "extra == 'mcp'", specifier = ">=3.4.2" }, - { name = "jsonschema", specifier = ">=4.26.0" }, - { name = "openai", specifier = ">=2.41.0" }, - { name = "python-dotenv", specifier = ">=1.2.2" }, - { name = "pyyaml", specifier = ">=6.0.3" }, - { name = "referencing", specifier = ">=0.37.0" }, -] -provides-extras = ["mcp"] - -[package.metadata.requires-dev] -dev = [ - { name = "mypy", specifier = ">=1.18.2" }, - { name = "ruff", specifier = ">=0.14.0" }, - { name = "types-jsonschema", specifier = ">=4.26.0.20260518" }, - { name = "types-pyyaml", specifier = ">=6.0.12.20250915" }, -] - [[package]] name = "sniffio" version = "1.3.1"