mirror of
https://github.com/stablyai/orca.git
synced 2026-10-17 00:03:08 +00:00
fix(linear): extract comment inline media before body truncation
Comment bodies are capped at 20k chars for output; extracting media from the truncated body dropped any screenshot past the cutoff. Extract from the full body in readComments and carry it on the comment node so aggregation surfaces it regardless of truncation.
This commit is contained in:
@@ -201,6 +201,44 @@ describe('Linear issue context includes', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('extracts comment media past the body truncation cap', async () => {
|
||||
const url = 'https://uploads.linear.app/w/file/late?sig=1'
|
||||
const body = `${'x'.repeat(20_001)}\n`
|
||||
rawRequest.mockResolvedValueOnce({
|
||||
data: {
|
||||
issue: {
|
||||
comments: {
|
||||
nodes: [{ id: 'comment-1', body }],
|
||||
pageInfo: { hasNextPage: false }
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
const { readOptionalIncludes } = await import('./issue-context-includes')
|
||||
const output = result()
|
||||
|
||||
await readOptionalIncludes(
|
||||
resolvedIssue(),
|
||||
requestWithComments(),
|
||||
output,
|
||||
[],
|
||||
output.meta.sections
|
||||
)
|
||||
|
||||
expect(output.comments?.[0]?.bodyTruncated).toBe(true)
|
||||
expect(output.comments?.[0]?.body).not.toContain(url)
|
||||
expect(output.comments?.[0]?.inlineMedia).toEqual([
|
||||
{
|
||||
source: 'comment',
|
||||
sourceId: 'comment-1',
|
||||
url,
|
||||
altText: 'late',
|
||||
fileName: 'late',
|
||||
linearUpload: true
|
||||
}
|
||||
])
|
||||
})
|
||||
|
||||
it('reads comment and child bodies through the signed public-file-url client', async () => {
|
||||
// Guards STA-1246: reverting to the plain entry client would return unsigned
|
||||
// uploads.linear.app URLs that 401 for agents.
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
LINEAR_RELATIONS_CAP,
|
||||
clampLinearIssueDepth
|
||||
} from '../../shared/linear-agent-access'
|
||||
import { extractLinearInlineMedia } from '../../shared/linear-inline-media'
|
||||
import type { ResolvedIssue } from './issue-context-client'
|
||||
import { getRequiredEntry, withLinearRead } from './issue-context-client'
|
||||
import { getPublicFileUrlClient } from './client'
|
||||
@@ -130,10 +131,14 @@ async function readComments(resolved: ResolvedIssue): Promise<{
|
||||
const nodes = response.nodes
|
||||
const items = nodes.slice(0, LINEAR_COMMENTS_CAP).map((comment) => {
|
||||
const body = comment.body ?? ''
|
||||
// Extract media from the full body before truncating so screenshots past
|
||||
// the body cap are still surfaced.
|
||||
const inlineMedia = extractLinearInlineMedia(body, 'comment', comment.id)
|
||||
return {
|
||||
id: comment.id,
|
||||
body: body.slice(0, LINEAR_COMMENT_BODY_CAP),
|
||||
bodyTruncated: body.length > LINEAR_COMMENT_BODY_CAP,
|
||||
...(inlineMedia.length > 0 ? { inlineMedia } : {}),
|
||||
createdAt: comment.createdAt,
|
||||
updatedAt: comment.updatedAt,
|
||||
parentId: comment.parent?.id ?? null,
|
||||
|
||||
@@ -108,8 +108,11 @@ export function collectInlineMedia(
|
||||
): LinearIssueContextResult['inlineMedia'] {
|
||||
const media = [
|
||||
...extractLinearInlineMedia(result.issue.description, 'description'),
|
||||
...(result.comments ?? []).flatMap((comment) =>
|
||||
extractLinearInlineMedia(comment.body, 'comment', comment.id)
|
||||
...(result.comments ?? []).flatMap(
|
||||
// Prefer media pre-extracted from the full (untruncated) comment body;
|
||||
// fall back to the stored body for callers that did not pre-extract.
|
||||
(comment) =>
|
||||
comment.inlineMedia ?? extractLinearInlineMedia(comment.body, 'comment', comment.id)
|
||||
),
|
||||
...(result.children ?? []).flatMap((child) => collectChildInlineMedia(child))
|
||||
]
|
||||
|
||||
@@ -44,6 +44,9 @@ export type LinearIssueCommentNode = {
|
||||
id: string
|
||||
body: string
|
||||
bodyTruncated: boolean
|
||||
// Extracted from the full comment body before truncation so media past the
|
||||
// body cap is not lost.
|
||||
inlineMedia?: LinearInlineMedia[]
|
||||
createdAt?: string | null
|
||||
updatedAt?: string | null
|
||||
parentId?: string | null
|
||||
|
||||
Reference in New Issue
Block a user