@ggui-ai/negotiator 0.1.0-rc.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.
- package/LICENSE +201 -0
- package/README.md +49 -0
- package/dist/contract-hash.d.ts +54 -0
- package/dist/contract-hash.d.ts.map +1 -0
- package/dist/contract-hash.js +96 -0
- package/dist/contract-validators.d.ts +171 -0
- package/dist/contract-validators.d.ts.map +1 -0
- package/dist/contract-validators.js +478 -0
- package/dist/decision-input.d.ts +48 -0
- package/dist/decision-input.d.ts.map +1 -0
- package/dist/decision-input.js +14 -0
- package/dist/decision.d.ts +54 -0
- package/dist/decision.d.ts.map +1 -0
- package/dist/decision.js +500 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/intent.d.ts +22 -0
- package/dist/intent.d.ts.map +1 -0
- package/dist/intent.js +28 -0
- package/dist/llm-caller.d.ts +70 -0
- package/dist/llm-caller.d.ts.map +1 -0
- package/dist/llm-caller.js +38 -0
- package/dist/llm-rerank.d.ts +101 -0
- package/dist/llm-rerank.d.ts.map +1 -0
- package/dist/llm-rerank.js +178 -0
- package/dist/negotiate.d.ts +141 -0
- package/dist/negotiate.d.ts.map +1 -0
- package/dist/negotiate.js +161 -0
- package/dist/normalize-schema.d.ts +22 -0
- package/dist/normalize-schema.d.ts.map +1 -0
- package/dist/normalize-schema.js +191 -0
- package/dist/pure.d.ts +30 -0
- package/dist/pure.d.ts.map +1 -0
- package/dist/pure.js +43 -0
- package/dist/rag-search.d.ts +73 -0
- package/dist/rag-search.d.ts.map +1 -0
- package/dist/rag-search.js +192 -0
- package/dist/rerank-eval/pairs.d.ts +28 -0
- package/dist/rerank-eval/pairs.d.ts.map +1 -0
- package/dist/rerank-eval/pairs.js +531 -0
- package/dist/rerank-eval/run-probe-cli.d.ts +3 -0
- package/dist/rerank-eval/run-probe-cli.d.ts.map +1 -0
- package/dist/rerank-eval/run-probe-cli.js +146 -0
- package/dist/rerank-eval/run-probe.d.ts +68 -0
- package/dist/rerank-eval/run-probe.d.ts.map +1 -0
- package/dist/rerank-eval/run-probe.js +113 -0
- package/dist/session.d.ts +42 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +21 -0
- package/dist/suggestion.d.ts +38 -0
- package/dist/suggestion.d.ts.map +1 -0
- package/dist/suggestion.js +47 -0
- package/dist/synth-bench/corpus.d.ts +106 -0
- package/dist/synth-bench/corpus.d.ts.map +1 -0
- package/dist/synth-bench/corpus.js +994 -0
- package/dist/synth-bench/run-bench-cli.d.ts +3 -0
- package/dist/synth-bench/run-bench-cli.d.ts.map +1 -0
- package/dist/synth-bench/run-bench-cli.js +181 -0
- package/dist/synth-bench/run-bench.d.ts +101 -0
- package/dist/synth-bench/run-bench.d.ts.map +1 -0
- package/dist/synth-bench/run-bench.js +374 -0
- package/dist/synthesize-contract.d.ts +131 -0
- package/dist/synthesize-contract.d.ts.map +1 -0
- package/dist/synthesize-contract.js +948 -0
- package/dist/types.d.ts +30 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +13 -0
- package/package.json +74 -0
- package/src/contract-hash.ts +102 -0
- package/src/contract-validators.ts +604 -0
- package/src/decision-input.ts +49 -0
- package/src/decision.ts +581 -0
- package/src/index.ts +63 -0
- package/src/intent.ts +37 -0
- package/src/llm-caller.ts +82 -0
- package/src/llm-rerank.ts +280 -0
- package/src/negotiate.ts +312 -0
- package/src/normalize-schema.ts +193 -0
- package/src/pure.ts +46 -0
- package/src/rag-search.ts +274 -0
- package/src/rerank-eval/pairs.ts +624 -0
- package/src/rerank-eval/run-probe-cli.ts +197 -0
- package/src/rerank-eval/run-probe.ts +198 -0
- package/src/session.ts +41 -0
- package/src/suggestion.ts +73 -0
- package/src/synth-bench/corpus.ts +1126 -0
- package/src/synth-bench/run-bench-cli.ts +237 -0
- package/src/synth-bench/run-bench.ts +525 -0
- package/src/synthesize-contract.ts +1161 -0
- package/src/types.ts +31 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contract synthesis.
|
|
3
|
+
*
|
|
4
|
+
* When an agent calls `ggui_handshake({story: {intent}})` without
|
|
5
|
+
* authoring a `contract`, the negotiator's cold path used to stamp an
|
|
6
|
+
* empty stub on `plan.contract`. The stub survived the handshake →
|
|
7
|
+
* push hop but failed downstream: the generator emitted
|
|
8
|
+
* `useAction(...)` / `useGguiContext(...)` calls that didn't match
|
|
9
|
+
* any declared `actionSpec` / `contextSpec`, and the validator
|
|
10
|
+
* stripped them, leaving dead buttons on the rendered UI.
|
|
11
|
+
*
|
|
12
|
+
* `synthesizeContract` closes that gap. Given an LLM caller and an
|
|
13
|
+
* intent string, it asks the model to infer a plausible
|
|
14
|
+
* `DataContract` from the natural-language ask: which actions a user
|
|
15
|
+
* might fire, which context slots the agent would observe, which
|
|
16
|
+
* stream channels would carry live updates. The resulting contract
|
|
17
|
+
* feeds the negotiator's `plan.contract`, rides through to the
|
|
18
|
+
* paired push, and arrives at the generator with a real wire surface
|
|
19
|
+
* that the validator accepts.
|
|
20
|
+
*
|
|
21
|
+
* **Conservative by design.** The synthesized contract emits only
|
|
22
|
+
* what the LLM is confident about — better to under-declare than to
|
|
23
|
+
* fabricate actions the UI doesn't actually need. Operators who want
|
|
24
|
+
* a richer surface should author the contract themselves on the
|
|
25
|
+
* handshake input; synthesis is a fallback, not a replacement.
|
|
26
|
+
*
|
|
27
|
+
* **Failure modes collapse to null.** LLM throws, parse fails,
|
|
28
|
+
* provider doesn't support `callStructured` → return `null`. Caller
|
|
29
|
+
* falls back to an empty stub; behavior regresses to pre-synth but
|
|
30
|
+
* doesn't crash.
|
|
31
|
+
*
|
|
32
|
+
* **Cost.** ~$0.0005-0.001 per call (Haiku 4.5, ~500 input + ~300
|
|
33
|
+
* output tokens). Latency ~1.5s. Fires only on cold-path Tier 3
|
|
34
|
+
* AND when the agent omitted the contract — most pushes from
|
|
35
|
+
* contract-aware agents skip synthesis entirely.
|
|
36
|
+
*/
|
|
37
|
+
import { type DataContract, type GadgetDescriptor } from '@ggui-ai/protocol';
|
|
38
|
+
import type { LLMCaller, ToolSchema } from './llm-caller.js';
|
|
39
|
+
import { type ContractValidationFinding } from './contract-validators.js';
|
|
40
|
+
/** Result of one synthesis attempt. */
|
|
41
|
+
export interface SynthesizeContractResult {
|
|
42
|
+
/** Synthesized contract, or `null` when synthesis declined / failed. */
|
|
43
|
+
readonly contract: DataContract | null;
|
|
44
|
+
/** Human-readable reason for the synthesis decision. */
|
|
45
|
+
readonly reason: string;
|
|
46
|
+
/** Wall-clock latency across every attempt. */
|
|
47
|
+
readonly latencyMs: number;
|
|
48
|
+
/**
|
|
49
|
+
* Number of LLM attempts the synthesizer made — `1` on the common
|
|
50
|
+
* already-valid path, up to {@link MAX_SYNTH_ATTEMPTS} when the
|
|
51
|
+
* validate-and-repair loop had to retry. `0` for the early-skip
|
|
52
|
+
* paths (empty intent, provider lacks structured output).
|
|
53
|
+
*/
|
|
54
|
+
readonly attempts: number;
|
|
55
|
+
/**
|
|
56
|
+
* Structural-validator findings produced when the synthesizer ran the
|
|
57
|
+
* `validateContractStructure` gate against its assembled contract.
|
|
58
|
+
* Empty when validator didn't run (early skip / decline). Surfaced
|
|
59
|
+
* so callers (cache-trace emit site, ops dashboards) can render
|
|
60
|
+
* findings without re-running the detector.
|
|
61
|
+
*/
|
|
62
|
+
readonly findings: readonly ContractValidationFinding[];
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Tool schema the synthesizer's structured-output call uses. The
|
|
66
|
+
* shape mirrors `DataContract` but stays loose at the ToolSchema
|
|
67
|
+
* layer — Anthropic's tool-use adapter doesn't enforce nested
|
|
68
|
+
* required-field rules deeply, and we re-validate on the return path.
|
|
69
|
+
*/
|
|
70
|
+
export declare const SYNTHESIZE_TOOL: ToolSchema;
|
|
71
|
+
/**
|
|
72
|
+
* Run the synthesizer for a contract-less cold-path handshake.
|
|
73
|
+
*
|
|
74
|
+
* Empty / whitespace intent short-circuits to null with a reason —
|
|
75
|
+
* no contract can be inferred from nothing.
|
|
76
|
+
*
|
|
77
|
+
* Provider lacking `callStructured` (test stubs, providers without
|
|
78
|
+
* tool-use) collapses to null.
|
|
79
|
+
*
|
|
80
|
+
* Each attempt is self-checked against the validation gate; a failure
|
|
81
|
+
* feeds the precise error back for up to {@link MAX_SYNTH_ATTEMPTS}
|
|
82
|
+
* attempts (a transient `callStructured` throw re-runs the same
|
|
83
|
+
* prompt). Only when the budget is exhausted does it collapse to null
|
|
84
|
+
* — the caller then falls back to an empty contract stub.
|
|
85
|
+
*/
|
|
86
|
+
export declare function synthesizeContract(deps: {
|
|
87
|
+
readonly llm: LLMCaller;
|
|
88
|
+
}, intent: string, options?: {
|
|
89
|
+
/**
|
|
90
|
+
* Per-app gadget catalog (`App.gadgets`) — when bound, synth
|
|
91
|
+
* emits an "AVAILABLE GADGETS" section on the user prompt (NOT
|
|
92
|
+
* the system prompt, so the system-prompt cache stays warm)
|
|
93
|
+
* listing each registered package's exports — hook AND component
|
|
94
|
+
* — with description + usage. The LLM uses this to decide which
|
|
95
|
+
* (if any) `clientCapabilities.gadgets[<package>][<export>]`
|
|
96
|
+
* entries to declare on the synthesized contract. Per-export
|
|
97
|
+
* budget ~300 chars; total budget ~3 KB.
|
|
98
|
+
*
|
|
99
|
+
* When omitted, synth still uses the static stdlib hint baked
|
|
100
|
+
* into SYNTHESIZE_SYSTEM_PROMPT (preserves behavior on the OSS
|
|
101
|
+
* no-app-registry path).
|
|
102
|
+
*/
|
|
103
|
+
readonly appGadgets?: readonly GadgetDescriptor[];
|
|
104
|
+
}): Promise<SynthesizeContractResult>;
|
|
105
|
+
/**
|
|
106
|
+
* Compose the "AVAILABLE GADGETS" section appended to synth's user
|
|
107
|
+
* prompt (and the decision-engine user message — both paths share
|
|
108
|
+
* this one composer). Flattens the package-keyed
|
|
109
|
+
* {@link GadgetDescriptor} catalog into one line per export:
|
|
110
|
+
*
|
|
111
|
+
* - hook `useGeolocation` (package `@ggui-ai/gadgets`) — <desc> (usage: <usage>)
|
|
112
|
+
* - component `Chart` (package `@acme/charts`) — <desc> (usage: <usage>)
|
|
113
|
+
*
|
|
114
|
+
* The leading `hook` / `component` tag teaches the LLM the two render
|
|
115
|
+
* idioms (a hook is CALLED, a component is RENDERED as JSX); the
|
|
116
|
+
* `(package …)` tag carries the npm package name the LLM needs to
|
|
117
|
+
* author the package-keyed
|
|
118
|
+
* `clientCapabilities.gadgets[<package>][<export>]` wire entry.
|
|
119
|
+
*
|
|
120
|
+
* Budget enforcement: per-export text capped at
|
|
121
|
+
* {@link SYNTH_PER_LIBRARY_BUDGET}, total section capped at
|
|
122
|
+
* {@link SYNTH_TOTAL_BUDGET}.
|
|
123
|
+
*
|
|
124
|
+
* Returns `undefined` when the catalog is empty / every export lacks
|
|
125
|
+
* teaching text — the caller then omits the section entirely
|
|
126
|
+
* (preserves the no-registry prompt verbatim for cache hit).
|
|
127
|
+
*
|
|
128
|
+
* Pure helper; exported for the prompt-builder unit test.
|
|
129
|
+
*/
|
|
130
|
+
export declare function composeAvailableGadgetsSection(gadgets: readonly GadgetDescriptor[] | undefined): string | undefined;
|
|
131
|
+
//# sourceMappingURL=synthesize-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"synthesize-contract.d.ts","sourceRoot":"","sources":["../src/synthesize-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACtB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7D,OAAO,EAKL,KAAK,yBAAyB,EAC/B,MAAM,0BAA0B,CAAC;AAsBlC,uCAAuC;AACvC,MAAM,WAAW,wBAAwB;IACvC,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IACvC,wDAAwD;IACxD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,+CAA+C;IAC/C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS,yBAAyB,EAAE,CAAC;CACzD;AA+ND;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,UA+I7B,CAAC;AAsGF;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAA;CAAE,EACjC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IACR;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,gBAAgB,EAAE,CAAC;CACnD,GACA,OAAO,CAAC,wBAAwB,CAAC,CAiKnC;AAgUD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,SAAS,gBAAgB,EAAE,GAAG,SAAS,GAC/C,MAAM,GAAG,SAAS,CA+CpB"}
|