Skip to content

feat: prepare combined chat, Official and Calls SDK counterparts - #357

Merged
purpshell merged 367 commits into
mainfrom
feat/console-chat-sdk-counterparts
Oct 22, 2026
Merged

purpshell merged 367 commits into
mainfrom
feat/console-chat-sdk-counterparts

Conversation

@purpshell

@purpshell purpshell commented Oct 19, 2026 •

Copy link
Copy Markdown
Member

This source-check candidate combines the reusable chat kit with the native SDK foundation, accepted credential fixtures, Official beta counterparts and Calls settings/types. The .NET cart decoder preserves API-valid wide quantities, and its regressions run by default. Rust WebhookDelivery::Single now contains Box<WebhookEvent>; manual construction uses Box::new(event).

Focused local checks passed at their recorded revisions. The PHP response fixture now allocates independent bodies, and the Rust catalog doctest has an explicit async client context. Validation of a98b69b on GitHub-hosted runners is pending; the failed 3f9866e wave does not qualify it. Packages are unpublished; registries and downstream pins remain held.

Historical local simulated-WhatsApp demo, SDK783bbe7 / evidence13ec0ac6; this does not validate the current candidate a98b69b: Console and Inspector video; recorded revisions and limits.

Keeps the later SDK360 integration free of a changelog conflict.
…ty QuickLink URLs

The Go, Python, PHP, Rust and ASP.NET example bridges passed the host's raw
receipt string where the chat kit expects an observed receipt object, so read
and delivered states never showed. They now map only receipts observed from
message.ack (delivered/delivery, read, played) on outbound messages, on load,
upsert and send. Send acceptance, inbound and unknown strings carry no receipt,
and the raw string still drives each example's status line. Native server code
is unchanged.

QuickLinkButton and <pmfa-quicklink-button> render nothing without a
development warning while the URL is missing or blank; a non-empty invalid URL
still renders nothing and warns once without the URL. The Elements README now
lists localhost and 127.0.0.1 like the React README.
@purpshell purpshell changed the title feat: move Console chat features into the reusable chat kit feat: prepare combined chat, Official and Calls SDK counterparts Oct 22, 2026
@purpshell
purpshell marked this pull request as ready for review October 22, 2026 11:09
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-22T11:24:47.910909Z 1964cc8 Draft marked ready
🔒 Security Review ✅ Completed 2026-10-22T11:13:47.973298Z 1964cc8 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@purpshell
purpshell merged commit 41e8afb into main Oct 22, 2026
15 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

const attachment = localAttachmentFromFile(file);

P2 Badge Preserve voice-note identity through upload

When the built-in recorder stops, the recording is converted to the same LocalAttachment shape as an ordinarily selected audio file, with no voice-note marker; the Web Components implementation does the same. Because the upload adapter receives no semantic distinction, its returned MessageAttachment cannot reliably set the new voice flag, and an outgoing adapter can send the recording as generic audio rather than a voice/PTT note. Carry an explicit voice-note flag through LocalAttachment, upload, and the outgoing draft instead of relying on the generated filename.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/release-gate.mjs
Comment on lines +126 to 128
validateFeatureContractPins(source, [
JSON.parse(readFileSync(join(root, "contracts/official-api-round2.json"))),
]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Validate the Official Platform pin before release

When this supplement is promoted by setting published and reconciling the baseline commit, this call validates only the top-level Messaging pin. The same supplement includes OA-30 Platform webhook changes under managementSource, but that Platform source path/hash is never compared with source.contracts.platform, so a mismatched management contract can pass the release gate and be published. Expand the supplement into both family pins, as is already done for the Calls supplement.

AGENTS.md reference: AGENTS.md:L22-L25

Useful? React with 👍 / 👎.

Comment on lines +207 to +211
return Err(Error::local(
ErrorKind::Authentication,
"Webhook signature verification failed.",
"invalid_webhook_signature",
));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve the Rust webhook-signature error kind

For any invalid signature passed to construct_event, this now returns ErrorKind::Authentication instead of the established ErrorKind::WebhookSignature; several branches of construct_local_event were changed similarly while other malformed inputs still use signature_error(). Rust callers matching the specialized kind will therefore miss common signature failures, and the classification depends on how the signature is malformed. Return signature_error() consistently, including from the new delivery constructor.

AGENTS.md reference: AGENTS.md:L14-L19

Useful? React with 👍 / 👎.

Comment on lines +532 to +535
from .cloud_order import CloudOrder as CloudOrder
from .cloud_order import CloudOrderItem as CloudOrderItem
from .official_round2 import (
CLOUD_READINESS_FAILURE_CODES as CLOUD_READINESS_FAILURE_CODES,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Add the new Python exports to all

These names are bound on the package module after the curated __all__ list is finalized, but none is appended to that list. Consequently from polymorfa import * omits every new Official round-2 public symbol (CloudOrder, Catalogs, delivery helpers, and related types), unlike the existing package surface. Add the new names to __all__ alongside the imports.

Useful? React with 👍 / 👎.

Comment on lines +291 to +294
var fields map[string]json.RawMessage
json.Unmarshal(member, &fields)
if _, ok := fields["object"]; ok {
return fail()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject only actual nested webhook batches

When a valid event envelope inside a batch carries an object extension whose value is not event_batch, this branch rejects the delivery solely because the key exists. OA-30 deliberately defines batch members with additionalProperties: true, and the TypeScript counterpart rejects only object === "event_batch"; the same presence-only check also appears in Python, PHP, Rust, and .NET. Check the value so only actual nested batches are invalid.

AGENTS.md reference: AGENTS.md:L14-L19

Useful? React with 👍 / 👎.


// ConversationReference accepts public IDs, E.164 phone numbers, or BSUIDs.
type ConversationReference struct {
ParentBSUID string `json:"parentBsuid,omitempty"`

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep parentBsuid out of send references

When a Go caller uses this shared ConversationReference in SendMessageRequest, setting the new ParentBSUID field serializes parentBsuid as a send target; the changed Python, .NET, and PHP send types expose the same invalid option. OA-18 defines parent BSUID as observation-only and explicitly says it cannot be used to send or block, while the API exposes parent_bsuid_not_supported for such requests. Split observed identities from outbound references and keep this field only on response, history, and event identities.

AGENTS.md reference: AGENTS.md:L14-L19

Useful? React with 👍 / 👎.


type CloudOrderItem struct {
ProductRetailerID string `json:"productRetailerId"`
Quantity int `json:"quantity"`

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use a fixed-width type for cart quantities

On 32-bit Go targets, int cannot hold API-valid cart quantities above 2147483647, so decoding a signed webhook, batch member, or history response containing a larger quantity fails even though this commit's quantity contract covers safe integers through 9007199254740991. Use int64 or uint64, as the Rust and .NET counterparts do, so the public Go model preserves the accepted range on every supported architecture.

AGENTS.md reference: AGENTS.md:L14-L19

Useful? React with 👍 / 👎.

Comment on lines +93 to +95
if (result.status === "failed") {
failed = { clientId: result.clientId ?? result.id, payload };
throw new Error(result.error ?? "Message send failed.");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reconcile inline retries with the retained composer draft

When a composer send fails, this throws after ConversationController has already retained a failed message, so the message list offers Retry while the composer keeps the same visible draft. If the user successfully invokes that inline retry and then presses the composer send button, the closure still retains the old failure but sees that its message is no longer failed, so it calls conversation.send and creates a duplicate. Clear or reconcile the retained draft when the external retry succeeds, or avoid exposing both retry paths for the same attempt.

Useful? React with 👍 / 👎.

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