getaiapi 1.0.0-alpha.3 → 1.0.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/README.md CHANGED
@@ -115,6 +115,48 @@ const cutout = await generate({
115
115
  })
116
116
  ```
117
117
 
118
+ ## Async Job Control
119
+
120
+ For long-running jobs (video generation, training), you can submit a job and poll for status separately instead of blocking until completion.
121
+
122
+ ```typescript
123
+ import { submit, poll } from 'getaiapi'
124
+
125
+ // Submit — returns immediately with the provider's task ID
126
+ const job = await submit({
127
+ model: 'veo3.1',
128
+ prompt: 'a timelapse of a flower blooming',
129
+ })
130
+
131
+ console.log(job.id) // provider task ID
132
+ console.log(job.status) // 'pending' | 'processing' | 'completed'
133
+
134
+ // Poll — check status manually (call in a loop, on a timer, etc.)
135
+ let result = await poll(job)
136
+
137
+ while (result.status === 'pending' || result.status === 'processing') {
138
+ await new Promise(r => setTimeout(r, 2000))
139
+ result = await poll(job)
140
+ }
141
+
142
+ if (result.status === 'completed') {
143
+ console.log(result.outputs[0].url)
144
+ }
145
+ ```
146
+
147
+ Synchronous providers (like OpenRouter) return `status: 'completed'` from `submit()` immediately -- check status before polling.
148
+
149
+ `submitAndPoll()` is an alias for `generate()` that makes the blocking behavior explicit:
150
+
151
+ ```typescript
152
+ import { submitAndPoll } from 'getaiapi'
153
+
154
+ const result = await submitAndPoll({
155
+ model: 'flux-schnell',
156
+ prompt: 'a cat in space',
157
+ })
158
+ ```
159
+
118
160
  ## Configuration
119
161
 
120
162
  ### Option 1: Environment Variables
@@ -302,6 +344,40 @@ interface OutputItem {
302
344
  }
303
345
  ```
304
346
 
347
+ ### `submit(request: GenerateRequest): Promise<SubmitResponse>`
348
+
349
+ Submits a job to the provider and returns immediately without waiting for completion. Returns the provider's task ID and enough context to poll later.
350
+
351
+ ```typescript
352
+ interface SubmitResponse {
353
+ id: string // provider's task/request ID
354
+ model: string // canonical model name
355
+ provider: ProviderName // which provider handled it
356
+ endpoint: string // needed for polling
357
+ status: 'pending' | 'processing' | 'completed'
358
+ }
359
+ ```
360
+
361
+ ### `poll(job: SubmitResponse): Promise<PollResponse>`
362
+
363
+ Checks the status of a submitted job once. Returns current status, and includes mapped outputs and metadata when completed.
364
+
365
+ ```typescript
366
+ interface PollResponse {
367
+ id: string
368
+ model: string
369
+ provider: ProviderName
370
+ status: 'completed' | 'failed' | 'processing' | 'pending'
371
+ outputs?: OutputItem[] // populated when completed
372
+ metadata?: GenerateResponse['metadata'] // populated when completed
373
+ error?: string // populated when failed
374
+ }
375
+ ```
376
+
377
+ ### `submitAndPoll(request: GenerateRequest): Promise<GenerateResponse>`
378
+
379
+ Alias for `generate()`. Submits a job and polls until completion. Use this when you want the blocking behavior but want to be explicit about it.
380
+
305
381
  ### `listModels(filters?: ListModelsFilters): ModelEntry[]`
306
382
 
307
383
  Returns all models in the registry. Accepts optional filters:
@@ -30542,11 +30542,11 @@ var registry_default = [
30542
30542
  endpoint: "fal-ai/kling-video/create-voice",
30543
30543
  auth_env: "FAL_KEY",
30544
30544
  param_map: {
30545
- image: "images_data_url"
30545
+ voice_url: "voice_url"
30546
30546
  },
30547
30547
  output_map: {
30548
30548
  type: "text",
30549
- extract_path: "video.url",
30549
+ extract_path: "voice_id",
30550
30550
  content_type: "text/plain"
30551
30551
  }
30552
30552
  }
@@ -70674,6 +70674,356 @@ var registry_default = [
70674
70674
  }
70675
70675
  }
70676
70676
  ]
