Skip to content

fix(tools): accept numeric priority and the commentText alias - #264

Open
aa-blinov wants to merge 1 commit into
bitrix24:mainfrom
aa-blinov:fix/input-shape-leniency
Open

aa-blinov wants to merge 1 commit into
bitrix24:mainfrom
aa-blinov:fix/input-shape-leniency

Conversation

@aa-blinov

Copy link
Copy Markdown

Summary

Two input shapes an agent naturally sends: priority: 2 on b24_task_create (rejected by a string-only enum) and commentText on the elapsed-time write tools (silently dropped, because the read tool returns that name and Zod ignores unknown keys). Both accepted now; the wire payload for input that already worked is unchanged.

Type of change

  • feat
  • fix
  • docs
  • chore
  • test
  • refactor
  • ci

Linked issue

Checklist

  • PR title follows Conventional Commits
  • pnpm lint passes
  • pnpm typecheck passes
  • pnpm test passes
  • New or changed code has tests
  • Public-facing changes reflected in docs/ and skills/ (tool descriptions updated in place; no convention change, so the authoring docs need no edit)
  • No unrelated changes
  • No secrets in code, tests, or CI logs

Screenshots / logs

priority as a number, before:

b24_task_create { title: "…", responsibleId: 9, groupId: 1, priority: 2 }
→ ERR  Input validation error: [{ "code": "invalid_value",
        "values": ["0","1","2"], "path": ["priority"],
        "message": "Invalid option: expected one of \"0\"|\"1\"|\"2\"" }]

After: {"created": true, "id": "4195", …}, with PRIORITY: "2" on the wire.

commentText, before — no error, and the note is gone:

b24_task_elapsed_time_add { taskId: 4193, seconds: 3600, commentText: "QA: час работы" }
→ {"added": true, "id": 7483, "seconds": 3600}
b24_task_elapsed_time_list { taskId: 4193 }
→ entries[0].commentText === ""

After:

b24_task_elapsed_time_add { taskId: 4193, seconds: 600, commentText: "алиас работает" }
→ {"added": true, "id": 7487, "comment": "алиас работает"}
b24_task_elapsed_time_list { taskId: 4193 }
→ entries[0].commentText === "алиас работает"

Notes for reviewers

Both are small, but they share a shape worth naming: the schema was stricter than the agent's natural guess, and in one case the strictness was silent.

On priority — the enum was presumably chosen because Bitrix24 wants a string. That's still what goes on the wire; the union just stops the tool from being the only place in the task API where a number isn't a number. If you'd rather keep one canonical form, z.coerce.string().pipe(z.enum([...])) would also work, but it accepts "true"-ish junk more readily than an explicit union, so I went with the union.

On the alias — the asymmetry is inherited from Bitrix24 (COMMENT_TEXT on the wire, comment in the tool schema), and I did not rename anything: comment stays the documented field, commentText is an accepted alias with a .describe() that says so. The alternative would be renaming the read-side projection to comment, which is a breaking change for anyone parsing the list output, so an alias seemed like the cheaper direction. Happy to flip it if you'd rather converge on one name.

There is a third instance of the same class I did not touch, since it's arguably intended: b24_task_update takes UPPERCASE fields keys while b24_task_list accepts camelCase filters. Worth a decision at some point, but not in a bug-fix PR.

Two input shapes an agent naturally sends, one rejected outright and one
silently dropped. Both surfaced while running every tool against a live
portal.

`b24_task_create` declared `priority` as `z.enum(['0','1','2'])`, so
`priority: 2` — the obvious thing to write next to `responsibleId: 9` and
`groupId: 1`, both numbers — failed validation with
`Invalid option: expected one of "0"|"1"|"2"`. It now takes a number or
the string and normalises to the string Bitrix24 wants on the wire.

`b24_task_elapsed_time_list` returns the note as `commentText`
(Bitrix24's COMMENT_TEXT), while add / update call the same field
`comment`. Zod drops unknown keys, so an agent that lists entries and
reuses the name it just read gets no error and no note:

  b24_task_elapsed_time_add { taskId: 4193, seconds: 3600,
                              commentText: "QA: час работы" }
  → {"added": true, ...}
  b24_task_elapsed_time_list { taskId: 4193 }
  → entries[0].commentText === ""        ← the note is gone

On update the same mix-up hit the "no changes" refusal instead, which at
least fails loudly but still blames the operator for something the
schema did. Both write tools now accept `commentText` as an alias of
`comment`, preferring `comment` when both are supplied.

Neither change alters the wire payload for input that already worked.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant