Skip to content

console AI chat: an uploaded image/PDF goes to the model and the agent puts that same file into the record's file field, as the user — ruled A #32749

Open

Description

@os-bob

Filing category: ② a decision only the maintainer can make.

维护者速读

  • 现象:员工最自然的做法是"把发票照片发给 AI,让它填报销单"。用外部 AI(Claude 等)走 MCP 时,照片在 AI 厂商那边,平台拿不到原文件,只能再发上传链接让人重选一次(storage + mcp: one upload link on a multiple: true file field accepts several files (same user, record, field, one use, same expiry) — ruled A #32747)。而平台自带的「问 AI」聊天,照片本来就是传到平台自己的页面里的,现在却直接回一句"当前仅支持读取表格类附件……这些文件的内容我没有读取"。
  • 要你裁:自带 AI 是否读取图片/PDF 附件,并把同一份上传直接写进它建的记录的文件字段(不再让人选第二次)。
  • 推荐:A:读取 + 直接附加,附加仍以当前用户身份、走记录的编辑门,图片与 PDF、限大小。

One-sentence problem

The one place where the photo's bytes are already inside the platform (the console's own chat) is the one place that refuses to look at it.

Evidence (reach)

  • ui/packages/app-shell/src/console/ai/AiChatPage.tsx doSend: files not matching \.(xlsx|xlsm|csv|tsv|txt)$ are not sent; the user's message gets (用户上传了 N 个附件:… — 当前仅支持读取表格类附件(Excel/CSV),这些文件的内容我没有读取。) (read at framework d7c3d44e).
  • External-client path measured on a hosted tenant (pnpm dev:stack --with-ui, cloud ff373e02): create_record → create_upload_link → user re-picks the file → read_file reads it back → run_action submits. Works, at the cost of re-picking every invoice.

Governing text

  • objectstack#30892 (closed): "An AI client sees an image the user attaches in its own chat, but it has no bytes to send." True for external clients; not true for the console chat, whose composer holds the File.
  • docs/NORTH-STAR.md: "Every step of the road must hold for both kinds of user."

Options

Option What it does What the customer sees Effort
A Console chat uploads image/PDF attachments to storage as the user (pending sys_file), sends them to the model as image/text parts, and lets the agent put that file id into a file field of a record it creates or edits (edit door as the user; only files this user uploaded in this conversation) "Here's my taxi receipt" → claim drafted with amount filled and the photo attached, nothing to pick twice ui + cloud AI seats · 2–3 PRs · precedent: spreadsheet attachments (cloud#797)
B Read only: the agent sees the photo and fills fields; attaching still goes through an upload link Fields filled, photo picked again ui + cloud AI seats · 1–2 PRs
C Keep declining non-spreadsheet attachments User types the numbers or uses the form none

Business reading: A makes the built-in assistant the shortest path for expenses, claims, contracts; B halves it; C keeps it a spreadsheet-only helper.

Recommendation

A. The bytes are already the user's own upload inside the platform, so attaching them raises none of #32747's provenance question (the user picked the file; the agent only routes it). Confidence gap: model vision cost per image and the size cap; recommend images ≤ 10 MiB, PDFs through the existing read_file text extraction.
Self-check: ①②③④ all pick A or B; only ④ alone would accept B first.

After the ruling

A: composer uploads non-spreadsheet attachments as pending files; the agent gets them as parts plus their file ids; a write that names such an id in a file field commits it; e2e: one photo in chat → a draft claim with the amount and the photo on invoices.

os-decision-facets
① 项目长远合理性: A 让文件只上传一次、由用户本人上传,复用现有文件字段和编辑门。
② 实际业务拉动: 报销(发票照片)是最常见的"拍照即录入"场景,本次实测用户第一反应就是把照片发给 AI。
③ 防 AI 犯错: A 只允许附加本人在本对话里上传的文件,agent 不能凭空造文件;读出的金额仍可用 read_file 复核。
④ 创业阶段不扩散: B 更小,A 多一步附加;都复用现有通道,不新增对外接口。
Prior rulings read: #30892 (external-client upload link); #32747 (open, one link for several files); thread: none

Reader who acts: the domain:ui seat (AiChatPage composer) and the cloud AI seat (agent message parts and the attach step), after the ruling.
Dedupe: repo:objectstack-ai/objectstack is:issue AI chat image attachment → 31 hits (#30892 closed, external clients; others PM seats); repo:objectstack-ai/cloud is:issue chat image attachment invoice photo → 0; Non-spreadsheet attachments chat → 0.

Activity

  1. added
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    on Nov 12, 2026
  2. objectstack-fleet commented on Nov 12, 2026

    @objectstack-fleet
    Contributor

    triage#1 · hotlong · session_01Q4EjjMnyLqJdzuktEmRPXH

    Path: none

    分诊首触 + 决策分析(fable 档独立评估)· 2026-11-12T16:56Z

    维护者速读

    • 员工把发票照片发给平台自带的「问 AI」,得到「只支持表格类附件」。拍照即录入是 AI 原生报销的标准形态,方向上应该做。
    • 卡里说的「先例」不成立:表格附件是在浏览器里解析的,字节从不离开页面;读照片则要把图片送到存储和模型厂商。这涉及视觉模型成本、套餐边界和数据出境。
    • 归属:应用内 AI 归 cloud 仓(ADR-0033 头注);objectstack 只有 AiChatPage.tsx 那一半。
    • 请裁:A 读取并把同一份上传挂到记录(排在 [Decision] How should an MCP agent create a record whose required file field must be filled (e.g. an expense line with a required e-invoice)? #32686 之后,决策部分转 cloud)/ B 只读取 / C 不做。推荐 A。

    是否已有裁决: 未找到(cloud 的 ADR 里没有图像或多模态相关条目)。

    前提核实:

    • ui/packages/app-shell/src/console/ai/AiChatPage.tsx:2196-2212:表格在客户端解析。
    • cloud 的 service-ai 里没有图像消息部件,所以这是新模态。
    选项 客户看到 工作量
    A 读取 + 挂载 发照片即得草稿报销单,照片已挂上 ui + cloud · 3–5 个 PR;无先例;挂载一步依赖 #32686
    B 只读取 字段已填,照片要再选一次 2–3 个 PR
    C 不做 手工录入 0

    四轴:

    • ① 长远:Expensify SmartScan、SAP Concur ExpenseIt、钉钉和飞书的智能报销都是拍照即录入,照片由用户本人上传。
    • ② 拉动:用户的第一反应就是发照片(实测一次)。
    • ③ 防 AI:只能挂本人在本对话里上传的文件,识别出的金额落为草稿,由人确认。
    • ④ 不扩散:新模态带来视觉成本和额度口径。

    推荐 A,排在 #32686 之后。置信缺口:每张图的成本、在哪些套餐开放、出境合规口径都未定。自检: 只看①选 A;④单看会选 B 或暂缓,不翻转。人工底线项:模型成本与套餐、图片出境。

    os-decision-facets

    Prior rulings read: objectstack ADR-0033 header (in-app AI is cloud's); cloud ADR-0005/0023 (model tiers); thread: none


    Generated by Claude Code

  3. added
    area:aiAI-native — agent / tool / skill metadata, and the MCP surface an agent drives
    domain:cloudTouches cloud: the whole card is the cloud PM's (repo:cloud seat); no objectstack lane claims it
    on Nov 12, 2026
  4. objectstack-fleet commented on Nov 13, 2026

    @objectstack-fleet
    Contributor

    triage#1 · hotlong · session_01Q4EjjMnyLqJdzuktEmRPXH

    Brief-claimed-by: session_01Q4EjjMnyLqJdzuktEmRPXH · batch #2 · 2026-11-13T04:45Z

    Decision batch #2, taken on the maintainer's 「5张一批按总监决裁格式给我」; batch #1 was answered 「以上原则同意」.

  5. objectstack-fleet commented on Nov 13, 2026

    @objectstack-fleet
    Contributor

    triage#1 · hotlong · session_01Q4EjjMnyLqJdzuktEmRPXH

    Ruling recorded · #32749 · A · 2026-11-13T05:19Z

    Maintainer, verbatim (triage#1 session): 「32677 暂停,先由元数据项目自己处理。其他同意」, answering decision batch #2 (proposed 32627 1B·2B·3A / 32749 A / 32979 A / 32677 B / 32688 C). The batch was analysed independently at the fable tier, with prior rulings checked first.


    Generated by Claude Code

  6. added
    pm:queueReady for the PM dispatch loop
    and removed
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    on Nov 13, 2026
  7. added
    priority:p0Queue-jump: outranks batch and breaks the round — never exempts claiming or same-file serial
    and removed on Nov 13, 2026
  8. os-bob commented on Nov 13, 2026

    @os-bob
    ContributorAuthor

    Re-grade on the maintainer's instruction: priority:p2 → priority:p0. State unchanged (pm:queue, domain:cloud, unassigned). Written by a test session, not a seat.


    Generated by Claude Code

  9. objectstack-fleet commented on Nov 13, 2026

    @objectstack-fleet
    Contributor

    triage#1 · hotlong · session_01Q4EjjMnyLqJdzuktEmRPXH

    Path: none

    Triage: p0 → p1 · not an 18.4.0 blocker · 2026-11-13T07:57Z

    ⛔ Not a claim; the claim and state are unchanged, and the work continues.


    Generated by Claude Code

  10. added
    priority:p1High: required for production / M2
    and removed
    priority:p0Queue-jump: outranks batch and breaks the round — never exempts claiming or same-file serial
    on Nov 13, 2026
  11. changed the title [-][Decision] Should the console's own AI chat read an invoice photo and attach that same upload to the record it files, instead of declining non-spreadsheet attachments?[/-] [+]console AI chat: an uploaded image/PDF goes to the model and the agent puts that same file into the record's file field, as the user — ruled A[/+] on Nov 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:aiAI-native — agent / tool / skill metadata, and the MCP surface an agent drivesdomain:cloudTouches cloud: the whole card is the cloud PM's (repo:cloud seat); no objectstack lane claims itpm:queueReady for the PM dispatch looppriority:p1High: required for production / M2

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions