@deepseek-ai/dsh-client-connection 0.1.0-rc.6 → 0.1.0-rc.8

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/lib/client.js CHANGED
@@ -5060,11 +5060,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5060
5060
  message: string(),
5061
5061
  details: object({ ns: string() })
5062
5062
  }),
5063
- object({
5064
- code: literal("settings-not-exposed"),
5065
- message: string(),
5066
- details: object({ ns: string() })
5067
- }),
5068
5063
  object({
5069
5064
  code: literal("settings-conflict"),
5070
5065
  message: string(),
@@ -5365,6 +5360,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5365
5360
  maxImagesPerMessage: number().int().positive(),
5366
5361
  maxMessageImageBytes: number().int().positive(),
5367
5362
  maxImagePixels: number().int().positive(),
5363
+ maxImageDimension: number().int().positive(),
5368
5364
  mediaTypes: array(string())
5369
5365
  });
5370
5366
  /** session.history response value (projections rides the tail page only). */
@@ -5712,6 +5708,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5712
5708
  provider: string().optional(),
5713
5709
  model: string().optional(),
5714
5710
  attachedSessions: number().int().nonnegative(),
5711
+ home: string(),
5715
5712
  canOpenPath: boolean()
5716
5713
  });
5717
5714
  object({});
@@ -7089,7 +7086,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7089
7086
  toolTurn(67, "grep", "{\"pattern\":\"SEARCH_MAX_LINES\",\"path\":\"packages/client\"}", SEARCH_MATCHES_TEXT);
7090
7087
  toolTurn(68, "glob", "{\"pattern\":\"**/SearchBlock*\",\"path\":\"packages/client\"}", SEARCH_PATHS_TEXT);
7091
7088
  toolTurn(69, "read", `{"file_path":${JSON.stringify(READ_SAMPLE_PATH)},"offset":${READ_SAMPLE_FIRST_LINE}}`, READ_SAMPLE_TEXT);
7092
- toolTurn(70, "web_search", "{\"query\":\"deepseek harness architecture\"}", "Search results for deepseek harness architecture.");
7089
+ toolTurn(70, "web_search", "{\"queries\":[\"deepseek harness architecture\"]}", "Search results for deepseek harness architecture.");
7093
7090
  toolTurn(71, "web_fetch", "{\"url\":\"https://www.deepseek.com/blog/harness-architecture\"}", "# Harness architecture\n\nEverything is a plugin.");
7094
7091
  push({
7095
7092
  type: "turn/start",
@@ -7269,7 +7266,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7269
7266
  };
7270
7267
  case "web_search": return {
7271
7268
  card: "generic",
7272
- title: `Search ${str(args.query)}`,
7269
+ title: `Search ${(Array.isArray(args.queries) ? args.queries.filter((query) => typeof query === "string" && query !== "") : []).join(", ")}`,
7273
7270
  kind: "search",
7274
7271
  rawInput: args
7275
7272
  };
@@ -7362,29 +7359,37 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7362
7359
  }
7363
7360
  }
7364
7361
  /**
7365
- * Fixture parallel of the plan unit's double-event fold: `command/run`
7366
- * records named `plan` with recorded input set the wanted target (`off` →
7367
- * false, else true); `plan/mode` commits and clears it. `wanted` is exposed
7368
- * for the prompt boundary (the fixture's step/start parallel).
7362
+ * Fixture parallel of the plan unit's lifecycle fold. The paired
7363
+ * `command/done` retains successful plan selections and drops failures;
7364
+ * `plan/mode` commits one. `wanted` is exposed for the prompt boundary (the
7365
+ * fixture's step/start parallel).
7369
7366
  */
7370
7367
  function foldPlan(log) {
7371
7368
  let active = false;
7372
7369
  let wanted = null;
7370
+ let running = null;
7373
7371
  for (const event of log) {
7374
7372
  const item = event;
7375
7373
  if (item.type === "command/run" && item.data?.["name"] === "plan") {
7376
7374
  const args = item.data["args"];
7377
7375
  if (typeof args !== "string") continue;
7378
- wanted = args.trim() !== "off";
7376
+ running = {
7377
+ commandId: item.data["commandId"],
7378
+ wanted: args.trim() !== "off"
7379
+ };
7380
+ } else if (item.type === "command/done" && item.data !== void 0 && running !== null && item.data["commandId"] === running.commandId) {
7381
+ wanted = item.data["kind"] === "success" && running.wanted !== active ? running.wanted : null;
7382
+ running = null;
7379
7383
  } else if (item.type === "plan/mode") {
7380
7384
  active = item.data?.["active"] === true;
7381
7385
  wanted = null;
7382
7386
  }
7383
7387
  }
7388
+ const selected = running?.wanted ?? wanted;
7384
7389
  return {
7385
7390
  active,
7386
- pending: wanted !== null && wanted !== active,
7387
- wanted
7391
+ pending: selected !== null && selected !== active,
7392
+ wanted: selected
7388
7393
  };
7389
7394
  }
7390
7395
  /** The plan projection's wire view over the full log. */
@@ -7624,6 +7629,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7624
7629
  maxImagesPerMessage: 20,
7625
7630
  maxMessageImageBytes: 100 * 1024 * 1024,
7626
7631
  maxImagePixels: 4e7,
7632
+ maxImageDimension: 2e3,
7627
7633
  mediaTypes: [
7628
7634
  "image/png",
7629
7635
  "image/jpeg",
@@ -7990,6 +7996,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7990
7996
  let attachedSessions = options.empty ? 0 : 1;
7991
7997
  const wid = (raw) => raw;
7992
7998
  const fixtureEpoch = (/* @__PURE__ */ new Date(Date.now() - 3e5)).toISOString();
7999
+ const FIXTURE_HOME = "/home/fixture";
7993
8000
  const workspaces = options.empty ? [] : [{
7994
8001
  workspaceId: wid("fx-ws-fixture"),
7995
8002
  path: "/tmp/fixture",
@@ -8001,10 +8008,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8001
8008
  ],
8002
8009
  createdAt: fixtureEpoch,
8003
8010
  updatedAt: fixtureEpoch
8011
+ }, {
8012
+ workspaceId: wid("fx-ws-home"),
8013
+ path: `${FIXTURE_HOME}/Documents/project`,
8014
+ title: "project",
8015
+ sessionIds: [],
8016
+ createdAt: fixtureEpoch,
8017
+ updatedAt: fixtureEpoch
8004
8018
  }];
8005
8019
  let nextWorkspace = 1;
8006
8020
  const archivedSessionIds = [];
8007
- const FIXTURE_HOME = "/home/fixture";
8008
8021
  const directoryTree = new Map([
8009
8022
  ["/", ["home"]],
8010
8023
  ["/home", ["fixture"]],
@@ -8232,7 +8245,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8232
8245
  {
8233
8246
  name: "goal",
8234
8247
  description: "set or view the goal for a long-running task",
8235
- input: { hint: "<objective>" }
8248
+ input: {
8249
+ hint: "<objective>",
8250
+ images: true
8251
+ }
8236
8252
  },
8237
8253
  {
8238
8254
  name: "permission",
@@ -8242,17 +8258,59 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8242
8258
  {
8243
8259
  name: "plan",
8244
8260
  description: "Enter or leave plan mode",
8245
- input: { hint: "[off|message]" }
8261
+ input: {
8262
+ hint: "[off|message]",
8263
+ images: true
8264
+ }
8246
8265
  }
8247
8266
  ]
8248
8267
  };
8249
8268
  },
