Skip to content

Guide Feishu sends during streaming card replies#506

Merged
evandance merged 2 commits into
larksuite:mainfrom
zhulijin1991:codex/lark-streaming-send-guidance
May 16, 2026
Merged

Guide Feishu sends during streaming card replies#506
evandance merged 2 commits into
larksuite:mainfrom
zhulijin1991:codex/lark-streaming-send-guidance

Conversation

@zhulijin1991
Copy link
Copy Markdown
Contributor

Summary

  • Add Feishu-owned shared message tool schema guidance for message / text.
  • Tell agents not to call send just to repeat or finalize the same answer while a normal Feishu streaming-card reply is active.
  • Keep send runtime behavior predictable by avoiding module-scope active-card rerouting.

Context

This supersedes #500. The earlier approach routed feishu.send through a process-local active-card map, which made empty-target sends implicit and fragile. This PR moves the fix to the tool-discovery layer instead.

Validation

  • pnpm vitest run tests/message-actions-schema.test.ts
  • pnpm exec tsc --noEmit
  • git diff --check

Copy link
Copy Markdown
Collaborator

@evandance evandance left a comment

Choose a reason for hiding this comment

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

Thanks for the rework — moving from runtime routing to the tool-discovery layer is exactly the right call, and the guidance text reads cleanly. One implementation detail to fix before merge.

The raw { type: 'string', description: ... } shape overrides the SDK base Type.Optional(Type.String()) for message: channel extraProperties are spread after the base in buildMessageToolSchemaProps, and without TypeBox's Optional marker both message and text become required across the shared message tool. send with only card/media, react, edit, read etc. would fail tool-input validation.

Bundled channels contribute real TypeBox schemas (Telegram, Slack, Discord all use Type.Optional(Type.X(...))). Switching to Type.Optional(Type.String({ description: FEISHU_SEND_TEXT_DESCRIPTION })) for both fields and dropping the as unknown as cast should do it. Extending the test to assert the composed tool schema's required does not include message or text would pin behavior against future merges.

@evandance evandance added feature request New feature or request messaging src/messaging/ + src/card/ — message rendering, cards, streaming changes requested Need do changes labels May 14, 2026
@zhulijin1991
Copy link
Copy Markdown
Contributor Author

Updated in e81fb62.

Changes:

  • Switched Feishu message / text schema contributions to Type.Optional(Type.String(...)).
  • Removed the as unknown as schema cast.
  • Added a composed TypeBox schema regression test asserting required does not include message or text.
  • Aligned the direct TypeBox dependency with the OpenClaw SDK version so the optional schema type-checks without a cast.

Validation:

  • pnpm test tests/message-actions-schema.test.ts
  • pnpm typecheck

Ready for re-review.

Copy link
Copy Markdown
Collaborator

@evandance evandance left a comment

Choose a reason for hiding this comment

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

Thanks for the rework — Type.Optional adoption, the satisfies-based contract, and the composed-schema regression test (asserting required excludes message/text) all land exactly the asks. The TypeBox version bump to align with the SDK is a nice extra. Approving.

@evandance evandance removed the changes requested Need do changes label May 16, 2026
@evandance evandance merged commit 6d95621 into larksuite:main May 16, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature request New feature or request messaging src/messaging/ + src/card/ — message rendering, cards, streaming

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants