@ycodium-ai/agent-grok 0.2.2888 → 0.2.2892

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.
Files changed (2) hide show
  1. package/dist/index.js +121 -27
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -160,7 +160,7 @@ var GROK_CARD = {
160
160
  // src/grokInstance.ts
161
161
  import * as NodeCrypto2 from "node:crypto";
162
162
  import * as NodeOS2 from "node:os";
163
- import * as NodePath4 from "node:path";
163
+ import * as NodePath5 from "node:path";
164
164
  import { mergeLaunchEnv } from "@ycodium-ai/plugin-api/executor";
165
165
  import { nodeStreamsFromHandle as nodeStreamsFromHandle2 } from "@ycodium-ai/plugin-api/process-stdin";
166
166
 
@@ -24194,6 +24194,60 @@ function approvalOutcomeForDecision(decision, optionId) {
24194
24194
  return decision !== "cancel" && optionId !== void 0 ? { outcome: "selected", optionId } : { outcome: "cancelled" };
24195
24195
  }
24196
24196
 
24197
+ // ../../packages/ycodium-acp-executor/src/artifacts.ts
24198
+ import * as NodePath from "node:path";
24199
+ import * as NodeURL from "node:url";
24200
+ function resourceLinkArtifacts(content) {
24201
+ if (content["type"] !== "resource_link" || typeof content["uri"] !== "string") return [];
24202
+ const uri = content["uri"].trim();
24203
+ let path;
24204
+ try {
24205
+ path = uri.toLowerCase().startsWith("file:") ? NodeURL.fileURLToPath(uri) : uri;
24206
+ } catch {
24207
+ return [];
24208
+ }
24209
+ if (!NodePath.isAbsolute(path)) return [];
24210
+ const name = typeof content["name"] === "string" ? content["name"].trim() : "";
24211
+ const mimeType = typeof content["mimeType"] === "string" ? content["mimeType"].trim() : "";
24212
+ return [
24213
+ {
24214
+ path,
24215
+ ...name.length > 0 ? { name } : {},
24216
+ ...mimeType.length > 0 ? { mimeType } : {}
24217
+ }
24218
+ ];
24219
+ }
24220
+ function acpArtifactEvent(input2) {
24221
+ if (input2.artifacts.length === 0) return void 0;
24222
+ const { toolCallId } = input2;
24223
+ return {
24224
+ ...input2.base,
24225
+ type: "assistant.artifact.produced",
24226
+ payload: {
24227
+ artifacts: input2.artifacts.map((artifact) => ({
24228
+ ...artifact,
24229
+ ...toolCallId !== void 0 ? { toolCallId } : {}
24230
+ }))
24231
+ }
24232
+ };
24233
+ }
24234
+ function makeArtifactEmitter(input2) {
24235
+ return (artifacts, toolCallId) => {
24236
+ const turnId = input2.turnId();
24237
+ const event = acpArtifactEvent({
24238
+ artifacts,
24239
+ toolCallId,
24240
+ base: {
24241
+ ...input2.stamp(),
24242
+ provider: input2.options.provider,
24243
+ threadId: input2.options.threadId,
24244
+ ...turnId === void 0 ? {} : { turnId }
24245
+ }
24246
+ });
24247
+ if (event !== void 0) input2.emit(event);
24248
+ };
24249
+ }
24250
+
24197
24251
  // ../../packages/ycodium-acp-executor/src/event-stream.ts
24198
24252
  var UnboundedEventStream = class {
24199
24253
  subscribers = /* @__PURE__ */ new Set();
@@ -25599,9 +25653,8 @@ function createAcpExecutor(options) {
25599
25653
  options.originBindingGeneration === void 0 ? event : { ...event, originBindingGeneration: options.originBindingGeneration }
25600
25654
  );
25601
25655
  };
25602
- const emit = (event) => {
25603
- publish(event);
25604
- };
25656
+ const emit = publish;
25657
+ const emitArtifacts = makeArtifactEmitter({ emit, stamp, options, turnId: () => activeTurnId });
25605
25658
  const failIfDisposed = () => {
25606
25659
  if (disposed) {
25607
25660
  throw new AcpExecutorDisposedError();
@@ -25704,6 +25757,8 @@ function createAcpExecutor(options) {
25704
25757
  payload: taskEvent.payload
25705
25758
  });
25706
25759
  }
25760
+ if (nextToolCall.status === "completed" && hookResult && "artifacts" in hookResult)
25761
+ emitArtifacts(hookResult.artifacts ?? [], nextToolCall.toolCallId);
25707
25762
  if (handledByHook || !decision.emit) {
25708
25763
  continue;
25709
25764
  }
@@ -25723,6 +25778,10 @@ function createAcpExecutor(options) {
25723
25778
  );
25724
25779
  continue;
25725
25780
  }
