Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
b67b726
fix(usage): attribute shared homes by transcript source
rynfar Sep 24, 2026
762792d
fix(server): preserve pending turn admission during provider bind (#752)
rynfar Sep 24, 2026
a8d9041
feat(chat): deliver buffered prose at natural boundaries (#757)
rynfar Sep 24, 2026
9cadbaa
fix(server): show Claude subagent tool progress (#745)
rynfar Sep 24, 2026
a675fa8
fix(server): show Relay workers from installed CLI results (#744)
rynfar Sep 24, 2026
90129e7
fix(relay): accept delegated thread IDs in activity routes (#756)
rynfar Sep 24, 2026
29e57cf
feat(prime): show child progress notes in Agents view (#748)
rynfar Sep 24, 2026
ccb8854
fix(server): bypass provider caches on explicit refresh (#743)
rynfar Sep 24, 2026
91e5166
fix(git): prevent stale ref checkout from restoring files (#751)
rynfar Sep 24, 2026
7cd8bb3
fix(shared): preserve final quoted empty CSV records (#761)
rynfar Sep 24, 2026
b7f9179
fix(server): reduce background GitHub PR quota use (#749)
rynfar Sep 24, 2026
b264cfb
fix(cursor): preserve internal agent errors (#754)
rynfar Sep 24, 2026
e82750e
fix(ci): compare transfer ceilings only within a scenario (#759)
rynfar Sep 24, 2026
298d788
fix(usage): retain saved totals after transcript cleanup (#762)
rynfar Sep 24, 2026
e4434e5
fix(ssh): find Linuxbrew Node on WSL hosts (#769)
rynfar Sep 24, 2026
08e6f51
fix(server): generate PR diffs from branch changes (#13170) (#742)
rynfar Sep 24, 2026
dbc8eeb
feat(observability): honor OpenTelemetry export kill switch (#746)
rynfar Sep 24, 2026
961c4dc
fix(grok): show monitor and background shell lifecycle (#753)
rynfar Sep 24, 2026
806d5f0
Merge commit 'b67b7265c5b4d9a3986aadee4c1a10f311bbce7d' into verify/u…
rynfar Sep 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .agents/upstream-review.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions .github/scripts/thread-transfer-report.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ function validateResult(value) {
}

assertExactKeys(value.scenario, SCENARIO_KEYS, "result.scenario");
if (value.scenario.id !== "thread-transfer-v1") {
if (!["thread-transfer-v1", "thread-transfer-v2"].includes(value.scenario.id)) {
throw new Error("result.scenario.id is not supported");
}
for (const key of SCENARIO_KEYS.slice(1)) {
Expand Down Expand Up @@ -157,7 +157,7 @@ function renderComment(input) {
`| ${provider === "codex" ? "Codex" : "Claude"} | ${metric.label} | ${baselineObserved === undefined ? "—" : formatValue(baselineObserved, metric.kind)} | ${formatValue(observed, metric.kind)} | ${formatImpact(observed, baselineObserved, metric.kind)} | ${formatValue(ceiling, metric.kind)} | ${pass ? "✅" : "❌"} |`,
);

if (baseline && baseline.providers[provider].ceiling[metric.key] !== ceiling) {
if (comparable && baseline.providers[provider].ceiling[metric.key] !== ceiling) {
ceilingChanges.push(
`- ${provider === "codex" ? "Codex" : "Claude"} ${metric.label}: ${formatValue(baseline.providers[provider].ceiling[metric.key], metric.kind)} → ${formatValue(ceiling, metric.kind)}`,
);
Expand Down
18 changes: 18 additions & 0 deletions .github/scripts/thread-transfer-report.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -290,3 +290,21 @@ test("preserves a successful result when a same-SHA rerun has no artifact", asyn
assert.equal(published, true);
assert.equal(updatedComment, false);
});

test("accepts V2 without comparing it to the V1 scenario", () => {
const current = result();
current.scenario.id = "thread-transfer-v2";
current.providers.codex.ceiling = { ...current.providers.codex.ceiling, totalWireBytes: 3000000 };
assert.equal(validateResult(current), current);
const comment = renderComment({
current,
baseline: result(),
currentRun: { sha: "bbbbbbbb", conclusion: "success", url: "https://example.com/current" },
baselineRun: { sha: "aaaaaaaa", matchesBase: true, url: "https://example.com/baseline" },
});
assert.match(comment, /fixture changed/);
assert.doesNotMatch(comment, /This PR changes transfer ceilings/);
assert.doesNotMatch(comment, /[+-]\d+\.\d+%/);
current.scenario.id = "unrecognized";
assert.throws(() => validateResult(current), /not supported/);
});
64 changes: 64 additions & 0 deletions apps/desktop/src/app/DesktopObservability.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as NodeHttpClient from "@effect/platform-node/NodeHttpClient";
import * as NodeServices from "@effect/platform-node/NodeServices";
import { assert, describe, it } from "@effect/vitest";
import * as ConfigProvider from "effect/ConfigProvider";
import * as Effect from "effect/Effect";
import * as FileSystem from "effect/FileSystem";
import * as Layer from "effect/Layer";
Expand Down Expand Up @@ -427,6 +428,36 @@ describe("DesktopObservability", () => {
);
});

it.effect("exports kill switch warnings through the configured logger", () => {
const requests: Array<ExportedRequest> = [];
return Effect.gen(function* () {
const fileSystem = yield* FileSystem.FileSystem;
const baseDir = yield* fileSystem.makeTempDirectoryScoped({
prefix: "t3-desktop-observability-test-",
});
const environmentLayer = makeEnvironmentLayer(baseDir, true, {
T3CODE_OTLP_LOGS_URL: "https://collector.example.com/v1/logs",
});

yield* Effect.scoped(
Effect.void.pipe(
Effect.provide(DesktopObservability.layer.pipe(Layer.provideMerge(environmentLayer))),
),
);

assert.include(requests[0]?.body ?? "", "OTEL_SDK_DISABLED=1 was read as false");
}).pipe(
Effect.scoped,
Effect.provide(
Layer.mergeAll(
NodeServices.layer,
collectorLayer(requests),
ConfigProvider.layer(ConfigProvider.fromEnv({ env: { OTEL_SDK_DISABLED: "1" } })),
),
),
);
});

it.effect("reads every signal endpoint from Settings when the environment names none", () => {
const requests: Array<ExportedRequest> = [];
return Effect.gen(function* () {
Expand Down Expand Up @@ -491,4 +522,37 @@ describe("DesktopObservability", () => {
Effect.provide(Layer.mergeAll(NodeServices.layer, collectorLayer(requests))),
);
});

it.effect("stops every export when the OpenTelemetry SDK is disabled", () => {
const requests: Array<ExportedRequest> = [];
return Effect.gen(function* () {
const fileSystem = yield* FileSystem.FileSystem;
const baseDir = yield* fileSystem.makeTempDirectoryScoped({
prefix: "t3-desktop-observability-test-",
});
const environmentLayer = makeEnvironmentLayer(baseDir);
yield* writeObservabilitySettings(environmentLayer, {
otlpTracesUrl: "https://settings.example.com/v1/traces",
otlpLogsUrl: "https://settings.example.com/v1/logs",
});

yield* Effect.scoped(
Effect.logInfo("desktop log stays local when disabled").pipe(
Effect.withSpan("desktop-disabled-test"),
Effect.provide(DesktopObservability.layer.pipe(Layer.provideMerge(environmentLayer))),
),
);

assert.lengthOf(requests, 0);
}).pipe(
Effect.scoped,
Effect.provide(
Layer.mergeAll(
NodeServices.layer,
collectorLayer(requests),
ConfigProvider.layer(ConfigProvider.fromEnv({ env: { OTEL_SDK_DISABLED: "true" } })),
),
),
);
});
});
14 changes: 13 additions & 1 deletion apps/desktop/src/app/DesktopObservability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
makeTraceSink,
otlpSerializationLayer,
} from "@t3tools/shared/observability";
import * as OtelEnvironment from "@t3tools/shared/otelEnvironment";
import {
parsePersistedServerObservabilitySettings,
type PersistedServerObservabilitySettings,
Expand Down Expand Up @@ -353,12 +354,18 @@ const readPersistedObservabilitySettings: Effect.Effect<
* resolve traces against one revision of the file and logs against another.
*/
const resolveOtlpEndpoints = Effect.gen(function* () {
const otel = yield* OtelEnvironment.load;
if (otel.disabled) {
return { traces: undefined, metrics: undefined, logs: undefined, warnings: otel.warnings };
}

const environment = yield* DesktopEnvironment.DesktopEnvironment;
const persisted = yield* readPersistedObservabilitySettings;
return {
traces: Option.getOrUndefined(environment.otlpTracesUrl) ?? persisted.otlpTracesUrl,
metrics: Option.getOrUndefined(environment.otlpMetricsUrl) ?? persisted.otlpMetricsUrl,
logs: Option.getOrUndefined(environment.otlpLogsUrl) ?? persisted.otlpLogsUrl,
warnings: otel.warnings,
};
});

Expand Down Expand Up @@ -671,7 +678,12 @@ const telemetryLayer = Layer.unwrap(
// resource,
// }).pipe(Layer.provide(serializationLayer));

return Layer.mergeAll(loggerLayer, tracerLayer);
// Logged once the loggers above are installed, so the warnings use them.
const otelWarningsLayer = Layer.effectDiscard(
Effect.forEach(endpoints.warnings, (warning) => Effect.logWarning(warning)),
);

return otelWarningsLayer.pipe(Layer.provideMerge(Layer.mergeAll(loggerLayer, tracerLayer)));
}),
);

Expand Down
43 changes: 43 additions & 0 deletions apps/desktop/src/backend/DesktopBackendConfiguration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1055,6 +1055,49 @@ describe("DesktopBackendConfiguration", () => {
}).pipe(Effect.scoped, Effect.provide(NodeServices.layer)),
);

it.effect("resolveWsl carries the kill switch into the distro", () =>
Effect.gen(function* () {
const fileSystem = yield* FileSystem.FileSystem;
const baseDir = yield* fileSystem.makeTempDirectoryScoped({
prefix: "t3-desktop-backend-config-test-",
});

const previousWslEnv = process.env.WSLENV;
const previousDisabled = process.env.OTEL_SDK_DISABLED;
try {
delete process.env.WSLENV;
process.env.OTEL_SDK_DISABLED = "true";

yield* Effect.gen(function* () {
const configuration = yield* DesktopBackendConfiguration.DesktopBackendConfiguration;
const config = yield* configuration.resolveWsl({ port: 5050, distro: null });

assert.equal(config.env.OTEL_SDK_DISABLED, "true");
assert.include((config.env.WSLENV ?? "").split(":"), "OTEL_SDK_DISABLED");
}).pipe(
Effect.provide(
DesktopBackendConfiguration.layer.pipe(
Layer.provideMerge(serverExposureLayer),
Layer.provideMerge(DesktopAppSettings.layerTest()),
Layer.provideMerge(DesktopWslServerTree.layerTest()),
Layer.provideMerge(
DesktopWslEnvironment.layerTest({
isAvailable: true,
windowsToWslPath: () => Option.some("/mnt/c/repo/apps/server/src/index.ts"),
getDistroIp: () => Option.some("172.27.0.99"),
}),
),
Layer.provideMerge(makeEnvironmentLayer(baseDir, { platform: "win32" })),
),
),
);
} finally {
restoreEnv("WSLENV", previousWslEnv);
restoreEnv("OTEL_SDK_DISABLED", previousDisabled);
}
}).pipe(Effect.scoped, Effect.provide(NodeServices.layer)),
);

it.effect("resolveWsl preserves existing WSLENV entries when forwarding backend secrets", () =>
Effect.gen(function* () {
const fileSystem = yield* FileSystem.FileSystem;
Expand Down
3 changes: 3 additions & 0 deletions apps/desktop/src/backend/DesktopBackendConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ const DESKTOP_BACKEND_ENV_NAMES = [
const WSL_FORWARDED_ENV_NAMES = [
"OPENAI_API_KEY",
"ANTHROPIC_API_KEY",
// Otherwise the WSL server keeps exporting to endpoints from the bootstrap.
"T3CODE_OTEL_SDK_DISABLED",
"OTEL_SDK_DISABLED",
"T3CODE_OTLP_HEADERS",
"T3CODE_OTLP_PROTOCOL",
] as const;
Expand Down
13 changes: 13 additions & 0 deletions apps/mobile/src/features/usage/UsageRouteScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,19 @@ export function UsageRouteScreen() {
{merged.duplicateSources.join(", ")}
</Text>
) : null}
{merged.approximateEnvironments.length > 0 ? (
<Text className="text-sm text-foreground-muted">
Totals may count shared usage more than once because these environments run older
servers or have directories whose filesystem identity could not be read:{" "}
{selectedEnvironments
.filter((environment) =>
merged.approximateEnvironments.includes(environment.environmentId),
)
.map((environment) => environment.label)
.join(", ")}
.
</Text>
) : null}
{isPending ? (
<Text className="py-16 text-center text-base text-foreground-muted">
Scanning provider transcripts…
Expand Down
104 changes: 104 additions & 0 deletions apps/server/scripts/acp-mock-agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ const emitXAiAskUserQuestionThenHang =
const emitContentThenHang = process.env.T3_ACP_EMIT_CONTENT_THEN_HANG === "1";
const emitPlanThenHang = process.env.T3_ACP_EMIT_PLAN_THEN_HANG === "1";
const emitActiveToolThenHang = process.env.T3_ACP_EMIT_ACTIVE_TOOL_THEN_HANG === "1";
const emitGrokMonitorPostTurnPoll = process.env.T3_ACP_EMIT_GROK_MONITOR_POST_TURN_POLL === "1";
const emitGrokBackgroundTaskStarted = process.env.T3_ACP_EMIT_GROK_BACKGROUND_TASK_STARTED === "1";
const emitForeignSessionUpdates = process.env.T3_ACP_EMIT_FOREIGN_SESSION_UPDATES === "1";
const emitPrivateThoughtChunk = process.env.T3_ACP_EMIT_PRIVATE_THOUGHT_CHUNK === "1";
const assistantMessageIdMode = process.env.T3_ACP_ASSISTANT_MESSAGE_IDS;
Expand Down Expand Up @@ -935,6 +937,108 @@ const program = Effect.gen(function* () {
return yield* Effect.never;
}

if (emitGrokMonitorPostTurnPoll) {
const monitorCallId = "call-monitor-1";
const pollCallId = "call-monitor-poll-1";
const taskId = "01a05f41-5107-7550-821e-79e8d1cd7687";
const description = "Watch count-sheet Typst unit until done";
writeJsonRpcNotification("session/update", {
sessionId: requestedSessionId,
update: {
sessionUpdate: "tool_call",
toolCallId: monitorCallId,
title: "monitor",
kind: "other",
status: "pending",
rawInput: { description },
_meta: {
"x.ai/tool": { version: 1, name: "monitor", kind: "task", namespace: "grok_build" },
},
},
});
writeJsonRpcNotification("session/update", {
sessionId: requestedSessionId,
update: {
sessionUpdate: "tool_call_update",
toolCallId: monitorCallId,
status: "completed",
rawInput: { description },
rawOutput: {
type: "Monitor",
taskId,
timeoutMs: 36_000_000,
},
},
});
writeJsonRpcNotification("_x.ai/session/prompt_complete", {
sessionId: requestedSessionId,
promptId: promptIdFromRequestMeta(request) ?? "mock-xai-prompt-1",
stopReason: "end_turn",
agentResult: null,
});
yield* Effect.sleep("120 millis");
writeJsonRpcNotification("session/update", {
sessionId: requestedSessionId,
update: {
sessionUpdate: "tool_call",
toolCallId: pollCallId,
title: "get_command_or_subagent_output",
kind: "other",
status: "completed",
rawInput: { variant: "TaskOutput", task_ids: [taskId], timeout_ms: 0 },
rawOutput: {
type: "TaskOutput",
Result: {
task_id: taskId,
command: `[monitor] ${description}`,
status: "completed",
exit_code: 0,
output: "Monitor finished.",
},
},
},
});
return yield* Effect.never;
}

if (emitGrokBackgroundTaskStarted) {
const toolCallId = "call-fb9d0000-0000-0000-0000-000000000026";
const command = "sleep 40; echo done-a";
writeJsonRpcNotification("session/update", {
sessionId: requestedSessionId,
update: {
sessionUpdate: "tool_call",
toolCallId,
title: "run_terminal_command",
kind: "execute",
status: "in_progress",
rawInput: { command },
},
});
writeJsonRpcNotification("session/update", {
sessionId: requestedSessionId,
update: {
sessionUpdate: "tool_call_update",
toolCallId,
status: "completed",
rawOutput: {
type: "BackgroundTaskStarted",
task_id: toolCallId,
task_type: "bash",
status: "running",
command,
},
},
});
writeJsonRpcNotification("_x.ai/session/prompt_complete", {
sessionId: requestedSessionId,
promptId: promptIdFromRequestMeta(request) ?? "mock-xai-prompt-1",
stopReason: "end_turn",
agentResult: null,
});
return yield* Effect.never;
}

if (emitInterleavedAssistantToolCalls) {
const toolCallId = "tool-call-1";

Expand Down
2 changes: 2 additions & 0 deletions apps/server/src/bin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import * as NetService from "@t3tools/shared/Net";
import { HostProcessEnvironment } from "@t3tools/shared/hostProcess";
import { DEFAULT_SIGNAL_EXPORT } from "@t3tools/shared/observability";
import * as OtelEnvironment from "@t3tools/shared/otelEnvironment";
import { assert, it } from "@effect/vitest";
import * as Effect from "effect/Effect";
import * as DateTime from "effect/DateTime";
Expand Down Expand Up @@ -106,6 +107,7 @@ const makeCliTestServerConfig = (baseDir: string) =>
otlpMetricsExport: DEFAULT_SIGNAL_EXPORT,
otlpLogsExport: DEFAULT_SIGNAL_EXPORT,
otlpServiceName: "t3-server",
otelEnvironment: OtelEnvironment.none,
mode: "web",
port: 0,
host: "127.0.0.1",
Expand Down
Loading
Loading