@magnitudedev/pi-extension 0.0.1-alpha.3 → 0.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
@@ -44,7 +44,7 @@ does all connection configuration and can be run safely after a standalone packa
44
44
 
45
45
  The extension bundles Magnitude's private SDK. Model status, loading, and stopping use the existing
46
46
  RPC endpoint at port 10100. When necessary the SDK runs `magnitude service start`; it does not use
47
- CLI output as a model API. If `/load-model` or `/stop-model` encounters a protocol mismatch, the
47
+ CLI output as a model API. If `/stop-model` encounters a protocol mismatch, the
48
48
  extension runs `magnitude connections sync pi` once to install the exact plugin version selected by
49
49
  the installed CLI, then reloads Pi. Retry your model command after reload; it is never replayed
50
50
  automatically. Failed sync reports the error without reloading or looping. Manually owned incompatible
@@ -57,7 +57,6 @@ latency, and token-weighted generation throughput. Pi extensions execute with yo
57
57
  Commands:
58
58
 
59
59
  - `/magnitude-setup` — open Magnitude's graphical model setup inside Pi
60
- - `/load-model [model-id]` — load an installed model
61
60
  - `/stop-model` — stop the active model
62
61
 
63
62
  Installed Magnitude models appear in Pi's built-in `/model` selector. To discover, compare, install,
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@magnitudedev/pi-extension",
3
- "version": "0.0.1-alpha.3",
3
+ "version": "0.0.1",
4
4
  "rpcVersion": 1,
5
- "contentFingerprint": "5d348e366e4c95b29edba024aae7756e7e941695537923bd3e82b1ddc54b9566",
5
+ "contentFingerprint": "3c0ea7c8e8d3a14eba260a94ba16b488550a04860c3c275f2f58a8da575cc439",
6
6
  "files": {
7
- "README.md": "c4536c32bc79ddaee7d09536f79c845c2189e8ddc721e583836eb399d9322053",
8
- "dist/magnitude.js": "14723faa27101270992397f22fcef2ca0f8cd55753e717250f0c92f921653e07",
7
+ "README.md": "26fa7e5b56c9b171946b7efec036703e258ab51607d1e20f00c45d6e96133a29",
8
+ "dist/magnitude.js": "b21c625dd7e2c0f00c6992845dad09cd753b4e85cf5b258d334ba4a4c6d065c3",
9
9
  "dist/skills/magnitude/SKILL.md": "37de67f0c7b831415f6298c8785b7ae97d5cfe454dc778651d96114840d2ace2"
10
10
  }
11
11
  }