8250
- execute(id, line) {
8269
+ execute(id, line, images = []) {
8251
8270
  const missing = requireGoalSession(id);
8252
8271
  if (missing !== void 0) return missing;
8253
8272
  const match = /^\/(\S+)((?:\s.*)?)$/.exec(line.trim());
8254
8273
  const name = match?.[1];
8255
8274
  const args = match?.[2] ?? "";
8275
+ if (images.length > 0 && name !== void 0 && [
8276
+ "permission",
8277
+ "goal",
8278
+ "compact",
8279
+ "echo",
8280
+ "plan"
8281
+ ].includes(name)) {
8282
+ const rejection = name !== "goal" && name !== "plan" ? `/${name} does not accept image attachments` : name === "goal" && args.trim() === "" ? "Image attachments only accompany a goal objective: /goal <objective> or /goal edit <objective>." : name === "plan" && args.trim() === "off" ? "Image attachments cannot accompany /plan off." : void 0;
8283
+ if (rejection !== void 0) {
8284
+ const commandId = `fx-cmd-${logOf(id).length}`;
8285
+ append(id, {
8286
+ type: "command/run",
8287
+ data: {
8288
+ commandId,
8289
+ name,
8290
+ args,
8291
+ source: { kind: "user" }
8292
+ }
8293
+ });
8294
+ const result = {
8295
+ kind: "error",
8296
+ text: rejection
8297
+ };
8298
+ append(id, {
8299
+ type: "command/done",
8300
+ data: {
8301
+ commandId,
8302
+ ...result
8303
+ }
8304
+ });
8305
+ return {
8306
+ ok: true,
8307
+ value: {
8308
+ commandId,
8309
+ result
8310
+ }
8311
+ };
8312
+ }
8313
+ }
8256
8314
  if (name === "permission") {
8257
8315
  const preset = args.trim();
8258
8316
  const commandId = `fx-cmd-${logOf(id).length}`;
@@ -8414,6 +8472,50 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8414
8472
  activation: projection.goal.phase === "active" ? "armed" : "disarmed"
8415
8473
  });
8416
8474
  /** Canonical fixture implementation of the generated Goal Remote contract. */
8475
+ /** Canonical fixture implementation of the generated reference-discovery Remote contracts. */
8476
+ const referenceRemotes = {
8477
+ files(id, query) {
8478
+ const missing = requireGoalSession(id);
8479
+ if (missing !== void 0) return missing;
8480
+ const needle = query.toLocaleLowerCase();
8481
+ return {
8482
+ ok: true,
8483
+ value: [
8484
+ {
8485
+ path: "notes",
8486
+ kind: "directory"
8487
+ },
8488
+ {
8489
+ path: "README.md",
8490
+ kind: "file"
8491
+ },
8492
+ {
8493
+ path: "notes/demo.txt",
8494
+ kind: "file"
8495
+ }
8496
+ ].filter((item) => item.path.toLocaleLowerCase().includes(needle))
8497
+ };
8498
+ },
8499
+ sessions(id, query) {
8500
+ const missing = requireGoalSession(id);
8501
+ if (missing !== void 0) return missing;
8502
+ const needle = query.toLocaleLowerCase();
8503
+ return {
8504
+ ok: true,
8505
+ value: sessions.filter((item) => item.sessionId !== id).filter((item) => String(item.sessionId).toLocaleLowerCase().includes(needle) || item.cwd?.toLocaleLowerCase().includes(needle) === true).map((item) => {
8506
+ const label = item.sessionId === sid("fx-beta") ? "Fixture child session" : String(item.sessionId);
8507
+ const encoded = btoa(JSON.stringify(item.sessionId)).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/u, "");
8508
+ return {
8509
+ sessionId: item.sessionId,
8510
+ label,
8511
+ ...item.cwd === void 0 ? {} : { cwd: item.cwd },
8512
+ createdAt: item.updatedAt,
8513
+ mention: `@[${label}](dsh-session:${encoded})`
8514
+ };
8515
+ })
8516
+ };
8517
+ }
8518
+ };
8417
8519
  const goalRemotes = {
8418
8520
  create(id, request) {
8419
8521
  const missing = requireGoalSession(id);
@@ -9209,11 +9311,18 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9209
9311
  message: `no session ${id}`,
9210
9312
  details: { sessionId: id }
9211
9313
  });
9212
- if (options.rejectPrompt) return err(request, {
9213
- code: "agent-busy",
9214
- message: "fixture: prompt rejected before acceptance",
9215
- details: { reason: "fixture-prompt-rejection" }
9216
- });
9314
+ if (options.rejectPrompt) {
9315
+ if (content.some((block) => block.type === "image")) return err(request, {
9316
+ code: "attachment-error",
9317
+ message: "fixture: image side exceeds the deployment limit",
9318
+ details: { reason: "IMAGE_DIMENSION_TOO_LARGE" }
9319
+ });
9320
+ return err(request, {
9321
+ code: "agent-busy",
9322
+ message: "fixture: prompt rejected before acceptance",
9323
+ details: { reason: "fixture-prompt-rejection" }
9324
+ });
9325
+ }
9217
9326
  summary.updatedAt = Date.now();
9218
9327
  summary.blank = false;
9219
9328
  const userText = content.map((b) => b.type === "text" ? b.text : "").join("");
@@ -9324,6 +9433,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9324
9433
  version: "0.0.0-fixture",
9325
9434
  cwd: "/tmp/fixture",
9326
9435
  attachedSessions,
9436
+ home: FIXTURE_HOME,
9327
9437
  canOpenPath: true
9328
9438
  }),
9329
9439
  pickDirectory: (request) => ok(request, { path: `${FIXTURE_HOME}/Documents/project` }),
@@ -9836,7 +9946,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9836
9946
  const sessionId = args.agentId;
