@lunora/testing 1.0.0-alpha.220 → 1.0.0-alpha.222

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/dist/index.d.mts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { AgentMessageRow, AgentRunInput, AgentGenerateResult, AgentRunResult, AgentDefinition } from '@lunora/agent';
2
+ import { ArtifactsBindingLike, ArtifactsErrorCode, ArtifactsCommitMetadata, ArtifactsTreeEntry } from '@lunora/bindings/artifacts';
2
3
  import { ScheduledJob, LogFields, RegisteredAction, RegisteredMutation, RegisteredQuery, ArgsValidator, InferArgs, ActionCtx, MutationCtx, QueryCtx, TableDefinition, Schema } from '@lunora/server';
3
4
  export {
4
5
  /**
@@ -228,6 +229,46 @@ declare const evaluationAttributes: (input: Pick<RecordEvaluationInput, "label"
228
229
  * emitted — never the graded prompt or output.
229
230
  */
230
231
  declare const recordEvaluation: (input: RecordEvaluationInput) => Record<string, EvaluationAttributeValue>;
232
+ /** Test controls returned alongside the fake binding. */
233
+ interface ArtifactsFake {
234
+ /** The fake `env.ARTIFACTS` binding. */
235
+ binding: ArtifactsBindingLike;
236
+ /** Make the next binding or repo call throw an `ArtifactsError` with `code` (e.g. `UPSTREAM_UNAVAILABLE`). */
237
+ failNext: (code: ArtifactsErrorCode) => void;
238
+ /** How many repo handles `get()` has handed out and how many were disposed — a leak shows as `opened > disposed`. */
239
+ readonly handles: {
240
+ disposed: number;
241
+ opened: number;
242
+ };
243
+ /** Stage a blob by object id. Returns the stored `Blob` (the exact instance `readBlob` hands back). */
244
+ putBlob: (repo: string, hash: string, content: Blob | string) => Blob;
245
+ /** Append a commit to the repo's history (newest first in `log()`), readable by `readCommit`. */
246
+ putCommit: (repo: string, commit: ArtifactsCommitMetadata) => void;
247
+ /** Stage a file at a ref, standing in for a push. Returns the stored `Blob` (the exact instance `readFile` hands back). */
248
+ putFile: (repo: string, file: {
249
+ content: Blob | string;
250
+ path: string;
251
+ ref: string;
252
+ type?: string;
253
+ }) => Blob;
254
+ /** Stage a tree by object id. */
255
+ putTree: (repo: string, hash: string, entries: ArtifactsTreeEntry[]) => void;
256
+ /** The repo names currently in the namespace. */
257
+ repoNames: () => string[];
258
+ }
259
+ /**
260
+ * Build an in-memory Artifacts binding plus seeding and inspection controls.
261
+ *
262
+ * ```ts
263
+ * const fake = createArtifactsFake({ namespace: "default" });
264
+ * const artifacts = createArtifacts({ binding: fake.binding });
265
+ * await artifacts.create("docs");
266
+ * fake.putFile("docs", { ref: "main", path: "README.md", content: "# hi" });
267
+ * ```
268
+ */
269
+ declare const createArtifactsFake: (options?: {
270
+ namespace?: string;
271
+ }) => ArtifactsFake;
231
272
  /** A pending job entry in the fake scheduler queue. */
232
273
  interface FakeScheduledJob extends ScheduledJob {
233
274
  /** The args the job was scheduled with. */
@@ -765,4 +806,4 @@ declare const groundednessScorer: (options: {
765
806
  judge: (prompt: string) => Promise<string>;
766
807
  name?: string;
767
808
  }) => Scorer;
768
- export { type AgentHarness, type AgentHarnessOptions, type AgentRunOverrides, type EvalCase, type EvalItemResult, type EvalResult, type EvaluationAttributeValue, type EvaluationMetrics, type EvaluationSpanHandle, type FakeScheduledJob, type FakeSchedulerControls, type FunctionRegistry, type HarnessDispatch, type HarnessMessage, type HarnessThread, type LunoraTestOptions, type ProducedOutput, type RecordEvaluationInput, type RetrievalScorerOptions, type ScheduledJobFailure, type ScoreResult, type Scorer, type ScorerSample, type SweepOptions, type TestHarness, type TestIdentity, type TestSubscription, agentHarness, containsScorer, evaluate, evaluationAttributes, exactMatchScorer, finalTurn, groundednessScorer, keywordScorer, llmScorer, lunoraTest, mrrScorer, ndcgAtK, precisionAtK, recallAtK, recordEvaluation, regexScorer, scoreSample, toolCallTurn };
809
+ export { type AgentHarness, type AgentHarnessOptions, type AgentRunOverrides, type ArtifactsFake, type EvalCase, type EvalItemResult, type EvalResult, type EvaluationAttributeValue, type EvaluationMetrics, type EvaluationSpanHandle, type FakeScheduledJob, type FakeSchedulerControls, type FunctionRegistry, type HarnessDispatch, type HarnessMessage, type HarnessThread, type LunoraTestOptions, type ProducedOutput, type RecordEvaluationInput, type RetrievalScorerOptions, type ScheduledJobFailure, type ScoreResult, type Scorer, type ScorerSample, type SweepOptions, type TestHarness, type TestIdentity, type TestSubscription, agentHarness, containsScorer, createArtifactsFake, evaluate, evaluationAttributes, exactMatchScorer, finalTurn, groundednessScorer, keywordScorer, llmScorer, lunoraTest, mrrScorer, ndcgAtK, precisionAtK, recallAtK, recordEvaluation, regexScorer, scoreSample, toolCallTurn };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { AgentMessageRow, AgentRunInput, AgentGenerateResult, AgentRunResult, AgentDefinition } from '@lunora/agent';
2
+ import { ArtifactsBindingLike, ArtifactsErrorCode, ArtifactsCommitMetadata, ArtifactsTreeEntry } from '@lunora/bindings/artifacts';
2
3
  import { ScheduledJob, LogFields, RegisteredAction, RegisteredMutation, RegisteredQuery, ArgsValidator, InferArgs, ActionCtx, MutationCtx, QueryCtx, TableDefinition, Schema } from '@lunora/server';
3
4
  export {
4
5
  /**
@@ -228,6 +229,46 @@ declare const evaluationAttributes: (input: Pick<RecordEvaluationInput, "label"
228
229
  * emitted — never the graded prompt or output.
229
230
  */
230
231
  declare const recordEvaluation: (input: RecordEvaluationInput) => Record<string, EvaluationAttributeValue>;
232
+ /** Test controls returned alongside the fake binding. */
233
+ interface ArtifactsFake {
234
+ /** The fake `env.ARTIFACTS` binding. */
235
+ binding: ArtifactsBindingLike;
236
+ /** Make the next binding or repo call throw an `ArtifactsError` with `code` (e.g. `UPSTREAM_UNAVAILABLE`). */
237
+ failNext: (code: ArtifactsErrorCode) => void;
238
+ /** How many repo handles `get()` has handed out and how many were disposed — a leak shows as `opened > disposed`. */
239
+ readonly handles: {
240
+ disposed: number;
241
+ opened: number;
242
+ };
243
+ /** Stage a blob by object id. Returns the stored `Blob` (the exact instance `readBlob` hands back). */
244
+ putBlob: (repo: string, hash: string, content: Blob | string) => Blob;
245
+ /** Append a commit to the repo's history (newest first in `log()`), readable by `readCommit`. */
246
+ putCommit: (repo: string, commit: ArtifactsCommitMetadata) => void;
247
+ /** Stage a file at a ref, standing in for a push. Returns the stored `Blob` (the exact instance `readFile` hands back). */
248
+ putFile: (repo: string, file: {
249
+ content: Blob | string;
250
+ path: string;
251
+ ref: string;
252
+ type?: string;
253
+ }) => Blob;
254
+ /** Stage a tree by object id. */
255
+ putTree: (repo: string, hash: string, entries: ArtifactsTreeEntry[]) => void;
256
+ /** The repo names currently in the namespace. */
257
+ repoNames: () => string[];
258
+ }
259
+ /**
260
+ * Build an in-memory Artifacts binding plus seeding and inspection controls.
261
+ *
262
+ * ```ts
263
+ * const fake = createArtifactsFake({ namespace: "default" });
264
+ * const artifacts = createArtifacts({ binding: fake.binding });
265
+ * await artifacts.create("docs");
266
+ * fake.putFile("docs", { ref: "main", path: "README.md", content: "# hi" });
267
+ * ```
268
+ */
269
+ declare const createArtifactsFake: (options?: {
270
+ namespace?: string;
271
+ }) => ArtifactsFake;
231
272
  /** A pending job entry in the fake scheduler queue. */
232
273
  interface FakeScheduledJob extends ScheduledJob {
233
274
  /** The args the job was scheduled with. */
@@ -765,4 +806,4 @@ declare const groundednessScorer: (options: {
765
806
  judge: (prompt: string) => Promise<string>;
766
807
  name?: string;
767
808
  }) => Scorer;
768
- export { type AgentHarness, type AgentHarnessOptions, type AgentRunOverrides, type EvalCase, type EvalItemResult, type EvalResult, type EvaluationAttributeValue, type EvaluationMetrics, type EvaluationSpanHandle, type FakeScheduledJob, type FakeSchedulerControls, type FunctionRegistry, type HarnessDispatch, type HarnessMessage, type HarnessThread, type LunoraTestOptions, type ProducedOutput, type RecordEvaluationInput, type RetrievalScorerOptions, type ScheduledJobFailure, type ScoreResult, type Scorer, type ScorerSample, type SweepOptions, type TestHarness, type TestIdentity, type TestSubscription, agentHarness, containsScorer, evaluate, evaluationAttributes, exactMatchScorer, finalTurn, groundednessScorer, keywordScorer, llmScorer, lunoraTest, mrrScorer, ndcgAtK, precisionAtK, recallAtK, recordEvaluation, regexScorer, scoreSample, toolCallTurn };
809
+ export { type AgentHarness, type AgentHarnessOptions, type AgentRunOverrides, type ArtifactsFake, type EvalCase, type EvalItemResult, type EvalResult, type EvaluationAttributeValue, type EvaluationMetrics, type EvaluationSpanHandle, type FakeScheduledJob, type FakeSchedulerControls, type FunctionRegistry, type HarnessDispatch, type HarnessMessage, type HarnessThread, type LunoraTestOptions, type ProducedOutput, type RecordEvaluationInput, type RetrievalScorerOptions, type ScheduledJobFailure, type ScoreResult, type Scorer, type ScorerSample, type SweepOptions, type TestHarness, type TestIdentity, type TestSubscription, agentHarness, containsScorer, createArtifactsFake, evaluate, evaluationAttributes, exactMatchScorer, finalTurn, groundednessScorer, keywordScorer, llmScorer, lunoraTest, mrrScorer, ndcgAtK, precisionAtK, recallAtK, recordEvaluation, regexScorer, scoreSample, toolCallTurn };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{agentHarness as o,finalTurn as t,toolCallTurn as a}from"./packem_shared/agentHarness-DA9onGVO.mjs";import{evaluationAttributes as l,recordEvaluation as n}from"./packem_shared/evaluationAttributes-CYLgTP1P.mjs";import{lunoraTest as s}from"./packem_shared/lunoraTest-ZriKevr9.mjs";import{groundednessScorer as p,mrrScorer as u,ndcgAtK as x,precisionAtK as S,recallAtK as f}from"./packem_shared/groundednessScorer-kgXJCZDg.mjs";import{containsScorer as g,evaluate as A,exactMatchScorer as v,keywordScorer as K,llmScorer as M,regexScorer as T,scoreSample as k}from"./packem_shared/containsScorer-DoLfFOs6.mjs";import{extractLink as C,listCapturedMail as b,waitForMail as h}from"@lunora/mail/testing";export{o as agentHarness,g as containsScorer,A as evaluate,l as evaluationAttributes,v as exactMatchScorer,C as extractLink,t as finalTurn,p as groundednessScorer,K as keywordScorer,b as listCapturedMail,M as llmScorer,s as lunoraTest,u as mrrScorer,x as ndcgAtK,S as precisionAtK,f as recallAtK,n as recordEvaluation,T as regexScorer,k as scoreSample,a as toolCallTurn,h as waitForMail};
1
+ import{agentHarness as o,finalTurn as t,toolCallTurn as a}from"./packem_shared/agentHarness-DA9onGVO.mjs";import{evaluationAttributes as l,recordEvaluation as n}from"./packem_shared/evaluationAttributes-CYLgTP1P.mjs";import{createArtifactsFake as s}from"./packem_shared/createArtifactsFake-L0tjki11.mjs";import{lunoraTest as p}from"./packem_shared/lunoraTest-ZriKevr9.mjs";import{groundednessScorer as f,mrrScorer as u,ndcgAtK as S,precisionAtK as d,recallAtK as A}from"./packem_shared/groundednessScorer-kgXJCZDg.mjs";import{containsScorer as k,evaluate as v,exactMatchScorer as K,keywordScorer as M,llmScorer as T,regexScorer as w,scoreSample as C}from"./packem_shared/containsScorer-DoLfFOs6.mjs";import{extractLink as b,listCapturedMail as h,waitForMail as y}from"@lunora/mail/testing";export{o as agentHarness,k as containsScorer,s as createArtifactsFake,v as evaluate,l as evaluationAttributes,K as exactMatchScorer,b as extractLink,t as finalTurn,f as groundednessScorer,M as keywordScorer,h as listCapturedMail,T as llmScorer,p as lunoraTest,u as mrrScorer,S as ndcgAtK,d as precisionAtK,A as recallAtK,n as recordEvaluation,w as regexScorer,C as scoreSample,a as toolCallTurn,y as waitForMail};
@@ -0,0 +1 @@
1
+ const R={ALREADY_EXISTS:10201,FORK_IN_PROGRESS:10303,IMPORT_IN_PROGRESS:10302,INTERNAL_ERROR:10400,INVALID_INPUT:10100,INVALID_REPO_NAME:10101,INVALID_TTL:10103,INVALID_URL:10104,MEMORY_LIMIT:10402,NOT_FOUND:10200,REMOTE_AUTH_REQUIRED:10106,UPSTREAM_UNAVAILABLE:10401},w=/^[\da-f]{40}$/,L=/^\d+$/,p=/^[a-z\d][\w.-]*$/i,y=60,b=31536e3,O=86400,a=(l,f)=>Object.assign(new Error(f),{code:l,name:"ArtifactsError",numericCode:R[l]}),S=(l,f="")=>typeof l=="string"?new Blob([l],{type:f}):l,g=(l={})=>{const f=l.namespace??"default",u=new Map,N={disposed:0,opened:0};let _,m=0;const A=t=>(m+=1,`${t}${String(m).padStart(6,"0")}`),h=()=>{if(_!==void 0){const t=_;throw _=void 0,a(t,`injected ${t}`)}},I=t=>{const e=u.get(t);if(e===void 0)throw a("NOT_FOUND",`repository "${t}" does not exist`);return e},E=(t,e,n)=>{const s=A("tok"),o=Date.now(),r=new Date(o+n*1e3).toISOString(),i=`art_fake_${s}?expires=${String(Math.floor(o/1e3)+n)}`;return t.tokens.set(s,{info:{createdAt:new Date(o).toISOString(),expiresAt:r,id:s,scope:e,state:"active"},plaintext:i}),{expiresAt:r,id:s,plaintext:i,scope:e}},T=(t,e)=>{if(!p.test(t))throw a("INVALID_REPO_NAME",`invalid repository name "${t}"`);if(u.has(t))throw a("ALREADY_EXISTS",`repository "${t}" already exists`);const n=new Date().toISOString(),s={createdAt:n,defaultBranch:e.defaultBranch??"main",description:e.description??null,id:A("repo"),lastPushAt:null,name:t,readOnly:e.readOnly??!1,remote:`https://artifacts.fake.test/${f}/${t}.git`,source:e.source??null,updatedAt:n},o={blobs:new Map,commits:[],files:new Map,info:s,tokens:new Map,trees:new Map};u.set(t,o);const{plaintext:r}=E(o,"write",O);return{defaultBranch:s.defaultBranch,description:s.description,id:s.id,name:t,remote:s.remote,token:r}},D=t=>{N.opened+=1;const e=()=>{if(h(),u.get(t.info.name)!==t)throw a("NOT_FOUND",`repository "${t.info.name}" does not exist`)};return{[Symbol.dispose]:()=>{N.disposed+=1},createToken:async(n="write",s=O)=>{if(e(),!Number.isInteger(s)||s<y||s>b)throw a("INVALID_TTL",`ttl must be between ${String(y)} and ${String(b)}`);return E(t,n,s)},fork:async(n,s)=>{e();const o=T(n,{defaultBranch:t.info.defaultBranch,description:s?.description,readOnly:s?.readOnly,source:`artifacts:${f}/${t.info.name}`}),r=I(n),i=s?.defaultBranchOnly??!0;for(const[c,d]of t.files)(!i||c.startsWith(`${t.info.defaultBranch}:`))&&r.files.set(c,d);for(const[c,d]of t.blobs)r.blobs.set(c,d);for(const[c,d]of t.trees)r.trees.set(c,d);return r.commits.push(...t.commits),o},info:async()=>(e(),{...t.info}),listTokens:async()=>{e();const n=[...t.tokens.values()].map(s=>({...s.info}));return{tokens:n,total:n.length}},log:async n=>{e();const s=n?.offset??0,o=Math.min(n?.limit??50,1e3),r=n?.ref;let i=0;return r!==void 0&&w.test(r)&&(i=t.commits.findIndex(c=>c.hash===r),i===-1)?[]:t.commits.slice(i+s,i+s+o)},readBlob:async n=>(e(),t.blobs.get(n)??null),readCommit:async n=>(e(),t.commits.find(s=>s.hash===n)??null),readFile:async({path:n,ref:s})=>{if(e(),s===""||n==="")throw a("INVALID_INPUT","ref and path must be non-empty");return t.files.get(`${s}:${n}`)??null},readTree:async n=>(e(),t.trees.get(n)??null),revokeToken:async n=>{if(e(),n==="")throw a("INVALID_INPUT","tokenOrId must be non-empty");const s=[...t.tokens.values()].find(o=>o.info.id===n||o.plaintext===n);return s?.info.state!=="active"?!1:(s.info.state="revoked",!0)}}};return{binding:{create:async(t,e)=>(h(),T(t,{defaultBranch:e?.setDefaultBranch,description:e?.description,readOnly:e?.readOnly})),delete:async t=>{if(h(),!p.test(t))throw a("INVALID_REPO_NAME",`invalid repository name "${t}"`);return u.get(t)?.tokens.clear(),u.delete(t)},get:async t=>(h(),D(I(t))),import:async({source:t,target:e})=>{if(h(),!t.url.startsWith("https://"))throw a("INVALID_INPUT","source url must be https");return T(e.name,{description:e.opts?.description,readOnly:e.opts?.readOnly,source:t.url})},list:async t=>{h();const e=[...u.values()].map(({info:{remote:c,...d}})=>d),n=t?.cursor??"0";if(!L.test(n))throw a("INVALID_INPUT","invalid cursor");const s=Number(n),o=t?.limit??50,r=e.slice(s,s+o),i=s+o;return i<e.length?{cursor:String(i),repos:r,total:e.length}:{repos:r,total:e.length}}},failNext:t=>{_=t},handles:N,putBlob:(t,e,n)=>{const s=S(n);return I(t).blobs.set(e,s),s},putCommit:(t,e)=>{const n=I(t);n.commits.unshift(e),n.info.lastPushAt=new Date().toISOString()},putFile:(t,{content:e,path:n,ref:s,type:o})=>{const r=S(e,o??"text/plain;charset=utf-8");return I(t).files.set(`${s}:${n}`,r),r},putTree:(t,e,n)=>{I(t).trees.set(e,n)},repoNames:()=>[...u.keys()]}};export{g as createArtifactsFake};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/testing",
3
- "version": "1.0.0-alpha.220",
3
+ "version": "1.0.0-alpha.222",
4
4
  "description": "Testing toolkit for Lunora: an in-memory harness for queries, mutations, and actions",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -50,12 +50,13 @@
50
50
  "access": "public"
51
51
  },
52
52
  "dependencies": {
53
- "@lunora/agent": "1.0.0-alpha.162",
54
- "@lunora/errors": "1.0.0-alpha.48",
55
- "@lunora/mail": "1.0.0-alpha.94",
56
- "@lunora/scheduler": "1.0.0-alpha.103",
57
- "@lunora/server": "1.0.0-alpha.169",
58
- "@lunora/shard-engine": "1.0.0-alpha.105"
53
+ "@lunora/agent": "1.0.0-alpha.164",
54
+ "@lunora/bindings": "1.0.0-alpha.92",
55
+ "@lunora/errors": "1.0.0-alpha.49",
56
+ "@lunora/mail": "1.0.0-alpha.95",
57
+ "@lunora/scheduler": "1.0.0-alpha.105",
58
+ "@lunora/server": "1.0.0-alpha.171",
59
+ "@lunora/shard-engine": "1.0.0-alpha.107"
59
60
  },
60
61
  "peerDependencies": {
61
62
  "@playwright/test": "^1.61.1"