@gajae-code/coding-agent 0.5.1 → 0.5.3
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 +31 -0
- package/README.md +1 -1
- package/dist/types/async/job-manager.d.ts +6 -0
- package/dist/types/cli/setup-cli.d.ts +8 -1
- package/dist/types/commands/setup.d.ts +7 -0
- package/dist/types/config/file-lock.d.ts +24 -2
- package/dist/types/config/model-registry.d.ts +4 -0
- package/dist/types/config/models-config-schema.d.ts +5 -0
- package/dist/types/config/settings-schema.d.ts +62 -0
- package/dist/types/dap/client.d.ts +2 -1
- package/dist/types/edit/read-file.d.ts +6 -0
- package/dist/types/eval/js/context-manager.d.ts +3 -0
- package/dist/types/eval/js/executor.d.ts +1 -0
- package/dist/types/exec/bash-executor.d.ts +2 -0
- package/dist/types/gjc-runtime/state-writer.d.ts +64 -2
- package/dist/types/gjc-runtime/tmux-sessions.d.ts +7 -1
- package/dist/types/gjc-runtime/ultragoal-guard.d.ts +10 -0
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +29 -0
- package/dist/types/lsp/types.d.ts +2 -0
- package/dist/types/modes/bridge/bridge-mode.d.ts +1 -0
- package/dist/types/modes/components/model-selector.d.ts +2 -0
- package/dist/types/modes/components/oauth-selector.d.ts +1 -0
- package/dist/types/modes/components/provider-onboarding-selector.d.ts +1 -1
- package/dist/types/modes/components/runtime-mcp-add-wizard.d.ts +1 -0
- package/dist/types/modes/components/tool-execution.d.ts +1 -0
- package/dist/types/modes/interactive-mode.d.ts +1 -1
- package/dist/types/modes/rpc/rpc-mode.d.ts +56 -1
- package/dist/types/modes/shared/agent-wire/unattended-session.d.ts +10 -0
- package/dist/types/modes/theme/defaults/index.d.ts +302 -0
- package/dist/types/modes/theme/theme.d.ts +1 -0
- package/dist/types/modes/types.d.ts +1 -1
- package/dist/types/runtime/process-lifecycle.d.ts +108 -0
- package/dist/types/runtime-mcp/transports/stdio.d.ts +1 -0
- package/dist/types/runtime-mcp/types.d.ts +2 -0
- package/dist/types/session/agent-session.d.ts +17 -1
- package/dist/types/session/artifacts.d.ts +4 -1
- package/dist/types/session/history-storage.d.ts +2 -2
- package/dist/types/session/session-manager.d.ts +10 -1
- package/dist/types/session/streaming-output.d.ts +5 -0
- package/dist/types/setup/credential-import.d.ts +79 -0
- package/dist/types/slash-commands/helpers/fast-status-report.d.ts +76 -0
- package/dist/types/task/executor.d.ts +1 -0
- package/dist/types/task/render.d.ts +1 -1
- package/dist/types/tools/bash.d.ts +1 -0
- package/dist/types/tools/browser/tab-supervisor.d.ts +9 -0
- package/dist/types/tools/sqlite-reader.d.ts +2 -1
- package/dist/types/tools/subagent-render.d.ts +7 -1
- package/dist/types/tools/subagent.d.ts +21 -0
- package/dist/types/tools/ultragoal-ask-guard.d.ts +5 -0
- package/dist/types/web/search/index.d.ts +4 -4
- package/dist/types/web/search/provider.d.ts +16 -20
- package/dist/types/web/search/providers/base.d.ts +2 -1
- package/dist/types/web/search/providers/openai-compatible.d.ts +9 -0
- package/dist/types/web/search/types.d.ts +14 -2
- package/package.json +7 -7
- package/scripts/build-binary.ts +7 -0
- package/src/async/job-manager.ts +153 -39
- package/src/cli/args.ts +2 -0
- package/src/cli/fast-help.ts +2 -0
- package/src/cli/setup-cli.ts +138 -3
- package/src/commands/setup.ts +5 -1
- package/src/commands/ultragoal.ts +3 -1
- package/src/config/file-lock-gc.ts +14 -2
- package/src/config/file-lock.ts +63 -13
- package/src/config/model-profile-activation.ts +15 -3
- package/src/config/model-profiles.ts +15 -15
- package/src/config/model-registry.ts +21 -1
- package/src/config/models-config-schema.ts +1 -0
- package/src/config/settings-schema.ts +62 -0
- package/src/dap/client.ts +105 -64
- package/src/dap/session.ts +44 -7
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +30 -8
- package/src/edit/read-file.ts +19 -1
- package/src/eval/js/context-manager.ts +228 -65
- package/src/eval/js/executor.ts +2 -0
- package/src/eval/js/index.ts +1 -0
- package/src/eval/js/worker-core.ts +10 -6
- package/src/eval/py/executor.ts +68 -19
- package/src/eval/py/kernel.ts +46 -22
- package/src/eval/py/runner.py +68 -14
- package/src/exec/bash-executor.ts +49 -13
- package/src/gjc-runtime/deep-interview-recorder.ts +40 -0
- package/src/gjc-runtime/launch-tmux.ts +3 -4
- package/src/gjc-runtime/ralplan-runtime.ts +174 -12
- package/src/gjc-runtime/state-runtime.ts +2 -1
- package/src/gjc-runtime/state-writer.ts +254 -7
- package/src/gjc-runtime/tmux-gc.ts +88 -38
- package/src/gjc-runtime/tmux-sessions.ts +44 -6
- package/src/gjc-runtime/ultragoal-guard.ts +155 -0
- package/src/gjc-runtime/ultragoal-runtime.ts +1227 -31
- package/src/gjc-runtime/workflow-manifest.generated.json +44 -0
- package/src/gjc-runtime/workflow-manifest.ts +12 -0
- package/src/harness-control-plane/owner.ts +3 -2
- package/src/harness-control-plane/rpc-adapter.ts +1 -1
- package/src/hooks/skill-state.ts +121 -2
- package/src/internal-urls/artifact-protocol.ts +10 -1
- package/src/internal-urls/docs-index.generated.ts +14 -10
- package/src/lsp/client.ts +64 -26
- package/src/lsp/defaults.json +1 -0
- package/src/lsp/index.ts +2 -1
- package/src/lsp/lspmux.ts +33 -9
- package/src/lsp/types.ts +2 -0
- package/src/main.ts +14 -4
- package/src/modes/acp/acp-agent.ts +4 -2
- package/src/modes/bridge/bridge-mode.ts +23 -1
- package/src/modes/components/assistant-message.ts +10 -2
- package/src/modes/components/bash-execution.ts +5 -1
- package/src/modes/components/eval-execution.ts +5 -1
- package/src/modes/components/history-search.ts +5 -2
- package/src/modes/components/model-selector.ts +60 -2
- package/src/modes/components/oauth-selector.ts +5 -0
- package/src/modes/components/provider-onboarding-selector.ts +6 -1
- package/src/modes/components/runtime-mcp-add-wizard.ts +58 -7
- package/src/modes/components/skill-message.ts +24 -16
- package/src/modes/components/tool-execution.ts +6 -0
- package/src/modes/controllers/extension-ui-controller.ts +33 -6
- package/src/modes/controllers/input-controller.ts +5 -0
- package/src/modes/controllers/selector-controller.ts +86 -2
- package/src/modes/interactive-mode.ts +11 -1
- package/src/modes/rpc/rpc-mode.ts +132 -18
- package/src/modes/shared/agent-wire/command-dispatch.ts +5 -2
- package/src/modes/shared/agent-wire/host-tool-bridge.ts +3 -0
- package/src/modes/shared/agent-wire/unattended-session.ts +16 -1
- package/src/modes/theme/defaults/claude-code.json +100 -0
- package/src/modes/theme/defaults/codex.json +100 -0
- package/src/modes/theme/defaults/index.ts +6 -0
- package/src/modes/theme/defaults/opencode.json +102 -0
- package/src/modes/theme/theme.ts +2 -2
- package/src/modes/types.ts +1 -1
- package/src/modes/utils/ui-helpers.ts +5 -2
- package/src/prompts/agents/executor.md +5 -2
- package/src/runtime/process-lifecycle.ts +400 -0
- package/src/runtime-mcp/manager.ts +164 -50
- package/src/runtime-mcp/transports/http.ts +12 -11
- package/src/runtime-mcp/transports/stdio.ts +64 -38
- package/src/runtime-mcp/types.ts +3 -0
- package/src/sdk.ts +39 -1
- package/src/session/agent-session.ts +190 -33
- package/src/session/artifacts.ts +17 -2
- package/src/session/blob-store.ts +36 -2
- package/src/session/history-storage.ts +32 -11
- package/src/session/session-manager.ts +99 -31
- package/src/session/streaming-output.ts +54 -3
- package/src/setup/credential-import.ts +429 -0
- package/src/skill-state/deep-interview-mutation-guard.ts +2 -1
- package/src/slash-commands/builtin-registry.ts +30 -3
- package/src/slash-commands/helpers/fast-status-report.ts +111 -0
- package/src/task/executor.ts +7 -1
- package/src/task/render.ts +18 -7
- package/src/tools/archive-reader.ts +10 -1
- package/src/tools/ask.ts +4 -2
- package/src/tools/bash.ts +11 -4
- package/src/tools/browser/tab-supervisor.ts +22 -0
- package/src/tools/browser.ts +38 -4
- package/src/tools/cron.ts +1 -1
- package/src/tools/read.ts +11 -12
- package/src/tools/sqlite-reader.ts +19 -5
- package/src/tools/subagent-render.ts +119 -29
- package/src/tools/subagent.ts +147 -7
- package/src/tools/ultragoal-ask-guard.ts +39 -0
- package/src/web/search/index.ts +25 -25
- package/src/web/search/provider.ts +178 -87
- package/src/web/search/providers/base.ts +2 -1
- package/src/web/search/providers/openai-compatible.ts +151 -0
- package/src/web/search/types.ts +47 -22
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AuthStorage } from "@gajae-code/ai";
|
|
2
|
-
import type { SearchProviderId, SearchResponse } from "../types";
|
|
2
|
+
import type { ActiveSearchModelContext, SearchProviderId, SearchResponse } from "../types";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Shared web search parameters passed to providers.
|
|
@@ -50,6 +50,7 @@ export interface SearchParams {
|
|
|
50
50
|
* caller's agent session when available; otherwise omit.
|
|
51
51
|
*/
|
|
52
52
|
sessionId?: string;
|
|
53
|
+
activeModelContext?: ActiveSearchModelContext;
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
/** Base class for web search providers. */
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import type { SearchCitation, SearchResponse, SearchSource } from "../types";
|
|
2
|
+
import { SearchProviderError } from "../types";
|
|
3
|
+
import type { SearchParams } from "./base";
|
|
4
|
+
import { SearchProvider } from "./base";
|
|
5
|
+
import { classifyProviderHttpError, withHardTimeout } from "./utils";
|
|
6
|
+
|
|
7
|
+
function endpoint(baseUrl: string, api: string): string {
|
|
8
|
+
const base = baseUrl.replace(/\/+$/, "");
|
|
9
|
+
return api === "openai-completions" ? `${base}/chat/completions` : `${base}/responses`;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function textFromResponse(json: any): string | undefined {
|
|
13
|
+
if (typeof json.output_text === "string") return json.output_text;
|
|
14
|
+
const chunks: string[] = [];
|
|
15
|
+
for (const item of json.output ?? []) {
|
|
16
|
+
for (const content of item.content ?? []) {
|
|
17
|
+
if (typeof content.text === "string") chunks.push(content.text);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const chat = json.choices?.[0]?.message?.content;
|
|
21
|
+
if (typeof chat === "string") chunks.push(chat);
|
|
22
|
+
return chunks.join("\n") || undefined;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function pushCitation(out: SearchCitation[], rawUrl: unknown, rawTitle: unknown, rawText: unknown): void {
|
|
26
|
+
if (typeof rawUrl !== "string" || !rawUrl) return;
|
|
27
|
+
out.push({
|
|
28
|
+
url: rawUrl,
|
|
29
|
+
title: typeof rawTitle === "string" && rawTitle ? rawTitle : rawUrl,
|
|
30
|
+
citedText: typeof rawText === "string" ? rawText : undefined,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Only recognized grounding annotations count as citations. An OpenAI-compatible
|
|
35
|
+
// endpoint that ignores the web_search request returns a normal answer with no
|
|
36
|
+
// `url_citation` annotations; treating arbitrary URL/`type:"source"` metadata as a
|
|
37
|
+
// citation would mask that non-search answer as a real search result. Restrict
|
|
38
|
+
// extraction to the documented annotation shapes (Responses
|
|
39
|
+
// `output[].content[].annotations[]` and Chat `choices[].message.annotations[]`),
|
|
40
|
+
// accepting only `type: "url_citation"` entries.
|
|
41
|
+
function collectCitationAnnotations(annotations: unknown, out: SearchCitation[]): void {
|
|
42
|
+
if (!Array.isArray(annotations)) return;
|
|
43
|
+
for (const annotation of annotations) {
|
|
44
|
+
if (!annotation || typeof annotation !== "object") continue;
|
|
45
|
+
const ann = annotation as Record<string, any>;
|
|
46
|
+
if (ann.type !== "url_citation") continue;
|
|
47
|
+
const cite =
|
|
48
|
+
ann.url_citation && typeof ann.url_citation === "object" ? (ann.url_citation as Record<string, any>) : ann;
|
|
49
|
+
pushCitation(out, cite.url ?? cite.uri, cite.title, cite.text ?? cite.quote ?? ann.text);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function parseCitations(json: any): SearchCitation[] {
|
|
54
|
+
const citations: SearchCitation[] = [];
|
|
55
|
+
for (const item of json?.output ?? []) {
|
|
56
|
+
for (const content of item?.content ?? []) {
|
|
57
|
+
collectCitationAnnotations(content?.annotations, citations);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
for (const choice of json?.choices ?? []) {
|
|
61
|
+
collectCitationAnnotations(choice?.message?.annotations, citations);
|
|
62
|
+
}
|
|
63
|
+
const seen = new Set<string>();
|
|
64
|
+
return citations.filter(c => {
|
|
65
|
+
if (seen.has(c.url)) return false;
|
|
66
|
+
seen.add(c.url);
|
|
67
|
+
return true;
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function toSources(citations: SearchCitation[], limit: number): SearchSource[] {
|
|
72
|
+
return citations.slice(0, limit).map(c => ({ title: c.title || c.url, url: c.url, snippet: c.citedText }));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export class OpenAICompatibleSearchProvider extends SearchProvider {
|
|
76
|
+
readonly id = "openai-compatible" as const;
|
|
77
|
+
readonly label = "OpenAI-compatible";
|
|
78
|
+
|
|
79
|
+
isAvailable(): boolean {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async search(params: SearchParams): Promise<SearchResponse> {
|
|
84
|
+
const ctx = params.activeModelContext;
|
|
85
|
+
if (!ctx)
|
|
86
|
+
throw new SearchProviderError(this.id, "OpenAI-compatible web search requires active model context", 400);
|
|
87
|
+
if (ctx.api !== "openai-responses" && ctx.api !== "openai-completions") {
|
|
88
|
+
throw new SearchProviderError(this.id, `OpenAI-compatible web search does not support ${ctx.api}`, 400);
|
|
89
|
+
}
|
|
90
|
+
const apiKey = await params.authStorage.getApiKey(ctx.provider, params.sessionId, {
|
|
91
|
+
baseUrl: ctx.baseUrl,
|
|
92
|
+
modelId: ctx.modelId,
|
|
93
|
+
signal: params.signal,
|
|
94
|
+
});
|
|
95
|
+
if (!apiKey) throw new SearchProviderError(this.id, `No credentials for ${ctx.provider}`, 401);
|
|
96
|
+
const model = ctx.wireModelId ?? ctx.modelId;
|
|
97
|
+
const headers = { ...(ctx.headers ?? {}), Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" };
|
|
98
|
+
const body =
|
|
99
|
+
ctx.api === "openai-completions"
|
|
100
|
+
? {
|
|
101
|
+
model,
|
|
102
|
+
messages: [
|
|
103
|
+
{ role: "system", content: params.systemPrompt },
|
|
104
|
+
{ role: "user", content: params.query },
|
|
105
|
+
],
|
|
106
|
+
web_search_options: {},
|
|
107
|
+
temperature: params.temperature,
|
|
108
|
+
max_tokens: params.maxOutputTokens,
|
|
109
|
+
}
|
|
110
|
+
: {
|
|
111
|
+
model,
|
|
112
|
+
input: [
|
|
113
|
+
{ role: "system", content: params.systemPrompt },
|
|
114
|
+
{ role: "user", content: params.query },
|
|
115
|
+
],
|
|
116
|
+
tools: [{ type: "web_search" }],
|
|
117
|
+
temperature: params.temperature,
|
|
118
|
+
max_output_tokens: params.maxOutputTokens,
|
|
119
|
+
};
|
|
120
|
+
const response = await fetch(endpoint(ctx.baseUrl ?? "", ctx.api), {
|
|
121
|
+
method: "POST",
|
|
122
|
+
headers,
|
|
123
|
+
body: JSON.stringify(body),
|
|
124
|
+
signal: withHardTimeout(params.signal),
|
|
125
|
+
});
|
|
126
|
+
const text = await response.text();
|
|
127
|
+
if (!response.ok) {
|
|
128
|
+
const classified = classifyProviderHttpError(this.id, response.status, text);
|
|
129
|
+
if (classified) throw classified;
|
|
130
|
+
throw new SearchProviderError(
|
|
131
|
+
this.id,
|
|
132
|
+
`OpenAI-compatible web search error (${response.status}): ${text}`,
|
|
133
|
+
response.status,
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
const json = text ? JSON.parse(text) : {};
|
|
137
|
+
const citations = parseCitations(json);
|
|
138
|
+
if (citations.length === 0) {
|
|
139
|
+
throw new SearchProviderError(this.id, "OpenAI-compatible web search returned no citations", 424);
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
provider: this.id,
|
|
143
|
+
answer: textFromResponse(json),
|
|
144
|
+
sources: toSources(citations, params.limit ?? params.numSearchResults ?? 10),
|
|
145
|
+
citations,
|
|
146
|
+
model,
|
|
147
|
+
requestId: json.id,
|
|
148
|
+
authMode: "api-key",
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
}
|
package/src/web/search/types.ts
CHANGED
|
@@ -20,30 +20,55 @@ export type SearchProviderId =
|
|
|
20
20
|
| "parallel"
|
|
21
21
|
| "kagi"
|
|
22
22
|
| "synthetic"
|
|
23
|
-
| "searxng"
|
|
23
|
+
| "searxng"
|
|
24
|
+
| "openai-compatible";
|
|
25
|
+
|
|
26
|
+
export type WebSearchMode = "on" | "off" | "auto";
|
|
27
|
+
|
|
28
|
+
export interface ActiveSearchModelContext {
|
|
29
|
+
provider: string;
|
|
30
|
+
modelId: string;
|
|
31
|
+
wireModelId?: string;
|
|
32
|
+
api: string;
|
|
33
|
+
baseUrl?: string;
|
|
34
|
+
headers?: Record<string, string>;
|
|
35
|
+
webSearch?: WebSearchMode;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const CONFIGURABLE_SEARCH_PROVIDER_IDS = [
|
|
39
|
+
"duckduckgo",
|
|
40
|
+
"exa",
|
|
41
|
+
"brave",
|
|
42
|
+
"jina",
|
|
43
|
+
"kimi",
|
|
44
|
+
"zai",
|
|
45
|
+
"anthropic",
|
|
46
|
+
"perplexity",
|
|
47
|
+
"gemini",
|
|
48
|
+
"codex",
|
|
49
|
+
"tavily",
|
|
50
|
+
"parallel",
|
|
51
|
+
"kagi",
|
|
52
|
+
"synthetic",
|
|
53
|
+
"searxng",
|
|
54
|
+
] as const satisfies readonly SearchProviderId[];
|
|
55
|
+
|
|
56
|
+
const SEARCH_PROVIDER_IDS = [...CONFIGURABLE_SEARCH_PROVIDER_IDS, "openai-compatible"] as const;
|
|
24
57
|
|
|
25
58
|
export function isSearchProviderId(value: string): value is SearchProviderId {
|
|
26
|
-
return [
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
"kagi",
|
|
40
|
-
"synthetic",
|
|
41
|
-
"searxng",
|
|
42
|
-
].includes(value);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function isSearchProviderPreference(value: string): value is SearchProviderId | "auto" {
|
|
46
|
-
return value === "auto" || isSearchProviderId(value);
|
|
59
|
+
return (SEARCH_PROVIDER_IDS as readonly string[]).includes(value);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function isConfigurableSearchProviderId(
|
|
63
|
+
value: string,
|
|
64
|
+
): value is (typeof CONFIGURABLE_SEARCH_PROVIDER_IDS)[number] {
|
|
65
|
+
return (CONFIGURABLE_SEARCH_PROVIDER_IDS as readonly string[]).includes(value);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function isSearchProviderPreference(
|
|
69
|
+
value: string,
|
|
70
|
+
): value is (typeof CONFIGURABLE_SEARCH_PROVIDER_IDS)[number] | "auto" {
|
|
71
|
+
return value === "auto" || isConfigurableSearchProviderId(value);
|
|
47
72
|
}
|
|
48
73
|
|
|
49
74
|
/** Source returned by search (all providers) */
|