@ampcode/plugin 0.0.0-20261006001912-g060eaed → 0.0.0-20261008001818-g5d841b4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/index.d.ts +193 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,6 +13,12 @@ Plugins can:
|
|
|
13
13
|
- **Show UI** — `ctx.ui.notify(...)`, `ctx.ui.confirm(...)`, `ctx.ui.input(...)`, and `ctx.ui.select(...)`
|
|
14
14
|
- **Use AI** — `amp.ai.ask(...)` for thread-scoped yes/no classification that defaults to no
|
|
15
15
|
reasoning unless `{ reasoningEffort }` is set
|
|
16
|
+
- **Decide fast** — `amp.ai.decide(...)`, `amp.ai.choice(...)`, `amp.ai.noul(...)`, and
|
|
17
|
+
`amp.ai.score(...)` for typed decisions with calibrated probabilities and no generated text,
|
|
18
|
+
answered by TypeSafe's Jev, or by OpenAI's Decisions API when you pass
|
|
19
|
+
`{ model: 'openai/gpt-6-luna' }`
|
|
20
|
+
- **Label threads** — `ctx.thread.labels()`, `ctx.thread.addLabels(...)`, and
|
|
21
|
+
`ctx.thread.setLabels(...)` to read and change the current thread's labels
|
|
16
22
|
- **Upload attachments** — `amp.attachments.upload(...)` to upload image bytes and get back a URL
|
|
17
23
|
for URL-backed `{ type: 'image', mimeType, url }` tool result blocks, keeping large images out
|
|
18
24
|
of thread state
|
package/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// sitemap-lastmod: /docs/plugin-api 2026-
|
|
1
|
+
// sitemap-lastmod: /docs/plugin-api 2026-10-06
|
|
2
2
|
|
|
3
3
|
declare module '@ampcode/plugin' {
|
|
4
4
|
/**
|
|
@@ -762,6 +762,134 @@ declare module '@ampcode/plugin' {
|
|
|
762
762
|
schema: PluginAIObjectSchema
|
|
763
763
|
}
|
|
764
764
|
|
|
765
|
+
/**
|
|
766
|
+
* Text or JSON accepted wherever a decision takes a state, instructions, or criteria. Objects
|
|
767
|
+
* and arrays are passed to the model as-is.
|
|
768
|
+
*/
|
|
769
|
+
export type DecisionInput = string | Record<string, unknown> | unknown[]
|
|
770
|
+
|
|
771
|
+
/** Estimates whether a condition holds for the state. Answers with a probability from 0 to 1. */
|
|
772
|
+
export interface NoulQuestion {
|
|
773
|
+
type: 'noul'
|
|
774
|
+
instructions: DecisionInput
|
|
775
|
+
/** Optional descriptions of what makes the condition true or false. */
|
|
776
|
+
criteria?: { true?: DecisionInput; false?: DecisionInput }
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
/** Rates the state on an ordered scale. `criteria` lists 2–10 levels, lowest first. */
|
|
780
|
+
export interface ScoreQuestion {
|
|
781
|
+
type: 'score'
|
|
782
|
+
instructions: DecisionInput
|
|
783
|
+
criteria: DecisionInput[]
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
/** Chooses one of 2–20 options. `criteria` maps each option to a description or `null`. */
|
|
787
|
+
export interface ChoiceQuestion<Option extends string = string> {
|
|
788
|
+
type: 'choice'
|
|
789
|
+
instructions: DecisionInput
|
|
790
|
+
criteria: Record<Option, DecisionInput | null>
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
export type DecisionQuestion = NoulQuestion | ScoreQuestion | ChoiceQuestion
|
|
794
|
+
|
|
795
|
+
export interface NoulAnswer {
|
|
796
|
+
type: 'noul'
|
|
797
|
+
/** Probability from 0 to 1 that the condition holds. */
|
|
798
|
+
noul: number
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
export interface ScoreAnswer {
|
|
802
|
+
type: 'score'
|
|
803
|
+
/** Probability-weighted score across the levels, from 0 to the number of levels minus one. */
|
|
804
|
+
score: number
|
|
805
|
+
/** Level index (as a string) to the level description. */
|
|
806
|
+
legend: Record<string, string>
|
|
807
|
+
/** Probability of each level index. */
|
|
808
|
+
probabilities: Record<string, number>
|
|
809
|
+
/**
|
|
810
|
+
* The model's confidence in the score, from 0 to 1. Each model defines it; it is not always
|
|
811
|
+
* the probability of the most likely level.
|
|
812
|
+
*/
|
|
813
|
+
confidence: number
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
export interface ChoiceAnswer<Option extends string = string> {
|
|
817
|
+
type: 'choice'
|
|
818
|
+
choice: Option
|
|
819
|
+
/** Probability of each option. */
|
|
820
|
+
probabilities: Record<Option, number>
|
|
821
|
+
/**
|
|
822
|
+
* The model's confidence in `choice`, from 0 to 1. Each model defines it; it is not always
|
|
823
|
+
* the probability of `choice`.
|
|
824
|
+
*/
|
|
825
|
+
confidence: number
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
export type DecisionAnswer = NoulAnswer | ScoreAnswer | ChoiceAnswer
|
|
829
|
+
|
|
830
|
+
/** The answer type returned for a question of type `Q`. */
|
|
831
|
+
export type DecisionAnswerFor<Q extends DecisionQuestion> =
|
|
832
|
+
Q extends ChoiceQuestion<infer Option>
|
|
833
|
+
? ChoiceAnswer<Option>
|
|
834
|
+
: Q extends ScoreQuestion
|
|
835
|
+
? ScoreAnswer
|
|
836
|
+
: NoulAnswer
|
|
837
|
+
|
|
838
|
+
/**
|
|
839
|
+
* A decision model, written as `provider/model`. `typesafe/jev` is TypeSafe's Jev.
|
|
840
|
+
* `openai/gpt-6-luna` is OpenAI's Decisions API. A workspace can disable a provider, so a model
|
|
841
|
+
* that exists here can still be unavailable in a thread.
|
|
842
|
+
*
|
|
843
|
+
* The models answer the same questions but are calibrated differently, so a threshold tuned on
|
|
844
|
+
* one does not carry over to the other. With `openai/gpt-6-luna`, JSON in `state`,
|
|
845
|
+
* `instructions`, and `criteria` is sent as its JSON text, the criteria of a `noul` question are
|
|
846
|
+
* appended to its instructions, and the call rejects if OpenAI declines to answer a question.
|
|
847
|
+
*/
|
|
848
|
+
export type DecisionModel = 'typesafe/jev' | 'openai/gpt-6-luna'
|
|
849
|
+
|
|
850
|
+
/** The state every decision is judged against, and the thread that routes the request. */
|
|
851
|
+
export interface DecisionOptions {
|
|
852
|
+
/** Thread to route the request through. Required outside a thread-bound handler. */
|
|
853
|
+
threadID?: ThreadID
|
|
854
|
+
/**
|
|
855
|
+
* The decision model to ask. Defaults to `typesafe/jev`. The call fails if the thread's
|
|
856
|
+
* workspace has disabled that model; Amp never asks another model in its place, so name
|
|
857
|
+
* `openai/gpt-6-luna` for a workspace that allows only OpenAI.
|
|
858
|
+
*/
|
|
859
|
+
model?: DecisionModel
|
|
860
|
+
/** The situation to judge: text, or JSON the model reads as-is. Up to 50,000 characters of text. */
|
|
861
|
+
state: DecisionInput
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
export interface DecisionRequest<
|
|
865
|
+
Q extends Record<string, DecisionQuestion> = Record<string, DecisionQuestion>,
|
|
866
|
+
> extends DecisionOptions {
|
|
867
|
+
/** 1–20 questions, each answered independently against `state`. */
|
|
868
|
+
questions: Q
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
export interface DecisionResult<
|
|
872
|
+
Q extends Record<string, DecisionQuestion> = Record<string, DecisionQuestion>,
|
|
873
|
+
> {
|
|
874
|
+
/**
|
|
875
|
+
* The exact model version that answered, as its provider reports it, such as `jev-1.13.0` or
|
|
876
|
+
* `gpt-6-luna`.
|
|
877
|
+
* Record it when you tune thresholds so a model change is visible.
|
|
878
|
+
*/
|
|
879
|
+
model: string
|
|
880
|
+
answers: { [K in keyof Q]: DecisionAnswerFor<Q[K]> }
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
/** A single {@link ChoiceQuestion} with its state. */
|
|
884
|
+
export interface ChoiceRequest<Option extends string = string>
|
|
885
|
+
extends DecisionOptions, Omit<ChoiceQuestion<Option>, 'type'> {}
|
|
886
|
+
|
|
887
|
+
/** A single {@link NoulQuestion} with its state. */
|
|
888
|
+
export interface NoulRequest extends DecisionOptions, Omit<NoulQuestion, 'type'> {}
|
|
889
|
+
|
|
890
|
+
/** A single {@link ScoreQuestion} with its state. */
|
|
891
|
+
export interface ScoreRequest extends DecisionOptions, Omit<ScoreQuestion, 'type'> {}
|
|
892
|
+
|
|
765
893
|
/**
|
|
766
894
|
* AI capabilities provided to plugins.
|
|
767
895
|
*/
|
|
@@ -793,6 +921,49 @@ declare module '@ampcode/plugin' {
|
|
|
793
921
|
* @returns Object with result, probability, and reason
|
|
794
922
|
*/
|
|
795
923
|
ask(question: string, options?: PluginAIAskOptions): Promise<PluginAIAskResult>
|
|
924
|
+
|
|
925
|
+
/**
|
|
926
|
+
* Ask a decision model typed questions about a state. A decision model does not generate
|
|
927
|
+
* text: each answer is a choice, a score, or a yes/no probability (`noul`) with calibrated
|
|
928
|
+
* probabilities, in well under a second and at a small fraction of the cost of
|
|
929
|
+
* {@link PluginAI.generate}. Use it for routing, triage, relevance, and policy checks where
|
|
930
|
+
* the application owns the thresholds and control flow; use {@link PluginAI.generate} when
|
|
931
|
+
* the answer needs reasoning or prose.
|
|
932
|
+
*
|
|
933
|
+
* All questions in one call are answered against the same `state` in one round trip. The
|
|
934
|
+
* answer type of each question is inferred from the request, so `result.answers.route.choice`
|
|
935
|
+
* is typed as the option names you passed. The typed shape is guaranteed; the answer can
|
|
936
|
+
* still be wrong, and adversarial text inside `state` can move it.
|
|
937
|
+
*
|
|
938
|
+
* TypeSafe's Jev answers unless you pass {@link DecisionOptions.model}, and
|
|
939
|
+
* {@link DecisionResult.model} reports the version that answered. The call rejects when the
|
|
940
|
+
* thread's workspace has disabled the model, so handle the error where a decision is
|
|
941
|
+
* optional.
|
|
942
|
+
*
|
|
943
|
+
* Calls are routed through the current thread. Pass `threadID` when calling outside a
|
|
944
|
+
* thread-bound handler.
|
|
945
|
+
*/
|
|
946
|
+
decide<Q extends Record<string, DecisionQuestion>>(
|
|
947
|
+
request: DecisionRequest<Q>,
|
|
948
|
+
): Promise<DecisionResult<Q>>
|
|
949
|
+
|
|
950
|
+
/**
|
|
951
|
+
* Choose one of 2–20 options for a state. Shorthand for {@link PluginAI.decide} with one
|
|
952
|
+
* `choice` question; `answer.choice` is typed as the keys of `criteria`.
|
|
953
|
+
*/
|
|
954
|
+
choice<Option extends string>(request: ChoiceRequest<Option>): Promise<ChoiceAnswer<Option>>
|
|
955
|
+
|
|
956
|
+
/**
|
|
957
|
+
* Estimate the probability that a condition holds for a state. Shorthand for
|
|
958
|
+
* {@link PluginAI.decide} with one `noul` question.
|
|
959
|
+
*/
|
|
960
|
+
noul(request: NoulRequest): Promise<NoulAnswer>
|
|
961
|
+
|
|
962
|
+
/**
|
|
963
|
+
* Rate a state on an ordered scale of 2–10 levels. Shorthand for {@link PluginAI.decide} with
|
|
964
|
+
* one `score` question.
|
|
965
|
+
*/
|
|
966
|
+
score(request: ScoreRequest): Promise<ScoreAnswer>
|
|
796
967
|
}
|
|
797
968
|
|
|
798
969
|
/**
|
|
@@ -1238,6 +1409,27 @@ declare module '@ampcode/plugin' {
|
|
|
1238
1409
|
*/
|
|
1239
1410
|
setMultiplayer(options: { ttlSeconds: number | null }): Promise<void>
|
|
1240
1411
|
|
|
1412
|
+
/**
|
|
1413
|
+
* Read the thread's labels, sorted alphabetically.
|
|
1414
|
+
*/
|
|
1415
|
+
labels(): Promise<string[]>
|
|
1416
|
+
|
|
1417
|
+
/**
|
|
1418
|
+
* Replace the thread's labels and resolve with the resulting labels.
|
|
1419
|
+
*
|
|
1420
|
+
* Labels are lowercased and deduplicated. Each label must be alphanumeric
|
|
1421
|
+
* with hyphens, start with an alphanumeric character, and be at most 32
|
|
1422
|
+
* characters long. A thread holds at most 20 labels. The authenticated user
|
|
1423
|
+
* must be allowed to manage the thread.
|
|
1424
|
+
*/
|
|
1425
|
+
setLabels(labels: string[]): Promise<string[]>
|
|
1426
|
+
|
|
1427
|
+
/**
|
|
1428
|
+
* Add labels to the thread, keeping its existing labels, and resolve with
|
|
1429
|
+
* the resulting labels. Same label rules as {@link setLabels}.
|
|
1430
|
+
*/
|
|
1431
|
+
addLabels(labels: string[]): Promise<string[]>
|
|
1432
|
+
|
|
1241
1433
|
/**
|
|
1242
1434
|
* Read messages from the thread in a stable plugin-facing schema.
|
|
1243
1435
|
*
|