@meistrari/remy-cli 1.15.0 → 1.16.0
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/README.md +3 -0
- package/dist/remy.js +149 -43
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -54,6 +54,8 @@ Published files and Tela Pages appear in the timeline. File artifacts include th
|
|
|
54
54
|
|
|
55
55
|
When Remy creates a plan, the session shows its checklist in the timeline and keeps `Plan <done>/<total>` with the current item pinned above the composer. Updates change the same checklist instead of producing repeated rows, and an unfinished plan remains visible after reconnecting or between turns. The collapsed timeline shows up to five plan items; press `Ctrl+O` for the complete checklist and activity detail.
|
|
56
56
|
|
|
57
|
+
Enter `/compact` to admit a durable main-thread context compaction control without sending a human message. Remy reports request admission immediately and shows the eventual completed, no-op, failed, or unknown provider result in retained activity. Compaction waits for a safe point and does not interrupt active work or jump ahead of an earlier Next message.
|
|
58
|
+
|
|
57
59
|
Drag to select visible text in any Remy view; Remy copies it to the local clipboard and emits OSC 52 for terminal or remote-session clipboard support, then clears the selection highlight. Published file artifacts show their filename and muted, full web preview URL; open the URL in a browser to select that artifact in its session. Tela Page rows retain their canonical Page URL. Remy does not fetch or print artifact bytes. When the conversation has focus, press `Tab` to return to the composer.
|
|
58
60
|
|
|
59
61
|
| Control | Result |
|
|
@@ -61,6 +63,7 @@ Drag to select visible text in any Remy view; Remy copies it to the local clipbo
|
|
|
61
63
|
| `Esc` | Interrupt the active turn; the session stays open. |
|
|
62
64
|
| `/complete` | Complete an open session after its active turn stops. |
|
|
63
65
|
| `/cancel` | Cancel the current session, including an active turn. |
|
|
66
|
+
| `/compact` | Admit a main-thread context compaction request without sending a message; the provider result appears in retained activity. |
|
|
64
67
|
| `/sessions` | Return to the dashboard. |
|
|
65
68
|
| `/new` | Start another new-session flow. |
|
|
66
69
|
| `/logout` | Sign out of Remy after confirmation. |
|
package/dist/remy.js
CHANGED
|
@@ -32214,6 +32214,10 @@ var interruptAgentCommandSchema = runningCommandBaseSchema.extend({
|
|
|
32214
32214
|
turnId: zod_default2.string().min(1).optional(),
|
|
32215
32215
|
reason: zod_default2.string().min(1).optional()
|
|
32216
32216
|
}).strict();
|
|
32217
|
+
var compactContextAgentCommandSchema = runningCommandBaseSchema.extend({
|
|
32218
|
+
type: zod_default2.literal("agent.compact-context"),
|
|
32219
|
+
commandId: commandIdSchema
|
|
32220
|
+
}).strict();
|
|
32217
32221
|
var stopAgentCommandSchema = runningCommandBaseSchema.extend({
|
|
32218
32222
|
type: zod_default2.literal("agent.stop"),
|
|
32219
32223
|
reason: zod_default2.string().min(1).optional()
|
|
@@ -32227,6 +32231,7 @@ var respondUserInputAgentCommandSchema = runningCommandBaseSchema.extend({
|
|
|
32227
32231
|
var agentCommandSchema = zod_default2.union([
|
|
32228
32232
|
sendPromptCommandSchema,
|
|
32229
32233
|
interruptAgentCommandSchema,
|
|
32234
|
+
compactContextAgentCommandSchema,
|
|
32230
32235
|
stopAgentCommandSchema,
|
|
32231
32236
|
respondUserInputAgentCommandSchema
|
|
32232
32237
|
]);
|
|
@@ -32420,6 +32425,12 @@ var agentTurnEndStatusSchema = zod_default2.enum(["completed", "failed", "cancel
|
|
|
32420
32425
|
var agentSubagentStatusSchema = zod_default2.enum(["completed", "failed", "cancelled"]);
|
|
32421
32426
|
var agentContextCompactionTriggerSchema = zod_default2.enum(["manual", "auto", "unknown"]);
|
|
32422
32427
|
var agentContextCompactionStatusSchema = zod_default2.enum(["completed", "failed"]);
|
|
32428
|
+
var agentContextCompactionRequestResultSchema = zod_default2.discriminatedUnion("status", [
|
|
32429
|
+
zod_default2.object({ status: zod_default2.literal("completed") }).strict(),
|
|
32430
|
+
zod_default2.object({ status: zod_default2.literal("no_op"), reason: zod_default2.string() }).strict(),
|
|
32431
|
+
zod_default2.object({ status: zod_default2.literal("failed"), error: agentErrorSchema }).strict(),
|
|
32432
|
+
zod_default2.object({ status: zod_default2.literal("unknown") }).strict()
|
|
32433
|
+
]);
|
|
32423
32434
|
var agentErrorSourceSchema = zod_default2.enum(["provider", "runtime", "transport", "unknown"]);
|
|
32424
32435
|
var agentSkillScopeSchema = zod_default2.enum(["user", "repository", "system", "admin"]);
|
|
32425
32436
|
var agentSkillSchema = zod_default2.object({
|
|
@@ -32672,6 +32683,13 @@ var contextCompactionCompletedAgentEventSchema = agentTurnEventBaseSchema.extend
|
|
|
32672
32683
|
error: agentErrorSchema.optional()
|
|
32673
32684
|
}).strict()
|
|
32674
32685
|
}).strict();
|
|
32686
|
+
var contextCompactionRequestCompletedAgentEventSchema = agentEventBaseSchema.extend({
|
|
32687
|
+
type: zod_default2.literal("context.compaction.request.completed"),
|
|
32688
|
+
payload: zod_default2.object({
|
|
32689
|
+
commandId: zod_default2.string().min(1),
|
|
32690
|
+
result: agentContextCompactionRequestResultSchema
|
|
32691
|
+
}).strict()
|
|
32692
|
+
}).strict();
|
|
32675
32693
|
var userInputRequestedAgentEventSchema = agentTurnEventBaseSchema.extend({
|
|
32676
32694
|
type: zod_default2.literal("user-input.requested"),
|
|
32677
32695
|
payload: zod_default2.object({
|
|
@@ -32724,6 +32742,7 @@ var agentEventSchema = zod_default2.discriminatedUnion("type", [
|
|
|
32724
32742
|
contextUpdatedAgentEventSchema,
|
|
32725
32743
|
contextCompactionStartedAgentEventSchema,
|
|
32726
32744
|
contextCompactionCompletedAgentEventSchema,
|
|
32745
|
+
contextCompactionRequestCompletedAgentEventSchema,
|
|
32727
32746
|
userInputRequestedAgentEventSchema,
|
|
32728
32747
|
userInputResolvedAgentEventSchema,
|
|
32729
32748
|
errorAgentEventSchema
|
|
@@ -32912,6 +32931,13 @@ var interruptSessionResponseSchema = exports_external2.strictObject({
|
|
|
32912
32931
|
type: exports_external2.literal("agent.interrupt")
|
|
32913
32932
|
})
|
|
32914
32933
|
});
|
|
32934
|
+
var compactSessionContextResponseSchema = exports_external2.strictObject({
|
|
32935
|
+
command: exports_external2.strictObject({
|
|
32936
|
+
id: exports_external2.string(),
|
|
32937
|
+
sequence: exports_external2.number().int().positive(),
|
|
32938
|
+
type: exports_external2.literal("agent.compact-context")
|
|
32939
|
+
})
|
|
32940
|
+
});
|
|
32915
32941
|
var withdrawSessionMessageResponseSchema = exports_external2.strictObject({
|
|
32916
32942
|
command: exports_external2.strictObject({
|
|
32917
32943
|
id: exports_external2.string(),
|
|
@@ -33082,6 +33108,24 @@ async function interruptSession({
|
|
|
33082
33108
|
throw new CodingAgentProtocolError("Session interrupt response did not match the public API contract.", { cause: parsed.error });
|
|
33083
33109
|
return parsed.data.command;
|
|
33084
33110
|
}
|
|
33111
|
+
async function compactSessionContext({
|
|
33112
|
+
client,
|
|
33113
|
+
sessionId,
|
|
33114
|
+
idempotencyKey
|
|
33115
|
+
}) {
|
|
33116
|
+
const response = await client.request(`/v1/sessions/${encodeURIComponent(sessionId)}/compact`, {
|
|
33117
|
+
method: "POST",
|
|
33118
|
+
headers: {
|
|
33119
|
+
"content-type": "application/json",
|
|
33120
|
+
"Idempotency-Key": idempotencyKey
|
|
33121
|
+
},
|
|
33122
|
+
body: "{}"
|
|
33123
|
+
});
|
|
33124
|
+
const parsed = compactSessionContextResponseSchema.safeParse(await parseJson2(response, "Session context compaction response was not valid JSON."));
|
|
33125
|
+
if (!parsed.success)
|
|
33126
|
+
throw new CodingAgentProtocolError("Session context compaction response did not match the public API contract.", { cause: parsed.error });
|
|
33127
|
+
return parsed.data.command;
|
|
33128
|
+
}
|
|
33085
33129
|
async function completeSession({ client, sessionId }) {
|
|
33086
33130
|
const response = await client.request(`/v1/sessions/${encodeURIComponent(sessionId)}/complete`, { method: "PUT" });
|
|
33087
33131
|
const parsed = sessionDetailResponseSchema.safeParse(await parseJson2(response, "Session completion response was not valid JSON."));
|
|
@@ -34022,6 +34066,9 @@ var wrappedContextCompactionStartedAgentEventSchema = contextCompactionStartedAg
|
|
|
34022
34066
|
var wrappedContextCompactionCompletedAgentEventSchema = contextCompactionCompletedAgentEventSchema.extend({
|
|
34023
34067
|
type: zod_default2.literal("agent.context.compaction.completed")
|
|
34024
34068
|
}).strict();
|
|
34069
|
+
var wrappedContextCompactionRequestCompletedAgentEventSchema = contextCompactionRequestCompletedAgentEventSchema.extend({
|
|
34070
|
+
type: zod_default2.literal("agent.context.compaction.request.completed")
|
|
34071
|
+
}).strict();
|
|
34025
34072
|
var wrappedUserInputRequestedAgentEventSchema = userInputRequestedAgentEventSchema.extend({
|
|
34026
34073
|
type: zod_default2.literal("agent.user-input.requested")
|
|
34027
34074
|
}).strict();
|
|
@@ -34056,11 +34103,31 @@ var wrappedAgentEventSchema = zod_default2.discriminatedUnion("type", [
|
|
|
34056
34103
|
wrappedContextUpdatedAgentEventSchema,
|
|
34057
34104
|
wrappedContextCompactionStartedAgentEventSchema,
|
|
34058
34105
|
wrappedContextCompactionCompletedAgentEventSchema,
|
|
34106
|
+
wrappedContextCompactionRequestCompletedAgentEventSchema,
|
|
34059
34107
|
wrappedUserInputRequestedAgentEventSchema,
|
|
34060
34108
|
wrappedUserInputResolvedAgentEventSchema,
|
|
34061
34109
|
wrappedErrorAgentEventSchema
|
|
34062
34110
|
]);
|
|
34063
34111
|
|
|
34112
|
+
// ../../packages/agents-protocol/src/agent-identity.ts
|
|
34113
|
+
function normalizeAgentSubagentIdentity(identity) {
|
|
34114
|
+
return {
|
|
34115
|
+
actorId: identity.actorId,
|
|
34116
|
+
subagentId: identity.subagentId,
|
|
34117
|
+
parentActorId: identity.parentActorId,
|
|
34118
|
+
origin: identity.origin,
|
|
34119
|
+
parentToolCallId: identity.parentToolCallId ?? (identity.origin.type === "tool_call" ? identity.origin.toolCallId : undefined)
|
|
34120
|
+
};
|
|
34121
|
+
}
|
|
34122
|
+
function agentSubagentIdentitiesEqual(left, right) {
|
|
34123
|
+
const normalizedLeft = normalizeAgentSubagentIdentity(left);
|
|
34124
|
+
const normalizedRight = normalizeAgentSubagentIdentity(right);
|
|
34125
|
+
return normalizedLeft.actorId === normalizedRight.actorId && normalizedLeft.subagentId === normalizedRight.subagentId && normalizedLeft.parentActorId === normalizedRight.parentActorId && normalizedLeft.parentToolCallId === normalizedRight.parentToolCallId && (normalizedLeft.origin.type === "tool_call" ? normalizedRight.origin.type === "tool_call" && normalizedLeft.origin.toolCallId === normalizedRight.origin.toolCallId : normalizedRight.origin.type === "provider_task" && normalizedLeft.origin.taskId === normalizedRight.origin.taskId);
|
|
34126
|
+
}
|
|
34127
|
+
function agentRuntimeIdentityKey(event) {
|
|
34128
|
+
return `${event.sessionId.length}:${event.sessionId}:${event.providerSessionId.length}:${event.providerSessionId}`;
|
|
34129
|
+
}
|
|
34130
|
+
|
|
34064
34131
|
// src/sessions/projection.ts
|
|
34065
34132
|
var sessionMessageCreatedEventSchema = exports_external2.object({
|
|
34066
34133
|
type: exports_external2.literal("session.message.created"),
|
|
@@ -34389,11 +34456,7 @@ function projectAgentTurnEnded({ state, event, occurredAt, retainedEventId }) {
|
|
|
34389
34456
|
retainedTurnEnds: { ...state.retainedTurnEnds, [event.turnId]: { actorType: event.actor.type, outcome: event.payload.status } },
|
|
34390
34457
|
messageTurns: Object.fromEntries(Object.entries(state.messageTurns).map(([messageId, turn]) => [messageId, turn.turnId === event.turnId ? { ...turn, outcome: event.payload.status } : turn]))
|
|
34391
34458
|
} : state;
|
|
34392
|
-
const card = event
|
|
34393
|
-
identity: event.actor,
|
|
34394
|
-
activityTitle: event.payload.status === "failed" ? "Turn failed" : "Turn ended",
|
|
34395
|
-
card: event.payload.status === "failed" ? { kind: "failure", weight: "signal", summary: providerText(event.payload.error?.message, "Turn failed.") } : { kind: "lifecycle", weight: "noise", summary: `Turn ${event.payload.status}.` }
|
|
34396
|
-
});
|
|
34459
|
+
const card = toAgentActivityCard(event);
|
|
34397
34460
|
return appendActivity({ state: stateWithTurnOutcome, retainedEventId, occurredAt, card });
|
|
34398
34461
|
}
|
|
34399
34462
|
function projectDurableAgentEvent({ state, event, occurredAt, retainedEventId }) {
|
|
@@ -34538,7 +34601,7 @@ function toMainAgentActivityCard(event) {
|
|
|
34538
34601
|
case "agent.turn.started":
|
|
34539
34602
|
return { kind: "lifecycle", weight: "noise", title: "Remy turn started", summary: "Turn started." };
|
|
34540
34603
|
case "agent.turn.ended":
|
|
34541
|
-
return event.payload.status === "failed" ? { kind: "failure", weight: "signal", title: "Remy turn failed", summary:
|
|
34604
|
+
return event.payload.status === "failed" ? { kind: "failure", weight: "signal", title: "Remy turn failed", summary: "Turn failed." } : { kind: "lifecycle", weight: "noise", title: "Remy turn ended", summary: `Turn ${event.payload.status}.` };
|
|
34542
34605
|
case "agent.work.observed":
|
|
34543
34606
|
return { kind: "progress", weight: "noise", title: "Work progress", summary: "Remy updated its work plan.", detail: jsonDetail(event.payload.observations) };
|
|
34544
34607
|
case "agent.message.started":
|
|
@@ -34574,6 +34637,16 @@ function toMainAgentActivityCard(event) {
|
|
|
34574
34637
|
return { kind: "reasoning", weight: "noise", title: "Context compaction started", summary: "Remy is compacting context." };
|
|
34575
34638
|
case "agent.context.compaction.completed":
|
|
34576
34639
|
return event.payload.status === "failed" ? { kind: "failure", weight: "signal", title: "Context compaction failed", summary: providerText(event.payload.error?.message, "Context compaction failed.") } : { kind: "reasoning", weight: "noise", title: "Context compaction completed", summary: "Remy compacted context." };
|
|
34640
|
+
case "agent.context.compaction.request.completed": {
|
|
34641
|
+
const result = event.payload.result;
|
|
34642
|
+
if (result.status === "completed")
|
|
34643
|
+
return { kind: "progress", weight: "signal", title: "Context compaction completed", summary: "The provider completed manual context compaction." };
|
|
34644
|
+
if (result.status === "no_op")
|
|
34645
|
+
return { kind: "progress", weight: "signal", title: "Context not compacted", summary: providerText(result.reason, "The provider did not compact context.") };
|
|
34646
|
+
if (result.status === "failed")
|
|
34647
|
+
return { kind: "failure", weight: "signal", title: "Context compaction failed", summary: providerText(result.error.message, "Context compaction failed.") };
|
|
34648
|
+
return { kind: "progress", weight: "signal", title: "Context compaction result unknown", summary: "The provider result could not be correlated." };
|
|
34649
|
+
}
|
|
34577
34650
|
case "agent.user-input.requested":
|
|
34578
34651
|
return { kind: "approval-question", weight: "signal", title: "Remy needs input", summary: providerText(event.payload.prompt, "Remy needs input."), detail: jsonDetail(event.payload.questions) };
|
|
34579
34652
|
case "agent.user-input.resolved":
|
|
@@ -34659,6 +34732,7 @@ function toChildAgentActivityCard({ event, identity }) {
|
|
|
34659
34732
|
case "agent.session.skills.updated":
|
|
34660
34733
|
case "agent.session.state.changed":
|
|
34661
34734
|
case "agent.session.ended":
|
|
34735
|
+
case "agent.context.compaction.request.completed":
|
|
34662
34736
|
case "agent.user-input.resolved":
|
|
34663
34737
|
case "agent.error":
|
|
34664
34738
|
throw new SessionProjectionProtocolError(`Cannot attribute non-child session event type ${event.type} to a subagent.`);
|
|
@@ -34701,7 +34775,7 @@ ${card.detail}`;
|
|
|
34701
34775
|
function childActivityIdentity(event) {
|
|
34702
34776
|
if (event.type === "agent.subagent.started" || event.type === "agent.subagent.progress" || event.type === "agent.subagent.ended") {
|
|
34703
34777
|
if (event.actor.type === "subagent") {
|
|
34704
|
-
if (!
|
|
34778
|
+
if (!agentSubagentIdentitiesEqual(event.actor, event.payload))
|
|
34705
34779
|
throw new SessionProjectionProtocolError(`Retained session event type ${event.type} carried contradictory subagent actor and payload identity.`);
|
|
34706
34780
|
return {
|
|
34707
34781
|
...event.actor,
|
|
@@ -34723,14 +34797,6 @@ function childActivityIdentity(event) {
|
|
|
34723
34797
|
}
|
|
34724
34798
|
return;
|
|
34725
34799
|
}
|
|
34726
|
-
function subagentLifecycleIdentityMatches({ actor, payload }) {
|
|
34727
|
-
return actor.actorId === payload.actorId && actor.subagentId === payload.subagentId && actor.parentActorId === payload.parentActorId && actor.parentToolCallId === payload.parentToolCallId && subagentOriginsMatch(actor.origin, payload.origin);
|
|
34728
|
-
}
|
|
34729
|
-
function subagentOriginsMatch(left, right) {
|
|
34730
|
-
if (left.type === "tool_call")
|
|
34731
|
-
return right.type === "tool_call" && left.toolCallId === right.toolCallId;
|
|
34732
|
-
return right.type === "provider_task" && left.taskId === right.taskId;
|
|
34733
|
-
}
|
|
34734
34800
|
function recordAgentLineageEvent({
|
|
34735
34801
|
state,
|
|
34736
34802
|
event,
|
|
@@ -34746,7 +34812,7 @@ function recordAgentLineageEvent({
|
|
|
34746
34812
|
return state;
|
|
34747
34813
|
throw error93;
|
|
34748
34814
|
}
|
|
34749
|
-
const runtimeBase =
|
|
34815
|
+
const runtimeBase = agentRuntimeIdentityKey(parsed);
|
|
34750
34816
|
let childLineage = state.childLineage;
|
|
34751
34817
|
if (parsed.type === "agent.session.started" || parsed.type === "agent.session.ended") {
|
|
34752
34818
|
const boundaryKey = `${runtimeBase}:${lengthPrefixed(parsed.eventId)}`;
|
|
@@ -34805,7 +34871,7 @@ function recordAgentLineageEvent({
|
|
|
34805
34871
|
return stampResolvedAttribution({ state: nextState, retainedEventId, fact, owner: resolution.owner });
|
|
34806
34872
|
}
|
|
34807
34873
|
function resolveBodyFactAgainstOwners(owners, fact) {
|
|
34808
|
-
const candidates = owners.filter((owner) => owner.runtimeScope === fact.runtimeScope &&
|
|
34874
|
+
const candidates = owners.filter((owner) => owner.runtimeScope === fact.runtimeScope && agentSubagentIdentitiesEqual(owner.identity, fact.identity));
|
|
34809
34875
|
const turnCandidates = candidates.filter((owner) => owner.childTurnIds.has(fact.turnId));
|
|
34810
34876
|
if (turnCandidates.length === 1)
|
|
34811
34877
|
return { status: "known", owner: turnCandidates[0] };
|
|
@@ -34837,9 +34903,6 @@ function stampResolvedAttribution({ state, retainedEventId, fact, owner }) {
|
|
|
34837
34903
|
}
|
|
34838
34904
|
return state;
|
|
34839
34905
|
}
|
|
34840
|
-
function lineageRuntimeBase(event) {
|
|
34841
|
-
return `${lengthPrefixed(event.sessionId)}:${lengthPrefixed(event.providerSessionId)}`;
|
|
34842
|
-
}
|
|
34843
34906
|
function lineageRuntimeScope({ runtimeBase, epoch }) {
|
|
34844
34907
|
return `${runtimeBase}:${epoch}`;
|
|
34845
34908
|
}
|
|
@@ -34852,9 +34915,6 @@ function isChildLineageFact(fact) {
|
|
|
34852
34915
|
function isSubagentLifecycleType(type) {
|
|
34853
34916
|
return type === "agent.subagent.started" || type === "agent.subagent.progress" || type === "agent.subagent.ended";
|
|
34854
34917
|
}
|
|
34855
|
-
function childIdentityMatches(left, right) {
|
|
34856
|
-
return left.actorId === right.actorId && left.subagentId === right.subagentId && left.parentActorId === right.parentActorId && left.parentToolCallId === right.parentToolCallId && subagentOriginsMatch(left.origin, right.origin);
|
|
34857
|
-
}
|
|
34858
34918
|
function childIdentityCanAnchor(identity) {
|
|
34859
34919
|
return identity.actorId !== identity.parentActorId && (identity.origin.type !== "tool_call" || identity.parentToolCallId === undefined || identity.parentToolCallId === identity.origin.toolCallId);
|
|
34860
34920
|
}
|
|
@@ -34888,9 +34948,9 @@ function reconcileChildLineage(state) {
|
|
|
34888
34948
|
if (parent && ownerHasActorAncestor(parent, fact.identity.actorId))
|
|
34889
34949
|
return;
|
|
34890
34950
|
const samePlacement = owners.filter((owner2) => owner2.runtimeScope === fact.runtimeScope && owner2.owningMainTurnId === owningMainTurnId && owner2.parent === parent && owner2.identity.actorId === fact.identity.actorId && owner2.identity.subagentId === fact.identity.subagentId);
|
|
34891
|
-
if (samePlacement.some((owner2) => !
|
|
34951
|
+
if (samePlacement.some((owner2) => !agentSubagentIdentitiesEqual(owner2.identity, fact.identity)))
|
|
34892
34952
|
return;
|
|
34893
|
-
const existing = samePlacement.find((owner2) =>
|
|
34953
|
+
const existing = samePlacement.find((owner2) => agentSubagentIdentitiesEqual(owner2.identity, fact.identity));
|
|
34894
34954
|
if (existing)
|
|
34895
34955
|
return existing;
|
|
34896
34956
|
const owner = {
|
|
@@ -34924,7 +34984,7 @@ function reconcileChildLineage(state) {
|
|
|
34924
34984
|
const toolTurn = mainTurnForToolOrigin(fact);
|
|
34925
34985
|
if (toolTurn === undefined)
|
|
34926
34986
|
continue;
|
|
34927
|
-
const owner = owners.find((candidate) => candidate.runtimeScope === fact.runtimeScope && candidate.parent === null && candidate.owningMainTurnId === toolTurn &&
|
|
34987
|
+
const owner = owners.find((candidate) => candidate.runtimeScope === fact.runtimeScope && candidate.parent === null && candidate.owningMainTurnId === toolTurn && agentSubagentIdentitiesEqual(candidate.identity, fact.identity)) ?? createOwner({ fact, owningMainTurnId: toolTurn, parent: null });
|
|
34928
34988
|
if (owner) {
|
|
34929
34989
|
ownerByFactOrder.set(fact.order, owner);
|
|
34930
34990
|
owner.childTurnIds.add(fact.turnId);
|
|
@@ -34937,7 +34997,7 @@ function reconcileChildLineage(state) {
|
|
|
34937
34997
|
for (const fact of childFacts) {
|
|
34938
34998
|
if (ownerByFactOrder.has(fact.order))
|
|
34939
34999
|
continue;
|
|
34940
|
-
const candidates = owners.filter((owner2) => owner2.runtimeScope === fact.runtimeScope &&
|
|
35000
|
+
const candidates = owners.filter((owner2) => owner2.runtimeScope === fact.runtimeScope && agentSubagentIdentitiesEqual(owner2.identity, fact.identity));
|
|
34941
35001
|
const turnCandidates = candidates.filter((owner2) => owner2.childTurnIds.has(fact.turnId));
|
|
34942
35002
|
const owner = turnCandidates.length === 1 ? turnCandidates[0] : candidates.length === 1 ? candidates[0] : undefined;
|
|
34943
35003
|
if (!owner || fact.eventType === "agent.subagent.started")
|
|
@@ -35013,12 +35073,16 @@ function ownerPath(owner) {
|
|
|
35013
35073
|
return path;
|
|
35014
35074
|
}
|
|
35015
35075
|
function childAttributionEqual(left, right) {
|
|
35016
|
-
if (left
|
|
35076
|
+
if (left === right)
|
|
35077
|
+
return true;
|
|
35078
|
+
if (!left || !right)
|
|
35079
|
+
return false;
|
|
35080
|
+
if (left.status !== right.status || left.activityTitle !== right.activityTitle || left.identity.name !== right.identity.name || !agentSubagentIdentitiesEqual(left.identity, right.identity)) {
|
|
35017
35081
|
return false;
|
|
35018
35082
|
}
|
|
35019
35083
|
if (left.status === "unresolved" || right.status === "unresolved")
|
|
35020
35084
|
return true;
|
|
35021
|
-
return left.ownerKey === right.ownerKey && left.owningMainTurnId === right.owningMainTurnId && left.path.length === right.path.length && left.path.every((identity, index) =>
|
|
35085
|
+
return left.ownerKey === right.ownerKey && left.owningMainTurnId === right.owningMainTurnId && left.path.length === right.path.length && left.path.every((identity, index) => identity.name === right.path[index].name && agentSubagentIdentitiesEqual(identity, right.path[index]));
|
|
35022
35086
|
}
|
|
35023
35087
|
function terminalSafeSingleLine(value) {
|
|
35024
35088
|
return stripAnsi(value).replace(/\s+/gu, " ").trim();
|
|
@@ -37990,6 +38054,7 @@ var composerSlashCommands = [
|
|
|
37990
38054
|
{ value: "/sessions", description: "Back to the session list" },
|
|
37991
38055
|
{ value: "/complete", description: "Finish this session" },
|
|
37992
38056
|
{ value: "/cancel", description: "Cancel this session" },
|
|
38057
|
+
{ value: "/compact", description: "Compact main-thread context" },
|
|
37993
38058
|
{ value: "/new", description: "Start a new session" },
|
|
37994
38059
|
{ value: "/logout", description: "Sign out of Remy" },
|
|
37995
38060
|
{ value: "/help", description: "Show what you can do here" },
|
|
@@ -38001,6 +38066,7 @@ async function createSessionTui({
|
|
|
38001
38066
|
controller,
|
|
38002
38067
|
submitMessage,
|
|
38003
38068
|
requestInterrupt,
|
|
38069
|
+
requestCompact,
|
|
38004
38070
|
requestComplete,
|
|
38005
38071
|
requestCancel,
|
|
38006
38072
|
repositoryLabel,
|
|
@@ -38242,6 +38308,7 @@ async function createSessionTui({
|
|
|
38242
38308
|
let admittedSubmissions = [];
|
|
38243
38309
|
let stopState = { kind: "idle" };
|
|
38244
38310
|
let lifecycleRequestState = { kind: "idle" };
|
|
38311
|
+
let contextCompactionRequestState = { kind: "idle" };
|
|
38245
38312
|
let helpVisible = false;
|
|
38246
38313
|
let logoutConfirmationOpen = false;
|
|
38247
38314
|
let latestState = controller.getState();
|
|
@@ -38592,6 +38659,12 @@ async function createSessionTui({
|
|
|
38592
38659
|
handleLifecycleRequest("cancel");
|
|
38593
38660
|
return true;
|
|
38594
38661
|
}
|
|
38662
|
+
if (command === "/compact") {
|
|
38663
|
+
composer.setText("");
|
|
38664
|
+
composerDraft = { ...composerDraft, text: "" };
|
|
38665
|
+
await handleCompactionRequest();
|
|
38666
|
+
return true;
|
|
38667
|
+
}
|
|
38595
38668
|
if (command === "/logout") {
|
|
38596
38669
|
composer.setText("");
|
|
38597
38670
|
composerDraft = { ...composerDraft, text: "" };
|
|
@@ -38679,6 +38752,39 @@ async function createSessionTui({
|
|
|
38679
38752
|
}
|
|
38680
38753
|
render();
|
|
38681
38754
|
}
|
|
38755
|
+
async function handleCompactionRequest() {
|
|
38756
|
+
if (contextCompactionRequestState.kind === "requesting")
|
|
38757
|
+
return;
|
|
38758
|
+
if (latestState.aggregateStatus !== "open") {
|
|
38759
|
+
composerFeedback = "This session is already terminal.";
|
|
38760
|
+
render();
|
|
38761
|
+
return;
|
|
38762
|
+
}
|
|
38763
|
+
const idempotencyKey = contextCompactionRequestState.kind === "delivery-unknown" ? contextCompactionRequestState.idempotencyKey : crypto.randomUUID();
|
|
38764
|
+
contextCompactionRequestState = { kind: "requesting", idempotencyKey };
|
|
38765
|
+
composerFeedback = "Requesting context compaction\u2026";
|
|
38766
|
+
render();
|
|
38767
|
+
try {
|
|
38768
|
+
await requestCompact({ idempotencyKey });
|
|
38769
|
+
if (!destroyed) {
|
|
38770
|
+
contextCompactionRequestState = { kind: "admitted" };
|
|
38771
|
+
composerFeedback = "Context compaction request admitted. Result will appear in the timeline.";
|
|
38772
|
+
}
|
|
38773
|
+
} catch (error93) {
|
|
38774
|
+
if (!destroyed) {
|
|
38775
|
+
const message = error93 instanceof Error ? error93.message : String(error93);
|
|
38776
|
+
if (isKnownClientRejection(error93)) {
|
|
38777
|
+
contextCompactionRequestState = { kind: "idle" };
|
|
38778
|
+
composerFeedback = `Could not request context compaction: ${message}`;
|
|
38779
|
+
} else {
|
|
38780
|
+
contextCompactionRequestState = { kind: "delivery-unknown", idempotencyKey };
|
|
38781
|
+
composerFeedback = `Context compaction admission is unknown: ${message}. Run /compact again to retry the same request.`;
|
|
38782
|
+
}
|
|
38783
|
+
}
|
|
38784
|
+
}
|
|
38785
|
+
if (!destroyed)
|
|
38786
|
+
render();
|
|
38787
|
+
}
|
|
38682
38788
|
async function handleLifecycleRequest(operation) {
|
|
38683
38789
|
if (lifecycleRequestState.kind === "pending")
|
|
38684
38790
|
return;
|
|
@@ -38805,6 +38911,7 @@ var helpEntries = [
|
|
|
38805
38911
|
{ group: "command", token: "/sessions", description: "back to the session list" },
|
|
38806
38912
|
{ group: "command", token: "/complete", description: "finish this session" },
|
|
38807
38913
|
{ group: "command", token: "/cancel", description: "cancel this session" },
|
|
38914
|
+
{ group: "command", token: "/compact", description: "compact main-thread context" },
|
|
38808
38915
|
{ group: "command", token: "/logout", description: "sign out of Remy" },
|
|
38809
38916
|
{ group: "command", token: "/exit", description: "leave Remy" },
|
|
38810
38917
|
{ group: "key", token: "esc", description: "stop Remy\u2019s current turn" },
|
|
@@ -39022,19 +39129,7 @@ function activityGlyph({ kind, inFlight }) {
|
|
|
39022
39129
|
return { glyph: "\u2713", color: PALETTE.dimText };
|
|
39023
39130
|
}
|
|
39024
39131
|
function activityCardsHaveEqualDisclosure(left, right) {
|
|
39025
|
-
return left.kind === right.kind && left.title === right.title && left.summary === right.summary && left.detail === right.detail && left.detailFormat === right.detailFormat &&
|
|
39026
|
-
}
|
|
39027
|
-
function canonicalValuesEqual(left, right) {
|
|
39028
|
-
if (Object.is(left, right))
|
|
39029
|
-
return true;
|
|
39030
|
-
if (Array.isArray(left) || Array.isArray(right)) {
|
|
39031
|
-
return Array.isArray(left) && Array.isArray(right) && left.length === right.length && left.every((value, index) => canonicalValuesEqual(value, right[index]));
|
|
39032
|
-
}
|
|
39033
|
-
if (typeof left !== "object" || left === null || typeof right !== "object" || right === null)
|
|
39034
|
-
return false;
|
|
39035
|
-
const leftEntries = Object.entries(left);
|
|
39036
|
-
const rightEntries = Object.entries(right);
|
|
39037
|
-
return leftEntries.length === rightEntries.length && leftEntries.every(([key, value], index) => rightEntries[index]?.[0] === key && canonicalValuesEqual(value, rightEntries[index]?.[1]));
|
|
39132
|
+
return left.kind === right.kind && left.title === right.title && left.summary === right.summary && left.detail === right.detail && left.detailFormat === right.detailFormat && childAttributionEqual(left.attribution, right.attribution);
|
|
39038
39133
|
}
|
|
39039
39134
|
function renderActivityGroup({ items, activityExpanded }) {
|
|
39040
39135
|
if (items.length === 0)
|
|
@@ -39235,6 +39330,12 @@ function renderComposerStatus({ admittedSubmissions }) {
|
|
|
39235
39330
|
|
|
39236
39331
|
`);
|
|
39237
39332
|
}
|
|
39333
|
+
function isKnownClientRejection(error93) {
|
|
39334
|
+
if (typeof error93 !== "object" || error93 === null || !("status" in error93))
|
|
39335
|
+
return false;
|
|
39336
|
+
const status = error93.status;
|
|
39337
|
+
return typeof status === "number" && status >= 400 && status < 500;
|
|
39338
|
+
}
|
|
39238
39339
|
async function createDefaultRenderer3() {
|
|
39239
39340
|
return await createRemyRenderer();
|
|
39240
39341
|
}
|
|
@@ -39495,7 +39596,7 @@ var compactMarkRows = 9;
|
|
|
39495
39596
|
var compactMinWidth = 48;
|
|
39496
39597
|
var compactMinHeight = 20;
|
|
39497
39598
|
var markBrightnessGain = 4.2;
|
|
39498
|
-
var remyCliVersion = "1.
|
|
39599
|
+
var remyCliVersion = "1.16.0";
|
|
39499
39600
|
async function showRemySplash({
|
|
39500
39601
|
createRenderer = createRemyRenderer,
|
|
39501
39602
|
durationMs = splashDurationMs,
|
|
@@ -40898,6 +40999,9 @@ async function runAttachedSession({
|
|
|
40898
40999
|
requestInterrupt: async ({ idempotencyKey }) => {
|
|
40899
41000
|
await operations.interruptSession({ client: operations.client, sessionId, idempotencyKey });
|
|
40900
41001
|
},
|
|
41002
|
+
requestCompact: async ({ idempotencyKey }) => {
|
|
41003
|
+
await operations.compactSessionContext({ client: operations.client, sessionId, idempotencyKey });
|
|
41004
|
+
},
|
|
40901
41005
|
requestComplete: async () => {
|
|
40902
41006
|
const detail = await operations.completeSession({ client: operations.client, sessionId });
|
|
40903
41007
|
controller.updateDetail(detail);
|
|
@@ -41024,6 +41128,7 @@ async function createSessionOperations(dependencies, { onAuthenticated } = {}) {
|
|
|
41024
41128
|
appendSessionMessage: dependencies.appendSessionMessage ?? appendSessionMessage,
|
|
41025
41129
|
cancelSession: dependencies.cancelSession ?? cancelSession,
|
|
41026
41130
|
completeSession: dependencies.completeSession ?? completeSession,
|
|
41131
|
+
compactSessionContext: dependencies.compactSessionContext ?? compactSessionContext,
|
|
41027
41132
|
interruptSession: dependencies.interruptSession ?? interruptSession,
|
|
41028
41133
|
getSession: dependencies.getSession ?? getSession,
|
|
41029
41134
|
listSessionEvents: dependencies.listSessionEvents ?? listSessionEvents,
|
|
@@ -41044,6 +41149,7 @@ async function createSessionOperations(dependencies, { onAuthenticated } = {}) {
|
|
|
41044
41149
|
appendSessionMessage: dependencies.appendSessionMessage ?? appendSessionMessage,
|
|
41045
41150
|
cancelSession: dependencies.cancelSession ?? cancelSession,
|
|
41046
41151
|
completeSession: dependencies.completeSession ?? completeSession,
|
|
41152
|
+
compactSessionContext: dependencies.compactSessionContext ?? compactSessionContext,
|
|
41047
41153
|
interruptSession: dependencies.interruptSession ?? interruptSession,
|
|
41048
41154
|
getSession: dependencies.getSession ?? getSession,
|
|
41049
41155
|
listSessionEvents: dependencies.listSessionEvents ?? listSessionEvents,
|