Skip to content

fix: harden select/cancel orchestration and swagger uploader#542

Merged
samchon merged 7 commits into
mainfrom
fix/chat-ui
May 20, 2026
Merged

fix: harden select/cancel orchestration and swagger uploader#542
samchon merged 7 commits into
mainfrom
fix/chat-ui

Conversation

@samchon

@samchon samchon commented May 20, 2026

Copy link
Copy Markdown
Member

Summary

Hardens the select/cancel orchestration and the packages/chat swagger uploader.

fix(core)select.ts / cancel.ts left behind by the typia v12 migration

The typia v12 migration (#534) updated call.ts to the new lenient
IJsonParseResult API but only mechanically renamed JsonUtil.parse
FUNCTION.parse in select.ts / cancel.ts. Since FUNCTION.parse() now
returns an IJsonParseResult wrapper ({ success, data, errors }), the
as object cast hid the fact that the whole wrapper was passed to
FUNCTION.validate() instead of its .data.

Result: validation failed on every select/cancel call, burning all RETRY
attempts and feeding garbage back to the LLM via emendMessages.

Brought both files to parity with call.ts:

  • validate the parsed .data, never the IJsonParseResult wrapper
  • distinguish JSON parse failures from type validation failures (discriminated IFailure union)
  • feed JSON parse failures back to the LLM (JSON_PARSE_ERROR prompt + failure detail) — previously absent entirely
  • enrich validation feedback with the VALIDATE prompt + LlmJson.stringify annotated errors
  • use the lenient parser in PROCESS COMPLETION instead of strict typia.json.isParse, so leniently-accepted arguments are not silently dropped

fix(core) — feed back non-existent function references

__IChatFunctionReference.name is typed as plain string, so typia validation
cannot tell whether a referenced function actually exists. A hallucinated name
was silently dropped by selectFunctionFromContext / cancelFunctionFromContext
with no feedback and no retry.

After type validation passes, each referenced name is checked — select against
ctx.operations.flat, cancel against the current ctx.stack. Unresolved
references become synthetic IValidation.IErrors (path → the offending
functions[i].name, valid names listed in expected, instruction in
description) pushed as an IValidation.IFailure, so the existing
validation-feedback path reports them to the LLM and retries within the same
bounded retry budget.

fix(chat) — redundant strict OpenAPI validation in the swagger uploader

AgenticaChatUploaderMovie ran its own strict typia.validate() against the
union of all OpenAPI document types, rejecting real-world specs that the rest
of the pipeline (OpenApiConverter / HttpLlm) accepts leniently — surfacing
as an "invalid json" error dialog. It now parses the file and hands it
straight to OpenApiConverter.upgradeDocument, with distinct messages for
parse vs. conversion failures.

chore(deps)

Bump openai catalog to ^6.38.0.

Test plan

  • tsc full build of packages/core — passes
  • tsc -p tsconfig.app.json of packages/chat — passes
  • eslint on all changed files — passes
  • Runtime behaviour of select/cancel orchestration not exercised here (requires live LLM calls).

Known follow-ups (not in this PR)

  • IFailure, emendMessages and validateFunctionExistence are duplicated across select.ts / cancel.ts — this duplication is what let the fix(core): new typia for lenient json parsing and coercing. #534 regression slip through; extracting a shared helper would prevent recurrence.
  • On final retry exhaustion select/cancel still silently drop, whereas call.ts surfaces a success: false event.

🤖 Generated with Claude Code

samchon and others added 3 commits May 20, 2026 18:51
`select.ts` and `cancel.ts` were left behind by the typia v12 migration
(#534). `FUNCTION.parse()` now returns an `IJsonParseResult` wrapper, but
the code passed the whole wrapper to `FUNCTION.validate()` instead of its
`.data` - so validation always failed and every select/cancel call burned
all retries feeding garbage back to the LLM.

Bring both files to parity with `call.ts`:

- validate the parsed `.data`, never the `IJsonParseResult` wrapper
- distinguish JSON parse failures from type validation failures via a
  discriminated `IFailure` union
- feed JSON parse failures back to the LLM (`JSON_PARSE_ERROR` prompt plus
  failure detail), which was previously absent entirely
- enrich validation feedback with the `VALIDATE` prompt and annotated
  errors via `LlmJson.stringify`
- use the lenient parser in PROCESS COMPLETION instead of the strict
  `typia.json.isParse`, so leniently-accepted arguments are not silently
  dropped

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The uploader ran its own strict `typia.validate()` against the union of
all OpenAPI document types, rejecting real-world specs that the rest of
the pipeline (`OpenApiConverter` / `HttpLlm`) accepts leniently. Valid
documents triggered an "invalid json" error dialog.

Parse the file, then hand it straight to `OpenApiConverter.upgradeDocument`
- the same lenient converter `Agentica` relies on. Parse failures and
conversion failures are now reported with distinct, accurate messages.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 20, 2026 09:52
@pkg-pr-new

pkg-pr-new Bot commented May 20, 2026

Copy link
Copy Markdown

Open in StackBlitz

@agentica/benchmark

npm i https://pkg.pr.new/@agentica/benchmark@542

@agentica/chat

npm i https://pkg.pr.new/@agentica/chat@542

agentica

npm i https://pkg.pr.new/agentica@542

@agentica/core

npm i https://pkg.pr.new/@agentica/core@542

create-agentica

npm i https://pkg.pr.new/create-agentica@542

@agentica/rpc

npm i https://pkg.pr.new/@agentica/rpc@542

@agentica/vector-selector

npm i https://pkg.pr.new/@agentica/vector-selector@542

commit: 9e2f467

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes lenient JSON handling regressions in the core select/cancel orchestration introduced during the typia v12 migration, and makes the chat Swagger/OpenAPI uploader accept real-world specs by removing redundant strict validation. It also bumps the openai dependency catalog.

Changes:

  • Align select.ts / cancel.ts with call.ts by validating FUNCTION.parse(...).data (not the IJsonParseResult wrapper) and feeding parse/validation failures back to the LLM with clearer prompts.
  • Remove strict typia.validate() gating in the swagger uploader and rely on OpenApiConverter.upgradeDocument() for lenient conversion with better error messages.
  • Bump openai catalog to ^6.38.0 (and update lockfile).

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pnpm-workspace.yaml Bumps the workspace openai catalog version.
pnpm-lock.yaml Updates locked openai resolution to match the catalog bump.
packages/core/src/orchestrate/select.ts Fixes parse/validate flow for select orchestration and improves LLM-facing error feedback.
packages/core/src/orchestrate/cancel.ts Fixes parse/validate flow for cancel orchestration and improves LLM-facing error feedback.
packages/chat/src/examples/uploader/AgenticaChatUploaderMovie.tsx Removes redundant strict OpenAPI validation and improves parse vs conversion error handling.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

// by the VALIDATION retry above are processed consistently here.
const parsed: IJsonParseResult<unknown> = FUNCTION.parse(
tc.function.arguments,
);
// by the VALIDATION retry above are processed consistently here.
const parsed: IJsonParseResult<unknown> = FUNCTION.parse(
tc.function.arguments,
);
@samchon samchon changed the title fix: lenient JSON handling in select/cancel orchestration and swagger uploader fix(core): lenient JSON handling in select/cancel orchestration and swagger uploader May 20, 2026
@samchon samchon self-assigned this May 20, 2026
@samchon samchon added bug Something isn't working enhancement New feature or request labels May 20, 2026
@samchon samchon added this to WrtnLabs May 20, 2026
`__IChatFunctionReference.name` is typed as plain `string`, so typia
validation cannot tell whether a referenced function actually exists. A
hallucinated name was silently dropped by `selectFunctionFromContext` /
`cancelFunctionFromContext` with no feedback and no retry.

After type validation passes, check each referenced name - select against
`ctx.operations.flat`, cancel against the current `ctx.stack`. Unresolved
references become synthetic `IValidation.IError`s (`path` pointing at the
offending `functions[i].name`, the valid function names listed in
`expected`, a human-readable instruction in `description`) and are pushed
as an `IValidation.IFailure`, so the existing validation-feedback path
reports them to the LLM and retries within the same bounded retry budget.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@samchon samchon changed the title fix(core): lenient JSON handling in select/cancel orchestration and swagger uploader fix: harden select/cancel orchestration and swagger uploader May 20, 2026
samchon and others added 3 commits May 20, 2026 19:31
…e "{}"

`reduceStreamingWithDispatch` bootstrapped its accumulator by calling
`ChatGptCompletionMessageUtil.merge([acc, chunk])` on the first reduction
step. `merge` runs an empty-arguments fixup (`arguments === "" -> "{}"`)
that is only valid on a final completion: applied mid-stream it seeded a
still-incomplete tool call with `"{}"`, and every subsequent streamed
argument chunk was appended onto it, yielding `{}{"functions":...}`.

The agent could then never select a function - the corrupted arguments
parsed to `{}`, validation failed on every retry, and `select` produced
an empty selection so the chat returned no response.

Split `merge` into `mergeChunks` (raw accumulation) + `fixEmptyToolArguments`
(the fixup). Streaming now accumulates with `mergeChunks` and applies the
fixup exactly once, to the final completion.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@samchon
samchon merged commit f7e4a27 into main May 20, 2026
12 checks passed
@samchon
samchon deleted the fix/chat-ui branch May 20, 2026 10:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants