@gajae-code/coding-agent 0.16.0 → 0.16.1
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 +41 -1
- package/dist/types/async/job-manager.d.ts +32 -1
- package/dist/types/browser-backend.d.ts +12 -0
- package/dist/types/cli/update-cli.d.ts +1 -0
- package/dist/types/commands/sdk.d.ts +2 -0
- package/dist/types/config/billing-path.d.ts +25 -0
- package/dist/types/config/config-schema-version.d.ts +13 -1
- package/dist/types/config/model-registry.d.ts +16 -0
- package/dist/types/config/settings-schema.d.ts +17 -7
- package/dist/types/extensibility/extensions/types.d.ts +8 -3
- package/dist/types/gjc-runtime/launch-worktree.d.ts +25 -1
- package/dist/types/gjc-runtime/session-state-lock.d.ts +22 -0
- package/dist/types/main.d.ts +1 -0
- package/dist/types/modes/acp/acp-agent.d.ts +21 -21
- package/dist/types/modes/components/model-selector.d.ts +4 -0
- package/dist/types/modes/components/session-selector.d.ts +1 -1
- package/dist/types/modes/components/sessions-dashboard.d.ts +2 -1
- package/dist/types/modes/interactive-mode.d.ts +16 -2
- package/dist/types/modes/theme/theme.d.ts +2 -1
- package/dist/types/modes/types.d.ts +2 -0
- package/dist/types/sdk/broker/broker.d.ts +2 -1
- package/dist/types/sdk/broker/ensure.d.ts +3 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +6 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +14 -0
- package/dist/types/sdk/broker/startup-budget.d.ts +52 -0
- package/dist/types/sdk/broker/state-version.d.ts +17 -0
- package/dist/types/sdk/bus/discord-daemon.d.ts +1 -1
- package/dist/types/sdk/bus/index.d.ts +3 -1
- package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +1 -1
- package/dist/types/sdk/bus/prompt-reconciliation.d.ts +1 -1
- package/dist/types/sdk/bus/slack-conversation.d.ts +1 -1
- package/dist/types/sdk/bus/slack-daemon.d.ts +1 -1
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +1 -1
- package/dist/types/sdk/cli/rows.d.ts +8 -2
- package/dist/types/sdk/cli/session-cli.d.ts +2 -1
- package/dist/types/sdk/host/events.d.ts +1 -0
- package/dist/types/sdk/host/query/cursor.d.ts +4 -2
- package/dist/types/sdk/host/query/handlers.d.ts +1 -0
- package/dist/types/sdk/host/query/revision-store.d.ts +1 -0
- package/dist/types/sdk/host/session-runtime.d.ts +18 -17
- package/dist/types/sdk/lifecycle-session.d.ts +1 -1
- package/dist/types/sdk/prompt-deadline-manager.d.ts +2 -5
- package/dist/types/sdk/receipt-state.d.ts +2 -0
- package/dist/types/sdk/router/session-router.d.ts +4 -0
- package/dist/types/sdk/turn-result.d.ts +6 -0
- package/dist/types/session/agent-session.d.ts +47 -7
- package/dist/types/session/fold-coordinator.d.ts +29 -2
- package/dist/types/session/session-manager.d.ts +14 -2
- package/dist/types/tools/ask.d.ts +1 -0
- package/dist/types/tools/bash.d.ts +12 -0
- package/dist/types/tools/browser/launch.d.ts +10 -0
- package/dist/types/tools/browser/registry.d.ts +8 -0
- package/dist/types/tools/index.d.ts +6 -10
- package/dist/types/tools/job.d.ts +3 -1
- package/dist/types/utils/external-editor.d.ts +7 -0
- package/examples/extensions/README.md +1 -1
- package/examples/extensions/pirate.ts +7 -4
- package/package.json +7 -7
- package/scripts/generate-sdk-operation-inventory.ts +7 -1
- package/src/async/job-manager.ts +107 -9
- package/src/browser-backend.ts +29 -0
- package/src/cli/plugin-cli.ts +29 -0
- package/src/cli/update-cli.ts +63 -12
- package/src/commands/sdk.ts +22 -7
- package/src/config/billing-path.ts +42 -0
- package/src/config/config-schema-version.ts +18 -1
- package/src/config/model-preset-registry.ts +177 -18
- package/src/config/model-registry.ts +268 -42
- package/src/config/settings-schema.ts +19 -7
- package/src/config/settings.ts +46 -15
- package/src/coordinator-mcp/projection-scan.ts +6 -6
- package/src/coordinator-mcp/server.ts +21 -1
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +1 -1
- package/src/extensibility/extensions/runner.ts +27 -0
- package/src/extensibility/extensions/types.ts +8 -3
- package/src/extensibility/gjc-plugins/installer.ts +51 -11
- package/src/extensibility/runtime-skill-discovery.ts +110 -3
- package/src/extensibility/skills.ts +22 -12
- package/src/gjc-runtime/launch-worktree.ts +285 -4
- package/src/gjc-runtime/session-state-lock.ts +154 -28
- package/src/gjc-runtime/session-state-sidecar.ts +10 -17
- package/src/gjc-runtime/tmux-owner-isolation.ts +16 -1
- package/src/internal-urls/docs-index.generated.ts +10 -10
- package/src/main.ts +4 -1
- package/src/modes/acp/acp-agent.ts +5 -5
- package/src/modes/components/model-selector.ts +76 -8
- package/src/modes/components/session-selector.ts +23 -15
- package/src/modes/components/sessions-dashboard.ts +8 -5
- package/src/modes/controllers/command-controller.ts +1 -1
- package/src/modes/controllers/event-controller.ts +30 -4
- package/src/modes/controllers/extension-ui-controller.ts +13 -13
- package/src/modes/controllers/input-controller.ts +2 -2
- package/src/modes/controllers/selector-controller.ts +10 -3
- package/src/modes/interactive-mode.ts +36 -12
- package/src/modes/prompt-action-autocomplete.ts +30 -4
- package/src/modes/runtime-init.ts +12 -9
- package/src/modes/theme/theme.ts +5 -0
- package/src/modes/types.ts +2 -0
- package/src/modes/utils/ui-helpers.ts +22 -3
- package/src/prompts/agent-fragments/browser-aside.md +22 -0
- package/src/prompts/tools/ask.md +1 -1
- package/src/prompts/tools/bash.md +1 -0
- package/src/prompts/tools/job.md +1 -1
- package/src/sdk/acp/adapter.ts +5 -0
- package/src/sdk/broker/broker.ts +10 -1
- package/src/sdk/broker/ensure.ts +76 -3
- package/src/sdk/broker/lifecycle-ledger.ts +6 -0
- package/src/sdk/broker/lifecycle.ts +254 -34
- package/src/sdk/broker/spawn-substrate.ts +45 -2
- package/src/sdk/broker/startup-budget.ts +144 -2
- package/src/sdk/broker/state-version.ts +17 -0
- package/src/sdk/bus/chat-daemon-control.ts +2 -2
- package/src/sdk/bus/chat-daemon-runtime.ts +111 -24
- package/src/sdk/bus/discord-daemon.ts +50 -10
- package/src/sdk/bus/index.ts +33 -3
- package/src/sdk/bus/kind-aware-reconciliation.ts +296 -48
- package/src/sdk/bus/lifecycle-commands.ts +4 -0
- package/src/sdk/bus/notification-service.ts +22 -5
- package/src/sdk/bus/prompt-reconciliation.ts +7 -2
- package/src/sdk/bus/reconciliation-store.ts +55 -31
- package/src/sdk/bus/slack-conversation.ts +1 -1
- package/src/sdk/bus/slack-daemon.ts +72 -38
- package/src/sdk/bus/telegram-daemon-contract.ts +1 -1
- package/src/sdk/cli/rows.ts +30 -7
- package/src/sdk/cli/session-cli.ts +33 -21
- package/src/sdk/host/control/dispatch.ts +2 -2
- package/src/sdk/host/events.ts +1 -0
- package/src/sdk/host/host.ts +2 -0
- package/src/sdk/host/query/cursor.ts +52 -7
- package/src/sdk/host/query/handlers.ts +33 -12
- package/src/sdk/host/query/revision-store.ts +12 -0
- package/src/sdk/host/session-runtime.test.ts +463 -8
- package/src/sdk/host/session-runtime.ts +383 -54
- package/src/sdk/host/surface-policy.ts +3 -3
- package/src/sdk/lifecycle-session.ts +7 -2
- package/src/sdk/prompt-deadline-manager.ts +2 -1
- package/src/sdk/protocol/operation-inventory.generated.json +54 -3
- package/src/sdk/protocol/operation-registry.ts +1 -1
- package/src/sdk/receipt-state.ts +10 -0
- package/src/sdk/router/session-router.ts +152 -59
- package/src/sdk/session.ts +60 -41
- package/src/sdk/turn-result.ts +22 -0
- package/src/session/agent-session.ts +1033 -260
- package/src/session/fold-coordinator.ts +40 -3
- package/src/session/session-manager.ts +517 -77
- package/src/slash-commands/builtin-registry.ts +41 -0
- package/src/task/executor.ts +9 -4
- package/src/tools/ask-contract.test.ts +64 -0
- package/src/tools/ask-contract.ts +36 -1
- package/src/tools/ask.ts +10 -8
- package/src/tools/bash-interactive.ts +11 -2
- package/src/tools/bash.ts +156 -33
- package/src/tools/browser/launch.ts +37 -0
- package/src/tools/browser/registry.ts +99 -9
- package/src/tools/cron.ts +6 -4
- package/src/tools/descriptors.test.ts +15 -0
- package/src/tools/descriptors.ts +5 -1
- package/src/tools/index.ts +6 -6
- package/src/tools/job.ts +4 -1
- package/src/tools/monitor.ts +12 -9
- package/src/tools/resolve.ts +30 -10
- package/src/tools/tool-catalog.generated.ts +2 -2
- package/src/utils/external-editor.ts +72 -1
package/src/sdk/session.ts
CHANGED
|
@@ -51,6 +51,7 @@ import {
|
|
|
51
51
|
isBackgroundJobSupportEnabled,
|
|
52
52
|
jobElapsedMs,
|
|
53
53
|
} from "../async";
|
|
54
|
+
import { resolveBrowserBackend } from "../browser-backend";
|
|
54
55
|
import { loadCapability, reset as resetCapabilities } from "../capability";
|
|
55
56
|
import { type Rule, ruleCapability, setActiveRules } from "../capability/rule";
|
|
56
57
|
import type { SourceMeta } from "../capability/types";
|
|
@@ -150,7 +151,7 @@ import { markAutoroutingInactive } from "../sdk/host/internal-autorouting-state"
|
|
|
150
151
|
import { createSdkSessionRuntimeExtension, registerSdkOnlyNotificationCommand } from "../sdk/host/session-runtime";
|
|
151
152
|
import { createSdkWebSocketTransport } from "../sdk/host/websocket-transport";
|
|
152
153
|
import type { SecretObfuscator } from "../secrets";
|
|
153
|
-
import { AgentSession, type ForkContextSeed } from "../session/agent-session";
|
|
154
|
+
import { AgentSession, type ForkContextSeed, isSessionDisposalIncompleteError } from "../session/agent-session";
|
|
154
155
|
import { AuthBrokerClient, AuthStorage, RemoteAuthCredentialStore } from "../session/auth-storage";
|
|
155
156
|
import { type CustomMessage, convertToLlm } from "../session/messages";
|
|
156
157
|
import { createReadonlySessionManager, SessionManager } from "../session/session-manager";
|
|
@@ -1104,12 +1105,16 @@ function buildMCPPromptCommands(manager: MCPManager): LoadedCustomCommand[] {
|
|
|
1104
1105
|
*/
|
|
1105
1106
|
|
|
1106
1107
|
function withEmbeddedDefaultGjcSkills(skills: Skill[]): Skill[] {
|
|
1107
|
-
const byName = new Map
|
|
1108
|
+
const byName = new Map<string, Skill>();
|
|
1109
|
+
for (const skill of skills) {
|
|
1110
|
+
const key = skill.name.toLowerCase();
|
|
1111
|
+
if (!byName.has(key)) byName.set(key, skill);
|
|
1112
|
+
}
|
|
1108
1113
|
// The four public GJC workflow skills are a product invariant: even if a
|
|
1109
1114
|
// caller-supplied or filesystem skill shares a name, the bundled definition
|
|
1110
1115
|
// wins so workflow routing can never be silently hijacked.
|
|
1111
1116
|
for (const defaultSkill of getEmbeddedDefaultGjcSkills()) {
|
|
1112
|
-
byName.set(defaultSkill.name, defaultSkill);
|
|
1117
|
+
byName.set(defaultSkill.name.toLowerCase(), defaultSkill);
|
|
1113
1118
|
}
|
|
1114
1119
|
return [...byName.values()];
|
|
1115
1120
|
}
|
|
@@ -2438,7 +2443,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2438
2443
|
"Cannot rescope a session with caller-owned MCP authority; recreate the session at the target cwd.",
|
|
2439
2444
|
);
|
|
2440
2445
|
}
|
|
2441
|
-
return sessionManager.
|
|
2446
|
+
return sessionManager.runExclusiveCwdMoveTransition(async () => {
|
|
2442
2447
|
if (moveConsumed) {
|
|
2443
2448
|
throw new Error(
|
|
2444
2449
|
"This session has already been rescoped; only one agent-invoked move is allowed per session.",
|
|
@@ -2713,7 +2718,9 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2713
2718
|
registerForegroundFoldParticipant: adapter =>
|
|
2714
2719
|
session?.registerForegroundFoldParticipant(adapter) ?? (() => {}),
|
|
2715
2720
|
hasForegroundBashBackgroundRequestHandler: () => session?.hasForegroundBashBackgroundRequestHandler() ?? false,
|
|
2716
|
-
requestForegroundBashBackground: () =>
|
|
2721
|
+
requestForegroundBashBackground: (reason, adapter) =>
|
|
2722
|
+
Promise.resolve(session?.requestForegroundBashBackground(reason, adapter) ?? false),
|
|
2723
|
+
getToolInterruptPolicy: () => agent?.getToolInterruptPolicy() ?? "abort_tools",
|
|
2717
2724
|
|
|
2718
2725
|
getCredentialSessionId: () => session?.credentialSessionId ?? credentialSessionId,
|
|
2719
2726
|
getMcpManager: () => mcpManager ?? options.inheritedMcpManager,
|
|
@@ -2770,16 +2777,6 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2770
2777
|
return m ? buildNamedToolChoice(name, m) : undefined;
|
|
2771
2778
|
},
|
|
2772
2779
|
buildToolChoiceResult: name => buildNamedToolChoiceResult(name, session.model),
|
|
2773
|
-
steer: msg =>
|
|
2774
|
-
session.agent.steer({
|
|
2775
|
-
role: "custom",
|
|
2776
|
-
customType: msg.customType,
|
|
2777
|
-
content: msg.content,
|
|
2778
|
-
display: false,
|
|
2779
|
-
details: msg.details,
|
|
2780
|
-
attribution: "agent",
|
|
2781
|
-
timestamp: Date.now(),
|
|
2782
|
-
}),
|
|
2783
2780
|
sendCustomMessage: (msg, opts) => session.sendCustomMessage(msg, opts),
|
|
2784
2781
|
purgeQueuedCustomMessages: predicate => session.purgeQueuedCustomMessages(predicate),
|
|
2785
2782
|
peekQueueInvoker: () => session.peekQueueInvoker(),
|
|
@@ -3562,7 +3559,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
3562
3559
|
!model &&
|
|
3563
3560
|
!options.modelPattern &&
|
|
3564
3561
|
!startupCredentialModelRejected &&
|
|
3565
|
-
configuredDefaultPatterns.length === 0
|
|
3562
|
+
(configuredDefaultPatterns.length === 0 || preferredCredentialProvider !== undefined)
|
|
3566
3563
|
) {
|
|
3567
3564
|
// Re-resolve the allowed set: extension factories above may have
|
|
3568
3565
|
// registered providers/models that weren't visible at startup.
|
|
@@ -3896,7 +3893,9 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
3896
3893
|
? await memoryBackend.buildDeveloperInstructions(agentDir, settings, session)
|
|
3897
3894
|
: undefined;
|
|
3898
3895
|
|
|
3899
|
-
const
|
|
3896
|
+
const browserBackend = resolveBrowserBackend(settings);
|
|
3897
|
+
const appendPrompt =
|
|
3898
|
+
[memoryInstructions, browserBackend.developerInstructions].filter(Boolean).join("\n\n") || undefined;
|
|
3900
3899
|
let pluginSystemAppendices = "";
|
|
3901
3900
|
try {
|
|
3902
3901
|
pluginSystemAppendices = await renderAlwaysOnSystemAppendices({ cwd: getLiveCwd() });
|
|
@@ -4277,7 +4276,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
4277
4276
|
transformContext,
|
|
4278
4277
|
steeringMode: settings.get("steeringMode") ?? "one-at-a-time",
|
|
4279
4278
|
followUpMode: settings.get("followUpMode") ?? "one-at-a-time",
|
|
4280
|
-
|
|
4279
|
+
toolInterruptPolicy: settings.get("toolInterruptPolicy") ?? "abort_tools",
|
|
4281
4280
|
thinkingBudgets: settings.getGroup("thinkingBudgets"),
|
|
4282
4281
|
temperature: settings.get("temperature") >= 0 ? settings.get("temperature") : undefined,
|
|
4283
4282
|
topP: settings.get("topP") >= 0 ? settings.get("topP") : undefined,
|
|
@@ -4575,38 +4574,49 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
4575
4574
|
|
|
4576
4575
|
// Attach the live session to the pre-registered ref so peers can route IRC
|
|
4577
4576
|
// messages here. Refresh sessionFile in case it was unavailable at pre-register
|
|
4578
|
-
// time. The
|
|
4577
|
+
// time. The registered terminal cleanup below unregisters on teardown.
|
|
4579
4578
|
agentRegistry.attachSession(resolvedAgentId, session, sessionManager.getSessionFile() ?? null);
|
|
4580
4579
|
{
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4580
|
+
let cleanupPromise: Promise<void> | undefined;
|
|
4581
|
+
const finishCleanup = async (): Promise<void> => {
|
|
4582
|
+
if (cleanupPromise) return cleanupPromise;
|
|
4583
|
+
const cleanup = (async () => {
|
|
4584
|
+
const failures: unknown[] = [];
|
|
4586
4585
|
try {
|
|
4587
4586
|
agentRegistry.unregister(resolvedAgentId);
|
|
4588
4587
|
releaseCredentialDisabledSubscription();
|
|
4589
4588
|
releaseLocalProtocolOverride();
|
|
4589
|
+
} catch (error) {
|
|
4590
|
+
failures.push(error);
|
|
4590
4591
|
} finally {
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
);
|
|
4603
|
-
|
|
4592
|
+
try {
|
|
4593
|
+
if (!options.parentTaskPrefix) {
|
|
4594
|
+
retireOwnedRegistrationsForEndpoint(
|
|
4595
|
+
AsyncJobManager.endpointIdOf(asyncJobManager) ?? asyncJobEndpointId,
|
|
4596
|
+
);
|
|
4597
|
+
AsyncJobManager.unregisterManager(asyncJobManager);
|
|
4598
|
+
}
|
|
4599
|
+
} catch (error) {
|
|
4600
|
+
failures.push(error);
|
|
4601
|
+
}
|
|
4602
|
+
try {
|
|
4603
|
+
await closeOwnedAuthStorage();
|
|
4604
|
+
} catch (error) {
|
|
4605
|
+
failures.push(error);
|
|
4606
|
+
}
|
|
4607
|
+
try {
|
|
4608
|
+
await closeOwnedSettings();
|
|
4609
|
+
} catch (error) {
|
|
4610
|
+
failures.push(error);
|
|
4604
4611
|
}
|
|
4605
|
-
await closeOwnedAuthStorage();
|
|
4606
|
-
await closeOwnedSettings();
|
|
4607
4612
|
}
|
|
4608
|
-
|
|
4613
|
+
if (failures.length > 0) throw new AggregateError(failures, "SDK disposal cleanup failed.");
|
|
4614
|
+
})();
|
|
4615
|
+
cleanupPromise = cleanup;
|
|
4616
|
+
void cleanup.catch(() => {});
|
|
4617
|
+
return cleanup;
|
|
4609
4618
|
};
|
|
4619
|
+
session.registerToolSessionCleanup(finishCleanup);
|
|
4610
4620
|
}
|
|
4611
4621
|
|
|
4612
4622
|
if (model?.api === "openai-codex-responses") {
|
|
@@ -4834,7 +4844,16 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
4834
4844
|
let cleanupDiagnostic: unknown;
|
|
4835
4845
|
try {
|
|
4836
4846
|
if (hasSession) {
|
|
4837
|
-
|
|
4847
|
+
try {
|
|
4848
|
+
await session.dispose();
|
|
4849
|
+
} catch (disposeError) {
|
|
4850
|
+
if (!isSessionDisposalIncompleteError(disposeError)) {
|
|
4851
|
+
throw disposeError;
|
|
4852
|
+
}
|
|
4853
|
+
// The first call is intentionally bounded for startup callers. Join the
|
|
4854
|
+
// retained teardown before releasing the resources it still owns.
|
|
4855
|
+
await session.awaitDisposeCompletion();
|
|
4856
|
+
}
|
|
4838
4857
|
} else {
|
|
4839
4858
|
if (hasRegistered) agentRegistry.unregister(resolvedAgentId);
|
|
4840
4859
|
// Admission happens before session construction. Any later startup
|
package/src/sdk/turn-result.ts
CHANGED
|
@@ -17,6 +17,7 @@ export interface TurnResultError {
|
|
|
17
17
|
code: string;
|
|
18
18
|
message: string;
|
|
19
19
|
}
|
|
20
|
+
export type TurnResultReceiptState = "absent" | "present" | "missing" | "unknown";
|
|
20
21
|
export interface TurnResultPage {
|
|
21
22
|
status: TurnResultStatus;
|
|
22
23
|
kind?: "prompt" | "skill";
|
|
@@ -26,6 +27,8 @@ export interface TurnResultPage {
|
|
|
26
27
|
acceptedAt?: number;
|
|
27
28
|
startedAt?: number;
|
|
28
29
|
terminalAt?: number;
|
|
30
|
+
receiptState?: TurnResultReceiptState;
|
|
31
|
+
outcome?: unknown;
|
|
29
32
|
content?: TurnResultContent;
|
|
30
33
|
error?: TurnResultError;
|
|
31
34
|
}
|
|
@@ -51,3 +54,22 @@ export function sanitizeTurnResultContent(text: unknown): TurnResultContent | un
|
|
|
51
54
|
truncated,
|
|
52
55
|
};
|
|
53
56
|
}
|
|
57
|
+
|
|
58
|
+
export function reportableTurnResultContent(content: TurnResultContent | undefined): boolean {
|
|
59
|
+
return content !== undefined && content.text.trim().length > 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** First reportable invocation-owned content wins; blank evidence remains replaceable. */
|
|
63
|
+
export function reduceTurnResultContent(
|
|
64
|
+
existing: TurnResultContent | undefined,
|
|
65
|
+
incoming: TurnResultContent | undefined,
|
|
66
|
+
): TurnResultContent | undefined {
|
|
67
|
+
if (reportableTurnResultContent(existing)) return existing;
|
|
68
|
+
if (incoming === undefined) return existing;
|
|
69
|
+
const sanitized = sanitizeTurnResultContent(incoming.text);
|
|
70
|
+
if (sanitized === undefined) return existing;
|
|
71
|
+
return {
|
|
72
|
+
...sanitized,
|
|
73
|
+
truncated: sanitized.truncated || incoming.truncated || existing?.truncated === true,
|
|
74
|
+
};
|
|
75
|
+
}
|