package/dist/magnitude.js CHANGED
@@ -17,7 +17,7 @@ var __export = (target, all) => {
17
17
  import { openAICompletionsApi } from "@earendil-works/pi-ai/compat";
18
18
 
19
19
  // extensions/commands.ts
20
- import { Context as Context6, Effect as Effect10, Exit as Exit2, Fiber, Layer as Layer5, ManagedRuntime, Match as Match2, Option as Option16, Ref, Schema as Schema50, Scope as Scope3 } from "effect";
20
+ import { Context as Context6, Effect as Effect10, Exit as Exit2, Fiber, Layer as Layer5, ManagedRuntime, Ref, Schema as Schema50, Scope as Scope3 } from "effect";
21
21
  import { FetchHttpClient } from "@effect/platform";
22
22
  import * as NodeCommandExecutor from "@effect/platform-node/NodeCommandExecutor";
23
23
  import * as NodeFileSystem from "@effect/platform-node/NodeFileSystem";
@@ -1366,10 +1366,6 @@ var LowMemoryModelInstanceFailureSchema = Schema20.TaggedStruct("LowMemory", {
1366
1366
  });
1367
1367
  var ModelInstanceFailureSchema = Schema20.Union(ModelFailureSchema, LowMemoryModelInstanceFailureSchema);
1368
1368
  var ModelVariantLabelSchema = NonEmptyString.pipe(Schema20.brand("ModelVariantLabel"));
1369
- var formatModelDisplayName = (displayName, variantLabel) => Option5.match(variantLabel, {
1370
- onNone: () => displayName,
1371
- onSome: (label) => `${displayName} (${label})`
1372
- });
1373
1369
  var ModelLoadPlanSchema = Schema20.Struct({
1374
1370
  contextWindowTokens: PositiveSafeInteger2,
1375
1371
  parallelSequences: PositiveSafeInteger2,
@@ -1552,7 +1548,6 @@ var LocalModelAcquisitionStateSchema = Schema20.Union(Schema20.TaggedStruct("Not
1552
1548
  ...InstalledModelFields,
1553
1549
  failure: ModelFailureSchema
1554
1550
  }));
1555
- var installedAcquisition = (state) => state._tag === "Installed" || state._tag === "UpdateAvailable" || state._tag === "Updating" || state._tag === "UpdateFailed" || state._tag === "Removing" || state._tag === "RemoveFailed" ? state : undefined;
1556
1551
  var ProviderModelDisabledReasonSchema2 = Schema20.Literal("insufficient_resources", "provider_unavailable", "model_unavailable", "installation_unavailable", "incompatible_runtime", "invalid_configuration");
1557
1552
  var ProviderModelCatalogEntrySchema = Schema20.Struct({
1558
1553
  providerId: ProviderIdSchema,
@@ -2082,7 +2077,6 @@ var ChangeSchema = Schema25.Struct({
2082
2077
  import { Option as Option6 } from "effect";
2083
2078
  // ../../packages/acn-protocol/src/schemas/local-model-projection.ts
2084
2079
  import { Option as Option7 } from "effect";
2085
- var localModelIsInstalled = (model) => model._tag === "Discovered" ? true : installedAcquisition(model.acquisitionState) !== undefined;
2086
2080
  // ../../packages/acn-protocol/src/schemas/inference-projection.ts
2087
2081
  import { Data, Effect, Match, Option as Option8 } from "effect";
2088
2082
  class InferenceHardwareProjectionError extends Data.TaggedError("InferenceHardwareProjectionError") {
@@ -5714,52 +5708,10 @@ var commandFailure = (error) => Schema50.is(ProtocolMismatch)(error) ? error : n
5714
5708
  var ModelCommands = Context6.GenericTag("pi/ModelCommands");
5715
5709
  var commandsLayer = Layer5.effect(ModelCommands, Effect10.gen(function* () {
5716
5710
  const client = yield* MagnitudeClient;
5717
- const [cached, invalidate] = yield* Effect10.cachedInvalidateWithTTL(client.models.getCatalog({}).pipe(Effect10.mapError(commandFailure)), "30 seconds");
5718
5711
  return {
5719
- status: (fresh) => Effect10.gen(function* () {
5720
- if (fresh)
5721
- yield* invalidate;
5722
- const result = yield* cached.pipe(Effect10.tapError(() => invalidate));
5723
- if (result._tag === "Initializing")
5724
- yield* invalidate;
5725
- return result;
5726
- }),
5727
- load: (input) => Schema50.decodeUnknown(ModelIdSchema)(input).pipe(Effect10.flatMap((modelId) => client.models.load({ modelId }).pipe(Effect10.as(modelId))), Effect10.tap(() => invalidate), Effect10.mapError(commandFailure)),
5728
- stop: client.models.stop({}).pipe(Effect10.tap(() => invalidate), Effect10.asVoid, Effect10.mapError(commandFailure))
5712
+ stop: client.models.stop({}).pipe(Effect10.asVoid, Effect10.mapError(commandFailure))
5729
5713
  };
5730
5714
  }));
5731
- var displayName = (model2) => formatModelDisplayName(model2.presentation.displayName, Option16.some(model2.presentation.variantLabel));
5732
- var residencyLabel = (state) => Match2.value(state).pipe(Match2.tagsExhaustive({
5733
- Unloaded: () => "unloaded",
5734
- Requested: () => "loading",
5735
- Loading: () => "loading",
5736
- Ready: () => "ready",
5737
- Stopping: () => "stopping",
5738
- Failed: () => "failed"
5739
- }));
5740
- var stateLabel = (model2) => Match2.value(model2).pipe(Match2.tagsExhaustive({
5741
- Discovered: ({ state }) => Match2.value(state).pipe(Match2.tagsExhaustive({
5742
- Ready: ({ residencyState }) => residencyLabel(residencyState),
5743
- Unavailable: () => "unavailable"
5744
- })),
5745
- Catalog: ({ acquisitionState }) => Match2.value(acquisitionState).pipe(Match2.tagsExhaustive({
5746
- NotInstalled: () => "not installed",
5747
- Installing: () => "installing",
5748
- InstallFailed: () => "installation failed",
5749
- Installed: ({ residencyState }) => residencyLabel(residencyState),
5750
- UpdateAvailable: ({ residencyState }) => residencyLabel(residencyState),
5751
- Updating: ({ residencyState }) => residencyLabel(residencyState),
5752
- UpdateFailed: ({ residencyState }) => residencyLabel(residencyState),
5753
- Removing: () => "removing",
5754
- RemoveFailed: () => "removal failed"
5755
- }))
5756
- }));
5757
- var loadable = (catalog) => catalog._tag === "Initializing" ? [] : catalog.models.flatMap((entry) => {
5758
- if (entry._tag !== "Local")
5759
- return [];
5760
- const model2 = entry.product;
5761
- return localModelIsInstalled(model2) && (model2._tag === "Discovered" ? model2.state._tag === "Ready" : model2.acquisitionState._tag !== "Removing" && model2.acquisitionState._tag !== "RemoveFailed") ? [model2] : [];
5762
- }).sort((a, b) => displayName(a).localeCompare(displayName(b)) || a.modelId.localeCompare(b.modelId));
5763
5715
  var magnitudeExecutable = () => process.env.MAGNITUDE_CLI?.trim() || "magnitude";
5764
5716
  var clientLayer2 = () => MagnitudeClient.layer().pipe(Layer5.provide([
5765
5717
  FetchHttpClient.layer,
@@ -5794,39 +5746,6 @@ var registerMagnitudeCommands = (pi, sdk = clientLayer2()) => {
5794
5746
  if (reload)
5795
5747
  await ctx.reload();
5796
5748
  };
5797
- pi.registerCommand("load-model", {
5798
- description: "Load a Magnitude model",
5799
- getArgumentCompletions: (prefix) => run(Effect10.gen(function* () {
5800
- const commands = yield* ModelCommands;
5801
- const status = yield* commands.status(false);
5802
- return loadable(status).filter((model2) => model2.modelId.toLowerCase().includes(prefix.trim().toLowerCase())).map((model2) => ({ value: model2.modelId, label: displayName(model2), description: stateLabel(model2) }));
5803
- }).pipe(Effect10.catchAll(() => Effect10.succeed(null)))),
5804
- handler: (args, ctx) => invoke(ctx, Effect10.gen(function* () {
5805
- const commands = yield* ModelCommands;
5806
- let modelId = args.trim();
5807
- if (!modelId) {
5808
- const status = yield* commands.status(true);
5809
- if (status._tag === "Initializing") {
5810
- yield* Effect10.sync(() => ctx.ui.notify("Magnitude is discovering local models. Try again shortly.", "info"));
5811
- return;
5812
- }
5813
- const eligible = loadable(status);
5814
- if (!eligible.length) {
5815
- yield* Effect10.sync(() => ctx.ui.notify("No installed Magnitude models are available.", "info"));
5816
- return;
5817
- }
5818
- const labels = eligible.map((model2) => `${displayName(model2)} · ${stateLabel(model2)} · ${model2.modelId}`);
5819
- const selected = yield* Effect10.promise(() => ctx.ui.select("Load Magnitude model", labels));
5820
- if (selected === undefined)
5821
- return;
5822
- modelId = eligible[labels.indexOf(selected)]?.modelId ?? "";
5823
- }
5824
- if (!modelId)
5825
- return;
5826
- const loaded = yield* commands.load(modelId);
5827
- yield* Effect10.sync(() => ctx.ui.notify(`Loaded ${loaded}.`, "info"));
5828
- }))
5829
- });
5830
5749
  pi.registerCommand("stop-model", {
5831
5750
  description: "Stop the active Magnitude model",
5832
5751
  handler: (_args, ctx) => invoke(ctx, Effect10.gen(function* () {
@@ -5861,7 +5780,7 @@ import { CancellableLoader } from "@earendil-works/pi-tui";
5861
5780
 
5862
5781
  // ../../packages/utils/src/process/interactive-process.ts
5863
5782
  import { spawn } from "node:child_process";
5864
- import { Deferred as Deferred3, Duration as Duration2, Effect as Effect11, Option as Option17, Schema as Schema51 } from "effect";
5783
+ import { Deferred as Deferred3, Duration as Duration2, Effect as Effect11, Option as Option16, Schema as Schema51 } from "effect";
5865
5784
 
5866
5785
  class InteractiveProcessFailed extends Schema51.TaggedError()("InteractiveProcessFailed", {
5867
5786
  operation: Schema51.Literal("spawn", "run"),
@@ -5953,7 +5872,7 @@ var terminateAndReap = ({ child, termination }) => Effect11.gen(function* () {
5953
5872
  } catch {}
5954
5873
  });
5955
5874
  const graceful = yield* Deferred3.await(termination).pipe(Effect11.ignore, Effect11.timeoutOption(Duration2.seconds(2)));
5956
- if (Option17.isSome(graceful))
5875
+ if (Option16.isSome(graceful))
5957
5876
  return;
5958
5877
  yield* Effect11.sync(() => {
5959
5878
  try {
@@ -6320,7 +6239,7 @@ var makeObservingFetch = (fetchImplementation, begin, scope) => {
6320
6239
 
6321
6240
  // extensions/progress.ts
6322
6241
  import { Text } from "@earendil-works/pi-tui";
6323
- import { Data as Data3, Effect as Effect15, Fiber as Fiber3, Option as Option18, Queue, Schema as Schema55 } from "effect";
6242
+ import { Data as Data3, Effect as Effect15, Fiber as Fiber3, Option as Option17, Queue, Schema as Schema55 } from "effect";
6324
6243
  var MAGNITUDE_SUMMARY_WIDGET_KEY = "magnitude-inference-summary";
6325
6244
  var RequestId = Schema55.Number.pipe(Schema55.int(), Schema55.brand("ProgressRequestId"));
6326
6245
 
@@ -6394,14 +6313,14 @@ var makeProgressTracker = (ui, now = () => performance.now()) => Effect15.gen(fu
6394
6313
  const finalize = Effect15.gen(function* () {
6395
6314
  if (state._tag !== "Settled")
6396
6315
  return;
6397
- if ([...state.run.responses.values()].some(Option18.isNone))
6316
+ if ([...state.run.responses.values()].some(Option17.isNone))
6398
6317
  return;
6399
6318
  if ([...state.run.requests.values()].some((r) => r._tag === "Observing"))
6400
6319
  return;
6401
6320
  const settled = state;
6402
6321
  state = runMachine.transition(settled, "Idle", {});
6403
6322
  const timings = [...settled.run.completed.entries()].filter(([id]) => settled.run.accepted.has(id)).sort(([a], [b]) => a - b).map(([, value]) => value);
6404
- if ([...settled.run.responses.values()].some((outcome) => !Option18.getOrElse(outcome, () => false)) || timings.length === 0) {
6323
+ if ([...settled.run.responses.values()].some((outcome) => !Option17.getOrElse(outcome, () => false)) || timings.length === 0) {
6405
6324
  yield* clearSummary;
6406
6325
  return;
6407
6326
  }
@@ -6456,12 +6375,12 @@ var makeProgressTracker = (ui, now = () => performance.now()) => Effect15.gen(fu
6456
6375
  const run = state._tag === "Working" ? state.run : undefined;
6457
6376
  const responseId = ++nextResponseId;
6458
6377
  const requests = [];
6459
- run?.responses.set(responseId, Option18.none());
6378
+ run?.responses.set(responseId, Option17.none());
6460
6379
  const belongs = () => run !== undefined && (state._tag === "Working" || state._tag === "Settled") && state.run === run;
6461
6380
  const end = (successful) => Effect15.gen(function* () {
6462
- if (!belongs() || Option18.isSome(run.responses.get(responseId)))
6381
+ if (!belongs() || Option17.isSome(run.responses.get(responseId)))
6463
6382
  return;
6464
- run.responses.set(responseId, Option18.some(successful));
6383
+ run.responses.set(responseId, Option17.some(successful));
6465
6384
  const last = requests.at(-1);
6466
6385
  if (successful && last !== undefined)
6467
6386
  run.accepted.add(last);
@@ -6481,13 +6400,13 @@ var makeProgressTracker = (ui, now = () => performance.now()) => Effect15.gen(fu
6481
6400
  yield* finalize;
6482
6401
  });
6483
6402
  const begin = Effect15.gen(function* () {
6484
- if (!belongs() || Option18.isSome(run.responses.get(responseId)))
6403
+ if (!belongs() || Option17.isSome(run.responses.get(responseId)))
6485
6404
  return { observe: () => Effect15.void, finish: Effect15.void, fail: Effect15.void };
6486
6405
  const id = RequestId.make(++nextId);
6487
6406
  requests.push(id);
6488
6407
  latest = id;
6489
6408
  active = undefined;
6490
- run?.requests.set(id, new Observing({ timings: Option18.none() }));
6409
+ run?.requests.set(id, new Observing({ timings: Option17.none() }));
6491
6410
  yield* resetRow;
6492
6411
  const close = (failed) => Effect15.gen(function* () {
6493
6412
  if (!belongs())
@@ -6499,7 +6418,7 @@ var makeProgressTracker = (ui, now = () => performance.now()) => Effect15.gen(fu
6499
6418
  run.requests.set(id, requestMachine.transition(request, "Closed", {}));
6500
6419
  else {
6501
6420
  run.requests.set(id, requestMachine.transition(request, "Observed", {}));
6502
- if (Option18.isSome(request.timings))
6421
+ if (Option17.isSome(request.timings))
6503
6422
  run.completed.set(id, request.timings.value);
6504
6423
  }
6505
6424
  if (latest === id) {
@@ -6516,7 +6435,7 @@ var makeProgressTracker = (ui, now = () => performance.now()) => Effect15.gen(fu
6516
6435
  if (request._tag !== "Observing")
6517
6436
  return;
6518
6437
  if (observation.timings)
6519
- run.requests.set(id, requestMachine.hold(request, { timings: Option18.some(observation.timings) }));
6438
+ run.requests.set(id, requestMachine.hold(request, { timings: Option17.some(observation.timings) }));
6520
6439
  if (latest !== id || !observation.progress)
6521
6440
  return;
6522
6441
  const progress = observation.progress;
package/package.json CHANGED
@@ -1,9 +1,14 @@
1
1
  {
2
2
  "name": "@magnitudedev/pi-extension",
3
- "version": "0.0.1-alpha.3",
4
- "description": "Magnitude model controls and inference progress for Pi",
3
+ "version": "0.0.1",
4
+ "description": "Run local AI models in Pi with Magnitude",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/magnitudedev/magnitude.git",
10
+ "directory": "integrations/pi"
11
+ },
7
12
  "publishConfig": {
8
13
  "access": "public"
9
14
  },
@@ -12,6 +17,7 @@
12
17
  "README.md"
13
18
  ],
14
19
  "pi": {
20
+ "image": "https://raw.githubusercontent.com/magnitudedev/magnitude/main/assets/readme/pi-preview.png",
15
21
  "extensions": [
16
22
  "./dist/magnitude.js"
17
23
  ]