@aifight/aifight 0.1.0-alpha.1 → 0.1.0-alpha.3

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.mjs CHANGED
@@ -104,4 +104,4 @@ ${vs}`:vs;if(c=a(l,y),c.length<=n)return c}return c=a(l,""),c.length<=n||(c=a(""
104
104
  `)}function nb(t){switch(t){case"texas_holdem":return["Phase:","Hand ","Your hand:","Board:","Your chips:","Pot:"];case"liars_dice":return["Phase:","Round ","Your dice:","Current bid:"];case"coup":return["Phase:","Your unrevealed cards:","Your coins:","Pending action:"]}}var jt=class extends Error{provider;cause;constructor(e,r,n){super(r),this.provider=e,this.cause=n}},ut=class extends jt{name="DirectModelNetworkError";kind="direct_model_network";constructor(e,r,n){super(e,r,n)}},Me=class extends jt{name="DirectModelHttpError";kind="direct_model_http";status;bodySnippet;constructor(e,r,n,s,o){super(e,n,o),this.status=r,this.bodySnippet=s}},be=class extends jt{name="DirectModelAbortedError";kind="direct_model_aborted";constructor(e,r,n){super(e,r,n)}},we=class extends jt{name="DirectModelInvalidResponseError";kind="direct_model_invalid_response";responseSnippet;constructor(e,r,n,s){super(e,r,s),this.responseSnippet=n}},J=class extends jt{name="DirectModelUnsupportedError";kind="direct_model_unsupported";field;constructor(e,r,n){super(e,n),this.field=r}},Md=2048,Id="[REDACTED]";function fn(t,e){let r=t;for(let n of e){if(!n)continue;let s=r.indexOf(n);for(;s>=0;)r=r.slice(0,s)+Id+r.slice(s+n.length),s=r.indexOf(n,s+Id.length)}return r}function sb(t,e=Md){if(e<=0)return"";if(t.length<=e)return t;let r=e,n="";for(let s=0;s<8;s++){let i=`...[truncated ${t.length-r} chars]`,a=Math.max(0,e-i.length);if(i===n&&a===r)break;n=i,r=a}return e<n.length?n.slice(0,e):t.slice(0,r)+n}function dt(t,e){if(t===void 0||t==="")return;let r=fn(t,e);return sb(r,Md)}var Ee="anthropic",ob="https://api.anthropic.com",ib="2023-06-01";function Dd(t){if(!t.apiKey)throw new J(Ee,"apiKey","apiKey must be a non-empty string");if(!t.model)throw new J(Ee,"model","model must be a non-empty string");let e=t.apiKey,r=t.model,n=(t.baseURL??ob).replace(/\/+$/,""),s=t.anthropicVersion??ib,o=t.fetchImpl??globalThis.fetch;if(typeof o!="function")throw new J(Ee,"fetchImpl","fetch is unavailable; pass fetchImpl explicitly");let i=`${n}/v1/messages`,a=[e];return{provider:Ee,model:r,generate:async l=>{if(!Number.isFinite(l.maxTokens)||l.maxTokens<=0)throw new J(Ee,"maxTokens","maxTokens must be a positive integer");let u=l.signal;if(u?.aborted)throw new be(Ee,"request aborted before send",u.reason);let d={model:r,system:l.systemPrompt,messages:[{role:"user",content:l.userPrompt}],max_tokens:l.maxTokens};l.temperature!==void 0&&(d.temperature=l.temperature);let f={"x-api-key":e,"anthropic-version":s,"content-type":"application/json"},p=performance.now(),h;try{h=await o(i,{method:"POST",headers:f,body:JSON.stringify(d),signal:u})}catch(v){if(ab(v))throw new be(Ee,"request aborted",v);let D=fn(cb(v),a);throw new ut(Ee,`fetch failed: ${D}`,v)}let m=Math.max(0,performance.now()-p);if(!h.ok){let v=await Ld(h),D=dt(v,a);throw new Me(Ee,h.status,`Anthropic returned HTTP ${h.status}`,D,h)}let y=await Ld(h),g;try{g=JSON.parse(y)}catch(v){throw new we(Ee,"response body is not valid JSON",dt(y,a),v)}let b=lb(g);if(b===null)throw new we(Ee,"response missing content[0].text or content[0].type !== 'text'",dt(y,a));let{inputTokens:E,outputTokens:S}=ub(g);return{text:b,inputTokens:E,outputTokens:S,latencyMs:m,raw:g}}}}function ab(t){if(t===null||typeof t!="object")return!1;let e=t;return e.name==="AbortError"||e.code==="ABORT_ERR"||e.code===20}function cb(t){if(t instanceof Error)return t.message;if(typeof t=="string")return t;try{return String(t)}catch{return"unknown"}}async function Ld(t){try{return await t.text()}catch{return""}}function lb(t){if(!bs(t))return null;let e=t.content;if(!Array.isArray(e)||e.length===0)return null;let r=e[0];if(!bs(r)||r.type!=="text")return null;let n=r.text;return typeof n!="string"?null:n}function ub(t){if(!bs(t))return{};let e=t.usage;if(!bs(e))return{};let r=e.input_tokens,n=e.output_tokens;return{inputTokens:typeof r=="number"?r:void 0,outputTokens:typeof n=="number"?n:void 0}}function bs(t){return typeof t=="object"&&t!==null}var Se="openai",db="https://api.openai.com/v1";function qd(t){if(!t.apiKey)throw new J(Se,"apiKey","apiKey must be a non-empty string");if(!t.model)throw new J(Se,"model","model must be a non-empty string");let e=t.apiKey,r=t.model,n=(t.baseURL??db).replace(/\/+$/,""),s=t.organization,o=t.fetchImpl??globalThis.fetch;if(typeof o!="function")throw new J(Se,"fetchImpl","fetch is unavailable; pass fetchImpl explicitly");let i=`${n}/chat/completions`,a=[e];return{provider:Se,model:r,generate:async l=>{if(!Number.isFinite(l.maxTokens)||l.maxTokens<=0)throw new J(Se,"maxTokens","maxTokens must be a positive integer");let u=l.signal;if(u?.aborted)throw new be(Se,"request aborted before send",u.reason);let d={model:r,messages:[{role:"system",content:l.systemPrompt},{role:"user",content:l.userPrompt}],max_completion_tokens:l.maxTokens};l.temperature!==void 0&&(d.temperature=l.temperature);let f={Authorization:`Bearer ${e}`,"content-type":"application/json"};s&&(f["OpenAI-Organization"]=s);let p=performance.now(),h;try{h=await o(i,{method:"POST",headers:f,body:JSON.stringify(d),signal:u})}catch(v){if(fb(v))throw new be(Se,"request aborted",v);let D=fn(hb(v),a);throw new ut(Se,`fetch failed: ${D}`,v)}let m=Math.max(0,performance.now()-p);if(!h.ok){let v=await jd(h),D=dt(v,a);throw new Me(Se,h.status,`OpenAI returned HTTP ${h.status}`,D,h)}let y=await jd(h),g;try{g=JSON.parse(y)}catch(v){throw new we(Se,"response body is not valid JSON",dt(y,a),v)}let b=pb(g);if(b===null)throw new we(Se,"response missing choices[0].message.content (or content is not a string)",dt(y,a));let{inputTokens:E,outputTokens:S}=mb(g);return{text:b,inputTokens:E,outputTokens:S,latencyMs:m,raw:g}}}}function fb(t){if(t===null||typeof t!="object")return!1;let e=t;return e.name==="AbortError"||e.code==="ABORT_ERR"||e.code===20}function hb(t){if(t instanceof Error)return t.message;if(typeof t=="string")return t;try{return String(t)}catch{return"unknown"}}async function jd(t){try{return await t.text()}catch{return""}}function pb(t){if(!hn(t))return null;let e=t.choices;if(!Array.isArray(e)||e.length===0)return null;let r=e[0];if(!hn(r))return null;let n=r.message;if(!hn(n))return null;let s=n.content;return typeof s!="string"?null:s}function mb(t){if(!hn(t))return{};let e=t.usage;if(!hn(e))return{};let r=e.prompt_tokens,n=e.completion_tokens;return{inputTokens:typeof r=="number"?r:void 0,outputTokens:typeof n=="number"?n:void 0}}function hn(t){return typeof t=="object"&&t!==null}var W=class extends Error{name="DecisionProviderError";kind;cause;constructor(e,r,n){super(r),this.kind=e,this.cause=n}},yb=2,gb=500;function _b(t){let e=t.retryBudget??yb,r=t.parseRetryHintCharCap??gb;if(!Number.isFinite(e)||!Number.isInteger(e)||e<0)throw new W("fatal_caller_bug",`retryBudget must be a non-negative integer (got ${String(t.retryBudget)})`);if(!Number.isFinite(r)||!Number.isInteger(r)||r<=0)throw new W("fatal_caller_bug",`parseRetryHintCharCap must be a positive integer (got ${String(t.parseRetryHintCharCap)})`);let n=new Map;function s(c,l){let u=`${c}:${l}`,d=n.get(u);if(d)return d;let f;try{f=t.apiKeyResolver(c,l)}catch(h){throw new W("fatal_unsupported",`apiKeyResolver threw for ${c}:${l}`,h)}if(typeof f!="string"||!f)throw new W("fatal_unsupported",`apiKeyResolver returned empty key for ${c}:${l}`);let p;try{c==="anthropic"?p=(t.clientFactory?.anthropic??Dd)({apiKey:f,model:l,fetchImpl:t.fetchImpl}):p=(t.clientFactory?.openai??qd)({apiKey:f,model:l,fetchImpl:t.fetchImpl})}catch(h){throw h instanceof J?new W("fatal_unsupported",h.message,h):new W("fatal_caller_bug",`clientFactory.${c} threw unexpected error`,h)}return n.set(u,p),p}async function o(c){if(typeof c.decisionBudgetMs!="number"||!Number.isFinite(c.decisionBudgetMs)||c.decisionBudgetMs<=0)throw new W("fatal_caller_bug","decisionBudgetMs must be a positive finite number");if(!bb(c.game))throw new W("fatal_caller_bug",`unsupported game: ${String(c.game)}`);let l=new AbortController,u=setTimeout(()=>{l.abort()},c.decisionBudgetMs);try{return await i(c,l.signal)}finally{clearTimeout(u)}}async function i(c,l){if(l.aborted)throw new W("fatal_aborted","decisionBudgetMs already elapsed before decide started");let u=s(c.strategyProfile.provider,c.strategyProfile.model),d=Cd(c),f,p,h=0,m;for(let g=0;g<=e;g++){if(l.aborted)throw new W("fatal_aborted","decisionBudgetMs elapsed mid-attempt");let b=g===0?d.userPrompt:d.userPrompt+`
105
105
 
106
106
  `+Tb(g,f,p,r),E;try{E=await u.generate({systemPrompt:d.systemPrompt,userPrompt:b,temperature:c.strategyProfile.temperature,maxTokens:c.strategyProfile.maxTokens,signal:l})}catch(v){if($b(v))throw kb(v);if(Sb(v)){f=`direct_model_${v.kind}`,p=Pb(v);continue}throw new W("fatal_caller_bug","client.generate threw unexpected error",v)}h+=E.latencyMs,m=E;let S=wb(c.game,E.text,c.legalActions,r);if(S.kind==="ok")return vb(c,S,E,h,g);f=`parse_${S.reason}`,p=S.rawSnippet}let y;try{y=Eb(c)}catch(g){throw new W("fatal_caller_bug",g instanceof Error?`fallback dispatch failed: ${g.message}`:"fallback dispatch failed",g)}return{action:y.type,params:Fd(y.data),summary:`(fallback: ${f??"unknown"})`,providerMetadata:{provider:c.strategyProfile.provider,model:c.strategyProfile.model,inputTokens:m?.inputTokens,outputTokens:m?.outputTokens,latencyMs:h,retries:e,fallback:!0}}}async function a(){if(!t.healthCheckProfile)return!1;try{return await s(t.healthCheckProfile.provider,t.healthCheckProfile.model).generate({systemPrompt:"ping",userPrompt:"respond with the word OK",maxTokens:10}),!0}catch{return!1}}return{name:t.name,decide:o,healthCheck:a}}function vb(t,e,r,n,s){let o=Fd(e.action.data),i={action:e.action.type,providerMetadata:{provider:t.strategyProfile.provider,model:t.strategyProfile.model,inputTokens:r.inputTokens,outputTokens:r.outputTokens,latencyMs:n,retries:s,fallback:!1}};return o!==void 0&&e.summary!==void 0?{...i,params:o,summary:e.summary}:o!==void 0?{...i,params:o}:e.summary!==void 0?{...i,summary:e.summary}:i}function bb(t){return t==="texas_holdem"||t==="liars_dice"||t==="coup"}function wb(t,e,r,n){switch(t){case"texas_holdem":return Sd(e,r,n);case"liars_dice":return $d(e,r,n);case"coup":return Pd(e,r,n)}}function Eb(t){switch(t.game){case"texas_holdem":return bd({publicState:t.publicState,legalActions:t.legalActions,yourPlayerId:t.playerId});case"liars_dice":return wd({publicState:t.publicState,legalActions:t.legalActions,yourPlayerId:t.playerId});case"coup":return Ed({publicState:t.publicState,legalActions:t.legalActions,yourPlayerId:t.playerId})}}function Fd(t){if(t!=null&&typeof t=="object"&&!Array.isArray(t))return t}function Sb(t){return t instanceof we||t instanceof ut?!0:t instanceof Me?t.status===429||t.status>=500:!1}function $b(t){return t instanceof be||t instanceof J?!0:t instanceof Me?!(t.status===429||t.status>=500):!1}function kb(t){return t instanceof be?new W("fatal_aborted",t.message,t):t instanceof J?new W("fatal_unsupported",t.message,t):new W("fatal_http",t.message,t)}function Pb(t){if(t instanceof Me)return t.bodySnippet;if(t instanceof we)return t.responseSnippet}function Tb(t,e,r,n){let s=[];if(s.push(`Retry attempt ${t}: previous output failed validation.`),e&&s.push(`Reason: ${e}.`),r!==void 0&&r!==""){let o=r.length>n?r.slice(0,n):r;s.push(`Previous output (truncated to ${n} chars): ${o}`)}return s.push("Please retry. Respond with a single JSON object exactly matching the schema in the system prompt."),s.join(`
107
- `)}var Rb="0.1.0-alpha.1",TS="v1.0.0";function xS(){let t=Ft(),e=ft(),r=Es();return{ok:!0,runtimeVersion:Rb,schemaCount:e.size,messageTypeCount:r.length,schemasRoot:t}}export{tn as AIFIGHT_CRYPTO_V1_PREFIX,en as AIFIGHT_KEYCHAIN_V1_PREFIX,nu as AIFIGHT_RUNTIME_SERVICE,Ae as CredentialsCorruptError,ue as CredentialsCryptoError,or as CredentialsError,ir as CredentialsKeychainUnavailableError,W as DecisionProviderError,TS as PROTOCOL_VERSION,Rb as RUNTIME_VERSION,_r as ReconnectStoppedError,sr as RegisterError,Xr as RegisterHttpError,St as RegisterNetworkError,$t as RegisterSchemaError,rt as StoreError,lr as StoreMigrationError,cr as StoreOpenError,nt as StoreQueryError,Ke as WSAbortedError,Y as WSClientError,Ct as WSClosedError,it as WSConnectError,at as WSHandshakeError,Ie as WSOutboundSchemaError,At as WSProtocolVersionError,se as WSSchemaError,ze as WSUnknownMessageError,ct as WSWelcomeInvalidError,Nt as WSWelcomeTimeoutError,_b as createDirectModelProvider,rv as createReconnectingWSClient,Xi as createWSClient,f_ as decryptFromStorage,h_ as deleteFromStorage,l_ as encryptForStorage,Zr as ensureRuntimeHome,Ft as findSchemasRoot,ou as getCredentialsBackend,_i as getDefaultDbPath,Qr as getRuntimeHome,xS as hello,iu as isKeychainAvailable,ft as loadAllSchemas,Ss as loadRestSchema,Jd as loadSchema,Es as messageTypes,Xg as openDatabase,Hg as registerAgent};
107
+ `)}var Rb="0.1.0-alpha.3",TS="v1.0.0";function xS(){let t=Ft(),e=ft(),r=Es();return{ok:!0,runtimeVersion:Rb,schemaCount:e.size,messageTypeCount:r.length,schemasRoot:t}}export{tn as AIFIGHT_CRYPTO_V1_PREFIX,en as AIFIGHT_KEYCHAIN_V1_PREFIX,nu as AIFIGHT_RUNTIME_SERVICE,Ae as CredentialsCorruptError,ue as CredentialsCryptoError,or as CredentialsError,ir as CredentialsKeychainUnavailableError,W as DecisionProviderError,TS as PROTOCOL_VERSION,Rb as RUNTIME_VERSION,_r as ReconnectStoppedError,sr as RegisterError,Xr as RegisterHttpError,St as RegisterNetworkError,$t as RegisterSchemaError,rt as StoreError,lr as StoreMigrationError,cr as StoreOpenError,nt as StoreQueryError,Ke as WSAbortedError,Y as WSClientError,Ct as WSClosedError,it as WSConnectError,at as WSHandshakeError,Ie as WSOutboundSchemaError,At as WSProtocolVersionError,se as WSSchemaError,ze as WSUnknownMessageError,ct as WSWelcomeInvalidError,Nt as WSWelcomeTimeoutError,_b as createDirectModelProvider,rv as createReconnectingWSClient,Xi as createWSClient,f_ as decryptFromStorage,h_ as deleteFromStorage,l_ as encryptForStorage,Zr as ensureRuntimeHome,Ft as findSchemasRoot,ou as getCredentialsBackend,_i as getDefaultDbPath,Qr as getRuntimeHome,xS as hello,iu as isKeychainAvailable,ft as loadAllSchemas,Ss as loadRestSchema,Jd as loadSchema,Es as messageTypes,Xg as openDatabase,Hg as registerAgent};
@@ -1,2 +1,7 @@
1
+ import { type BridgeRuntimeType } from "../../bridge/config";
1
2
  import type { HandlerArgs, HandlerEnv } from "../shared";
2
3
  export declare function runBridgeRegister(args: HandlerArgs, env: HandlerEnv): Promise<number>;
4
+ export declare function detectRuntimeTypeForApprovedSetup(env: HandlerEnv): Promise<{
5
+ readonly runtimeType?: BridgeRuntimeType;
6
+ readonly detail: string;
7
+ }>;
@@ -1,3 +1,5 @@
1
1
  import type { HandlerArgs, HandlerEnv } from "../shared";
2
2
  export declare function runBridgeService(args: HandlerArgs, env: HandlerEnv): Promise<number>;
3
- export declare function offerBridgeServiceInstall(env: HandlerEnv): Promise<"installed" | "declined" | "unavailable">;
3
+ export declare function offerBridgeServiceInstall(env: HandlerEnv, opts?: {
4
+ readonly approvedLocalSetup?: boolean;
5
+ }): Promise<"installed" | "declined" | "unavailable">;
@@ -10,7 +10,9 @@ export declare function execCommand(command: string, args: readonly string[]): P
10
10
  export declare function writeExecResult(env: HandlerEnv, label: string, result: ExecResult): void;
11
11
  export declare function promptYesNo(env: HandlerEnv, question: string): Promise<boolean>;
12
12
  export declare function promptYesNoDefaultNo(env: HandlerEnv, question: string): Promise<boolean>;
13
- export declare function offerGatewayRestart(env: HandlerEnv, runtime: RuntimeName, reason: string): Promise<boolean>;
13
+ export declare function offerGatewayRestart(env: HandlerEnv, runtime: RuntimeName, reason: string, opts?: {
14
+ readonly approvedLocalSetup?: boolean;
15
+ }): Promise<boolean>;
14
16
  export declare function systemdUnitIsActive(result: ExecResult): boolean;
15
17
  export declare function hermesRestartUnavailable(result: ExecResult): boolean;
16
18
  export {};
@@ -2,6 +2,7 @@ import type { BridgeRuntimeType } from "../../bridge/config";
2
2
  import type { HandlerEnv } from "../shared";
3
3
  export interface RuntimeSetupResult {
4
4
  readonly runtimeLocalToken?: string;
5
+ readonly blockedReason?: string;
5
6
  }
6
7
  interface RuntimeSetupOptions {
7
8
  readonly env: HandlerEnv;
@@ -10,9 +11,10 @@ interface RuntimeSetupOptions {
10
11
  readonly runtimeLocalToken?: string;
11
12
  readonly runtimeModel?: string;
12
13
  readonly jsonMode: boolean;
14
+ readonly approvedLocalSetup?: boolean;
13
15
  }
14
- type ProbeStatus = "ready" | "endpoint_reachable" | "disabled" | "auth_failed" | "unreachable";
15
- interface ProbeResult {
16
+ export type ProbeStatus = "ready" | "endpoint_reachable" | "disabled" | "auth_failed" | "unreachable";
17
+ export interface ProbeResult {
16
18
  readonly status: ProbeStatus;
17
19
  readonly detail: string;
18
20
  }
@@ -18,7 +18,7 @@ export { createDirectModelProvider, DecisionProviderError, } from "./decision/pr
18
18
  export type { DecisionProvider, DirectModelProviderOptions, DirectModelProviderName, DecisionProviderErrorKind, } from "./decision/provider";
19
19
  export type { DecisionRequest, DecisionResponse, DecisionResponseProviderMetadata, StrategyProfile, GameSpecificProfile, GameType, GameRules, LegalAction, } from "./decision/types";
20
20
  export type { ParseResult, ParseInvalidReason, } from "./decision/parser-types";
21
- export declare const RUNTIME_VERSION = "0.1.0-alpha.1";
21
+ export declare const RUNTIME_VERSION = "0.1.0-alpha.3";
22
22
  export declare const PROTOCOL_VERSION = "v1.0.0";
23
23
  export interface HelloResult {
24
24
  ok: true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aifight/aifight",
3
- "version": "0.1.0-alpha.1",
3
+ "version": "0.1.0-alpha.3",
4
4
  "description": "AIFight CLI — local outbound bridge that connects AIFight to user-selected Agent runtimes.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.mjs",