9837
9947
  switch (endpoint) {
9838
9948
  case "commands/list": return Promise.resolve(commandRemotes.list(sessionId));
9839
- case "commands/execute": return Promise.resolve(commandRemotes.execute(sessionId, args.line));
9949
+ case "commands/execute": return Promise.resolve(commandRemotes.execute(sessionId, args.line, args.images ?? []));
9950
+ case "fileReferences/list": return Promise.resolve(referenceRemotes.files(sessionId, args.query ?? ""));
9951
+ case "sessionReferenceResolver/candidates": return Promise.resolve(referenceRemotes.sessions(sessionId, args.query ?? ""));
9840
9952
  case "goals/create": return Promise.resolve(goalRemotes.create(sessionId, {
9841
9953
  objective: args.request?.objective,
9842
9954
  ...args.request?.maxGoalRounds === void 0 ? {} : { maxGoalRounds: args.request.maxGoalRounds }
@@ -30,7 +30,7 @@ export interface ConnectionHandle {
30
30
  readonly api: IApiClient;
31
31
  /** Whether the current page authority is loopback; non-browser contexts default to true. */
32
32
  readonly isLoopback: boolean;
33
- /** Generation-scoped Host facts, including native path-open capability. */
33
+ /** Generation-scoped Host facts, including the account home and native path-open capability. */
34
34
  readonly hostDescription: HostDescriptionSource;
35
35
  /** Generic logical RPC channels over the same Connection transport. */
36
36
  readonly rpc: ClientConnectionRpc;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-client-connection",
3
3
  "description": "Wire consumer layer: HTTP-up/WebSocket-down client, ConnectionController dual streams with reconnect, and fixture api",
4
- "version": "0.1.0-rc.6",
4
+ "version": "0.1.0-rc.8",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -39,12 +39,6 @@
39
39
  "license": "MIT",
40
40
  "dependencies": {
41
41
  "ws": "^8.21.0",
42
- "@deepseek-ai/dsh-host-apiproxy": "^0.1.0-rc.6",
43
- "@deepseek-ai/dsh-commands": "^0.1.0-rc.6",
44
- "@deepseek-ai/dsh-llm": "^0.1.0-rc.6",
45
- "@deepseek-ai/dsh-session": "^0.1.0-rc.6",
46
- "@deepseek-ai/dsh-attachment": "^0.1.0-rc.6",
47
- "@deepseek-ai/dsh-tools": "^0.1.0-rc.6",
48
42
  "@deepseek-ai/schemastery": "^3.18.1"
49
43
  },
50
44
  "files": [
@@ -54,14 +48,26 @@
54
48
  "lib/types/**/*.d.ts"
55
49
  ],
56
50
  "peerDependencies": {
57
- "@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6",
58
- "@deepseek-ai/dsh-invariants": "^0.1.0-rc.6",
51
+ "@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.8",
52
+ "@deepseek-ai/dsh-invariants": "^0.1.0-rc.8",
53
+ "@deepseek-ai/dsh-attachment": "^0.1.0-rc.8",
54
+ "@deepseek-ai/dsh-host-apiproxy": "^0.1.0-rc.8",
55
+ "@deepseek-ai/dsh-commands": "^0.1.0-rc.8",
56
+ "@deepseek-ai/dsh-llm": "^0.1.0-rc.8",
57
+ "@deepseek-ai/dsh-session": "^0.1.0-rc.8",
58
+ "@deepseek-ai/dsh-tools": "^0.1.0-rc.8",
59
59
  "@deepseek-ai/cordis": "^4.0.1"
60
60
  },
61
61
  "devDependencies": {
62
62
  "@types/ws": "^8.18.1",
63
- "@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6",
64
- "@deepseek-ai/dsh-invariants": "^0.1.0-rc.6",
65
- "@deepseek-ai/cordis": "^4.0.1"
63
+ "@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.8",
64
+ "@deepseek-ai/cordis": "^4.0.1",
65
+ "@deepseek-ai/dsh-attachment": "^0.1.0-rc.8",
66
+ "@deepseek-ai/dsh-host-apiproxy": "^0.1.0-rc.8",
67
+ "@deepseek-ai/dsh-invariants": "^0.1.0-rc.8",
68
+ "@deepseek-ai/dsh-commands": "^0.1.0-rc.8",
69
+ "@deepseek-ai/dsh-llm": "^0.1.0-rc.8",
70
+ "@deepseek-ai/dsh-session": "^0.1.0-rc.8",
71
+ "@deepseek-ai/dsh-tools": "^0.1.0-rc.8"
66
72
  }
67
73
  }