@owlmeans/llm-common 0.1.18-rc.11 → 0.1.18-rc.13

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 (50) hide show
  1. package/README.md +9 -3
  2. package/agent-meta/manifest.json +2 -2
  3. package/agent-meta/skills/llm-common/SKILL.md +54 -4
  4. package/build/consts.d.ts +15 -1
  5. package/build/consts.d.ts.map +1 -1
  6. package/build/consts.js +14 -0
  7. package/build/consts.js.map +1 -1
  8. package/build/delegate/index.d.ts +2 -0
  9. package/build/delegate/index.d.ts.map +1 -0
  10. package/build/delegate/index.js +2 -0
  11. package/build/delegate/index.js.map +1 -0
  12. package/build/delegate/types.d.ts +108 -0
  13. package/build/delegate/types.d.ts.map +1 -0
  14. package/build/delegate/types.js +39 -0
  15. package/build/delegate/types.js.map +1 -0
  16. package/build/files/utils.d.ts.map +1 -1
  17. package/build/index.d.ts +2 -0
  18. package/build/index.d.ts.map +1 -1
  19. package/build/index.js +2 -0
  20. package/build/index.js.map +1 -1
  21. package/build/inquiry/consts.d.ts +48 -0
  22. package/build/inquiry/consts.d.ts.map +1 -0
  23. package/build/inquiry/consts.js +50 -0
  24. package/build/inquiry/consts.js.map +1 -0
  25. package/build/inquiry/index.d.ts +4 -0
  26. package/build/inquiry/index.d.ts.map +1 -0
  27. package/build/inquiry/index.js +3 -0
  28. package/build/inquiry/index.js.map +1 -0
  29. package/build/inquiry/types.d.ts +72 -0
  30. package/build/inquiry/types.d.ts.map +1 -0
  31. package/build/inquiry/types.js +2 -0
  32. package/build/inquiry/types.js.map +1 -0
  33. package/build/inquiry/utils.d.ts +45 -0
  34. package/build/inquiry/utils.d.ts.map +1 -0
  35. package/build/inquiry/utils.js +72 -0
  36. package/build/inquiry/utils.js.map +1 -0
  37. package/build/types.d.ts +16 -2
  38. package/build/types.d.ts.map +1 -1
  39. package/package.json +4 -2
  40. package/src/consts.ts +14 -0
  41. package/src/delegate/index.ts +1 -0
  42. package/src/delegate/types.ts +116 -0
  43. package/src/index.ts +2 -0
  44. package/src/inquiry/consts.ts +52 -0
  45. package/src/inquiry/index.ts +3 -0
  46. package/src/inquiry/types.ts +77 -0
  47. package/src/inquiry/utils.ts +84 -0
  48. package/src/types.ts +16 -2
  49. package/tests/inquiry.spec.ts +112 -0
  50. package/tsconfig.json +3 -1
package/README.md CHANGED
@@ -10,6 +10,8 @@ persistence/queue consumer need to name the same things.
10
10
  - The inheritable `ModelPolicy` and its JSON-safe `ModelConfigPatch` / `ModelConfigOverride`
11
11
  - `ExecutionState` / `TaskExecutionState` — what an execution looks like once its
12
12
  collaborators (models, file access, live handles) are stripped off
13
+ - The inquiry contracts — one question put to a person mid-run, the answer that comes back,
14
+ and the pure helpers every layer reads an answer through
13
15
  - Spectator record contracts and the `NullCapture` diagnostic
14
16
  - No `@langchain/*` runtime dependency: safe to import from a browser bundle, a queue
15
17
  worker, or a package that must not pull an inference SDK
@@ -20,7 +22,7 @@ extends these; `@owlmeans/llm` implements against them.
20
22
  ## Installation
21
23
 
22
24
  ```bash
23
- bun add @owlmeans/llm-common
25
+ bun add @owlmeans/llm-common@^0.1.18-rc.11
24
26
  ```
25
27
 
26
28
  ## Usage