70677
+ },
70678
+ {
70679
+ canonical_name: "gpt-5.4-pro",
70680
+ aliases: [
70681
+ "gpt-5.4-pro",
70682
+ "openai-gpt-5.4-pro"
70683
+ ],
70684
+ modality: {
70685
+ inputs: ["text"],
70686
+ outputs: ["text"]
70687
+ },
70688
+ providers: [
70689
+ {
70690
+ provider: "openrouter",
70691
+ skill_id: "openrouter-gpt-5.4-pro",
70692
+ endpoint: "openai/gpt-5.4-pro",
70693
+ auth_env: "OPENROUTER_API_KEY",
70694
+ param_map: { prompt: "prompt" },
70695
+ output_map: {
70696
+ type: "text",
70697
+ extract_path: "choices[0].message.content",
70698
+ content_type: "text/plain"
70699
+ }
70700
+ }
70701
+ ]
70702
+ },
70703
+ {
70704
+ canonical_name: "gpt-5.4",
70705
+ aliases: [
70706
+ "gpt-5.4",
70707
+ "openai-gpt-5.4"
70708
+ ],
70709
+ modality: {
70710
+ inputs: ["text"],
70711
+ outputs: ["text"]
70712
+ },
70713
+ providers: [
70714
+ {
70715
+ provider: "openrouter",
70716
+ skill_id: "openrouter-gpt-5.4",
70717
+ endpoint: "openai/gpt-5.4",
70718
+ auth_env: "OPENROUTER_API_KEY",
70719
+ param_map: { prompt: "prompt" },
70720
+ output_map: {
70721
+ type: "text",
70722
+ extract_path: "choices[0].message.content",
70723
+ content_type: "text/plain"
70724
+ }
70725
+ }
70726
+ ]
70727
+ },
70728
+ {
70729
+ canonical_name: "gpt-5.4-mini",
70730
+ aliases: [
70731
+ "gpt-5.4-mini",
70732
+ "openai-gpt-5.4-mini"
70733
+ ],
70734
+ modality: {
70735
+ inputs: ["text"],
70736
+ outputs: ["text"]
70737
+ },
70738
+ providers: [
70739
+ {
70740
+ provider: "openrouter",
70741
+ skill_id: "openrouter-gpt-5.4-mini",
70742
+ endpoint: "openai/gpt-5.4-mini",
70743
+ auth_env: "OPENROUTER_API_KEY",
70744
+ param_map: { prompt: "prompt" },
70745
+ output_map: {
70746
+ type: "text",
70747
+ extract_path: "choices[0].message.content",
70748
+ content_type: "text/plain"
70749
+ }
70750
+ }
70751
+ ]
70752
+ },
70753
+ {
70754
+ canonical_name: "gemini-3.1-pro",
70755
+ aliases: [
70756
+ "gemini-3.1-pro",
70757
+ "google-gemini-3.1-pro"
70758
+ ],
70759
+ modality: {
70760
+ inputs: ["text"],
70761
+ outputs: ["text"]
70762
+ },
70763
+ providers: [
70764
+ {
70765
+ provider: "openrouter",
70766
+ skill_id: "openrouter-gemini-3.1-pro",
70767
+ endpoint: "google/gemini-3.1-pro-preview",
70768
+ auth_env: "OPENROUTER_API_KEY",
70769
+ param_map: { prompt: "prompt" },
70770
+ output_map: {
70771
+ type: "text",
70772
+ extract_path: "choices[0].message.content",
70773
+ content_type: "text/plain"
70774
+ }
70775
+ }
70776
+ ]
70777
+ },
70778
+ {
70779
+ canonical_name: "grok-4.20",
70780
+ aliases: [
70781
+ "grok-4.20",
70782
+ "xai-grok-4.20"
70783
+ ],
70784
+ modality: {
70785
+ inputs: ["text"],
70786
+ outputs: ["text"]
70787
+ },
70788
+ providers: [
70789
+ {
70790
+ provider: "openrouter",
70791
+ skill_id: "openrouter-grok-4.20",
70792
+ endpoint: "x-ai/grok-4.20-beta",
70793
+ auth_env: "OPENROUTER_API_KEY",
70794
+ param_map: { prompt: "prompt" },
70795
+ output_map: {
70796
+ type: "text",
70797
+ extract_path: "choices[0].message.content",
70798
+ content_type: "text/plain"
70799
+ }
70800
+ }
70801
+ ]
70802
+ },
70803
+ {
70804
+ canonical_name: "palmyra-x5",
70805
+ aliases: [
70806
+ "palmyra-x5",
70807
+ "writer-palmyra-x5"
70808
+ ],
70809
+ modality: {
70810
+ inputs: ["text"],
70811
+ outputs: ["text"]
70812
+ },
70813
+ providers: [
70814
+ {
70815
+ provider: "openrouter",
70816
+ skill_id: "openrouter-palmyra-x5",
70817
+ endpoint: "writer/palmyra-x5",
70818
+ auth_env: "OPENROUTER_API_KEY",
70819
+ param_map: { prompt: "prompt" },
70820
+ output_map: {
70821
+ type: "text",
70822
+ extract_path: "choices[0].message.content",
70823
+ content_type: "text/plain"
70824
+ }
70825
+ }
70826
+ ]
70827
+ },
70828
+ {
70829
+ canonical_name: "gpt-5.4-nano",
70830
+ aliases: [
70831
+ "gpt-5.4-nano",
70832
+ "openai-gpt-5.4-nano"
70833
+ ],
70834
+ modality: {
70835
+ inputs: ["text"],
70836
+ outputs: ["text"]
70837
+ },
70838
+ providers: [
70839
+ {
70840
+ provider: "openrouter",
70841
+ skill_id: "openrouter-gpt-5.4-nano",
70842
+ endpoint: "openai/gpt-5.4-nano",
70843
+ auth_env: "OPENROUTER_API_KEY",
70844
+ param_map: { prompt: "prompt" },
70845
+ output_map: {
70846
+ type: "text",
70847
+ extract_path: "choices[0].message.content",
70848
+ content_type: "text/plain"
70849
+ }
70850
+ }
70851
+ ]
70852
+ },
70853
+ {
70854
+ canonical_name: "mimo-v2-pro",
70855
+ aliases: [
70856
+ "mimo-v2-pro",
70857
+ "xiaomi-mimo-v2-pro"
70858
+ ],
70859
+ modality: {
70860
+ inputs: ["text"],
70861
+ outputs: ["text"]
70862
+ },
70863
+ providers: [
70864
+ {
70865
+ provider: "openrouter",
70866
+ skill_id: "openrouter-mimo-v2-pro",
70867
+ endpoint: "xiaomi/mimo-v2-pro",
70868
+ auth_env: "OPENROUTER_API_KEY",
70869
+ param_map: { prompt: "prompt" },
70870
+ output_map: {
70871
+ type: "text",
70872
+ extract_path: "choices[0].message.content",
70873
+ content_type: "text/plain"
70874
+ }
70875
+ }
70876
+ ]
70877
+ },
70878
+ {
70879
+ canonical_name: "mimo-v2-omni",
70880
+ aliases: [
70881
+ "mimo-v2-omni",
70882
+ "xiaomi-mimo-v2-omni"
70883
+ ],
70884
+ modality: {
70885
+ inputs: ["text"],
70886
+ outputs: ["text"]
70887
+ },
70888
+ providers: [
70889
+ {
70890
+ provider: "openrouter",
70891
+ skill_id: "openrouter-mimo-v2-omni",
70892
+ endpoint: "xiaomi/mimo-v2-omni",
70893
+ auth_env: "OPENROUTER_API_KEY",
70894
+ param_map: { prompt: "prompt" },
70895
+ output_map: {
70896
+ type: "text",
70897
+ extract_path: "choices[0].message.content",
70898
+ content_type: "text/plain"
70899
+ }
70900
+ }
70901
+ ]
70902
+ },
70903
+ {
70904
+ canonical_name: "mistral-small-4",
70905
+ aliases: [
70906
+ "mistral-small-4",
70907
+ "mistralai-mistral-small-4"
70908
+ ],
70909
+ modality: {
70910
+ inputs: ["text"],
70911
+ outputs: ["text"]
70912
+ },
70913
+ providers: [
70914
+ {
70915
+ provider: "openrouter",
70916
+ skill_id: "openrouter-mistral-small-4",
70917
+ endpoint: "mistralai/mistral-small-2603",
70918
+ auth_env: "OPENROUTER_API_KEY",
70919
+ param_map: { prompt: "prompt" },
70920
+ output_map: {
70921
+ type: "text",
70922
+ extract_path: "choices[0].message.content",
70923
+ content_type: "text/plain"
70924
+ }
70925
+ }
70926
+ ]
70927
+ },
70928
+ {
70929
+ canonical_name: "minimax-m2.7",
70930
+ aliases: [
70931
+ "minimax-m2.7",
70932
+ "minimax-m27"
70933
+ ],
70934
+ modality: {
70935
+ inputs: ["text"],
70936
+ outputs: ["text"]
70937
+ },
70938
+ providers: [
70939
+ {
70940
+ provider: "openrouter",
70941
+ skill_id: "openrouter-minimax-m2.7",
70942
+ endpoint: "minimax/minimax-m2.7",
70943
+ auth_env: "OPENROUTER_API_KEY",
70944
+ param_map: { prompt: "prompt" },
70945
+ output_map: {
70946
+ type: "text",
70947
+ extract_path: "choices[0].message.content",
70948
+ content_type: "text/plain"
70949
+ }
70950
+ }
70951
+ ]
70952
+ },
70953
+ {
70954
+ canonical_name: "nemotron-3-super",
70955
+ aliases: [
70956
+ "nemotron-3-super",
70957
+ "nvidia-nemotron-3-super"
70958
+ ],
70959
+ modality: {
70960
+ inputs: ["text"],
70961
+ outputs: ["text"]
70962
+ },
70963
+ providers: [
70964
+ {
70965
+ provider: "openrouter",
70966
+ skill_id: "openrouter-nemotron-3-super",
70967
+ endpoint: "nvidia/nemotron-3-super-120b-a12b",
70968
+ auth_env: "OPENROUTER_API_KEY",
70969
+ param_map: { prompt: "prompt" },
70970
+ output_map: {
70971
+ type: "text",
70972
+ extract_path: "choices[0].message.content",
70973
+ content_type: "text/plain"
70974
+ }
70975
+ }
70976
+ ]
70977
+ },
70978
+ {
70979
+ canonical_name: "qwen-3.5-72b",
70980
+ aliases: [
70981
+ "qwen-3.5-72b",
70982
+ "qwen-35-72b"
70983
+ ],
70984
+ modality: {
70985
+ inputs: ["text"],
70986
+ outputs: ["text"]
70987
+ },
70988
+ providers: [
70989
+ {
70990
+ provider: "openrouter",
70991
+ skill_id: "openrouter-qwen-3.5-72b",
70992
+ endpoint: "qwen/qwen3.5-9b",
70993
+ auth_env: "OPENROUTER_API_KEY",
70994
+ param_map: { prompt: "prompt" },
70995
+ output_map: {
70996
+ type: "text",
70997
+ extract_path: "choices[0].message.content",
70998
+ content_type: "text/plain"
70999
+ }
71000
+ }
71001
+ ]
71002
+ },
71003
+ {
71004
+ canonical_name: "glm-5-turbo",
71005
+ aliases: [
71006
+ "glm-5-turbo",
71007
+ "z-ai-glm-5-turbo"
71008
+ ],
71009
+ modality: {
71010
+ inputs: ["text"],
71011
+ outputs: ["text"]
71012
+ },
71013
+ providers: [
71014
+ {
71015
+ provider: "openrouter",
71016
+ skill_id: "openrouter-glm-5-turbo",
71017
+ endpoint: "z-ai/glm-5-turbo",
71018
+ auth_env: "OPENROUTER_API_KEY",
71019
+ param_map: { prompt: "prompt" },
71020
+ output_map: {
71021
+ type: "text",
71022
+ extract_path: "choices[0].message.content",
71023
+ content_type: "text/plain"
71024
+ }
71025
+ }
71026
+ ]
70677
71027
  }
