@intentius/chant-lexicon-fountain 0.105.0 → 0.106.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/acp/serve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAUH,wFAAwF;AACxF,wBAAsB,iBAAiB,CAAC,IAAI,GAAE;IAAE,eAAe,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BjH"}
1
+ {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/acp/serve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAUH,wFAAwF;AACxF,wBAAsB,iBAAiB,CAAC,IAAI,GAAE;IAAE,eAAe,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAmCjH"}
@@ -42,6 +42,14 @@ export interface AcpServerOptions {
42
42
  createHost?: (cwd: string) => ChantHost;
43
43
  /** Mints permission request ids. Injected so a test can pin them. */
44
44
  newRequestId?: () => string;
45
+ /**
46
+ * The id every Op run in this process is named by (#3539). On fountain it
47
+ * is the conversation id the sandbox's environment carries
48
+ * (`FOUNTAIN_CONVERSATION_ID`), so the run record the sandbox writes and
49
+ * the run `chant run status --on fountain` reports have the same id.
50
+ * Omitted, the local runtime mints one per run.
51
+ */
52
+ runId?: string;
45
53
  }
46
54
  export declare class AcpServer implements JsonRpcHandler {
47
55
  private peer;
@@ -50,6 +58,7 @@ export declare class AcpServer implements JsonRpcHandler {
50
58
  private readonly version;
51
59
  private readonly createHost;
52
60
  private readonly newRequestId;
61
+ private readonly runId;
53
62
  /** Serializes turns — see the module doc. */
54
63
  private queue;
55
64
  constructor(opts?: AcpServerOptions);
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/acp/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,EAEL,WAAW,EACX,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,WAAW,CAAC;AAoBnB,OAAO,EAAiC,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC;AAGvE,mFAAmF;AACnF,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wFAAwF;IACxF,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,CAAC;IACxC,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,MAAM,CAAC;CAC7B;AAgBD,qBAAa,SAAU,YAAW,cAAc;IAC9C,OAAO,CAAC,IAAI,CAA0B;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA8B;IACvD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAU;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA6B;IACxD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,6CAA6C;IAC7C,OAAO,CAAC,KAAK,CAAuC;IAEpD,YAAY,IAAI,GAAE,gBAAqB,EAKtC;IAED,4CAA4C;IAC5C,OAAO,CAAC,SAAS,EAAE,aAAa,GAAG,WAAW,CAG7C;IAEK,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAW/D;IAED,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAQ5C;IAED,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,UAAU;IAuBlB,OAAO,CAAC,UAAU;YAYJ,MAAM;IAcpB;;;;;;OAMG;YACW,MAAM;YAuCN,cAAc;IAiC5B,8DAA8D;IAC9D,OAAO,CAAC,OAAO;CA0DhB"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/acp/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,EAEL,WAAW,EACX,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,WAAW,CAAC;AAoBnB,OAAO,EAAiC,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC;AAGvE,mFAAmF;AACnF,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wFAAwF;IACxF,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,CAAC;IACxC,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAgBD,qBAAa,SAAU,YAAW,cAAc;IAC9C,OAAO,CAAC,IAAI,CAA0B;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA8B;IACvD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAU;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA6B;IACxD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAC3C,6CAA6C;IAC7C,OAAO,CAAC,KAAK,CAAuC;IAEpD,YAAY,IAAI,GAAE,gBAAqB,EAMtC;IAED,4CAA4C;IAC5C,OAAO,CAAC,SAAS,EAAE,aAAa,GAAG,WAAW,CAG7C;IAEK,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAW/D;IAED,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAQ5C;IAED,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,UAAU;IAuBlB,OAAO,CAAC,UAAU;YAYJ,MAAM;IAcpB;;;;;;OAMG;YACW,MAAM;YAuCN,cAAc;IAkC5B,8DAA8D;IAC9D,OAAO,CAAC,OAAO;CA0DhB"}
@@ -59,6 +59,8 @@ export interface TurnOptions {
59
59
  durableRequests: boolean;
60
60
  /** Mints the id a resume prompt names. Injected so a test can pin it. */
61
61
  newRequestId: () => string;
62
+ /** The id an Op run is named by, when the host names runs (#3539: fountain's conversation id). */
63
+ runId?: string;
62
64
  }
63
65
  /**
64
66
  * Run one prompt.
@@ -1 +1 @@
1
- {"version":3,"file":"turn.d.ts","sourceRoot":"","sources":["../../src/acp/turn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAQH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAG/E,kDAAkD;AAClD,MAAM,WAAW,QAAQ;IACvB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC7E,cAAc,CACZ,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,cAAc,EACtB,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAC9D,IAAI,CAAC;IACR,gFAAgF;IAChF,iBAAiB,CACf,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,gBAAgB,EAAE,EAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAED,0FAA0F;AAC1F,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,4CAA4C;AAC5C,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,UAAU,CAAC;IACvB,mEAAmE;IACnE,UAAU,CAAC,EAAE,iBAAiB,CAAC;CAChC;AAED,iFAAiF;AACjF,eAAO,MAAM,YAAY,UAAU,CAAC;AACpC,eAAO,MAAM,aAAa,WAAW,CAAC;AA8BtC,iCAAiC;AACjC,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,YAAY,CAAC;IACtB,2EAA2E;IAC3E,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,WAAW,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;IACzB,yEAAyE;IACzE,YAAY,EAAE,MAAM,MAAM,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAmCrE"}
1
+ {"version":3,"file":"turn.d.ts","sourceRoot":"","sources":["../../src/acp/turn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAQH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAG/E,kDAAkD;AAClD,MAAM,WAAW,QAAQ;IACvB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC7E,cAAc,CACZ,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,cAAc,EACtB,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAC9D,IAAI,CAAC;IACR,gFAAgF;IAChF,iBAAiB,CACf,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,gBAAgB,EAAE,EAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAED,0FAA0F;AAC1F,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,4CAA4C;AAC5C,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,UAAU,CAAC;IACvB,mEAAmE;IACnE,UAAU,CAAC,EAAE,iBAAiB,CAAC;CAChC;AAED,iFAAiF;AACjF,eAAO,MAAM,YAAY,UAAU,CAAC;AACpC,eAAO,MAAM,aAAa,WAAW,CAAC;AA8BtC,iCAAiC;AACjC,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,YAAY,CAAC;IACtB,2EAA2E;IAC3E,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,WAAW,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;IACzB,yEAAyE;IACzE,YAAY,EAAE,MAAM,MAAM,CAAC;IAC3B,kGAAkG;IAClG,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAmCrE"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "algorithm": "sha256",
3
3
  "artifacts": {
4
- "manifest.json": "1ddd60ad73f6dec853f9b7029a3ea9218e9e9c728829a7e09f4e275202695cb8",
4
+ "manifest.json": "a8525549701de716ae91d92c3965e91ab8993ec47b4b30ae9c1e5746a6918bc4",
5
5
  "meta.json": "3301437a2a56eaf1a5cc8f6eabb18a40767f916e09701b2d9bf20aba4066738c",
6
6
  "types/index.d.ts": "cf6b634fe0a8e9e96f1d9d07e3df53838def2683dc93dbe3c7fd971c6d3908ae",
7
7
  "rules/ftn001-no-secret-literals.ts": "a417b194cd7039911cca9a0f14c49b042dfa6b1ee48517f7c2e22b16590a8599",
@@ -21,7 +21,7 @@
21
21
  "skills/chant-fountain.md": "906a312756a02c88de634915f63ab4dfe1b1078ff4d8cfb4b6dc97eec14bc237",
22
22
  "skills/chant-fountain-secrets.md": "40aa847d62547581bebdde630b54796c4e1cbf498869392e0d396d96a75c0ab6",
23
23
  "skills/chant-fountain-ops.md": "4e72f0a0c7477a9e98f85ea45e49ba69e8a699f9c13ba0f0cf1cb20a88151373",
24
- "skills/chant-fountain-locked-sandboxes.md": "48f4840a891e6b1cc7b5ac3319aebaec8c4e934f452370e55d60cb02a05812ae"
24
+ "skills/chant-fountain-locked-sandboxes.md": "7404ece96f2a3bc9105942fd3b6db156a3537db7e34c8cf2faa9ba87f5512567"
25
25
  },
26
- "composite": "9231fb938ba1f0f20b995f3fcb9d527dca4f454e6c2af6f2f8304d6c531129c1"
26
+ "composite": "ee0015b352b6395456b2c8a5099b69666d65efb9afa333b117390452bdc9081a"
27
27
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fountain",
3
- "version": "0.105.0",
3
+ "version": "0.106.1",
4
4
  "chantVersion": ">=0.1.0",
5
5
  "namespace": "Fountain",
6
6
  "specVersion": "v0.21.0"
@@ -13,10 +13,11 @@
13
13
  * What fountain v0.21.0 can and cannot do here, which decides the arguments:
14
14
  *
15
15
  * - A conversation that is `terminated` takes no more turns: the prompts route
16
- * answers 410. `fountainRun` terminates an ephemeral agent's conversation at
17
- * its deadline by default, so a caller that wants a later turn runs the first
18
- * one with `terminate: "never"` (a persistent agent's default) and ends the
19
- * conversation itself, or with this op's `terminate`, after the last turn.
16
+ * answers 410. `fountainRun` terminates an ephemeral agent's conversation
17
+ * once its turn ends (or at its deadline) by default, so a caller that wants a
18
+ * later turn runs the first one with `terminate: "never"` (a persistent
19
+ * agent's default) and ends the conversation itself, or with this op's
20
+ * `terminate`, after the last turn.
20
21
  * - A turn has no tool allowlist of its own. The prompts route takes only the
21
22
  * prompt, images and `client_request_id`; the tools a conversation may use are
22
23
  * its agent's `permission_policy`, narrowed once at launch, and nothing on the
@@ -1 +1 @@
1
- {"version":3,"file":"fountain-prompt.d.ts","sourceRoot":"","sources":["../../../src/op/activities/fountain-prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAGH,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAKtD,MAAM,WAAW,kBAAkB;IACjC,8EAA8E;IAC9E,YAAY,EAAE,MAAM,CAAC;IACrB,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4FAA4F;IAC5F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,kCAAkC;IAClC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,oBAAoB;IACnC,cAAc,EAAE,MAAM,CAAC;IACvB,8DAA8D;IAC9D,eAAe,EAAE,MAAM,CAAC;IACxB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,qBAAqB,EAAE,OAAO,CAAC;IAC/B,sHAAsH;IACtH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,UAAU,EAAE,OAAO,CAAC;CACrB;AAuCD,wBAAsB,cAAc,CAClC,IAAI,EAAE,kBAAkB,EACxB,MAAM,CAAC,EAAE,WAAW,EACpB,IAAI,CAAC,EAAE,YAAY,EACnB,IAAI,CAAC,EAAE,sBAAsB,GAC5B,OAAO,CAAC,oBAAoB,CAAC,CA2D/B"}
1
+ {"version":3,"file":"fountain-prompt.d.ts","sourceRoot":"","sources":["../../../src/op/activities/fountain-prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAGH,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAKtD,MAAM,WAAW,kBAAkB;IACjC,8EAA8E;IAC9E,YAAY,EAAE,MAAM,CAAC;IACrB,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4FAA4F;IAC5F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,kCAAkC;IAClC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,oBAAoB;IACnC,cAAc,EAAE,MAAM,CAAC;IACvB,8DAA8D;IAC9D,eAAe,EAAE,MAAM,CAAC;IACxB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,qBAAqB,EAAE,OAAO,CAAC;IAC/B,sHAAsH;IACtH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,UAAU,EAAE,OAAO,CAAC;CACrB;AAuCD,wBAAsB,cAAc,CAClC,IAAI,EAAE,kBAAkB,EACxB,MAAM,CAAC,EAAE,WAAW,EACpB,IAAI,CAAC,EAAE,YAAY,EACnB,IAAI,CAAC,EAAE,sBAAsB,GAC5B,OAAO,CAAC,oBAAoB,CAAC,CA2D/B"}
@@ -7,12 +7,18 @@
7
7
  * imperative half: resolve the agent by name, POST the conversation, and
8
8
  * poll until the turn is done.
9
9
  *
10
- * What "done" means depends on the agent's `sandbox_mode` (#2718). An
11
- * `ephemeral` conversation's machine is its own and this polls the
12
- * conversation's own status to `completed | failed | timed_out |
13
- * terminated` — none of which a running server's conversation status
14
- * actually reaches on its own, so in practice this waits out `timeoutMs`
15
- * and terminates, as it always has. A `persistent` agent's conversation
10
+ * What "done" means depends on the agent's `sandbox_mode` (#2718). Any
11
+ * conversation is done at `completed | failed | timed_out | terminated`,
12
+ * but a running server's conversation reaches none of those on its own: when
13
+ * a turn ends, the conversation settles on `idle`. An `ephemeral`
14
+ * conversation is done once it is `idle` and its latest turn (`GET .../turns`)
15
+ * has ended (`completed | failed | interrupted`), and the result is that
16
+ * turn's outcome (#3386). Before #3386 this path waited for the four statuses
17
+ * only, so every ephemeral run waited out `timeoutMs` and was terminated. An
18
+ * ephemeral machine is its own, so by default it is terminated once the wait
19
+ * ends, cleanly or not (`terminate: "always"`); pass `terminate: "never"` to
20
+ * keep the conversation up for a later turn through `fountainPrompt`
21
+ * (#3356). A `persistent` agent's conversation
16
22
  * (`Steward`, and `Box` from #2705) shares one machine across every
17
23
  * conversation on it, and a turn ending there does not tear the sandbox
18
24
  * down: the conversation settles on `idle`, not on any of the four
@@ -43,11 +49,12 @@
43
49
  */
44
50
  import { type FountainHttp, type FountainConnectionDeps } from "./fountain-apply.js";
45
51
  /**
46
- * Conversation statuses that end an *ephemeral* agent's run. `completed`
47
- * and `timed_out` are not values fountain's `Conversation.status` takes
48
- * today (its enum is `pending | running | idle | failed | terminated`) —
49
- * they are kept so a server that starts reporting them is handled without
50
- * a further change here.
52
+ * Conversation statuses that end any agent's run without reading its turns.
53
+ * `completed` and `timed_out` are not values fountain's `Conversation.status`
54
+ * takes today (its enum is `pending | running | idle | failed | terminated`);
55
+ * they are kept so a server that starts reporting them is handled without a
56
+ * further change here. An ephemeral conversation also ends on `idle` once its
57
+ * latest turn has ended (#3386).
51
58
  */
52
59
  export declare const TERMINAL_STATUSES: Set<string>;
53
60
  /**
@@ -105,10 +112,12 @@ export interface FountainRunArgs {
105
112
  pollMs?: number;
106
113
  /**
107
114
  * When to terminate the conversation's machine (#2718). Default follows
108
- * the agent's `sandbox_mode`: `on-deadline` for `ephemeral` (unchanged),
109
- * `never` for `persistent` — its machine is a home meant to outlive the
115
+ * the agent's `sandbox_mode`: `always` for `ephemeral` (the machine is the
116
+ * run's own, so it goes once the turn ends or the deadline fires, #3386),
117
+ * `never` for `persistent` (its machine is a home meant to outlive the
110
118
  * conversation, so a run that hits its deadline leaves it be unless this
111
- * says otherwise.
119
+ * says otherwise). Pass `never` on an ephemeral run to send it a later turn
120
+ * with `fountainPrompt`.
112
121
  */
113
122
  terminate?: TerminatePolicy;
114
123
  /** Injectable clock/sleep for tests. */
@@ -117,9 +126,10 @@ export interface FountainRunArgs {
117
126
  export interface FountainRunResult {
118
127
  conversationId: string;
119
128
  /**
120
- * The run's outcome. For a persistent agent whose turn ended, this is the
121
- * turn's own status (`completed | failed | interrupted`); otherwise it is
122
- * the conversation's status when the wait ended (`terminated` on a
129
+ * The run's outcome. For a conversation that settled on `idle` after its
130
+ * turn (persistent, or ephemeral since #3386), this is the turn's own
131
+ * status (`completed | failed | interrupted`); otherwise it is the
132
+ * conversation's status when the wait ended (`terminated` on a
123
133
  * deadline). For a persistent agent launched with no prompt (#2781), it is
124
134
  * the sandbox's outcome: `provisioned` or `failed`.
125
135
  */
@@ -1 +1 @@
1
- {"version":3,"file":"fountain-run.d.ts","sourceRoot":"","sources":["../../../src/op/activities/fountain-run.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAC5B,MAAM,kBAAkB,CAAC;AAE1B;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,aAA8D,CAAC;AAE7F;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,aAA0C,CAAC;AAKhF;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,aAAa,GAAG,QAAQ,CAAC;AAEjE,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,wCAAwC;IACxC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,UAAU,EAAE,OAAO,CAAC;IACpB,wEAAwE;IACxE,oBAAoB,EAAE,OAAO,CAAC;IAC9B,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8FAA8F;IAC9F,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yHAAyH;IACzH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAaD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,qEAAqE;AACrE,wBAAsB,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAe5F;AAED,qFAAqF;AACrF,wBAAsB,cAAc,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGvF;AAyCD,wBAAsB,WAAW,CAC/B,IAAI,EAAE,eAAe,EACrB,MAAM,CAAC,EAAE,WAAW,EACpB,IAAI,CAAC,EAAE,YAAY,EACnB,IAAI,CAAC,EAAE,sBAAsB,GAC5B,OAAO,CAAC,iBAAiB,CAAC,CAqH5B"}
1
+ {"version":3,"file":"fountain-run.d.ts","sourceRoot":"","sources":["../../../src/op/activities/fountain-run.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAEH,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAC5B,MAAM,kBAAkB,CAAC;AAE1B;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,aAA8D,CAAC;AAE7F;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,aAA0C,CAAC;AAKhF;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,aAAa,GAAG,QAAQ,CAAC;AAEjE,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,wCAAwC;IACxC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;;;OAOG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,UAAU,EAAE,OAAO,CAAC;IACpB,wEAAwE;IACxE,oBAAoB,EAAE,OAAO,CAAC;IAC9B,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8FAA8F;IAC9F,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yHAAyH;IACzH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAaD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,qEAAqE;AACrE,wBAAsB,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAe5F;AAED,qFAAqF;AACrF,wBAAsB,cAAc,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGvF;AAyCD,wBAAsB,WAAW,CAC/B,IAAI,EAAE,eAAe,EACrB,MAAM,CAAC,EAAE,WAAW,EACpB,IAAI,CAAC,EAAE,YAAY,EACnB,IAAI,CAAC,EAAE,sBAAsB,GAC5B,OAAO,CAAC,iBAAiB,CAAC,CAwH5B"}
@@ -9,6 +9,48 @@
9
9
  * spelling of the same command. Hence one module, imported by both, with no
10
10
  * dependencies of its own so neither drags the other in.
11
11
  */
12
- /** The prompt one run of `op` is posted as, and the string a turn is matched by. */
12
+ /**
13
+ * The bare line one run of `op` is: what a steward's Schedule posts, and the
14
+ * prefix a turn is matched by. The runtime posts {@link hostedRunPrompt}.
15
+ */
13
16
  export declare function runPrompt(op: string): string;
17
+ /**
18
+ * One argument as the posted command line spells it (#3539): bare when it is
19
+ * a plain word, otherwise in double quotes with `\` and `"` escaped, which
20
+ * is the quoting `tokenize` undoes. An approver named "Alex Smith" reaches the
21
+ * sandbox as one `--approver` value rather than as `Alex` and a stray `Smith`.
22
+ */
23
+ export declare function quoteArg(value: string): string;
24
+ /** What {@link hostedRunPrompt} puts on the line after `chant run <op>`. */
25
+ export interface HostedRunPromptOptions {
26
+ /** `--env`: refused by name unless it is one plain word. */
27
+ env?: string;
28
+ /** `--param name=value`, one flag per entry, in order (#3539). */
29
+ params?: Record<string, unknown>;
30
+ /** Flags after `--on local`, as `[flag, value]`; each value is quoted as needed. */
31
+ flags?: Array<[string, string]>;
32
+ /** Words appended as they are, already spelled for the command line. */
33
+ extra?: string[];
34
+ }
35
+ /**
36
+ * The prompt a hosted run is posted as: {@link runPrompt}, then `--env <env>`
37
+ * when the caller named one (#3232), then each `--param` (#3539), then
38
+ * `--on local` (#3225), then any further flags.
39
+ *
40
+ * `--env` carries the environment the caller asked for into the sandbox,
41
+ * where `chant acp` hands it to the run as `currentOpRun().env`. `--param`
42
+ * rides along so the sandbox runs the line the caller typed. `--on local`
43
+ * keeps a project's `run.on: "fountain"` from sending the posted command
44
+ * back to fountain: the sandbox runs the Op itself. `chant acp` already runs
45
+ * every `chant run <op>` on the local runtime; the flag makes the same true
46
+ * for any other agent that runs the line at a shell.
47
+ *
48
+ * A turn still matches {@link runPrompt} by prefix (`turnRunsOp`), and a
49
+ * steward's Schedule keeps the bare line. An `--env` value that is not one
50
+ * plain word is refused by name rather than posted; a `--param` or flag value
51
+ * is quoted ({@link quoteArg}).
52
+ */
53
+ export declare function hostedRunPrompt(op: string, opts?: HostedRunPromptOptions): string;
54
+ /** The `--env` a posted prompt carries, or undefined. */
55
+ export declare function envOfPrompt(prompt: string | undefined): string | undefined;
14
56
  //# sourceMappingURL=run-prompt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"run-prompt.d.ts","sourceRoot":"","sources":["../../src/op/run-prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,oFAAoF;AACpF,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE5C"}
1
+ {"version":3,"file":"run-prompt.d.ts","sourceRoot":"","sources":["../../src/op/run-prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;GAGG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE5C;AAeD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAG9C;AAED,4EAA4E;AAC5E,MAAM,WAAW,sBAAsB;IACrC,4DAA4D;IAC5D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,oFAAoF;IACpF,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChC,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,GAAE,sBAA2B,GAAG,MAAM,CAkBrF;AASD,yDAAyD;AACzD,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAK1E"}
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * `chant run <op> --on fountain` hands the run to a fountain teammate instead
5
5
  * of executing it here. This module is the client for that: it posts the
6
- * command line `chant run <op>` as a prompt on the steward's thread, tails the
6
+ * command line `chant run <op> [--env <env>] [--param k=v ...] --on local` ({@link hostedRunPrompt})
7
+ * as a prompt on the steward's thread, tails the
7
8
  * conversation's SSE stream, and reports what comes back through the
8
9
  * {@link OpRuntimeProvider} contract core defines in
9
10
  * `packages/core/src/op/runtime.ts`.
@@ -62,8 +63,8 @@
62
63
  import { type ChantConfig } from "@intentius/chant/config";
63
64
  import type { OpRunRecord, OpRunState, OpRunStatus, OpRuntimeProvider, StepRecord } from "@intentius/chant/op";
64
65
  import { type FountainHttp } from "./activities/fountain-apply.js";
65
- import { runPrompt } from "./run-prompt.js";
66
- export { runPrompt };
66
+ import { runPrompt, hostedRunPrompt, envOfPrompt, quoteArg } from "./run-prompt.js";
67
+ export { runPrompt, hostedRunPrompt, envOfPrompt, quoteArg };
67
68
  /** One server-sent event, already framed. `data` is the raw payload text. */
68
69
  export interface FountainSseEvent {
69
70
  /** The event id, which becomes the next connection's `Last-Event-ID`. */
@@ -181,7 +182,7 @@ export declare function conversationIsTerminal(status?: string): boolean;
181
182
  * turn — its status, its sandbox's, and how many turns it managed. Pure.
182
183
  */
183
184
  export declare function conversationFailureReason(conversation: Conversation): string;
184
- /** Does this turn's prompt name `op`? The prompt is `chant run <op>`, exactly. */
185
+ /** Does this turn's prompt name `op`? The prompt is `chant run <op>`, alone or followed by flags. */
185
186
  export declare function turnRunsOp(turn: Turn, op: string): boolean;
186
187
  /**
187
188
  * The run record a turn's final message carries.
@@ -207,6 +208,15 @@ export declare function runStateOfTurn(conversationStatus?: string, turnState?:
207
208
  * processes, because nothing here is this client's to remember.
208
209
  */
209
210
  export declare function createFountainOpRuntime(opts?: FountainOpRuntimeOptions): OpRuntimeProvider;
211
+ /**
212
+ * The `--env` and `--param`s a posted prompt carries, read with the same
213
+ * quote-aware split `chant acp` uses. A prompt that does not split (an
214
+ * unterminated quote) carries neither.
215
+ */
216
+ export declare function flagsOfPrompt(prompt: string | undefined): {
217
+ env?: string;
218
+ params?: Record<string, string>;
219
+ };
210
220
  interface TailOptions {
211
221
  sse: FountainSse;
212
222
  conversationId: string;
@@ -223,6 +233,12 @@ interface TailOptions {
223
233
  http?: FountainHttp;
224
234
  /** How much silence asks fountain about the conversation. Default 2s. */
225
235
  pollIntervalMs?: number;
236
+ /**
237
+ * Turn ids that existed before this run's prompt was posted. The stream
238
+ * replays the whole log on a first connection, so events of these turns are
239
+ * skipped: an earlier turn's `done` must not settle this run (#3524).
240
+ */
241
+ ignoreTurns?: ReadonlySet<string>;
226
242
  }
227
243
  /**
228
244
  * Tail one conversation to the end of its turn.
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/op/runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/op/runtime.ts"],"names":[],"mappings":"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"}
@@ -31,4 +31,4 @@ The environment's config is the enforcement boundary, so watch it: `chant lifecy
31
31
 
32
32
  ## Running conversations
33
33
 
34
- Conversations are runs, not resources. Use the `fountainRun` activity: resolves the agent by name, starts (optionally with a prompt and an allowlisted vault), and waits for the turn to end. What "end" means, and what happens to the machine, follows the agent's `sandbox_mode`: an `ephemeral` agent's conversation is polled for a terminal status and terminated on deadline, same as before; a `persistent` agent's (a `Steward` or `Box`) conversation settles on `idle` once its turn ends — machine still up for the next turn — so `fountainRun` reads the turn back and returns its outcome (`completed | failed | interrupted`) without terminating anything, by default. Pass `terminate: "on-deadline" | "always"` to opt a persistent agent's run back into ending the machine. To add a turn to a conversation that already exists, use `fountainPrompt` with the conversation's id: it sends the prompt on the same session and waits for that turn, interrupting it at `timeoutMs`. It cannot reach a terminated conversation (fountain answers 410), so run the earlier turn with `terminate: "never"`, and it cannot narrow tools for one turn: that is the agent's `permission_policy`, set at launch. Interrupts and permission answers on their own are fountain's own conversations API.
34
+ Conversations are runs, not resources. Use the `fountainRun` activity: resolves the agent by name, starts (optionally with a prompt and an allowlisted vault), and waits for the turn to end. What "end" means, and what happens to the machine, follows the agent's `sandbox_mode`: an `ephemeral` agent's conversation is done once it settles on `idle` with its turn ended, and `fountainRun` returns that turn's outcome and terminates the machine (`terminate: "always"`, its default; pass `"never"` to keep it for a later turn); a `persistent` agent's (a `Steward` or `Box`) conversation settles on `idle` once its turn ends — machine still up for the next turn — so `fountainRun` reads the turn back and returns its outcome (`completed | failed | interrupted`) without terminating anything, by default. Pass `terminate: "on-deadline" | "always"` to opt a persistent agent's run back into ending the machine. To add a turn to a conversation that already exists, use `fountainPrompt` with the conversation's id: it sends the prompt on the same session and waits for that turn, interrupting it at `timeoutMs`. It cannot reach a terminated conversation (fountain answers 410), so run the earlier turn with `terminate: "never"`, and it cannot narrow tools for one turn: that is the agent's `permission_policy`, set at launch. Interrupts and permission answers on their own are fountain's own conversations API.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentius/chant-lexicon-fountain",
3
- "version": "0.105.0",
3
+ "version": "0.106.1",
4
4
  "type": "module",
5
5
  "description": "Fountain lexicon for chant — sandboxed agent environments, vaults, and agents as typed estate",
6
6
  "license": "Apache-2.0",
@@ -50,7 +50,7 @@
50
50
  "bundle": "tsx src/package-cli.ts"
51
51
  },
52
52
  "peerDependencies": {
53
- "@intentius/chant": "^0.105.0",
53
+ "@intentius/chant": "^0.106.1",
54
54
  "typescript": "^5.9.3",
55
55
  "zod": "^4.3.6"
56
56
  },
@@ -8,8 +8,15 @@
8
8
  * would pass without the protocol ever being spoken.
9
9
  */
10
10
 
11
- import { describe, it, expect } from "vitest";
11
+ import { describe, it, expect, vi } from "vitest";
12
12
  import { PassThrough } from "node:stream";
13
+
14
+ // The workspace's sealed gates (`identity.gates`), standing in for a project's declaration.
15
+ const sealedGates = new Set<string>();
16
+ vi.mock("@intentius/chant/op/gate", async (importOriginal) => {
17
+ const actual = await importOriginal<typeof import("@intentius/chant/op/gate")>();
18
+ return { ...actual, gateIsSealed: async (gate: string) => sealedGates.has(gate) };
19
+ });
13
20
  import {
14
21
  JsonRpcPeer,
15
22
  memoryTransportPair,
@@ -126,6 +133,8 @@ interface StubHostOptions {
126
133
 
127
134
  interface StubHost extends ChantHost {
128
135
  started: string[];
136
+ /** The options each `startOp` was handed, in order. */
137
+ startOpts: OpRunStartOptions[];
129
138
  verbsRun: string[];
130
139
  resolvedGates: Array<{ op: string; gate: string; by: string }>;
131
140
  firstStep: Promise<void>;
@@ -140,6 +149,7 @@ function stubHost(opts: StubHostOptions = {}): StubHost {
140
149
  const host: StubHost = {
141
150
  cwd: process.cwd(),
142
151
  started: [],
152
+ startOpts: [],
143
153
  verbsRun: [],
144
154
  resolvedGates: [],
145
155
  firstStep,
@@ -153,6 +163,7 @@ function stubHost(opts: StubHostOptions = {}): StubHost {
153
163
  },
154
164
  async startOp(op: OpConfig, start: OpRunStartOptions): Promise<OpRunHandle> {
155
165
  host.started.push(op.name);
166
+ host.startOpts.push(start);
156
167
  const runId = "run-1";
157
168
  const settled = (async (): Promise<OpRunStatus> => {
158
169
  const records = opts.records ?? [];
@@ -405,6 +416,39 @@ describe("chant acp", () => {
405
416
  }
406
417
  });
407
418
 
419
+ // #3539: on fountain the session names every run by the conversation id,
420
+ // and a prompt's --param and --work reach the run as `chant run` passes them.
421
+ it("names the run by the server's runId and passes --env, --param and --work through", async () => {
422
+ const host = stubHost({ records: okRecords });
423
+ const server = new AcpServer({ createHost: () => host, runId: "conv-42" });
424
+ const { client, sessionId } = await open(server);
425
+
426
+ await client.peer.request("session/prompt", {
427
+ sessionId,
428
+ prompt: promptOf('chant run demo-op --env prod --param tier=gold --param "note=two words" --work ISSUE-7 --on local'),
429
+ });
430
+
431
+ expect(host.startOpts).toHaveLength(1);
432
+ expect(host.startOpts[0]).toMatchObject({
433
+ env: "prod",
434
+ runId: "conv-42",
435
+ params: { tier: "gold", note: "two words" },
436
+ work: { item: "ISSUE-7" },
437
+ });
438
+ });
439
+
440
+ it("leaves the run id to the runtime when the server names none", async () => {
441
+ const host = stubHost({ records: okRecords });
442
+ const server = new AcpServer({ createHost: () => host });
443
+ const { client, sessionId } = await open(server);
444
+
445
+ await client.peer.request("session/prompt", { sessionId, prompt: promptOf("chant run demo-op") });
446
+
447
+ expect(host.startOpts[0]).not.toHaveProperty("runId");
448
+ expect(host.startOpts[0]).not.toHaveProperty("params");
449
+ expect(host.startOpts[0]).not.toHaveProperty("work");
450
+ });
451
+
408
452
  it("replies with the run record as the final chunk", async () => {
409
453
  const record = {
410
454
  version: 1 as const,
@@ -527,12 +571,34 @@ describe("chant acp", () => {
527
571
 
528
572
  expect(result.stopReason).toBe("end_turn");
529
573
  expect(text(client.updates)).toContain("chant approve demo-op deploy");
574
+ expect(text(client.updates)).not.toContain("--sign");
530
575
  expect(client.permissionRequests).toEqual([]);
531
576
 
532
577
  // A step the run never reached is settled rather than left spinning.
533
578
  expect(toolUpdates(client.updates).length).toBe(toolCalls(client.updates).length);
534
579
  });
535
580
 
581
+ it("names --sign in the approve hint when the gate is sealed (#3521)", async () => {
582
+ sealedGates.add("deploy");
583
+ try {
584
+ const host = stubHost({
585
+ records: [okRecords[0]],
586
+ status: {
587
+ state: "gated",
588
+ gate: { name: "deploy", since: "2026-09-06T00:00:01.000Z" },
589
+ } as Partial<OpRunStatus>,
590
+ });
591
+ const server = new AcpServer({ createHost: () => host });
592
+ const { client, sessionId } = await open(server);
593
+
594
+ await client.peer.request("session/prompt", { sessionId, prompt: promptOf("chant run demo-op") });
595
+
596
+ expect(text(client.updates)).toContain("chant approve demo-op deploy --sign");
597
+ } finally {
598
+ sealedGates.delete("deploy");
599
+ }
600
+ });
601
+
536
602
  it("asks for permission and waits under --durable-requests, then completes on resume", async () => {
537
603
  let gated = true;
538
604
  const gatedHost = stubHost({
package/src/acp/serve.ts CHANGED
@@ -33,9 +33,17 @@ export async function serveAcpOverStdio(opts: { durableRequests?: boolean; stewa
33
33
  // this session is refused, as the gate's resolution is above.
34
34
  if (opts.steward) setStewardTurn({ steward: opts.steward });
35
35
 
36
+ // chant#3539 — fountain gives the command it spawns the conversation's id
37
+ // in `FOUNTAIN_CONVERSATION_ID` (process env only, never on disk), and
38
+ // `chant run <op> --on fountain` names the run by that same id. Naming the
39
+ // sandbox's runs by it joins the two: the run record written here carries
40
+ // the id the caller's `chant run status` reports.
41
+ const conversationId = process.env.FOUNTAIN_CONVERSATION_ID?.trim();
42
+
36
43
  const server = new AcpServer({
37
44
  durableRequests: opts.durableRequests ?? false,
38
45
  version: lexiconVersion(),
46
+ ...(conversationId ? { runId: conversationId } : {}),
39
47
  });
40
48
 
41
49
  const transport = streamTransport(process.stdin, process.stdout);
package/src/acp/server.ts CHANGED
@@ -70,6 +70,14 @@ export interface AcpServerOptions {
70
70
  createHost?: (cwd: string) => ChantHost;
71
71
  /** Mints permission request ids. Injected so a test can pin them. */
72
72
  newRequestId?: () => string;
73
+ /**
74
+ * The id every Op run in this process is named by (#3539). On fountain it
75
+ * is the conversation id the sandbox's environment carries
76
+ * (`FOUNTAIN_CONVERSATION_ID`), so the run record the sandbox writes and
77
+ * the run `chant run status --on fountain` reports have the same id.
78
+ * Omitted, the local runtime mints one per run.
79
+ */
80
+ runId?: string;
73
81
  }
74
82
 
75
83
  /** One open session: a working directory, the turn in flight, and any gate awaiting an answer. */
@@ -93,6 +101,7 @@ export class AcpServer implements JsonRpcHandler {
93
101
  private readonly version: string;
94
102
  private readonly createHost: (cwd: string) => ChantHost;
95
103
  private readonly newRequestId: () => string;
104
+ private readonly runId: string | undefined;
96
105
  /** Serializes turns — see the module doc. */
97
106
  private queue: Promise<unknown> = Promise.resolve();
98
107
 
@@ -101,6 +110,7 @@ export class AcpServer implements JsonRpcHandler {
101
110
  this.version = opts.version ?? "dev";
102
111
  this.createHost = opts.createHost ?? createChantHost;
103
112
  this.newRequestId = opts.newRequestId ?? (() => randomUUID());
113
+ this.runId = opts.runId !== undefined && opts.runId !== "" ? opts.runId : undefined;
104
114
  }
105
115
 
106
116
  /** Serve one connection until it closes. */
@@ -256,6 +266,7 @@ export class AcpServer implements JsonRpcHandler {
256
266
  signal: controller.signal,
257
267
  durableRequests: this.durableRequests,
258
268
  newRequestId: this.newRequestId,
269
+ ...(this.runId ? { runId: this.runId } : {}),
259
270
  });
260
271
  if (outcome.permission) {
261
272
  session.permissions.set(outcome.permission.requestId, { ...outcome.permission });
package/src/acp/turn.ts CHANGED
@@ -22,7 +22,7 @@ import type { OpConfig, StepDefinition } from "@intentius/chant/op/types";
22
22
  import type { StepRecord } from "@intentius/chant/op/local-executor";
23
23
  import type { OpRunStatus } from "@intentius/chant/op/runtime";
24
24
  import type { PendingGateRecord } from "@intentius/chant/lifecycle/gate-ledger";
25
- import { approveCommand } from "@intentius/chant/op/gate";
25
+ import { approveCommand, gateIsSealed } from "@intentius/chant/op/gate";
26
26
  import { gateName } from "@intentius/chant/op/gate-name";
27
27
  import type { ChantCommand } from "./command-line";
28
28
  import type { ChantHost } from "./host";
@@ -106,6 +106,8 @@ export interface TurnOptions {
106
106
  durableRequests: boolean;
107
107
  /** Mints the id a resume prompt names. Injected so a test can pin it. */
108
108
  newRequestId: () => string;
109
+ /** The id an Op run is named by, when the host names runs (#3539: fountain's conversation id). */
110
+ runId?: string;
109
111
  }
110
112
 
111
113
  /**
@@ -210,8 +212,19 @@ async function runOpTurn(
210
212
 
211
213
  let status: OpRunStatus;
212
214
  try {
215
+ // What `chant run` itself hands a runtime (#3539): the run's id, when
216
+ // the session names it, and the prompt's `--param` and `--work`, which a
217
+ // turn used to drop.
218
+ const params = paramsOf(command.args.param);
219
+ const work = {
220
+ ...(command.args.work !== undefined ? { item: command.args.work } : {}),
221
+ ...(command.args.holder !== undefined ? { holder: command.args.holder } : {}),
222
+ };
213
223
  const handle = await host.startOp(config, {
214
224
  ...(command.args.env ? { env: command.args.env } : {}),
225
+ ...(opts.runId ? { runId: opts.runId } : {}),
226
+ ...(params ? { params } : {}),
227
+ ...(Object.keys(work).length > 0 ? { work } : {}),
215
228
  progress: settle,
216
229
  signal,
217
230
  });
@@ -252,6 +265,18 @@ async function runOpTurn(
252
265
  return { stopReason: "end_turn" };
253
266
  }
254
267
 
268
+ /** `--param name=value` flags as a record, the way `chant run` reads them. */
269
+ function paramsOf(entries: string[] | undefined): Record<string, string> | undefined {
270
+ if (!entries?.length) return undefined;
271
+ const out: Record<string, string> = {};
272
+ for (const entry of entries) {
273
+ const eq = entry.indexOf("=");
274
+ if (eq === -1) out[entry] = "";
275
+ else out[entry.slice(0, eq)] = entry.slice(eq + 1);
276
+ }
277
+ return out;
278
+ }
279
+
255
280
  /**
256
281
  * A gated run's reply.
257
282
  *
@@ -277,7 +302,7 @@ async function gatedReply(
277
302
  sink.message(
278
303
  `Op "${command.op}" is waiting on gate "${gate.name}", pending since ${gate.since}` +
279
304
  (pending?.expiresAt ? ` and expiring ${pending.expiresAt}` : "") +
280
- `.\nApprove with: ${approveCommand(command.op, gate.name)}\n`,
305
+ `.\nApprove with: ${approveCommand(command.op, gate.name, undefined, undefined, await gateIsSealed(gate.name))}\n`,
281
306
  );
282
307
  sink.message(JSON.stringify(status.result?.record ?? status, null, 2) + "\n");
283
308
 
@@ -13,10 +13,11 @@
13
13
  * What fountain v0.21.0 can and cannot do here, which decides the arguments:
14
14
  *
15
15
  * - A conversation that is `terminated` takes no more turns: the prompts route
16
- * answers 410. `fountainRun` terminates an ephemeral agent's conversation at
17
- * its deadline by default, so a caller that wants a later turn runs the first
18
- * one with `terminate: "never"` (a persistent agent's default) and ends the
19
- * conversation itself, or with this op's `terminate`, after the last turn.
16
+ * answers 410. `fountainRun` terminates an ephemeral agent's conversation
17
+ * once its turn ends (or at its deadline) by default, so a caller that wants a
18
+ * later turn runs the first one with `terminate: "never"` (a persistent
19
+ * agent's default) and ends the conversation itself, or with this op's
20
+ * `terminate`, after the last turn.
20
21
  * - A turn has no tool allowlist of its own. The prompts route takes only the
21
22
  * prompt, images and `client_request_id`; the tools a conversation may use are
22
23
  * its agent's `permission_policy`, narrowed once at launch, and nothing on the