@@ -63,12 +65,13 @@ export interface MyExecutionState extends ExecutionState {
63
65
 
64
66
  | Export | Description |
65
67
  |--------|-------------|
66
- | `ModelProvider` | `OpenAI` · `Anthropic` · `Compatible` — each maps to an `LlmPlugin` type in `@owlmeans/llm`. |
68
+ | `ModelProvider` | `OpenAI` · `Anthropic` · `Compatible` · `Delegated` — each maps to an `LlmPlugin` type in `@owlmeans/llm`. `Delegated` talks to no provider: the call is handed to a transport the application seated (`@owlmeans/llm-delegate`). |
67
69
  | `ExecutionLevel` | `Project` → `Task` → `Helper`; an execution is refined downward only. |
68
70
  | `ExecutionEffort` | `Economy` · `Standard` · `High` · `Max` — the one "how hard should this run" axis. |
69
71
  | `StructuredMode` | `Native` (provider JSON-schema mode) vs `Tool` (forced tool call). |
70
72
  | `SpectatorContentType` | `Text` · `Json` · `ToolCall`. |
71
73
  | `SPECTATOR_GENERAL` | Default entry kind for consumers that do not classify calls. |
74
+ | `DEFAULT_INQUIRY_ANSWER_CHARS` (2000) · `DEFAULT_INQUIRY_OPTIONS` (12) · `INQUIRY_STATE_TEXT_CHARS` (200) · `CONFIRM_YES` / `CONFIRM_NO` | The one ceiling on a stored answer, the point past which a choice is not a question, what a pipeline state keeps of an answer's prose, and the two confirmation values. Never introduce a second copy of any of them. |
72
75
 
73
76
  ### Types
74
77
 
@@ -82,6 +85,9 @@ export interface MyExecutionState extends ExecutionState {
82
85
  | `TaskExecutionState` | Adds `phase` / `completed` / `cursor` / `data` for checkpoint & resume. |
83
86
  | `LlmPurpose` | `{ type?, dedication? }` — observability metadata carried on every call. |
84
87
  | `NullCapture`, `NullKind` | Full diagnostics of a call that returned nothing usable. |
88
+ | `Inquiry`, `InquiryAnswer`, `InquiryOption`, `InquiryTransport`, `InquiryConfig` | One question put to a person while a run is in flight, and its answer. `ExecutionState.inquiry` carries the channel and the policy, so a resumed run asks the same way. |
89
+ | `InquiryKind`, `InquiryPolicy` | `choice` / `text` / `confirm`; `ask` / `default` / `refuse` — no configuration means `default`, so a run nobody is watching never blocks on a question. |
90
+ | `defaultAnswerFor`, `answeredWith`, `isDeclined`, `capAnswer`, `stateAnswerOf`, `renderInquiry` | The ONE reading of an answer every layer shares. `capAnswer` cuts prose only and reports the cut; a `value` is the decision itself and is never shortened. |
85
91
  | `SpectatorArgument`, `SpectatorEntry`, `SpectatorEntryLogged`, `SpectatorEntryMessage` | The record format an observability sink stores. |
86
92
 
87
93
  ## Related
@@ -96,7 +102,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
96
102
  your project's skill store (`.agents/skills/`):
97
103
 
98
104
  ```sh
99
- npx @owlmeans/agent-skills
105
+ npx @owlmeans/agent-skills@^0.1.18-rc.13
100
106
  ```
101
107
 
102
108
  The embedded files are version-matched to this package release. Do not edit them
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@owlmeans/llm-common",
4
- "version": "0.1.18-rc.11",
5
- "generatedAt": "2026-09-01T22:50:56.459Z",
4
+ "version": "0.1.18-rc.13",
5
+ "generatedAt": "2026-09-10T18:54:42.500Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -8,7 +8,7 @@ user-invocable: false
8
8
  # @owlmeans/llm-common
9
9
 
10
10
  **Layer:** Core
11
- **Install:** `"@owlmeans/llm-common": "^0.1.18-rc.11"` in `dependencies`
11
+ **Install:** `"@owlmeans/llm-common": "^0.1.18-rc.13"` in `dependencies`
12
12
 
13
13
  The contracts half of the LLM stack. **No `@langchain/*` runtime dependency** — importable
14
14
  from a browser bundle, a queue worker, or any package that must not pull an inference SDK.
@@ -34,21 +34,47 @@ The dependency direction is one-way: a domain contracts package extends these;
34
34
  | `SkillDefinition` | One named block of reusable prompt knowledge. `body` must be a pure constant. |
35
35
  | `PromptPolicy` | `{ role?, skills?, cacheSystem?, cacheTtl? }` — carried on `ExecutionState`, merged downward. |
36
36
  | `CacheTtl`, `CacheUsage` | `'5m' \| '1h'`; normalized prompt-cache accounting. |
37
- | `LlmFileProvider`, `FileProviderRef`, `resolveFileProvider` | The minimal read/write file contract prompt plugins work against. Its optional `key` is the provider's stable identity (project root, sandbox id) — the only thing a plugin caching per-project reads can key on, since providers are rebuilt per request. |
37
+ | `LlmFileProvider`, `FileProviderRef`, `resolveFileProvider` | The file contract prompt plugins work against — four members, every path relative to the host's project root. `FileProviderRef` accepts the provider or a thunk returning one; `resolveFileProvider` unwraps whichever form arrived, or `undefined`. |
38
38
  | `NullCapture`, `NullKind` | Full diagnostics of a call that returned nothing usable. |
39
+ | `Inquiry`, `InquiryAnswer`, `InquiryOption`, `InquiryTransport`, `InquiryConfig` | One question put to a person mid-run, and the answer that comes back. |
40
+ | `InquiryKind`, `InquiryPolicy` | `choice`/`text`/`confirm`; `ask`/`default`/`refuse`. |
41
+ | `DEFAULT_INQUIRY_ANSWER_CHARS`, `DEFAULT_INQUIRY_OPTIONS`, `INQUIRY_STATE_TEXT_CHARS`, `CONFIRM_YES`, `CONFIRM_NO` | The one answer ceiling, the option ceiling, what a pipeline state may hold of an answer's prose, and the two confirmation values. |
42
+ | `defaultAnswerFor`, `answeredWith`, `capAnswer`, `isDeclined`, `stateAnswerOf`, `renderInquiry` | The pure reading of an inquiry and its answer, shared by every layer. |
39
43
  | `SpectatorArgument`, `SpectatorEntry`, `SpectatorEntryLogged`, `SpectatorEntryMessage` | What an observability sink stores. |
40
44
 
45
+ ## `LlmFileProvider` — what a host must supply
46
+
47
+ A consumer's own file helper satisfies it structurally (`interface FileHelper extends
48
+ LlmFileProvider`); implementing it from scratch means all four:
49
+
50
+ | Member | Contract |
51
+ |---|---|
52
+ | `readFile(path, noThrow?)` | Read a file relative to the root. With `noThrow`, a missing file yields `''`. |
53
+ | `getSourceList(pattern?)` | Glob for files relative to the root. Project-skill discovery in `@owlmeans/agent-skills` is built on it, so a provider that stubs it indexes nothing. |
54
+ | `writeFile(path, content)` | Write relative to the root, creating parent directories. |
55
+ | `deleteFile(path, noThrow?)` | Delete relative to the root. With `noThrow`, a missing file is a no-op. |
56
+ | `key?` | Optional. The provider's stable identity (project root, sandbox id) — the only thing a plugin caching per-project reads can key on, since providers are rebuilt per request. A provider without one is treated as uncacheable. |
57
+
58
+ Resolving the project root is deliberately NOT part of the contract, and an implementation must not
59
+ narrow an inherited signature — that is what stops a rich helper from satisfying this one.
60
+
41
61
  ## Extension rules
42
62
 
43
63
  Open types are open **on purpose** — extend, do not fork:
44
64
 
45
65
  ```typescript
66
+ import type {
67
+ ExecutionState as LlmExecutionState, LlmPurpose,
68
+ TaskExecutionState as LlmTaskExecutionState,
69
+ } from '@owlmeans/llm-common'
70
+
46
71
  // Your roles: an enum whose values satisfy the open `ModelRole` string.
47
72
  export enum MyRole { Analyst = 'analyst', Coder = 'coder' }
48
73
 
49
- // Your purpose and state: extend, never redeclare.
74
+ // Your purpose and state: extend, never redeclare. Aliasing the imports keeps your own
75
+ // `ExecutionState` the name the rest of your domain uses.
50
76
  export interface MyPurpose extends LlmPurpose { agent?: string }
51
- export interface MyExecutionState extends ExecutionState {
77
+ export interface MyExecutionState extends LlmExecutionState {
52
78
  purpose: MyPurpose
53
79
  projectId?: string
54
80
  }
@@ -64,12 +90,35 @@ export interface MyTaskState
64
90
  `SpectatorEntry.kind` is an open `string` for the same reason: declare your own kind enum
65
91
  and narrow it on your own entry interface.
66
92
 
93
+ ## Inquiry — the contracts half
94
+
95
+ `src/inquiry/` carries the human-in-the-loop primitive's serializable half: the question, the
96
+ answer, the transport interface, and the pure helpers every layer reads an answer through.
97
+ `ExecutionState.inquiry?: InquiryConfig` says how one run may put a question to a person, and it is
98
+ STATE rather than a collaborator — a resumed run must ask through the same channel under the same
99
+ policy, so it travels into every snapshot (it is deliberately absent from `@owlmeans/llm`'s
100
+ `COLLABORATOR_KEYS`).
101
+
102
+ `DEFAULT_INQUIRY_ANSWER_CHARS` is the ONE ceiling on a stored answer; every other layer references
103
+ it rather than choosing its own, and `capAnswer` reports the cut (`truncated: true`) instead of
104
+ truncating silently. It cuts the PROSE only: a `value` is the decision itself, so a shortened one
105
+ matches no option and is passed through whole with `truncated` raised on it.
106
+ `INQUIRY_STATE_TEXT_CHARS` is the much smaller amount a resumable pipeline
107
+ state may hold of an answer's free text (`stateAnswerOf`, the other writer of `truncated`) — a
108
+ state is keys and markers, not prose.
109
+ The primitive end to end, including the runtime registry and the pipeline park: [[inquiry]].
110
+
67
111
  ## What must NOT go here
68
112
 
69
113
  Anything that cannot survive `JSON.stringify` or that needs an inference SDK: model
70
114
  instances, credentials, file handles, callbacks, `ModelConfig` (it carries `secret` /
71
115
  `headers` / `fallback` — that lives in `@owlmeans/llm`).
72
116
 
117
+ ## Tests
118
+
119
+ `bun test ./tests` in the package. Contracts and enums are not tested (nothing to assert); the
120
+ specs cover the pure helpers that carry a decision — `tests/inquiry.spec.ts`.
121
+
73
122
  ## Depends On
74
123
 
75
124
  Nothing at runtime. `@langchain/core` is a **dev** dependency, for the `UsageMetadata` type
@@ -78,3 +127,4 @@ on a spectator message only.
78
127
  ## Related
79
128
 
80
129
  - [[llm]] — the runtime that implements these contracts
130
+ - [[inquiry]] — the human-in-the-loop primitive whose contracts live here
package/build/consts.d.ts CHANGED
@@ -9,7 +9,21 @@ export declare enum ModelProvider {
9
9
  /** Anthropic messages API. */
10
10
  Anthropic = "anthropic",
11
11
  /** Any OpenAI-compatible endpoint — OpenRouter, HuggingFace router, Together, vLLM, … */
12
- Compatible = "compatible"
12
+ Compatible = "compatible",
13
+ /**
14
+ * No endpoint at all: the call is handed to whoever holds the execution.
15
+ *
16
+ * A delegated model does not talk to a provider. It packages the call — the system prompt, the
17
+ * conversation, the tools or the schema — and hands it to a transport the application seated,
18
+ * which carries it to something outside this process entirely: a coding agent driving the
19
+ * application through a connector, a human, a test. The answer comes back the same way and is
20
+ * turned into a completion the rest of the stack cannot tell apart from a provider's.
21
+ *
22
+ * It exists so that "who performs this call" can be a property of the SESSION rather than of the
23
+ * code: the same pipeline, the same prompts and the same retry rules, billed to somebody else's
24
+ * model.
25
+ */
26
+ Delegated = "delegated"
13
27
  }
14
28
  /**
15
29
  * Refinement level of an execution. An execution is refined downward only:
@@ -1 +1 @@
1
- {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA;;;;GAIG;AACH,oBAAY,aAAa;IACvB,yFAAyF;IACzF,MAAM,WAAW;IACjB,8BAA8B;IAC9B,SAAS,cAAc;IACvB,yFAAyF;IACzF,UAAU,eAAe;CAC1B;AAED;;;GAGG;AACH,oBAAY,cAAc;IACxB,OAAO,YAAY;IACnB,IAAI,SAAS;IACb,MAAM,WAAW;CAClB;AAED;;;;GAIG;AACH,oBAAY,eAAe;IACzB,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,IAAI,SAAS;IACb,GAAG,QAAQ;CACZ;AAED;;;;;;;;;GASG;AACH,oBAAY,cAAc;IACxB,MAAM,WAAW;IACjB,IAAI,SAAS;CACd;AAED,0DAA0D;AAC1D,oBAAY,oBAAoB;IAC9B,IAAI,SAAS;IACb,IAAI,SAAS;IACb,QAAQ,cAAc;CACvB;AAED,mFAAmF;AACnF,eAAO,MAAM,iBAAiB,YAAY,CAAA;AAE1C;;;;;;;;;;;;;;GAcG;AACH,oBAAY,WAAW;IACrB,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,OAAO,YAAY;CACpB;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,WAAW,EAK3C,CAAA;AAEV,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,MAAM,CAAA;AAEtC;;;;;GAKG;AACH,eAAO,MAAM,YAAY,YAAY,CAAA"}
1
+ {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA;;;;GAIG;AACH,oBAAY,aAAa;IACvB,yFAAyF;IACzF,MAAM,WAAW;IACjB,8BAA8B;IAC9B,SAAS,cAAc;IACvB,yFAAyF;IACzF,UAAU,eAAe;IACzB;;;;;;;;;;;;OAYG;IACH,SAAS,cAAc;CACxB;AAED;;;GAGG;AACH,oBAAY,cAAc;IACxB,OAAO,YAAY;IACnB,IAAI,SAAS;IACb,MAAM,WAAW;CAClB;AAED;;;;GAIG;AACH,oBAAY,eAAe;IACzB,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,IAAI,SAAS;IACb,GAAG,QAAQ;CACZ;AAED;;;;;;;;;GASG;AACH,oBAAY,cAAc;IACxB,MAAM,WAAW;IACjB,IAAI,SAAS;CACd;AAED,0DAA0D;AAC1D,oBAAY,oBAAoB;IAC9B,IAAI,SAAS;IACb,IAAI,SAAS;IACb,QAAQ,cAAc;CACvB;AAED,mFAAmF;AACnF,eAAO,MAAM,iBAAiB,YAAY,CAAA;AAE1C;;;;;;;;;;;;;;GAcG;AACH,oBAAY,WAAW;IACrB,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,OAAO,YAAY;CACpB;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,WAAW,EAK3C,CAAA;AAEV,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,MAAM,CAAA;AAEtC;;;;;GAKG;AACH,eAAO,MAAM,YAAY,YAAY,CAAA"}
package/build/consts.js CHANGED
@@ -11,6 +11,20 @@ export var ModelProvider;
11
11
  ModelProvider["Anthropic"] = "anthropic";
12
12
  /** Any OpenAI-compatible endpoint — OpenRouter, HuggingFace router, Together, vLLM, … */
13
13
  ModelProvider["Compatible"] = "compatible";
14
+ /**
15
+ * No endpoint at all: the call is handed to whoever holds the execution.
16
+ *
17
+ * A delegated model does not talk to a provider. It packages the call — the system prompt, the
18
+ * conversation, the tools or the schema — and hands it to a transport the application seated,
19
+ * which carries it to something outside this process entirely: a coding agent driving the
20
+ * application through a connector, a human, a test. The answer comes back the same way and is
21
+ * turned into a completion the rest of the stack cannot tell apart from a provider's.
22
+ *
23
+ * It exists so that "who performs this call" can be a property of the SESSION rather than of the
24
+ * code: the same pipeline, the same prompts and the same retry rules, billed to somebody else's
25
+ * model.
26
+ */
27
+ ModelProvider["Delegated"] = "delegated";
14
28
  })(ModelProvider || (ModelProvider = {}));
15
29
  /**
16
30
  * Refinement level of an execution. An execution is refined downward only:
@@ -1 +1 @@
1
- {"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA;;;;GAIG;AACH,MAAM,CAAN,IAAY,aAOX;AAPD,WAAY,aAAa;IACvB,yFAAyF;IACzF,kCAAiB,CAAA;IACjB,8BAA8B;IAC9B,wCAAuB,CAAA;IACvB,yFAAyF;IACzF,0CAAyB,CAAA;AAC3B,CAAC,EAPW,aAAa,KAAb,aAAa,QAOxB;AAED;;;GAGG;AACH,MAAM,CAAN,IAAY,cAIX;AAJD,WAAY,cAAc;IACxB,qCAAmB,CAAA;IACnB,+BAAa,CAAA;IACb,mCAAiB,CAAA;AACnB,CAAC,EAJW,cAAc,KAAd,cAAc,QAIzB;AAED;;;;GAIG;AACH,MAAM,CAAN,IAAY,eAKX;AALD,WAAY,eAAe;IACzB,sCAAmB,CAAA;IACnB,wCAAqB,CAAA;IACrB,gCAAa,CAAA;IACb,8BAAW,CAAA;AACb,CAAC,EALW,eAAe,KAAf,eAAe,QAK1B;AAED;;;;;;;;;GASG;AACH,MAAM,CAAN,IAAY,cAGX;AAHD,WAAY,cAAc;IACxB,mCAAiB,CAAA;IACjB,+BAAa,CAAA;AACf,CAAC,EAHW,cAAc,KAAd,cAAc,QAGzB;AAED,0DAA0D;AAC1D,MAAM,CAAN,IAAY,oBAIX;AAJD,WAAY,oBAAoB;IAC9B,qCAAa,CAAA;IACb,qCAAa,CAAA;IACb,8CAAsB,CAAA;AACxB,CAAC,EAJW,oBAAoB,KAApB,oBAAoB,QAI/B;AAED,mFAAmF;AACnF,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAA;AAE1C;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAN,IAAY,WAKX;AALD,WAAY,WAAW;IACrB,4BAAa,CAAA;IACb,gCAAiB,CAAA;IACjB,oCAAqB,CAAA;IACrB,kCAAmB,CAAA;AACrB,CAAC,EALW,WAAW,KAAX,WAAW,QAKtB;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAA2B;IACxD,WAAW,CAAC,IAAI;IAChB,WAAW,CAAC,MAAM;IAClB,WAAW,CAAC,QAAQ;IACpB,WAAW,CAAC,OAAO;CACX,CAAA;AAEV,+EAA+E;AAC/E,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAA;AAEtC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,SAAS,CAAA"}
1
+ {"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA;;;;GAIG;AACH,MAAM,CAAN,IAAY,aAqBX;AArBD,WAAY,aAAa;IACvB,yFAAyF;IACzF,kCAAiB,CAAA;IACjB,8BAA8B;IAC9B,wCAAuB,CAAA;IACvB,yFAAyF;IACzF,0CAAyB,CAAA;IACzB;;;;;;;;;;;;OAYG;IACH,wCAAuB,CAAA;AACzB,CAAC,EArBW,aAAa,KAAb,aAAa,QAqBxB;AAED;;;GAGG;AACH,MAAM,CAAN,IAAY,cAIX;AAJD,WAAY,cAAc;IACxB,qCAAmB,CAAA;IACnB,+BAAa,CAAA;IACb,mCAAiB,CAAA;AACnB,CAAC,EAJW,cAAc,KAAd,cAAc,QAIzB;AAED;;;;GAIG;AACH,MAAM,CAAN,IAAY,eAKX;AALD,WAAY,eAAe;IACzB,sCAAmB,CAAA;IACnB,wCAAqB,CAAA;IACrB,gCAAa,CAAA;IACb,8BAAW,CAAA;AACb,CAAC,EALW,eAAe,KAAf,eAAe,QAK1B;AAED;;;;;;;;;GASG;AACH,MAAM,CAAN,IAAY,cAGX;AAHD,WAAY,cAAc;IACxB,mCAAiB,CAAA;IACjB,+BAAa,CAAA;AACf,CAAC,EAHW,cAAc,KAAd,cAAc,QAGzB;AAED,0DAA0D;AAC1D,MAAM,CAAN,IAAY,oBAIX;AAJD,WAAY,oBAAoB;IAC9B,qCAAa,CAAA;IACb,qCAAa,CAAA;IACb,8CAAsB,CAAA;AACxB,CAAC,EAJW,oBAAoB,KAApB,oBAAoB,QAI/B;AAED,mFAAmF;AACnF,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAA;AAE1C;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAN,IAAY,WAKX;AALD,WAAY,WAAW;IACrB,4BAAa,CAAA;IACb,gCAAiB,CAAA;IACjB,oCAAqB,CAAA;IACrB,kCAAmB,CAAA;AACrB,CAAC,EALW,WAAW,KAAX,WAAW,QAKtB;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAA2B;IACxD,WAAW,CAAC,IAAI;IAChB,WAAW,CAAC,MAAM;IAClB,WAAW,CAAC,QAAQ;IACpB,WAAW,CAAC,OAAO;CACX,CAAA;AAEV,+EAA+E;AAC/E,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAA;AAEtC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,SAAS,CAAA"}
@@ -0,0 +1,2 @@
1
+ export * from './types.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/delegate/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA"}
@@ -0,0 +1,2 @@
1
+ export * from './types.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/delegate/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * The serializable form of one model call, for a performer outside this process.
3
+ *
4
+ * A delegated call cannot pass a `BaseChatModel` or a langchain message anywhere: the thing that
5
+ * answers it is a coding agent on somebody's laptop, a test double, or a person. So the call is
6
+ * reduced to what any of them can act on — a persona, a conversation, and the shape the answer
7
+ * must take — and everything provider-specific is left behind.
8
+ *
9
+ * There is no vocabulary here from whatever pipeline asked. A `role` and a `tier` travel because
10
+ * the performer has to choose a model; nothing else about the caller does.
11
+ */
12
+ /** What the answer must be. */
13
+ export declare enum DelegatedMode {
14
+ /** Prose or code. */
15
+ Text = "text",
16
+ /** Exactly one JSON object satisfying `outputSchema`. */
17
+ Json = "json",
18
+ /** A list of calls chosen from `tools`. */
19
+ Tools = "tools"
20
+ }
21
+ /** Who a message came from. Deliberately the four roles every chat API agrees on. */
22
+ export declare enum DelegatedRole {
23
+ System = "system",
24
+ User = "user",
25
+ Assistant = "assistant",
26
+ Tool = "tool"
27
+ }
28
+ /** What shape an answer came back in. */
29
+ export declare enum DelegatedResultKind {
30
+ Text = "text",
31
+ Json = "json",
32
+ ToolCalls = "tool-calls",
33
+ /** The performer could not answer. Treated as a malformed answer: asked again, with the reason. */
34
+ Error = "error"
35
+ }
36
+ export interface DelegatedToolCall {
37
+ id?: string;
38
+ name: string;
39
+ args: Record<string, unknown>;
40
+ }
41
+ export interface DelegatedMessage {
42
+ role: DelegatedRole;
43
+ content: string;
44
+ /** Assistant turns that called tools. */
45
+ toolCalls?: DelegatedToolCall[];
46
+ /** Tool turns answer one call, and name the tool they answer. */
47
+ toolCallId?: string;
48
+ name?: string;
49
+ }
50
+ export interface DelegatedTool {
51
+ name: string;
52
+ description?: string;
53
+ /** JSON Schema of the arguments. */
54
+ parameters: Record<string, unknown>;
55
+ }
56
+ export type DelegatedToolChoice = 'auto' | 'none' | {
57
+ name: string;
58
+ };
59
+ export interface DelegatedTask {
60
+ id: string;
61
+ /** Which transport is expected to answer it — the key the application seated it under. */
62
+ delegate: string;
63
+ /** The performer's role name, for its own logging. Never load-bearing. */
64
+ role?: string;
65
+ /** Which power class the performer should run this on. */
66
+ tier?: string;
67
+ /** 0-based. Above zero means a previous answer was refused; `feedback` says why. */
68
+ attempt: number;
69
+ mode: DelegatedMode;
70
+ system?: string;
71
+ messages: DelegatedMessage[];
72
+ tools?: DelegatedTool[];
73
+ toolChoice?: DelegatedToolChoice;
74
+ outputSchema?: Record<string, unknown>;
75
+ /** A soft cap, stated so a performer can size its own call. */
76
+ maxOutputChars?: number;
77
+ feedback?: string;
78
+ /** ISO. A performer past this may say so rather than answer. */
79
+ expiresAt?: string;
80
+ }
81
+ export interface DelegatedUsage {
82
+ inputTokens?: number;
83
+ outputTokens?: number;
84
+ }
85
+ export interface DelegatedResult {
86
+ taskId: string;
87
+ kind: DelegatedResultKind;
88
+ text?: string;
89
+ json?: unknown;
90
+ toolCalls?: DelegatedToolCall[];
91
+ error?: string;
92
+ /** What the performer spent. Recorded; it costs this deployment nothing. */
93
+ usage?: DelegatedUsage;
94
+ /** What the performer actually ran. Display only. */
95
+ model?: string;
96
+ }
97
+ /**
98
+ * How a delegated call reaches its performer.
99
+ *
100
+ * One method, because that is the whole seam: everything about routing, waiting, redelivery and
101
+ * giving up belongs to whoever implements it. A transport that cannot serve the call must THROW
102
+ * rather than answer with an error result — an error result is a bad answer, which is retried,
103
+ * while a transport that is gone is terminal.
104
+ */
105
+ export interface DelegateTransport {
106
+ dispatch: (task: DelegatedTask, signal?: AbortSignal) => Promise<DelegatedResult>;
107
+ }
108
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/delegate/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,+BAA+B;AAC/B,oBAAY,aAAa;IACvB,qBAAqB;IACrB,IAAI,SAAS;IACb,yDAAyD;IACzD,IAAI,SAAS;IACb,2CAA2C;IAC3C,KAAK,UAAU;CAChB;AAED,qFAAqF;AACrF,oBAAY,aAAa;IACvB,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,SAAS,cAAc;IACvB,IAAI,SAAS;CACd;AAED,yCAAyC;AACzC,oBAAY,mBAAmB;IAC7B,IAAI,SAAS;IACb,IAAI,SAAS;IACb,SAAS,eAAe;IACxB,mGAAmG;IACnG,KAAK,UAAU;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC9B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,aAAa,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,yCAAyC;IACzC,SAAS,CAAC,EAAE,iBAAiB,EAAE,CAAA;IAC/B,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACpC;AAED,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAEpE,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,0FAA0F;IAC1F,QAAQ,EAAE,MAAM,CAAA;IAChB,0EAA0E;IAC1E,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,oFAAoF;IACpF,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,aAAa,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,gBAAgB,EAAE,CAAA;IAC5B,KAAK,CAAC,EAAE,aAAa,EAAE,CAAA;IACvB,UAAU,CAAC,EAAE,mBAAmB,CAAA;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACtC,+DAA+D;IAC/D,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,mBAAmB,CAAA;IACzB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,SAAS,CAAC,EAAE,iBAAiB,EAAE,CAAA;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,4EAA4E;IAC5E,KAAK,CAAC,EAAE,cAAc,CAAA;IACtB,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,eAAe,CAAC,CAAA;CAClF"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * The serializable form of one model call, for a performer outside this process.
3
+ *
4
+ * A delegated call cannot pass a `BaseChatModel` or a langchain message anywhere: the thing that
5
+ * answers it is a coding agent on somebody's laptop, a test double, or a person. So the call is
6
+ * reduced to what any of them can act on — a persona, a conversation, and the shape the answer
7
+ * must take — and everything provider-specific is left behind.
8
+ *
9
+ * There is no vocabulary here from whatever pipeline asked. A `role` and a `tier` travel because
10
+ * the performer has to choose a model; nothing else about the caller does.
11
+ */
12
+ /** What the answer must be. */
13
+ export var DelegatedMode;
14
+ (function (DelegatedMode) {
15
+ /** Prose or code. */
16
+ DelegatedMode["Text"] = "text";
17
+ /** Exactly one JSON object satisfying `outputSchema`. */
18
+ DelegatedMode["Json"] = "json";
19
+ /** A list of calls chosen from `tools`. */
20
+ DelegatedMode["Tools"] = "tools";
21
+ })(DelegatedMode || (DelegatedMode = {}));
22
+ /** Who a message came from. Deliberately the four roles every chat API agrees on. */
23
+ export var DelegatedRole;
24
+ (function (DelegatedRole) {
25
+ DelegatedRole["System"] = "system";
26
+ DelegatedRole["User"] = "user";
27
+ DelegatedRole["Assistant"] = "assistant";
28
+ DelegatedRole["Tool"] = "tool";
29
+ })(DelegatedRole || (DelegatedRole = {}));
30
+ /** What shape an answer came back in. */
31
+ export var DelegatedResultKind;
32
+ (function (DelegatedResultKind) {
33
+ DelegatedResultKind["Text"] = "text";
34
+ DelegatedResultKind["Json"] = "json";
35
+ DelegatedResultKind["ToolCalls"] = "tool-calls";
36
+ /** The performer could not answer. Treated as a malformed answer: asked again, with the reason. */
37
+ DelegatedResultKind["Error"] = "error";
38
+ })(DelegatedResultKind || (DelegatedResultKind = {}));
39
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/delegate/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,+BAA+B;AAC/B,MAAM,CAAN,IAAY,aAOX;AAPD,WAAY,aAAa;IACvB,qBAAqB;IACrB,8BAAa,CAAA;IACb,yDAAyD;IACzD,8BAAa,CAAA;IACb,2CAA2C;IAC3C,gCAAe,CAAA;AACjB,CAAC,EAPW,aAAa,KAAb,aAAa,QAOxB;AAED,qFAAqF;AACrF,MAAM,CAAN,IAAY,aAKX;AALD,WAAY,aAAa;IACvB,kCAAiB,CAAA;IACjB,8BAAa,CAAA;IACb,wCAAuB,CAAA;IACvB,8BAAa,CAAA;AACf,CAAC,EALW,aAAa,KAAb,aAAa,QAKxB;AAED,yCAAyC;AACzC,MAAM,CAAN,IAAY,mBAMX;AAND,WAAY,mBAAmB;IAC7B,oCAAa,CAAA;IACb,oCAAa,CAAA;IACb,+CAAwB,CAAA;IACxB,mGAAmG;IACnG,sCAAe,CAAA;AACjB,CAAC,EANW,mBAAmB,KAAnB,mBAAmB,QAM9B"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/files/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAElE,qEAAqE;AACrE,eAAO,MAAM,mBAAmB,GAC9B,KAAK,eAAe,GAAG,SAAS,KAC/B,eAAe,GAAG,SAAoD,CAAA"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/files/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAElE,qEAAqE;AACrE,eAAO,MAAM,mBAAmB,QACzB,eAAe,GAAG,SAAS,KAC/B,eAAe,GAAG,SAAoD,CAAA"}
package/build/index.d.ts CHANGED
@@ -3,4 +3,6 @@ export type * from './types.js';
3
3
  export type * from './spectator/types.js';
4
4
  export type * from './files/types.js';
5
5
  export * from './files/utils.js';
6
+ export * from './delegate/index.js';
7
+ export * from './inquiry/index.js';
6
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,aAAa,CAAA;AAC3B,mBAAmB,YAAY,CAAA;AAC/B,mBAAmB,sBAAsB,CAAA;AACzC,mBAAmB,kBAAkB,CAAA;AACrC,cAAc,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,aAAa,CAAA;AAC3B,mBAAmB,YAAY,CAAA;AAC/B,mBAAmB,sBAAsB,CAAA;AACzC,mBAAmB,kBAAkB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,qBAAqB,CAAA;AACnC,cAAc,oBAAoB,CAAA"}
package/build/index.js CHANGED
@@ -1,3 +1,5 @@
1
1
  export * from './consts.js';
2
2
  export * from './files/utils.js';
3
+ export * from './delegate/index.js';
4
+ export * from './inquiry/index.js';
3
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,aAAa,CAAA;AAI3B,cAAc,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,aAAa,CAAA;AAI3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,qBAAqB,CAAA;AACnC,cAAc,oBAAoB,CAAA"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * What shape of answer a question expects. Deliberately three, because a question a person is
3
+ * asked mid-run is answered in seconds or not at all: pick one of these, say it in your own
4
+ * words, or say yes/no. Anything richer is a form, and a form belongs to an application screen.
5
+ */
6
+ export declare enum InquiryKind {
7
+ Choice = "choice",
8
+ Text = "text",
9
+ Confirm = "confirm"
10
+ }
11
+ /**
12
+ * What a run is allowed to do when it needs a decision that is not its own.
13
+ *
14
+ * - `Ask` — put it to a person through the seated transport and wait.
15
+ * - `Default` — assume the question's own default (or record a decline) and carry on. The caller
16
+ * is expected to RECORD the assumption; a run nobody is watching must never block.
17
+ * - `Refuse` — nobody may be asked at all; the attempt is an error.
18
+ */
19
+ export declare enum InquiryPolicy {
20
+ Ask = "ask",
21
+ Default = "default",
22
+ Refuse = "refuse"
23
+ }
24
+ /**
25
+ * The ONE ceiling on a stored answer, in characters. An answer is a decision, not a document.
26
+ *
27
+ * Every layer that carries an answer references this constant rather than choosing its own:
28
+ * `viable-common`'s `CONNECT_INQUIRY_MAX_TEXT` (the wire copy) equals it, `capAnswer` enforces it,
29
+ * and the connector's answer schema caps `text` at it. Three ceilings for one value is how a
30
+ * user's answer gets accepted on the wire and silently halved further in.
31
+ */
32
+ export declare const DEFAULT_INQUIRY_ANSWER_CHARS = 2000;
33
+ /** How many options one question may offer. Beyond this it is not a question. */
34
+ export declare const DEFAULT_INQUIRY_OPTIONS = 12;
35
+ /**
36
+ * How much of an answer's free text a resumable pipeline STATE may hold.
37
+ *
38
+ * A pipeline state is keys, markers and paths — a couple of full-size answers would make it prose,
39
+ * which is the invariant the whole pipeline design rests on. The decision (`value`/`declined`)
40
+ * stays whole; the prose is cut here and belongs in whatever document the application keeps for
41
+ * it (`stateAnswerOf`).
42
+ */
43
+ export declare const INQUIRY_STATE_TEXT_CHARS = 200;
44
+ /** The answer value of a confirmed {@link InquiryKind.Confirm}. */
45
+ export declare const CONFIRM_YES = "yes";
46
+ /** The answer value of a refused {@link InquiryKind.Confirm}. */
47
+ export declare const CONFIRM_NO = "no";
48
+ //# sourceMappingURL=consts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../../src/inquiry/consts.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,oBAAY,WAAW;IACrB,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,OAAO,YAAY;CACpB;AAED;;;;;;;GAOG;AACH,oBAAY,aAAa;IACvB,GAAG,QAAQ;IACX,OAAO,YAAY;IACnB,MAAM,WAAW;CAClB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,4BAA4B,OAAQ,CAAA;AAEjD,iFAAiF;AACjF,eAAO,MAAM,uBAAuB,KAAK,CAAA;AAEzC;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,MAAM,CAAA;AAE3C,mEAAmE;AACnE,eAAO,MAAM,WAAW,QAAQ,CAAA;AAChC,iEAAiE;AACjE,eAAO,MAAM,UAAU,OAAO,CAAA"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * What shape of answer a question expects. Deliberately three, because a question a person is
3
+ * asked mid-run is answered in seconds or not at all: pick one of these, say it in your own
4
+ * words, or say yes/no. Anything richer is a form, and a form belongs to an application screen.
5
+ */
6
+ export var InquiryKind;
7
+ (function (InquiryKind) {
8
+ InquiryKind["Choice"] = "choice";
9
+ InquiryKind["Text"] = "text";
10
+ InquiryKind["Confirm"] = "confirm";
11
+ })(InquiryKind || (InquiryKind = {}));
12
+ /**
13
+ * What a run is allowed to do when it needs a decision that is not its own.
14
+ *
15
+ * - `Ask` — put it to a person through the seated transport and wait.
16
+ * - `Default` — assume the question's own default (or record a decline) and carry on. The caller
17
+ * is expected to RECORD the assumption; a run nobody is watching must never block.
18
+ * - `Refuse` — nobody may be asked at all; the attempt is an error.
19
+ */
20
+ export var InquiryPolicy;
21
+ (function (InquiryPolicy) {
22
+ InquiryPolicy["Ask"] = "ask";
23
+ InquiryPolicy["Default"] = "default";
24
+ InquiryPolicy["Refuse"] = "refuse";
25
+ })(InquiryPolicy || (InquiryPolicy = {}));
26
+ /**
27
+ * The ONE ceiling on a stored answer, in characters. An answer is a decision, not a document.
28
+ *
29
+ * Every layer that carries an answer references this constant rather than choosing its own:
30
+ * `viable-common`'s `CONNECT_INQUIRY_MAX_TEXT` (the wire copy) equals it, `capAnswer` enforces it,
31
+ * and the connector's answer schema caps `text` at it. Three ceilings for one value is how a
32
+ * user's answer gets accepted on the wire and silently halved further in.
33
+ */
34
+ export const DEFAULT_INQUIRY_ANSWER_CHARS = 2_000;
35
+ /** How many options one question may offer. Beyond this it is not a question. */
36
+ export const DEFAULT_INQUIRY_OPTIONS = 12;
37
+ /**
38
+ * How much of an answer's free text a resumable pipeline STATE may hold.
39
+ *
40
+ * A pipeline state is keys, markers and paths — a couple of full-size answers would make it prose,
41
+ * which is the invariant the whole pipeline design rests on. The decision (`value`/`declined`)
42
+ * stays whole; the prose is cut here and belongs in whatever document the application keeps for
43
+ * it (`stateAnswerOf`).
44
+ */
45
+ export const INQUIRY_STATE_TEXT_CHARS = 200;
46
+ /** The answer value of a confirmed {@link InquiryKind.Confirm}. */
47
+ export const CONFIRM_YES = 'yes';
48
+ /** The answer value of a refused {@link InquiryKind.Confirm}. */
49
+ export const CONFIRM_NO = 'no';
50
+ //# sourceMappingURL=consts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.js","sourceRoot":"","sources":["../../src/inquiry/consts.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAN,IAAY,WAIX;AAJD,WAAY,WAAW;IACrB,gCAAiB,CAAA;IACjB,4BAAa,CAAA;IACb,kCAAmB,CAAA;AACrB,CAAC,EAJW,WAAW,KAAX,WAAW,QAItB;AAED;;;;;;;GAOG;AACH,MAAM,CAAN,IAAY,aAIX;AAJD,WAAY,aAAa;IACvB,4BAAW,CAAA;IACX,oCAAmB,CAAA;IACnB,kCAAiB,CAAA;AACnB,CAAC,EAJW,aAAa,KAAb,aAAa,QAIxB;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,KAAK,CAAA;AAEjD,iFAAiF;AACjF,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,CAAA;AAEzC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,CAAA;AAE3C,mEAAmE;AACnE,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,CAAA;AAChC,iEAAiE;AACjE,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAA"}
@@ -0,0 +1,4 @@
1
+ export * from './consts.js';
2
+ export type * from './types.js';
3
+ export * from './utils.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/inquiry/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,mBAAmB,YAAY,CAAA;AAC/B,cAAc,YAAY,CAAA"}
@@ -0,0 +1,3 @@
1
+ export * from './consts.js';
2
+ export * from './utils.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/inquiry/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAE3B,cAAc,YAAY,CAAA"}
@@ -0,0 +1,72 @@
1
+ import type { InquiryKind, InquiryPolicy } from './consts.js';
2
+ /**
3
+ * One question put to a person while a run is in flight, and the answer that comes back.
4
+ *
5
+ * Everything here is serializable for the same reason a delegated task is: whoever answers is
6
+ * outside this process — a browser dialog, a coding agent driving the application through a
7
+ * connector, a test double — and the question may outlive the process that asked it, parked on a
8
+ * pipeline run row until somebody comes back to it.
9
+ */
10
+ export interface InquiryOption {
11
+ value: string;
12
+ label: string;
13
+ description?: string;
14
+ }
15
+ export interface Inquiry {
16
+ /** Stable id, chosen by whoever asks. The ONLY thing that routes an answer back. */
17
+ id: string;
18
+ kind: InquiryKind;
19
+ /** One question, in plain words. */
20
+ question: string;
21
+ /** One or two sentences of background. Never the whole task. */
22
+ context?: string;
23
+ /** Required for {@link InquiryKind.Choice}; ignored otherwise. */
24
+ options?: InquiryOption[];
25
+ multiple?: boolean;
26
+ /** A `Choice` the answerer may answer in their own words instead. */
27
+ allowText?: boolean;
28
+ /** What to assume when nobody answers. {@link InquiryPolicy.Default} returns exactly this. */
29
+ default?: string | string[];
30
+ expiresAt?: string;
31
+ }
32
+ export interface InquiryAnswer {
33
+ inquiryId: string;
34
+ value?: string | string[];
35
+ text?: string;
36
+ /** Nobody could decide. A legitimate ANSWER, never a failure. */
37
+ declined?: boolean;
38
+ /**
39
+ * This answer is not exactly the one that was given. Never an answerer's own flag.
40
+ *
41
+ * Two writers, two ceilings: `capAnswer` cuts the text to `DEFAULT_INQUIRY_ANSWER_CHARS` (and
42
+ * raises this WITHOUT cutting when a `value` arrived over that ceiling, since a shortened
43
+ * identifier matches no option), while `stateAnswerOf` cuts the text again to the much smaller
44
+ * `INQUIRY_STATE_TEXT_CHARS` a pipeline state may hold. So a flag read back off a resumed run
45
+ * says the state's copy is short — not that the person hit the answer ceiling.
46
+ *
47
+ * It exists so no cut is silent: whoever records the answer can say that the rest of it was
48
+ * dropped, instead of the answerer discovering it in the work that followed.
49
+ */
50
+ truncated?: boolean;
51
+ }
52
+ /**
53
+ * How a question reaches a person.
54
+ *
55
+ * One method, like `DelegateTransport` beside it, and for the same reason: routing, waiting,
56
+ * redelivery and giving up all belong to whoever implements it. A transport that cannot serve the
57
+ * question must THROW rather than answer — a declined answer is a decision, while a channel that
58
+ * is not there is terminal, and the two must never look alike.
59
+ */
60
+ export interface InquiryTransport {
61
+ ask: (inquiry: Inquiry, signal?: AbortSignal) => Promise<InquiryAnswer>;
62
+ }
63
+ /**
64
+ * How one run may put a question to a person. Carried on an execution's serializable state, so a
65
+ * resumed run keeps the channel and the policy it was started with.
66
+ */
67
+ export interface InquiryConfig {
68
+ /** The key the application seated an {@link InquiryTransport} under. */
69
+ transport?: string;
70
+ policy: InquiryPolicy;
71
+ }
72
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/inquiry/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE7D;;;;;;;GAOG;AAEH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,OAAO;IACtB,oFAAoF;IACpF,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,WAAW,CAAA;IACjB,oCAAoC;IACpC,QAAQ,EAAE,MAAM,CAAA;IAChB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,kEAAkE;IAClE,OAAO,CAAC,EAAE,aAAa,EAAE,CAAA;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,qEAAqE;IACrE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,8FAA8F;IAC9F,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACzB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,iEAAiE;IACjE,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,aAAa,CAAC,CAAA;CACxE;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,aAAa,CAAA;CACtB"}