Repository navigation
Promptise Foundry 1.9.0
Runtime processes can pick their reasoning pattern. Traces keep the tenant and the session, record tool arguments as data and show refused calls and approval decisions. Plus fixes for promptise run --check with agent factories and a Prompt that reached the model twice.
Upgrade notes
- A
tool.callentry'smetadata["arguments"]is JSON data, not text. It was the Python repr of the call ("{'sku': 'MS-30'}"); it is now a dict for a structured call ({"sku": "MS-30"}), with nested models as objects, and stays text only for a tool given plain text. Code that parsed the string should read the dict. Long strings are still cut at 2,000 characters, now per value. The OTLP span attributepromptise.argumentsis now JSON text. collector.purge_user("alice")andfor_user("alice")no longer reach a tenant'salice. Without a tenant they match only entries recorded without one, asMemoryProvider.purge_userdoes. Passtenant_id=or the isolation key ("acme::alice") for a tenant's user;purge_userlogs a warning when it kept entries of a tenant's user with that id. The signatures are unchanged apart from the new keyword.collector.get_users()lists isolation keys:"acme::alice"for a user with a tenant (it was"alice"for every tenant). Users without a tenant are listed as before.AuditMiddleware(include_args=True)writes a nested Pydantic argument as a JSON object, not itsstr()("sku='MS-30' qty=2"); dataclasses, dates and sets get their JSON form too. Existing log files still verify.StructuredLoggingMiddleware(include_args=True)does the same.promptise runstats payloads have new keys:totals.tool_deniedand adeniedcount per tool. Code that compared a tool row exactly needs updating.- A
Promptused as instructions now comes before other system messages -- before, it came after the first system message in the input (for examplechat(system_prompt=...)). Check prompts that relied on the old order. - With a context engine, a
Prompt's context providers run on every call -- before, only the build-time render was sent. Providers that are slow or have side effects now run once per call.
Added
ProcessConfig(agent_pattern=...)-- choose the reasoning pattern of a runtime process, so a run started by a cron schedule or a webhook can use"peoatr","research"or any other name fromAGENT_PATTERNS(or, in code, aPromptGraph). An unknown name fails when the config is created..agentmanifests set it with a top-levelagent_pattern:key. Before,ProcessConfigrefused the key and every process ran the default ReAct loop.TimelineEntry.tenant_idandTimelineEntry.isolation_key-- every trace entry records the caller's tenant next to its user id.for_user()andpurge_user()taketenant_id=(or the"tenant::user"key),query()takestenant_ids=, and the OTLP transporter setspromptise.tenant_id.- Refused tool calls on the trace -- a call the autonomy budget refuses, or an approval gate denies, is a
tool.call/tool.resultwithstatus="denied",denied_byand thereason.get_stats()counts them astool_denied_count, andpromptise run --devtoolsprints them and counts them in its summary.
Fixed
- Two tenants' users with the same id merged in traces -- entries stored
caller.user_idonly, soacme'saliceandglobex'salicewere one user, andpurge_user("alice")deleted both. chat(session_id=...)left the session empty in traces -- every entry of the run now carries it.- A call refused by the autonomy budget was missing from traces and
--devtools-- withmax_irreversible_per_run=3, the 4th call reached only the journal (tool_denied) and thepermission_deniedhook. approval.*events reached the event notifier but not the timeline --approval.requested,approval.grantedandapproval.deniedare now recorded on the observed run (aCALLBACKtransporter,--devtools), with a newapproval.timeoutentry, and a denied call'stool.resultsaysstatus="denied"instead of looking like a successful call.promptise run --checkfailed for an agent factory in a package -- withagent = "customer_agent.agent:create_agent",promptise run --mode chat --checkreported "No module named 'customer_agent'" while the real run worked, because the check imported the factory before it put the project root onsys.path.--checknow adds the project root and thepython_pathentries first, the same way the run does.- A
Promptasbuild_agent(instructions=...)reached the model twice -- its build-time render was the graph's system prompt, and the per-request render (with the context providers) was added as a second system message, so every block was sent twice on every call. The model now gets the per-request render once, as the start of its one system message, after a conversation flow's prompt and before the tool list. If the render fails or is empty, the build-time render is sent instead. astream(),astream_with_tools()and the context-engine path skipped aPrompt's context providers -- they sent only the build-time render. They now send the per-request render too.- A
PromptSuiteas instructions sent<MySuite prompts=N>as a system message -- its build-time text was the suite'srepr. It is nowsuite.system_prompt(), used for the cache key, the context engine'sidentitybudget and the fallback.
Full changelog: https://docs.promptise.com/resources/changelog/