@oddington/sdk 0.1.21 → 0.1.23

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.
@@ -14,7 +14,9 @@ export type { RecordReadInput } from '../../../shared/record-capture.js';
14
14
  export type { RecordDeleteRequest, RecordUpdateRequest, RecordWriteRequest } from '../../../shared/record-write.js';
15
15
  export { RoutineRecordWriteError } from '../../../shared/record-write.js';
16
16
  export { AirtableOperationError } from '../../../shared/airtable-contract.js';
17
- export type { AirtableField, AirtableTable, AirtableRecord, AirtableListInput, AirtableGetInput, AirtableCreateInput, AirtableUpdateInput, AirtableDeleteInput, AirtableReceipt, AirtableWriteResult, AirtableClient, Connections } from '../../../shared/airtable-contract.js';
17
+ export type { AirtableField, AirtableTable, AirtableRecord, AirtableListInput, AirtableGetInput, AirtableCreateInput, AirtableUpdateInput, AirtableDeleteInput, AirtableReceipt, AirtableWriteResult, AirtableClient } from '../../../shared/airtable-contract.js';
18
+ export type { GmailRuntimeConnection, AirtableRuntimeConnection, RuntimeConnection } from '../../../shared/connection-runtime.js';
19
+ export type { Connections } from '../../../shared/airtable-contract.js';
18
20
  export declare const connections: import('../../../shared/airtable-contract.js').Connections;
19
21
  export { DataOperationError } from '../../../shared/data-contract.js';
20
22
  export type { DataRepository, DataErrorCode, PublicValueDefinition, PublicField, CollectionSummary, CollectionSchema, QueryScalar, SelectionOptions, RecordSelection, RecordsQuery, DataValue, SelectedRecord, SelectionMetadata, RecordsResult, RecordsSearchOptions, RecordsSearchResult, HistoryListOptions, HistoryEntry, HistoryChangesOptions, HistoryChange, HistoryChangesResult, RecordIdentity, RecordCreation, RecordUpdateSet, DataPublication, DataChangeSet, DataEffect } from '../../../shared/data-contract.js';
@@ -1,9 +1,12 @@
1
1
  import type { AppValueSchema } from '../../../shared/app-routine-contract.js';
2
2
  import type { File } from '../../../shared/files-contract.js';
3
3
  import type { Connections } from '../../../shared/airtable-contract.js';
4
+ import type { RuntimeConnectionFor } from '../../../shared/connection-runtime.js';
4
5
  import type { DataRepository } from '../../../shared/data-contract.js';
5
6
  import type { Handler } from '../../../shared/inbox-contract.js';
6
7
  import type { files, RoutinePublicationClient } from './public.js';
8
+ import type { RoutineAccess } from '../../../shared/routine-definition-contract.js';
9
+ export type { RoutineAccess } from '../../../shared/routine-definition-contract.js';
7
10
  declare const valueType: unique symbol;
8
11
  /** Serializable declaration; the phantom type never carries authority. */
9
12
  export type RoutineSchema<Value, Defaulted extends boolean = boolean> = AppValueSchema & {
@@ -12,13 +15,6 @@ export type RoutineSchema<Value, Defaulted extends boolean = boolean> = AppValue
12
15
  readonly hasDefault?: Defaulted;
13
16
  };
14
17
  export type RoutineSchemaValue<Schema> = Schema extends RoutineSchema<infer Value> ? Value : undefined;
15
- export type RoutineAccess = {
16
- readonly repositories?: Readonly<Record<string, 'read' | 'write'>>;
17
- readonly connections?: readonly string[];
18
- readonly models?: readonly string[];
19
- readonly files?: 'read' | 'read-write';
20
- readonly publish?: readonly ('asks' | 'digests')[];
21
- };
22
18
  export type RoutineStepOutput = {
23
19
  summary: unknown;
24
20
  data: unknown;
@@ -64,11 +60,18 @@ export type RoutineCapabilities<Access extends RoutineAccess> = {
64
60
  readonly files: Access['files'] extends 'read-write' ? typeof files : Access['files'] extends 'read' ? Pick<typeof files, 'get' | 'read'> : {};
65
61
  readonly connections: {
66
62
  airtable(name: ConnectionName<Access>): ReturnType<Connections['airtable']>;
63
+ get<Name extends Extract<NonNullable<Access['connections']>[number], string>>(name: Name): Promise<RuntimeConnectionFor<Name>>;
67
64
  };
68
65
  readonly inbox: Pick<RoutinePublicationClient, (Access['publish'] extends readonly string[] ? 'asks' extends Access['publish'][number] ? 'publishAsk' : never : never) | (Access['publish'] extends readonly string[] ? 'digests' extends Access['publish'][number] ? 'publishDigest' : never : never)>;
69
66
  };
67
+ type RoutineStepCalls<Steps extends RoutineSteps> = {
68
+ [Key in keyof Steps]: {
69
+ input: Parameters<Steps[Key]['run']> extends [] ? [] : [input: RoutineInput<RoutineStepInput<Steps[Key]>>];
70
+ result: RoutineStepResult<Steps[Key]>;
71
+ };
72
+ };
70
73
  export type RoutineRuntime<Steps extends RoutineSteps, Access extends RoutineAccess = RoutineAccess> = RoutineCapabilities<Access> & {
71
- step<Key extends Extract<keyof Steps, string>>(id: Key, ...input: Parameters<Steps[Key]['run']> extends [] ? [] : [input: RoutineInput<RoutineStepInput<Steps[Key]>>]): Promise<RoutineStepResult<Steps[Key]>>;
74
+ step<Key extends Extract<keyof Steps, string>>(id: Key, ...input: RoutineStepCalls<Steps>[Key]['input']): Promise<RoutineStepCalls<Steps>[Key]['result']>;
72
75
  };
73
76
  export type RoutineDefinition<Input extends RoutineSchema<unknown> | undefined = RoutineSchema<unknown> | undefined, Steps extends RoutineSteps = RoutineSteps, Result extends RoutineSchema<unknown> | undefined = RoutineSchema<unknown> | undefined, Access extends RoutineAccess = RoutineAccess, Responses extends readonly Handler<any>[] = readonly Handler<any>[], Id extends string = string> = {
74
77
  readonly id: Id;
@@ -103,5 +106,6 @@ export type RoutineSchemaBuilders = {
103
106
  }): RoutineSchema<number, false>;
104
107
  boolean(): RoutineSchema<boolean, false>;
105
108
  };
106
- export type RoutineFileSchema = () => RoutineSchema<File, false>;
107
- export {};
109
+ export type RoutineFileSchema = (options?: {
110
+ storage?: 'local' | 'remote';
111
+ }) => RoutineSchema<File, false>;
@@ -73,6 +73,7 @@ export interface AirtableClient {
73
73
  }
74
74
  export interface Connections {
75
75
  airtable(name: string): AirtableClient;
76
+ get<Name extends string>(identity: Name): Promise<import('./connection-runtime.js').RuntimeConnectionFor<Name>>;
76
77
  }
77
78
  /** Safe provider failure. An uncertain or partial mutation must never be retried blindly. */
78
79
  export declare class AirtableOperationError extends Error {
@@ -1,4 +1,5 @@
1
1
  import type { AppValueSchema } from './app-routine-contract.js';
2
+ import type { RoutineContract } from './routine-definition-contract.js';
2
3
  /** Build-time structure only. Runtime readiness and availability belong to hosts. */
3
4
  export type AppRoutineDescriptor = {
4
5
  id: string;
@@ -19,3 +20,5 @@ export type AppRoutineDescriptor = {
19
20
  export type AppDescriptor = {
20
21
  routines: AppRoutineDescriptor[];
21
22
  };
23
+ /** The shared safe projection for generated apps and deployed preparation. */
24
+ export declare function routineDefinitionDescriptor(contract: RoutineContract): AppRoutineDescriptor;
@@ -29,6 +29,7 @@ export type AppValueSchema = {
29
29
  maximum?: number;
30
30
  } | {
31
31
  type: 'file';
32
+ storage?: 'local' | 'remote';
32
33
  };
33
34
  export type AppRoutineContract = {
34
35
  routine: string;
@@ -0,0 +1,20 @@
1
+ /** Public values delivered only inside trusted routine or handler execution. */
2
+ export type GmailRuntimeConnection = {
3
+ id: `gmail/${string}`;
4
+ provider: 'gmail';
5
+ name: string;
6
+ accountEmail: string;
7
+ scopes: string[];
8
+ accessToken: string;
9
+ expiresAt: string;
10
+ };
11
+ export type AirtableRuntimeConnection = {
12
+ id: `airtable/${string}`;
13
+ provider: 'airtable';
14
+ name: string;
15
+ baseId: string;
16
+ accessToken: string;
17
+ runExpiresAt: string;
18
+ };
19
+ export type RuntimeConnection = GmailRuntimeConnection | AirtableRuntimeConnection;
20
+ export type RuntimeConnectionFor<Name extends string> = string extends Name ? RuntimeConnection : Name extends `gmail/${string}` ? GmailRuntimeConnection : Name extends `airtable/${string}` ? AirtableRuntimeConnection : never;
@@ -138,9 +138,15 @@ type Presentation = {
138
138
  body?: InboxBlock[];
139
139
  notifyImmediately?: boolean;
140
140
  };
141
+ export type AskRecordRef = {
142
+ repository: string;
143
+ id: string;
144
+ };
141
145
  export type AskInput = Presentation & {
142
146
  recipients?: string[];
143
147
  questions?: QuestionInput[];
148
+ tags?: string[];
149
+ recordRefs?: AskRecordRef[];
144
150
  };
145
151
  export type DigestInput = Presentation & {
146
152
  recipients: string[];
@@ -149,6 +155,8 @@ export type AskPublication = Presentation & {
149
155
  kind: 'ask';
150
156
  recipients: string[];
151
157
  questions: Question[];
158
+ tags: string[];
159
+ recordRefs: AskRecordRef[];
152
160
  };
153
161
  export type DigestPublication = DigestInput & {
154
162
  kind: 'digest';
@@ -333,7 +341,7 @@ export declare function validateHandlerTransition(value: unknown, state: {
333
341
  export declare function validateResolution(value: unknown): ResolutionInput;
334
342
  export type PublicationRequest = {
335
343
  requestKey: string;
336
- item: Publication;
344
+ item: DigestPublication | (Omit<AskPublication, 'tags' | 'recordRefs'> & Pick<AskInput, 'tags' | 'recordRefs'>);
337
345
  };
338
346
  export type PublishedAsk = {
339
347
  id: string;
@@ -11,8 +11,8 @@ export declare const INBOX_LOCAL_INPUT_BYTES: number;
11
11
  export declare const INBOX_UUID: RegExp;
12
12
  export type InboxOperation = 'current' | 'items.list' | 'items.read' | 'items.see' | 'items.markDigestRead' | 'items.rename' | 'items.setLifecycle' | 'items.listRecipientCandidates' | 'items.addRecipient' | 'questions.list' | 'questions.answer' | 'questions.searchRecords' | 'files.read';
13
13
  export declare function isAppQuestionOperation(operation: InboxOperation): boolean;
14
- /** Closed wire vocabulary. Hosts select the listing mode; input cannot select it. */
15
- export declare function parseInboxRequest(value: unknown, questionListContext?: 'local' | 'hosted'): {
14
+ /** Closed wire vocabulary; both placements require an explicit relevance filter. */
15
+ export declare function parseInboxRequest(value: unknown): {
16
16
  operation: InboxOperation;
17
17
  input: Record<string, unknown>;
18
18
  };
@@ -63,11 +63,11 @@ export type LinkedAskSnapshot = {
63
63
  state: 'unavailable';
64
64
  done: boolean;
65
65
  };
66
- export interface InboxItem {
66
+ interface InboxItemSnapshot {
67
+ canonicalRoutineId?: string | null;
67
68
  id: string;
68
69
  workspaceId: string;
69
70
  number: number;
70
- kind: 'ask' | 'digest';
71
71
  title: string;
72
72
  description: string;
73
73
  author: string;
@@ -104,6 +104,18 @@ export interface InboxItem {
104
104
  settledAt: string | null;
105
105
  }[];
106
106
  }
107
+ export type InboxItem = InboxItemSnapshot & ({
108
+ kind: 'ask';
109
+ tags: string[];
110
+ recordRefs: Array<{
111
+ repository: string;
112
+ id: string;
113
+ }>;
114
+ } | {
115
+ kind: 'digest';
116
+ tags?: never;
117
+ recordRefs?: never;
118
+ });
107
119
  export interface DigestReadConfirmation {
108
120
  readAt: string;
109
121
  activityId: number;
@@ -116,23 +128,21 @@ export interface ResponseAcceptance {
116
128
  acceptanceOrder?: number;
117
129
  }
118
130
  export interface AnswerableQuestion {
119
- item: {
120
- id: string;
121
- number: number;
122
- revision: number;
123
- title: string;
124
- href: string;
125
- };
126
- origin: {
127
- routine: string;
128
- };
129
- question: {
131
+ itemId: string;
132
+ revision: number;
133
+ title: string;
134
+ inboxUrl: string;
135
+ questionId: string;
136
+ routine: string;
137
+ prompt: string;
138
+ instructions?: string;
139
+ response: ResponseDefinition;
140
+ answerable: boolean;
141
+ tags: string[];
142
+ recordRefs: Array<{
143
+ repository: string;
130
144
  id: string;
131
- prompt: string;
132
- instructions: string | null;
133
- response: ResponseDefinition;
134
- };
135
- recordRefs: string[];
145
+ }>;
136
146
  }
137
147
  export interface AskUpdate {
138
148
  item: InboxItem;
@@ -185,7 +195,7 @@ export interface InboxMember {
185
195
  }): Promise<RecipientAddition>;
186
196
  };
187
197
  questions: {
188
- list(input?: InboxQuestionListInput): Promise<AnswerableQuestion[]>;
198
+ list(input: InboxQuestionListInput): Promise<AnswerableQuestion[]>;
189
199
  answer(input: InboxAnswerInput): Promise<ResponseAcceptance>;
190
200
  searchRecords(input: InboxSearchInput): Promise<RecordSelectionResult>;
191
201
  };
@@ -196,3 +206,4 @@ export interface InboxMember {
196
206
  }): Promise<Response>;
197
207
  };
198
208
  }
209
+ export {};
@@ -0,0 +1,33 @@
1
+ import { type AppValueSchema } from './app-routine-contract.js';
2
+ export type RoutineAccess = {
3
+ readonly repositories?: Readonly<Record<string, 'read' | 'write'>>;
4
+ readonly connections?: readonly string[];
5
+ readonly models?: readonly string[];
6
+ readonly files?: 'read' | 'read-write';
7
+ readonly publish?: readonly ('asks' | 'digests')[];
8
+ };
9
+ export type RoutineContract = {
10
+ id: string;
11
+ title?: string;
12
+ input: AppValueSchema;
13
+ inputDefault?: unknown;
14
+ access: RoutineAccess;
15
+ responses: {
16
+ id: string;
17
+ }[];
18
+ steps: {
19
+ id: string;
20
+ title: string;
21
+ }[];
22
+ result?: AppValueSchema;
23
+ };
24
+ export declare const routineTitle: (value: unknown) => value is string;
25
+ export declare function freezeRoutineMetadata<Value>(value: Value): Value;
26
+ /** Reject values JSON would drop, rewrite, or obtain by invoking authored code. */
27
+ export declare function assertRoutineJson(value: unknown, ancestors?: Set<object>): void;
28
+ /** Inspect property descriptors before reading authored metadata or functions. */
29
+ export declare function assertRoutineFields(value: unknown, allowed?: string[]): asserts value is Record<string, any>;
30
+ export declare function parseRoutineAccess(value: unknown): RoutineAccess;
31
+ /** Inert report/admission grammar shared with authoring; imports no runtime or
32
+ * capability modules and never constructs executable customer functions. */
33
+ export declare function parseRoutineDefinitionContract(value: unknown): RoutineContract;
@@ -0,0 +1,47 @@
1
+ import type { RoutineSourceProvenance } from './routine-source-provenance.js';
2
+ import type { RoutineContract } from './routine-definition-contract.js';
3
+ export declare const ROUTINE_DECLARATION_SCHEMA = "https://schemas.oddington.ai/routine/v1.json";
4
+ export declare const ROUTINE_SOURCE_LIMITS: {
5
+ files: number;
6
+ bytes: number;
7
+ declarationBytes: number;
8
+ };
9
+ export type RoutineDeclaration = {
10
+ $schema: typeof ROUTINE_DECLARATION_SCHEMA;
11
+ access: {
12
+ repositories: Record<string, 'read' | 'write'>;
13
+ connections: string[];
14
+ models: string[];
15
+ files?: 'read' | 'read-write';
16
+ publish: Array<'asks' | 'digests'>;
17
+ };
18
+ runtime: {
19
+ features: Array<'python' | 'documents' | 'browser'>;
20
+ resources: 'standard' | 'large';
21
+ maxDuration: string;
22
+ };
23
+ retry: {
24
+ maxAttempts: number;
25
+ };
26
+ assets: string[];
27
+ };
28
+ export type RoutineDeploymentSource = {
29
+ digest: string;
30
+ declaration: RoutineDeclaration;
31
+ definition?: {
32
+ entry: string;
33
+ contract: RoutineContract;
34
+ };
35
+ files: Array<{
36
+ path: string;
37
+ sha256: string;
38
+ size: number;
39
+ }>;
40
+ provenance?: RoutineSourceProvenance;
41
+ };
42
+ /** An authored definition has one fixed, private execution profile. */
43
+ export declare function routineDefinitionDeclaration(contract: RoutineContract): RoutineDeclaration;
44
+ export declare function routineDefinitionDirectory(entry: string): string;
45
+ export declare const routineAlias: (value: unknown) => value is string;
46
+ export declare function routineAssetPattern(value: unknown): value is string;
47
+ export declare function parseRoutineDeclaration(value: unknown): RoutineDeclaration;
@@ -0,0 +1,6 @@
1
+ export declare const isRoutineSourceDirectory: (value: string) => boolean;
2
+ /** Both the collector and untrusted upload/build admission use this boundary. */
3
+ export declare function eligibleDeploymentPath(path: string): boolean;
4
+ /** Package metadata is admitted only at the root and selected direct child.
5
+ * Inventory parsing has no selection yet; sealing supplies the exact name. */
6
+ export declare function eligibleDeploymentInputPath(path: string, routine?: string): boolean;
@@ -0,0 +1,7 @@
1
+ /** Checkout evidence is descriptive and never selects routine authority. */
2
+ export type RoutineSourceProvenance = {
3
+ branch?: string;
4
+ commit?: string;
5
+ dirty: boolean;
6
+ };
7
+ export declare function parseRoutineSourceProvenance(value: unknown): RoutineSourceProvenance;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oddington/sdk",
3
- "version": "0.1.21",
3
+ "version": "0.1.23",
4
4
  "description": "Oddington routine and response-handler SDK",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "module",