70678
71028
  ];
70679
71029
 
@@ -71935,8 +72285,7 @@ var adapters = {
71935
72285
  "openrouter": openRouterAdapter
71936
72286
  };
71937
72287
  var DEFAULT_TIMEOUT_MS = 12e4;
71938
- async function generate(request) {
71939
- const startTime = Date.now();
72288
+ async function _prepare(request) {
71940
72289
  if (!request.model) throw new ValidationError("model", "model is required");
71941
72290
  const auth = new AuthManager();
71942
72291
  const model = resolveModel(request.model, auth.availableProviders());
@@ -71965,6 +72314,80 @@ async function generate(request) {
71965
72314
  });
71966
72315
  const adapter = adapters[binding.provider];
71967
72316
  const apiKey = auth.getKey(binding.provider);
72317
+ return { binding, adapter, apiKey, finalParams, model };
72318
+ }
72319
+ async function submit(request) {
72320
+ const { binding, adapter, apiKey, finalParams, model } = await _prepare(request);
72321
+ const timeoutMs = request.options?.timeout ?? DEFAULT_TIMEOUT_MS;
72322
+ const submitted = await withRetry(
72323
+ () => adapter.submit(binding.endpoint, finalParams, apiKey),
72324
+ { timeoutMs, provider: binding.provider, model: model.canonical_name }
72325
+ );
72326
+ return {
72327
+ id: submitted.id,
72328
+ model: model.canonical_name,
72329
+ provider: binding.provider,
72330
+ endpoint: binding.endpoint,
72331
+ status: submitted.status === "completed" ? "completed" : submitted.status
72332
+ };
72333
+ }
72334
+ async function poll(job) {
72335
+ const adapter = adapters[job.provider];
72336
+ if (!adapter) {
72337
+ throw new ValidationError("provider", `Unknown provider "${job.provider}"`);
72338
+ }
72339
+ const auth = new AuthManager();
72340
+ const apiKey = auth.getKey(job.provider);
72341
+ const result = await adapter.poll(job.id, apiKey, job.endpoint);
72342
+ if (result.status === "completed") {
72343
+ const model = resolveModel(job.model, auth.availableProviders());
72344
+ const binding = model.providers.find((p) => p.provider === job.provider);
72345
+ if (!binding) {
72346
+ throw new ProviderError(job.provider, job.model, 0, "Could not resolve provider binding for output mapping");
72347
+ }
72348
+ const outputs = mapOutput(result.output, binding.output_map);
72349
+ const rawOutput = typeof result.output === "object" && result.output !== null ? result.output : void 0;
72350
+ const metadata = {
72351
+ seed: rawOutput?.seed,
72352
+ safety_flagged: rawOutput ? Array.isArray(rawOutput.has_nsfw_concepts) ? rawOutput.has_nsfw_concepts.some((v) => v) : void 0 : void 0
72353
+ };
72354
+ if (rawOutput?.usage) {
72355
+ const usage = rawOutput.usage;
72356
+ metadata.tokens = usage.total_tokens;
72357
+ metadata.prompt_tokens = usage.prompt_tokens;
72358
+ metadata.completion_tokens = usage.completion_tokens;
72359
+ }
72360
+ return {
72361
+ id: job.id,
72362
+ model: job.model,
72363
+ provider: job.provider,
72364
+ status: "completed",
72365
+ outputs,
72366
+ metadata
72367
+ };
72368
+ }
72369
+ if (result.status === "failed") {
72370
+ return {
72371
+ id: job.id,
72372
+ model: job.model,
72373
+ provider: job.provider,
72374
+ status: "failed",
72375
+ error: result.error || "Generation failed"
72376
+ };
72377
+ }
72378
+ return {
72379
+ id: job.id,
72380
+ model: job.model,
72381
+ provider: job.provider,
72382
+ status: result.status
72383
+ };
72384
+ }
72385
+ async function submitAndPoll(request) {
72386
+ return generate(request);
72387
+ }
72388
+ async function generate(request) {
72389
+ const startTime = Date.now();
72390
+ const { binding, adapter, apiKey, finalParams, model } = await _prepare(request);
71968
72391
  const timeoutMs = request.options?.timeout ?? DEFAULT_TIMEOUT_MS;
71969
72392
  const submitted = await withRetry(
71970
72393
  () => adapter.submit(binding.endpoint, finalParams, apiKey),
@@ -72061,8 +72484,11 @@ export {
72061
72484
  uploadAsset,
72062
72485
  presignAsset,
72063
72486
  deleteAsset,
72487
+ submit,
72488
+ poll,
72489
+ submitAndPoll,
72064
72490
  generate,
72065
72491
  listModels,
72066
72492
  deriveCategory
72067
72493
  };
72068
- //# sourceMappingURL=chunk-HNBZJY7Z.js.map
72494
+ //# sourceMappingURL=chunk-TB6M4OFF.js.map