25781
+ if (event._tag === "AssistantContentBlock") {
25782
+ emitArtifacts(resourceLinkArtifacts(event.content));
25783
+ continue;
25784
+ }
25726
25785
  if (event._tag === "CompactionUpdated") {
25727
25786
  applyCompactionUpdate(event);
25728
25787
  continue;
@@ -26933,7 +26992,7 @@ function tokenizeLaunchArgs(value) {
26933
26992
 
26934
26993
  // src/grokAccount.ts
26935
26994
  import * as NodeFS from "node:fs";
26936
- import * as NodePath from "node:path";
26995
+ import * as NodePath2 from "node:path";
26937
26996
  var AUTH_FILE_NAME = "auth.json";
26938
26997
  var isRecord7 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
26939
26998
  var readString2 = (record3, key) => {
@@ -27001,7 +27060,7 @@ var isExpired = (expiresAt, nowMs) => {
27001
27060
  };
27002
27061
  var readGrokAccount = (homePath) => {
27003
27062
  const exists = directoryExists(homePath);
27004
- const raw = readCredentialFile(NodePath.join(homePath, AUTH_FILE_NAME));
27063
+ const raw = readCredentialFile(NodePath2.join(homePath, AUTH_FILE_NAME));
27005
27064
  if (raw === void 0) return signedOutProbe(exists);
27006
27065
  const parsed = parseJsonRecord(raw);
27007
27066
  const identity = parsed === void 0 ? void 0 : findIdentityEntry(parsed);
@@ -27018,7 +27077,7 @@ var readGrokAccount = (homePath) => {
27018
27077
 
27019
27078
  // src/grokQuota.ts
27020
27079
  import * as NodeFS2 from "node:fs";
27021
- import * as NodePath2 from "node:path";
27080
+ import * as NodePath3 from "node:path";
27022
27081
  import {
27023
27082
  parseRetryAfterMs
27024
27083
  } from "@ycodium-ai/plugin-api/usage";
@@ -27065,7 +27124,7 @@ var grokQuotaWindows = (body) => {
27065
27124
  };
27066
27125
  var createGrokUsage = (input2) => {
27067
27126
  const now = input2.now ?? Date.now;
27068
- const authPath = NodePath2.join(input2.homePath, AUTH_FILE_NAME2);
27127
+ const authPath = NodePath3.join(input2.homePath, AUTH_FILE_NAME2);
27069
27128
  const readQuota = async (request) => {
27070
27129
  const baseUrlKey = GROK_CARD.modelConnectivity.baseUrlEnvKey;
27071
27130
  if (baseUrlKey !== void 0 && (input2.environment[baseUrlKey]?.trim() ?? "") !== "") {
@@ -27453,6 +27512,39 @@ function buildGrokBackgroundTaskEvents(input2) {
27453
27512
  return events;
27454
27513
  }
27455
27514
 
27515
+ // src/grokImageArtifacts.ts
27516
+ function imageGenResult(rawOutput) {
27517
+ let value = rawOutput;
27518
+ if (typeof value === "string") {
27519
+ try {
27520
+ value = JSON.parse(value);
27521
+ } catch {
27522
+ return void 0;
27523
+ }
27524
+ }
27525
+ return value !== null && typeof value === "object" && value["type"] === "ImageGen" ? value : void 0;
27526
+ }
27527
+ function sessionDirectory(path, sessionFolder, filename) {
27528
+ if (typeof sessionFolder !== "string" || sessionFolder.trim().length === 0) return void 0;
27529
+ const tail = [...sessionFolder.split(/[\\/]/).filter((part) => part.length > 0), filename];
27530
+ const parts = path.split(/([\\/])/);
27531
+ const segments = parts.filter((_, index) => index % 2 === 0);
27532
+ if (segments.length <= tail.length) return void 0;
27533
+ const matches = tail.every(
27534
+ (part, index) => segments[segments.length - tail.length + index] === part
27535
+ );
27536
+ if (!matches) return void 0;
27537
+ return parts.slice(0, parts.length - tail.length * 2).join("");
27538
+ }
27539
+ function grokImageArtifacts(rawOutput) {
27540
+ const result = imageGenResult(rawOutput);
27541
+ const path = typeof result?.["path"] === "string" ? result["path"].trim() : "";
27542
+ if (result === void 0 || path.length === 0) return [];
27543
+ const filename = typeof result["filename"] === "string" && result["filename"].trim().length > 0 ? result["filename"].trim() : path.split(/[\\/]/).at(-1) ?? path;
27544
+ const linkBase = sessionDirectory(path, result["session_folder"], filename);
27545
+ return [{ path, name: filename, ...linkBase !== void 0 ? { linkBase } : {} }];
27546
+ }
27547
+
27456
27548
  // src/grokSupport.ts
27457
27549
  import { modelSelectionStringOption } from "@ycodium-ai/plugin-api/executor";
27458
27550
  var GROK_NATIVE_MODE_BY_RUNTIME_MODE = {
@@ -27746,7 +27838,7 @@ var grokPromptSettlement = {
27746
27838
 
27747
27839
  // src/grokSkills.ts
27748
27840
  import * as NodeOS from "node:os";
27749
- import * as NodePath3 from "node:path";
27841
+ import * as NodePath4 from "node:path";
27750
27842
  var INSPECT_TIMEOUT_MS = 15e3;
27751
27843
  var MAX_INSPECT_OUTPUT_BYTES = 4 * 1024 * 1024;
27752
27844
  var GROK_INSPECT_ARGS = ["inspect", "--json"];
@@ -27814,14 +27906,14 @@ async function inspectGrokWorkspace(input2) {
27814
27906
  const skills = await runGrokInspect(input2);
27815
27907
  const watched = /* @__PURE__ */ new Set([
27816
27908
  // 项目技能目录的位置没有实测,这两处只是触发重查的提示,不影响答案本身。
27817
- NodePath3.join(input2.cwd, ".grok", "skills"),
27818
- NodePath3.join(input2.cwd, ".agents", "skills")
27909
+ NodePath4.join(input2.cwd, ".grok", "skills"),
27910
+ NodePath4.join(input2.cwd, ".agents", "skills")
27819
27911
  ]);
27820
27912
  for (const skill of skills) {
27821
27913
  watched.add(skill.path);
27822
- const skillDirectory = NodePath3.dirname(skill.path);
27914
+ const skillDirectory = NodePath4.dirname(skill.path);
27823
27915
  watched.add(skillDirectory);
27824
- watched.add(NodePath3.dirname(skillDirectory));
27916
+ watched.add(NodePath4.dirname(skillDirectory));
27825
27917
  }
27826
27918
  return { skills, watchPaths: [...watched] };
27827
27919
  }
@@ -27937,14 +28029,14 @@ var hasDeviceCode = (output2) => deviceCodeUrl(output2) !== void 0 && deviceCode
27937
28029
  function expandHomePath(value) {
27938
28030
  if (value === "~") return NodeOS2.homedir();
27939
28031
  if (value.startsWith("~/") || value.startsWith("~\\")) {
27940
- return NodePath4.join(NodeOS2.homedir(), value.slice(2));
28032
+ return NodePath5.join(NodeOS2.homedir(), value.slice(2));
27941
28033
  }
27942
28034
  return value;
27943
28035
  }
27944
28036
  function resolveGrokHomePath(value) {
27945
28037
  const trimmed3 = value.trim();
27946
- if (trimmed3.length === 0) return NodePath4.join(NodeOS2.homedir(), ".grok");
27947
- return NodePath4.resolve(expandHomePath(trimmed3));
28038
+ if (trimmed3.length === 0) return NodePath5.join(NodeOS2.homedir(), ".grok");
28039
+ return NodePath5.resolve(expandHomePath(trimmed3));
27948
28040
  }
27949
28041
  function probeGrokAccount(accountPath) {
27950
28042
  const resolved = resolveGrokHomePath(accountPath);
@@ -27963,12 +28055,12 @@ function grokContinuationKey(recipe) {
27963
28055
  function resolveAccountHomePath(recipe, configuredHome) {
27964
28056
  const fromEnvironment = recipe.environment["GROK_HOME"]?.trim();
27965
28057
  if (fromEnvironment !== void 0 && fromEnvironment.length > 0) {
27966
- return NodePath4.resolve(expandHomePath(fromEnvironment));
28058
+ return NodePath5.resolve(expandHomePath(fromEnvironment));
27967
28059
  }
27968
28060
  return resolveGrokHomePath(configuredHome);
27969
28061
  }
27970
28062
  function absentPath() {
27971
- return NodePath4.join(
28063
+ return NodePath5.join(
27972
28064
  NodeOS2.tmpdir(),
27973
28065
  `ycodium-grok-no-auth-${NodeCrypto2.randomUUID()}`,
27974
28066
  "auth.json"
@@ -28075,8 +28167,7 @@ var createGrokInstance = (config2, host) => {
28075
28167
  readiness: outcome.kind === "not-started" ? outcome.readiness : "error",
28076
28168
  auth: probeAuth(),
28077
28169
  ...outcome.detail === void 0 ? {} : { detail: outcome.detail },
28078
- // 装着但握不上手时,界面照样画权限格。不报档就退回宿主四档,而那四档对这双手
28079
- // 是撒谎的——这台开发机的 grok 就长期停在这个出口上。
28170
+ // 装着但握不上手时,界面照样画权限格。不报档就退回宿主四档,而那四档对这双手是撒谎的——这台开发机的 grok 就长期停在这个出口上。
28080
28171
  ...outcome.kind === "failed" ? GROK_NATIVE_MODE_REPORT : {}
28081
28172
  };
28082
28173
  }
@@ -28174,13 +28265,16 @@ var createGrokInstance = (config2, host) => {
28174
28265
  authMethodId: resolveGrokAuthMethodId,
28175
28266
  hooks: {
28176
28267
  promptSettlement: turnUsage.settlement,
28177
- onToolCallUpdated: (update) => buildGrokBackgroundTaskEvents({
28178
- tasks: backgroundTasks,
28179
- toolCallId: update.toolCallId,
28180
- rawInput: update.rawInput,
28181
- rawOutput: update.rawOutput,
28182
- toolCallStatus: update.status,
28183
- turnId: update.turnId
28268
+ onToolCallUpdated: (update) => ({
28269
+ events: buildGrokBackgroundTaskEvents({
28270
+ tasks: backgroundTasks,
28271
+ toolCallId: update.toolCallId,
28272
+ rawInput: update.rawInput,
28273
+ rawOutput: update.rawOutput,
28274
+ toolCallStatus: update.status,
28275
+ turnId: update.turnId
28276
+ }),
28277
+ artifacts: grokImageArtifacts(update.rawOutput)
28184
28278
  }),
28185
28279
  onExtensionRequest: async (method, params, ctx) => {
28186
28280
  if (XAI_EXIT_PLAN_MODE_METHODS.includes(method)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ycodium-ai/agent-grok",
3
- "version": "0.2.2888",
3
+ "version": "0.2.2892",
4
4
  "description": "Grok executor: grok CLI over Agent Client Protocol stdio.",
5
5
  "keywords": [
6
6
  "ycodium",
@@ -21,8 +21,8 @@
21
21
  "@types/node": "24.12.4",
22
22
  "esbuild": "0.28.1",
23
23
  "vite-plus": "0.2.2",
24
- "@ycodium-ai/plugin-api": "0.2.2888",
25
- "ycodium-acp-executor": "0.2.2888",
24
+ "ycodium-acp-executor": "0.2.2892",
25
+ "@ycodium-ai/plugin-api": "0.2.2892",
26
26
  "ycodium-executor-testing": "0.0.0"
27
27
  },
28
28
  "ycodium": {