@tryvira/opencode 0.1.0 → 0.1.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.
Files changed (2) hide show
  1. package/dist/index.js +55 -5
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -97,8 +97,11 @@ var ViraClient = class {
97
97
  };
98
98
  if (request.body) headers["content-type"] = "application/json";
99
99
  if (this.apiKey) {
100
- headers.authorization = `Bearer ${this.apiKey}`;
101
- headers["x-vira-api-key"] = this.apiKey;
100
+ if (this.apiKey.startsWith("vira_live_")) headers["x-vira-api-key"] = this.apiKey;
101
+ else {
102
+ headers.authorization = `Bearer ${this.apiKey}`;
103
+ headers["x-vira-api-key"] = this.apiKey;
104
+ }
102
105
  }
103
106
  if (options.idempotencyKey)
104
107
  headers["idempotency-key"] = options.idempotencyKey;
@@ -1242,7 +1245,7 @@ var ViraOpenCodeActionError = class extends Error {
1242
1245
  this.decision = decision;
1243
1246
  }
1244
1247
  };
1245
- var index_default = Plugin.define({
1248
+ var v2Plugin = Plugin.define({
1246
1249
  id: "vira",
1247
1250
  async setup(rawContext) {
1248
1251
  const ctx = rawContext;
@@ -1267,7 +1270,7 @@ var index_default = Plugin.define({
1267
1270
  } catch (error) {
1268
1271
  return { decision: "ERROR", reasonCode: error instanceof Error ? error.message : "RUNTIME_ACTION_AUTHORIZATION_FAILED" };
1269
1272
  }
1270
- }), connect: { ...scope, name: "OpenCode", systemType: "agent", adapterType: "opencode", adapterVersion: options.hostVersion ?? ctx.app?.version ?? "unknown", idempotencyKey: "opencode:vira:connect" } });
1273
+ }), ...(options.aiSystemId ?? env("VIRA_AI_SYSTEM_ID")) && (options.connectionId ?? env("VIRA_CONNECTION_ID")) ? {} : { connect: { ...scope, name: "OpenCode", systemType: "agent", adapterType: "custom-node", adapterVersion: options.hostVersion ?? ctx.app?.version ?? "unknown", idempotencyKey: "opencode:vira:connect" } } });
1271
1274
  const registrations = [];
1272
1275
  const sessionIdentity = (event) => ({ ...scope, hostName: options.hostName ?? "opencode", hostVersion: options.hostVersion ?? ctx.app?.version ?? "unknown", aiSystemId: required2(options.aiSystemId ?? env("VIRA_AI_SYSTEM_ID"), "VIRA_HOST_AI_SYSTEM_REQUIRED"), connectionId: required2(options.connectionId ?? env("VIRA_CONNECTION_ID"), "VIRA_HOST_CONNECTION_REQUIRED"), conversationId: required2(event.sessionID ?? event.conversationId, "VIRA_HOST_SESSION_REQUIRED") });
