dsh-agy-link 0.4.33 → 0.4.34
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 +11 -0
- package/dist/client.js +76 -6
- package/dist/index.js +29 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.4.34 (2026-09-18)
|
|
4
|
+
|
|
5
|
+
### English
|
|
6
|
+
|
|
7
|
+
- **UI: cleaner tool cards in Code Mode.** When DSH registers `agy_tool`, the bridge now emits native tool-call blocks instead of `run_code` wrappers. Code Mode titles use a human preview (`$ ls · run_command`) instead of `replay agy tool step N`. A `run_code` toolview renders Antigravity cards when the program is still a mirror wrapper.
|
|
8
|
+
- **UI: less thinking spam.** Banner-only `[agy thinking turn · N tokens]` chips (no prose) emit at most once per run; turns that extract thought prose still show full reasoning.
|
|
9
|
+
|
|
10
|
+
### 中文 (Chinese)
|
|
11
|
+
|
|
12
|
+
- **界面:** Code Mode 下工具卡片更干净;有 prose 的思考仍完整展示,无正文的 token 横幅每轮最多一条。
|
|
13
|
+
|
|
3
14
|
## 0.4.33 (2026-09-18)
|
|
4
15
|
|
|
5
16
|
### English
|
package/dist/client.js
CHANGED
|
@@ -664,13 +664,83 @@ window.__ModuleLoader__.load({
|
|
|
664
664
|
inspect
|
|
665
665
|
}))] : []);
|
|
666
666
|
}
|
|
667
|
+
/** Extract the agy mirror cursor (and tool name) from a run_code program. */
|
|
668
|
+
function parseAgyMirrorFromCode(argsRaw) {
|
|
669
|
+
try {
|
|
670
|
+
const parsed = JSON.parse(argsRaw);
|
|
671
|
+
const code = typeof parsed?.code === "string" ? parsed.code : "";
|
|
672
|
+
const m = /tools\['agy_tool'\]\((\{.*?"step":\d+\})\)/.exec(code);
|
|
673
|
+
if (!m) return null;
|
|
674
|
+
const v = JSON.parse(m[1]);
|
|
675
|
+
if (typeof v.run !== "string" || typeof v.step !== "number") return null;
|
|
676
|
+
const tm = /replay recorded agy tool step \d+ \(([^)]+)\)/.exec(code);
|
|
677
|
+
return {
|
|
678
|
+
run: v.run,
|
|
679
|
+
step: v.step,
|
|
680
|
+
tool: tm?.[1]
|
|
681
|
+
};
|
|
682
|
+
} catch {}
|
|
683
|
+
return null;
|
|
684
|
+
}
|
|
685
|
+
/**
|
|
686
|
+
* run_code toolview: when the program is an agy mirror wrapper, render the
|
|
687
|
+
* native Antigravity card instead of a raw code row. Other run_code calls
|
|
688
|
+
* fall through to the host renderer via a minimal wrapper that still shows
|
|
689
|
+
* something useful.
|
|
690
|
+
*/
|
|
691
|
+
function AgyRunCodeToolView(props) {
|
|
692
|
+
const block = props?.block;
|
|
693
|
+
const raw = block !== void 0 ? parsedArgsRaw(block) : "{}";
|
|
694
|
+
const mirror = parseAgyMirrorFromCode(raw);
|
|
695
|
+
if (mirror === null) {
|
|
696
|
+
let code = "";
|
|
697
|
+
try {
|
|
698
|
+
const parsed = JSON.parse(raw);
|
|
699
|
+
code = typeof parsed?.code === "string" ? parsed.code : raw;
|
|
700
|
+
} catch {
|
|
701
|
+
code = raw;
|
|
702
|
+
}
|
|
703
|
+
return hx("div", { className: cls("agy-tv-root") }, hx("div", { className: "agy-tv-header" }, hx("span", { className: "agy-tv-title" }, "run_code"), hx("span", { className: "agy-tv-badge" }, "code")), hx("pre", {
|
|
704
|
+
className: "agy-tv-pre",
|
|
705
|
+
style: {
|
|
706
|
+
margin: 0,
|
|
707
|
+
whiteSpace: "pre-wrap",
|
|
708
|
+
fontSize: "12px"
|
|
709
|
+
}
|
|
710
|
+
}, code.slice(0, 400)));
|
|
711
|
+
}
|
|
712
|
+
return AgyMirrorToolView({ block: {
|
|
713
|
+
...block,
|
|
714
|
+
call: {
|
|
715
|
+
...block?.call ?? {},
|
|
716
|
+
name: "agy_tool",
|
|
717
|
+
argsRaw: JSON.stringify({
|
|
718
|
+
run: mirror.run,
|
|
719
|
+
step: mirror.step,
|
|
720
|
+
...mirror.tool !== void 0 ? { tool: mirror.tool } : {}
|
|
721
|
+
})
|
|
722
|
+
}
|
|
723
|
+
} });
|
|
724
|
+
}
|
|
667
725
|
function installAgyToolView(ctx) {
|
|
668
|
-
ctx.slots.inject("tool.call.toolview", () =>
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
726
|
+
ctx.slots.inject("tool.call.toolview", () => {
|
|
727
|
+
const d1 = ctx.slots.register({
|
|
728
|
+
name: "tool.call.toolview",
|
|
729
|
+
key: "agy_tool",
|
|
730
|
+
id: "agy-tool-view",
|
|
731
|
+
label: "Antigravity tool"
|
|
732
|
+
}, AgyMirrorToolView);
|
|
733
|
+
const d2 = ctx.slots.register({
|
|
734
|
+
name: "tool.call.toolview",
|
|
735
|
+
key: "run_code",
|
|
736
|
+
id: "agy-run-code-view",
|
|
737
|
+
label: "Antigravity (code mode)"
|
|
738
|
+
}, AgyRunCodeToolView);
|
|
739
|
+
return () => {
|
|
740
|
+
d2();
|
|
741
|
+
d1();
|
|
742
|
+
};
|
|
743
|
+
});
|
|
674
744
|
}
|
|
675
745
|
const ROW_CSS = `
|
|
676
746
|
/* Container */
|
package/dist/index.js
CHANGED
|
@@ -650,16 +650,37 @@ function getGitHeadContent(filePath, execFn = execFileSync) {
|
|
|
650
650
|
* whose single statement calls the registered mirror tool — the inner
|
|
651
651
|
* dispatch is what renders the native tool card.
|
|
652
652
|
*/
|
|
653
|
-
function buildMirrorRunCode(runId, eventIndex, toolName) {
|
|
653
|
+
function buildMirrorRunCode(runId, eventIndex, toolName, brief) {
|
|
654
654
|
const invocation = JSON.stringify({
|
|
655
655
|
run: runId,
|
|
656
656
|
step: eventIndex
|
|
657
657
|
});
|
|
658
658
|
return {
|
|
659
659
|
code: "// dsh-agy-link mirror: replay recorded agy tool step " + eventIndex + " (" + toolName + ")\nreturn await tools['agy_tool'](" + invocation + ")",
|
|
660
|
-
description:
|
|
660
|
+
description: brief !== void 0 && brief !== "" ? brief + " · " + toolName : toolName
|
|
661
661
|
};
|
|
662
662
|
}
|
|
663
|
+
/** Short human preview for a recorded tool step (used in Code Mode titles). */
|
|
664
|
+
function toolStepBrief(toolName, args) {
|
|
665
|
+
const a = args !== null && typeof args === "object" ? args : {};
|
|
666
|
+
const pickStr = (...keys) => {
|
|
667
|
+
for (const k of keys) {
|
|
668
|
+
const v = a[k];
|
|
669
|
+
if (typeof v === "string" && v.trim() !== "") return v.trim();
|
|
670
|
+
}
|
|
671
|
+
return "";
|
|
672
|
+
};
|
|
673
|
+
if (toolName === "run_command" || toolName === "execute_command") {
|
|
674
|
+
const cmd = pickStr("Command", "command", "Cmd", "cmd");
|
|
675
|
+
return cmd !== "" ? "$ " + cmd.slice(0, 80) : "run command";
|
|
676
|
+
}
|
|
677
|
+
if (toolName === "view_file" || toolName === "read_file") return "read " + (pickStr("Path", "path", "TargetFile", "File") || "file");
|
|
678
|
+
if (toolName === "write_to_file" || toolName === "create_file") return "write " + (pickStr("Path", "path", "TargetFile", "File") || "file");
|
|
679
|
+
if (toolName === "replace_file_content" || toolName === "edit_file") return "edit " + (pickStr("Path", "path", "TargetFile", "File") || "file");
|
|
680
|
+
if (toolName === "grep_search" || toolName === "search") return "search " + (pickStr("Query", "query", "SearchPattern") || "");
|
|
681
|
+
if (toolName === "list_dir" || toolName === "list_directory") return "ls " + (pickStr("Path", "path", "DirectoryPath") || ".");
|
|
682
|
+
return toolName;
|
|
683
|
+
}
|
|
663
684
|
/** agy serializes some tool args as a JSON string; presenters get an object. */
|
|
664
685
|
function toolInput(args) {
|
|
665
686
|
const raw = args.input;
|
|
@@ -967,6 +988,7 @@ var EventMapper = class {
|
|
|
967
988
|
emittedByKey = /* @__PURE__ */ new Map();
|
|
968
989
|
announcedTools = /* @__PURE__ */ new Set();
|
|
969
990
|
thinkingAnnounced = /* @__PURE__ */ new Set();
|
|
991
|
+
bannerOnlyThinkingEmitted = false;
|
|
970
992
|
sawTextStep;
|
|
971
993
|
finished = false;
|
|
972
994
|
constructor(opts) {
|
|
@@ -1031,6 +1053,7 @@ var EventMapper = class {
|
|
|
1031
1053
|
const text = this.opts.resolvedThoughts?.get(absIndex);
|
|
1032
1054
|
const hasText = text !== void 0 && text.trim() !== "";
|
|
1033
1055
|
if (!hasText && thoughtTokens <= 0) return;
|
|
1056
|
+
if (!hasText && this.bannerOnlyThinkingEmitted) return;
|
|
1034
1057
|
yield* this.ensureBlock("reasoning");
|
|
1035
1058
|
const banner = thoughtTokens > 0 ? "[agy thinking turn · " + thoughtTokens + " thinking tokens]" : "[agy thinking turn]";
|
|
1036
1059
|
if (hasText) {
|
|
@@ -1038,6 +1061,7 @@ var EventMapper = class {
|
|
|
1038
1061
|
const d = this.appendDelta(combined);
|
|
1039
1062
|
if (d) yield d;
|
|
1040
1063
|
} else {
|
|
1064
|
+
this.bannerOnlyThinkingEmitted = true;
|
|
1041
1065
|
const d = this.appendDelta(`${banner}\n`);
|
|
1042
1066
|
if (d) yield d;
|
|
1043
1067
|
}
|
|
@@ -1125,7 +1149,7 @@ var EventMapper = class {
|
|
|
1125
1149
|
...fullArgs,
|
|
1126
1150
|
...typeof ev.tool.args === "object" ? ev.tool.args : {}
|
|
1127
1151
|
} : ev.tool.args;
|
|
1128
|
-
const argumentsJson = useCode ? JSON.stringify(buildMirrorRunCode(this.opts.runId, absIndex, ev.tool.name)) : JSON.stringify({
|
|
1152
|
+
const argumentsJson = useCode ? JSON.stringify(buildMirrorRunCode(this.opts.runId, absIndex, ev.tool.name, toolStepBrief(ev.tool.name, effectiveArgs))) : JSON.stringify({
|
|
1129
1153
|
run: this.opts.runId,
|
|
1130
1154
|
step: absIndex,
|
|
1131
1155
|
tool: ev.tool.name,
|
|
@@ -2824,7 +2848,8 @@ var AgyAdapter = class extends LlmAdapter {
|
|
|
2824
2848
|
if (!bin) throw new LlmError("agy binary not found on PATH — install it via https://antigravity.google/docs/cli/install", Err.AGY_NOT_INSTALLED);
|
|
2825
2849
|
const isAux = options.purpose === "compaction" || options.purpose === "session-title";
|
|
2826
2850
|
if (isAux && !cfg.allowAuxiliary) throw new LlmError("auxiliary calls are disabled for the antigravity route (allowAuxiliary: false)", Err.AUX_DISABLED);
|
|
2827
|
-
const
|
|
2851
|
+
const toolNames = new Set((options.tools ?? []).map((t) => t.name));
|
|
2852
|
+
const isCodeMode = toolNames.has("run_code") && !toolNames.has("agy_tool");
|
|
2828
2853
|
const sessionKey = options.sessionId !== void 0 ? String(options.sessionId) : "";
|
|
2829
2854
|
let workspaceRoot = cfg.workspaceRoot;
|
|
2830
2855
|
if (workspaceRoot === "") {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-agy-link",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.34",
|
|
4
4
|
"description": "Google Antigravity (agy CLI) models for DeepSeek Harness — stream Gemini/Claude/GPT-OSS subscriptions into DSH with thinking, tool activity, token usage and in-GUI Google OAuth login.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|