@ycodium-ai/agent-fake 0.2.2526 → 0.2.2554

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/README.md CHANGED
@@ -6,6 +6,9 @@ A minimal executor plugin. It starts no CLI and replays a fixed event script:
6
6
  - `sendTurn` emits one `content.delta` then `turn.completed`
7
7
  - `interruptTurn` (or an aborted `AbortSignal`) ends the in-flight turn as `interrupted`
8
8
  - `readThread` returns the bookkeeping the instance recorded
9
+ - `probe` reports two models, `fake` (default) and `fake-large`
10
+
11
+ The card also shows how a third-party executor gets its own settings form: `configSchema` marks `replyText` with `x-ycodium-form`, and the labels resolve in this package's `locales/en.json` and `locales/zh-CN.json`. `replyText` is what the plain script answers; empty means `fake turn complete`.
9
12
 
10
13
  Two uses:
11
14
 
package/dist/index.js CHANGED
@@ -33,11 +33,23 @@ var FAKE_CARD = {
33
33
  },
34
34
  credentialSources: [],
35
35
  diagnostics: [],
36
+ // 设置表单照这份画:带 x-ycodium-form 的属性才进表单,顺序看 x-ycodium-form-order,
37
+ // 文案键在本插件 locales/<locale>.json 里解析。第三方插件照这个写法就有一张自己的表单。
36
38
  configSchema: {
37
39
  type: "object",
38
40
  additionalProperties: false,
41
+ "x-ycodium-form-order": ["replyText"],
39
42
  properties: {
40
- script: { type: "string", enum: ["plain", "approval-tool"] }
43
+ script: { type: "string", enum: ["plain", "approval-tool"] },
44
+ replyText: {
45
+ type: "string",
46
+ "x-ycodium-form": {
47
+ titleKey: "form.replyText.title",
48
+ descriptionKey: "form.replyText.description",
49
+ placeholderKey: "form.replyText.placeholder",
50
+ clearWhenEmpty: true
51
+ }
52
+ }
41
53
  }
42
54
  },
43
55
  modelConnectivity: {
@@ -48,6 +60,7 @@ var FAKE_CARD = {
48
60
  };
49
61
 
50
62
  // src/fakeInstance.ts
63
+ import * as NodeCrypto from "node:crypto";
51
64
  var yieldTick = () => Promise.resolve();
52
65
  var EventBus = class {
53
66
  #queued = [];
@@ -86,16 +99,26 @@ function parseScript(input) {
86
99
  const script = envelope?.config?.script;
87
100
  return script === "approval-tool" ? "approval-tool" : "plain";
88
101
  }
102
+ var parseReplyText = (input) => {
103
+ const envelope = input;
104
+ const replyText = envelope?.config?.replyText;
105
+ return typeof replyText === "string" && replyText.trim() !== "" ? replyText : FAKE_ASSISTANT_TEXT;
106
+ };
107
+ var FAKE_MODELS = [
108
+ { slug: "fake", name: "Fake", isDefault: true },
109
+ { slug: "fake-large", name: "Fake Large" }
110
+ ];
89
111
  var createFakeInstance = (config, host) => {
90
112
  const events = new EventBus();
91
113
  const threads = /* @__PURE__ */ new Map();
92
114
  const script = parseScript(config);
115
+ const replyText = parseReplyText(config);
93
116
  const pendingDecisions = /* @__PURE__ */ new Map();
94
117
  let seq = 0;
95
118
  let inflight = null;
96
119
  let disposed = false;
97
- const nextId = (prefix) => `${prefix}-fake-${++seq}`;
98
- const now = () => "2026-09-15T00:00:00.000Z";
120
+ const nextId = (prefix) => `${prefix}-fake-${++seq}-${NodeCrypto.randomUUID()}`;
121
+ const now = () => (/* @__PURE__ */ new Date()).toISOString();
99
122
  const emit = (type, threadId, payload, extra) => {
100
123
  events.push({
101
124
  eventId: nextId("evt"),
@@ -246,7 +269,8 @@ var createFakeInstance = (config, host) => {
246
269
  installed: true,
247
270
  version: "0.0.0-fake",
248
271
  readiness: "ready",
249
- auth: { status: "unknown" }
272
+ auth: { status: "unknown" },
273
+ models: FAKE_MODELS
250
274
  }),
251
275
  startSession: async (input, signal) => {
252
276
  if (disposed) throw new Error("instance disposed");
@@ -308,17 +332,15 @@ var createFakeInstance = (config, host) => {
308
332
  emit(
309
333
  "content.delta",
310
334
  input.threadId,
311
- { streamKind: "assistant_text", delta: FAKE_ASSISTANT_TEXT },
335
+ { streamKind: "assistant_text", delta: replyText },
312
336
  { turnId }
313
337
  );
314
338
  await yieldTick();
315
339
  if (aborted) {
316
- finishTurn(booked, turnId, "interrupted", [
317
- { kind: "assistant", text: FAKE_ASSISTANT_TEXT }
318
- ]);
340
+ finishTurn(booked, turnId, "interrupted", [{ kind: "assistant", text: replyText }]);
319
341
  return { threadId: input.threadId, turnId };
320
342
  }
321
- finishTurn(booked, turnId, "completed", [{ kind: "assistant", text: FAKE_ASSISTANT_TEXT }]);
343
+ finishTurn(booked, turnId, "completed", [{ kind: "assistant", text: replyText }]);
322
344
  return { threadId: input.threadId, turnId };
323
345
  } finally {
324
346
  signal?.removeEventListener("abort", onAbort);
@@ -0,0 +1,9 @@
1
+ {
2
+ "form": {
3
+ "replyText": {
4
+ "title": "Reply text",
5
+ "description": "What the fake executor answers to every message. Leave empty to use the built-in reply.",
6
+ "placeholder": "fake turn complete"
7
+ }
8
+ }
9
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "form": {
3
+ "replyText": {
4
+ "title": "回复内容",
5
+ "description": "假执行器对每条消息的回答。留空就用内置的那句。",
6
+ "placeholder": "fake turn complete"
7
+ }
8
+ }
9
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ycodium-ai/agent-fake",
3
- "version": "0.2.2526",
3
+ "version": "0.2.2554",
4
4
  "description": "Minimal fake executor for plugin authors and host orchestration tests.",
5
5
  "keywords": [
6
6
  "ycodium",
@@ -10,6 +10,7 @@
10
10
  "files": [
11
11
  "dist",
12
12
  "assets",
13
+ "locales",
13
14
  "README.md"
14
15
  ],
15
16
  "type": "module",
@@ -20,7 +21,7 @@
20
21
  "@types/node": "24.12.4",
21
22
  "esbuild": "0.28.1",
22
23
  "vite-plus": "0.2.2",
23
- "@ycodium-ai/plugin-api": "0.2.2526"
24
+ "@ycodium-ai/plugin-api": "0.2.2554"
24
25
  },
25
26
  "ycodium": {
26
27
  "plugin": "./dist/index.js",