@gajae-code/coding-agent 0.16.3 → 0.16.4
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/CHANGELOG.md +59 -0
- package/dist/types/cli/args.d.ts +2 -2
- package/dist/types/cli/root-flags.d.ts +4 -2
- package/dist/types/cli.d.ts +1 -1
- package/dist/types/commands/launch.d.ts +1 -1
- package/dist/types/config/autorouting-tier-map.d.ts +3 -0
- package/dist/types/config/model-registry.d.ts +4 -0
- package/dist/types/config/model-resolver.d.ts +9 -0
- package/dist/types/config/settings-schema.d.ts +29 -1
- package/dist/types/discovery/claude-plugins.d.ts +3 -1
- package/dist/types/discovery/helpers.d.ts +2 -0
- package/dist/types/extensibility/gjc-plugins/mcp-policy.d.ts +16 -0
- package/dist/types/extensibility/gjc-plugins/paths.d.ts +2 -0
- package/dist/types/extensibility/runtime-skill-discovery.d.ts +1 -1
- package/dist/types/extensibility/shared-events.d.ts +1 -1
- package/dist/types/gjc-runtime/session-state-lock.d.ts +2 -0
- package/dist/types/modes/components/assistant-message.d.ts +1 -2
- package/dist/types/modes/components/settings-selector.d.ts +6 -1
- package/dist/types/modes/components/status-line/command.d.ts +35 -0
- package/dist/types/modes/components/status-line/index.d.ts +1 -0
- package/dist/types/modes/components/status-line/types.d.ts +5 -0
- package/dist/types/modes/components/tool-status-header.d.ts +14 -0
- package/dist/types/modes/controllers/event-controller.d.ts +6 -0
- package/dist/types/modes/interactive-mode.d.ts +1 -0
- package/dist/types/modes/types.d.ts +1 -0
- package/dist/types/runtime-mcp/client.d.ts +9 -1
- package/dist/types/runtime-mcp/manager.d.ts +7 -1
- package/dist/types/runtime-mcp/pool.d.ts +22 -3
- package/dist/types/runtime-mcp/transports/stdio.d.ts +0 -4
- package/dist/types/runtime-mcp/types.d.ts +22 -0
- package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +12 -0
- package/dist/types/sdk/bus/slack-live-provider.d.ts +6 -0
- package/dist/types/sdk/bus/slack-provider.d.ts +12 -0
- package/dist/types/sdk/host/session-runtime.d.ts +23 -0
- package/dist/types/sdk/session-api-key.d.ts +26 -0
- package/dist/types/sdk/transport/serve-cli.d.ts +1 -1
- package/dist/types/session/agent-session.d.ts +9 -0
- package/dist/types/setup/paseo/announce.d.ts +111 -0
- package/dist/types/setup/paseo/setup-deps.d.ts +2 -1
- package/dist/types/system-prompt.d.ts +2 -0
- package/dist/types/task/executor.d.ts +2 -1
- package/dist/types/tools/fetch.d.ts +7 -0
- package/dist/types/tools/index.d.ts +8 -0
- package/dist/types/tools/path-utils.d.ts +2 -0
- package/dist/types/tools/search.d.ts +6 -0
- package/package.json +7 -7
- package/scripts/capture-status-line-custom-editor-showcase.ts +151 -0
- package/scripts/generate-sdk-operation-inventory.ts +9 -0
- package/scripts/verify-status-line-custom-editor-showcase.ts +309 -0
- package/src/cli/args.ts +20 -9
- package/src/cli/root-flags.ts +5 -3
- package/src/config/autorouting-tier-map.ts +1 -0
- package/src/config/file-lock.ts +181 -17
- package/src/config/model-preset-registry.ts +5 -3
- package/src/config/model-profiles.ts +40 -0
- package/src/config/model-registry.ts +57 -11
- package/src/config/model-resolver.ts +48 -0
- package/src/config/settings-schema.ts +33 -1
- package/src/config/settings.ts +1 -0
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/models/catalog.ts +11 -11
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/provider/register.ts +13 -2
- package/src/discovery/builtin.ts +13 -4
- package/src/discovery/claude-plugins.ts +12 -4
- package/src/discovery/helpers.ts +10 -2
- package/src/extensibility/gjc-plugins/compiler.ts +208 -58
- package/src/extensibility/gjc-plugins/installer.ts +13 -12
- package/src/extensibility/gjc-plugins/mcp-policy.ts +81 -52
- package/src/extensibility/gjc-plugins/paths.ts +13 -0
- package/src/extensibility/gjc-plugins/runtime-adapters.ts +758 -16
- package/src/extensibility/runtime-skill-discovery.ts +77 -151
- package/src/extensibility/shared-events.ts +1 -1
- package/src/extensibility/skills.ts +44 -16
- package/src/gjc-runtime/repository-binding.ts +1 -1
- package/src/gjc-runtime/session-state-lock.ts +92 -2
- package/src/internal-urls/docs-index.generated.ts +7 -7
- package/src/main.ts +72 -34
- package/src/modes/DESIGN.md +54 -0
- package/src/modes/components/assistant-message.ts +22 -9
- package/src/modes/components/model-selector.ts +166 -33
- package/src/modes/components/settings-selector.ts +1075 -235
- package/src/modes/components/status-line/command.ts +190 -0
- package/src/modes/components/status-line/index.ts +1 -0
- package/src/modes/components/status-line/segments.ts +32 -5
- package/src/modes/components/status-line/types.ts +5 -0
- package/src/modes/components/tool-status-header.ts +393 -21
- package/src/modes/controllers/command-controller.ts +2 -0
- package/src/modes/controllers/event-controller.ts +148 -5
- package/src/modes/controllers/selector-controller.ts +21 -0
- package/src/modes/interactive-mode.ts +47 -1
- package/src/modes/types.ts +1 -0
- package/src/modes/utils/ui-helpers.ts +1 -0
- package/src/prompts/system/system-prompt.md +8 -0
- package/src/prompts/tools/search.md +2 -0
- package/src/runtime-mcp/client.ts +60 -17
- package/src/runtime-mcp/manager.ts +171 -14
- package/src/runtime-mcp/pool.test.ts +209 -0
- package/src/runtime-mcp/pool.ts +224 -23
- package/src/runtime-mcp/transports/stdio.ts +158 -24
- package/src/runtime-mcp/types.ts +24 -0
- package/src/sdk/broker/broker.ts +5 -4
- package/src/sdk/bus/chat-daemon-control.ts +1 -1
- package/src/sdk/bus/chat-daemon-runtime.ts +37 -1
- package/src/sdk/bus/slack-daemon.ts +92 -2
- package/src/sdk/bus/slack-live-provider.ts +12 -0
- package/src/sdk/bus/slack-provider.ts +5 -0
- package/src/sdk/cli/session-cli.ts +9 -6
- package/src/sdk/host/session-runtime.test.ts +2 -2
- package/src/sdk/host/session-runtime.ts +275 -43
- package/src/sdk/protocol/operation-inventory.generated.json +66 -0
- package/src/sdk/session-api-key.ts +94 -0
- package/src/sdk/session.ts +73 -29
- package/src/sdk/transport/serve-cli.ts +3 -3
- package/src/session/agent-session.ts +123 -38
- package/src/session/contribution-prep.ts +214 -21
- package/src/setup/paseo/announce.ts +450 -0
- package/src/setup/paseo/setup-deps.ts +15 -3
- package/src/slash-commands/builtin-registry.ts +1 -0
- package/src/system-prompt.ts +4 -0
- package/src/task/executor.ts +2 -1
- package/src/task/index.ts +17 -4
- package/src/tools/bash.ts +35 -8
- package/src/tools/cron.ts +1 -1
- package/src/tools/fetch.ts +29 -1
- package/src/tools/index.ts +8 -0
- package/src/tools/job.ts +8 -2
- package/src/tools/monitor.ts +8 -2
- package/src/tools/path-utils.ts +7 -0
- package/src/tools/search.ts +116 -58
- package/src/tools/skill.ts +22 -2
- package/src/tools/subagent.ts +3 -1
- package/src/tools/tool-catalog.generated.ts +8 -1
- package/src/web/insane/bridge.ts +113 -23
- package/src/web/search/providers/perplexity.ts +102 -41
|
@@ -92,6 +92,36 @@ function isReservedIdentity(name: string | undefined): boolean {
|
|
|
92
92
|
return isLifecycleEvent(name) || isControlPlaneFrameType(name);
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Chat notifications in lean mode are an answer surface, not a mirror of the
|
|
97
|
+
* session protocol. Lifecycle, identity, and activity frames remain available
|
|
98
|
+
* to verbose consumers, while finalized answers and action-needed events are
|
|
99
|
+
* delivered in lean mode.
|
|
100
|
+
*/
|
|
101
|
+
export function shouldPublishChatFrame(
|
|
102
|
+
frame: Record<string, unknown>,
|
|
103
|
+
verbosity: "lean" | "verbose" | undefined,
|
|
104
|
+
): boolean {
|
|
105
|
+
if (verbosity !== "lean") return frame.type !== "turn_stream" || frame.phase !== "live";
|
|
106
|
+
return frame.type === "turn_stream" && frame.phase === "finalized" && frame.finalAnswer === true;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* A final answer's message ref identifies its one rendered message even when
|
|
111
|
+
* the SDK transport delivers an unpositioned duplicate frame.
|
|
112
|
+
*/
|
|
113
|
+
export function publicationIdForFinalChatAnswer(sessionId: string, frame: Record<string, unknown>): string | undefined {
|
|
114
|
+
if (
|
|
115
|
+
frame.type !== "turn_stream" ||
|
|
116
|
+
frame.phase !== "finalized" ||
|
|
117
|
+
frame.finalAnswer !== true ||
|
|
118
|
+
typeof frame.messageRef !== "string" ||
|
|
119
|
+
frame.messageRef.length === 0
|
|
120
|
+
)
|
|
121
|
+
return undefined;
|
|
122
|
+
return `turn:${sessionId}:${frame.messageRef}`;
|
|
123
|
+
}
|
|
124
|
+
|
|
95
125
|
/** One delivered frame reduced to a single event identity. */
|
|
96
126
|
type CorrelatedFrame = SessionRouterFrame;
|
|
97
127
|
|
|
@@ -571,8 +601,9 @@ export class ChatDaemonRuntime {
|
|
|
571
601
|
if (this.#attachments.get(attachment.sessionId) !== attachment) return;
|
|
572
602
|
await this.#attachmentBarriers.get(attachment.sessionId);
|
|
573
603
|
if (this.#attachments.get(attachment.sessionId) !== attachment) return;
|
|
574
|
-
const publicationId = correlated.publicationId;
|
|
575
604
|
const normalizedFrame = correlated.body;
|
|
605
|
+
const publicationId =
|
|
606
|
+
publicationIdForFinalChatAnswer(attachment.sessionId, normalizedFrame) ?? correlated.publicationId;
|
|
576
607
|
const bodyType = typeof normalizedFrame.type === "string" ? normalizedFrame.type : undefined;
|
|
577
608
|
if (isControlPlaneFrameType(correlated.name) || isControlPlaneFrameType(bodyType)) return;
|
|
578
609
|
if (normalizedFrame.type === "turn_stream" && normalizedFrame.phase === "live") return;
|
|
@@ -607,6 +638,11 @@ export class ChatDaemonRuntime {
|
|
|
607
638
|
return;
|
|
608
639
|
}
|
|
609
640
|
if (!notification) return;
|
|
641
|
+
if (
|
|
642
|
+
notification.type === "frame" &&
|
|
643
|
+
!shouldPublishChatFrame(normalizedFrame, this.input.config.presentation?.verbosity)
|
|
644
|
+
)
|
|
645
|
+
return;
|
|
610
646
|
const payload = this.#presentation?.fanout(notification)[0];
|
|
611
647
|
const body = payload?.body;
|
|
612
648
|
const content =
|
|
@@ -58,7 +58,9 @@ function slackPublicationClientMsgId(publicationId: string): string {
|
|
|
58
58
|
|
|
59
59
|
// Durable filesystem publication leases must outlast one event-loop and persistence turn.
|
|
60
60
|
const MIN_PUBLICATION_LEASE_MS = 100;
|
|
61
|
+
const INBOUND_REACTION_DEADLINE_MS = 5_000;
|
|
61
62
|
const RETIREMENT_DRAIN_MS = 5_000;
|
|
63
|
+
const INBOUND_REACTION = "eyes";
|
|
62
64
|
|
|
63
65
|
type SlackProviderWorkScope = {
|
|
64
66
|
sessionId: string;
|
|
@@ -70,6 +72,8 @@ type SlackProviderWork = {
|
|
|
70
72
|
scopeKey: string;
|
|
71
73
|
invalidate(): Promise<void>;
|
|
72
74
|
abort(): void;
|
|
75
|
+
/** Best-effort work is aborted before the graceful shutdown drain. */
|
|
76
|
+
abortOnStop?: boolean;
|
|
73
77
|
terminalize(): Promise<void>;
|
|
74
78
|
settled: Promise<void>;
|
|
75
79
|
};
|
|
@@ -362,6 +366,7 @@ export class SlackNotificationDaemon {
|
|
|
362
366
|
this.#startedGeneration = undefined;
|
|
363
367
|
if (this.#providerRunningGeneration === lifecycleGeneration) this.#providerRunningGeneration = undefined;
|
|
364
368
|
this.#clearLeaseRecoveryTimer();
|
|
369
|
+
for (const work of this.#workInvalidators) if (work.abortOnStop) work.abort();
|
|
365
370
|
if (stopProvider) this.#providerStopRequestedGenerations.add(lifecycleGeneration);
|
|
366
371
|
const providerStop = stopProvider ? Promise.resolve().then(() => this.options.provider.stop()) : undefined;
|
|
367
372
|
const providerStopResult = providerStop?.then(
|
|
@@ -449,6 +454,7 @@ export class SlackNotificationDaemon {
|
|
|
449
454
|
|
|
450
455
|
/** Accepted inbound effects are durably claimed before their Socket Mode ACK. */
|
|
451
456
|
async handleEnvelope(envelope: SlackSocketEnvelope): Promise<boolean> {
|
|
457
|
+
const lifecycleGeneration = this.#lifecycleGeneration;
|
|
452
458
|
if (!text(envelope.envelope_id)) return false;
|
|
453
459
|
const inbound = messageFromEnvelope(envelope.payload);
|
|
454
460
|
if (!inbound || inbound.teamId !== this.options.teamId || inbound.channelId !== this.options.channelId) {
|
|
@@ -479,6 +485,15 @@ export class SlackNotificationDaemon {
|
|
|
479
485
|
this.#inflightInbound.add(inflightKey);
|
|
480
486
|
try {
|
|
481
487
|
await this.options.provider.ack(envelope.envelope_id);
|
|
488
|
+
const messageTs = text(inbound.event.ts);
|
|
489
|
+
if (messageTs)
|
|
490
|
+
this.#scheduleInboundReaction(
|
|
491
|
+
claim.sessionId,
|
|
492
|
+
claim.endpoint,
|
|
493
|
+
inbound.channelId,
|
|
494
|
+
messageTs,
|
|
495
|
+
lifecycleGeneration,
|
|
496
|
+
);
|
|
482
497
|
return await this.#dispatchInbound(claim);
|
|
483
498
|
} finally {
|
|
484
499
|
this.#inflightInbound.delete(inflightKey);
|
|
@@ -491,6 +506,76 @@ export class SlackNotificationDaemon {
|
|
|
491
506
|
return work.finally(() => this.#activeWork.delete(work));
|
|
492
507
|
}
|
|
493
508
|
|
|
509
|
+
/** Track the best-effort acknowledgement in the owning attachment's provider-work scope. */
|
|
510
|
+
#scheduleInboundReaction(
|
|
511
|
+
sessionId: string,
|
|
512
|
+
endpoint: SessionAttachment,
|
|
513
|
+
channel: string,
|
|
514
|
+
timestamp: string,
|
|
515
|
+
lifecycleGeneration: number,
|
|
516
|
+
): void {
|
|
517
|
+
const scope: SlackProviderWorkScope = {
|
|
518
|
+
sessionId,
|
|
519
|
+
endpointGeneration: endpoint.generation,
|
|
520
|
+
...(endpoint.authorityId === undefined ? {} : { attachmentAuthorityId: endpoint.authorityId }),
|
|
521
|
+
};
|
|
522
|
+
const scopeKey = slackProviderWorkScopeKey(scope);
|
|
523
|
+
const workGeneration = this.#workGeneration;
|
|
524
|
+
const controller = new AbortController();
|
|
525
|
+
const settled = Promise.withResolvers<void>();
|
|
526
|
+
let abortKind: "deadline" | "lifecycle" | undefined;
|
|
527
|
+
const abort = (kind: "deadline" | "lifecycle"): void => {
|
|
528
|
+
abortKind ??= kind;
|
|
529
|
+
controller.abort();
|
|
530
|
+
};
|
|
531
|
+
const work: SlackProviderWork = {
|
|
532
|
+
scopeKey,
|
|
533
|
+
invalidate: async () => abort("lifecycle"),
|
|
534
|
+
abort: () => abort("lifecycle"),
|
|
535
|
+
abortOnStop: true,
|
|
536
|
+
terminalize: async () => abort("lifecycle"),
|
|
537
|
+
settled: settled.promise,
|
|
538
|
+
};
|
|
539
|
+
this.#workInvalidators.add(work);
|
|
540
|
+
const reaction = (async () => {
|
|
541
|
+
const deadline = setTimeout(() => abort("deadline"), INBOUND_REACTION_DEADLINE_MS);
|
|
542
|
+
try {
|
|
543
|
+
if (
|
|
544
|
+
workGeneration !== this.#workGeneration ||
|
|
545
|
+
lifecycleGeneration !== this.#lifecycleGeneration ||
|
|
546
|
+
this.#retiredProviderWorkScopes.has(scopeKey) ||
|
|
547
|
+
!endpoint.isCurrent()
|
|
548
|
+
) {
|
|
549
|
+
abort("lifecycle");
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
await this.options.provider.addReaction({
|
|
553
|
+
channel,
|
|
554
|
+
timestamp,
|
|
555
|
+
name: INBOUND_REACTION,
|
|
556
|
+
signal: controller.signal,
|
|
557
|
+
});
|
|
558
|
+
if (abortKind === "deadline")
|
|
559
|
+
logger.warn(
|
|
560
|
+
`Slack inbound acknowledgement reaction exceeded the ${INBOUND_REACTION_DEADLINE_MS}ms deadline and was aborted.`,
|
|
561
|
+
);
|
|
562
|
+
} catch {
|
|
563
|
+
if (abortKind !== "lifecycle")
|
|
564
|
+
logger.warn(
|
|
565
|
+
abortKind === "deadline"
|
|
566
|
+
? `Slack inbound acknowledgement reaction exceeded the ${INBOUND_REACTION_DEADLINE_MS}ms deadline and was aborted.`
|
|
567
|
+
: "Slack inbound acknowledgement reaction failed.",
|
|
568
|
+
);
|
|
569
|
+
} finally {
|
|
570
|
+
clearTimeout(deadline);
|
|
571
|
+
this.#workInvalidators.delete(work);
|
|
572
|
+
settled.resolve();
|
|
573
|
+
this.#tryReleaseRetiredProviderWorkScope(scopeKey);
|
|
574
|
+
}
|
|
575
|
+
})();
|
|
576
|
+
void this.#track(reaction);
|
|
577
|
+
}
|
|
578
|
+
|
|
494
579
|
async #invalidateActiveWork(): Promise<void> {
|
|
495
580
|
this.#workGeneration += 1;
|
|
496
581
|
await Promise.allSettled([...this.#workInvalidators].map(work => work.invalidate()));
|
|
@@ -1496,7 +1581,11 @@ export class SlackNotificationDaemon {
|
|
|
1496
1581
|
updatedAt: this.#now(),
|
|
1497
1582
|
});
|
|
1498
1583
|
});
|
|
1499
|
-
|
|
1584
|
+
if (!sessionId || !receipt) {
|
|
1585
|
+
await this.#journal.terminalize(effectId, { status: "rejected" });
|
|
1586
|
+
return undefined;
|
|
1587
|
+
}
|
|
1588
|
+
return { key, endpoint, sessionId, receipt };
|
|
1500
1589
|
}
|
|
1501
1590
|
|
|
1502
1591
|
async #dispatchInbound(claim: {
|
|
@@ -2020,7 +2109,8 @@ export class SlackNotificationDaemon {
|
|
|
2020
2109
|
current.seenEventIds.includes(routing.eventId) ||
|
|
2021
2110
|
current.seenInteractionIds.includes(routing.interactionId) ||
|
|
2022
2111
|
current.seenRetryKeys.includes(routing.retryKey) ||
|
|
2023
|
-
(routing.kind === "action" && replyableActionId(current.pendingActionId) !== routing.actionId)
|
|
2112
|
+
(routing.kind === "action" && replyableActionId(current.pendingActionId) !== routing.actionId) ||
|
|
2113
|
+
(routing.kind === "message" && replyableActionId(current.pendingActionId) !== undefined)
|
|
2024
2114
|
)
|
|
2025
2115
|
return current;
|
|
2026
2116
|
receipt = {
|
|
@@ -294,6 +294,18 @@ export class SlackLiveProvider implements SlackProviderClient, SlackDiagnosticPr
|
|
|
294
294
|
return message;
|
|
295
295
|
}
|
|
296
296
|
|
|
297
|
+
async addReaction(input: { channel: string; timestamp: string; name: string; signal?: AbortSignal }): Promise<void> {
|
|
298
|
+
await this.#api(
|
|
299
|
+
"reactions.add",
|
|
300
|
+
{
|
|
301
|
+
channel: input.channel,
|
|
302
|
+
timestamp: input.timestamp,
|
|
303
|
+
name: input.name,
|
|
304
|
+
},
|
|
305
|
+
input.signal,
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
|
|
297
309
|
async findMessageByClientMsgId(input: {
|
|
298
310
|
channel: string;
|
|
299
311
|
clientMsgId: string;
|
|
@@ -57,6 +57,7 @@ export interface SlackProviderClient {
|
|
|
57
57
|
threadTs?: string;
|
|
58
58
|
signal?: AbortSignal;
|
|
59
59
|
}): Promise<SlackMessageSearchResult | null>;
|
|
60
|
+
addReaction?(input: { channel: string; timestamp: string; name: string; signal?: AbortSignal }): Promise<void>;
|
|
60
61
|
/**
|
|
61
62
|
* Prove that an operator-supplied timestamp addresses a real message in the
|
|
62
63
|
* requested channel. Adoption of an existing root is refused when a client
|
|
@@ -108,6 +109,10 @@ export class SlackProvider {
|
|
|
108
109
|
return (await this.client.findMessageByClientMsgId?.(input)) ?? null;
|
|
109
110
|
}
|
|
110
111
|
|
|
112
|
+
async addReaction(input: { channel: string; timestamp: string; name: string; signal?: AbortSignal }): Promise<void> {
|
|
113
|
+
await this.client.addReaction?.(input);
|
|
114
|
+
}
|
|
115
|
+
|
|
111
116
|
/** Fail-closed root verification: a client without this capability can never confirm a root. */
|
|
112
117
|
async findMessageByTimestamp(input: { channel: string; ts: string }): Promise<SlackMessageSearchResult | null> {
|
|
113
118
|
return (await this.client.findMessageByTimestamp?.(input)) ?? null;
|
|
@@ -334,13 +334,14 @@ function throwResponseFailure(response: unknown): void {
|
|
|
334
334
|
async function paginatedSessionList(
|
|
335
335
|
router: SessionRouter,
|
|
336
336
|
input: JsonRecord = {},
|
|
337
|
-
requestKey = `${SDK_SESSION_CLI_LIFECYCLE_ACTOR.namespace}:session.list`,
|
|
337
|
+
requestKey = `${SDK_SESSION_CLI_LIFECYCLE_ACTOR.namespace}:session.list:${randomBytes(12).toString("hex")}`,
|
|
338
338
|
): Promise<unknown> {
|
|
339
339
|
try {
|
|
340
340
|
const pages = await traverseSessionList(
|
|
341
341
|
input,
|
|
342
342
|
async pageInput => {
|
|
343
|
-
const
|
|
343
|
+
const cursor = typeof pageInput.cursor === "string" ? pageInput.cursor : "initial";
|
|
344
|
+
const response = object(await router.listBrokerSessions(pageInput, `${requestKey}:${cursor}`));
|
|
344
345
|
if (response?.ok === false) {
|
|
345
346
|
const failure = object(response.error);
|
|
346
347
|
throw new SdkClientError(
|
|
@@ -375,10 +376,10 @@ type SessionRows = {
|
|
|
375
376
|
sessions: SdkSessionRowV1[];
|
|
376
377
|
};
|
|
377
378
|
|
|
378
|
-
async function sessionRows(agentDir: string): Promise<SessionRows> {
|
|
379
|
+
async function sessionRows(agentDir: string, input: JsonRecord = {}): Promise<SessionRows> {
|
|
379
380
|
await ensureBroker({ agentDir });
|
|
380
381
|
return await withRouter(agentDir, async router => {
|
|
381
|
-
const response = await paginatedSessionList(router);
|
|
382
|
+
const response = await paginatedSessionList(router, input);
|
|
382
383
|
const result = resultObject(response) ?? {};
|
|
383
384
|
let sessions: SdkSessionRowV1[];
|
|
384
385
|
try {
|
|
@@ -689,7 +690,7 @@ async function runList(agentDir: string, args: SdkSessionCliArgs): Promise<unkno
|
|
|
689
690
|
}
|
|
690
691
|
|
|
691
692
|
async function runInspect(agentDir: string, sessionId: string): Promise<unknown> {
|
|
692
|
-
const listing = await sessionRows(agentDir);
|
|
693
|
+
const listing = await sessionRows(agentDir, { resolveSessionId: sessionId });
|
|
693
694
|
const session = listing.sessions.find(candidate => candidate.sessionId === sessionId);
|
|
694
695
|
if (!session)
|
|
695
696
|
throw new SdkSessionCliError("session_unavailable", `Session ${sessionId} is not indexed by the broker.`, 1);
|
|
@@ -1671,7 +1672,9 @@ export async function runTail(
|
|
|
1671
1672
|
sessionId: string,
|
|
1672
1673
|
args: SdkSessionCliArgs,
|
|
1673
1674
|
): Promise<unknown> {
|
|
1674
|
-
const row = (await sessionRows(agentDir)).sessions.find(
|
|
1675
|
+
const row = (await sessionRows(agentDir, { resolveSessionId: sessionId })).sessions.find(
|
|
1676
|
+
candidate => candidate.sessionId === sessionId,
|
|
1677
|
+
);
|
|
1675
1678
|
if (!row)
|
|
1676
1679
|
throw new SdkSessionCliError("session_unavailable", `Session ${sessionId} is not indexed by the broker.`, 1);
|
|
1677
1680
|
if (row.deleted)
|
|
@@ -2125,7 +2125,7 @@ describe("SessionSdkSessionRuntime", () => {
|
|
|
2125
2125
|
while (!transport.sent.some(frame => frame.id === "predecessor-prompt")) await Bun.sleep(10);
|
|
2126
2126
|
await handlers.get("agent_start")?.({}, ctx); // lifecycle epoch 1
|
|
2127
2127
|
await handlers.get("agent_end")?.(
|
|
2128
|
-
{ type: "agent_end", stopReason: "maintenance", maintenanceOutcome: "
|
|
2128
|
+
{ type: "agent_end", stopReason: "maintenance", maintenanceOutcome: "compacted" },
|
|
2129
2129
|
ctx,
|
|
2130
2130
|
);
|
|
2131
2131
|
transport.feed("client", {
|
|
@@ -2148,7 +2148,7 @@ describe("SessionSdkSessionRuntime", () => {
|
|
|
2148
2148
|
while (abortCalls < 1) await Bun.sleep(10);
|
|
2149
2149
|
await handlers.get("agent_end")?.({ type: "agent_end" }, ctx); // delayed predecessor
|
|
2150
2150
|
await handlers.get("agent_end")?.(
|
|
2151
|
-
{ type: "agent_end", stopReason: "maintenance", maintenanceOutcome: "
|
|
2151
|
+
{ type: "agent_end", stopReason: "maintenance", maintenanceOutcome: "compacted" },
|
|
2152
2152
|
ctx,
|
|
2153
2153
|
);
|
|
2154
2154
|
abortRelease.resolve();
|