1273
1276
  registrations.push(await ctx.session.hook("context", async (event) => {
@@ -1289,7 +1292,11 @@ var index_default = Plugin.define({
1289
1292
  }));
1290
1293
  registrations.push(await ctx.tool.hook("execute.after", async (event) => {
1291
1294
  const identity = sessionIdentity(event);
1292
- await runtime.afterTool({ ...identity, requestId: text(event.messageID ?? event.requestId) || `opencode:${Date.now()}`, callId: required2(event.callID ?? event.id, "VIRA_HOST_TOOL_CALL_REQUIRED"), toolName: required2(event.tool ?? event.name, "VIRA_HOST_TOOL_NAME_REQUIRED"), args: asRecord(event.input ?? event.args), ok: event.status === "completed", result: event.result, errorCode: text(asRecord(event.error).code), traceId: text(event.traceID), turnId: text(event.turnID) });
1295
+ try {
1296
+ await runtime.afterTool({ ...identity, requestId: text(event.messageID ?? event.requestId) || `opencode:${Date.now()}`, callId: required2(event.callID ?? event.id, "VIRA_HOST_TOOL_CALL_REQUIRED"), toolName: required2(event.tool ?? event.name, "VIRA_HOST_TOOL_NAME_REQUIRED"), args: asRecord(event.input ?? event.args), ok: event.status === "completed", result: event.result, errorCode: text(asRecord(event.error).code), traceId: text(event.traceID), turnId: text(event.turnID) });
1297
+ } catch (error) {
1298
+ if (mode === "enforce") throw error;
1299
+ }
1293
1300
  }));
1294
1301
  registrations.push(await ctx.session.hook("fork", (event) => runtime.endSession({ ...scope, hostName: "opencode", hostVersion: ctx.app?.version ?? "unknown", aiSystemId: options.aiSystemId ?? "", connectionId: options.connectionId ?? "", conversationId: text(event.sessionID) })));
1295
1302
  return async () => {
@@ -1298,6 +1305,49 @@ var index_default = Plugin.define({
1298
1305
  };
1299
1306
  }
1300
1307
  });
1308
+ var v1Runtime = () => {
1309
+ const env = (name) => typeof process !== "undefined" ? process.env[name] : void 0;
1310
+ const mode = env("VIRA_HOST_MODE") ?? "off";
1311
+ if (mode === "off") return null;
1312
+ const scope = { organizationId: required2(env("VIRA_ORGANIZATION_ID"), "VIRA_HOST_ORGANIZATION_REQUIRED"), projectId: required2(env("VIRA_PROJECT_ID"), "VIRA_HOST_PROJECT_REQUIRED"), environmentId: required2(env("VIRA_ENVIRONMENT_ID"), "VIRA_HOST_ENVIRONMENT_REQUIRED") };
1313
+ const client = new ViraClient({ baseUrl: required2(env("VIRA_CONTROL_URL") ?? env("VIRA_API_URL"), "VIRA_HOST_API_URL_REQUIRED"), apiKey: env("VIRA_API_KEY") });
1314
+ return { mode, scope, client, runtime: createViraHostRuntime(client, { mode, capabilities: { canObserveModel: true, canInjectContext: true, canInterceptToolBefore: true, canInspectToolAfter: true, canPreventSideEffect: mode === "enforce", canInterceptResponseBeforeDisplay: false }, authorizeAction: async () => ({ decision: "BLOCK", reasonCode: "VIRA_V1_ACTION_AUTHORIZER_UNAVAILABLE" }) }) };
1315
+ };
1316
+ var index_default = { ...v2Plugin, async server() {
1317
+ const configured = v1Runtime();
1318
+ if (!configured) return {};
1319
+ const { mode, scope, runtime } = configured;
1320
+ const env = (name) => typeof process !== "undefined" ? process.env[name] : void 0;
1321
+ const prompts = /* @__PURE__ */ new Map();
1322
+ const identity = (input) => ({ ...scope, hostName: "opencode", hostVersion: "1.19.5", aiSystemId: required2(env("VIRA_AI_SYSTEM_ID"), "VIRA_HOST_AI_SYSTEM_REQUIRED"), connectionId: required2(env("VIRA_CONNECTION_ID"), "VIRA_HOST_CONNECTION_REQUIRED"), conversationId: required2(input.sessionID ?? input.conversationId ?? input.id, "VIRA_HOST_SESSION_REQUIRED") });
1323
+ const partsText = (value) => Array.isArray(value) ? value.map((part) => text(asRecord(part).text)).filter(Boolean).join("\n") : "";
1324
+ return {
1325
+ "chat.message": async (input, output) => {
1326
+ const sessionId = text(input.sessionID ?? input.conversationId ?? input.id);
1327
+ const message = asRecord(output.message ?? input.message);
1328
+ const prompt = text(message.text ?? message.content) || partsText(output.parts ?? input.parts);
1329
+ if (sessionId && prompt.trim()) prompts.set(sessionId, prompt);
1330
+ },
1331
+ "chat.params": async (input, output) => {
1332
+ const sessionId = text(input.sessionID ?? input.conversationId ?? input.id);
1333
+ const prompt = text(input.prompt ?? asRecord(input.message).text ?? input.input ?? output.prompt) || prompts.get(sessionId) || "";
1334
+ if (!prompt.trim()) return;
1335
+ const result = await runtime.beforeModel({ ...identity(input), requestId: text(input.messageID ?? input.requestId) || `opencode:${Date.now()}`, input: prompt, traceId: text(input.traceID), turnId: text(input.turnID) });
1336
+ if (result.status === "applied" && result.projection) output.system = [...Array.isArray(output.system) ? output.system : [], result.projection];
1337
+ },
1338
+ "tool.execute.before": async (input, output) => {
1339
+ const decision = await runtime.beforeTool({ ...identity(input), requestId: text(input.messageID ?? input.requestId) || `opencode:${Date.now()}`, callId: required2(input.callID ?? input.id, "VIRA_HOST_TOOL_CALL_REQUIRED"), toolName: required2(input.tool ?? input.name, "VIRA_HOST_TOOL_NAME_REQUIRED"), args: asRecord(output.args ?? input.args ?? input.input), traceId: text(input.traceID), turnId: text(input.turnID) });
1340
+ if (mode === "enforce" && decision.decision !== "ALLOW") throw new ViraOpenCodeActionError(decision.decision, text(decision.reasonCode) || "VIRA_ACTION_NOT_ALLOWED");
1341
+ },
1342
+ "tool.execute.after": async (input, output) => {
1343
+ try {
1344
+ await runtime.afterTool({ ...identity(input), requestId: text(input.messageID ?? input.requestId) || `opencode:${Date.now()}`, callId: required2(input.callID ?? input.id, "VIRA_HOST_TOOL_CALL_REQUIRED"), toolName: required2(input.tool ?? input.name, "VIRA_HOST_TOOL_NAME_REQUIRED"), args: asRecord(input.args ?? input.input), ok: true, result: output.output, errorCode: text(asRecord(output.error).code), traceId: text(input.traceID), turnId: text(input.turnID) });
1345
+ } catch (error) {
1346
+ if (mode === "enforce") throw error;
1347
+ }
1348
+ }
1349
+ };
1350
+ } };
1301
1351
  export {
1302
1352
  ViraOpenCodeActionError,
1303
1353
  index_default as default
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@tryvira/opencode",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "OpenCode V2 host lifecycle integration for Vira",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "exports": {".": "./dist/index.js"},
8
8
  "files": ["dist", "README.md"],
9
9
  "scripts": {"build": "node ../../scripts/build-opencode-plugin.mjs", "pack:check": "npm run build && npm pack --dry-run"},
10
- "dependencies": {"@tryvira/sdk": "0.1.46"},
10
+ "dependencies": {"@tryvira/sdk": "0.1.47"},
11
11
  "peerDependencies": {"effect": "^4.0.0"},
12
12
  "engines": {"node": ">=20"},
13
13
  "license": "MIT"