@gajae-code/coding-agent 0.18.12 → 0.19.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/CHANGELOG.md +467 -0
- package/dist/types/capability/rule.d.ts +7 -2
- package/dist/types/cli/append-system-prompt.d.ts +6 -0
- package/dist/types/cli/args.d.ts +7 -2
- package/dist/types/cli/customize-doctor-precedence.d.ts +16 -0
- package/dist/types/cli/customize-doctor.d.ts +4 -3
- package/dist/types/cli/public-command-errors.d.ts +1 -0
- package/dist/types/cli/root-flags.d.ts +0 -12
- package/dist/types/cli/update-cli.d.ts +7 -2
- package/dist/types/cli-main.d.ts +0 -6
- package/dist/types/commands/launch.d.ts +0 -6
- package/dist/types/commands/migrate.d.ts +1 -1
- package/dist/types/commands/sdk.d.ts +8 -0
- package/dist/types/commit/map-reduce/index.d.ts +4 -4
- package/dist/types/config/autorouting-tier-map.d.ts +23 -1
- package/dist/types/config/config-hot-reload.d.ts +5 -0
- package/dist/types/config/file-lock.d.ts +44 -2
- package/dist/types/config/model-profile-activation.d.ts +19 -5
- package/dist/types/config/model-registry.d.ts +16 -3
- package/dist/types/config/model-resolver.d.ts +5 -4
- package/dist/types/config/settings-schema.d.ts +11 -1
- package/dist/types/coordinator-mcp/server.d.ts +4 -0
- package/dist/types/customization/import.d.ts +2 -0
- package/dist/types/customization/types.d.ts +1 -1
- package/dist/types/dap/session.d.ts +11 -2
- package/dist/types/discovery/helpers.d.ts +7 -2
- package/dist/types/edit/index.d.ts +5 -0
- package/dist/types/edit/modes/patch.d.ts +9 -0
- package/dist/types/eval/py/runtime.d.ts +9 -0
- package/dist/types/export/ttsr.d.ts +19 -0
- package/dist/types/extensibility/extensions/types.d.ts +5 -1
- package/dist/types/extensibility/slash-commands.d.ts +1 -0
- package/dist/types/gjc-runtime/ralplan-current-final.d.ts +54 -0
- package/dist/types/gjc-runtime/ralplan-runtime.d.ts +5 -0
- package/dist/types/gjc-runtime/tmux-sessions.d.ts +24 -0
- package/dist/types/gjc-runtime/ultragoal-change-set.d.ts +6 -0
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +1 -0
- package/dist/types/harness-control-plane/receipt-spool.d.ts +4 -0
- package/dist/types/hindsight/content.d.ts +5 -6
- package/dist/types/internal-urls/types.d.ts +2 -0
- package/dist/types/lsp/clients/swiftlint-client.d.ts +0 -4
- package/dist/types/main.d.ts +23 -18
- package/dist/types/migrate/action-planner.d.ts +10 -1
- package/dist/types/migrate/adapters/codex.d.ts +1 -1
- package/dist/types/migrate/adapters/index.d.ts +35 -3
- package/dist/types/migrate/hook-module.d.ts +23 -0
- package/dist/types/migrate/report.d.ts +2 -1
- package/dist/types/migrate/types.d.ts +69 -2
- package/dist/types/modes/components/agent-dashboard.d.ts +1 -1
- package/dist/types/modes/components/model-selector.d.ts +43 -0
- package/dist/types/modes/prompt-suggestion-controller.d.ts +1 -1
- package/dist/types/modes/utils/host-status.d.ts +15 -11
- package/dist/types/runtime-mcp/project-host-values.d.ts +11 -5
- package/dist/types/sdk/broker/broker-exit.d.ts +1 -1
- package/dist/types/sdk/broker/broker.d.ts +22 -1
- package/dist/types/sdk/broker/ensure.d.ts +5 -2
- package/dist/types/sdk/broker/hop.d.ts +9 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +22 -0
- package/dist/types/sdk/broker/session-index.d.ts +2 -0
- package/dist/types/sdk/broker/transport.d.ts +2 -0
- package/dist/types/sdk/bus/index.d.ts +21 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +7 -1
- package/dist/types/sdk/bus/telegram-daemon.d.ts +2 -0
- package/dist/types/sdk/bus/threaded-render.d.ts +2 -1
- package/dist/types/sdk/host/control/operations.d.ts +5 -1
- package/dist/types/sdk/host/events.d.ts +4 -0
- package/dist/types/sdk/host/host.d.ts +2 -1
- package/dist/types/sdk/host/prompt-image-upload.d.ts +43 -0
- package/dist/types/sdk/host/session-runtime.d.ts +8 -8
- package/dist/types/sdk/host/surface-policy.d.ts +2 -1
- package/dist/types/sdk/lifecycle/service.d.ts +12 -0
- package/dist/types/sdk/prompt-status.d.ts +11 -4
- package/dist/types/session/agent-session.d.ts +50 -8
- package/dist/types/session/session-manager.d.ts +16 -0
- package/dist/types/skill-state/workflow-mutation-guard.d.ts +13 -1
- package/dist/types/slash-commands/helpers/mcp.d.ts +5 -0
- package/dist/types/ssh/ssh-executor.d.ts +8 -1
- package/dist/types/system-prompt.d.ts +3 -2
- package/dist/types/task/role-body.d.ts +11 -0
- package/dist/types/tools/awaiting-input.d.ts +28 -0
- package/dist/types/tools/bash-allowed-prefixes.d.ts +6 -0
- package/dist/types/tools/bash-skill-urls.d.ts +4 -0
- package/dist/types/tools/bash.d.ts +7 -0
- package/dist/types/tools/descriptors.d.ts +13 -2
- package/dist/types/tools/fetch.d.ts +6 -0
- package/dist/types/tools/irc.d.ts +5 -3
- package/dist/types/tools/tmux-self-injection-guard.d.ts +2 -0
- package/dist/types/tools/ultragoal-ask-guard.d.ts +1 -1
- package/dist/types/tools/write.d.ts +2 -0
- package/dist/types/utils/file-mentions.d.ts +5 -0
- package/dist/types/utils/image-limits.d.ts +7 -0
- package/dist/types/utils/image-loading.d.ts +0 -1
- package/dist/types/utils/open.d.ts +0 -1
- package/dist/types/utils/pasted-image-loading.d.ts +1 -5
- package/dist/types/utils/prompt-suggestion.d.ts +2 -2
- package/dist/types/utils/shell-snapshot.d.ts +2 -0
- package/dist/types/utils/title-generator.d.ts +13 -3
- package/dist/types/web/search/providers/codex.d.ts +6 -7
- package/package.json +9 -8
- package/scripts/acp-conformance-agent.ts +12 -2
- package/scripts/generate-sdk-operation-inventory.ts +16 -0
- package/src/capability/fs.ts +31 -3
- package/src/capability/rule.ts +11 -2
- package/src/cli/append-system-prompt.ts +12 -0
- package/src/cli/args.ts +11 -7
- package/src/cli/customize-doctor-precedence.ts +31 -0
- package/src/cli/customize-doctor.ts +49 -39
- package/src/cli/fast-help.ts +0 -2
- package/src/cli/migrate-cli.ts +14 -3
- package/src/cli/public-command-errors.ts +2 -0
- package/src/cli/root-flags.ts +0 -2
- package/src/cli/update-cli.ts +247 -6
- package/src/commands/harness.ts +25 -15
- package/src/commands/migrate.ts +3 -3
- package/src/commands/sdk.ts +81 -11
- package/src/commit/agentic/agent.ts +6 -6
- package/src/commit/analysis/conventional.ts +14 -5
- package/src/commit/map-reduce/index.ts +7 -7
- package/src/commit/pipeline.ts +12 -12
- package/src/config/autorouting-tier-map.ts +20 -1
- package/src/config/config-file.ts +106 -3
- package/src/config/config-hot-reload.ts +8 -0
- package/src/config/file-lock.ts +1431 -304
- package/src/config/keybindings.ts +154 -7
- package/src/config/model-profile-activation.ts +177 -39
- package/src/config/model-registry.ts +380 -55
- package/src/config/model-resolver.ts +49 -21
- package/src/config/settings-schema.ts +13 -1
- package/src/config/settings.ts +2 -0
- package/src/coordinator-mcp/server.ts +37 -2
- package/src/crash/sanitize.ts +3 -1
- package/src/customization/import.ts +276 -7
- package/src/customization/inventory.ts +24 -8
- package/src/customization/types.ts +1 -0
- package/src/dap/client.ts +3 -2
- package/src/dap/session.ts +161 -36
- package/src/debug/crash-diagnostics.ts +87 -5
- package/src/debug/report-bundle.ts +71 -2
- package/src/discovery/builtin.ts +4 -3
- package/src/discovery/helpers.ts +24 -14
- package/src/edit/index.ts +191 -5
- package/src/edit/modes/patch.ts +27 -0
- package/src/eval/py/runtime.ts +44 -4
- package/src/exec/non-interactive-env.ts +0 -1
- package/src/export/html/index.ts +60 -20
- package/src/export/ttsr.ts +176 -1
- package/src/extensibility/extensions/loader.ts +2 -0
- package/src/extensibility/extensions/ouroboros-ooo-bridge.ts +63 -1
- package/src/extensibility/extensions/types.ts +5 -1
- package/src/extensibility/hooks/loader.ts +10 -2
- package/src/extensibility/plugins/marketplace/manager.ts +36 -10
- package/src/extensibility/slash-commands.ts +5 -0
- package/src/gjc-runtime/gc-runtime.ts +4 -1
- package/src/gjc-runtime/launch-tmux.ts +23 -13
- package/src/gjc-runtime/ralplan-current-final.ts +294 -0
- package/src/gjc-runtime/ralplan-runtime.ts +95 -1
- package/src/gjc-runtime/state-writer.ts +109 -5
- package/src/gjc-runtime/tmux-sessions.ts +93 -13
- package/src/gjc-runtime/ultragoal-change-set.ts +90 -11
- package/src/gjc-runtime/ultragoal-guard.ts +9 -1
- package/src/gjc-runtime/ultragoal-runtime.ts +15 -5
- package/src/harness-control-plane/finalize.ts +11 -0
- package/src/harness-control-plane/receipt-spool.ts +105 -28
- package/src/harness-control-plane/storage.ts +124 -6
- package/src/hindsight/content.ts +116 -16
- package/src/hindsight/mental-models.ts +22 -10
- package/src/hindsight/state.ts +7 -4
- package/src/hooks/native-skill-hook.ts +3 -1
- package/src/internal-urls/artifact-protocol.ts +3 -1
- package/src/internal-urls/docs-index.generated.ts +14 -14
- package/src/internal-urls/local-protocol.ts +28 -3
- package/src/internal-urls/types.ts +2 -0
- package/src/lsp/client.ts +2 -1
- package/src/lsp/clients/biome-client.ts +2 -0
- package/src/lsp/clients/swiftlint-client.ts +2 -0
- package/src/main.ts +330 -92
- package/src/memories/index.ts +25 -2
- package/src/migrate/action-planner.ts +517 -2
- package/src/migrate/adapters/claude-code.ts +141 -3
- package/src/migrate/adapters/codex.ts +57 -5
- package/src/migrate/adapters/index.ts +240 -5
- package/src/migrate/adapters/opencode.ts +4 -0
- package/src/migrate/executor.ts +141 -3
- package/src/migrate/hook-module.ts +193 -0
- package/src/migrate/report.ts +45 -1
- package/src/migrate/types.ts +73 -3
- package/src/modes/acp/acp-agent.ts +10 -1
- package/src/modes/components/agent-dashboard.ts +20 -4
- package/src/modes/components/customization/customization-dashboard.ts +7 -0
- package/src/modes/components/customization/import-wizard.ts +29 -3
- package/src/modes/components/model-selector.ts +157 -103
- package/src/modes/components/welcome.ts +3 -1
- package/src/modes/controllers/command-controller.ts +271 -16
- package/src/modes/controllers/event-controller.ts +1 -1
- package/src/modes/controllers/extension-ui-controller.ts +31 -1
- package/src/modes/controllers/goal-mode-controller.ts +79 -10
- package/src/modes/controllers/input-controller.ts +2 -0
- package/src/modes/controllers/plan-mode-controller.ts +49 -4
- package/src/modes/controllers/runtime-mcp-command-controller.ts +7 -6
- package/src/modes/controllers/selector-controller.ts +14 -1
- package/src/modes/interactive-mode.ts +55 -4
- package/src/modes/prompt-suggestion-controller.ts +1 -1
- package/src/modes/runtime-init.ts +5 -1
- package/src/modes/utils/host-status.ts +21 -10
- package/src/prompts/agent-fragments/browser-aside.md +2 -2
- package/src/prompts/system/irc-incoming.md +3 -1
- package/src/prompts/tools/irc.md +1 -1
- package/src/runtime-mcp/manager.ts +8 -3
- package/src/runtime-mcp/project-host-values.ts +12 -8
- package/src/runtime-mcp/tool-bridge.ts +68 -4
- package/src/runtime-mcp/transports/stdio.ts +2 -1
- package/src/sdk/broker/broker-exit.ts +2 -0
- package/src/sdk/broker/broker.ts +143 -4
- package/src/sdk/broker/ensure.ts +74 -6
- package/src/sdk/broker/hop.ts +13 -1
- package/src/sdk/broker/lifecycle-ledger.ts +3 -0
- package/src/sdk/broker/lifecycle.ts +102 -6
- package/src/sdk/broker/session-index.ts +29 -4
- package/src/sdk/broker/transport.ts +17 -1
- package/src/sdk/bus/chat-daemon-control.ts +2 -2
- package/src/sdk/bus/index.ts +408 -14
- package/src/sdk/bus/session-control.ts +2 -0
- package/src/sdk/bus/slack-daemon.ts +105 -9
- package/src/sdk/bus/telegram-daemon-contract.ts +7 -1
- package/src/sdk/bus/telegram-daemon.ts +10 -2
- package/src/sdk/bus/threaded-render.ts +20 -1
- package/src/sdk/cli/session-cli.ts +2 -0
- package/src/sdk/host/control/dispatch.ts +13 -1
- package/src/sdk/host/control/operations.ts +10 -1
- package/src/sdk/host/events.ts +67 -4
- package/src/sdk/host/host.ts +8 -2
- package/src/sdk/host/prompt-image-upload.ts +438 -0
- package/src/sdk/host/sdk-surface-parity.test.ts +15 -0
- package/src/sdk/host/session-runtime.test.ts +1537 -24
- package/src/sdk/host/session-runtime.ts +332 -36
- package/src/sdk/host/surface-policy.ts +4 -0
- package/src/sdk/host/websocket-transport.lifecycle.test.ts +90 -2
- package/src/sdk/host/websocket-transport.ts +19 -7
- package/src/sdk/lifecycle/service.ts +14 -1
- package/src/sdk/prompt-status.ts +6 -4
- package/src/sdk/protocol/adapter-validation.ts +28 -1
- package/src/sdk/protocol/operation-inventory.generated.json +160 -0
- package/src/sdk/protocol/operation-registry.ts +33 -3
- package/src/sdk/session.ts +123 -36
- package/src/session/agent-session.ts +1614 -329
- package/src/session/history-storage.ts +182 -12
- package/src/session/internal/managed-session-scope.ts +47 -18
- package/src/session/internal/managed-session-storage.ts +71 -1
- package/src/session/session-manager.ts +90 -5
- package/src/session-import/redact.ts +53 -2
- package/src/skill-state/workflow-mutation-guard.ts +1498 -18
- package/src/slash-commands/builtin-registry.ts +6 -3
- package/src/slash-commands/helpers/mcp.ts +11 -3
- package/src/ssh/ssh-executor.ts +9 -2
- package/src/stt/recorder.ts +26 -9
- package/src/system-prompt.ts +61 -16
- package/src/task/executor.ts +12 -8
- package/src/task/role-body.ts +84 -0
- package/src/task/token-log-mode.test.ts +162 -0
- package/src/task/token-log.ts +91 -2
- package/src/tools/archive-reader.ts +650 -37
- package/src/tools/ask.ts +1 -0
- package/src/tools/ast-grep.ts +7 -2
- package/src/tools/auto-generated-guard.ts +12 -3
- package/src/tools/awaiting-input.ts +114 -0
- package/src/tools/bash-allowed-prefixes.ts +61 -1
- package/src/tools/bash-skill-urls.ts +58 -5
- package/src/tools/bash.ts +99 -26
- package/src/tools/browser/tab-worker.ts +39 -13
- package/src/tools/browser.ts +17 -7
- package/src/tools/cron.ts +10 -1
- package/src/tools/debug.ts +9 -2
- package/src/tools/descriptors.test.ts +4 -4
- package/src/tools/descriptors.ts +16 -4
- package/src/tools/eval.ts +15 -0
- package/src/tools/fetch.ts +90 -2
- package/src/tools/gh.ts +27 -12
- package/src/tools/image-gen.ts +20 -6
- package/src/tools/irc.ts +5 -3
- package/src/tools/monitor.ts +9 -1
- package/src/tools/output-meta.ts +51 -3
- package/src/tools/read.ts +9 -2
- package/src/tools/recipe/runner.ts +23 -12
- package/src/tools/render-utils.ts +2 -2
- package/src/tools/search.ts +3 -2
- package/src/tools/ssh.ts +274 -8
- package/src/tools/subagent.ts +10 -4
- package/src/tools/tmux-self-injection-guard.ts +3301 -122
- package/src/tools/tool-catalog.generated.ts +1 -1
- package/src/tools/ultragoal-ask-guard.ts +13 -1
- package/src/tools/write.ts +7 -0
- package/src/tui/tree-list.ts +15 -1
- package/src/utils/commit-message-generator.ts +3 -2
- package/src/utils/external-editor.ts +21 -7
- package/src/utils/file-mentions.ts +46 -6
- package/src/utils/git.ts +38 -7
- package/src/utils/image-limits.ts +8 -0
- package/src/utils/image-loading.ts +1 -1
- package/src/utils/open.ts +73 -4
- package/src/utils/pasted-image-loading.ts +9 -8
- package/src/utils/prompt-suggestion.ts +5 -4
- package/src/utils/shell-snapshot.ts +9 -1
- package/src/utils/title-generator.ts +65 -20
- package/src/web/search/index.ts +2 -1
- package/src/web/search/providers/codex.ts +29 -32
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Generate session titles
|
|
2
|
+
* Generate session titles with the `default` model role.
|
|
3
3
|
*/
|
|
4
4
|
import * as path from "node:path";
|
|
5
5
|
|
|
@@ -10,6 +10,7 @@ import type { ModelRegistry } from "../config/model-registry";
|
|
|
10
10
|
import { resolveRoleSelection } from "../config/model-resolver";
|
|
11
11
|
import type { Settings } from "../config/settings";
|
|
12
12
|
import titleSystemPrompt from "../prompts/system/title-system.md" with { type: "text" };
|
|
13
|
+
import { collectEnvSecrets, createSecretObfuscator, loadSecrets } from "../secrets";
|
|
13
14
|
import { syncCmuxWorkspaceTitle } from "./cmux-workspace";
|
|
14
15
|
import { syncHerdrPaneTitle } from "./herdr-pane";
|
|
15
16
|
|
|
@@ -37,8 +38,13 @@ const MAX_TITLE_WORDS = 12;
|
|
|
37
38
|
* Build a bounded conversation digest for title regeneration. Regeneration
|
|
38
39
|
* reads several messages so a throwaway first prompt can be corrected, while
|
|
39
40
|
* the automatic first-message path intentionally uses only its initial input.
|
|
41
|
+
* `obfuscateText`, when set, runs on each kept message's full text before the
|
|
42
|
+
* per-message character cut so a secret cannot be split by that cut.
|
|
40
43
|
*/
|
|
41
|
-
export function buildConversationTitleInput(
|
|
44
|
+
export function buildConversationTitleInput(
|
|
45
|
+
messages: readonly AgentMessage[],
|
|
46
|
+
obfuscateText?: (text: string) => string,
|
|
47
|
+
): string | undefined {
|
|
42
48
|
const userMessages: string[] = [];
|
|
43
49
|
for (const message of messages) {
|
|
44
50
|
if (message.role !== "user") continue;
|
|
@@ -51,7 +57,10 @@ export function buildConversationTitleInput(messages: readonly AgentMessage[]):
|
|
|
51
57
|
.map(block => block.text)
|
|
52
58
|
.join("\n");
|
|
53
59
|
const trimmed = text.trim();
|
|
54
|
-
if (trimmed)
|
|
60
|
+
if (!trimmed) continue;
|
|
61
|
+
// Emptiness uses the trimmed text. With an obfuscator, keep the original
|
|
62
|
+
// so a secret that includes edge whitespace still matches, then trim.
|
|
63
|
+
userMessages.push(obfuscateText ? text : trimmed);
|
|
55
64
|
}
|
|
56
65
|
|
|
57
66
|
if (userMessages.length === 0) return undefined;
|
|
@@ -60,13 +69,19 @@ export function buildConversationTitleInput(messages: readonly AgentMessage[]):
|
|
|
60
69
|
userMessages.length > MAX_TITLE_CONVERSATION_MESSAGES
|
|
61
70
|
? [userMessages[0]!, ...userMessages.slice(-(MAX_TITLE_CONVERSATION_MESSAGES - 1))]
|
|
62
71
|
: userMessages;
|
|
72
|
+
// Obfuscate the full kept text first. The 400-character cut below, and the
|
|
73
|
+
// later 2,000-character cap, then keep their existing limits.
|
|
74
|
+
const preparedMessages = obfuscateText
|
|
75
|
+
? keptMessages.map(message => obfuscateText(message).trim()).filter(message => message.length > 0)
|
|
76
|
+
: keptMessages;
|
|
77
|
+
if (preparedMessages.length === 0) return undefined;
|
|
63
78
|
// Reserve separator and ellipsis room so the digest is already within the
|
|
64
79
|
// generator's MAX_INPUT_CHARS bound; its existing truncation is a no-op here.
|
|
65
80
|
const maxMessageChars = Math.min(
|
|
66
81
|
MAX_TITLE_MESSAGE_CHARS,
|
|
67
|
-
Math.floor((MAX_INPUT_CHARS - (
|
|
82
|
+
Math.floor((MAX_INPUT_CHARS - (preparedMessages.length - 1) - preparedMessages.length) / preparedMessages.length),
|
|
68
83
|
);
|
|
69
|
-
return
|
|
84
|
+
return preparedMessages
|
|
70
85
|
.map(message => (message.length > maxMessageChars ? `${message.slice(0, maxMessageChars)}…` : message))
|
|
71
86
|
.join("\n");
|
|
72
87
|
}
|
|
@@ -87,8 +102,13 @@ const setTitleTool: Tool = {
|
|
|
87
102
|
},
|
|
88
103
|
};
|
|
89
104
|
|
|
90
|
-
function getTitleModel(
|
|
91
|
-
|
|
105
|
+
function getTitleModel(
|
|
106
|
+
registry: ModelRegistry,
|
|
107
|
+
settings: Settings,
|
|
108
|
+
currentModel?: Model<Api>,
|
|
109
|
+
credentialSessionId?: string,
|
|
110
|
+
): Model<Api> | undefined {
|
|
111
|
+
const availableModels = registry.getAvailable(credentialSessionId);
|
|
92
112
|
if (availableModels.length === 0) return undefined;
|
|
93
113
|
|
|
94
114
|
const titleModel = resolveRoleSelection(["default"], settings, availableModels, registry)?.model;
|
|
@@ -99,6 +119,32 @@ function getTitleModel(registry: ModelRegistry, settings: Settings, currentModel
|
|
|
99
119
|
return undefined;
|
|
100
120
|
}
|
|
101
121
|
|
|
122
|
+
/**
|
|
123
|
+
* Obfuscate the full title input, then truncate, then wrap.
|
|
124
|
+
* A secret that crosses the character cap is replaced before the cut, and the
|
|
125
|
+
* `<user-message>` fence stays outside the truncated body.
|
|
126
|
+
*/
|
|
127
|
+
export function prepareTitleOutboundText(firstMessage: string, obfuscateText?: (text: string) => string): string {
|
|
128
|
+
const source = obfuscateText ? obfuscateText(firstMessage) : firstMessage;
|
|
129
|
+
const truncated = source.length > MAX_INPUT_CHARS ? `${source.slice(0, MAX_INPUT_CHARS)}…` : source;
|
|
130
|
+
return `<user-message>\n${truncated}\n</user-message>`;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export async function titleInputObfuscator(
|
|
134
|
+
settings: Settings,
|
|
135
|
+
activeCwd?: string,
|
|
136
|
+
): Promise<((text: string) => string) | undefined> {
|
|
137
|
+
const reader = settings as Partial<Pick<Settings, "get" | "getCwd" | "getAgentDir">>;
|
|
138
|
+
if (typeof reader.get !== "function" || reader.get("secrets.enabled") !== true) return undefined;
|
|
139
|
+
const cwd = activeCwd ?? (typeof reader.getCwd === "function" ? reader.getCwd() : process.cwd());
|
|
140
|
+
const agentDir = typeof reader.getAgentDir === "function" ? reader.getAgentDir() : cwd;
|
|
141
|
+
const entries = [...collectEnvSecrets(), ...(await loadSecrets(cwd, agentDir))];
|
|
142
|
+
if (entries.length === 0) return undefined;
|
|
143
|
+
const obfuscator = createSecretObfuscator(entries);
|
|
144
|
+
if (!obfuscator.hasSecrets()) return undefined;
|
|
145
|
+
return text => obfuscator.obfuscate(text);
|
|
146
|
+
}
|
|
147
|
+
|
|
102
148
|
/**
|
|
103
149
|
* Generate a title for a session based on the provided user-message input.
|
|
104
150
|
* Automatic titles pass the first user message; regeneration passes a bounded
|
|
@@ -106,13 +152,14 @@ function getTitleModel(registry: ModelRegistry, settings: Settings, currentModel
|
|
|
106
152
|
*
|
|
107
153
|
* @param firstMessage The first user message or bounded conversation digest
|
|
108
154
|
* @param registry Model registry
|
|
109
|
-
* @param settings Settings used to resolve the
|
|
155
|
+
* @param settings Settings used to resolve the `default` model role
|
|
110
156
|
* @param sessionId Optional session id for sticky API key selection
|
|
111
157
|
* @param currentModel Current model (used to derive title model)
|
|
112
158
|
* @param metadataResolver Optional resolver evaluated after credential selection
|
|
113
159
|
* to produce request metadata (e.g. user_id for session attribution). Using a
|
|
114
160
|
* resolver instead of a pre-evaluated value ensures the metadata's account_uuid
|
|
115
161
|
* reflects the credential actually selected for this request.
|
|
162
|
+
* @param activeCwd Active session cwd for project-scoped secret lookup.
|
|
116
163
|
*/
|
|
117
164
|
export async function generateSessionTitle(
|
|
118
165
|
firstMessage: string,
|
|
@@ -121,23 +168,17 @@ export async function generateSessionTitle(
|
|
|
121
168
|
sessionId?: string,
|
|
122
169
|
currentModel?: Model<Api>,
|
|
123
170
|
metadataResolver?: (provider: string) => Record<string, unknown> | undefined,
|
|
171
|
+
activeCwd?: string,
|
|
124
172
|
): Promise<string | null> {
|
|
125
|
-
const model = getTitleModel(registry, settings, currentModel);
|
|
173
|
+
const model = getTitleModel(registry, settings, currentModel, sessionId);
|
|
126
174
|
if (!model) {
|
|
127
175
|
logger.debug("title-generator: no title model found");
|
|
128
176
|
return null;
|
|
129
177
|
}
|
|
130
178
|
|
|
131
|
-
// Truncate message if too long
|
|
132
|
-
const truncatedMessage =
|
|
133
|
-
firstMessage.length > MAX_INPUT_CHARS ? `${firstMessage.slice(0, MAX_INPUT_CHARS)}…` : firstMessage;
|
|
134
|
-
const userMessage = `<user-message>
|
|
135
|
-
${truncatedMessage}
|
|
136
|
-
</user-message>`;
|
|
137
|
-
|
|
138
179
|
const apiKey = await registry.getApiKey(model, sessionId);
|
|
139
180
|
if (!apiKey) {
|
|
140
|
-
logger.debug("title-generator: no API key for
|
|
181
|
+
logger.debug("title-generator: no API key for title model", {
|
|
141
182
|
provider: model.provider,
|
|
142
183
|
id: model.id,
|
|
143
184
|
});
|
|
@@ -147,6 +188,7 @@ ${truncatedMessage}
|
|
|
147
188
|
// request is already recorded; metadataResolver can then return the correct
|
|
148
189
|
// account_uuid rather than the snapshot-at-call-site value.
|
|
149
190
|
const metadata = metadataResolver?.(model.provider);
|
|
191
|
+
const userMessage = prepareTitleOutboundText(firstMessage, await titleInputObfuscator(settings, activeCwd));
|
|
150
192
|
|
|
151
193
|
// Title generation is a 3-6 word task, but some reasoning backends ignore
|
|
152
194
|
// disableReasoning. Keep the normal cheap budget for non-reasoning models
|
|
@@ -187,7 +229,10 @@ ${truncatedMessage}
|
|
|
187
229
|
logger.debug("title-generator: response error", {
|
|
188
230
|
model: request.model,
|
|
189
231
|
stopReason: response.stopReason,
|
|
190
|
-
errorMessage:
|
|
232
|
+
errorMessage:
|
|
233
|
+
typeof response.errorMessage === "string"
|
|
234
|
+
? redactCrashSecrets(response.errorMessage)
|
|
235
|
+
: response.errorMessage,
|
|
191
236
|
});
|
|
192
237
|
return null;
|
|
193
238
|
}
|
|
@@ -196,7 +241,7 @@ ${truncatedMessage}
|
|
|
196
241
|
|
|
197
242
|
logger.debug("title-generator: response", {
|
|
198
243
|
model: request.model,
|
|
199
|
-
title,
|
|
244
|
+
title: redactCrashSecrets(title),
|
|
200
245
|
usage: response.usage,
|
|
201
246
|
stopReason: response.stopReason,
|
|
202
247
|
});
|
|
@@ -209,7 +254,7 @@ ${truncatedMessage}
|
|
|
209
254
|
} catch (err) {
|
|
210
255
|
logger.debug("title-generator: error", {
|
|
211
256
|
model: request.model,
|
|
212
|
-
error: err instanceof Error ? err.message : String(err),
|
|
257
|
+
error: redactCrashSecrets(err instanceof Error ? err.message : String(err)),
|
|
213
258
|
});
|
|
214
259
|
return null;
|
|
215
260
|
}
|
package/src/web/search/index.ts
CHANGED
|
@@ -15,6 +15,7 @@ import webSearchSystemPrompt from "../../prompts/system/web-search.md" with { ty
|
|
|
15
15
|
import webSearchDescription from "../../prompts/tools/web-search.md" with { type: "text" };
|
|
16
16
|
import { discoverAuthStorage } from "../../sdk";
|
|
17
17
|
import type { ToolSession } from "../../tools";
|
|
18
|
+
import { wrapUntrustedContent } from "../../tools/fetch";
|
|
18
19
|
import { formatAge } from "../../tools/render-utils";
|
|
19
20
|
import { throwIfAborted } from "../../tools/tool-errors";
|
|
20
21
|
import {
|
|
@@ -157,7 +158,7 @@ export function formatSearchResponseForLlm(response: SearchResponse): string {
|
|
|
157
158
|
}
|
|
158
159
|
}
|
|
159
160
|
|
|
160
|
-
return
|
|
161
|
+
return wrapUntrustedContent(parts.join("\n"));
|
|
161
162
|
}
|
|
162
163
|
|
|
163
164
|
interface ExecuteSearchOptions {
|
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
* SQLite store, never POSTs the broker sentinel to an OpenAI token endpoint.
|
|
8
8
|
*/
|
|
9
9
|
import * as os from "node:os";
|
|
10
|
-
import {
|
|
10
|
+
import type { AuthStorage } from "@gajae-code/ai/core";
|
|
11
11
|
import { OPENAI_HEADER_VALUES } from "@gajae-code/ai/providers/openai-codex/constants";
|
|
12
|
+
import { fetchCodexModels } from "@gajae-code/ai/utils/discovery/codex";
|
|
12
13
|
import { decodeJwt } from "@gajae-code/ai/utils/oauth/openai-codex";
|
|
13
14
|
import { $env, readSseJson, sanitizeHeaderComponent } from "@gajae-code/utils";
|
|
14
15
|
import packageJson from "../../../../package.json" with { type: "json" };
|
|
@@ -21,17 +22,9 @@ import { classifyProviderHttpError, withHardTimeout } from "./utils";
|
|
|
21
22
|
|
|
22
23
|
const CODEX_BASE_URL = "https://chatgpt.com/backend-api";
|
|
23
24
|
const CODEX_RESPONSES_PATH = "/codex/responses";
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"gpt-5.4",
|
|
28
|
-
"gpt-5-codex",
|
|
29
|
-
"gpt-5",
|
|
30
|
-
"gpt-5.3-codex",
|
|
31
|
-
"gpt-5.2-codex",
|
|
32
|
-
"gpt-5.1-codex",
|
|
33
|
-
"gpt-5-codex-mini",
|
|
34
|
-
];
|
|
25
|
+
// Reviewed search candidates, additionally filtered by current account discovery.
|
|
26
|
+
// Upstream Codex web-search metadata informs this policy, not bundle presence.
|
|
27
|
+
const DEFAULT_MODEL_PREFERENCES = ["gpt-6.1-sol", "gpt-6-luna"];
|
|
35
28
|
const JWT_CLAIM_PATH = "https://api.openai.com/auth";
|
|
36
29
|
const DEFAULT_INSTRUCTIONS =
|
|
37
30
|
"You are a helpful assistant with web search capabilities. Search the web to answer the user's question accurately and cite your sources.";
|
|
@@ -41,21 +34,26 @@ function getConfiguredModel(): string | undefined {
|
|
|
41
34
|
return configuredModel ? configuredModel : undefined;
|
|
42
35
|
}
|
|
43
36
|
|
|
44
|
-
function getDefaultModelCandidates(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
37
|
+
async function getDefaultModelCandidates(
|
|
38
|
+
auth: { accessToken: string; accountId: string },
|
|
39
|
+
signal: AbortSignal | undefined,
|
|
40
|
+
): Promise<string[]> {
|
|
41
|
+
signal?.throwIfAborted();
|
|
42
|
+
const discovery = await fetchCodexModels({ ...auth, signal: withHardTimeout(signal, "llm") });
|
|
43
|
+
signal?.throwIfAborted();
|
|
44
|
+
if (!discovery) {
|
|
45
|
+
throw new SearchProviderError("codex", "Codex model discovery unavailable", 503);
|
|
51
46
|
}
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
if (
|
|
55
|
-
|
|
47
|
+
const advertisedIds = new Set(discovery.models.map(model => model.id));
|
|
48
|
+
const candidates = DEFAULT_MODEL_PREFERENCES.filter(modelId => advertisedIds.has(modelId));
|
|
49
|
+
if (candidates.length === 0) {
|
|
50
|
+
throw new SearchProviderError(
|
|
51
|
+
"codex",
|
|
52
|
+
"No preferred Codex web-search models are advertised for this account",
|
|
53
|
+
503,
|
|
54
|
+
);
|
|
56
55
|
}
|
|
57
|
-
|
|
58
|
-
return bundledModels[0]?.id ? [bundledModels[0].id] : [FALLBACK_MODEL];
|
|
56
|
+
return candidates;
|
|
59
57
|
}
|
|
60
58
|
|
|
61
59
|
function shouldRetryWithNextDefaultModel(error: unknown): boolean {
|
|
@@ -337,12 +335,11 @@ async function callCodexSearch(
|
|
|
337
335
|
* Executes a web search using OpenAI code provider's built-in web search tool.
|
|
338
336
|
*
|
|
339
337
|
* Default-model behavior:
|
|
340
|
-
* -
|
|
341
|
-
* upstream
|
|
342
|
-
* - Otherwise
|
|
343
|
-
*
|
|
344
|
-
*
|
|
345
|
-
* `gpt-5-codex-mini` first on ChatGPT accounts, which OpenAI rejects.
|
|
338
|
+
* - Use `GJC_OPENAI_CODE_WEB_SEARCH_MODEL` (then `PI_CODEX_WEB_SEARCH_MODEL`)
|
|
339
|
+
* exactly once when configured and surface upstream errors without model retries.
|
|
340
|
+
* - Otherwise intersect current account discovery with GPT-6.1 Sol, then GPT-6 Luna.
|
|
341
|
+
* Fail closed when discovery is unavailable or neither candidate is advertised.
|
|
342
|
+
* Retry the next advertised candidate only for the known unsupported-model 400 family.
|
|
346
343
|
*/
|
|
347
344
|
export async function searchCodex(params: SearchParams): Promise<SearchResponse> {
|
|
348
345
|
const auth = await findCodexAuth(params.authStorage, params.sessionId, params.signal);
|
|
@@ -353,7 +350,7 @@ export async function searchCodex(params: SearchParams): Promise<SearchResponse>
|
|
|
353
350
|
}
|
|
354
351
|
|
|
355
352
|
const configuredModel = getConfiguredModel();
|
|
356
|
-
const modelCandidates = configuredModel ? [configuredModel] : getDefaultModelCandidates();
|
|
353
|
+
const modelCandidates = configuredModel ? [configuredModel] : await getDefaultModelCandidates(auth, params.signal);
|
|
357
354
|
|
|
358
355
|
let result:
|
|
359
356
|
| {
|