replicas-engine 0.1.626 → 0.1.628
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/index.js +121 -71
- package/package.json +1 -1
package/dist/src/index.js
CHANGED
|
@@ -1586,35 +1586,8 @@ var GITLAB_ABILITY = {
|
|
|
1586
1586
|
referenceFile: { name: "GITLAB.md", content: REFERENCE4 }
|
|
1587
1587
|
};
|
|
1588
1588
|
|
|
1589
|
-
// ../shared/src/default-skills/replicas-agent/abilities/learnings.ts
|
|
1590
|
-
var SECTION5 = `### Learnings
|
|
1591
|
-
Propose additions, updates, or deletions to curated organization knowledge.
|
|
1592
|
-
|
|
1593
|
-
**Reference:** \`references/LEARNINGS.md\``;
|
|
1594
|
-
var REFERENCE5 = `# Learnings
|
|
1595
|
-
|
|
1596
|
-
Learnings are curated, human-approved knowledge entries your organization maintains: conventions, gotchas, environment facts, and process rules.
|
|
1597
|
-
|
|
1598
|
-
All writes are proposals: a human reviews them in the dashboard, and nothing takes effect until approved.
|
|
1599
|
-
|
|
1600
|
-
Use \`replicas learnings --help\` and subcommand help such as \`replicas learnings add --help\`, \`replicas learnings update --help\`, or \`replicas learnings delete --help\` for current command syntax.
|
|
1601
|
-
|
|
1602
|
-
A human approves every proposal before it takes effect, so don't agonize over borderline calls \u2014 but keep proposals genuinely useful rather than reflexive.
|
|
1603
|
-
|
|
1604
|
-
- Propose \`add\` for anything repeatable and org-useful: user corrections and preferences, hard-won environment or process knowledge, conventions and decisions worth following, and gotchas that would waste time again. If you learned it the hard way this task, capture it.
|
|
1605
|
-
- Never store task-specific details that won't recur, facts trivially derivable by reading the repo, or secrets/credentials.
|
|
1606
|
-
- Propose \`update\` or \`delete\` when a learning is contradicted by the current code or docs, especially if the outdated guidance would affect future repeated work.
|
|
1607
|
-
- Write narrow triggers describing when the entry should surface (e.g. "UI/UX work on the admin panel"), not vague topics.`;
|
|
1608
|
-
var LEARNINGS_ABILITY = {
|
|
1609
|
-
label: "Learnings",
|
|
1610
|
-
description: "Propose changes to curated org knowledge for human review.",
|
|
1611
|
-
bullet: "- Proposing changes to organization Learnings (curated, human-approved knowledge)",
|
|
1612
|
-
section: SECTION5,
|
|
1613
|
-
referenceFile: { name: "LEARNINGS.md", content: REFERENCE5 }
|
|
1614
|
-
};
|
|
1615
|
-
|
|
1616
1589
|
// ../shared/src/default-skills/replicas-agent/abilities/linear.ts
|
|
1617
|
-
var
|
|
1590
|
+
var SECTION5 = `### Linear
|
|
1618
1591
|
Fetch issues, update state, add comments, and search through the workspace-scoped TypeScript SDK.
|
|
1619
1592
|
|
|
1620
1593
|
**Reference:** \`references/LINEAR.md\`
|
|
@@ -1623,7 +1596,7 @@ Use this when:
|
|
|
1623
1596
|
- You encounter a Linear issue link and need to understand the task
|
|
1624
1597
|
- You need to update an issue's state or add a comment
|
|
1625
1598
|
- You need to search Linear issues`;
|
|
1626
|
-
var
|
|
1599
|
+
var REFERENCE5 = `# Linear Integration
|
|
1627
1600
|
|
|
1628
1601
|
Use \`@replicas/sdk\`; never request or handle a Linear OAuth token. Replicas refreshes the organization credential behind the gateway.
|
|
1629
1602
|
|
|
@@ -1673,12 +1646,12 @@ var LINEAR_ABILITY = {
|
|
|
1673
1646
|
label: "Linear",
|
|
1674
1647
|
description: "Fetch issues, comment, and update state through @replicas/sdk.",
|
|
1675
1648
|
bullet: "- Interacting with Linear (fetching issues, updating state, commenting, etc.)",
|
|
1676
|
-
section:
|
|
1677
|
-
referenceFile: { name: "LINEAR.md", content:
|
|
1649
|
+
section: SECTION5,
|
|
1650
|
+
referenceFile: { name: "LINEAR.md", content: REFERENCE5 }
|
|
1678
1651
|
};
|
|
1679
1652
|
|
|
1680
1653
|
// ../shared/src/default-skills/replicas-agent/abilities/media.ts
|
|
1681
|
-
var
|
|
1654
|
+
var SECTION6 = `### Media
|
|
1682
1655
|
Share screenshots, screen recordings, generated diagrams, audio clips, and self-contained HTML pages through Replicas and external messages.
|
|
1683
1656
|
|
|
1684
1657
|
**Reference:** \`references/MEDIA.md\`
|
|
@@ -1688,7 +1661,7 @@ Use this when:
|
|
|
1688
1661
|
- You produce a self-contained HTML report that should be linked from a pull request
|
|
1689
1662
|
- You record video output (browser automation, screen capture) \u2014 including the recommended aspect ratio and FPS
|
|
1690
1663
|
- You need to embed media in a Slack/Linear/GitHub message AND keep a referenceable copy in the Replicas dashboard`;
|
|
1691
|
-
var
|
|
1664
|
+
var REFERENCE6 = `# Media (Screenshots, Recordings, Audio, HTML)
|
|
1692
1665
|
|
|
1693
1666
|
This guide covers how to share screenshots, screen recordings, generated diagrams, audio clips, and self-contained HTML pages through Replicas and external surfaces (Slack, Linear, GitHub).
|
|
1694
1667
|
|
|
@@ -1994,12 +1967,12 @@ var MEDIA_ABILITY = {
|
|
|
1994
1967
|
label: "Media",
|
|
1995
1968
|
description: "Share screenshots, recordings, generated images, audio clips, and HTML pages.",
|
|
1996
1969
|
bullet: "- Producing or showing the user any media \u2014 screenshots, screen recordings, generated images or diagrams, audio clips, or HTML recap pages \u2014 including in your Replicas chat reply, PR descriptions/comments, and other external platforms",
|
|
1997
|
-
section:
|
|
1998
|
-
referenceFile: { name: "MEDIA.md", content:
|
|
1970
|
+
section: SECTION6,
|
|
1971
|
+
referenceFile: { name: "MEDIA.md", content: REFERENCE6 }
|
|
1999
1972
|
};
|
|
2000
1973
|
|
|
2001
1974
|
// ../shared/src/default-skills/replicas-agent/abilities/previews.ts
|
|
2002
|
-
var
|
|
1975
|
+
var SECTION7 = `### Previews
|
|
2003
1976
|
Expose locally running services (web apps, APIs, databases) as public preview URLs so humans can interact with them directly.
|
|
2004
1977
|
|
|
2005
1978
|
**Reference:** \`references/PREVIEWS.md\`
|
|
@@ -2008,7 +1981,7 @@ Use this when:
|
|
|
2008
1981
|
- You need to start a service that a human should view or interact with
|
|
2009
1982
|
- The task involves UI work that benefits from human review
|
|
2010
1983
|
- You are verifying frontend/backend integrations visually`;
|
|
2011
|
-
var
|
|
1984
|
+
var REFERENCE7 = `# Preview URLs
|
|
2012
1985
|
|
|
2013
1986
|
When you run services on ports \u2014 such as a web app, API server, or database \u2014 humans may want to interact with them directly. You can expose your locally running services as public preview URLs.
|
|
2014
1987
|
|
|
@@ -2084,12 +2057,12 @@ var PREVIEWS_ABILITY = {
|
|
|
2084
2057
|
label: "Previews",
|
|
2085
2058
|
description: "Expose locally running services on public preview URLs for humans.",
|
|
2086
2059
|
bullet: "- Creating preview URLs for locally running services",
|
|
2087
|
-
section:
|
|
2088
|
-
referenceFile: { name: "PREVIEWS.md", content:
|
|
2060
|
+
section: SECTION7,
|
|
2061
|
+
referenceFile: { name: "PREVIEWS.md", content: REFERENCE7 }
|
|
2089
2062
|
};
|
|
2090
2063
|
|
|
2091
2064
|
// ../shared/src/default-skills/replicas-agent/abilities/plugins.ts
|
|
2092
|
-
var
|
|
2065
|
+
var SECTION8 = `### Plugins
|
|
2093
2066
|
Discover and execute installed marketplace tools through the workspace-scoped TypeScript SDK.
|
|
2094
2067
|
|
|
2095
2068
|
**Reference:** \`references/PLUGINS.md\`
|
|
@@ -2104,7 +2077,7 @@ Use this when:
|
|
|
2104
2077
|
- The user asks for PlanetScale organizations, databases, branches, or Insights data
|
|
2105
2078
|
- The user asks to analyze text with Pangram
|
|
2106
2079
|
- The user asks for Stripe customers, payments, invoices, subscriptions, or balances`;
|
|
2107
|
-
var
|
|
2080
|
+
var REFERENCE8 = `# Plugins
|
|
2108
2081
|
|
|
2109
2082
|
Plugins are TypeScript libraries, not MCP servers. Import \`@replicas/sdk\`; Replicas authenticates the workspace and selects only the owner\u2019s personal connection or the organization fallback. Provider credentials, sessions, and project keys are never exposed.
|
|
2110
2083
|
|
|
@@ -2212,12 +2185,12 @@ var PLUGINS_ABILITY = {
|
|
|
2212
2185
|
label: "Plugins",
|
|
2213
2186
|
description: "Use installed marketplace tools through @replicas/sdk.",
|
|
2214
2187
|
bullet: "- Interacting with installed marketplace plugins through TypeScript",
|
|
2215
|
-
section:
|
|
2216
|
-
referenceFile: { name: "PLUGINS.md", content:
|
|
2188
|
+
section: SECTION8,
|
|
2189
|
+
referenceFile: { name: "PLUGINS.md", content: REFERENCE8 }
|
|
2217
2190
|
};
|
|
2218
2191
|
|
|
2219
2192
|
// ../shared/src/default-skills/replicas-agent/abilities/replicas.ts
|
|
2220
|
-
var
|
|
2193
|
+
var SECTION9 = `### Replicas (in-workspace CLI)
|
|
2221
2194
|
Take action *with* Replicas itself \u2014 manage automations, environments (variables, files), repos, and \`replicas.json\` config \u2014 using the pre-installed, pre-authenticated \`replicas\` CLI.
|
|
2222
2195
|
|
|
2223
2196
|
**Reference:** \`references/REPLICAS.md\`
|
|
@@ -2228,7 +2201,7 @@ Use this when:
|
|
|
2228
2201
|
- The user asks "what envs / repos / automations do I have?"
|
|
2229
2202
|
- The user asks you to scaffold a \`replicas.json\` / \`replicas.yaml\` in a repo
|
|
2230
2203
|
- You need to run a long-lived service (dev server, daemon) \u2014 always use \`replicas service start\` so it survives workspace sleep/wake`;
|
|
2231
|
-
var
|
|
2204
|
+
var REFERENCE9 = `# Replicas (in-workspace CLI)
|
|
2232
2205
|
|
|
2233
2206
|
This guide covers how to take action *with* Replicas itself from inside a Replicas workspace \u2014 managing automations, environments (and their variables/files), repos, previews, and the user's \`replicas.json\` config \u2014 using the pre-installed \`replicas\` CLI.
|
|
2234
2207
|
|
|
@@ -2455,13 +2428,13 @@ var REPLICAS_ABILITY = {
|
|
|
2455
2428
|
description: "Teach the agent about Replicas itself \u2014 automations, environments, the in-workspace CLI.",
|
|
2456
2429
|
// No bullet — help_instructions covers the `replicas` CLI surface in detail.
|
|
2457
2430
|
bullet: "",
|
|
2458
|
-
section:
|
|
2459
|
-
referenceFile: { name: "REPLICAS.md", content:
|
|
2431
|
+
section: SECTION9,
|
|
2432
|
+
referenceFile: { name: "REPLICAS.md", content: REFERENCE9 },
|
|
2460
2433
|
locked: true
|
|
2461
2434
|
};
|
|
2462
2435
|
|
|
2463
2436
|
// ../shared/src/default-skills/replicas-agent/abilities/sentry.ts
|
|
2464
|
-
var
|
|
2437
|
+
var SECTION10 = `### Sentry
|
|
2465
2438
|
Read issues and project data through the workspace-scoped TypeScript SDK.
|
|
2466
2439
|
|
|
2467
2440
|
**Reference:** \`references/SENTRY.md\`
|
|
@@ -2469,7 +2442,7 @@ Read issues and project data through the workspace-scoped TypeScript SDK.
|
|
|
2469
2442
|
Use this when:
|
|
2470
2443
|
- You need to inspect Sentry projects or issues
|
|
2471
2444
|
- A user asks for error-monitoring context outside a webhook-triggered task`;
|
|
2472
|
-
var
|
|
2445
|
+
var REFERENCE10 = `# Sentry Integration
|
|
2473
2446
|
|
|
2474
2447
|
Use \`@replicas/sdk\`; never request or read a Sentry token. Sentry access is organization-scoped and read-only.
|
|
2475
2448
|
|
|
@@ -2488,12 +2461,12 @@ var SENTRY_ABILITY = {
|
|
|
2488
2461
|
label: "Sentry",
|
|
2489
2462
|
description: "Read Sentry projects and issues through @replicas/sdk.",
|
|
2490
2463
|
bullet: "- Interacting with Sentry (reading projects, issues, and error context)",
|
|
2491
|
-
section:
|
|
2492
|
-
referenceFile: { name: "SENTRY.md", content:
|
|
2464
|
+
section: SECTION10,
|
|
2465
|
+
referenceFile: { name: "SENTRY.md", content: REFERENCE10 }
|
|
2493
2466
|
};
|
|
2494
2467
|
|
|
2495
2468
|
// ../shared/src/default-skills/replicas-agent/abilities/slack.ts
|
|
2496
|
-
var
|
|
2469
|
+
var SECTION11 = `### Slack
|
|
2497
2470
|
Send messages, read threads, search conversations, and upload files through the workspace-scoped TypeScript SDK.
|
|
2498
2471
|
|
|
2499
2472
|
**Reference:** \`references/SLACK.md\`
|
|
@@ -2502,7 +2475,7 @@ Use this when:
|
|
|
2502
2475
|
- You need to send a message to a Slack channel or thread
|
|
2503
2476
|
- You need to read or search Slack conversations
|
|
2504
2477
|
- You encounter a Slack message link and need its full thread`;
|
|
2505
|
-
var
|
|
2478
|
+
var REFERENCE11 = `# Slack Integration
|
|
2506
2479
|
|
|
2507
2480
|
Use \`@replicas/sdk\`; never read or send a Slack token directly. The SDK calls Replicas, which selects only this workspace's organization connection.
|
|
2508
2481
|
|
|
@@ -2575,8 +2548,8 @@ var SLACK_ABILITY = {
|
|
|
2575
2548
|
label: "Slack",
|
|
2576
2549
|
description: "Send messages, read threads, and search through @replicas/sdk.",
|
|
2577
2550
|
bullet: "- Interacting with Slack (sending messages, reading threads, etc.)",
|
|
2578
|
-
section:
|
|
2579
|
-
referenceFile: { name: "SLACK.md", content:
|
|
2551
|
+
section: SECTION11,
|
|
2552
|
+
referenceFile: { name: "SLACK.md", content: REFERENCE11 }
|
|
2580
2553
|
};
|
|
2581
2554
|
|
|
2582
2555
|
// ../shared/src/default-skills/replicas-agent/registry.ts
|
|
@@ -2586,7 +2559,6 @@ var REPLICAS_AGENT_ABILITY_REGISTRY = {
|
|
|
2586
2559
|
docker: DOCKER_ABILITY,
|
|
2587
2560
|
github: GITHUB_ABILITY,
|
|
2588
2561
|
gitlab: GITLAB_ABILITY,
|
|
2589
|
-
learnings: LEARNINGS_ABILITY,
|
|
2590
2562
|
linear: LINEAR_ABILITY,
|
|
2591
2563
|
media: MEDIA_ABILITY,
|
|
2592
2564
|
plugins: PLUGINS_ABILITY,
|
|
@@ -3315,7 +3287,8 @@ var workspaceChangedEventSchema = z2.discriminatedUnion("type", [
|
|
|
3315
3287
|
workspaceId: z2.string(),
|
|
3316
3288
|
completion: z2.object({
|
|
3317
3289
|
workspaceName: z2.string(),
|
|
3318
|
-
completedAt: z2.string()
|
|
3290
|
+
completedAt: z2.string(),
|
|
3291
|
+
processing: z2.boolean().optional()
|
|
3319
3292
|
}).optional(),
|
|
3320
3293
|
ts: z2.string()
|
|
3321
3294
|
}),
|
|
@@ -5375,6 +5348,63 @@ var MEDIA_KIND = {
|
|
|
5375
5348
|
var MEDIA_KINDS = [MEDIA_KIND.IMAGE, MEDIA_KIND.VIDEO, MEDIA_KIND.AUDIO, MEDIA_KIND.HTML];
|
|
5376
5349
|
var PUBLIC_MEDIA_KINDS = [MEDIA_KIND.IMAGE, MEDIA_KIND.VIDEO, MEDIA_KIND.AUDIO];
|
|
5377
5350
|
var MAX_ENGINE_LOG_BYTES = 50 * 1024 * 1024;
|
|
5351
|
+
function normalizeChatMessageSenders(value) {
|
|
5352
|
+
if (!Array.isArray(value)) return void 0;
|
|
5353
|
+
const senders = value.flatMap((sender) => {
|
|
5354
|
+
if (!isChatMessageSender(sender)) return [];
|
|
5355
|
+
const { senderUserId, senderEmail, senderDisplayName, senderAvatarUrl, recordedAt } = sender;
|
|
5356
|
+
return [{
|
|
5357
|
+
senderUserId,
|
|
5358
|
+
senderEmail,
|
|
5359
|
+
...typeof senderDisplayName === "string" ? { senderDisplayName } : {},
|
|
5360
|
+
...typeof senderAvatarUrl === "string" ? { senderAvatarUrl } : {},
|
|
5361
|
+
recordedAt
|
|
5362
|
+
}];
|
|
5363
|
+
});
|
|
5364
|
+
return senders;
|
|
5365
|
+
}
|
|
5366
|
+
function normalizeChatTranscriptMetadata(value) {
|
|
5367
|
+
if (!isRecord(value)) return {};
|
|
5368
|
+
const metadata = {};
|
|
5369
|
+
const {
|
|
5370
|
+
provider,
|
|
5371
|
+
title,
|
|
5372
|
+
createdAt,
|
|
5373
|
+
updatedAt,
|
|
5374
|
+
parentChatId,
|
|
5375
|
+
deletedAt,
|
|
5376
|
+
senders,
|
|
5377
|
+
captureId,
|
|
5378
|
+
captureReason,
|
|
5379
|
+
sha256
|
|
5380
|
+
} = value;
|
|
5381
|
+
if (typeof provider === "string" && isValidAgentProvider(provider)) metadata.provider = provider;
|
|
5382
|
+
if (typeof title === "string") metadata.title = title;
|
|
5383
|
+
if (typeof createdAt === "string") metadata.createdAt = createdAt;
|
|
5384
|
+
if (typeof updatedAt === "string") metadata.updatedAt = updatedAt;
|
|
5385
|
+
if (typeof parentChatId === "string" || parentChatId === null) metadata.parentChatId = parentChatId;
|
|
5386
|
+
if (typeof deletedAt === "string" || deletedAt === null) metadata.deletedAt = deletedAt;
|
|
5387
|
+
const normalizedSenders = normalizeChatMessageSenders(senders);
|
|
5388
|
+
if (normalizedSenders) metadata.senders = normalizedSenders;
|
|
5389
|
+
if (typeof captureId === "string") metadata.captureId = captureId;
|
|
5390
|
+
if (captureReason === "workspace_sleep") metadata.captureReason = captureReason;
|
|
5391
|
+
if (typeof sha256 === "string") metadata.sha256 = sha256;
|
|
5392
|
+
return metadata;
|
|
5393
|
+
}
|
|
5394
|
+
function parseChatTranscriptArtifact(value) {
|
|
5395
|
+
if (!isRecord(value) || typeof value.id !== "string" || typeof value.workspace_id !== "string" || value.kind !== "chat_transcript" || value.provider !== "s3" || typeof value.bucket !== "string" || typeof value.key !== "string" || typeof value.size !== "number" || typeof value.created_at !== "string") return null;
|
|
5396
|
+
return {
|
|
5397
|
+
id: value.id,
|
|
5398
|
+
workspace_id: value.workspace_id,
|
|
5399
|
+
kind: "chat_transcript",
|
|
5400
|
+
provider: "s3",
|
|
5401
|
+
bucket: value.bucket,
|
|
5402
|
+
key: value.key,
|
|
5403
|
+
size: value.size,
|
|
5404
|
+
metadata: normalizeChatTranscriptMetadata(value.metadata),
|
|
5405
|
+
created_at: value.created_at
|
|
5406
|
+
};
|
|
5407
|
+
}
|
|
5378
5408
|
|
|
5379
5409
|
// ../shared/src/memory.ts
|
|
5380
5410
|
var MEMORY_ROOT = `${SANDBOX_PATHS.REPLICAS_DIR}/memories`;
|
|
@@ -10972,7 +11002,7 @@ var DEFAULT_CODEX_ARGS = [
|
|
|
10972
11002
|
var MIN_CODEX_CLI_VERSION = "0.144.6";
|
|
10973
11003
|
var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
|
|
10974
11004
|
var codexCliVersionEnsured = null;
|
|
10975
|
-
var ENGINE_PACKAGE_VERSION = "0.1.
|
|
11005
|
+
var ENGINE_PACKAGE_VERSION = "0.1.628";
|
|
10976
11006
|
var INITIALIZE_METHOD = "initialize";
|
|
10977
11007
|
var INITIALIZED_NOTIFICATION = "initialized";
|
|
10978
11008
|
var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
|
|
@@ -15932,6 +15962,7 @@ async function reconcileCanvasItems(filenames) {
|
|
|
15932
15962
|
|
|
15933
15963
|
// src/services/upload-chat-transcripts.ts
|
|
15934
15964
|
import { createReadStream } from "fs";
|
|
15965
|
+
import { createHash as createHash2 } from "crypto";
|
|
15935
15966
|
import { readdir as readdir8, readFile as readFile14, stat as stat4 } from "fs/promises";
|
|
15936
15967
|
import { request as httpRequest } from "http";
|
|
15937
15968
|
import { request as httpsRequest } from "https";
|
|
@@ -15989,9 +16020,10 @@ async function putTranscript(uploadUrl, filePath, size) {
|
|
|
15989
16020
|
file.pipe(request);
|
|
15990
16021
|
});
|
|
15991
16022
|
}
|
|
15992
|
-
async function flushAllChatTranscripts(chatsById = /* @__PURE__ */ new Map()) {
|
|
16023
|
+
async function flushAllChatTranscripts(chatsById = /* @__PURE__ */ new Map(), capture) {
|
|
15993
16024
|
let flushed = 0;
|
|
15994
16025
|
let failed = 0;
|
|
16026
|
+
const revisions = [];
|
|
15995
16027
|
const tasks = [];
|
|
15996
16028
|
for (const dir of HISTORY_DIRS) {
|
|
15997
16029
|
let entries;
|
|
@@ -16004,8 +16036,9 @@ async function flushAllChatTranscripts(chatsById = /* @__PURE__ */ new Map()) {
|
|
|
16004
16036
|
if (!entry.endsWith(".jsonl")) continue;
|
|
16005
16037
|
const chatId = basename2(entry, ".jsonl");
|
|
16006
16038
|
tasks.push(
|
|
16007
|
-
uploadChatTranscript(chatId, join25(dir, entry), chatsById.get(chatId)).then(() => {
|
|
16039
|
+
uploadChatTranscript(chatId, join25(dir, entry), chatsById.get(chatId), capture).then((artifact) => {
|
|
16008
16040
|
flushed++;
|
|
16041
|
+
if (artifact && capture) revisions.push(artifact);
|
|
16009
16042
|
}).catch((err) => {
|
|
16010
16043
|
failed++;
|
|
16011
16044
|
console.error("[ChatTranscriptUploader] upload failed:", { chatId, err });
|
|
@@ -16014,11 +16047,11 @@ async function flushAllChatTranscripts(chatsById = /* @__PURE__ */ new Map()) {
|
|
|
16014
16047
|
}
|
|
16015
16048
|
}
|
|
16016
16049
|
await Promise.all(tasks);
|
|
16017
|
-
return { flushed, failed };
|
|
16050
|
+
return capture ? { flushed, failed, captureSupported: true, revisions } : { flushed, failed };
|
|
16018
16051
|
}
|
|
16019
|
-
async function uploadChatTranscript(chatId, filePath, chat) {
|
|
16052
|
+
async function uploadChatTranscript(chatId, filePath, chat, capture) {
|
|
16020
16053
|
const { size } = await stat4(filePath);
|
|
16021
|
-
if (size === 0) return;
|
|
16054
|
+
if (size === 0) return null;
|
|
16022
16055
|
const metadata = chat ? {
|
|
16023
16056
|
provider: chat.provider,
|
|
16024
16057
|
title: chat.title,
|
|
@@ -16027,6 +16060,13 @@ async function uploadChatTranscript(chatId, filePath, chat) {
|
|
|
16027
16060
|
parentChatId: chat.parentChatId,
|
|
16028
16061
|
deletedAt: chat.deletedAt ?? null
|
|
16029
16062
|
} : {};
|
|
16063
|
+
if (capture) {
|
|
16064
|
+
const hash = createHash2("sha256");
|
|
16065
|
+
for await (const chunk of createReadStream(filePath)) hash.update(chunk);
|
|
16066
|
+
metadata.captureId = capture.captureId;
|
|
16067
|
+
metadata.captureReason = capture.reason;
|
|
16068
|
+
metadata.sha256 = hash.digest("hex");
|
|
16069
|
+
}
|
|
16030
16070
|
try {
|
|
16031
16071
|
metadata.senders = parseChatMessageSendersJsonl(
|
|
16032
16072
|
await readFile14(chatMessageSendersFilePath(chatId), "utf-8")
|
|
@@ -16045,7 +16085,7 @@ async function uploadChatTranscript(chatId, filePath, chat) {
|
|
|
16045
16085
|
if (!isRecord(prepareBody) || typeof prepareBody.uploadUrl !== "string" && prepareBody.uploadUrl !== null) {
|
|
16046
16086
|
throw new Error("prepare failed: invalid response");
|
|
16047
16087
|
}
|
|
16048
|
-
if (prepareBody.uploadUrl === null) return;
|
|
16088
|
+
if (prepareBody.uploadUrl === null) return null;
|
|
16049
16089
|
await putTranscript(prepareBody.uploadUrl, filePath, size);
|
|
16050
16090
|
const finalizeResponse = await monolithRequest("/v1/engine/chat-transcripts/finalize", {
|
|
16051
16091
|
body: uploadRequest
|
|
@@ -16053,6 +16093,12 @@ async function uploadChatTranscript(chatId, filePath, chat) {
|
|
|
16053
16093
|
if (!finalizeResponse.ok) {
|
|
16054
16094
|
throw new Error(`finalize failed: ${finalizeResponse.status} ${await finalizeResponse.text()}`);
|
|
16055
16095
|
}
|
|
16096
|
+
const finalizeBody = await finalizeResponse.json();
|
|
16097
|
+
if (!isRecord(finalizeBody)) throw new Error("finalize failed: invalid response");
|
|
16098
|
+
if (finalizeBody.artifact === null) return null;
|
|
16099
|
+
const artifact = parseChatTranscriptArtifact(finalizeBody.artifact);
|
|
16100
|
+
if (!artifact) throw new Error("finalize failed: invalid artifact");
|
|
16101
|
+
return artifact;
|
|
16056
16102
|
}
|
|
16057
16103
|
|
|
16058
16104
|
// src/services/upload-repo-state.ts
|
|
@@ -16759,12 +16805,12 @@ var ChatService = class {
|
|
|
16759
16805
|
[...this.chats.entries()].map(([chatId, chat]) => [chatId, this.toSummary(chat)])
|
|
16760
16806
|
));
|
|
16761
16807
|
}
|
|
16762
|
-
async flushAllWorkspaceArtifacts() {
|
|
16808
|
+
async flushAllWorkspaceArtifacts(capture) {
|
|
16763
16809
|
const chatsById = new Map(
|
|
16764
16810
|
[...this.chats.entries()].map(([chatId, chat]) => [chatId, this.toSummary(chat)])
|
|
16765
16811
|
);
|
|
16766
16812
|
const [chatTranscripts, canvas, repoState, engineLogs, chatActivity] = await Promise.all([
|
|
16767
|
-
flushAllChatTranscripts(chatsById),
|
|
16813
|
+
flushAllChatTranscripts(chatsById, capture),
|
|
16768
16814
|
flushAllCanvasItems(),
|
|
16769
16815
|
flushRepoState(),
|
|
16770
16816
|
flushAllEngineLogs(),
|
|
@@ -17019,17 +17065,18 @@ var ChatService = class {
|
|
|
17019
17065
|
chat.activeMessageId = null;
|
|
17020
17066
|
this.agentChatActivityTrackerService.noteTurnEnded(chatId);
|
|
17021
17067
|
const completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
17068
|
+
const processing = chat.provider.getQueue().length > 0;
|
|
17022
17069
|
this.publish({
|
|
17023
17070
|
type: "chat.turn.completed",
|
|
17024
17071
|
payload: {
|
|
17025
17072
|
chatId,
|
|
17026
17073
|
isComplete: true,
|
|
17027
|
-
processing
|
|
17074
|
+
processing,
|
|
17028
17075
|
completedAt
|
|
17029
17076
|
}
|
|
17030
17077
|
}).catch(() => {
|
|
17031
17078
|
});
|
|
17032
|
-
monolithService.sendEvent({ type: "agent_response_complete", payload: { completedAt } }).catch(() => {
|
|
17079
|
+
monolithService.sendEvent({ type: "agent_response_complete", payload: { completedAt, processing } }).catch(() => {
|
|
17033
17080
|
});
|
|
17034
17081
|
uploadChatTranscript(
|
|
17035
17082
|
chatId,
|
|
@@ -17041,7 +17088,7 @@ var ChatService = class {
|
|
|
17041
17088
|
flushAllCanvasItems().catch((err) => {
|
|
17042
17089
|
console.error("[ChatService] Failed to upload canvas items:", { chatId, err });
|
|
17043
17090
|
});
|
|
17044
|
-
await this.publishAgentTurnCompleteWebhook(chat, completedAt);
|
|
17091
|
+
await this.publishAgentTurnCompleteWebhook(chat, completedAt, processing);
|
|
17045
17092
|
}
|
|
17046
17093
|
getRuntimeChat(chatId) {
|
|
17047
17094
|
const chat = this.chats.get(chatId) ?? null;
|
|
@@ -17123,7 +17170,7 @@ var ChatService = class {
|
|
|
17123
17170
|
} catch {
|
|
17124
17171
|
}
|
|
17125
17172
|
}
|
|
17126
|
-
async publishAgentTurnCompleteWebhook(chat, completedAt) {
|
|
17173
|
+
async publishAgentTurnCompleteWebhook(chat, completedAt, processing = false) {
|
|
17127
17174
|
await Promise.all([
|
|
17128
17175
|
githubTokenManager.refreshOnce().catch(() => {
|
|
17129
17176
|
}),
|
|
@@ -17156,6 +17203,7 @@ var ChatService = class {
|
|
|
17156
17203
|
const payload = {
|
|
17157
17204
|
...linearSessionId ? { linearSessionId } : {},
|
|
17158
17205
|
...completedAt ? { completedAt } : {},
|
|
17206
|
+
processing,
|
|
17159
17207
|
repoStatuses,
|
|
17160
17208
|
...errors?.length ? { errors } : {},
|
|
17161
17209
|
...errors?.length && errorNotificationTarget ? { errorNotificationTarget } : {}
|
|
@@ -18255,7 +18303,9 @@ function createV1Routes(deps) {
|
|
|
18255
18303
|
});
|
|
18256
18304
|
app2.post("/workspace-artifacts/flush-all", async (c) => {
|
|
18257
18305
|
try {
|
|
18258
|
-
const
|
|
18306
|
+
const body = await c.req.json().catch(() => void 0);
|
|
18307
|
+
const capture = body && typeof body.captureId === "string" && body.reason === "workspace_sleep" ? body : void 0;
|
|
18308
|
+
const result = await deps.chatService.flushAllWorkspaceArtifacts(capture);
|
|
18259
18309
|
return c.json(result);
|
|
18260
18310
|
} catch (error) {
|
|
18261
18311
|
return c.json(
|