@aid-framework/runtime 0.0.0 → 0.1.48
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 +183 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/agents/deep_agents.d.ts +78 -0
- package/dist/agents/deep_agents.d.ts.map +1 -0
- package/dist/agents/deep_agents.js +477 -0
- package/dist/agents/deep_agents.js.map +1 -0
- package/dist/agents/engine.d.ts +85 -0
- package/dist/agents/engine.d.ts.map +1 -0
- package/dist/agents/engine.js +129 -0
- package/dist/agents/engine.js.map +1 -0
- package/dist/agents/gateway_chat_model.d.ts +151 -0
- package/dist/agents/gateway_chat_model.d.ts.map +1 -0
- package/dist/agents/gateway_chat_model.js +350 -0
- package/dist/agents/gateway_chat_model.js.map +1 -0
- package/dist/agents/guardrail_middleware.d.ts +57 -0
- package/dist/agents/guardrail_middleware.d.ts.map +1 -0
- package/dist/agents/guardrail_middleware.js +85 -0
- package/dist/agents/guardrail_middleware.js.map +1 -0
- package/dist/agents/guardrails.d.ts +124 -0
- package/dist/agents/guardrails.d.ts.map +1 -0
- package/dist/agents/guardrails.js +336 -0
- package/dist/agents/guardrails.js.map +1 -0
- package/dist/agents/index.d.ts +15 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +15 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/ir.d.ts +144 -0
- package/dist/agents/ir.d.ts.map +1 -0
- package/dist/agents/ir.js +513 -0
- package/dist/agents/ir.js.map +1 -0
- package/dist/agents/loop.d.ts +145 -0
- package/dist/agents/loop.d.ts.map +1 -0
- package/dist/agents/loop.js +1025 -0
- package/dist/agents/loop.js.map +1 -0
- package/dist/agents/memory.d.ts +115 -0
- package/dist/agents/memory.d.ts.map +1 -0
- package/dist/agents/memory.js +258 -0
- package/dist/agents/memory.js.map +1 -0
- package/dist/agents/state.d.ts +137 -0
- package/dist/agents/state.d.ts.map +1 -0
- package/dist/agents/state.js +255 -0
- package/dist/agents/state.js.map +1 -0
- package/dist/concurrency.d.ts +36 -0
- package/dist/concurrency.d.ts.map +1 -0
- package/dist/concurrency.js +86 -0
- package/dist/concurrency.js.map +1 -0
- package/dist/control.d.ts +116 -0
- package/dist/control.d.ts.map +1 -0
- package/dist/control.js +281 -0
- package/dist/control.js.map +1 -0
- package/dist/cost.d.ts +95 -0
- package/dist/cost.d.ts.map +1 -0
- package/dist/cost.js +161 -0
- package/dist/cost.js.map +1 -0
- package/dist/errors.d.ts +213 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +316 -0
- package/dist/errors.js.map +1 -0
- package/dist/evals/dataset.d.ts +45 -0
- package/dist/evals/dataset.d.ts.map +1 -0
- package/dist/evals/dataset.js +147 -0
- package/dist/evals/dataset.js.map +1 -0
- package/dist/evals/gate.d.ts +236 -0
- package/dist/evals/gate.d.ts.map +1 -0
- package/dist/evals/gate.js +572 -0
- package/dist/evals/gate.js.map +1 -0
- package/dist/evals/metrics.d.ts +141 -0
- package/dist/evals/metrics.d.ts.map +1 -0
- package/dist/evals/metrics.js +364 -0
- package/dist/evals/metrics.js.map +1 -0
- package/dist/evals/predicate.d.ts +79 -0
- package/dist/evals/predicate.d.ts.map +1 -0
- package/dist/evals/predicate.js +178 -0
- package/dist/evals/predicate.js.map +1 -0
- package/dist/evals/runner.d.ts +94 -0
- package/dist/evals/runner.d.ts.map +1 -0
- package/dist/evals/runner.js +202 -0
- package/dist/evals/runner.js.map +1 -0
- package/dist/gateway.d.ts +118 -0
- package/dist/gateway.d.ts.map +1 -0
- package/dist/gateway.js +250 -0
- package/dist/gateway.js.map +1 -0
- package/dist/index.d.ts +83 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/json.d.ts +44 -0
- package/dist/internal/json.d.ts.map +1 -0
- package/dist/internal/json.js +90 -0
- package/dist/internal/json.js.map +1 -0
- package/dist/internal/text.d.ts +17 -0
- package/dist/internal/text.d.ts.map +1 -0
- package/dist/internal/text.js +22 -0
- package/dist/internal/text.js.map +1 -0
- package/dist/pipeline.d.ts +80 -0
- package/dist/pipeline.d.ts.map +1 -0
- package/dist/pipeline.js +159 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/policy.d.ts +52 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +199 -0
- package/dist/policy.js.map +1 -0
- package/dist/prompts.d.ts +86 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +337 -0
- package/dist/prompts.js.map +1 -0
- package/dist/providers/base.d.ts +19 -0
- package/dist/providers/base.d.ts.map +1 -0
- package/dist/providers/base.js +13 -0
- package/dist/providers/base.js.map +1 -0
- package/dist/providers/fake.d.ts +98 -0
- package/dist/providers/fake.d.ts.map +1 -0
- package/dist/providers/fake.js +181 -0
- package/dist/providers/fake.js.map +1 -0
- package/dist/providers/http.d.ts +62 -0
- package/dist/providers/http.d.ts.map +1 -0
- package/dist/providers/http.js +245 -0
- package/dist/providers/http.js.map +1 -0
- package/dist/retrieval/chunking.d.ts +88 -0
- package/dist/retrieval/chunking.d.ts.map +1 -0
- package/dist/retrieval/chunking.js +188 -0
- package/dist/retrieval/chunking.js.map +1 -0
- package/dist/retrieval/citations.d.ts +98 -0
- package/dist/retrieval/citations.d.ts.map +1 -0
- package/dist/retrieval/citations.js +134 -0
- package/dist/retrieval/citations.js.map +1 -0
- package/dist/retrieval/connectors.d.ts +74 -0
- package/dist/retrieval/connectors.d.ts.map +1 -0
- package/dist/retrieval/connectors.js +218 -0
- package/dist/retrieval/connectors.js.map +1 -0
- package/dist/retrieval/embedding.d.ts +116 -0
- package/dist/retrieval/embedding.d.ts.map +1 -0
- package/dist/retrieval/embedding.js +282 -0
- package/dist/retrieval/embedding.js.map +1 -0
- package/dist/retrieval/gate.d.ts +52 -0
- package/dist/retrieval/gate.d.ts.map +1 -0
- package/dist/retrieval/gate.js +91 -0
- package/dist/retrieval/gate.js.map +1 -0
- package/dist/retrieval/hybrid.d.ts +76 -0
- package/dist/retrieval/hybrid.d.ts.map +1 -0
- package/dist/retrieval/hybrid.js +150 -0
- package/dist/retrieval/hybrid.js.map +1 -0
- package/dist/retrieval/metrics.d.ts +126 -0
- package/dist/retrieval/metrics.d.ts.map +1 -0
- package/dist/retrieval/metrics.js +200 -0
- package/dist/retrieval/metrics.js.map +1 -0
- package/dist/retrieval/pgvector.d.ts +62 -0
- package/dist/retrieval/pgvector.d.ts.map +1 -0
- package/dist/retrieval/pgvector.js +262 -0
- package/dist/retrieval/pgvector.js.map +1 -0
- package/dist/retrieval/rerank.d.ts +61 -0
- package/dist/retrieval/rerank.d.ts.map +1 -0
- package/dist/retrieval/rerank.js +105 -0
- package/dist/retrieval/rerank.js.map +1 -0
- package/dist/retrieval/retriever.d.ts +125 -0
- package/dist/retrieval/retriever.d.ts.map +1 -0
- package/dist/retrieval/retriever.js +281 -0
- package/dist/retrieval/retriever.js.map +1 -0
- package/dist/retrieval/stores.d.ts +106 -0
- package/dist/retrieval/stores.d.ts.map +1 -0
- package/dist/retrieval/stores.js +142 -0
- package/dist/retrieval/stores.js.map +1 -0
- package/dist/retrieval/types.d.ts +314 -0
- package/dist/retrieval/types.d.ts.map +1 -0
- package/dist/retrieval/types.js +388 -0
- package/dist/retrieval/types.js.map +1 -0
- package/dist/steps.d.ts +156 -0
- package/dist/steps.d.ts.map +1 -0
- package/dist/steps.js +199 -0
- package/dist/steps.js.map +1 -0
- package/dist/structured.d.ts +91 -0
- package/dist/structured.d.ts.map +1 -0
- package/dist/structured.js +155 -0
- package/dist/structured.js.map +1 -0
- package/dist/tools.d.ts +100 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +201 -0
- package/dist/tools.js.map +1 -0
- package/dist/tracing.d.ts +104 -0
- package/dist/tracing.d.ts.map +1 -0
- package/dist/tracing.js +155 -0
- package/dist/tracing.js.map +1 -0
- package/dist/types.d.ts +240 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +357 -0
- package/dist/types.js.map +1 -0
- package/package.json +80 -14
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A plain-async pipeline engine.
|
|
3
|
+
*
|
|
4
|
+
* This is the answer to "the loop". It is a sequential reducer over an immutable
|
|
5
|
+
* context: each step receives the context and returns the context, optionally
|
|
6
|
+
* enriched. No graph, no scheduler, no orchestration dependency.
|
|
7
|
+
*
|
|
8
|
+
* That is a deliberate ceiling. When branching, retries and human-in-the-loop
|
|
9
|
+
* interrupts are real requirements an orchestration library is the right tool, but
|
|
10
|
+
* adopting one before those requirements exist would place an unobservable graph
|
|
11
|
+
* between the user and their own trace.
|
|
12
|
+
*/
|
|
13
|
+
/** Context key under which {@link Pipeline.run} records the steps that ran, in order. */
|
|
14
|
+
export declare const STEPS_KEY = "steps";
|
|
15
|
+
/** Thrown from a step to end the pipeline successfully and early. */
|
|
16
|
+
export declare class StopPipeline extends Error {
|
|
17
|
+
readonly reason: string;
|
|
18
|
+
constructor(reason?: string);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The value threaded through a pipeline.
|
|
22
|
+
*
|
|
23
|
+
* Immutable, so a step cannot mutate what an earlier step observed; it returns a new
|
|
24
|
+
* context instead. That keeps a failed run's state inspectable and makes replaying a
|
|
25
|
+
* pipeline reproducible.
|
|
26
|
+
*/
|
|
27
|
+
export declare class PipelineContext {
|
|
28
|
+
readonly values: Readonly<Record<string, unknown>>;
|
|
29
|
+
constructor(values?: Readonly<Record<string, unknown>>);
|
|
30
|
+
get(key: string, fallback?: unknown): unknown;
|
|
31
|
+
/** A value that must be present, or a {@link PipelineError} naming the key. */
|
|
32
|
+
require(key: string): unknown;
|
|
33
|
+
/** A new context with `values` merged over the current members. */
|
|
34
|
+
withValues(values: Readonly<Record<string, unknown>>): PipelineContext;
|
|
35
|
+
/** A new context without the named keys. */
|
|
36
|
+
without(...keys: readonly string[]): PipelineContext;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* What a step may produce: a new context, a record that *becomes* the new context, or
|
|
40
|
+
* nothing for an empty one.
|
|
41
|
+
*
|
|
42
|
+
* A returned record replaces the context rather than merging into it, matching the
|
|
43
|
+
* reference runtime: a step that wants to preserve earlier values re-spreads them.
|
|
44
|
+
*/
|
|
45
|
+
export type StepResult = PipelineContext | Record<string, unknown> | null | undefined;
|
|
46
|
+
/** A step: a callable from context to a step result. */
|
|
47
|
+
export type Step = (context: PipelineContext) => StepResult | Promise<StepResult>;
|
|
48
|
+
/** The shape of one pipeline entry. */
|
|
49
|
+
export type NamedStep = readonly [name: string, step: Step];
|
|
50
|
+
/** Runs named steps in order, tracing each one. */
|
|
51
|
+
export declare class Pipeline {
|
|
52
|
+
private readonly _steps;
|
|
53
|
+
private readonly _tracerName;
|
|
54
|
+
private readonly _recordSteps;
|
|
55
|
+
constructor(steps: readonly NamedStep[], options?: {
|
|
56
|
+
readonly tracerName?: string;
|
|
57
|
+
readonly recordSteps?: boolean;
|
|
58
|
+
});
|
|
59
|
+
get stepNames(): string[];
|
|
60
|
+
/** Build a pipeline from bare callables, naming each by its function. */
|
|
61
|
+
static of(...steps: readonly Step[]): Pipeline;
|
|
62
|
+
/**
|
|
63
|
+
* A new pipeline with `step` appended. This instance is unchanged.
|
|
64
|
+
*
|
|
65
|
+
* Named `add` rather than Python's `then` because a `then` member makes the
|
|
66
|
+
* object thenable: `await` on a Pipeline would invoke it with `(resolve,
|
|
67
|
+
* reject)` and construct a nonsense step instead of leaving it alone.
|
|
68
|
+
*/
|
|
69
|
+
add(name: string, step: Step): Pipeline;
|
|
70
|
+
/**
|
|
71
|
+
* Execute every step, stopping early if one throws {@link StopPipeline}.
|
|
72
|
+
*
|
|
73
|
+
* A step that throws anything else aborts the run, and the original error's
|
|
74
|
+
* message is carried into the {@link PipelineError} so the failure names both the
|
|
75
|
+
* pipeline coordinate and the real cause.
|
|
76
|
+
*/
|
|
77
|
+
run(initial?: PipelineContext | Record<string, unknown> | null): Promise<PipelineContext>;
|
|
78
|
+
private finish;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,yFAAyF;AACzF,eAAO,MAAM,SAAS,UAAU,CAAC;AAEjC,qEAAqE;AACrE,qBAAa,YAAa,SAAQ,KAAK;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,YAAY,MAAM,SAAK,EAItB;CACF;AAED;;;;;;GAMG;AACH,qBAAa,eAAe;IAC1B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAEnD,YAAY,MAAM,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAM,EAEzD;IAED,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,CAE5C;IAED,+EAA+E;IAC/E,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAK5B;IAED,mEAAmE;IACnE,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,eAAe,CAErE;IAED,4CAA4C;IAC5C,OAAO,CAAC,GAAG,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,eAAe,CAInD;CACF;AAED;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;AAEtF,wDAAwD;AACxD,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,eAAe,KAAK,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAElF,uCAAuC;AACvC,MAAM,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAyB5D,mDAAmD;AACnD,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAC9C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;IAEvC,YACE,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,OAAO,GAAE;QAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAA;KAAO,EAW/E;IAED,IAAI,SAAS,IAAI,MAAM,EAAE,CAExB;IAED,yEAAyE;IACzE,MAAM,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,QAAQ,CAE7C;IAED;;;;;;OAMG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,QAAQ,CAKtC;IAED;;;;;;OAMG;IACG,GAAG,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAqC9F;IAED,OAAO,CAAC,MAAM;CAGf"}
|
package/dist/pipeline.js
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A plain-async pipeline engine.
|
|
3
|
+
*
|
|
4
|
+
* This is the answer to "the loop". It is a sequential reducer over an immutable
|
|
5
|
+
* context: each step receives the context and returns the context, optionally
|
|
6
|
+
* enriched. No graph, no scheduler, no orchestration dependency.
|
|
7
|
+
*
|
|
8
|
+
* That is a deliberate ceiling. When branching, retries and human-in-the-loop
|
|
9
|
+
* interrupts are real requirements an orchestration library is the right tool, but
|
|
10
|
+
* adopting one before those requirements exist would place an unobservable graph
|
|
11
|
+
* between the user and their own trace.
|
|
12
|
+
*/
|
|
13
|
+
import { PipelineError } from './errors.js';
|
|
14
|
+
import { repr } from './internal/json.js';
|
|
15
|
+
import { getTracer, recordException } from './tracing.js';
|
|
16
|
+
/** Context key under which {@link Pipeline.run} records the steps that ran, in order. */
|
|
17
|
+
export const STEPS_KEY = 'steps';
|
|
18
|
+
/** Thrown from a step to end the pipeline successfully and early. */
|
|
19
|
+
export class StopPipeline extends Error {
|
|
20
|
+
reason;
|
|
21
|
+
constructor(reason = '') {
|
|
22
|
+
super(reason || 'pipeline stopped');
|
|
23
|
+
this.name = 'StopPipeline';
|
|
24
|
+
this.reason = reason;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The value threaded through a pipeline.
|
|
29
|
+
*
|
|
30
|
+
* Immutable, so a step cannot mutate what an earlier step observed; it returns a new
|
|
31
|
+
* context instead. That keeps a failed run's state inspectable and makes replaying a
|
|
32
|
+
* pipeline reproducible.
|
|
33
|
+
*/
|
|
34
|
+
export class PipelineContext {
|
|
35
|
+
values;
|
|
36
|
+
constructor(values = {}) {
|
|
37
|
+
this.values = values;
|
|
38
|
+
}
|
|
39
|
+
get(key, fallback) {
|
|
40
|
+
return Object.hasOwn(this.values, key) ? this.values[key] : fallback;
|
|
41
|
+
}
|
|
42
|
+
/** A value that must be present, or a {@link PipelineError} naming the key. */
|
|
43
|
+
require(key) {
|
|
44
|
+
if (!Object.hasOwn(this.values, key)) {
|
|
45
|
+
throw new PipelineError(`pipeline context has no ${repr(key)}`);
|
|
46
|
+
}
|
|
47
|
+
return this.values[key];
|
|
48
|
+
}
|
|
49
|
+
/** A new context with `values` merged over the current members. */
|
|
50
|
+
withValues(values) {
|
|
51
|
+
return new PipelineContext({ ...this.values, ...values });
|
|
52
|
+
}
|
|
53
|
+
/** A new context without the named keys. */
|
|
54
|
+
without(...keys) {
|
|
55
|
+
const remaining = { ...this.values };
|
|
56
|
+
for (const key of keys)
|
|
57
|
+
delete remaining[key];
|
|
58
|
+
return new PipelineContext(remaining);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function messageOf(error) {
|
|
62
|
+
return error instanceof Error ? error.message : String(error);
|
|
63
|
+
}
|
|
64
|
+
function asContext(value) {
|
|
65
|
+
if (value instanceof PipelineContext)
|
|
66
|
+
return value;
|
|
67
|
+
if (value === null || value === undefined)
|
|
68
|
+
return new PipelineContext();
|
|
69
|
+
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
70
|
+
return new PipelineContext({ ...value });
|
|
71
|
+
}
|
|
72
|
+
// `null` cannot reach this line -- it returned above -- so the old `NoneType` arm
|
|
73
|
+
// was unreachable and the message never named the one case it was written for.
|
|
74
|
+
// What does reach it is a list, a primitive or a function, and those are what the
|
|
75
|
+
// message now names.
|
|
76
|
+
throw new PipelineError(`a pipeline step must return a PipelineContext, a mapping or None, got ${describeValue(value)}`);
|
|
77
|
+
}
|
|
78
|
+
function describeValue(value) {
|
|
79
|
+
return Array.isArray(value) ? 'list' : typeof value;
|
|
80
|
+
}
|
|
81
|
+
/** Runs named steps in order, tracing each one. */
|
|
82
|
+
export class Pipeline {
|
|
83
|
+
_steps;
|
|
84
|
+
_tracerName;
|
|
85
|
+
_recordSteps;
|
|
86
|
+
constructor(steps, options = {}) {
|
|
87
|
+
if (steps.length === 0)
|
|
88
|
+
throw new PipelineError('a pipeline needs at least one step');
|
|
89
|
+
const seen = new Set();
|
|
90
|
+
for (const [name] of steps) {
|
|
91
|
+
if (seen.has(name))
|
|
92
|
+
throw new PipelineError(`duplicate step name ${repr(name)}`);
|
|
93
|
+
seen.add(name);
|
|
94
|
+
}
|
|
95
|
+
this._steps = steps;
|
|
96
|
+
this._tracerName = options.tracerName ?? 'aid_runtime';
|
|
97
|
+
this._recordSteps = options.recordSteps ?? true;
|
|
98
|
+
}
|
|
99
|
+
get stepNames() {
|
|
100
|
+
return this._steps.map(([name]) => name);
|
|
101
|
+
}
|
|
102
|
+
/** Build a pipeline from bare callables, naming each by its function. */
|
|
103
|
+
static of(...steps) {
|
|
104
|
+
return new Pipeline(steps.map((step) => [step.name || 'anonymous', step]));
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* A new pipeline with `step` appended. This instance is unchanged.
|
|
108
|
+
*
|
|
109
|
+
* Named `add` rather than Python's `then` because a `then` member makes the
|
|
110
|
+
* object thenable: `await` on a Pipeline would invoke it with `(resolve,
|
|
111
|
+
* reject)` and construct a nonsense step instead of leaving it alone.
|
|
112
|
+
*/
|
|
113
|
+
add(name, step) {
|
|
114
|
+
return new Pipeline([...this._steps, [name, step]], {
|
|
115
|
+
tracerName: this._tracerName,
|
|
116
|
+
recordSteps: this._recordSteps,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Execute every step, stopping early if one throws {@link StopPipeline}.
|
|
121
|
+
*
|
|
122
|
+
* A step that throws anything else aborts the run, and the original error's
|
|
123
|
+
* message is carried into the {@link PipelineError} so the failure names both the
|
|
124
|
+
* pipeline coordinate and the real cause.
|
|
125
|
+
*/
|
|
126
|
+
async run(initial) {
|
|
127
|
+
let context = asContext(initial);
|
|
128
|
+
const ran = [];
|
|
129
|
+
const tracer = getTracer(this._tracerName);
|
|
130
|
+
for (const [name, step] of this._steps) {
|
|
131
|
+
const outcome = await tracer.startActiveSpan(`pipeline.${name}`, { attributes: { 'aid.pipeline.step': name } }, async (span) => {
|
|
132
|
+
try {
|
|
133
|
+
return { stopped: false, context: asContext(await step(context)) };
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
if (error instanceof StopPipeline) {
|
|
137
|
+
if (error.reason.length > 0) {
|
|
138
|
+
span.setAttribute('aid.pipeline.stop_reason', error.reason);
|
|
139
|
+
}
|
|
140
|
+
return { stopped: true };
|
|
141
|
+
}
|
|
142
|
+
recordException(span, error);
|
|
143
|
+
throw new PipelineError(`step ${repr(name)} failed: ${messageOf(error)}`, {
|
|
144
|
+
cause: error,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
ran.push(name);
|
|
149
|
+
if (outcome.stopped)
|
|
150
|
+
return this.finish(context, ran);
|
|
151
|
+
context = outcome.context;
|
|
152
|
+
}
|
|
153
|
+
return this.finish(context, ran);
|
|
154
|
+
}
|
|
155
|
+
finish(context, ran) {
|
|
156
|
+
return this._recordSteps ? context.withValues({ [STEPS_KEY]: [...ran] }) : context;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"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"}
|
package/dist/policy.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evaluation of the IR's `PolicyExpr` AST.
|
|
3
|
+
*
|
|
4
|
+
* The grammar is the one `packages/ir/src/policy` parses, and the AST is plain JSON
|
|
5
|
+
* precisely so a target does not need a second parser:
|
|
6
|
+
*
|
|
7
|
+
* expression := or
|
|
8
|
+
* or := and ('or' and)*
|
|
9
|
+
* and := comparison ('and' comparison)*
|
|
10
|
+
* comparison := unary (('==' | '!=' | '<' | '<=' | '>' | '>=') unary)?
|
|
11
|
+
* unary := 'not' unary | primary
|
|
12
|
+
* primary := 'true' | 'false' | string | number | call | '(' expression ')'
|
|
13
|
+
* call := builtin '(' (operand (',' operand)*)? ')'
|
|
14
|
+
*
|
|
15
|
+
* The builtins are the closed set `hasRole`, `hasScope`, `isAuthenticated`, so the
|
|
16
|
+
* context this evaluates against is a {@link Principal} -- who is asking -- and not
|
|
17
|
+
* loop state such as a step counter. Anything the evaluator cannot decide raises:
|
|
18
|
+
* for a human-in-the-loop gate, "could not decide" must never degrade into "do not
|
|
19
|
+
* ask".
|
|
20
|
+
*
|
|
21
|
+
* This file mirrors `aid_runtime/agents/policy.py`. The builtin set is duplicated
|
|
22
|
+
* from `packages/ir` rather than imported, because this package has no dependency on
|
|
23
|
+
* the spec toolchain; a test reads the IR source and keeps the two sets equal.
|
|
24
|
+
*/
|
|
25
|
+
/** One node of a parsed policy. Plain JSON, as the IR carries it. */
|
|
26
|
+
export type PolicyNode = Readonly<Record<string, unknown>>;
|
|
27
|
+
/** Builtin policy functions, in the order the IR declares them. */
|
|
28
|
+
export declare const POLICY_BUILTINS: readonly ['hasRole', 'hasScope', 'isAuthenticated'];
|
|
29
|
+
/** How many operands each builtin takes. */
|
|
30
|
+
export declare const POLICY_BUILTIN_ARITY: Readonly<Record<string, number>>;
|
|
31
|
+
/**
|
|
32
|
+
* Who a policy is evaluated for.
|
|
33
|
+
*
|
|
34
|
+
* Defaults are the anonymous-but-authenticated caller an app with no auth layer has:
|
|
35
|
+
* `isAuthenticated()` is true and both role and scope sets are empty, so
|
|
36
|
+
* `hasRole('admin')` is false rather than undefined.
|
|
37
|
+
*/
|
|
38
|
+
export declare class Principal {
|
|
39
|
+
readonly roles: ReadonlySet<string>;
|
|
40
|
+
readonly scopes: ReadonlySet<string>;
|
|
41
|
+
readonly authenticated: boolean;
|
|
42
|
+
constructor(init?: {
|
|
43
|
+
readonly roles?: Iterable<string>;
|
|
44
|
+
readonly scopes?: Iterable<string>;
|
|
45
|
+
readonly authenticated?: boolean;
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
/** Evaluate a parsed policy against `principal`. Never returns "maybe". */
|
|
49
|
+
export declare function evaluatePolicy(node: PolicyNode, principal: Principal): boolean;
|
|
50
|
+
/** Render an AST back to source, so a trace or error can quote the policy. */
|
|
51
|
+
export declare function policySource(node: PolicyNode): string;
|
|
52
|
+
//# sourceMappingURL=policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAKH,qEAAqE;AACrE,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAK3D,mEAAmE;AACnE,eAAO,MAAM,eAAe,YAAI,SAAS,EAAE,UAAU,EAAE,iBAAiB,CAAU,CAAC;AAEnF,4CAA4C;AAC5C,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIjE,CAAC;AAEF;;;;;;GAMG;AACH,qBAAa,SAAS;IACpB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAEhC,YACE,IAAI,GAAE;QACJ,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QACnC,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;KAC7B,EAKP;CACF;AAED,2EAA2E;AAC3E,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAQ9E;AAED,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAqBrD"}
|
package/dist/policy.js
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evaluation of the IR's `PolicyExpr` AST.
|
|
3
|
+
*
|
|
4
|
+
* The grammar is the one `packages/ir/src/policy` parses, and the AST is plain JSON
|
|
5
|
+
* precisely so a target does not need a second parser:
|
|
6
|
+
*
|
|
7
|
+
* expression := or
|
|
8
|
+
* or := and ('or' and)*
|
|
9
|
+
* and := comparison ('and' comparison)*
|
|
10
|
+
* comparison := unary (('==' | '!=' | '<' | '<=' | '>' | '>=') unary)?
|
|
11
|
+
* unary := 'not' unary | primary
|
|
12
|
+
* primary := 'true' | 'false' | string | number | call | '(' expression ')'
|
|
13
|
+
* call := builtin '(' (operand (',' operand)*)? ')'
|
|
14
|
+
*
|
|
15
|
+
* The builtins are the closed set `hasRole`, `hasScope`, `isAuthenticated`, so the
|
|
16
|
+
* context this evaluates against is a {@link Principal} -- who is asking -- and not
|
|
17
|
+
* loop state such as a step counter. Anything the evaluator cannot decide raises:
|
|
18
|
+
* for a human-in-the-loop gate, "could not decide" must never degrade into "do not
|
|
19
|
+
* ask".
|
|
20
|
+
*
|
|
21
|
+
* This file mirrors `aid_runtime/agents/policy.py`. The builtin set is duplicated
|
|
22
|
+
* from `packages/ir` rather than imported, because this package has no dependency on
|
|
23
|
+
* the spec toolchain; a test reads the IR source and keeps the two sets equal.
|
|
24
|
+
*/
|
|
25
|
+
import { PolicyEvaluationError } from './errors.js';
|
|
26
|
+
import { repr } from './internal/json.js';
|
|
27
|
+
const COMPARISONS = new Set(['==', '!=', '<', '<=', '>', '>=']);
|
|
28
|
+
const LOGICAL = new Set(['and', 'or']);
|
|
29
|
+
/** Builtin policy functions, in the order the IR declares them. */
|
|
30
|
+
export const POLICY_BUILTINS = ['hasRole', 'hasScope', 'isAuthenticated'];
|
|
31
|
+
/** How many operands each builtin takes. */
|
|
32
|
+
export const POLICY_BUILTIN_ARITY = {
|
|
33
|
+
hasRole: 1,
|
|
34
|
+
hasScope: 1,
|
|
35
|
+
isAuthenticated: 0,
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Who a policy is evaluated for.
|
|
39
|
+
*
|
|
40
|
+
* Defaults are the anonymous-but-authenticated caller an app with no auth layer has:
|
|
41
|
+
* `isAuthenticated()` is true and both role and scope sets are empty, so
|
|
42
|
+
* `hasRole('admin')` is false rather than undefined.
|
|
43
|
+
*/
|
|
44
|
+
export class Principal {
|
|
45
|
+
roles;
|
|
46
|
+
scopes;
|
|
47
|
+
authenticated;
|
|
48
|
+
constructor(init = {}) {
|
|
49
|
+
this.roles = new Set(init.roles ?? []);
|
|
50
|
+
this.scopes = new Set(init.scopes ?? []);
|
|
51
|
+
this.authenticated = init.authenticated ?? true;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/** Evaluate a parsed policy against `principal`. Never returns "maybe". */
|
|
55
|
+
export function evaluatePolicy(node, principal) {
|
|
56
|
+
const value = evaluateNode(node, principal);
|
|
57
|
+
if (typeof value !== 'boolean') {
|
|
58
|
+
throw new PolicyEvaluationError(`policy did not evaluate to a boolean, got ${typeName(value)}: ${policySource(node)}`);
|
|
59
|
+
}
|
|
60
|
+
return value;
|
|
61
|
+
}
|
|
62
|
+
/** Render an AST back to source, so a trace or error can quote the policy. */
|
|
63
|
+
export function policySource(node) {
|
|
64
|
+
const kind = node.kind;
|
|
65
|
+
if (kind === 'string' || kind === 'number' || kind === 'boolean') {
|
|
66
|
+
return literalSource(node.value);
|
|
67
|
+
}
|
|
68
|
+
if (kind === 'call') {
|
|
69
|
+
const args = asArray(node.args).map((argument) => policySource(argument));
|
|
70
|
+
return `${String(node.name)}(${args.join(', ')})`;
|
|
71
|
+
}
|
|
72
|
+
if (kind === 'comparison') {
|
|
73
|
+
return `${policySource(asNode(node.left))} ${String(node.op)} ${policySource(asNode(node.right))}`;
|
|
74
|
+
}
|
|
75
|
+
if (typeof kind === 'string' && LOGICAL.has(kind)) {
|
|
76
|
+
return `(${policySource(asNode(node.left))} ${kind} ${policySource(asNode(node.right))})`;
|
|
77
|
+
}
|
|
78
|
+
if (kind === 'not') {
|
|
79
|
+
return `not ${policySource(asNode(node.operand))}`;
|
|
80
|
+
}
|
|
81
|
+
throw new PolicyEvaluationError(`unsupported policy node kind ${describe(kind)}`);
|
|
82
|
+
}
|
|
83
|
+
function literalSource(value) {
|
|
84
|
+
if (typeof value === 'boolean')
|
|
85
|
+
return value ? 'true' : 'false';
|
|
86
|
+
if (typeof value === 'string')
|
|
87
|
+
return `"${value}"`;
|
|
88
|
+
return String(value);
|
|
89
|
+
}
|
|
90
|
+
function evaluateNode(node, principal) {
|
|
91
|
+
const kind = node.kind;
|
|
92
|
+
if (kind === 'string' || kind === 'number' || kind === 'boolean') {
|
|
93
|
+
return node.value;
|
|
94
|
+
}
|
|
95
|
+
if (kind === 'call')
|
|
96
|
+
return call(node, principal);
|
|
97
|
+
if (kind === 'comparison')
|
|
98
|
+
return compare(node, principal);
|
|
99
|
+
if (typeof kind === 'string' && LOGICAL.has(kind))
|
|
100
|
+
return logic(kind, node, principal);
|
|
101
|
+
if (kind === 'not') {
|
|
102
|
+
return !asBoolean(evaluateNode(asNode(node.operand), principal), node);
|
|
103
|
+
}
|
|
104
|
+
throw new PolicyEvaluationError(`unsupported policy node kind ${describe(kind)}`);
|
|
105
|
+
}
|
|
106
|
+
function call(node, principal) {
|
|
107
|
+
const name = node.name;
|
|
108
|
+
const args = asArray(node.args).map((argument) => evaluateNode(argument, principal));
|
|
109
|
+
if (name === 'isAuthenticated') {
|
|
110
|
+
if (args.length > 0)
|
|
111
|
+
throw new PolicyEvaluationError('isAuthenticated() takes no arguments');
|
|
112
|
+
return principal.authenticated;
|
|
113
|
+
}
|
|
114
|
+
if (name === 'hasRole')
|
|
115
|
+
return membership(String(name), args, principal.roles);
|
|
116
|
+
if (name === 'hasScope')
|
|
117
|
+
return membership(String(name), args, principal.scopes);
|
|
118
|
+
throw new PolicyEvaluationError(`unknown policy builtin ${describe(name)}`);
|
|
119
|
+
}
|
|
120
|
+
function membership(name, args, held) {
|
|
121
|
+
if (args.length !== 1) {
|
|
122
|
+
throw new PolicyEvaluationError(`${name}() takes exactly one argument`);
|
|
123
|
+
}
|
|
124
|
+
const [wanted] = args;
|
|
125
|
+
if (typeof wanted !== 'string') {
|
|
126
|
+
throw new PolicyEvaluationError(`${name}() argument must be a string, got ${describe(wanted)}`);
|
|
127
|
+
}
|
|
128
|
+
return held.has(wanted);
|
|
129
|
+
}
|
|
130
|
+
function compare(node, principal) {
|
|
131
|
+
const operator = node.op;
|
|
132
|
+
if (typeof operator !== 'string' || !COMPARISONS.has(operator)) {
|
|
133
|
+
throw new PolicyEvaluationError(`unknown comparison operator ${describe(operator)}`);
|
|
134
|
+
}
|
|
135
|
+
const left = evaluateNode(asNode(node.left), principal);
|
|
136
|
+
const right = evaluateNode(asNode(node.right), principal);
|
|
137
|
+
if (operator === '==')
|
|
138
|
+
return left === right;
|
|
139
|
+
if (operator === '!=')
|
|
140
|
+
return left !== right;
|
|
141
|
+
const comparable = (typeof left === 'number' && typeof right === 'number') ||
|
|
142
|
+
(typeof left === 'string' && typeof right === 'string');
|
|
143
|
+
if (!comparable) {
|
|
144
|
+
throw new PolicyEvaluationError(`cannot compare ${typeName(left)} ${operator} ${typeName(right)}: ${policySource(node)}`);
|
|
145
|
+
}
|
|
146
|
+
const a = left;
|
|
147
|
+
const b = right;
|
|
148
|
+
switch (operator) {
|
|
149
|
+
case '<':
|
|
150
|
+
return a < b;
|
|
151
|
+
case '<=':
|
|
152
|
+
return a <= b;
|
|
153
|
+
case '>':
|
|
154
|
+
return a > b;
|
|
155
|
+
default:
|
|
156
|
+
return a >= b;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
function logic(kind, node, principal) {
|
|
160
|
+
const left = asBoolean(evaluateNode(asNode(node.left), principal), node);
|
|
161
|
+
// `and`/`or` short-circuit on the left operand's truth value.
|
|
162
|
+
if (kind === 'and' && !left)
|
|
163
|
+
return false;
|
|
164
|
+
if (kind === 'or' && left)
|
|
165
|
+
return true;
|
|
166
|
+
return asBoolean(evaluateNode(asNode(node.right), principal), node);
|
|
167
|
+
}
|
|
168
|
+
function asBoolean(value, node) {
|
|
169
|
+
if (typeof value !== 'boolean') {
|
|
170
|
+
throw new PolicyEvaluationError(`expected a boolean operand in ${policySource(node)}, got ${describe(value)}`);
|
|
171
|
+
}
|
|
172
|
+
return value;
|
|
173
|
+
}
|
|
174
|
+
function asNode(value) {
|
|
175
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
176
|
+
throw new PolicyEvaluationError(`policy operand is not a node: ${describe(value)}`);
|
|
177
|
+
}
|
|
178
|
+
return value;
|
|
179
|
+
}
|
|
180
|
+
function asArray(value) {
|
|
181
|
+
if (value === undefined || value === null)
|
|
182
|
+
return [];
|
|
183
|
+
if (!Array.isArray(value)) {
|
|
184
|
+
throw new PolicyEvaluationError(`policy operands are not a list: ${describe(value)}`);
|
|
185
|
+
}
|
|
186
|
+
return value.map((entry) => asNode(entry));
|
|
187
|
+
}
|
|
188
|
+
function typeName(value) {
|
|
189
|
+
if (value === null)
|
|
190
|
+
return 'null';
|
|
191
|
+
if (Array.isArray(value))
|
|
192
|
+
return 'array';
|
|
193
|
+
const kind = typeof value;
|
|
194
|
+
return kind === 'object' ? 'object' : kind;
|
|
195
|
+
}
|
|
196
|
+
function describe(value) {
|
|
197
|
+
return typeof value === 'string' ? repr(value) : String(value);
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Versioned prompt templates.
|
|
3
|
+
*
|
|
4
|
+
* A prompt is a versioned artifact, not a string constant, for the same reason a
|
|
5
|
+
* model is pinned: a baseline recorded against `support-reply` v2 means nothing if
|
|
6
|
+
* "v2" quietly becomes v3. The registry therefore refuses a duplicate name+version
|
|
7
|
+
* rather than overwriting, and version ordering is defined here rather than left to
|
|
8
|
+
* `Array.prototype.sort` on strings (`'v10' < 'v9'` lexicographically, which is
|
|
9
|
+
* exactly the bug this ordering exists to prevent).
|
|
10
|
+
*/
|
|
11
|
+
import { Message } from './types.js';
|
|
12
|
+
/** One worked example, rendered into the message list between system and user. */
|
|
13
|
+
export declare class Example {
|
|
14
|
+
readonly input: string;
|
|
15
|
+
readonly output: string;
|
|
16
|
+
constructor(init: {
|
|
17
|
+
readonly input: string;
|
|
18
|
+
readonly output: string;
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
/** A template plus the metadata a registry keys it by. */
|
|
22
|
+
export declare class PromptTemplate {
|
|
23
|
+
readonly name: string;
|
|
24
|
+
readonly version: string;
|
|
25
|
+
readonly template: string;
|
|
26
|
+
readonly description: string;
|
|
27
|
+
readonly examples: readonly Example[];
|
|
28
|
+
readonly required: readonly string[];
|
|
29
|
+
constructor(init: {
|
|
30
|
+
readonly name: string;
|
|
31
|
+
readonly version: string;
|
|
32
|
+
readonly template: string;
|
|
33
|
+
readonly description?: string;
|
|
34
|
+
readonly examples?: readonly Example[];
|
|
35
|
+
readonly required?: readonly string[];
|
|
36
|
+
});
|
|
37
|
+
/** The variables the template body actually uses. */
|
|
38
|
+
get variables(): readonly string[];
|
|
39
|
+
/** Fill the template, refusing both missing and unused variables. */
|
|
40
|
+
render(values?: Readonly<Record<string, unknown>>): RenderedPrompt;
|
|
41
|
+
}
|
|
42
|
+
/** The result of rendering a template. */
|
|
43
|
+
export declare class RenderedPrompt {
|
|
44
|
+
readonly name: string;
|
|
45
|
+
readonly version: string;
|
|
46
|
+
readonly text: string;
|
|
47
|
+
readonly examples: readonly Example[];
|
|
48
|
+
constructor(init: {
|
|
49
|
+
readonly name: string;
|
|
50
|
+
readonly version: string;
|
|
51
|
+
readonly text: string;
|
|
52
|
+
readonly examples?: readonly Example[];
|
|
53
|
+
});
|
|
54
|
+
/**
|
|
55
|
+
* The message list this prompt becomes: system, then one pair per example, then
|
|
56
|
+
* the user turn.
|
|
57
|
+
*
|
|
58
|
+
* The examples sit between the system turn and the real question deliberately:
|
|
59
|
+
* they are part of the instructions, and putting them after the question invites
|
|
60
|
+
* a model to answer the last example instead.
|
|
61
|
+
*/
|
|
62
|
+
asMessages(system?: string): Message[];
|
|
63
|
+
}
|
|
64
|
+
/** Compare two version strings by dotted-segment order. */
|
|
65
|
+
export declare function compareVersions(left: string, right: string): number;
|
|
66
|
+
/** Sort version strings oldest to newest. */
|
|
67
|
+
export declare function orderedVersions(versions: Iterable<string>): string[];
|
|
68
|
+
/** A closed set of templates, keyed by name and version. */
|
|
69
|
+
export declare class PromptRegistry {
|
|
70
|
+
private readonly _templates;
|
|
71
|
+
constructor(templates?: Iterable<PromptTemplate>);
|
|
72
|
+
/** Add a template. A duplicate name+version is a configuration error, not a replace. */
|
|
73
|
+
register(template: PromptTemplate): void;
|
|
74
|
+
/** The registered names, sorted. */
|
|
75
|
+
names(): string[];
|
|
76
|
+
/** Every version of one prompt, oldest first. */
|
|
77
|
+
versions(name: string): string[];
|
|
78
|
+
/** The newest version of one prompt. */
|
|
79
|
+
latest(name: string): PromptTemplate;
|
|
80
|
+
/** One prompt, by explicit version or the newest. */
|
|
81
|
+
get(name: string, version?: string): PromptTemplate;
|
|
82
|
+
/** Resolve and render in one step. */
|
|
83
|
+
render(name: string, values?: Readonly<Record<string, unknown>>, version?: string): RenderedPrompt;
|
|
84
|
+
private key;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"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"}
|